/*
* vmg - a versatile multigrid solver
* Copyright (C) 2012 Institute for Numerical Simulation, University of Bonn
*
* vmg is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* vmg is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see .
*/
/**
* @file jacobi.hpp
* @author Julian Iseringhausen
* @date Fri Apr 27 19:50:36 2012
*
* @brief Jacobi smoother
*
*/
#ifdef HAVE_CONFIG_H
#include
#endif
#ifdef HAVE_MPI
#include
#endif
#include "base/discretization.hpp"
#include "base/stencil.hpp"
#include "comm/comm.hpp"
#include "grid/grid.hpp"
#include "grid/tempgrid.hpp"
#include "smoother/jacobi.hpp"
#include "mg.hpp"
using namespace VMG;
static inline void ComputePartial(Grid& sol_new, const Grid& sol_old, const Grid& rhs,
const Stencil& mat, const GridIteratorSet& bounds,
const vmg_float& prefactor, const vmg_float& diag_inv)
{
Grid::iterator grid_iter;
Stencil::iterator stencil_iter;
for (grid_iter=bounds.Begin(); grid_iter!=bounds.End(); ++grid_iter) {
sol_new(*grid_iter) = prefactor * rhs.GetVal(*grid_iter);
for (stencil_iter=mat.begin(); stencil_iter!=mat.end(); ++stencil_iter)
sol_new(*grid_iter) -= stencil_iter->Val() * sol_old.GetVal(*grid_iter + stencil_iter->Disp());
sol_new(*grid_iter) *= diag_inv;
}
}
void Jacobi::Compute(Grid& sol, Grid& rhs)
{
Comm& comm = *MG::GetComm();
TempGrid& sol_new = *MG::GetTempGrid();
const Stencil& mat = MG::GetDiscretization()->GetStencil();
const vmg_float prefactor_inv = 1.0 / MG::GetDiscretization()->OperatorPrefactor(sol);
const vmg_float diag_inv = 1.0 / mat.GetDiag();
sol_new.SetProperties(sol);
comm.CommToGhostsAsyncStart(sol);
ComputePartial(sol_new, sol, rhs, mat, sol.Iterators().InnerLocalGrid(), prefactor_inv, diag_inv);
comm.CommToGhostsAsyncFinish(sol);
for (int i=0; i<3; ++i) {
ComputePartial(sol_new, sol, rhs, mat, sol.Iterators().NearBoundary1()[i], prefactor_inv, diag_inv);
ComputePartial(sol_new, sol, rhs, mat, sol.Iterators().NearBoundary2()[i], prefactor_inv, diag_inv);
}
sol.SetGrid(sol_new);
}