//#####################################################################
// Copyright 2002-2006, Ronald Fedkiw, Geoffrey Irving, Frank Losasso, Andrew Selle, Tamar Shinar.
// This file is part of PhysBAM whose distribution is governed by the license contained in the accompanying file PHYSBAM_COPYRIGHT.txt.
//#####################################################################
// Class BOUNDARY_PERIODIC
//#####################################################################
#include <Core/Boundaries/BOUNDARY_PERIODIC.h>
#include <Core/Arrays/ARRAY.h>
#include <Core/Arrays/FACE_ARRAYS.h>
#include <Core/Boundaries/PERIODIC_BOUNDARY_HELPER.h>
#include <Core/Grids/CELL_ITERATOR.h>
#include <Core/Grids/FACE_ITERATOR.h>
#include <Core/Grids/GRID.h>
#include <Core/Grids/NODE_ITERATOR.h>
#include <Core/Matrices/MATRIX.h>
#include <Core/Matrices/SYMMETRIC_MATRIX.h>
namespace PhysBAM{
//#####################################################################
// Function Apply_Boundary_Condition_Face
//#####################################################################
template<class TV,class T2> void BOUNDARY_PERIODIC<TV,T2>::
Apply_Boundary_Condition_Face(const GRID<TV>& grid,ARRAY<T2,FACE_INDEX<TV::m> >& u) const
{
    typedef VECTOR<int,TV::m> IV;
    IV periods=grid.numbers_of_cells;
    for(int axis=0;axis<TV::m;axis++){
        if(!is_periodic(axis)) continue;
        for(FACE_ITERATOR<TV> it(grid,0,BOUNDARY_REGION,2*axis,axis);it.Valid();it.Next()){
            FACE_INDEX<TV::m> face(it.Full_Index());
            face.index(axis)+=periods(axis);
            u(face)=u(it.Full_Index());}}
}
//#####################################################################
// Function Fill_Ghost_Cells
//#####################################################################
template<class TV,class T2> void BOUNDARY_PERIODIC<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
    Fill_Ghost_Cells_Periodic(grid,u_ghost,is_periodic);
}
//#####################################################################
// Function Fill_Ghost_Faces
//#####################################################################
template<class TV,class T2> void BOUNDARY_PERIODIC<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
{
    ARRAY<T2,FACE_INDEX<TV::m> >::Put(u,u_ghost); // interior
    Fill_Ghost_Faces_Periodic(grid,u_ghost,is_periodic);
}
//#####################################################################
template class BOUNDARY_PERIODIC<VECTOR<float,2>,VECTOR<float,3> >;
template class BOUNDARY_PERIODIC<VECTOR<float,3>,VECTOR<float,3> >;
template class BOUNDARY_PERIODIC<VECTOR<float,2>,VECTOR<float,2> >;
template class BOUNDARY_PERIODIC<VECTOR<double,2>,MATRIX<double,2> >;
template class BOUNDARY_PERIODIC<VECTOR<double,2>,SYMMETRIC_MATRIX<double,2> >;
template class BOUNDARY_PERIODIC<VECTOR<double,2>,VECTOR<double,3> >;
template class BOUNDARY_PERIODIC<VECTOR<double,3>,VECTOR<double,3> >;
template class BOUNDARY_PERIODIC<VECTOR<double,2>,VECTOR<double,2> >;
template class BOUNDARY_PERIODIC<VECTOR<double,1>,double>;
template class BOUNDARY_PERIODIC<VECTOR<double,2>,double>;
template class BOUNDARY_PERIODIC<VECTOR<double,2>,int>;
template class BOUNDARY_PERIODIC<VECTOR<double,3>,MATRIX<double,3> >;
template class BOUNDARY_PERIODIC<VECTOR<double,3>,SYMMETRIC_MATRIX<double,3> >;
template class BOUNDARY_PERIODIC<VECTOR<double,3>,double>;
template class BOUNDARY_PERIODIC<VECTOR<double,3>,int>;
template class BOUNDARY_PERIODIC<VECTOR<float,2>,MATRIX<float,2> >;
template class BOUNDARY_PERIODIC<VECTOR<float,2>,SYMMETRIC_MATRIX<float,2> >;
template class BOUNDARY_PERIODIC<VECTOR<float,2>,float>;
template class BOUNDARY_PERIODIC<VECTOR<float,2>,int>;
template class BOUNDARY_PERIODIC<VECTOR<float,3>,MATRIX<float,3> >;
template class BOUNDARY_PERIODIC<VECTOR<float,3>,SYMMETRIC_MATRIX<float,3> >;
template class BOUNDARY_PERIODIC<VECTOR<float,3>,float>;
template class BOUNDARY_PERIODIC<VECTOR<float,3>,int>;
}
