CartDecomposition_ext.hpp 7.56 KB
Newer Older
1
2
3
4
5
6
7
8
9
10
/*
 * CartDecomposition_ext.hpp
 *
 *  Created on: Mar 6, 2016
 *      Author: i-bird
 */

#ifndef SRC_DECOMPOSITION_CARTDECOMPOSITION_EXT_HPP_
#define SRC_DECOMPOSITION_CARTDECOMPOSITION_EXT_HPP_

incardon's avatar
incardon committed
11
12
13
14
15
#include "memory/HeapMemory.hpp"
#include "Decomposition/Distribution/ParMetisDistribution.hpp"
#include "Space/Ghost.hpp"
#include "Decomposition/nn_processor.hpp"

16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
template<unsigned int dim, typename T, typename Memory = HeapMemory, 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, typename Distribution = ParMetisDistribution<dim, T>>
class CartDecomposition_ext: public CartDecomposition<dim,T,Memory,Distribution>
{
private:

	/*! \brief It copy the sub-domains into another CartesianDecomposition object extending them
	 *
	 * \see duplicate (in case of extended domain)
	 *
incardon's avatar
incardon committed
50
51
	 * \param dec Cartesian decomposition object
	 * \param ext_dom Extended domain
52
53
54
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
	 *
	 */
	void extend_subdomains(const CartDecomposition<dim,T,Memory,Distribution> & dec, const ::Box<dim,T> & ext_dom)
	{
		// 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
	 *
incardon's avatar
incardon committed
90
	 * \param dec Non-extended decomposition
91
92
93
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
155
156
157
158
159
160
161
162
163
164
165
166
167
168
	 *
	 */
	void extend_fines(const CartDecomposition<dim,T> & dec)
	{
		// 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);
	}

public:

	/*! \brief Cartesian decomposition constructor
	 *
	 * \param v_cl VCluster
	 *
	 */
	CartDecomposition_ext(Vcluster & v_cl)
	:CartDecomposition<dim,T,Memory,Distribution>(v_cl)
	{
	}

incardon's avatar
incardon committed
169
	//! The non-extended decomposition base class
170
171
172
173
174
175
176
177
	typedef CartDecomposition<dim,T,Memory,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
	 *
incardon's avatar
incardon committed
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
	+--------------^--------^----------^----------+
	|              |        |          |          |
	|        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---------------+
202
203
204
205

	 *
	 * \endverbatim
	 *
incardon's avatar
incardon committed
206
	 * \param dec Decomposition
207
	 * \param g ghost
incardon's avatar
incardon committed
208
	 * \param ext_domain extended domain (MUST be extended)
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
	 *
	 * \return a duplicated decomposition with different ghost boxes and an extended domain
	 *
	 */
	void setParameters(const CartDecomposition<dim,T,Memory,Distribution> & dec, const Ghost<dim,T> & g, const ::Box<dim,T> & ext_domain)
	{
		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
		extend_fines(dec);

		// Get the old sub-sub-domain grid extension

		this->domain = ext_domain;

		// spacing does not change
incardon's avatar
incardon committed
229
230
231

		for (size_t i = 0 ; i < dim ; i++)
		{this->spacing[i] = dec.spacing[i];};
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250

		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> &>(*this)).create(this->box_nn_processor, this->sub_domains);
		(static_cast<nn_prcs<dim,T> &>(*this)).applyBC(ext_domain,g,this->bc);

		this->Initialize_geo_cell_lists();
		this->calculateGhostBoxes();
	}

};



#endif /* SRC_DECOMPOSITION_CARTDECOMPOSITION_EXT_HPP_ */