source: ThirdParty/vmg/src/grid/multigrid.cpp@ 775f3f

Adding_MD_integration_tests Adding_StructOpt_integration_tests AutomationFragmentation_failures Candidate_v1.6.1 ChemicalSpaceEvaluator Enhanced_StructuralOptimization Enhanced_StructuralOptimization_continued Exclude_Hydrogens_annealWithBondGraph ForceAnnealing_with_BondGraph ForceAnnealing_with_BondGraph_contraction-expansion Gui_displays_atomic_force_velocity JobMarket_RobustOnKillsSegFaults JobMarket_StableWorkerPool PythonUI_with_named_parameters StoppableMakroAction TremoloParser_IncreasedPrecision
Last change on this file since 775f3f was 7faa5c, checked in by Frederik Heber <heber@…>, 8 years ago

Merge commit 'de061d9d851257a04e924d4472df4523d33bb08b' as 'ThirdParty/vmg'

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