1/*
2 * CartDecomposition_ext.hpp
3 *
4 * Created on: Mar 6, 2016
5 * Author: i-bird
6 */
7
8#ifndef SRC_DECOMPOSITION_CARTDECOMPOSITION_EXT_HPP_
9#define SRC_DECOMPOSITION_CARTDECOMPOSITION_EXT_HPP_
10
11#include "memory/HeapMemory.hpp"
12#include "Decomposition/Distribution/ParMetisDistribution.hpp"
13#include "Space/Ghost.hpp"
14#include "Decomposition/nn_processor.hpp"
15
16template<unsigned int dim, typename T, typename Memory = HeapMemory, template<typename> class layout_base = memory_traits_lin, typename Distribution = ParMetisDistribution<dim, T>>
17class CartDecomposition;
18
19/**
20 * \brief This class decompose a space into sub-sub-domains and distribute them across processors
21 *
22 * \tparam dim is the dimensionality of the physical domain we are going to decompose.
23 * \tparam T type of the space we decompose, Real, Integer, Complex ...
24 * \tparam Memory Memory factory used to allocate memory
25 * \tparam Distribution type of distribution, can be ParMetisDistribution or MetisDistribution
26 *
27 * Most of the functionality is the same as CartDecomposition so refer to that class for more information
28 *
29 * The additional functionality is the possibility to produce an extended decomposition, in figure is
30 * show what we mean with extended
31 *
32 * \see CartDecomposition
33 *
34 *
35 *
36 * ### Create a Cartesian decomposition object on a Box space, distribute, calculate internal and external ghost boxes
37 * \snippet CartDecomposition_unit_test.hpp Create CartDecomposition
38 *
39 */
40
41template<unsigned int dim, typename T, typename Memory = HeapMemory, template<typename> class layout_base = memory_traits_lin, typename Distribution = ParMetisDistribution<dim, T>>
42class CartDecomposition_ext: public CartDecomposition<dim,T,Memory,layout_base,Distribution>
43{
44private:
45
46 /*! \brief It copy the sub-domains into another CartesianDecomposition object extending them
47 *
48 * \see duplicate (in case of extended domain)
49 *
50 * \param dec Cartesian decomposition object
51 * \param ext_dom Extended domain
52 *
53 */
54 void extend_subdomains(const CartDecomposition<dim,T,Memory,layout_base,Distribution> & dec, const ::Box<dim,T> & ext_dom)
55 {
56 // Box
57 typedef ::Box<dim,T> b;
58
59 this->bbox.zero();
60
61 // Extend sub-domains
62 for (size_t i = 0 ; i < dec.sub_domains.size() ; i++)
63 {
64 ::Box<dim,T> box;
65
66 // Calculate the extended box
67 for (size_t j = 0 ; j < dim ; j++)
68 {
69 if (dec.sub_domains.template get<b::p1>(i)[j] == dec.domain.getLow(j))
70 box.setLow(j,ext_dom.getLow(j));
71 else
72 box.setLow(j,dec.sub_domains.template get<b::p1>(i)[j]);
73
74 if (dec.sub_domains.template get<b::p2>(i)[j] == dec.domain.getHigh(j))
75 box.setHigh(j,ext_dom.getHigh(j));
76 else
77 box.setHigh(j,dec.sub_domains.template get<b::p2>(i)[j]);
78 }
79
80 // add the subdomain
81 this->sub_domains.add(box);
82
83 // Calculate the bound box
84 this->bbox.enclose(box);
85 }
86 }
87
88 /*! \brief Extend the fines for the new Cartesian decomposition
89 *
90 * \param dec Non-extended decomposition
91 *
92 */
93/* void extend_fines(const CartDecomposition<dim,T,Memory,Distribution> & dec)
94 {
95 // Extension, first we calculate the extensions of the new domain compared
96 // to the old one in cell units (each cell unit is a sub-sub-domain)
97 ::Box<dim,size_t> ext;
98 // Extension of the new fines structure
99 ::Box<dim,size_t> n_fines_ext;
100 // Extension of the old fines structure
101 ::Box<dim,size_t> o_fines_ext;
102
103 size_t sz_new[dim];
104 size_t sz_old[dim];
105
106 for (size_t i = 0; i < dim ; i++)
107 {
108 size_t p1 = (dec.domain.getLow(i) - dec.domain.getLow(i)) / dec.cd.getCellBox().getHigh(i) + 1;
109 size_t p2 = (dec.domain.getLow(i) - dec.domain.getLow(i)) / dec.cd.getCellBox().getHigh(i) + 1;
110
111 ext.setLow(i,p1);
112 ext.setHigh(i,p2);
113 sz_new[i] = p1+p2+dec.cd.getGrid().size(i);
114 sz_old[i] = dec.cd.getGrid().size(i);
115 }
116
117 grid_sm<dim,void> info_new(sz_new);
118 grid_sm<dim,void> info_old(sz_old);
119
120 // resize the new fines
121 this->fine_s.resize(info_new.size());
122
123 // we create an iterator that iterate across the full new fines
124 grid_key_dx_iterator<dim> fines_t(info_new);
125
126 while (fines_t.isNext())
127 {
128 auto key = fines_t.get();
129
130 // new_fines is bigger than old_fines structure
131 // out of bound key must be adjusted
132 // The adjustment produce a natural extension
133 // a representation can be seen in the figure of
134 // CartDecomposition duplicate function with extended domains
135
136 grid_key_dx<dim> key_old;
137 for (size_t i = 0 ; i < dim ; i++)
138 {
139 key_old.set_d(i,(long int)key.get(i) - ext.getLow(i));
140 if (key_old.get(i) < 0)
141 key_old.set_d(i,0);
142 else if(key_old.get(i) >= (long int)info_old.size(i) )
143 key_old.set_d(i,info_old.size(i)-1);
144 }
145
146 this->fine_s.get(info_new.LinId(key)) = dec.fine_s.get(info_old.LinId(key_old));
147
148 ++fines_t;
149 }
150
151 this->gr.setDimensions(sz_new);
152
153 // the new extended CellDecomposer must be consistent with the old cellDecomposer.
154 this->cd.setDimensions(dec.cd,ext);
155 }*/
156
157 void reconstruct_fine_s_from_extended_domain(const ::Box<dim,T> & ext_domain)
158 {
159 this->initialize_fine_s(ext_domain);
160 this->construct_fine_s();
161 }
162
163public:
164
165 /*! \brief Cartesian decomposition constructor
166 *
167 * \param v_cl VCluster
168 *
169 */
170 CartDecomposition_ext(Vcluster<> & v_cl)
171 :CartDecomposition<dim,T,Memory,layout_base,Distribution>(v_cl)
172 {
173 }
174
175 //! The non-extended decomposition base class
176 typedef CartDecomposition<dim,T,Memory,layout_base,Distribution> base_type;
177
178 /*! \brief It create another object that contain the same decomposition information but with different ghost boxes and an extended domain
179 *
180 * The domain extension is produced extending the boxes at the border like in figure
181 *
182 * \verbatim
183 *
184 +--------------^--------^----------^----------+
185 | | | | |
186 | A | E | F | N |
187 | +-----------------------------------+---->
188 | | | | | | |
189 | A | A | | F | | |
190 | | | | | | |
191 | | | E +----------+ N | N |
192 <--------------+ | | | |
193 | | | | | | |
194 | | | | G | | |
195 | | | | +---------->
196 | B | B | +----------+ | |
197 | | +--------+ | M | M |
198 | | | | H | | |
199 | | | +-----+----+---------->
200 <--------------+ D | | | |
201 | | | | I | L | L |
202 | C | C | | | | |
203 | | | | | | |
204 | +-----------------------------------+ |
205 | | | | |
206 | C | D | I | L |
207 +--------------v--------v-----v---------------+
208
209 *
210 * \endverbatim
211 *
212 * \param dec Decomposition
213 * \param g ghost
214 * \param ext_domain extended domain (MUST be extended)
215 *
216 * \return a duplicated decomposition with different ghost boxes and an extended domain
217 *
218 */
219 void setParameters(const CartDecomposition<dim,T,Memory,layout_base,Distribution> & dec, const Ghost<dim,T> & g, const ::Box<dim,T> & ext_domain)
220 {
221 // Set the decomposition parameters
222 this->gr.setDimensions(dec.gr.getSize());
223 this->cd.setDimensions(ext_domain, dec.gr.getSize(), 0);
224
225 this->box_nn_processor = dec.box_nn_processor;
226
227 // Calculate new sub-domains for extended domain
228 extend_subdomains(dec,ext_domain);
229
230 // Calculate fine_s structure for the extended domain
231 // update the cell decomposer and gr
232 reconstruct_fine_s_from_extended_domain(ext_domain);
233
234 // Get the old sub-sub-domain grid extension
235
236 this->domain = ext_domain;
237
238 // spacing does not change
239
240 for (size_t i = 0 ; i < dim ; i++)
241 {this->spacing[i] = dec.spacing[i];};
242
243 this->ghost = g;
244 this->dist = dec.dist;
245
246 for (size_t i = 0 ; i < dim ; i++)
247 this->bc[i] = dec.bc[i];
248
249 (static_cast<nn_prcs<dim,T,layout_base,Memory> &>(*this)).create(this->box_nn_processor, this->sub_domains);
250 (static_cast<nn_prcs<dim,T, layout_base,Memory> &>(*this)).applyBC(ext_domain,g,this->bc);
251
252 this->Initialize_geo_cell_lists();
253 this->calculateGhostBoxes();
254 }
255
256};
257
258
259
260#endif /* SRC_DECOMPOSITION_CARTDECOMPOSITION_EXT_HPP_ */
261