/*
 *    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   stencils.hpp
 * @author Julian Iseringhausen 
 * @date   Mon Apr 18 13:06:11 2011
 *
 * @brief  Some examples for stencils.
 *
 */
#ifndef STENCILS_HPP_
#define STENCILS_HPP_
#include "base/stencil.hpp"
namespace VMG
{
class Injection : public Stencil
{
public:
  Injection() :
    Stencil(1.0)
  {}
};
class InterpolationTrilinear : public Stencil
{
public:
  InterpolationTrilinear() :
    Stencil(1.0)
  {
    this->push_back( 1,  0,  0, 0.5);
    this->push_back(-1,  0,  0, 0.5);
    this->push_back( 0,  1,  0, 0.5);
    this->push_back( 0, -1,  0, 0.5);
    this->push_back( 0,  0,  1, 0.5);
    this->push_back( 0,  0, -1, 0.5);
    this->push_back( 1,  1,  0, 0.25);
    this->push_back( 1, -1,  0, 0.25);
    this->push_back(-1,  1,  0, 0.25);
    this->push_back(-1, -1,  0, 0.25);
    this->push_back( 0,  1,  1, 0.25);
    this->push_back( 0,  1, -1, 0.25);
    this->push_back( 0, -1,  1, 0.25);
    this->push_back( 0, -1, -1, 0.25);
    this->push_back( 1,  0,  1, 0.25);
    this->push_back( 1,  0, -1, 0.25);
    this->push_back(-1,  0,  1, 0.25);
    this->push_back(-1,  0, -1, 0.25);
    this->push_back( 1,  1,  1, 0.125);
    this->push_back( 1,  1, -1, 0.125);
    this->push_back( 1, -1,  1, 0.125);
    this->push_back(-1,  1,  1, 0.125);
    this->push_back( 1, -1, -1, 0.125);
    this->push_back(-1,  1, -1, 0.125);
    this->push_back(-1, -1,  1, 0.125);
    this->push_back(-1, -1, -1, 0.125);
  }
};
class RestrictionFullWeight : public Stencil
{
public:
  RestrictionFullWeight() :
    Stencil(0.125)
  {
    this->push_back( 1,  0,  0, 0.0625);
    this->push_back(-1,  0,  0, 0.0625);
    this->push_back( 0,  1,  0, 0.0625);
    this->push_back( 0, -1,  0, 0.0625);
    this->push_back( 0,  0,  1, 0.0625);
    this->push_back( 0,  0, -1, 0.0625);
    this->push_back( 1,  1,  0, 0.03125);
    this->push_back( 1, -1,  0, 0.03125);
    this->push_back(-1,  1,  0, 0.03125);
    this->push_back(-1, -1,  0, 0.03125);
    this->push_back( 0,  1,  1, 0.03125);
    this->push_back( 0,  1, -1, 0.03125);
    this->push_back( 0, -1,  1, 0.03125);
    this->push_back( 0, -1, -1, 0.03125);
    this->push_back( 1,  0,  1, 0.03125);
    this->push_back( 1,  0, -1, 0.03125);
    this->push_back(-1,  0,  1, 0.03125);
    this->push_back(-1,  0, -1, 0.03125);
    this->push_back( 1,  1,  1, 0.015625);
    this->push_back( 1,  1, -1, 0.015625);
    this->push_back( 1, -1,  1, 0.015625);
    this->push_back(-1,  1,  1, 0.015625);
    this->push_back( 1, -1, -1, 0.015625);
    this->push_back(-1,  1, -1, 0.015625);
    this->push_back(-1, -1,  1, 0.015625);
    this->push_back(-1, -1, -1, 0.015625);
  }
};
namespace Stencils
{
  static const VMG::Stencil Injection = VMG::Injection();
  static const VMG::Stencil InterpolationTrilinear = VMG::InterpolationTrilinear();
  static const VMG::Stencil RestrictionFullWeight = VMG::RestrictionFullWeight();
}
}
#endif /* STENCILS_HPP_ */