Newer
Older
/*
* CartDecomposition_ext.hpp
*
* Created on: Mar 6, 2016
* Author: i-bird
*/
#ifndef SRC_DECOMPOSITION_CARTDECOMPOSITION_EXT_HPP_
#define SRC_DECOMPOSITION_CARTDECOMPOSITION_EXT_HPP_
#include "memory/HeapMemory.hpp"
#include "Decomposition/Distribution/ParMetisDistribution.hpp"
#include "Space/Ghost.hpp"
#include "Decomposition/nn_processor.hpp"
template<unsigned int dim, typename T, typename Memory = HeapMemory, template<typename> class layout_base = memory_traits_lin, typename Distribution = ParMetisDistribution<dim, T>>
class CartDecomposition;
/**
* \brief This class decompose a space into sub-sub-domains and distribute them across processors
*
* \tparam dim is the dimensionality of the physical domain we are going to decompose.
* \tparam T type of the space we decompose, Real, Integer, Complex ...
* \tparam Memory Memory factory used to allocate memory
* \tparam Distribution type of distribution, can be ParMetisDistribution or MetisDistribution
*
* Most of the functionality is the same as CartDecomposition so refer to that class for more information
*
* The additional functionality is the possibility to produce an extended decomposition, in figure is
* show what we mean with extended
*
* \see CartDecomposition
*
*
*
* ### Create a Cartesian decomposition object on a Box space, distribute, calculate internal and external ghost boxes
* \snippet CartDecomposition_unit_test.hpp Create CartDecomposition
*
*/
template<unsigned int dim, typename T, typename Memory = HeapMemory, template<typename> class layout_base = memory_traits_lin, typename Distribution = ParMetisDistribution<dim, T>>
class CartDecomposition_ext: public CartDecomposition<dim,T,Memory,layout_base,Distribution>
{
private:
/*! \brief It copy the sub-domains into another CartesianDecomposition object extending them
*
* \see duplicate (in case of extended domain)
*
* \param dec Cartesian decomposition object
* \param ext_dom Extended domain
void extend_subdomains(const CartDecomposition<dim,T,Memory,layout_base,Distribution> & dec, const ::Box<dim,T> & ext_dom)
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
{
// Box
typedef ::Box<dim,T> b;
this->bbox.zero();
// Extend sub-domains
for (size_t i = 0 ; i < dec.sub_domains.size() ; i++)
{
::Box<dim,T> box;
// Calculate the extended box
for (size_t j = 0 ; j < dim ; j++)
{
if (dec.sub_domains.template get<b::p1>(i)[j] == dec.domain.getLow(j))
box.setLow(j,ext_dom.getLow(j));
else
box.setLow(j,dec.sub_domains.template get<b::p1>(i)[j]);
if (dec.sub_domains.template get<b::p2>(i)[j] == dec.domain.getHigh(j))
box.setHigh(j,ext_dom.getHigh(j));
else
box.setHigh(j,dec.sub_domains.template get<b::p2>(i)[j]);
}
// add the subdomain
this->sub_domains.add(box);
// Calculate the bound box
this->bbox.enclose(box);
}
}
/*! \brief Extend the fines for the new Cartesian decomposition
*
/* void extend_fines(const CartDecomposition<dim,T,Memory,Distribution> & dec)
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
{
// Extension, first we calculate the extensions of the new domain compared
// to the old one in cell units (each cell unit is a sub-sub-domain)
::Box<dim,size_t> ext;
// Extension of the new fines structure
::Box<dim,size_t> n_fines_ext;
// Extension of the old fines structure
::Box<dim,size_t> o_fines_ext;
size_t sz_new[dim];
size_t sz_old[dim];
for (size_t i = 0; i < dim ; i++)
{
size_t p1 = (dec.domain.getLow(i) - dec.domain.getLow(i)) / dec.cd.getCellBox().getHigh(i) + 1;
size_t p2 = (dec.domain.getLow(i) - dec.domain.getLow(i)) / dec.cd.getCellBox().getHigh(i) + 1;
ext.setLow(i,p1);
ext.setHigh(i,p2);
sz_new[i] = p1+p2+dec.cd.getGrid().size(i);
sz_old[i] = dec.cd.getGrid().size(i);
}
grid_sm<dim,void> info_new(sz_new);
grid_sm<dim,void> info_old(sz_old);
// resize the new fines
this->fine_s.resize(info_new.size());
// we create an iterator that iterate across the full new fines
grid_key_dx_iterator<dim> fines_t(info_new);
while (fines_t.isNext())
{
auto key = fines_t.get();
// new_fines is bigger than old_fines structure
// out of bound key must be adjusted
// The adjustment produce a natural extension
// a representation can be seen in the figure of
// CartDecomposition duplicate function with extended domains
grid_key_dx<dim> key_old;
for (size_t i = 0 ; i < dim ; i++)
{
key_old.set_d(i,(long int)key.get(i) - ext.getLow(i));
if (key_old.get(i) < 0)
key_old.set_d(i,0);
else if(key_old.get(i) >= (long int)info_old.size(i) )
key_old.set_d(i,info_old.size(i)-1);
}
this->fine_s.get(info_new.LinId(key)) = dec.fine_s.get(info_old.LinId(key_old));
++fines_t;
}
this->gr.setDimensions(sz_new);
// the new extended CellDecomposer must be consistent with the old cellDecomposer.
this->cd.setDimensions(dec.cd,ext);
}*/
void reconstruct_fine_s_from_extended_domain(const ::Box<dim,T> & ext_domain)
{
this->initialize_fine_s(ext_domain);
this->construct_fine_s();
}
public:
/*! \brief Cartesian decomposition constructor
*
* \param v_cl VCluster
*
*/
CartDecomposition_ext(Vcluster<> & v_cl)
:CartDecomposition<dim,T,Memory,layout_base,Distribution>(v_cl)
//! The non-extended decomposition base class
typedef CartDecomposition<dim,T,Memory,layout_base,Distribution> base_type;
/*! \brief It create another object that contain the same decomposition information but with different ghost boxes and an extended domain
*
* The domain extension is produced extending the boxes at the border like in figure
*
* \verbatim
*
+--------------^--------^----------^----------+
| | | | |
| A | E | F | N |
| +-----------------------------------+---->
| | | | | | |
| A | A | | F | | |
| | | | | | |
| | | E +----------+ N | N |
<--------------+ | | | |
| | | | | | |
| | | | G | | |
| | | | +---------->
| B | B | +----------+ | |
| | +--------+ | M | M |
| | | | H | | |
| | | +-----+----+---------->
<--------------+ D | | | |
| | | | I | L | L |
| C | C | | | | |
| | | | | | |
| +-----------------------------------+ |
| | | | |
| C | D | I | L |
+--------------v--------v-----v---------------+
* \param ext_domain extended domain (MUST be extended)
*
* \return a duplicated decomposition with different ghost boxes and an extended domain
*
*/
void setParameters(const CartDecomposition<dim,T,Memory,layout_base,Distribution> & dec, const Ghost<dim,T> & g, const ::Box<dim,T> & ext_domain)
// Set the decomposition parameters
this->gr.setDimensions(dec.gr.getSize());
this->cd.setDimensions(ext_domain, dec.gr.getSize(), 0);
this->box_nn_processor = dec.box_nn_processor;
// Calculate new sub-domains for extended domain
extend_subdomains(dec,ext_domain);
// Calculate fine_s structure for the extended domain
// update the cell decomposer and gr
reconstruct_fine_s_from_extended_domain(ext_domain);
// Get the old sub-sub-domain grid extension
this->domain = ext_domain;
// spacing does not change
for (size_t i = 0 ; i < dim ; i++)
{this->spacing[i] = dec.spacing[i];};
this->ghost = g;
this->dist = dec.dist;
for (size_t i = 0 ; i < dim ; i++)
this->bc[i] = dec.bc[i];
(static_cast<nn_prcs<dim,T,layout_base,Memory> &>(*this)).create(this->box_nn_processor, this->sub_domains);
(static_cast<nn_prcs<dim,T, layout_base,Memory> &>(*this)).applyBC(ext_domain,g,this->bc);