source: src/grid/multigrid.cpp@ a72216

Last change on this file since a72216 was a72216, checked in by Olaf Lenz <olenz@…>, 13 years ago

Fixed permissions.

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

  • Property mode set to 100644
File size: 8.1 KB
Line 
1/*
2 * vmg - a versatile multigrid solver
3 * Copyright (C) 2012 Institute for Numerical Simulation, University of Bonn
4 *
5 * vmg is free software: you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation, either version 3 of the License, or
8 * (at your option) any later version.
9 *
10 * vmg is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program. If not, see <http://www.gnu.org/licenses/>.
17 */
18
19/**
20 * @file multigrid.cpp
21 * @author Julian Iseringhausen <isering@ins.uni-bonn.de>
22 * @date Mon Apr 18 12:54:37 2011
23 *
24 * @brief VMG::Multigrid
25 *
26 */
27
28#ifdef HAVE_CONFIG_H
29#include <config.h>
30#endif
31
32#include <iostream>
33
34#include "base/helper.hpp"
35#include "base/index.hpp"
36#include "base/interface.hpp"
37#include "comm/comm.hpp"
38#include "comm/domain_decomposition.hpp"
39#include "grid/grid.hpp"
40#include "grid/grid_properties.hpp"
41#include "grid/multigrid.hpp"
42
43using namespace VMG;
44
45Multigrid::Multigrid(Comm* comm, const Interface* interface)
46{
47 Index points, remainder;
48 LocalIndices local_l;
49 std::vector<GlobalIndices> global_separated;
50
51 const std::vector<GlobalIndices>& global = interface->Global();
52 const std::vector<SpatialExtent>& extent = interface->Extent();
53
54 comm->GetDomainDecomposition().Compute(comm, interface, global_separated);
55
56 for (unsigned int i=0; i<global.size(); ++i) {
57
58 /*
59 * Check if this level is the finest global level
60 */
61 if (global[i].BoundaryType() == GlobalMax)
62 levelGlobalMax = interface->MaxLevel() - i;
63
64
65 if (global_separated[i].LocalSize().Product() > 0) {
66
67 /*
68 * Initialize some properties with zero
69 */
70 local_l.HaloBegin1() = 0;
71 local_l.HaloEnd1() = 0;
72 local_l.HaloBegin2() = 0;
73 local_l.HaloEnd2() = 0;
74 local_l.BoundaryBegin1() = 0;
75 local_l.BoundaryEnd1() = 0;
76 local_l.BoundaryBegin2() = 0;
77 local_l.BoundaryEnd2() = 0;
78
79 /*
80 * Set boundary dependant properties
81 */
82 for (int j=0; j<3; ++j) {
83
84 if (comm->BoundaryConditions()[j] == Dirichlet ||
85 comm->BoundaryConditions()[j] == Open) {
86
87 local_l.SizeTotal()[j] = global_separated[i].LocalSize()[j] +
88 (global_separated[i].BoundaryType() == LocallyRefined ? 2 : 0);
89
90 /*
91 * We have a boundary at the ends of the process grids
92 * and halo grid points otherwise
93 */
94 if (global_separated[i].LocalBegin()[j] == 0) {
95 local_l.BoundaryBegin1()[j] = 0;
96 local_l.BoundaryEnd1()[j] = 1;
97 }else {
98 ++local_l.SizeTotal()[j];
99 local_l.HaloBegin1()[j] = 0;
100 local_l.HaloEnd1()[j] = 1;
101 }
102
103 if (global_separated[i].LocalEnd()[j] == global_separated[i].GlobalSize()[j]) {
104 local_l.BoundaryBegin2()[j] = local_l.SizeTotal()[j] - 1;
105 local_l.BoundaryEnd2()[j] = local_l.SizeTotal()[j];
106 }else {
107 ++local_l.SizeTotal()[j];
108 local_l.HaloBegin2()[j] = local_l.SizeTotal()[j] - 1;
109 local_l.HaloEnd2()[j] = local_l.SizeTotal()[j];
110 }
111
112 }else if (comm->BoundaryConditions()[j] == Periodic) {
113
114 local_l.SizeTotal()[j] = global_separated[i].LocalSize()[j] + 2;
115
116 /*
117 * No boundary
118 */
119 local_l.BoundaryBegin1()[j] = local_l.BoundaryEnd1()[j] = 0;
120 local_l.BoundaryBegin2()[j] = local_l.BoundaryEnd2()[j] = 0;
121
122 /*
123 * Halo grid points on all processes
124 */
125 local_l.HaloBegin1()[j] = 0;
126 local_l.HaloEnd1()[j] = 1;
127 local_l.HaloBegin2()[j] = local_l.SizeTotal()[j] - 1;
128 local_l.HaloEnd2()[j] = local_l.SizeTotal()[j];
129
130 }
131
132 }
133
134 local_l.Begin() = 1;
135 local_l.End() = local_l.SizeTotal() - 1;
136
137 local_l.Size() = local_l.End() - local_l.Begin();
138 local_l.HaloSize1() = local_l.HaloEnd1() - local_l.HaloBegin1();
139 local_l.HaloSize2() = local_l.HaloEnd2() - local_l.HaloBegin2();
140 local_l.BoundarySize1() = local_l.BoundaryEnd1() - local_l.BoundaryBegin1();
141 local_l.BoundarySize2() = local_l.BoundaryEnd2() - local_l.BoundaryBegin2();
142
143 local_l.FinerSize() = global_separated[i].LocalFinerSize() - local_l.BoundarySize1() - local_l.BoundarySize2();
144 local_l.FinerBegin() = global_separated[i].LocalFinerBegin() - global_separated[i].LocalBegin() + local_l.Begin();
145 local_l.FinerEnd() = local_l.FinerBegin() + local_l.FinerSize();
146
147
148 }else {
149
150 local_l.Begin() = 0;
151 local_l.End() = 0;
152 local_l.Size() = 0;
153 local_l.SizeTotal() = 0;
154 local_l.HaloBegin1() = 0;
155 local_l.HaloEnd1() = 0;
156 local_l.HaloSize1() = 0;
157 local_l.HaloBegin2() = 0;
158 local_l.HaloEnd2() = 0;
159 local_l.HaloSize2() = 0;
160 local_l.BoundaryBegin1() = 0;
161 local_l.BoundaryEnd1() = 0;
162 local_l.BoundarySize1() = 0;
163 local_l.BoundaryBegin2() = 0;
164 local_l.BoundaryEnd2() = 0;
165 local_l.BoundarySize2() = 0;
166 local_l.FinerBegin() = 0;
167 local_l.FinerEnd() = 0;
168 local_l.FinerSize() = 0;
169
170 }
171
172 grids.push_back(new Grid(global_separated[i], local_l, extent[i], interface->MaxLevel()-i, this));
173
174 }
175
176 numLevels = grids.size();
177
178 levelMax = interface->MaxLevel();
179 levelMin = levelMax - numLevels + 1;
180
181 levelIndex = 0;
182 levelCurrent = levelMax;
183
184}
185
186void Multigrid::SetLevel(int level)
187{
188 assert(level >= levelMin && level <= levelMax);
189 levelCurrent = level;
190 levelIndex = levelMax - level;
191}
192
193void Multigrid::ToCoarserLevel()
194{
195 assert(levelCurrent-1 >= levelMin);
196 --levelCurrent;
197 ++levelIndex;
198}
199
200void Multigrid::ToFinerLevel()
201{
202 assert(levelCurrent+1 <= levelMax);
203 ++levelCurrent;
204 --levelIndex;
205}
206
207void Multigrid::ClearAll()
208{
209 for (int i=MinLevel(); i<=MaxLevel(); ++i)
210 (*this)(i).Clear();
211}
212
213// TODO: diff that in case that breaks QP
214void Multigrid::ClearAllCoarseLevels()
215{
216 for (int i=MinLevel(); i<MaxLevel(); ++i)
217 (*this)(i).Clear();
218}
219
220
221void Multigrid::SetCoarserDirichletValues()
222{
223 Index i_c, i_f;
224
225 for (int i=GlobalMaxLevel(); i>MinLevel(); --i) {
226
227 Grid& grid_f = (*this)(i);
228 Grid& grid_c = (*this)(i-1);
229
230 i_c.X() = grid_c.Local().BoundaryBegin1().X();
231 i_f.X() = grid_f.Local().BoundaryBegin1().X();
232 for (i_c.Y()=grid_c.Local().Begin().Y(); i_c.Y()<grid_c.Local().End().Y(); ++i_c.Y())
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(i_f.X(), 2*i_c.Y(), 2*i_c.Z());
235
236 i_c.X() = grid_c.Local().BoundaryBegin2().X();
237 i_f.X() = grid_f.Local().BoundaryBegin2().X();
238 for (i_c.Y()=grid_c.Local().Begin().Y(); i_c.Y()<grid_c.Local().End().Y(); ++i_c.Y())
239 for (i_c.Z()=grid_c.Local().Begin().Z(); i_c.Z()<grid_c.Local().End().Z(); ++i_c.Z())
240 grid_c(i_c) = grid_f.GetVal(i_f.X(), 2*i_c.Y(), 2*i_c.Z());
241
242 i_c.Y() = grid_c.Local().BoundaryBegin1().Y();
243 i_f.Y() = grid_f.Local().BoundaryBegin1().Y();
244 for (i_c.X()=0; i_c.X()<grid_c.Local().SizeTotal().X(); ++i_c.X())
245 for (i_c.Z()=grid_c.Local().Begin().Z(); i_c.Z()<grid_c.Local().End().Z(); ++i_c.Z())
246 grid_c(i_c) = grid_f.GetVal(2*i_c.X(), i_f.Y(), 2*i_c.Z());
247
248 i_c.Y() = grid_c.Local().BoundaryBegin2().Y();
249 i_f.Y() = grid_f.Local().BoundaryBegin2().Y();
250 for (i_c.X()=0; i_c.X()<grid_c.Local().SizeTotal().X(); ++i_c.X())
251 for (i_c.Z()=grid_c.Local().Begin().Z(); i_c.Z()<grid_c.Local().End().Z(); ++i_c.Z())
252 grid_c(i_c) = grid_f.GetVal(2*i_c.X(), i_f.Y(), 2*i_c.Z());
253
254 i_c.Z() = grid_c.Local().BoundaryBegin1().Z();
255 i_f.Z() = grid_f.Local().BoundaryBegin1().Z();
256 for (i_c.X()=0; i_c.X()<grid_c.Local().SizeTotal().X(); ++i_c.X())
257 for (i_c.Y()=0; i_c.Y()<grid_c.Local().SizeTotal().Y(); ++i_c.Y())
258 grid_c(i_c) = grid_f.GetVal(2*i_c.X(), 2*i_c.Y(), i_f.Z());
259
260 i_c.Z() = grid_c.Local().BoundaryBegin2().Z();
261 i_f.Z() = grid_f.Local().BoundaryBegin2().Z();
262 for (i_c.X()=0; i_c.X()<grid_c.Local().SizeTotal().X(); ++i_c.X())
263 for (i_c.Y()=0; i_c.Y()<grid_c.Local().SizeTotal().Y(); ++i_c.Y())
264 grid_c(i_c) = grid_f.GetVal(2*i_c.X(), 2*i_c.Y(), i_f.Z());
265
266 }
267}
268
269Multigrid::~Multigrid()
270{
271 for (unsigned int i=0; i<grids.size(); ++i)
272 delete grids[i];
273}
Note: See TracBrowser for help on using the repository browser.