source: src/grid/multigrid.cpp@ 66f24d

Last change on this file since 66f24d was 48b662, checked in by Olaf Lenz <olenz@…>, 14 years ago

Moved files in scafacos_fcs one level up.

git-svn-id: https://svn.version.fz-juelich.de/scafacos/trunk@847 5161e1c8-67bf-11de-9fd5-51895aff932f

  • Property mode set to 100644
File size: 8.0 KB
Line 
1/**
2 * @file multigrid.cpp
3 * @author Julian Iseringhausen <isering@ins.uni-bonn.de>
4 * @date Mon Apr 18 12:54:37 2011
5 *
6 * @brief VMG::Multigrid
7 *
8 */
9
10#ifdef HAVE_CONFIG_H
11#include <config.h>
12#endif
13
14#include "base/helper.hpp"
15#include "base/index.hpp"
16#include "comm/comm.hpp"
17#include "grid/grid.hpp"
18#include "grid/grid_indexing.hpp"
19#include "grid/multigrid.hpp"
20#include "interface/interface.hpp"
21
22using namespace VMG;
23
24Multigrid::Multigrid(Comm* comm, const Interface* interface)
25{
26 bool active;
27 Index points, remainder;
28 Index procs_l;
29 LocalIndices local_l;
30 GlobalIndices global_l;
31
32 const Index& pos = comm->Pos();
33 const Index& procs = comm->Procs();
34 const Index points_min = 5 * procs;
35 const std::vector<GlobalIndices>& global = interface->Global();
36 const std::vector<SpatialExtent>& extent = interface->Extent();
37
38 for (unsigned int i=0; i<global.size(); ++i) {
39
40 procs_l = global[i].Size() / points_min;
41
42 active = true;
43 for (int j=0; j<3; ++j) {
44 procs_l[j] = std::max(procs_l[j], 1);
45 procs_l[j] = std::min(procs[j], procs_l[j]);
46 active &= pos[j] < procs_l[j];
47 }
48
49 if (global[i].BoundaryType() == GlobalMax)
50 levelGlobalMax = interface->MaxLevel() - i;
51
52 if (active) {
53
54 // Set boundary type
55 global_l.BoundaryType() = global[i].BoundaryType();
56
57 // Compute global size
58 global_l.Size() = global[i].Size() / procs_l;
59 remainder = global[i].Size() % procs_l;
60
61 for (int j=0; j<3; ++j)
62 if (pos[j] < remainder[j])
63 ++(global_l.Size()[j]);
64
65 // Compute global begin
66 global_l.Begin() = pos * global_l.Size();
67
68 for (int j=0; j<3; ++j)
69 if (pos[j] >= remainder[j])
70 global_l.Begin()[j] += remainder[j];
71
72 // Compute global end
73 global_l.End() = global_l.Begin() + global_l.Size();
74
75 // Set alignment
76 for (int j=0; j<3; ++j) {
77 global_l.AlignmentBegin()[j] = std::max(0, global[i].AlignmentBegin()[j] - global_l.Begin()[j]);
78 global_l.AlignmentEnd()[j] = std::min(global_l.Size()[j], global[i].AlignmentEnd()[j] - global_l.Begin()[j]);
79 }
80
81 switch (comm->BoundaryConditions())
82 {
83 case Dirichlet:
84 local_l = InitDirichlet(global_l, extent[i], pos, procs_l);
85 break;
86 case Periodic:
87 local_l = InitPeriodic(global_l, extent[i], pos, procs_l);
88 break;
89 case Quasiperiodic:
90 local_l = InitDirichlet(global_l, extent[i], pos, procs_l);
91 break;
92 }
93
94 grids.push_back(new Grid(global_l, local_l, extent[i]));
95
96 }else {
97
98 global_l.Size() = 0;
99 global_l.Begin() = 0;
100 global_l.End() = 0;
101 global_l.AlignmentBegin() = 0;
102 global_l.AlignmentEnd() = 0;
103 global_l.BoundaryType() = EmptyGrid;
104
105 local_l.Size() = 0;
106 local_l.SizeTotal() = 0;
107 local_l.Begin() = 0;
108 local_l.End() = 0;
109 local_l.HaloBegin1() = 0;
110 local_l.HaloBegin2() = 0;
111 local_l.HaloEnd1() = 0;
112 local_l.HaloEnd2() = 0;
113 local_l.BoundaryBegin1() = 0;
114 local_l.BoundaryBegin2() = 0;
115 local_l.BoundaryEnd1() = 0;
116 local_l.BoundaryEnd2() = 0;
117 local_l.AlignmentBegin() = 0;
118 local_l.AlignmentEnd() = 0;
119
120 grids.push_back(new Grid(global_l, local_l, extent[i]));
121
122 }
123 }
124
125 numLevels = grids.size();
126
127 levelMax = interface->MaxLevel();
128 levelMin = levelMax - numLevels + 1;
129
130 levelIndex = 0;
131 levelCurrent = levelMax;
132}
133
134LocalIndices Multigrid::InitDirichlet(const GlobalIndices& global, const SpatialExtent& extent, const Index& pos, const Index& procs)
135{
136 LocalIndices local;
137
138 local.HaloBegin1() = local.HaloEnd1() = 0;
139 local.HaloBegin2() = local.HaloEnd2() = 0;
140 local.BoundaryBegin1() = local.BoundaryEnd1() = 0;
141 local.BoundaryBegin2() = local.BoundaryEnd2() = 0;
142
143 local.SizeTotal() = global.End() - global.Begin() + (global.BoundaryType() == LocallyRefined ? 2 : 0);
144
145 for (int i=0; i<3; ++i) {
146
147 if (pos[i] == 0) {
148 local.BoundaryBegin1()[i] = 0;
149 local.BoundaryEnd1()[i] = 1;
150 }else {
151 ++local.SizeTotal()[i];
152 local.HaloBegin1()[i] = 0;
153 local.HaloEnd1()[i] = 1;
154 }
155
156 if (pos[i] == procs[i]-1) {
157 local.BoundaryBegin2()[i] = local.SizeTotal()[i] - 1;
158 local.BoundaryEnd2()[i] = local.SizeTotal()[i];
159 }else {
160 ++local.SizeTotal()[i];
161 local.HaloBegin2()[i] = local.SizeTotal()[i] - 1;
162 local.HaloEnd2()[i] = local.SizeTotal()[i];
163 }
164
165 }
166
167 local.Begin() = 1;
168 local.End() = local.SizeTotal() - 1;
169
170 local.Size() = local.End() - local.Begin();
171
172 local.AlignmentBegin() = global.AlignmentBegin() + local.Begin();
173 local.AlignmentEnd() = global.AlignmentEnd() - local.Begin();
174
175 return local;
176}
177
178LocalIndices Multigrid::InitPeriodic(const GlobalIndices& global, const SpatialExtent& extent, const Index& pos, const Index& procs)
179{
180 LocalIndices local;
181
182 local.SizeTotal() = global.End() - global.Begin() + 2;
183
184 local.BoundaryBegin1() = local.BoundaryEnd1() = 0;
185 local.BoundaryBegin2() = local.BoundaryEnd2() = 0;
186
187 local.HaloBegin1() = 0;
188 local.HaloEnd1() = 1;
189 local.HaloBegin2() = local.SizeTotal() - 1;
190 local.HaloEnd2() = local.SizeTotal();
191
192 local.Begin() = 1;
193 local.End() = local.SizeTotal() - 1;
194
195 local.Size() = local.End() - local.Begin();
196
197 local.AlignmentBegin() = global.AlignmentBegin() + local.Begin();
198 local.AlignmentEnd() = global.AlignmentEnd() + local.Begin();
199
200 return local;
201}
202
203void Multigrid::SetLevel(int level)
204{
205 assert(level >= levelMin && level <= levelMax);
206 levelCurrent = level;
207 levelIndex = levelMax - level;
208}
209
210void Multigrid::ToCoarserLevel()
211{
212 assert(levelCurrent-1 >= levelMin);
213 --levelCurrent;
214 ++levelIndex;
215}
216
217void Multigrid::ToFinerLevel()
218{
219 assert(levelCurrent+1 <= levelMax);
220 ++levelCurrent;
221 --levelIndex;
222}
223
224void Multigrid::ClearAll()
225{
226 for (int i=MinLevel(); i<=MaxLevel(); ++i)
227 (*this)(i).Clear();
228}
229
230// TODO: diff that in case that breaks QP
231void Multigrid::ClearAllCoarseLevels()
232{
233 for (int i=MinLevel(); i<MaxLevel(); ++i)
234 (*this)(i).Clear();
235}
236
237
238void Multigrid::SetCoarserDirichletValues()
239{
240 Index i_c, i_f;
241
242 for (int i=GlobalMaxLevel(); i>MinLevel(); --i) {
243
244 Grid& grid_f = (*this)(i);
245 Grid& grid_c = (*this)(i-1);
246
247 i_c.X() = grid_c.Local().BoundaryBegin1().X();
248 i_f.X() = grid_f.Local().BoundaryBegin1().X();
249 for (i_c.Y()=grid_c.Local().Begin().Y(); i_c.Y()<grid_c.Local().End().Y(); ++i_c.Y())
250 for (i_c.Z()=grid_c.Local().Begin().Z(); i_c.Z()<grid_c.Local().End().Z(); ++i_c.Z())
251 grid_c(i_c) = grid_f.GetVal(i_f.X(), 2*i_c.Y(), 2*i_c.Z());
252
253 i_c.X() = grid_c.Local().BoundaryBegin2().X();
254 i_f.X() = grid_f.Local().BoundaryBegin2().X();
255 for (i_c.Y()=grid_c.Local().Begin().Y(); i_c.Y()<grid_c.Local().End().Y(); ++i_c.Y())
256 for (i_c.Z()=grid_c.Local().Begin().Z(); i_c.Z()<grid_c.Local().End().Z(); ++i_c.Z())
257 grid_c(i_c) = grid_f.GetVal(i_f.X(), 2*i_c.Y(), 2*i_c.Z());
258
259 i_c.Y() = grid_c.Local().BoundaryBegin1().Y();
260 i_f.Y() = grid_f.Local().BoundaryBegin1().Y();
261 for (i_c.X()=0; i_c.X()<grid_c.Local().SizeTotal().X(); ++i_c.X())
262 for (i_c.Z()=grid_c.Local().Begin().Z(); i_c.Z()<grid_c.Local().End().Z(); ++i_c.Z())
263 grid_c(i_c) = grid_f.GetVal(2*i_c.X(), i_f.Y(), 2*i_c.Z());
264
265 i_c.Y() = grid_c.Local().BoundaryBegin2().Y();
266 i_f.Y() = grid_f.Local().BoundaryBegin2().Y();
267 for (i_c.X()=0; i_c.X()<grid_c.Local().SizeTotal().X(); ++i_c.X())
268 for (i_c.Z()=grid_c.Local().Begin().Z(); i_c.Z()<grid_c.Local().End().Z(); ++i_c.Z())
269 grid_c(i_c) = grid_f.GetVal(2*i_c.X(), i_f.Y(), 2*i_c.Z());
270
271 i_c.Z() = grid_c.Local().BoundaryBegin1().Z();
272 i_f.Z() = grid_f.Local().BoundaryBegin1().Z();
273 for (i_c.X()=0; i_c.X()<grid_c.Local().SizeTotal().X(); ++i_c.X())
274 for (i_c.Y()=0; i_c.Y()<grid_c.Local().SizeTotal().Y(); ++i_c.Y())
275 grid_c(i_c) = grid_f.GetVal(2*i_c.X(), 2*i_c.Y(), i_f.Z());
276
277 i_c.Z() = grid_c.Local().BoundaryBegin2().Z();
278 i_f.Z() = grid_f.Local().BoundaryBegin2().Z();
279 for (i_c.X()=0; i_c.X()<grid_c.Local().SizeTotal().X(); ++i_c.X())
280 for (i_c.Y()=0; i_c.Y()<grid_c.Local().SizeTotal().Y(); ++i_c.Y())
281 grid_c(i_c) = grid_f.GetVal(2*i_c.X(), 2*i_c.Y(), i_f.Z());
282
283 }
284}
285
286Multigrid::~Multigrid()
287{
288 for (unsigned int i=0; i<grids.size(); ++i)
289 delete grids[i];
290}
Note: See TracBrowser for help on using the repository browser.