/*
* 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 is_grid.hpp
* @author Julian Iseringhausen
* @date Mon Apr 18 12:53:45 2011
*
* @brief Grid-like class that holds arbitrary data.
*
*/
#ifndef IS_GRID_HPP_
#define IS_GRID_HPP_
#include "base/object.hpp"
#include "grid/grid.hpp"
#include "grid/grid_iterator.hpp"
#include "grid/grid_iterator_suite.hpp"
#include "grid/grid_properties.hpp"
namespace VMG
{
class Comm;
class Grid;
class Multigrid;
class Stencil;
template
class IsGrid
{
public:
typedef GridIterator iterator;
IsGrid(int level = 0) :
level(level)
{
grid = NULL;
}
IsGrid(const GlobalIndices& global,
const LocalIndices& local,
const SpatialExtent& extent,
int level = 0) :
level(level),
global(global),
local(local),
extent(extent),
iterators(local)
{
InitIsGrid();
}
IsGrid(const IsGrid& rhs) :
level(rhs.Level()),
global(rhs.Global()),
local(rhs.Local()),
extent(rhs.Extent()),
iterators(rhs.Iterators())
{
InitIsGrid();
SetGrid(rhs);
}
IsGrid(const Grid& rhs) :
level(rhs.Level()),
global(rhs.Global()),
local(rhs.Local()),
extent(rhs.Extent()),
iterators(rhs.Iterators())
{
InitIsGrid();
}
virtual ~IsGrid();
void SetGridSize(const Grid& grid);
void SetGridSize(const GlobalIndices& global,
const LocalIndices& local,
const SpatialExtent& extent);
IsGrid& operator=(const IsGrid& rhs);
const GlobalIndices& Global() const {return global;}
const LocalIndices& Local() const {return local;}
const SpatialExtent& Extent() const {return extent;}
GlobalIndices& Global() {return global;}
LocalIndices& Local() {return local;}
SpatialExtent& Extent() {return extent;}
GridIteratorSuite& Iterators() {return iterators;}
const GridIteratorSuite& Iterators() const {return iterators;}
const vmg_float& MeshWidth() const {return Extent().MeshWidth().X();} ///< Mesh width of current level
T& operator()(int x, int y, int z); ///< Returns a reference to the requested gridpoint.
T& operator()(const Index& index);
const T& GetVal(int x, int y, int z) const; ///< Returns the value of a requested gridpoint.
const T& GetVal(const Index& index) const;
void SetGrid(const IsGrid& rhs); ///< Overwrite current grid with values from another grid
void SetBoundary(const IsGrid& rhs); ///< Overwrite boundary with values from rhs
int GlobalLinearIndex(int x, int y, int z) const; ///< Compute a unique 1-dimensional global index
int GlobalLinearIndex(const Index& index) const;
const int& Level() const {return level;}
bool IsActive() const {return Local().Size().Product() > 0;}
private:
void InitIsGrid();
protected:
int level;
GlobalIndices global;
LocalIndices local;
SpatialExtent extent;
GridIteratorSuite iterators;
T* grid;
static vmg_float correction;
};
template
inline T& IsGrid::operator()(int x, int y, int z)
{
return grid[z + local.SizeTotal().Z() * (y + local.SizeTotal().Y() * x)];
}
template
inline T& IsGrid::operator()(const Index& index)
{
return this->operator()(index.X(), index.Y(), index.Z());
}
template
inline const T& IsGrid::GetVal(int x, int y, int z) const
{
return grid[z + local.SizeTotal().Z() * (y + local.SizeTotal().Y() * x)];
}
template
inline const T& IsGrid::GetVal(const Index& index) const
{
return this->GetVal(index.X(), index.Y(), index.Z());
}
template
inline int IsGrid::GlobalLinearIndex(int x, int y, int z) const
{
return z + global.GlobalSize().Z() * (y + global.GlobalSize().Y() * x);
}
template
inline int IsGrid::GlobalLinearIndex(const Index& index) const
{
return index.Z() + global.GlobalSize().Z() * (index.Y() + global.GlobalSize().Y() * index.X());
}
template
void IsGrid::InitIsGrid()
{
grid = new T[local.SizeTotal().Product()];
}
template
IsGrid::~IsGrid()
{
delete [] grid;
}
template
void IsGrid::SetGridSize(const Grid& rhs)
{
global = rhs.Global();
local = rhs.Local();
extent = rhs.Extent();
iterators = rhs.Iterators();
level = rhs.Level();
delete [] grid;
grid = new T[local.SizeTotal().Product()];
}
template
void IsGrid::SetGridSize(const GlobalIndices& global_,
const LocalIndices& local_,
const SpatialExtent& extent_)
{
global = global_;
local = local_;
extent = extent_;
iterators.SetSubgrids(local);
level = 0;
delete [] grid;
grid = new T[local.SizeTotal().Product()];
}
template
IsGrid& IsGrid::operator=(const IsGrid& rhs)
{
if (this != &rhs) {
global = rhs.Global();
local = rhs.Local();
extent = rhs.Extent();
iterators = rhs.Iterators();
level = rhs.Level();
delete [] grid;
grid = new T[local.SizeTotal().Product()];
SetGrid(rhs);
}
return *this;
}
template
void IsGrid::SetGrid(const IsGrid& rhs)
{
for (typename IsGrid::iterator iter = Iterators().CompleteGrid().Begin(); iter != Iterators().CompleteGrid().End(); ++iter)
(*this)(*iter) = rhs.GetVal(*iter);
}
template
void IsGrid::SetBoundary(const IsGrid& rhs)
{
typename IsGrid::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);
}
}
}
#endif /* GRID_HPP_ */