source: ThirdParty/vmg/src/grid/grid.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.8 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 grid.cpp
21 * @author Julian Iseringhausen <isering@ins.uni-bonn.de>
22 * @date Mon Apr 18 12:53:27 2011
23 *
24 * @brief VMG::Grid
25 *
26 */
27
28#ifdef HAVE_CONFIG_H
29#include <libvmg_config.h>
30#endif
31
32#include <cstdio>
33#include <cmath>
34#include <limits>
35
36#include "base/helper.hpp"
37#include "base/stencil.hpp"
38#include "comm/comm.hpp"
39#include "grid/grid.hpp"
40#include "grid/tempgrid.hpp"
41#include "mg.hpp"
42
43using namespace VMG;
44
45void Grid::InitGrid()
46{
47 grid = new vmg_float[local.SizeTotal().Product()];
48}
49
50Grid::~Grid()
51{
52 delete [] grid;
53}
54
55Grid& Grid::operator=(const Grid& rhs)
56{
57 if (this != &rhs) {
58
59 global = rhs.Global();
60 local = rhs.Local();
61 extent = rhs.Extent();
62 iterators = rhs.Iterators();
63 father = rhs.Father();
64 level = rhs.Level();
65
66 delete [] grid;
67 grid = new vmg_float[local.SizeTotal().Product()];
68
69 SetGrid(rhs);
70
71 }
72
73 return *this;
74}
75
76void Grid::Clear()
77{
78 for (int i=0; i<local.SizeTotal().Product(); ++i)
79 grid[i] = 0.0;
80}
81
82void Grid::ClearInner()
83{
84 for (Grid::iterator iter=Iterators().Local().Begin(); iter!=Iterators().Local().End(); ++iter)
85 (*this)(*iter) = 0.0;
86}
87
88void Grid::ClearHalo()
89{
90 Grid::iterator iter;
91
92 for (int i=0; i<3; ++i) {
93
94 for (iter = Iterators().Halo1()[i].Begin(); iter != Iterators().Halo1()[i].End(); ++iter)
95 (*this)(*iter) = 0.0;
96
97 for (iter = Iterators().Halo2()[i].Begin(); iter != Iterators().Halo2()[i].End(); ++iter)
98 (*this)(*iter) = 0.0;
99
100 }
101
102}
103
104void Grid::ClearBoundary()
105{
106 Grid::iterator iter;
107
108 for (int i=0; i<3; ++i) {
109
110 for (iter = Iterators().Boundary1()[i].Begin(); iter != Iterators().Boundary1()[i].End(); ++iter)
111 (*this)(*iter) = 0.0;
112
113 for (iter = Iterators().Boundary2()[i].Begin(); iter != Iterators().Boundary2()[i].End(); ++iter)
114 (*this)(*iter) = 0.0;
115
116 }
117
118}
119
120void Grid::SetAverageToZero()
121{
122 Grid::iterator iter;
123 vmg_float avg = 0.0;
124
125 for (iter = Iterators().Local().Begin(); iter != Iterators().Local().End(); ++iter)
126 avg += GetVal(*iter);
127
128 avg = MG::GetComm()->GlobalSum(avg) / Global().GlobalSize().Product();
129
130 MG::GetComm()->PrintOnce(Info, "Global constraint enforcement: %e", avg);
131
132 if (std::abs(avg) > std::numeric_limits<vmg_float>::epsilon())
133 for (iter = Iterators().Local().Begin(); iter != Iterators().Local().End(); ++iter)
134 (*this)(*iter) -= avg;
135}
136
137void Grid::ForceDiscreteCompatibilityCondition()
138{
139 Grid::iterator iter;
140 vmg_float val = 0.0;
141
142 for (iter = Iterators().Local().Begin(); iter != Iterators().Local().End(); ++iter)
143 val += GetVal(*iter);
144
145 val = MG::GetComm()->GlobalSum(val) / Global().GlobalSize().Product();
146
147 if (std::abs(val) > std::numeric_limits<vmg_float>::epsilon()) {
148
149 MG::GetComm()->PrintOnce(Info, "Right hand side does not satisfy the compatibility condition. Trying to enforce.");
150
151 for (iter = Iterators().Local().Begin(); iter != Iterators().Local().End(); ++iter)
152 (*this)(*iter) -= val;
153
154#ifdef OUPUT_DEBUG
155 val = 0.0;
156 for (iter = Iterators().Local().Begin(); iter != Iterators().Local().End(); ++iter)
157 val += GetVal(*iter);
158 val = MG::GetComm()->GlobalSumRoot(val);
159 MG::GetComm()->PrintOnce(Debug, "Sum of grid charges after forcing the discrete compatibility condition: %e", val);
160#endif
161 }
162}
163
164void Grid::SetGrid(const Grid& rhs)
165{
166#ifdef DEBUG
167 IsCompatible(rhs);
168#endif
169
170 std::memcpy(grid, rhs.grid, local.SizeTotal().Product()*sizeof(vmg_float));
171}
172
173void Grid::SetBoundary(const Grid& rhs)
174{
175#ifdef DEBUG
176 IsCompatible(rhs);
177#endif
178 Grid::iterator iter;
179
180 for (int i=0; i<3; ++i) {
181
182 for (iter = Iterators().Boundary1()[i].Begin(); iter != Iterators().Boundary1()[i].End(); ++iter)
183 (*this)(*iter) = rhs.GetVal(*iter);
184
185 for (iter = Iterators().Boundary2()[i].Begin(); iter != Iterators().Boundary2()[i].End(); ++iter)
186 (*this)(*iter) = rhs.GetVal(*iter);
187
188 }
189}
190
191void Grid::AddGrid(const Grid& rhs)
192{
193#ifdef DEBUG_MATRIX_CHECKS
194 IsCompatible(rhs);
195#endif
196
197 for (Grid::iterator iter = Iterators().CompleteGrid().Begin(); iter != Iterators().CompleteGrid().End(); ++iter)
198 (*this)(*iter) += rhs.GetVal(*iter);
199}
200
201void Grid::SubtractGrid(const Grid& rhs)
202{
203#ifdef DEBUG_MATRIX_CHECKS
204 IsCompatible(rhs);
205#endif
206
207 for (Grid::iterator iter = Iterators().CompleteGrid().Begin(); iter != Iterators().CompleteGrid().End(); ++iter)
208 (*this)(*iter) -= rhs.GetVal(*iter);
209}
210
211void Grid::MultiplyScalar(const vmg_float& scalar)
212{
213 for (Grid::iterator iter = Iterators().CompleteGrid().Begin(); iter != Iterators().CompleteGrid().End(); ++iter)
214 (*this)(*iter) *= scalar;
215}
216
217void Grid::ApplyStencil(const Stencil& stencil)
218{
219 Grid::iterator grid_iter;
220 Stencil::iterator stencil_iter;
221 TempGrid *temp = MG::GetTempGrid();
222
223 temp->SetProperties(*this);
224 temp->SetGrid(*this);
225 MG::GetComm()->CommToGhosts(*temp);
226
227 for (grid_iter = Iterators().Local().Begin(); grid_iter != Iterators().Local().End(); ++grid_iter) {
228
229 (*this)(*grid_iter) = stencil.GetDiag() * temp->GetVal(*grid_iter);
230
231 for (stencil_iter=stencil.begin(); stencil_iter!=stencil.end(); ++stencil_iter)
232 (*this)(*grid_iter) += stencil_iter->Val() * temp->GetVal(*grid_iter + stencil_iter->Disp());
233 }
234}
235
236bool Grid::IsCompatible(const Grid& rhs) const
237{
238 bool eq = true;
239
240 eq &= Helper::IsEq(Local().Begin(), rhs.Local().Begin(), "Local().Begin");
241 eq &= Helper::IsEq(Local().End(), rhs.Local().End(), "Local().End");
242 eq &= Helper::IsEq(Local().Size(), rhs.Local().Size(), "Local().Size");
243 eq &= Helper::IsEq(Local().SizeTotal(), rhs.Local().SizeTotal(), "Local().SizeTotal");
244
245 eq &= Helper::IsEq(Global().LocalBegin(), rhs.Global().LocalBegin(), "Global().LocalBegin");
246 eq &= Helper::IsEq(Global().LocalEnd(), rhs.Global().LocalEnd(), "Global().LocalEnd");
247 eq &= Helper::IsEq(Global().LocalSize(), rhs.Global().LocalSize(), "Global().LocalSize");
248 eq &= Helper::IsEq(Global().GlobalSizeFinest(), rhs.Global().GlobalSizeFinest(), "Global().GlobalSizeFinest");
249
250
251 eq &= Helper::IsEq(Local().HaloBegin1(), rhs.Local().HaloBegin1(), "Local().HaloBegin1");
252 eq &= Helper::IsEq(Local().HaloBegin2(), rhs.Local().HaloBegin2(), "Local().HaloBegin2");
253 eq &= Helper::IsEq(Local().HaloEnd1(), rhs.Local().HaloEnd1(), "Local().HaloEnd1");
254 eq &= Helper::IsEq(Local().HaloEnd2(), rhs.Local().HaloEnd2(), "Local().HaloEnd2");
255
256 eq &= Helper::IsEq(Extent().MeshWidth(), rhs.Extent().MeshWidth(), "MeshWidth");
257
258 return eq;
259}
260
261bool Grid::IsConsistent() const
262{
263 bool consistent = true;
264
265 for (Grid::iterator iter=Iterators().Local().Begin(); iter!=Iterators().Local().End(); ++iter)
266 consistent &= Helper::CheckNumber(GetVal(*iter));
267
268 return consistent;
269}
270
271Vector Grid::GetSpatialPos(const Index& index_local) const
272{
273 return Extent().Begin() + Extent().MeshWidth() * (index_local - Local().HaloSize1() + Global().LocalBegin() - Global().GlobalBegin());
274}
275
276Vector Grid::GetSpatialPosGlobal(const Index& index_global) const
277{
278 return Extent().Begin() + Extent().MeshWidth() * (index_global - Global().GlobalBegin());
279}
280
281
282Index Grid::GetGlobalIndex(const Vector& pos) const
283{
284 const Index index = (pos - Extent().Begin()) / Extent().MeshWidth() + 0.5;
285 return index + (Global().BoundaryType() == LocallyRefined ? 1 : 0);
286}
287
Note: See TracBrowser for help on using the repository browser.