//#####################################################################
// Copyright 2002-2007, Ronald Fedkiw, Geoffrey Irving, Nipun Kwatra, Andrew Selle.
// This file is part of PhysBAM whose distribution is governed by the license contained in the accompanying file PHYSBAM_COPYRIGHT.txt.
//#####################################################################
// Class BOUNDARY_CUSTOM_FUNCTION
//#####################################################################
#include <Core/Boundaries/BOUNDARY_CUSTOM_FUNCTION.h>
#include <Core/Arrays/ARRAY.h>
#include <Core/Arrays/ARRAYS_ND_BASE.h>
#include <Core/Grids/CELL_ITERATOR.h>
#include <Core/Grids/FACE_ITERATOR.h>
#include <Core/Grids/NODE_ITERATOR.h>
#include <Core/Matrices/SYMMETRIC_MATRIX.h>
using namespace PhysBAM;

//#####################################################################
// Function Fill_Ghost_Cells
//#####################################################################
template<class TV,class T2> void BOUNDARY_CUSTOM_FUNCTION<TV,T2>::
Fill_Ghost_Cells(const GRID<TV>& grid,const ARRAYS_ND_BASE<T2,IV>& u,ARRAYS_ND_BASE<T2,IV>& u_ghost,const int number_of_ghost_cells) const
{
    ARRAYS_ND_BASE<T2,IV>::Put(u,u_ghost); // interior
    for(CELL_ITERATOR<TV> it(grid, number_of_ghost_cells, GHOST_REGION);it.Valid();it.Next())
        u_ghost(it.index)=F(it.Location());
}

//#####################################################################
// Function Fill_Ghost_Nodes
//#####################################################################
template<class TV,class T2> void BOUNDARY_CUSTOM_FUNCTION<TV,T2>::
Fill_Ghost_Nodes(const GRID<TV>& grid,const ARRAYS_ND_BASE<T2,IV>& u,ARRAYS_ND_BASE<T2,IV>& u_ghost,const int number_of_ghost_cells) const
{
    ARRAYS_ND_BASE<T2,IV>::Put(u,u_ghost); // interior
    for(NODE_ITERATOR<TV> it(grid, number_of_ghost_cells, GHOST_REGION);it.Valid();it.Next())
        u_ghost(it.index)=F(it.Location());
}

//#####################################################################
// Function Fill_Ghost_Faces
//#####################################################################
template<class TV,class T2> void BOUNDARY_CUSTOM_FUNCTION<TV,T2>::
Fill_Ghost_Faces(const GRID<TV>& grid,const ARRAY<T2,FACE_INDEX<TV::m> >& u,ARRAY<T2,FACE_INDEX<TV::m> >& u_ghost,const int number_of_ghost_cells) const
{
    //ARRAYS_ND_BASE<T2,FACE_INDEX<TV::m> >::Put(u,u_ghost); // doesn't work for face indexed arrays
    for(FACE_ITERATOR<TV> it(grid);it.Valid();it.Next())
        u_ghost(it.face)=u(it.face);
    for(FACE_ITERATOR<TV> it(grid, number_of_ghost_cells, GHOST_REGION);it.Valid();it.Next())
        u_ghost(it.face)=F(it.Location());
}

//#####################################################################
// Function Fill_Single_Ghost_Region_Node
//#####################################################################
template<class TV,class T2> void BOUNDARY_CUSTOM_FUNCTION<TV,T2>::
Fill_Single_Ghost_Region_Node(const GRID<TV>& grid,ARRAYS_ND_BASE<T2,IV>& u_ghost,const RANGE<IV>& region,const int side,const int number_of_ghost_cells) const
{
    for(NODE_ITERATOR<TV> it(grid,region);it.Valid();it.Next())
        u_ghost(it.index)=F(it.Location());
}

//#####################################################################
// Function Fill_Single_Ghost_Region_Cell
//#####################################################################
template<class TV,class T2> void BOUNDARY_CUSTOM_FUNCTION<TV,T2>::
Fill_Single_Ghost_Region_Cell(const GRID<TV>& grid,ARRAYS_ND_BASE<T2,IV>& u_ghost,const RANGE<IV>& region,const int side,const int number_of_ghost_cells) const
{
    for(CELL_ITERATOR<TV> it(grid, region);it.Valid();it.Next())
        u_ghost(it.index)=F(it.Location());
}
//#####################################################################
namespace PhysBAM{
template class BOUNDARY_CUSTOM_FUNCTION<VECTOR<float,1>,float>;
template class BOUNDARY_CUSTOM_FUNCTION<VECTOR<float,2>,float>;
template class BOUNDARY_CUSTOM_FUNCTION<VECTOR<float,3>,float>;
template class BOUNDARY_CUSTOM_FUNCTION<VECTOR<float,1>,SYMMETRIC_MATRIX<float,1> >;
template class BOUNDARY_CUSTOM_FUNCTION<VECTOR<float,2>,SYMMETRIC_MATRIX<float,2> >;
template class BOUNDARY_CUSTOM_FUNCTION<VECTOR<float,3>,SYMMETRIC_MATRIX<float,3> >;
template class BOUNDARY_CUSTOM_FUNCTION<VECTOR<double,1>,double>;
template class BOUNDARY_CUSTOM_FUNCTION<VECTOR<double,2>,double>;
template class BOUNDARY_CUSTOM_FUNCTION<VECTOR<double,3>,double>;
template class BOUNDARY_CUSTOM_FUNCTION<VECTOR<double,1>,SYMMETRIC_MATRIX<double,1> >;
template class BOUNDARY_CUSTOM_FUNCTION<VECTOR<double,2>,SYMMETRIC_MATRIX<double,2> >;
template class BOUNDARY_CUSTOM_FUNCTION<VECTOR<double,3>,SYMMETRIC_MATRIX<double,3> >;
}
