Commit d5f45d0b authored by Chris Cantwell's avatar Chris Cantwell
Browse files

Merge branch 'feature/3dh1dDiscontinuous' of /opt/gitlab/repositories/nektar

parents a03f2778 7b9e80c6
......@@ -868,6 +868,11 @@ namespace Nektar
return m_bndCondTraceToGlobalTraceMap[i];
}
const Array<OneD, const int> &AssemblyMap
::GetBndCondTraceToGlobalTraceMap()
{
return m_bndCondTraceToGlobalTraceMap;
}
NekDouble AssemblyMap::GetBndCondCoeffsToGlobalCoeffsSign(const int i)
{
......
......@@ -157,8 +157,10 @@ namespace Nektar
MULTI_REGIONS_EXPORT NekDouble GetBndCondCoeffsToGlobalCoeffsSign(const int i);
/// Returns the global index of the boundary trace giving the
/// index on the boundary expansion
/// index on the boundary expansion
MULTI_REGIONS_EXPORT int GetBndCondTraceToGlobalTraceMap(const int i);
MULTI_REGIONS_EXPORT const Array<OneD, const int>
&GetBndCondTraceToGlobalTraceMap();
/// Returns the number of global Dirichlet boundary coefficients.
MULTI_REGIONS_EXPORT int GetNumGlobalDirBndCoeffs() const;
......
......@@ -47,16 +47,19 @@ namespace Nektar
{
}
ContField3DHomogeneous1D::ContField3DHomogeneous1D(const ContField3DHomogeneous1D &In):
DisContField3DHomogeneous1D (In,false)
ContField3DHomogeneous1D::ContField3DHomogeneous1D(
const ContField3DHomogeneous1D &In):
DisContField3DHomogeneous1D (In,false)
{
bool False = false;
ContField2DSharedPtr zero_plane = boost::dynamic_pointer_cast<ContField2D> (In.m_planes[0]);
ContField2DSharedPtr zero_plane =
boost::dynamic_pointer_cast<ContField2D> (In.m_planes[0]);
for(int n = 0; n < m_planes.num_elements(); ++n)
{
m_planes[n] = MemoryManager<ContField2D>::AllocateSharedPtr(*zero_plane,False);
m_planes[n] = MemoryManager<ContField2D>::
AllocateSharedPtr(*zero_plane,False);
}
SetCoeffPhys();
......@@ -67,14 +70,14 @@ namespace Nektar
}
ContField3DHomogeneous1D::ContField3DHomogeneous1D(
const LibUtilities::SessionReaderSharedPtr &pSession,
const LibUtilities::BasisKey &HomoBasis,
const NekDouble lhom,
const bool useFFT,
const bool dealiasing,
const SpatialDomains::MeshGraphSharedPtr &graph2D,
const std::string &variable,
const bool CheckIfSingularSystem):
const LibUtilities::SessionReaderSharedPtr &pSession,
const LibUtilities::BasisKey &HomoBasis,
const NekDouble lhom,
const bool useFFT,
const bool dealiasing,
const SpatialDomains::MeshGraphSharedPtr &graph2D,
const std::string &variable,
const bool CheckIfSingularSystem):
DisContField3DHomogeneous1D(pSession,HomoBasis,lhom,useFFT,dealiasing)
{
int i,n,nel;
......@@ -82,7 +85,7 @@ namespace Nektar
ContField2DSharedPtr plane_two;
SpatialDomains::BoundaryConditions bcs(m_session, graph2D);
m_graph = graph2D;
m_graph = graph2D;
// Plane zero (k=0 - cos) - singularaty check required for Poisson
// problems
......@@ -128,7 +131,8 @@ namespace Nektar
nel = GetExpSize();
m_globalOptParam = MemoryManager<NekOptimize::GlobalOptParam>::AllocateSharedPtr(nel);
m_globalOptParam = MemoryManager<NekOptimize::GlobalOptParam>::
AllocateSharedPtr(nel);
SetCoeffPhys();
......@@ -136,7 +140,8 @@ namespace Nektar
}
void ContField3DHomogeneous1D::v_ImposeDirichletConditions(Array<OneD,NekDouble>& outarray)
void ContField3DHomogeneous1D::v_ImposeDirichletConditions(
Array<OneD,NekDouble>& outarray)
{
Array<OneD, NekDouble> tmp;
int ncoeffs = m_planes[0]->GetNcoeffs();
......@@ -215,13 +220,16 @@ namespace Nektar
}
else
{
HomogeneousFwdTrans(inarray,fce,(flags.isSet(eUseGlobal))?eGlobal:eLocal);
HomogeneousFwdTrans(inarray, fce,
(flags.isSet(eUseGlobal))?eGlobal:eLocal);
}
bool smode = false;
if (m_homogeneousBasis->GetBasisType() == LibUtilities::eFourierHalfModeRe ||
m_homogeneousBasis->GetBasisType() == LibUtilities::eFourierHalfModeIm )
if (m_homogeneousBasis->GetBasisType() ==
LibUtilities::eFourierHalfModeRe ||
m_homogeneousBasis->GetBasisType() ==
LibUtilities::eFourierHalfModeIm )
{
smode = true;
}
......@@ -233,11 +241,13 @@ namespace Nektar
beta = 2*M_PI*(m_transposition->GetK(n))/m_lhom;
new_factors = factors;
// add in Homogeneous Fourier direction and SVV if turned on
new_factors[StdRegions::eFactorLambda] += beta*beta*(1+GetSpecVanVisc(n));
new_factors[StdRegions::eFactorLambda] +=
beta*beta*(1+GetSpecVanVisc(n));
m_planes[n]->HelmSolve(fce + cnt,
e_out = outarray + cnt1,
flags, new_factors, varcoeff, dirForcing);
flags, new_factors, varcoeff,
dirForcing);
}
cnt += m_planes[n]->GetTotPoints();
......
......@@ -49,30 +49,35 @@ namespace Nektar
{
namespace MultiRegions
{
DisContField2D::DisContField2D(void):
ExpList2D (),
m_bndCondExpansions(),
m_bndConditions (),
m_trace (NullExpListSharedPtr)
DisContField2D::DisContField2D(void)
: ExpList2D (),
m_bndCondExpansions(),
m_bndConditions (),
m_trace (NullExpListSharedPtr)
{
}
DisContField2D::DisContField2D(
const DisContField2D &In,
const bool DeclareCoeffPhysArrays) :
ExpList2D (In,DeclareCoeffPhysArrays),
m_bndCondExpansions (In.m_bndCondExpansions),
m_bndConditions (In.m_bndConditions),
m_globalBndMat (In.m_globalBndMat),
m_trace (In.m_trace),
m_traceMap (In.m_traceMap),
m_boundaryEdges (In.m_boundaryEdges),
m_periodicVerts (In.m_periodicVerts),
m_periodicEdges (In.m_periodicEdges),
m_periodicFwdCopy (In.m_periodicFwdCopy),
m_periodicBwdCopy (In.m_periodicBwdCopy),
m_leftAdjacentEdges (In.m_leftAdjacentEdges)
const bool DeclareCoeffPhysArrays)
: ExpList2D (In,DeclareCoeffPhysArrays),
m_bndCondExpansions (In.m_bndCondExpansions),
m_bndConditions (In.m_bndConditions),
m_globalBndMat (In.m_globalBndMat),
m_traceMap (In.m_traceMap),
m_boundaryEdges (In.m_boundaryEdges),
m_periodicVerts (In.m_periodicVerts),
m_periodicEdges (In.m_periodicEdges),
m_periodicFwdCopy (In.m_periodicFwdCopy),
m_periodicBwdCopy (In.m_periodicBwdCopy),
m_leftAdjacentEdges (In.m_leftAdjacentEdges)
{
if (In.m_trace)
{
m_trace = MemoryManager<ExpList1D>::AllocateSharedPtr(
*boost::dynamic_pointer_cast<ExpList1D>(In.m_trace),
DeclareCoeffPhysArrays);
}
}
DisContField2D::DisContField2D(
......@@ -81,7 +86,7 @@ namespace Nektar
const std::string &variable,
const bool SetUpJustDG,
const bool DeclareCoeffPhysArrays)
: ExpList2D(pSession,graph2D,DeclareCoeffPhysArrays),
: ExpList2D(pSession, graph2D, DeclareCoeffPhysArrays),
m_bndCondExpansions(),
m_bndConditions(),
m_trace(NullExpListSharedPtr),
......@@ -112,9 +117,9 @@ namespace Nektar
else
{
// Set element edges to point to Robin BC edges if required.
int i,cnt;
Array<OneD, int> ElmtID,EdgeID;
GetBoundaryToElmtMap(ElmtID,EdgeID);
int i, cnt;
Array<OneD, int> ElmtID, EdgeID;
GetBoundaryToElmtMap(ElmtID, EdgeID);
for(cnt = i = 0; i < m_bndCondExpansions.num_elements(); ++i)
{
......@@ -124,26 +129,28 @@ namespace Nektar
for(e = 0; e < locExpList->GetExpSize(); ++e)
{
LocalRegions::Expansion2DSharedPtr exp2d
= boost::dynamic_pointer_cast<
LocalRegions::Expansion2DSharedPtr exp2d =
boost::dynamic_pointer_cast<
LocalRegions::Expansion2D>((*m_exp)[ElmtID[cnt+e]]);
LocalRegions::Expansion1DSharedPtr exp1d
= boost::dynamic_pointer_cast<
LocalRegions::Expansion1DSharedPtr exp1d =
boost::dynamic_pointer_cast<
LocalRegions::Expansion1D>(locExpList->GetExp(e));
LocalRegions::ExpansionSharedPtr exp
= boost::dynamic_pointer_cast<
LocalRegions::ExpansionSharedPtr exp =
boost::dynamic_pointer_cast<
LocalRegions::Expansion> (locExpList->GetExp(e));
exp2d->SetEdgeExp(EdgeID[cnt+e],exp);
exp1d->SetAdjacentElementExp(EdgeID[cnt+e],exp2d);
exp2d->SetEdgeExp(EdgeID[cnt+e], exp);
exp1d->SetAdjacentElementExp(EdgeID[cnt+e], exp2d);
}
cnt += m_bndCondExpansions[i]->GetExpSize();
}
if(m_session->DefinesSolverInfo("PROJECTION"))
{
std::string ProjectStr = m_session->GetSolverInfo("PROJECTION");
if((ProjectStr == "MixedCGDG")||(ProjectStr == "Mixed_CG_Discontinuous"))
std::string ProjectStr =
m_session->GetSolverInfo("PROJECTION");
if((ProjectStr == "MixedCGDG") ||
(ProjectStr == "Mixed_CG_Discontinuous"))
{
SetUpDG();
}
......@@ -167,13 +174,13 @@ namespace Nektar
const SpatialDomains::MeshGraphSharedPtr &graph2D,
const std::string &variable,
const bool SetUpJustDG,
const bool DeclareCoeffPhysArrays) :
ExpList2D(In,DeclareCoeffPhysArrays),
m_trace(NullExpListSharedPtr)
const bool DeclareCoeffPhysArrays)
: ExpList2D(In,DeclareCoeffPhysArrays),
m_trace(NullExpListSharedPtr)
{
// Set up boundary conditions for this variable.
SpatialDomains::BoundaryConditions bcs(m_session, graph2D);
GenerateBoundaryConditionExpansion(graph2D,bcs,variable);
GenerateBoundaryConditionExpansion(graph2D, bcs, variable);
if (DeclareCoeffPhysArrays)
{
......@@ -227,8 +234,11 @@ namespace Nektar
if(m_session->DefinesSolverInfo("PROJECTION"))
{
std::string ProjectStr = m_session->GetSolverInfo("PROJECTION");
if((ProjectStr == "MixedCGDG")||(ProjectStr == "Mixed_CG_Discontinuous"))
std::string ProjectStr =
m_session->GetSolverInfo("PROJECTION");
if((ProjectStr == "MixedCGDG") ||
(ProjectStr == "Mixed_CG_Discontinuous"))
{
SetUpDG();
}
......@@ -271,8 +281,8 @@ namespace Nektar
// set elmt edges to point to robin bc edges if required.
int i, cnt = 0;
Array<OneD, int> ElmtID,EdgeID;
GetBoundaryToElmtMap(ElmtID,EdgeID);
Array<OneD, int> ElmtID, EdgeID;
GetBoundaryToElmtMap(ElmtID, EdgeID);
for(i = 0; i < m_bndCondExpansions.num_elements(); ++i)
{
......@@ -312,7 +322,6 @@ namespace Nektar
*/
DisContField2D::~DisContField2D()
{
}
GlobalLinSysSharedPtr DisContField2D::GetGlobalBndLinSys(
......@@ -652,7 +661,7 @@ namespace Nektar
m_bndConditions[cnt] = bc;
SpatialDomains::BndUserDefinedType type =
m_bndConditions[cnt++]->GetUserDefined();
if (type == SpatialDomains::eI ||
if (type == SpatialDomains::eI ||
type == SpatialDomains::eCalcBC)
{
SetUpPhysNormals();
......@@ -953,7 +962,8 @@ namespace Nektar
c[1] = compMap[id2];
}
ASSERTL0(c[0] || c[1], "Both composites not found on this process!");
ASSERTL0(c[0] || c[1],
"Both composites not found on this process!");
// Loop over composite ordering to construct list of all
// periodic edges regardless of whether they are on this
......@@ -1575,7 +1585,8 @@ namespace Nektar
offset = GetCoeff_Offset(n);
for(e = 0; e < (*m_exp)[n]->GetNedges(); ++e)
{
t_offset = GetTrace()->GetPhys_Offset(elmtToTrace[n][e]->GetElmtId());
t_offset = GetTrace()->GetPhys_Offset(
elmtToTrace[n][e]->GetElmtId());
// Evaluate upwind flux less local edge
if(IsLeftAdjacentEdge(n,e))
......@@ -2148,7 +2159,8 @@ namespace Nektar
cout << "Boundary condition from file:"
<< filebcs << endl;
std::vector<LibUtilities::FieldDefinitionsSharedPtr> FieldDef;
std::vector<LibUtilities::FieldDefinitionsSharedPtr>
FieldDef;
std::vector<std::vector<NekDouble> > FieldData;
LibUtilities::FieldIO f(m_session->GetComm());
f.Import(filebcs,FieldDef, FieldData);
......@@ -2156,7 +2168,8 @@ namespace Nektar
// copy FieldData into locExpList
locExpList->ExtractDataToCoeffs(
FieldDef[0], FieldData[0],
FieldDef[0]->m_fields[0], locExpList->UpdateCoeffs());
FieldDef[0]->m_fields[0],
locExpList->UpdateCoeffs());
locExpList->BwdTrans_IterPerExp(
locExpList->GetCoeffs(),
locExpList->UpdatePhys());
......@@ -2196,7 +2209,8 @@ namespace Nektar
cout << "Boundary condition from file: "
<< filebcs << endl;
std::vector<LibUtilities::FieldDefinitionsSharedPtr> FieldDef;
std::vector<LibUtilities::FieldDefinitionsSharedPtr>
FieldDef;
std::vector<std::vector<NekDouble> > FieldData;
LibUtilities::FieldIO f(m_session->GetComm());
f.Import(filebcs,FieldDef, FieldData);
......@@ -2204,7 +2218,8 @@ namespace Nektar
// copy FieldData into locExpList
locExpList->ExtractDataToCoeffs(
FieldDef[0], FieldData[0],
FieldDef[0]->m_fields[0], locExpList->UpdateCoeffs());
FieldDef[0]->m_fields[0],
locExpList->UpdateCoeffs());
locExpList->BwdTrans_IterPerExp(
locExpList->GetCoeffs(),
locExpList->UpdatePhys());
......@@ -2250,7 +2265,8 @@ namespace Nektar
int len = var.length();
var = var.substr(len-1,len);
std::vector<LibUtilities::FieldDefinitionsSharedPtr> FieldDef;
std::vector<LibUtilities::FieldDefinitionsSharedPtr>
FieldDef;
std::vector<std::vector<NekDouble> > FieldData;
LibUtilities::FieldIO f(m_session->GetComm());
f.Import(filebcs,FieldDef, FieldData);
......@@ -2258,7 +2274,8 @@ namespace Nektar
// copy FieldData into locExpList
locExpList->ExtractDataToCoeffs(
FieldDef[0], FieldData[0],
FieldDef[0]->m_fields[0],locExpList->UpdateCoeffs());
FieldDef[0]->m_fields[0],
locExpList->UpdateCoeffs());
locExpList->BwdTrans_IterPerExp(
locExpList->GetCoeffs(),
locExpList->UpdatePhys());
......
......@@ -82,6 +82,17 @@ namespace Nektar
MULTI_REGIONS_EXPORT void EvaluateHDGPostProcessing(
Array<OneD, NekDouble> &outarray);
virtual ExpListSharedPtr &v_GetTrace()
{
if(m_trace == NullExpListSharedPtr)
{
SetUpDG();
}
return m_trace;
}
protected:
/**
......@@ -108,7 +119,7 @@ namespace Nektar
Array<OneD, Array<OneD, unsigned int> > m_mapEdgeToElmn;
Array<OneD, Array<OneD, unsigned int> > m_signEdgeToElmn;
Array<OneD,StdRegions::Orientation> m_edgedir;
Array<OneD,StdRegions::Orientation> m_edgedir;
/**
* @brief A set storing the global IDs of any boundary edges.
......@@ -205,16 +216,7 @@ namespace Nektar
periodicEdges = m_periodicEdges;
}
virtual ExpListSharedPtr &v_GetTrace()
{
if(m_trace == NullExpListSharedPtr)
{
SetUpDG();
}
return m_trace;
}
virtual AssemblyMapDGSharedPtr &v_GetTraceMap()
{
return m_traceMap;
......
......@@ -38,7 +38,13 @@
#define NEKTAR_LIBS_MULTIREGIONS_DISCONTFIELD3DHOMO1D_H
#include <MultiRegions/MultiRegionsDeclspec.h>
#include <MultiRegions/MultiRegions.hpp>
#include <MultiRegions/ExpList3DHomogeneous1D.h>
#include <MultiRegions/ExpList2D.h>
#include <MultiRegions/AssemblyMap/AssemblyMapDG.h>
#include <SpatialDomains/Conditions.h>
#include <MultiRegions/GlobalLinSys.h>
namespace Nektar
{
......@@ -50,93 +56,117 @@ namespace Nektar
MULTI_REGIONS_EXPORT DisContField3DHomogeneous1D();
MULTI_REGIONS_EXPORT DisContField3DHomogeneous1D(
const LibUtilities::SessionReaderSharedPtr &pSession,
const LibUtilities::BasisKey &HomoBasis,
const NekDouble lhom,
const bool useFFT,
const bool dealiasing);
const LibUtilities::SessionReaderSharedPtr &pSession,
const LibUtilities::BasisKey &HomoBasis,
const NekDouble lhom,
const bool useFFT,
const bool dealiasing);
MULTI_REGIONS_EXPORT DisContField3DHomogeneous1D(
const LibUtilities::SessionReaderSharedPtr &pSession,
const LibUtilities::BasisKey &HomoBasis,
const NekDouble lhom,
const bool useFFT,
const bool dealiasing,
const SpatialDomains::MeshGraphSharedPtr &graph2D,
const std::string &variable);
const LibUtilities::SessionReaderSharedPtr &pSession,
const LibUtilities::BasisKey &HomoBasis,
const NekDouble lhom,
const bool useFFT,
const bool dealiasing,
const SpatialDomains::MeshGraphSharedPtr &graph2D,
const std::string &variable);
/// Copy constructor.
MULTI_REGIONS_EXPORT DisContField3DHomogeneous1D(const DisContField3DHomogeneous1D &In,
const bool DeclarePlanesSetCoeffPhys = true);
MULTI_REGIONS_EXPORT DisContField3DHomogeneous1D(
const DisContField3DHomogeneous1D &In,
const bool DeclarePlanesSetCoeffPhys = true);
/// Destructor.
/// Destructor.
MULTI_REGIONS_EXPORT virtual ~DisContField3DHomogeneous1D();
MULTI_REGIONS_EXPORT void SetupBoundaryConditions(const LibUtilities::BasisKey &HomoBasis, const NekDouble lhom, SpatialDomains::BoundaryConditions &bcs, const std::string variable);
MULTI_REGIONS_EXPORT void SetupBoundaryConditions(
const LibUtilities::BasisKey &HomoBasis,
const NekDouble lhom,
SpatialDomains::BoundaryConditions &bcs,
const std::string variable);
/**
* \brief This function evaluates the boundary conditions at a certain
* time-level.
* \brief This function evaluates the boundary conditions
* at a certaintime-level.
*
* Based on the boundary condition \f$g(\boldsymbol{x},t)\f$ evaluated
* at a given time-level \a t, this function transforms the boundary
* conditions onto the coefficients of the (one-dimensional) boundary
* expansion. Depending on the type of boundary conditions, these
* expansion coefficients are calculated in different ways:
* Based on the boundary condition \f$g(\boldsymbol{x},t)\f$
* evaluated at a given time-level \a t, this function transforms
* the boundary conditions onto the coefficients of the
* (one-dimensional) boundary expansion.
* Depending on the type of boundary conditions, these expansion
* coefficients are calculated in different ways:
* - <b>Dirichlet boundary conditions</b><BR>
* In order to ensure global \f$C^0\f$ continuity of the spectral/hp
* approximation, the Dirichlet boundary conditions are projected onto
* the boundary expansion by means of a modified \f$C^0\f$ continuous
* Galerkin projection. This projection can be viewed as a collocation
* projection at the vertices, followed by an \f$L^2\f$ projection on
* the interior modes of the edges. The resulting coefficients
* \f$\boldsymbol{\hat{u}}^{\mathcal{D}}\f$ will be stored for the
* In order to ensure global \f$C^0\f$ continuity of the
* spectral/hp approximation, the Dirichlet boundary conditions
* are projected onto the boundary expansion by means of a
* modified \f$C^0\f$ continuous Galerkin projection.
* This projection can be viewed as a collocation projection at the
* vertices, followed by an \f$L^2\f$ projection on the interior
* modes of the edges. The resulting coefficients
* \f$\boldsymbol{\hat{u}}^{\mathcal{D}}\f$ will be stored for the
* boundary expansion.
* - <b>Neumann boundary conditions</b>
* In the discrete Galerkin formulation of the problem to be solved,
* the Neumann boundary conditions appear as the set of surface
* integrals: \f[\boldsymbol{\hat{g}}=\int_{\Gamma}
* In the discrete Galerkin formulation of the problem to be
* solved, the Neumann boundary conditions appear as the set of
* surface integrals: \f[\boldsymbol{\hat{g}}=\int_{\Gamma}
* \phi^e_n(\boldsymbol{x})g(\boldsymbol{x})d(\boldsymbol{x})\quad
* \forall n \f]
* As a result, it are the coefficients \f$\boldsymbol{\hat{g}}\f$
* As a result, it are the coefficients \f$\boldsymbol{\hat{g}}\f$
* that will be stored in the boundary expansion
*
* \param time The time at which the boundary conditions should be
* \param time The time at which the boundary conditions should be
* evaluated
*/
MULTI_REGIONS_EXPORT void EvaluateBoundaryConditions(const NekDouble time = 0.0);
inline const Array<OneD,const MultiRegions::ExpListSharedPtr> &GetBndCondExpansions();
inline const Array<OneD,const SpatialDomains::BoundaryConditionShPtr> &GetBndConditions();
*/
MULTI_REGIONS_EXPORT void EvaluateBoundaryConditions(
const NekDouble time = 0.0);
inline const Array<OneD,const MultiRegions::ExpListSharedPtr>
&GetBndCondExpansions();
inline const Array<OneD,const SpatialDomains::
BoundaryConditionShPtr> &GetBndConditions();
inline boost::shared_ptr<ExpList> &UpdateBndCondExpansion(int i);
inline Array<OneD, SpatialDomains::BoundaryConditionShPtr>& UpdateBndConditions();
inline Array<OneD, SpatialDomains::BoundaryConditionShPtr>&
UpdateBndConditions();
/// \brief Set up a list of element ids and edge ids the link to the
/// boundary conditions
MULTI_REGIONS_EXPORT void GetBoundaryToElmtMap(Array<OneD, int> &ElmtID,Array<OneD,int> &EdgeID);
MULTI_REGIONS_EXPORT void GetBoundaryToElmtMap(
Array<OneD, int> &ElmtID,
Array<OneD,int> &EdgeID);
/// This funtion extract form a vector containing a full
/// 3D-homogenous-1D field the value associated with a
/// specific boundary conditions.
/// TotField is the full field contaning all the physical values
/// BndVals is the vector where the boundary physical values are stored
/// BndID is the identifier of the boundary region
MULTI_REGIONS_EXPORT void GetBCValues(Array<OneD, NekDouble> &BndVals, const Array<OneD, NekDouble> &TotField, int BndID);
/// This function calculate the inner product of two vectors (V1 and V2)
/// respect to the basis along a boundary region.
/// outarray is the inner product result multiplied by the normal to the edge (specified by the BndID)
MULTI_REGIONS_EXPORT void NormVectorIProductWRTBase(Array<OneD, const NekDouble> &V1, Array<OneD, const NekDouble> &V2, Array<OneD, NekDouble> &outarray, int BndID);
/// Storage space for the boundary to element and boundary to trace map.
/// This member variable is really allocated just in case a boundary expansion
/// recasting is required at the solver level. Otherwise is the 2 vectors are not filled up.
/// If is needed all the funcitons whihc require to use this map do not have to recalculate it anymore.
/// BndVals is the vector where the boundary physical values are
/// stored BndID is the identifier of the boundary region
MULTI_REGIONS_EXPORT void GetBCValues(
Array<OneD, NekDouble> &BndVals,
const Array<OneD, NekDouble> &TotField,