/** * @file grid.cpp * @author Julian Iseringhausen * @date Mon Apr 18 12:53:27 2011 * * @brief VMG::Grid * */ #ifdef HAVE_CONFIG_H #include #endif #include #include #include #include "base/helper.hpp" #include "base/stencil.hpp" #include "comm/comm.hpp" #include "grid/grid.hpp" #include "grid/tempgrid.hpp" #include "mg.hpp" using namespace VMG; vmg_float Grid::correction; void Grid::InitGrid() { grid = new vmg_float[local.SizeTotal().Product()]; } Grid::~Grid() { delete [] grid; } Grid& Grid::operator=(const Grid& rhs) { if (this != &rhs) { global = rhs.Global(); local = rhs.Local(); extent = rhs.Extent(); iterators = rhs.Iterators(); father = rhs.Father(); index_translations = rhs.Indexing(); level = rhs.Level(); delete [] grid; grid = new vmg_float[local.SizeTotal().Product()]; SetGrid(rhs); } return *this; } void Grid::Clear() { for (int i=0; iGlobalSum(val); if (fabs(val) > Global().SizeGlobal().Product() * std::numeric_limits::epsilon()) { #ifdef DEBUG_OUTPUT MG::GetComm()->PrintStringOnce("WARNING: Right hand side does not satisfy the compatibility condition."); #endif val *= MeshWidth() * MeshWidth(); for (iter = Iterators().Local().Begin(); iter != Iterators().Local().End(); ++iter) (*this)(*iter) -= val; #ifdef DEBUG_OUTPUT val = 0.0; for (iter = Iterators().Local().Begin(); iter != Iterators().Local().End(); ++iter) val += GetVal(*iter); val = MG::GetComm()->GlobalSumRoot(val); MG::GetComm()->PrintStringOnce("Sum of grid charges after forcing the discrete compatibility condition: %e", val); #endif } } void Grid::SetGrid(const Grid& rhs) { #ifdef DEBUG IsCompatible(rhs); #endif for (Grid::iterator iter = Iterators().CompleteGrid().Begin(); iter != Iterators().CompleteGrid().End(); ++iter) (*this)(*iter) = rhs.GetVal(*iter); } void Grid::SetBoundary(const Grid& rhs) { #ifdef DEBUG IsCompatible(rhs); #endif Grid::iterator iter; for (int i=0; i<3; ++i) { for (iter = Iterators().Boundary1()[i].Begin(); iter != Iterators().Boundary1()[i].End(); ++iter) (*this)(*iter) = rhs.GetVal(*iter); for (iter = Iterators().Boundary2()[i].Begin(); iter != Iterators().Boundary2()[i].End(); ++iter) (*this)(*iter) = rhs.GetVal(*iter); } } void Grid::AddGrid(const Grid& rhs) { #ifdef DEBUG_MATRIX_CHECKS IsCompatible(rhs); #endif for (Grid::iterator iter = Iterators().CompleteGrid().Begin(); iter != Iterators().CompleteGrid().End(); ++iter) (*this)(*iter) += rhs.GetVal(*iter); } void Grid::SubtractGrid(const Grid& rhs) { #ifdef DEBUG_MATRIX_CHECKS IsCompatible(rhs); #endif for (Grid::iterator iter = Iterators().CompleteGrid().Begin(); iter != Iterators().CompleteGrid().End(); ++iter) (*this)(*iter) -= rhs.GetVal(*iter); } void Grid::MultiplyScalar(const vmg_float& scalar) { for (Grid::iterator iter = Iterators().CompleteGrid().Begin(); iter != Iterators().CompleteGrid().End(); ++iter) (*this)(*iter) *= scalar; } void Grid::ApplyStencil(const Stencil& stencil) { Grid::iterator grid_iter; Stencil::iterator stencil_iter; TempGrid *temp = MG::GetTempGrid(); temp->SetProperties(*this); temp->SetGrid(*this); MG::GetComm()->CommToGhosts(*temp); for (grid_iter = Iterators().Local().Begin(); grid_iter != Iterators().Local().End(); ++grid_iter) { (*this)(*grid_iter) = stencil.GetDiag() * temp->GetVal(*grid_iter); for (stencil_iter=stencil.begin(); stencil_iter!=stencil.end(); ++stencil_iter) (*this)(*grid_iter) += stencil_iter->Val() * temp->GetVal(*grid_iter + stencil_iter->Disp()); } } bool Grid::IsCompatible(const Grid& rhs) const { bool eq = true; eq &= Helper::IsEq(Local().Begin(), rhs.Local().Begin(), "Local().Begin"); eq &= Helper::IsEq(Local().End(), rhs.Local().End(), "Local().End"); eq &= Helper::IsEq(Local().Size(), rhs.Local().Size(), "Local().Size"); eq &= Helper::IsEq(Local().SizeTotal(), rhs.Local().SizeTotal(), "Local().SizeTotal"); eq &= Helper::IsEq(Global().BeginFinest(), rhs.Global().BeginFinest(), "Global().BeginFinest"); eq &= Helper::IsEq(Global().EndFinest(), rhs.Global().EndFinest(), "Global().EndFinest"); eq &= Helper::IsEq(Global().BeginLocal(), rhs.Global().BeginLocal(), "Global().BeginLocal"); eq &= Helper::IsEq(Global().EndLocal(), rhs.Global().EndLocal(), "Global().EndLocal"); eq &= Helper::IsEq(Global().SizeGlobal(), rhs.Global().SizeGlobal(), "Global().SizeGlobal"); eq &= Helper::IsEq(Global().SizeLocal(), rhs.Global().SizeLocal(), "Global().SizeLocal"); eq &= Helper::IsEq(Local().HaloBegin1(), rhs.Local().HaloBegin1(), "Local().HaloBegin1"); eq &= Helper::IsEq(Local().HaloBegin2(), rhs.Local().HaloBegin2(), "Local().HaloBegin2"); eq &= Helper::IsEq(Local().HaloEnd1(), rhs.Local().HaloEnd1(), "Local().HaloEnd1"); eq &= Helper::IsEq(Local().HaloEnd2(), rhs.Local().HaloEnd2(), "Local().HaloEnd2"); eq &= Helper::IsEq(MeshWidth(), rhs.MeshWidth(), "MeshWidth"); return eq; } bool Grid::IsConsistent() const { bool consistent = true; for (Grid::iterator iter=Iterators().CompleteGrid().Begin(); iter!=Iterators().CompleteGrid().End(); ++iter) consistent &= Helper::CheckNumber(GetVal(*iter)); return consistent; }