source: src/grid/multigrid.cpp@ f57182

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

Open boundary conditions.

Conflicts:

lib/vmg/src/Makefile.am
lib/vmg/src/base/factory.cpp
lib/vmg/test/unit_test/library/dirichlet_fas_lr_mpi.cpp

  • Property mode set to 100644
File size: 8.0 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
89 /*
90 * We have a boundary at the ends of the process grids
91 * and halo grid points otherwise
92 */
93 if (global_separated[i].LocalBegin()[j] == 0) {
94 local_l.BoundaryBegin1()[j] = 0;
95 local_l.BoundaryEnd1()[j] = 1;
96 }else {
97 ++local_l.SizeTotal()[j];
98 local_l.HaloBegin1()[j] = 0;
99 local_l.HaloEnd1()[j] = 1;
100 }
101
102 if (global_separated[i].LocalEnd()[j] == global_separated[i].GlobalSize()[j]) {
103 local_l.BoundaryBegin2()[j] = local_l.SizeTotal()[j] - 1;
104 local_l.BoundaryEnd2()[j] = local_l.SizeTotal()[j];
105 }else {
106 ++local_l.SizeTotal()[j];
107 local_l.HaloBegin2()[j] = local_l.SizeTotal()[j] - 1;
108 local_l.HaloEnd2()[j] = local_l.SizeTotal()[j];
109 }
110
111 }else if (comm->BoundaryConditions()[j] == Periodic) {
112
113 local_l.SizeTotal()[j] = global_separated[i].LocalSize()[j] + 2;
114
115 /*
116 * No boundary
117 */
118 local_l.BoundaryBegin1()[j] = local_l.BoundaryEnd1()[j] = 0;
119 local_l.BoundaryBegin2()[j] = local_l.BoundaryEnd2()[j] = 0;
120
121 /*
122 * Halo grid points on all processes
123 */
124 local_l.HaloBegin1()[j] = 0;
125 local_l.HaloEnd1()[j] = 1;
126 local_l.HaloBegin2()[j] = local_l.SizeTotal()[j] - 1;
127 local_l.HaloEnd2()[j] = local_l.SizeTotal()[j];
128
129 }
130
131 }
132
133 local_l.Begin() = 1;
134 local_l.End() = local_l.SizeTotal() - 1;
135
136 local_l.Size() = local_l.End() - local_l.Begin();
137 local_l.HaloSize1() = local_l.HaloEnd1() - local_l.HaloBegin1();
138 local_l.HaloSize2() = local_l.HaloEnd2() - local_l.HaloBegin2();
139 local_l.BoundarySize1() = local_l.BoundaryEnd1() - local_l.BoundaryBegin1();
140 local_l.BoundarySize2() = local_l.BoundaryEnd2() - local_l.BoundaryBegin2();
141
142 local_l.FinerSize() = global_separated[i].LocalFinerSize();
143 local_l.FinerBegin() = global_separated[i].LocalFinerBegin() - global_separated[i].LocalBegin() + local_l.HaloSize1();
144 local_l.FinerEnd() = local_l.FinerBegin() + local_l.FinerSize();
145
146
147 }else {
148
149 local_l.Begin() = 0;
150 local_l.End() = 0;
151 local_l.Size() = 0;
152 local_l.SizeTotal() = 0;
153 local_l.HaloBegin1() = 0;
154 local_l.HaloEnd1() = 0;
155 local_l.HaloSize1() = 0;
156 local_l.HaloBegin2() = 0;
157 local_l.HaloEnd2() = 0;
158 local_l.HaloSize2() = 0;
159 local_l.BoundaryBegin1() = 0;
160 local_l.BoundaryEnd1() = 0;
161 local_l.BoundarySize1() = 0;
162 local_l.BoundaryBegin2() = 0;
163 local_l.BoundaryEnd2() = 0;
164 local_l.BoundarySize2() = 0;
165 local_l.FinerBegin() = 0;
166 local_l.FinerEnd() = 0;
167 local_l.FinerSize() = 0;
168
169 }
170
171 grids.push_back(new Grid(global_separated[i], local_l, extent[i], interface->MaxLevel()-i, this));
172
173 }
174
175 numLevels = grids.size();
176
177 levelMax = interface->MaxLevel();
178 levelMin = levelMax - numLevels + 1;
179
180 levelIndex = 0;
181 levelCurrent = levelMax;
182
183}
184
185void Multigrid::SetLevel(int level)
186{
187 assert(level >= levelMin && level <= levelMax);
188 levelCurrent = level;
189 levelIndex = levelMax - level;
190}
191
192void Multigrid::ToCoarserLevel()
193{
194 assert(levelCurrent-1 >= levelMin);
195 --levelCurrent;
196 ++levelIndex;
197}
198
199void Multigrid::ToFinerLevel()
200{
201 assert(levelCurrent+1 <= levelMax);
202 ++levelCurrent;
203 --levelIndex;
204}
205
206void Multigrid::ClearAll()
207{
208 for (int i=MinLevel(); i<=MaxLevel(); ++i)
209 (*this)(i).Clear();
210}
211
212// TODO: diff that in case that breaks QP
213void Multigrid::ClearAllCoarseLevels()
214{
215 for (int i=MinLevel(); i<MaxLevel(); ++i)
216 (*this)(i).Clear();
217}
218
219
220void Multigrid::SetCoarserDirichletValues()
221{
222 Index i_c, i_f;
223
224 for (int i=GlobalMaxLevel(); i>MinLevel(); --i) {
225
226 Grid& grid_f = (*this)(i);
227 Grid& grid_c = (*this)(i-1);
228
229 i_c.X() = grid_c.Local().BoundaryBegin1().X();
230 i_f.X() = grid_f.Local().BoundaryBegin1().X();
231 for (i_c.Y()=grid_c.Local().Begin().Y(); i_c.Y()<grid_c.Local().End().Y(); ++i_c.Y())
232 for (i_c.Z()=grid_c.Local().Begin().Z(); i_c.Z()<grid_c.Local().End().Z(); ++i_c.Z())
233 grid_c(i_c) = grid_f.GetVal(i_f.X(), 2*i_c.Y(), 2*i_c.Z());
234
235 i_c.X() = grid_c.Local().BoundaryBegin2().X();
236 i_f.X() = grid_f.Local().BoundaryBegin2().X();
237 for (i_c.Y()=grid_c.Local().Begin().Y(); i_c.Y()<grid_c.Local().End().Y(); ++i_c.Y())
238 for (i_c.Z()=grid_c.Local().Begin().Z(); i_c.Z()<grid_c.Local().End().Z(); ++i_c.Z())
239 grid_c(i_c) = grid_f.GetVal(i_f.X(), 2*i_c.Y(), 2*i_c.Z());
240
241 i_c.Y() = grid_c.Local().BoundaryBegin1().Y();
242 i_f.Y() = grid_f.Local().BoundaryBegin1().Y();
243 for (i_c.X()=0; i_c.X()<grid_c.Local().SizeTotal().X(); ++i_c.X())
244 for (i_c.Z()=grid_c.Local().Begin().Z(); i_c.Z()<grid_c.Local().End().Z(); ++i_c.Z())
245 grid_c(i_c) = grid_f.GetVal(2*i_c.X(), i_f.Y(), 2*i_c.Z());
246
247 i_c.Y() = grid_c.Local().BoundaryBegin2().Y();
248 i_f.Y() = grid_f.Local().BoundaryBegin2().Y();
249 for (i_c.X()=0; i_c.X()<grid_c.Local().SizeTotal().X(); ++i_c.X())
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(2*i_c.X(), i_f.Y(), 2*i_c.Z());
252
253 i_c.Z() = grid_c.Local().BoundaryBegin1().Z();
254 i_f.Z() = grid_f.Local().BoundaryBegin1().Z();
255 for (i_c.X()=0; i_c.X()<grid_c.Local().SizeTotal().X(); ++i_c.X())
256 for (i_c.Y()=0; i_c.Y()<grid_c.Local().SizeTotal().Y(); ++i_c.Y())
257 grid_c(i_c) = grid_f.GetVal(2*i_c.X(), 2*i_c.Y(), i_f.Z());
258
259 i_c.Z() = grid_c.Local().BoundaryBegin2().Z();
260 i_f.Z() = grid_f.Local().BoundaryBegin2().Z();
261 for (i_c.X()=0; i_c.X()<grid_c.Local().SizeTotal().X(); ++i_c.X())
262 for (i_c.Y()=0; i_c.Y()<grid_c.Local().SizeTotal().Y(); ++i_c.Y())
263 grid_c(i_c) = grid_f.GetVal(2*i_c.X(), 2*i_c.Y(), i_f.Z());
264
265 }
266}
267
268Multigrid::~Multigrid()
269{
270 for (unsigned int i=0; i<grids.size(); ++i)
271 delete grids[i];
272}
Note: See TracBrowser for help on using the repository browser.