source: src/grid/grid.cpp@ d13e27

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

vmg: Work on output verbosity.

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

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