//#####################################################################
// Copyright 2021, Craig Schroeder.
// This file is part of PhysBAM whose distribution is governed by the license contained in the accompanying file PHYSBAM_COPYRIGHT.txt.
//#####################################################################
#ifndef __GENERAL_INTERPOLATION_NODE_DEFINITION__
#define __GENERAL_INTERPOLATION_NODE_DEFINITION__

#include <Core/Arrays/ARRAY.h>
#include <Core/Arrays/ARRAYS_ND.h>
#include <Core/Arrays/FACE_ARRAYS.h>
#include <Core/Interpolation/GENERAL_INTERPOLATION_HELPERS.h>
#include <Core/Interpolation/GENERAL_INTERPOLATION_NODE.h>
#include <Core/Interpolation/INTERPOLATION_HELPERS.h>
#include <Core/Interpolation/INTERPOLATION_NODE.h>
#include <Core/Log/DEBUG_UTILITIES.h>
namespace PhysBAM{

//#####################################################################
// Function Interpolate_Node
//#####################################################################
template<class TV,class T2,class STENCIL,bool const_extrap> auto
GENERAL_INTERPOLATION_NODE<TV,T2,STENCIL,const_extrap>::
Interpolate_Node(const GRID<TV>& grid,const ARRAYS_ND_BASE<T2,IV>& u,const TV& X) const -> T2
{
    auto p=INTERPOLATION_HELPERS::Clamped_Index<ss,const_extrap>(grid,at_nodes,u.domain,X);
    return Interpolate<-1>(stencil,grid,u,p);
}
//#####################################################################
// Function Extrema_Node
//#####################################################################
template<class TV,class T2,class STENCIL,bool const_extrap> auto
GENERAL_INTERPOLATION_NODE<TV,T2,STENCIL,const_extrap>::
Extrema_Node(const GRID<TV>& grid,const ARRAYS_ND_BASE<T2,IV>& u0,const ARRAYS_ND_BASE<T2,IV>& u1,const TV& X) const -> VECTOR<T2,2>
{
    auto p=INTERPOLATION_HELPERS::Clamped_Index<ss,const_extrap>(grid,at_nodes,u0.domain,X);
    return Extrema<ss,-1>(grid,u0,u1,p);
}
//#####################################################################
// Function Gradient_Node
//#####################################################################
template<class TV,class T2,class STENCIL,bool const_extrap> auto
GENERAL_INTERPOLATION_NODE<TV,T2,STENCIL,const_extrap>::
Gradient_Node(const GRID<TV>& grid,const ARRAYS_ND_BASE<T2,IV>& u,const TV& X) const -> TV2
{
    auto p=INTERPOLATION_HELPERS::Clamped_Index<ss,const_extrap>(grid,at_nodes,u.domain,X);
    return Gradient<-1>(stencil,grid,u,p);
}
//#####################################################################
// Function Hessian_Node
//#####################################################################
template<class TV,class T2,class STENCIL,bool const_extrap> auto
GENERAL_INTERPOLATION_NODE<TV,T2,STENCIL,const_extrap>::
Hessian_Node(const GRID<TV>& grid,const ARRAYS_ND_BASE<T2,IV>& u,const TV& X) const -> SM2
{
    auto p=INTERPOLATION_HELPERS::Clamped_Index<ss,const_extrap>(grid,at_nodes,u.domain,X);
    return Hessian<-1>(stencil,grid,u,p);
}
//#####################################################################
// Function Interpolate_Node_V
//#####################################################################
template<class TV,class T2,class STENCIL,bool const_extrap> auto
GENERAL_INTERPOLATION_NODE<TV,T2,STENCIL,const_extrap>::
Interpolate_Node_V(const GRID<TV>& grid,const ARRAYS_ND_BASE<T2,IV>& u,const TV& X) const -> T2
{
    return Interpolate_Node(grid,u,X);
}
//#####################################################################
// Function Extrema_Node_V
//#####################################################################
template<class TV,class T2,class STENCIL,bool const_extrap> auto
GENERAL_INTERPOLATION_NODE<TV,T2,STENCIL,const_extrap>::
Extrema_Node_V(const GRID<TV>& grid,const ARRAYS_ND_BASE<T2,IV>& u0,const ARRAYS_ND_BASE<T2,IV>& u1,const TV& X) const -> VECTOR<T2,2>
{
    return Extrema_Node(grid,u0,u1,X);
}
//#####################################################################
// Function Gradient_Node_V
//#####################################################################
template<class TV,class T2,class STENCIL,bool const_extrap> auto
GENERAL_INTERPOLATION_NODE<TV,T2,STENCIL,const_extrap>::
Gradient_Node_V(const GRID<TV>& grid,const ARRAYS_ND_BASE<T2,IV>& u,const TV& X) const -> TV2
{
    return Gradient_Node(grid,u,X);
}
//#####################################################################
// Function Hessian_Node_V
//#####################################################################
template<class TV,class T2,class STENCIL,bool const_extrap> auto
GENERAL_INTERPOLATION_NODE<TV,T2,STENCIL,const_extrap>::
Hessian_Node_V(const GRID<TV>& grid,const ARRAYS_ND_BASE<T2,IV>& u,const TV& X) const -> SM2
{
    return Hessian_Node(grid,u,X);
}
//#####################################################################
}
#endif
