source: src/grid/multigrid.cpp@ facba0

Last change on this file since facba0 was dfed1c, checked in by Julian Iseringhausen <isering@…>, 14 years ago

Major vmg update.

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

  • Property mode set to 100644
File size: 7.9 KB
RevLine 
[48b662]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
[dfed1c]14#include <iostream>
15
[48b662]16#include "base/helper.hpp"
17#include "base/index.hpp"
18#include "comm/comm.hpp"
[dfed1c]19#include "comm/domain_decomposition.hpp"
[48b662]20#include "grid/grid.hpp"
[dfed1c]21#include "grid/grid_properties.hpp"
[48b662]22#include "grid/multigrid.hpp"
23#include "interface/interface.hpp"
24
25using namespace VMG;
26
27Multigrid::Multigrid(Comm* comm, const Interface* interface)
28{
29 Index points, remainder;
30 LocalIndices local_l;
[dfed1c]31 std::vector<GlobalIndices> global_separated;
[48b662]32
33 const std::vector<GlobalIndices>& global = interface->Global();
34 const std::vector<SpatialExtent>& extent = interface->Extent();
35
[dfed1c]36 comm->GetDomainDecomposition().Compute(comm, interface, global_separated);
[48b662]37
[dfed1c]38 for (unsigned int i=0; i<global.size(); ++i) {
[48b662]39
[dfed1c]40 /*
41 * Check if this level is the finest global level
42 */
[48b662]43 if (global[i].BoundaryType() == GlobalMax)
44 levelGlobalMax = interface->MaxLevel() - i;
45
46
[dfed1c]47 if (global_separated[i].SizeLocal().Product() > 0) {
[48b662]48
[dfed1c]49 /*
50 * Initialize some properties with zero
51 */
52 local_l.HaloBegin1() = local_l.HaloEnd1() = 0;
53 local_l.HaloBegin2() = local_l.HaloEnd2() = 0;
54 local_l.BoundaryBegin1() = local_l.BoundaryEnd1() = 0;
55 local_l.BoundaryBegin2() = local_l.BoundaryEnd2() = 0;
[48b662]56
[dfed1c]57 /*
58 * Set boundary dependant properties
59 */
60 for (int j=0; j<3; ++j) {
[48b662]61
[dfed1c]62 if (comm->BoundaryConditions()[j] == Dirichlet ||
63 comm->BoundaryConditions()[j] == Open) {
64
65 local_l.SizeTotal()[j] = global_separated[i].SizeLocal()[j] +
66 (global_separated[i].BoundaryType() == LocallyRefined ? 2 : 0);
67
68 /*
69 * We have a boundary at the ends of the process grids
70 * and halo grid points otherwise
71 */
72 if (global_separated[i].BeginLocal()[j] == 0) {
73 local_l.BoundaryBegin1()[j] = 0;
74 local_l.BoundaryEnd1()[j] = 1;
75 }else {
76 ++local_l.SizeTotal()[j];
77 local_l.HaloBegin1()[j] = 0;
78 local_l.HaloEnd1()[j] = 1;
79 }
80
81 if (global_separated[i].EndLocal()[j] == global_separated[i].SizeGlobal()[j]) {
82 local_l.BoundaryBegin2()[j] = local_l.SizeTotal()[j] - 1;
83 local_l.BoundaryEnd2()[j] = local_l.SizeTotal()[j];
84 }else {
85 ++local_l.SizeTotal()[j];
86 local_l.HaloBegin2()[j] = local_l.SizeTotal()[j] - 1;
87 local_l.HaloEnd2()[j] = local_l.SizeTotal()[j];
88 }
89
90 }else if (comm->BoundaryConditions()[j] == Periodic) {
91
92 local_l.SizeTotal()[j] = global_separated[i].SizeLocal()[j] + 2;
93
94 /*
95 * No boundary
96 */
97 local_l.BoundaryBegin1()[j] = local_l.BoundaryEnd1()[j] = 0;
98 local_l.BoundaryBegin2()[j] = local_l.BoundaryEnd2()[j] = 0;
99
100 /*
101 * Halo grid points on all processes
102 */
103 local_l.HaloBegin1()[j] = 0;
104 local_l.HaloEnd1()[j] = 1;
105 local_l.HaloBegin2()[j] = local_l.SizeTotal()[j] - 1;
106 local_l.HaloEnd2()[j] = local_l.SizeTotal()[j];
[48b662]107
[dfed1c]108 }
[48b662]109
110 }
111
[dfed1c]112 local_l.Begin() = 1;
113 local_l.End() = local_l.SizeTotal() - 1;
114
115 local_l.Size() = local_l.End() - local_l.Begin();
[48b662]116
[dfed1c]117 if (i==0)
118 local_l.AlignmentBegin() = (global_separated[i].SizeGlobal() - static_cast<int>( pow(2.0, interface->MaxLevel() ) + 0.5 ) - 1) / 2;
119 else if (global_separated[i].BoundaryType() == LocallyRefined)
120 local_l.AlignmentBegin() = (extent[i].Size() - extent[i-1].Size()) * pow(2.0, interface->MaxLevel()-i-1) + 0.5;
121 else if (global_separated[i].BoundaryType() == GlobalMax)
122 local_l.AlignmentBegin() = (extent[i].Size() - extent[i-1].Size()) * pow(2.0, interface->MaxLevel()-i-1) - 0.5;
123 else
124 local_l.AlignmentBegin() = 0;
125
126 local_l.AlignmentBegin() += local_l.Begin();
127 local_l.AlignmentEnd() = local_l.AlignmentBegin() + global_separated[i].SizeLocal();
128
129 local_l.AlignmentBegin().Clamp(local_l.Begin(), local_l.End());
130 local_l.AlignmentEnd().Clamp(local_l.Begin(), local_l.End());
131
132
133 grids.push_back(new Grid(global_separated[i], local_l, extent[i], interface->MaxLevel()-i, this));
[48b662]134
135 }else {
136
[dfed1c]137 global_separated[i].SizeGlobal() = global[i].SizeGlobal();
138 global_separated[i].BeginFinest() = global[i].BeginFinest();
139 global_separated[i].EndFinest() = global[i].EndFinest();
140 global_separated[i].SizeFinest() = global[i].SizeFinest();
141 global_separated[i].SizeLocal() = 0;
142 global_separated[i].BeginLocal() = 0;
143 global_separated[i].EndLocal() = 0;
144 global_separated[i].BoundaryType() = global[i].BoundaryType();
[48b662]145
146 local_l.Size() = 0;
147 local_l.SizeTotal() = 0;
148 local_l.Begin() = 0;
149 local_l.End() = 0;
150 local_l.HaloBegin1() = 0;
151 local_l.HaloBegin2() = 0;
152 local_l.HaloEnd1() = 0;
153 local_l.HaloEnd2() = 0;
154 local_l.BoundaryBegin1() = 0;
155 local_l.BoundaryBegin2() = 0;
156 local_l.BoundaryEnd1() = 0;
157 local_l.BoundaryEnd2() = 0;
158 local_l.AlignmentBegin() = 0;
159 local_l.AlignmentEnd() = 0;
160
[dfed1c]161 grids.push_back(new Grid(global_separated[i], local_l, extent[i], interface->MaxLevel()-i, this));
[48b662]162
163 }
164 }
165
166 numLevels = grids.size();
167
168 levelMax = interface->MaxLevel();
169 levelMin = levelMax - numLevels + 1;
170
171 levelIndex = 0;
172 levelCurrent = levelMax;
173
174}
175
176void Multigrid::SetLevel(int level)
177{
178 assert(level >= levelMin && level <= levelMax);
179 levelCurrent = level;
180 levelIndex = levelMax - level;
181}
182
183void Multigrid::ToCoarserLevel()
184{
185 assert(levelCurrent-1 >= levelMin);
186 --levelCurrent;
187 ++levelIndex;
188}
189
190void Multigrid::ToFinerLevel()
191{
192 assert(levelCurrent+1 <= levelMax);
193 ++levelCurrent;
194 --levelIndex;
195}
196
197void Multigrid::ClearAll()
198{
199 for (int i=MinLevel(); i<=MaxLevel(); ++i)
200 (*this)(i).Clear();
201}
202
203// TODO: diff that in case that breaks QP
204void Multigrid::ClearAllCoarseLevels()
205{
206 for (int i=MinLevel(); i<MaxLevel(); ++i)
207 (*this)(i).Clear();
208}
209
210
211void Multigrid::SetCoarserDirichletValues()
212{
213 Index i_c, i_f;
214
215 for (int i=GlobalMaxLevel(); i>MinLevel(); --i) {
216
217 Grid& grid_f = (*this)(i);
218 Grid& grid_c = (*this)(i-1);
219
220 i_c.X() = grid_c.Local().BoundaryBegin1().X();
221 i_f.X() = grid_f.Local().BoundaryBegin1().X();
222 for (i_c.Y()=grid_c.Local().Begin().Y(); i_c.Y()<grid_c.Local().End().Y(); ++i_c.Y())
223 for (i_c.Z()=grid_c.Local().Begin().Z(); i_c.Z()<grid_c.Local().End().Z(); ++i_c.Z())
224 grid_c(i_c) = grid_f.GetVal(i_f.X(), 2*i_c.Y(), 2*i_c.Z());
225
226 i_c.X() = grid_c.Local().BoundaryBegin2().X();
227 i_f.X() = grid_f.Local().BoundaryBegin2().X();
228 for (i_c.Y()=grid_c.Local().Begin().Y(); i_c.Y()<grid_c.Local().End().Y(); ++i_c.Y())
229 for (i_c.Z()=grid_c.Local().Begin().Z(); i_c.Z()<grid_c.Local().End().Z(); ++i_c.Z())
230 grid_c(i_c) = grid_f.GetVal(i_f.X(), 2*i_c.Y(), 2*i_c.Z());
231
232 i_c.Y() = grid_c.Local().BoundaryBegin1().Y();
233 i_f.Y() = grid_f.Local().BoundaryBegin1().Y();
234 for (i_c.X()=0; i_c.X()<grid_c.Local().SizeTotal().X(); ++i_c.X())
235 for (i_c.Z()=grid_c.Local().Begin().Z(); i_c.Z()<grid_c.Local().End().Z(); ++i_c.Z())
236 grid_c(i_c) = grid_f.GetVal(2*i_c.X(), i_f.Y(), 2*i_c.Z());
237
238 i_c.Y() = grid_c.Local().BoundaryBegin2().Y();
239 i_f.Y() = grid_f.Local().BoundaryBegin2().Y();
240 for (i_c.X()=0; i_c.X()<grid_c.Local().SizeTotal().X(); ++i_c.X())
241 for (i_c.Z()=grid_c.Local().Begin().Z(); i_c.Z()<grid_c.Local().End().Z(); ++i_c.Z())
242 grid_c(i_c) = grid_f.GetVal(2*i_c.X(), i_f.Y(), 2*i_c.Z());
243
244 i_c.Z() = grid_c.Local().BoundaryBegin1().Z();
245 i_f.Z() = grid_f.Local().BoundaryBegin1().Z();
246 for (i_c.X()=0; i_c.X()<grid_c.Local().SizeTotal().X(); ++i_c.X())
247 for (i_c.Y()=0; i_c.Y()<grid_c.Local().SizeTotal().Y(); ++i_c.Y())
248 grid_c(i_c) = grid_f.GetVal(2*i_c.X(), 2*i_c.Y(), i_f.Z());
249
250 i_c.Z() = grid_c.Local().BoundaryBegin2().Z();
251 i_f.Z() = grid_f.Local().BoundaryBegin2().Z();
252 for (i_c.X()=0; i_c.X()<grid_c.Local().SizeTotal().X(); ++i_c.X())
253 for (i_c.Y()=0; i_c.Y()<grid_c.Local().SizeTotal().Y(); ++i_c.Y())
254 grid_c(i_c) = grid_f.GetVal(2*i_c.X(), 2*i_c.Y(), i_f.Z());
255
256 }
257}
258
259Multigrid::~Multigrid()
260{
261 for (unsigned int i=0; i<grids.size(); ++i)
262 delete grids[i];
263}
Note: See TracBrowser for help on using the repository browser.