source: src/grid/multigrid.cpp@ 716da7

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

Fix energy calculation.

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

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