Nektar++
Public Member Functions | Public Attributes | Protected Member Functions | Protected Attributes | Private Member Functions | Private Attributes | List of all members
Nektar::MultiRegions::DisContField Class Reference

This class is the abstractio n of a global discontinuous two- dimensional spectral/hp element expansion which approximates the solution of a set of partial differential equations. More...

#include <DisContField.h>

Inheritance diagram for Nektar::MultiRegions::DisContField:
[legend]

Public Member Functions

 DisContField ()
 Default constructor. More...
 
 DisContField (const LibUtilities::SessionReaderSharedPtr &pSession, const SpatialDomains::MeshGraphSharedPtr &graph, const std::string &variable, const bool SetUpJustDG=true, const bool DeclareCoeffPhysArrays=true, const Collections::ImplementationType ImpType=Collections::eNoImpType, const std::string bcvariable="NotSet")
 Constructs a 1D discontinuous field based on a mesh and boundary conditions. More...
 
 DisContField (const LibUtilities::SessionReaderSharedPtr &pSession, const SpatialDomains::MeshGraphSharedPtr &graph1D, const SpatialDomains::CompositeMap &domain, const SpatialDomains::BoundaryConditions &Allbcs, const std::string &variable, const LibUtilities::CommSharedPtr &comm, bool SetToOneSpaceDimensions=false, const Collections::ImplementationType ImpType=Collections::eNoImpType)
 Constructor for a DisContField from a List of subdomains New Constructor for arterial network. More...
 
 DisContField (const DisContField &In, const bool DeclareCoeffPhysArrays=true)
 Constructs a 1D discontinuous field based on an existing field. More...
 
 DisContField (const DisContField &In, const SpatialDomains::MeshGraphSharedPtr &graph, const std::string &variable, const bool SetUpJustDG=false, const bool DeclareCoeffPhysArrays=true)
 
 DisContField (const ExpList &In)
 Constructs a 1D discontinuous field based on an existing field. (needed in order to use ContField( const ExpList &In) constructor. More...
 
 ~DisContField () override
 Destructor. More...
 
GlobalLinSysSharedPtr GetGlobalBndLinSys (const GlobalLinSysKey &mkey)
 For a given key, returns the associated global linear system. More...
 
bool SameTypeOfBoundaryConditions (const DisContField &In)
 Check to see if expansion has the same BCs as In. More...
 
std::vector< bool > & GetNegatedFluxNormal (void)
 
NekDouble L2_DGDeriv (const int dir, const Array< OneD, const NekDouble > &coeffs, const Array< OneD, const NekDouble > &soln)
 Calculate the \( L^2 \) error of the \( Q_{\rm dir} \) derivative using the consistent DG evaluation of \( Q_{\rm dir} \). More...
 
void EvaluateHDGPostProcessing (const Array< OneD, const NekDouble > &coeffs, Array< OneD, NekDouble > &outarray)
 Evaluate HDG post-processing to increase polynomial order of solution. More...
 
void GetLocTraceToTraceMap (LocTraceToTraceMapSharedPtr &LocTraceToTraceMap)
 
void GetFwdBwdTracePhys (const Array< OneD, const NekDouble > &field, Array< OneD, NekDouble > &Fwd, Array< OneD, NekDouble > &Bwd, const Array< OneD, const SpatialDomains::BoundaryConditionShPtr > &bndCond, const Array< OneD, const ExpListSharedPtr > &BndCondExp)
 This method extracts the "forward" and "backward" trace data from the array field and puts the data into output vectors Fwd and Bwd. More...
 
- Public Member Functions inherited from Nektar::MultiRegions::ExpList
 ExpList (const ExpansionType Type=eNoType)
 The default constructor using a type. More...
 
 ExpList (const ExpList &in, const bool DeclareCoeffPhysArrays=true)
 The copy constructor. More...
 
 ExpList (const ExpList &in, const std::vector< unsigned int > &eIDs, const bool DeclareCoeffPhysArrays=true, const Collections::ImplementationType ImpType=Collections::eNoImpType)
 Constructor copying only elements defined in eIds. More...
 
 ExpList (const LibUtilities::SessionReaderSharedPtr &pSession, const SpatialDomains::MeshGraphSharedPtr &graph, const bool DeclareCoeffPhysArrays=true, const std::string &var="DefaultVar", const Collections::ImplementationType ImpType=Collections::eNoImpType)
 Generate an ExpList from a meshgraph graph and session file. More...
 
 ExpList (const LibUtilities::SessionReaderSharedPtr &pSession, const SpatialDomains::ExpansionInfoMap &expansions, const bool DeclareCoeffPhysArrays=true, const Collections::ImplementationType ImpType=Collections::eNoImpType)
 Sets up a list of local expansions based on an expansion Map. More...
 
 ExpList (const SpatialDomains::PointGeomSharedPtr &geom)
 Specialised constructors for 0D Expansions Wrapper around LocalRegion::PointExp - used in PrePacing.cpp. More...
 
 ExpList (const LibUtilities::SessionReaderSharedPtr &pSession, const Array< OneD, const ExpListSharedPtr > &bndConstraint, const Array< OneD, const SpatialDomains ::BoundaryConditionShPtr > &bndCond, const LocalRegions::ExpansionVector &locexp, const SpatialDomains::MeshGraphSharedPtr &graph, const LibUtilities::CommSharedPtr &comm, const bool DeclareCoeffPhysArrays=true, const std::string variable="DefaultVar", const Collections::ImplementationType ImpType=Collections::eNoImpType)
 Generate expansions for the trace space expansions used in DisContField. More...
 
 ExpList (const LibUtilities::SessionReaderSharedPtr &pSession, const LocalRegions::ExpansionVector &locexp, const SpatialDomains::MeshGraphSharedPtr &graph, const bool DeclareCoeffPhysArrays, const std::string variable, const Collections::ImplementationType ImpType=Collections::eNoImpType)
 Generate an trace ExpList from a meshgraph graph and session file. More...
 
 ExpList (const LibUtilities::SessionReaderSharedPtr &pSession, const SpatialDomains::CompositeMap &domain, const SpatialDomains::MeshGraphSharedPtr &graph, const bool DeclareCoeffPhysArrays=true, const std::string variable="DefaultVar", bool SetToOneSpaceDimension=false, const LibUtilities::CommSharedPtr comm=LibUtilities::CommSharedPtr(), const Collections::ImplementationType ImpType=Collections::eNoImpType)
 Constructor based on domain information only for 1D & 2D boundary conditions. More...
 
virtual ~ExpList ()
 The default destructor. More...
 
int GetNcoeffs (void) const
 Returns the total number of local degrees of freedom \(N_{\mathrm{eof}}=\sum_{e=1}^{{N_{\mathrm{el}}}}N^{e}_m\). More...
 
int GetNcoeffs (const int eid) const
 Returns the total number of local degrees of freedom for element eid. More...
 
ExpansionType GetExpType (void)
 Returns the type of the expansion. More...
 
void SetExpType (ExpansionType Type)
 Returns the type of the expansion. More...
 
int EvalBasisNumModesMax (void) const
 Evaulates the maximum number of modes in the elemental basis order over all elements. More...
 
const Array< OneD, int > EvalBasisNumModesMaxPerExp (void) const
 Returns the vector of the number of modes in the elemental basis order over all elements. More...
 
int GetTotPoints (void) const
 Returns the total number of quadrature points m_npoints \(=Q_{\mathrm{tot}}\). More...
 
int GetTotPoints (const int eid) const
 Returns the total number of quadrature points for eid's element \(=Q_{\mathrm{tot}}\). More...
 
int GetNpoints (void) const
 Returns the total number of quadrature points m_npoints \(=Q_{\mathrm{tot}}\). More...
 
int Get1DScaledTotPoints (const NekDouble scale) const
 Returns the total number of qudature points scaled by the factor scale on each 1D direction. More...
 
void SetWaveSpace (const bool wavespace)
 Sets the wave space to the one of the possible configuration true or false. More...
 
void SetModifiedBasis (const bool modbasis)
 Set Modified Basis for the stability analysis. More...
 
bool GetWaveSpace (void) const
 This function returns the third direction expansion condition, which can be in wave space (coefficient) or not It is stored in the variable m_WaveSpace. More...
 
void SetPhys (int i, NekDouble val)
 Set the i th value of m_phys to value val. More...
 
void SetPhys (const Array< OneD, const NekDouble > &inarray)
 Fills the array m_phys. More...
 
void SetPhysArray (Array< OneD, NekDouble > &inarray)
 Sets the array m_phys. More...
 
void SetPhysState (const bool physState)
 This function manually sets whether the array of physical values \(\boldsymbol{u}_l\) (implemented as m_phys) is filled or not. More...
 
bool GetPhysState (void) const
 This function indicates whether the array of physical values \(\boldsymbol{u}_l\) (implemented as m_phys) is filled or not. More...
 
void MultiplyByQuadratureMetric (const Array< OneD, const NekDouble > &inarray, Array< OneD, NekDouble > &outarray)
 multiply the metric jacobi and quadrature weights More...
 
void DivideByQuadratureMetric (const Array< OneD, const NekDouble > &inarray, Array< OneD, NekDouble > &outarray)
 Divided by the metric jacobi and quadrature weights. More...
 
void IProductWRTBase (const Array< OneD, const NekDouble > &inarray, Array< OneD, NekDouble > &outarray)
 This function calculates the inner product of a function \(f(\boldsymbol{x})\) with respect to all local expansion modes \(\phi_n^e(\boldsymbol{x})\). More...
 
void IProductWRTDerivBase (const int dir, const Array< OneD, const NekDouble > &inarray, Array< OneD, NekDouble > &outarray)
 This function calculates the inner product of a function \(f(\boldsymbol{x})\) with respect to the derivative (in direction. More...
 
void IProductWRTDirectionalDerivBase (const Array< OneD, const NekDouble > &direction, const Array< OneD, const NekDouble > &inarray, Array< OneD, NekDouble > &outarray)
 Directional derivative along a given direction. More...
 
void IProductWRTDerivBase (const Array< OneD, const Array< OneD, NekDouble > > &inarray, Array< OneD, NekDouble > &outarray)
 This function calculates the inner product of a function \(f(\boldsymbol{x})\) with respect to the derivative of all local expansion modes \(\phi_n^e(\boldsymbol{x})\). More...
 
void FwdTransLocalElmt (const Array< OneD, const NekDouble > &inarray, Array< OneD, NekDouble > &outarray)
 This function elementally evaluates the forward transformation of a function \(u(\boldsymbol{x})\) onto the global spectral/hp expansion. More...
 
void FwdTrans (const Array< OneD, const NekDouble > &inarray, Array< OneD, NekDouble > &outarray)
 
void ExponentialFilter (Array< OneD, NekDouble > &array, const NekDouble alpha, const NekDouble exponent, const NekDouble cutoff)
 
void MultiplyByElmtInvMass (const Array< OneD, const NekDouble > &inarray, Array< OneD, NekDouble > &outarray)
 This function elementally mulplies the coefficient space of Sin my the elemental inverse of the mass matrix. More...
 
void MultiplyByInvMassMatrix (const Array< OneD, const NekDouble > &inarray, Array< OneD, NekDouble > &outarray)
 
void MultiplyByMassMatrix (const Array< OneD, const NekDouble > &inarray, Array< OneD, NekDouble > &outarray)
 
void SmoothField (Array< OneD, NekDouble > &field)
 Smooth a field across elements. More...
 
GlobalLinSysKey HelmSolve (const Array< OneD, const NekDouble > &inarray, Array< OneD, NekDouble > &outarray, const StdRegions::ConstFactorMap &factors, const StdRegions::VarCoeffMap &varcoeff=StdRegions::NullVarCoeffMap, const MultiRegions::VarFactorsMap &varfactors=MultiRegions::NullVarFactorsMap, const Array< OneD, const NekDouble > &dirForcing=NullNekDouble1DArray, const bool PhysSpaceForcing=true)
 Solve helmholtz problem. More...
 
GlobalLinSysKey LinearAdvectionDiffusionReactionSolve (const Array< OneD, const NekDouble > &inarray, Array< OneD, NekDouble > &outarray, const StdRegions::ConstFactorMap &factors, const StdRegions::VarCoeffMap &varcoeff=StdRegions::NullVarCoeffMap, const MultiRegions::VarFactorsMap &varfactors=MultiRegions::NullVarFactorsMap, const Array< OneD, const NekDouble > &dirForcing=NullNekDouble1DArray, const bool PhysSpaceForcing=true)
 Solve Advection Diffusion Reaction. More...
 
void LinearAdvectionReactionSolve (const Array< OneD, Array< OneD, NekDouble > > &velocity, const Array< OneD, const NekDouble > &inarray, Array< OneD, NekDouble > &outarray, const NekDouble lambda, const Array< OneD, const NekDouble > &dirForcing=NullNekDouble1DArray)
 Solve Advection Diffusion Reaction. More...
 
void FwdTransBndConstrained (const Array< OneD, const NekDouble > &inarray, Array< OneD, NekDouble > &outarray)
 
void BwdTrans (const Array< OneD, const NekDouble > &inarray, Array< OneD, NekDouble > &outarray)
 This function elementally evaluates the backward transformation of the global spectral/hp element expansion. More...
 
void GetCoords (Array< OneD, NekDouble > &coord_0, Array< OneD, NekDouble > &coord_1=NullNekDouble1DArray, Array< OneD, NekDouble > &coord_2=NullNekDouble1DArray)
 This function calculates the coordinates of all the elemental quadrature points \(\boldsymbol{x}_i\). More...
 
void GetCoords (const int eid, Array< OneD, NekDouble > &coord_0, Array< OneD, NekDouble > &coord_1=NullNekDouble1DArray, Array< OneD, NekDouble > &coord_2=NullNekDouble1DArray)
 
void HomogeneousFwdTrans (const int npts, const Array< OneD, const NekDouble > &inarray, Array< OneD, NekDouble > &outarray, bool Shuff=true, bool UnShuff=true)
 
void HomogeneousBwdTrans (const int npts, const Array< OneD, const NekDouble > &inarray, Array< OneD, NekDouble > &outarray, bool Shuff=true, bool UnShuff=true)
 
void DealiasedProd (const int num_dofs, const Array< OneD, NekDouble > &inarray1, const Array< OneD, NekDouble > &inarray2, Array< OneD, NekDouble > &outarray)
 
void DealiasedDotProd (const int num_dofs, const Array< OneD, Array< OneD, NekDouble > > &inarray1, const Array< OneD, Array< OneD, NekDouble > > &inarray2, Array< OneD, Array< OneD, NekDouble > > &outarray)
 
void GetBCValues (Array< OneD, NekDouble > &BndVals, const Array< OneD, NekDouble > &TotField, int BndID)
 
void NormVectorIProductWRTBase (Array< OneD, const NekDouble > &V1, Array< OneD, const NekDouble > &V2, Array< OneD, NekDouble > &outarray, int BndID)
 
void NormVectorIProductWRTBase (Array< OneD, Array< OneD, NekDouble > > &V, Array< OneD, NekDouble > &outarray)
 
void ApplyGeomInfo ()
 Apply geometry information to each expansion. More...
 
void Reset ()
 Reset geometry information and reset matrices. More...
 
void WriteTecplotHeader (std::ostream &outfile, std::string var="")
 
void WriteTecplotZone (std::ostream &outfile, int expansion=-1)
 
void WriteTecplotField (std::ostream &outfile, int expansion=-1)
 
void WriteTecplotConnectivity (std::ostream &outfile, int expansion=-1)
 
void WriteVtkHeader (std::ostream &outfile)
 
void WriteVtkFooter (std::ostream &outfile)
 
void WriteVtkPieceHeader (std::ostream &outfile, int expansion, int istrip=0)
 
void WriteVtkPieceFooter (std::ostream &outfile, int expansion)
 
void WriteVtkPieceData (std::ostream &outfile, int expansion, std::string var="v")
 
int GetCoordim (int eid)
 This function returns the dimension of the coordinates of the element eid. More...
 
void SetCoeff (int i, NekDouble val)
 Set the i th coefficiient in m_coeffs to value val. More...
 
void SetCoeffs (int i, NekDouble val)
 Set the i th coefficiient in m_coeffs to value val. More...
 
void SetCoeffsArray (Array< OneD, NekDouble > &inarray)
 Set the m_coeffs array to inarray. More...
 
int GetShapeDimension ()
 This function returns the dimension of the shape of the element eid. More...
 
const Array< OneD, const NekDouble > & GetCoeffs () const
 This function returns (a reference to) the array \(\boldsymbol{\hat{u}}_l\) (implemented as m_coeffs) containing all local expansion coefficients. More...
 
void ImposeDirichletConditions (Array< OneD, NekDouble > &outarray)
 Impose Dirichlet Boundary Conditions onto Array. More...
 
void FillBndCondFromField (const Array< OneD, NekDouble > coeffs)
 Fill Bnd Condition expansion from the values stored in expansion. More...
 
void FillBndCondFromField (const int nreg, const Array< OneD, NekDouble > coeffs)
 Fill Bnd Condition expansion in nreg from the values stored in expansion. More...
 
void LocalToGlobal (bool useComm=true)
 Gathers the global coefficients \(\boldsymbol{\hat{u}}_g\) from the local coefficients \(\boldsymbol{\hat{u}}_l\). More...
 
void LocalToGlobal (const Array< OneD, const NekDouble > &inarray, Array< OneD, NekDouble > &outarray, bool useComm=true)
 
void GlobalToLocal (void)
 Scatters from the global coefficients \(\boldsymbol{\hat{u}}_g\) to the local coefficients \(\boldsymbol{\hat{u}}_l\). More...
 
void GlobalToLocal (const Array< OneD, const NekDouble > &inarray, Array< OneD, NekDouble > &outarray)
 
NekDouble GetCoeff (int i)
 Get the i th value (coefficient) of m_coeffs. More...
 
NekDouble GetCoeffs (int i)
 Get the i th value (coefficient) of m_coeffs. More...
 
const Array< OneD, const NekDouble > & GetPhys () const
 This function returns (a reference to) the array \(\boldsymbol{u}_l\) (implemented as m_phys) containing the function \(u^{\delta}(\boldsymbol{x})\) evaluated at the quadrature points. More...
 
NekDouble Linf (const Array< OneD, const NekDouble > &inarray, const Array< OneD, const NekDouble > &soln=NullNekDouble1DArray)
 This function calculates the \(L_\infty\) error of the global spectral/hp element approximation. More...
 
NekDouble L2 (const Array< OneD, const NekDouble > &inarray, const Array< OneD, const NekDouble > &soln=NullNekDouble1DArray)
 This function calculates the \(L_\infty\) error of the global This function calculates the \(L_2\) error with respect to soln of the global spectral/hp element approximation. More...
 
NekDouble H1 (const Array< OneD, const NekDouble > &inarray, const Array< OneD, const NekDouble > &soln=NullNekDouble1DArray)
 Calculates the \(H^1\) error of the global spectral/hp element approximation. More...
 
NekDouble Integral ()
 Calculates the \(H^1\) error of the global spectral/hp element approximation. More...
 
NekDouble Integral (const Array< OneD, const NekDouble > &inarray)
 
NekDouble VectorFlux (const Array< OneD, Array< OneD, NekDouble > > &inarray)
 
Array< OneD, const NekDoubleHomogeneousEnergy (void)
 This function calculates the energy associated with each one of the modesof a 3D homogeneous nD expansion. More...
 
void SetHomo1DSpecVanVisc (Array< OneD, NekDouble > visc)
 This function sets the Spectral Vanishing Viscosity in homogeneous1D expansion. More...
 
Array< OneD, const unsigned int > GetZIDs (void)
 This function returns a vector containing the wave numbers in z-direction associated with the 3D homogenous expansion. Required if a parellelisation is applied in the Fourier direction. More...
 
LibUtilities::TranspositionSharedPtr GetTransposition (void)
 This function returns the transposition class associated with the homogeneous expansion. More...
 
NekDouble GetHomoLen (void)
 This function returns the Width of homogeneous direction associated with the homogeneous expansion. More...
 
void SetHomoLen (const NekDouble lhom)
 This function sets the Width of homogeneous direction associated with the homogeneous expansion. More...
 
Array< OneD, const unsigned int > GetYIDs (void)
 This function returns a vector containing the wave numbers in y-direction associated with the 3D homogenous expansion. Required if a parellelisation is applied in the Fourier direction. More...
 
void PhysInterp1DScaled (const NekDouble scale, const Array< OneD, NekDouble > &inarray, Array< OneD, NekDouble > &outarray)
 This function interpolates the physical space points in inarray to outarray using the same points defined in the expansion but where the number of points are rescaled by 1DScale. More...
 
void PhysGalerkinProjection1DScaled (const NekDouble scale, const Array< OneD, NekDouble > &inarray, Array< OneD, NekDouble > &outarray)
 This function Galerkin projects the physical space points in inarray to outarray where inarray is assumed to be defined in the expansion but where the number of points are rescaled by 1DScale. More...
 
int GetExpSize (void)
 This function returns the number of elements in the expansion. More...
 
size_t GetNumElmts (void)
 This function returns the number of elements in the expansion which may be different for a homogeoenous extended expansionp. More...
 
const std::shared_ptr< LocalRegions::ExpansionVectorGetExp () const
 This function returns the vector of elements in the expansion. More...
 
LocalRegions::ExpansionSharedPtrGetExp (int n) const
 This function returns (a shared pointer to) the local elemental expansion of the \(n^{\mathrm{th}}\) element. More...
 
LocalRegions::ExpansionSharedPtrGetExpFromGeomId (int n)
 This function returns (a shared pointer to) the local elemental expansion of the \(n^{\mathrm{th}}\) element given a global geometry ID. More...
 
LocalRegions::ExpansionSharedPtrGetExp (const Array< OneD, const NekDouble > &gloCoord)
 This function returns (a shared pointer to) the local elemental expansion containing the arbitrary point given by gloCoord. More...
 
int GetExpIndex (const Array< OneD, const NekDouble > &gloCoord, NekDouble tol=0.0, bool returnNearestElmt=false, int cachedId=-1, NekDouble maxDistance=1e6)
 This function returns the index of the local elemental expansion containing the arbitrary point given by gloCoord, within a distance tolerance of tol. More...
 
int GetExpIndex (const Array< OneD, const NekDouble > &gloCoords, Array< OneD, NekDouble > &locCoords, NekDouble tol=0.0, bool returnNearestElmt=false, int cachedId=-1, NekDouble maxDistance=1e6)
 
NekDouble PhysEvaluate (const Array< OneD, const NekDouble > &coords, const Array< OneD, const NekDouble > &phys)
 
int GetCoeff_Offset (int n) const
 Get the start offset position for a local contiguous list of coeffs correspoinding to element n. More...
 
int GetPhys_Offset (int n) const
 Get the start offset position for a local contiguous list of quadrature points in a full array correspoinding to element n. More...
 
Array< OneD, NekDouble > & UpdateCoeffs ()
 This function returns (a reference to) the array \(\boldsymbol{\hat{u}}_l\) (implemented as m_coeffs) containing all local expansion coefficients. More...
 
Array< OneD, NekDouble > & UpdatePhys ()
 This function returns (a reference to) the array \(\boldsymbol{u}_l\) (implemented as m_phys) containing the function \(u^{\delta}(\boldsymbol{x})\) evaluated at the quadrature points. More...
 
void PhysDeriv (Direction edir, const Array< OneD, const NekDouble > &inarray, Array< OneD, NekDouble > &out_d)
 
void PhysDeriv (const Array< OneD, const NekDouble > &inarray, Array< OneD, NekDouble > &out_d0, Array< OneD, NekDouble > &out_d1=NullNekDouble1DArray, Array< OneD, NekDouble > &out_d2=NullNekDouble1DArray)
 This function discretely evaluates the derivative of a function \(f(\boldsymbol{x})\) on the domain consisting of all elements of the expansion. More...
 
void PhysDeriv (const int dir, const Array< OneD, const NekDouble > &inarray, Array< OneD, NekDouble > &out_d)
 
void Curl (Array< OneD, Array< OneD, NekDouble > > &Vel, Array< OneD, Array< OneD, NekDouble > > &Q)
 
void CurlCurl (Array< OneD, Array< OneD, NekDouble > > &Vel, Array< OneD, Array< OneD, NekDouble > > &Q)
 
void PhysDirectionalDeriv (const Array< OneD, const NekDouble > &direction, const Array< OneD, const NekDouble > &inarray, Array< OneD, NekDouble > &outarray)
 
void GetMovingFrames (const SpatialDomains::GeomMMF MMFdir, const Array< OneD, const NekDouble > &CircCentre, Array< OneD, Array< OneD, NekDouble > > &outarray)
 
const Array< OneD, const std::shared_ptr< ExpList > > & GetBndCondExpansions ()
 
const Array< OneD, const NekDouble > & GetBndCondBwdWeight ()
 Get the weight value for boundary conditions. More...
 
void SetBndCondBwdWeight (const int index, const NekDouble value)
 Set the weight value for boundary conditions. More...
 
std::shared_ptr< ExpList > & UpdateBndCondExpansion (int i)
 
void Upwind (const Array< OneD, const NekDouble > &Vn, const Array< OneD, const NekDouble > &Fwd, const Array< OneD, const NekDouble > &Bwd, Array< OneD, NekDouble > &Upwind)
 
void Upwind (const Array< OneD, const Array< OneD, NekDouble > > &Vec, const Array< OneD, const NekDouble > &Fwd, const Array< OneD, const NekDouble > &Bwd, Array< OneD, NekDouble > &Upwind)
 
std::shared_ptr< ExpList > & GetTrace ()
 
std::shared_ptr< AssemblyMapDG > & GetTraceMap (void)
 
const Array< OneD, const int > & GetTraceBndMap (void)
 
void GetNormals (Array< OneD, Array< OneD, NekDouble > > &normals)
 
void GetElmtNormalLength (Array< OneD, NekDouble > &lengthsFwd, Array< OneD, NekDouble > &lengthsBwd)
 Get the length of elements in boundary normal direction. More...
 
void GetBwdWeight (Array< OneD, NekDouble > &weightAver, Array< OneD, NekDouble > &weightJump)
 Get the weight value for boundary conditions for boundary average and jump calculations. More...
 
void AddTraceIntegral (const Array< OneD, const NekDouble > &Fn, Array< OneD, NekDouble > &outarray)
 
void AddFwdBwdTraceIntegral (const Array< OneD, const NekDouble > &Fwd, const Array< OneD, const NekDouble > &Bwd, Array< OneD, NekDouble > &outarray)
 
void GetFwdBwdTracePhys (Array< OneD, NekDouble > &Fwd, Array< OneD, NekDouble > &Bwd)
 
void GetFwdBwdTracePhys (const Array< OneD, const NekDouble > &field, Array< OneD, NekDouble > &Fwd, Array< OneD, NekDouble > &Bwd, bool FillBnd=true, bool PutFwdInBwdOnBCs=false, bool DoExchange=true)
 
void FillBwdWithBoundCond (const Array< OneD, NekDouble > &Fwd, Array< OneD, NekDouble > &Bwd, bool PutFwdInBwdOnBCs=false)
 
void AddTraceQuadPhysToField (const Array< OneD, const NekDouble > &Fwd, const Array< OneD, const NekDouble > &Bwd, Array< OneD, NekDouble > &field)
 Add Fwd and Bwd value to field, a reverse procedure of GetFwdBwdTracePhys. More...
 
void AddTraceQuadPhysToOffDiag (const Array< OneD, const NekDouble > &Fwd, const Array< OneD, const NekDouble > &Bwd, Array< OneD, NekDouble > &field)
 
void GetLocTraceFromTracePts (const Array< OneD, const NekDouble > &Fwd, const Array< OneD, const NekDouble > &Bwd, Array< OneD, NekDouble > &locTraceFwd, Array< OneD, NekDouble > &locTraceBwd)
 
void FillBwdWithBwdWeight (Array< OneD, NekDouble > &weightave, Array< OneD, NekDouble > &weightjmp)
 Fill Bwd with boundary conditions. More...
 
void PeriodicBwdCopy (const Array< OneD, const NekDouble > &Fwd, Array< OneD, NekDouble > &Bwd)
 Copy and fill the Periodic boundaries. More...
 
const std::vector< bool > & GetLeftAdjacentFaces (void) const
 
void ExtractTracePhys (Array< OneD, NekDouble > &outarray)
 
void ExtractTracePhys (const Array< OneD, const NekDouble > &inarray, Array< OneD, NekDouble > &outarray)
 
const Array< OneD, const SpatialDomains::BoundaryConditionShPtr > & GetBndConditions ()
 
Array< OneD, SpatialDomains::BoundaryConditionShPtr > & UpdateBndConditions ()
 
void EvaluateBoundaryConditions (const NekDouble time=0.0, const std::string varName="", const NekDouble=NekConstants::kNekUnsetDouble, const NekDouble=NekConstants::kNekUnsetDouble)
 
void GeneralMatrixOp (const GlobalMatrixKey &gkey, const Array< OneD, const NekDouble > &inarray, Array< OneD, NekDouble > &outarray)
 This function calculates the result of the multiplication of a matrix of type specified by mkey with a vector given by inarray. More...
 
void SetUpPhysNormals ()
 
void GetBoundaryToElmtMap (Array< OneD, int > &ElmtID, Array< OneD, int > &EdgeID)
 
virtual void GetBndElmtExpansion (int i, std::shared_ptr< ExpList > &result, const bool DeclareCoeffPhysArrays=true)
 
void ExtractElmtToBndPhys (int i, const Array< OneD, NekDouble > &elmt, Array< OneD, NekDouble > &boundary)
 
void ExtractPhysToBndElmt (int i, const Array< OneD, const NekDouble > &phys, Array< OneD, NekDouble > &bndElmt)
 
void ExtractPhysToBnd (int i, const Array< OneD, const NekDouble > &phys, Array< OneD, NekDouble > &bnd)
 
void GetBoundaryNormals (int i, Array< OneD, Array< OneD, NekDouble > > &normals)
 
void GeneralGetFieldDefinitions (std::vector< LibUtilities::FieldDefinitionsSharedPtr > &fielddef, int NumHomoDir=0, Array< OneD, LibUtilities::BasisSharedPtr > &HomoBasis=LibUtilities::NullBasisSharedPtr1DArray, std::vector< NekDouble > &HomoLen=LibUtilities::NullNekDoubleVector, bool homoStrips=false, std::vector< unsigned int > &HomoSIDs=LibUtilities::NullUnsignedIntVector, std::vector< unsigned int > &HomoZIDs=LibUtilities::NullUnsignedIntVector, std::vector< unsigned int > &HomoYIDs=LibUtilities::NullUnsignedIntVector)
 
std::map< int, RobinBCInfoSharedPtrGetRobinBCInfo ()
 
void GetPeriodicEntities (PeriodicMap &periodicVerts, PeriodicMap &periodicEdges, PeriodicMap &periodicFaces=NullPeriodicMap)
 
std::vector< LibUtilities::FieldDefinitionsSharedPtrGetFieldDefinitions ()
 
void GetFieldDefinitions (std::vector< LibUtilities::FieldDefinitionsSharedPtr > &fielddef)
 
void AppendFieldData (LibUtilities::FieldDefinitionsSharedPtr &fielddef, std::vector< NekDouble > &fielddata)
 Append the element data listed in elements fielddef->m_ElementIDs onto fielddata. More...
 
void AppendFieldData (LibUtilities::FieldDefinitionsSharedPtr &fielddef, std::vector< NekDouble > &fielddata, Array< OneD, NekDouble > &coeffs)
 Append the data in coeffs listed in elements fielddef->m_ElementIDs onto fielddata. More...
 
void ExtractElmtDataToCoeffs (LibUtilities::FieldDefinitionsSharedPtr &fielddef, std::vector< NekDouble > &fielddata, std::string &field, Array< OneD, NekDouble > &coeffs)
 Extract the data in fielddata into the coeffs using the basic ExpList Elemental expansions rather than planes in homogeneous case. More...
 
void ExtractCoeffsToCoeffs (const std::shared_ptr< ExpList > &fromExpList, const Array< OneD, const NekDouble > &fromCoeffs, Array< OneD, NekDouble > &toCoeffs)
 Extract the data from fromField using fromExpList the coeffs using the basic ExpList Elemental expansions rather than planes in homogeneous case. More...
 
void ExtractDataToCoeffs (LibUtilities::FieldDefinitionsSharedPtr &fielddef, std::vector< NekDouble > &fielddata, std::string &field, Array< OneD, NekDouble > &coeffs, std::unordered_map< int, int > zIdToPlane=std::unordered_map< int, int >())
 Extract the data in fielddata into the coeffs. More...
 
void ExtractCoeffsFromFile (const std::string &fileName, LibUtilities::CommSharedPtr comm, const std::string &varName, Array< OneD, NekDouble > &coeffs)
 
void GenerateElementVector (const int ElementID, const NekDouble scalar1, const NekDouble scalar2, Array< OneD, NekDouble > &outarray)
 Generate vector v such that v[i] = scalar1 if i is in the element < ElementID. Otherwise, v[i] = scalar2. More...
 
std::shared_ptr< ExpListGetSharedThisPtr ()
 Returns a shared pointer to the current object. More...
 
std::shared_ptr< LibUtilities::SessionReaderGetSession () const
 Returns the session object. More...
 
std::shared_ptr< LibUtilities::CommGetComm () const
 Returns the comm object. More...
 
SpatialDomains::MeshGraphSharedPtr GetGraph ()
 
LibUtilities::BasisSharedPtr GetHomogeneousBasis (void)
 
std::shared_ptr< ExpList > & GetPlane (int n)
 
void CreateCollections (Collections::ImplementationType ImpType=Collections::eNoImpType)
 Construct collections of elements containing a single element type and polynomial order from the list of expansions. More...
 
void ClearGlobalLinSysManager (void)
 
int GetPoolCount (std::string)
 
void UnsetGlobalLinSys (GlobalLinSysKey, bool)
 
LibUtilities::NekManager< GlobalLinSysKey, GlobalLinSys > & GetGlobalLinSysManager (void)
 
const Array< OneD, const std::pair< int, int > > & GetCoeffsToElmt () const
 Get m_coeffs to elemental value map. More...
 
void AddTraceJacToElmtJac (const Array< OneD, const DNekMatSharedPtr > &FwdMat, const Array< OneD, const DNekMatSharedPtr > &BwdMat, Array< OneD, DNekMatSharedPtr > &fieldMat)
 inverse process of v_GetFwdBwdTracePhys. Given Trace integration of Fwd and Bwd Jacobian, with dimension NtotalTrace*TraceCoef*TracePhys. return Elemental Jacobian matrix with dimension NtotalElement*ElementCoef*ElementPhys. More...
 
void GetMatIpwrtDeriveBase (const Array< OneD, const Array< OneD, NekDouble > > &inarray, const int nDirctn, Array< OneD, DNekMatSharedPtr > &mtxPerVar)
 
void GetMatIpwrtDeriveBase (const TensorOfArray3D< NekDouble > &inarray, Array< OneD, DNekMatSharedPtr > &mtxPerVar)
 
void GetDiagMatIpwrtBase (const Array< OneD, const Array< OneD, NekDouble > > &inarray, Array< OneD, DNekMatSharedPtr > &mtxPerVar)
 
void AddTraceIntegralToOffDiag (const Array< OneD, const NekDouble > &FwdFlux, const Array< OneD, const NekDouble > &BwdFlux, Array< OneD, NekDouble > &outarray)
 
void AddRightIPTPhysDerivBase (const int dir, const Array< OneD, const DNekMatSharedPtr > ElmtJacQuad, Array< OneD, DNekMatSharedPtr > ElmtJacCoef)
 
void AddRightIPTBaseMatrix (const Array< OneD, const DNekMatSharedPtr > ElmtJacQuad, Array< OneD, DNekMatSharedPtr > ElmtJacCoef)
 
const LocTraceToTraceMapSharedPtrGetLocTraceToTraceMap () const
 
std::vector< bool > & GetLeftAdjacentTraces (void)
 
const std::unordered_map< int, int > & GetElmtToExpId (void)
 This function returns the map of index inside m_exp to geom id. More...
 
int GetElmtToExpId (int elmtId)
 This function returns the index inside m_exp for a given geom id. More...
 

Public Attributes

Array< OneD, int > m_BCtoElmMap
 
Array< OneD, int > m_BCtoTraceMap
 

Protected Member Functions

void GenerateBoundaryConditionExpansion (const SpatialDomains::MeshGraphSharedPtr &graph1D, const SpatialDomains::BoundaryConditions &bcs, const std::string variable, const bool DeclareCoeffPhysArrays=true)
 Discretises the boundary conditions. More...
 
void FindPeriodicTraces (const SpatialDomains::BoundaryConditions &bcs, const std::string variable)
 Generate a associative map of periodic vertices in a mesh. More...
 
void SetUpDG (const std::string="DefaultVar", const Collections::ImplementationType ImpType=Collections::eNoImpType)
 Set up all DG member variables and maps. More...
 
bool IsLeftAdjacentTrace (const int n, const int e)
 This routine determines if an element is to the "left" of the adjacent trace, which arises from the idea there is a local normal direction between two elements (i.e. on the trace) and one elements would then be the left. More...
 
ExpListSharedPtrv_GetTrace () override
 
AssemblyMapDGSharedPtrv_GetTraceMap (void) override
 
const LocTraceToTraceMapSharedPtrv_GetLocTraceToTraceMap (void) const override
 
std::vector< bool > & v_GetLeftAdjacentTraces (void) override
 
void v_AddTraceIntegral (const Array< OneD, const NekDouble > &Fn, Array< OneD, NekDouble > &outarray) override
 Add trace contributions into elemental coefficient spaces. More...
 
void v_AddFwdBwdTraceIntegral (const Array< OneD, const NekDouble > &Fwd, const Array< OneD, const NekDouble > &Bwd, Array< OneD, NekDouble > &outarray) override
 Add trace contributions into elemental coefficient spaces. More...
 
void v_AddTraceQuadPhysToField (const Array< OneD, const NekDouble > &Fwd, const Array< OneD, const NekDouble > &Bwd, Array< OneD, NekDouble > &field) override
 
void v_ExtractTracePhys (const Array< OneD, const NekDouble > &inarray, Array< OneD, NekDouble > &outarray) override
 This method extracts the trace (verts in 1D) from the field inarray and puts the values in outarray. More...
 
void v_ExtractTracePhys (Array< OneD, NekDouble > &outarray) override
 
void v_GetLocTraceFromTracePts (const Array< OneD, const NekDouble > &Fwd, const Array< OneD, const NekDouble > &Bwd, Array< OneD, NekDouble > &locTraceFwd, Array< OneD, NekDouble > &locTraceBwd) override
 
void GenerateFieldBnd1D (SpatialDomains::BoundaryConditions &bcs, const std::string variable)
 
std::map< int, RobinBCInfoSharedPtrv_GetRobinBCInfo () override
 
const Array< OneD, const MultiRegions::ExpListSharedPtr > & v_GetBndCondExpansions () override
 
const Array< OneD, const SpatialDomains::BoundaryConditionShPtr > & v_GetBndConditions () override
 
MultiRegions::ExpListSharedPtrv_UpdateBndCondExpansion (int i) override
 
Array< OneD, SpatialDomains::BoundaryConditionShPtr > & v_UpdateBndConditions () override
 
void v_GetBoundaryToElmtMap (Array< OneD, int > &ElmtID, Array< OneD, int > &TraceID) override
 
void v_GetBndElmtExpansion (int i, std::shared_ptr< ExpList > &result, const bool DeclareCoeffPhysArrays) override
 
void v_Reset () override
 Reset this field, so that geometry information can be updated. More...
 
void v_EvaluateBoundaryConditions (const NekDouble time=0.0, const std::string varName="", const NekDouble x2_in=NekConstants::kNekUnsetDouble, const NekDouble x3_in=NekConstants::kNekUnsetDouble) override
 Evaluate all boundary conditions at a given time.. More...
 
GlobalLinSysKey v_HelmSolve (const Array< OneD, const NekDouble > &inarray, Array< OneD, NekDouble > &outarray, const StdRegions::ConstFactorMap &factors, const StdRegions::VarCoeffMap &varcoeff, const MultiRegions::VarFactorsMap &varfactors, const Array< OneD, const NekDouble > &dirForcing, const bool PhysSpaceForcing) override
 Solve the Helmholtz equation. More...
 
void v_PeriodicBwdCopy (const Array< OneD, const NekDouble > &Fwd, Array< OneD, NekDouble > &Bwd) override
 
void v_FillBwdWithBwdWeight (Array< OneD, NekDouble > &weightave, Array< OneD, NekDouble > &weightjmp) override
 Fill the weight with m_bndCondBndWeight. More...
 
void v_GetFwdBwdTracePhys (Array< OneD, NekDouble > &Fwd, Array< OneD, NekDouble > &Bwd) override
 
void v_GetFwdBwdTracePhys (const Array< OneD, const NekDouble > &field, Array< OneD, NekDouble > &Fwd, Array< OneD, NekDouble > &Bwd, bool FillBnd=true, bool PutFwdInBwdOnBCs=false, bool DoExchange=true) override
 
void v_FillBwdWithBoundCond (const Array< OneD, NekDouble > &Fwd, Array< OneD, NekDouble > &Bwd, bool PutFwdInBwdOnBCs) override
 
void FillBwdWithBoundCond (const Array< OneD, NekDouble > &Fwd, Array< OneD, NekDouble > &Bwd, const Array< OneD, const SpatialDomains::BoundaryConditionShPtr > &bndConditions, const Array< OneD, const ExpListSharedPtr > &BndCondExpansions, bool PutFwdInBwdOnBCs)
 
const Array< OneD, const NekDouble > & v_GetBndCondBwdWeight () override
 
void v_SetBndCondBwdWeight (const int index, const NekDouble value) override
 
void v_GetPeriodicEntities (PeriodicMap &periodicVerts, PeriodicMap &periodicEdges, PeriodicMap &periodicFaces) override
 Obtain a copy of the periodic edges and vertices for this field. More...
 
void v_AddTraceIntegralToOffDiag (const Array< OneD, const NekDouble > &FwdFlux, const Array< OneD, const NekDouble > &BwdFlux, Array< OneD, NekDouble > &outarray) override
 
- Protected Member Functions inherited from Nektar::MultiRegions::ExpList
std::shared_ptr< DNekMatGenGlobalMatrixFull (const GlobalLinSysKey &mkey, const std::shared_ptr< AssemblyMapCG > &locToGloMap)
 
const DNekScalBlkMatSharedPtr GenBlockMatrix (const GlobalMatrixKey &gkey)
 This function assembles the block diagonal matrix of local matrices of the type mtype. More...
 
const DNekScalBlkMatSharedPtrGetBlockMatrix (const GlobalMatrixKey &gkey)
 
void MultiplyByBlockMatrix (const GlobalMatrixKey &gkey, const Array< OneD, const NekDouble > &inarray, Array< OneD, NekDouble > &outarray)
 
std::shared_ptr< GlobalMatrixGenGlobalMatrix (const GlobalMatrixKey &mkey, const std::shared_ptr< AssemblyMapCG > &locToGloMap)
 Generates a global matrix from the given key and map. More...
 
void GlobalEigenSystem (const std::shared_ptr< DNekMat > &Gmat, Array< OneD, NekDouble > &EigValsReal, Array< OneD, NekDouble > &EigValsImag, Array< OneD, NekDouble > &EigVecs=NullNekDouble1DArray)
 
std::shared_ptr< GlobalLinSysGenGlobalLinSys (const GlobalLinSysKey &mkey, const std::shared_ptr< AssemblyMapCG > &locToGloMap)
 This operation constructs the global linear system of type mkey. More...
 
std::shared_ptr< GlobalLinSysGenGlobalBndLinSys (const GlobalLinSysKey &mkey, const AssemblyMapSharedPtr &locToGloMap)
 Generate a GlobalLinSys from information provided by the key "mkey" and the mapping provided in LocToGloBaseMap. More...
 
virtual size_t v_GetNumElmts (void)
 
virtual const Array< OneD, const std::shared_ptr< ExpList > > & v_GetBndCondExpansions (void)
 
virtual const Array< OneD, const NekDouble > & v_GetBndCondBwdWeight ()
 
virtual void v_SetBndCondBwdWeight (const int index, const NekDouble value)
 
virtual std::shared_ptr< ExpList > & v_UpdateBndCondExpansion (int i)
 
virtual void v_Upwind (const Array< OneD, const Array< OneD, NekDouble > > &Vec, const Array< OneD, const NekDouble > &Fwd, const Array< OneD, const NekDouble > &Bwd, Array< OneD, NekDouble > &Upwind)
 
virtual void v_Upwind (const Array< OneD, const NekDouble > &Vn, const Array< OneD, const NekDouble > &Fwd, const Array< OneD, const NekDouble > &Bwd, Array< OneD, NekDouble > &Upwind)
 
virtual std::shared_ptr< ExpList > & v_GetTrace ()
 
virtual std::shared_ptr< AssemblyMapDG > & v_GetTraceMap ()
 
virtual const Array< OneD, const int > & v_GetTraceBndMap ()
 
virtual const std::shared_ptr< LocTraceToTraceMap > & v_GetLocTraceToTraceMap (void) const
 
virtual std::vector< bool > & v_GetLeftAdjacentTraces (void)
 
virtual void v_GetNormals (Array< OneD, Array< OneD, NekDouble > > &normals)
 Populate normals with the normals of all expansions. More...
 
virtual void v_AddTraceIntegral (const Array< OneD, const NekDouble > &Fn, Array< OneD, NekDouble > &outarray)
 
virtual void v_AddFwdBwdTraceIntegral (const Array< OneD, const NekDouble > &Fwd, const Array< OneD, const NekDouble > &Bwd, Array< OneD, NekDouble > &outarray)
 
virtual void v_GetFwdBwdTracePhys (Array< OneD, NekDouble > &Fwd, Array< OneD, NekDouble > &Bwd)
 
virtual void v_GetFwdBwdTracePhys (const Array< OneD, const NekDouble > &field, Array< OneD, NekDouble > &Fwd, Array< OneD, NekDouble > &Bwd, bool FillBnd=true, bool PutFwdInBwdOnBCs=false, bool DoExchange=true)
 
virtual void v_FillBwdWithBoundCond (const Array< OneD, NekDouble > &Fwd, Array< OneD, NekDouble > &Bwd, bool PutFwdInBwdOnBCs)
 
virtual void v_AddTraceQuadPhysToField (const Array< OneD, const NekDouble > &Fwd, const Array< OneD, const NekDouble > &Bwd, Array< OneD, NekDouble > &field)
 
virtual void v_AddTraceQuadPhysToOffDiag (const Array< OneD, const NekDouble > &Fwd, const Array< OneD, const NekDouble > &Bwd, Array< OneD, NekDouble > &field)
 
virtual void v_GetLocTraceFromTracePts (const Array< OneD, const NekDouble > &Fwd, const Array< OneD, const NekDouble > &Bwd, Array< OneD, NekDouble > &locTraceFwd, Array< OneD, NekDouble > &locTraceBwd)
 
virtual void v_FillBwdWithBwdWeight (Array< OneD, NekDouble > &weightave, Array< OneD, NekDouble > &weightjmp)
 
virtual void v_PeriodicBwdCopy (const Array< OneD, const NekDouble > &Fwd, Array< OneD, NekDouble > &Bwd)
 
virtual const std::vector< bool > & v_GetLeftAdjacentFaces (void) const
 
virtual void v_ExtractTracePhys (Array< OneD, NekDouble > &outarray)
 
virtual void v_ExtractTracePhys (const Array< OneD, const NekDouble > &inarray, Array< OneD, NekDouble > &outarray)
 
virtual void v_MultiplyByInvMassMatrix (const Array< OneD, const NekDouble > &inarray, Array< OneD, NekDouble > &outarray)
 
virtual GlobalLinSysKey v_HelmSolve (const Array< OneD, const NekDouble > &inarray, Array< OneD, NekDouble > &outarray, const StdRegions::ConstFactorMap &factors, const StdRegions::VarCoeffMap &varcoeff, const MultiRegions::VarFactorsMap &varfactors, const Array< OneD, const NekDouble > &dirForcing, const bool PhysSpaceForcing)
 
virtual GlobalLinSysKey v_LinearAdvectionDiffusionReactionSolve (const Array< OneD, const NekDouble > &inarray, Array< OneD, NekDouble > &outarray, const StdRegions::ConstFactorMap &factors, const StdRegions::VarCoeffMap &varcoeff, const MultiRegions::VarFactorsMap &varfactors, const Array< OneD, const NekDouble > &dirForcing, const bool PhysSpaceForcing)
 
virtual void v_LinearAdvectionReactionSolve (const Array< OneD, Array< OneD, NekDouble > > &velocity, const Array< OneD, const NekDouble > &inarray, Array< OneD, NekDouble > &outarray, const NekDouble lambda, const Array< OneD, const NekDouble > &dirForcing=NullNekDouble1DArray)
 
virtual void v_ImposeDirichletConditions (Array< OneD, NekDouble > &outarray)
 
virtual void v_FillBndCondFromField (const Array< OneD, NekDouble > coeffs)
 
virtual void v_FillBndCondFromField (const int nreg, const Array< OneD, NekDouble > coeffs)
 
virtual void v_Reset ()
 Reset geometry information, metrics, matrix managers and geometry information. More...
 
virtual void v_LocalToGlobal (bool UseComm)
 
virtual void v_LocalToGlobal (const Array< OneD, const NekDouble > &inarray, Array< OneD, NekDouble > &outarray, bool UseComm)
 
virtual void v_GlobalToLocal (void)
 
virtual void v_GlobalToLocal (const Array< OneD, const NekDouble > &inarray, Array< OneD, NekDouble > &outarray)
 
virtual void v_BwdTrans (const Array< OneD, const NekDouble > &inarray, Array< OneD, NekDouble > &outarray)
 
virtual void v_FwdTrans (const Array< OneD, const NekDouble > &inarray, Array< OneD, NekDouble > &outarray)
 
virtual void v_FwdTransLocalElmt (const Array< OneD, const NekDouble > &inarray, Array< OneD, NekDouble > &outarray)
 
virtual void v_FwdTransBndConstrained (const Array< OneD, const NekDouble > &inarray, Array< OneD, NekDouble > &outarray)
 
virtual void v_SmoothField (Array< OneD, NekDouble > &field)
 
virtual void v_IProductWRTBase (const Array< OneD, const NekDouble > &inarray, Array< OneD, NekDouble > &outarray)
 
virtual void v_IProductWRTDerivBase (const int dir, const Array< OneD, const NekDouble > &inarray, Array< OneD, NekDouble > &outarray)
 
virtual void v_IProductWRTDerivBase (const Array< OneD, const Array< OneD, NekDouble > > &inarray, Array< OneD, NekDouble > &outarray)
 
virtual void v_GetCoords (Array< OneD, NekDouble > &coord_0, Array< OneD, NekDouble > &coord_1=NullNekDouble1DArray, Array< OneD, NekDouble > &coord_2=NullNekDouble1DArray)
 
virtual void v_GetCoords (const int eid, Array< OneD, NekDouble > &xc0, Array< OneD, NekDouble > &xc1, Array< OneD, NekDouble > &xc2)
 
virtual void v_PhysDeriv (const Array< OneD, const NekDouble > &inarray, Array< OneD, NekDouble > &out_d0, Array< OneD, NekDouble > &out_d1, Array< OneD, NekDouble > &out_d2)
 
virtual void v_PhysDeriv (const int dir, const Array< OneD, const NekDouble > &inarray, Array< OneD, NekDouble > &out_d)
 
virtual void v_PhysDeriv (Direction edir, const Array< OneD, const NekDouble > &inarray, Array< OneD, NekDouble > &out_d)
 
virtual void v_Curl (Array< OneD, Array< OneD, NekDouble > > &Vel, Array< OneD, Array< OneD, NekDouble > > &Q)
 
virtual void v_CurlCurl (Array< OneD, Array< OneD, NekDouble > > &Vel, Array< OneD, Array< OneD, NekDouble > > &Q)
 
virtual void v_PhysDirectionalDeriv (const Array< OneD, const NekDouble > &direction, const Array< OneD, const NekDouble > &inarray, Array< OneD, NekDouble > &outarray)
 
virtual void v_GetMovingFrames (const SpatialDomains::GeomMMF MMFdir, const Array< OneD, const NekDouble > &CircCentre, Array< OneD, Array< OneD, NekDouble > > &outarray)
 
virtual void v_HomogeneousFwdTrans (const int npts, const Array< OneD, const NekDouble > &inarray, Array< OneD, NekDouble > &outarray, bool Shuff=true, bool UnShuff=true)
 
virtual void v_HomogeneousBwdTrans (const int npts, const Array< OneD, const NekDouble > &inarray, Array< OneD, NekDouble > &outarray, bool Shuff=true, bool UnShuff=true)
 
virtual void v_DealiasedProd (const int num_dofs, const Array< OneD, NekDouble > &inarray1, const Array< OneD, NekDouble > &inarray2, Array< OneD, NekDouble > &outarray)
 
virtual void v_DealiasedDotProd (const int num_dofs, const Array< OneD, Array< OneD, NekDouble > > &inarray1, const Array< OneD, Array< OneD, NekDouble > > &inarray2, Array< OneD, Array< OneD, NekDouble > > &outarray)
 
virtual void v_GetBCValues (Array< OneD, NekDouble > &BndVals, const Array< OneD, NekDouble > &TotField, int BndID)
 
virtual void v_NormVectorIProductWRTBase (Array< OneD, const NekDouble > &V1, Array< OneD, const NekDouble > &V2, Array< OneD, NekDouble > &outarray, int BndID)
 
virtual void v_NormVectorIProductWRTBase (Array< OneD, Array< OneD, NekDouble > > &V, Array< OneD, NekDouble > &outarray)
 
virtual void v_SetUpPhysNormals ()
 : Set up a normal along the trace elements between two elements at elemental level More...
 
virtual void v_GetBoundaryToElmtMap (Array< OneD, int > &ElmtID, Array< OneD, int > &EdgeID)
 
virtual void v_GetBndElmtExpansion (int i, std::shared_ptr< ExpList > &result, const bool DeclareCoeffPhysArrays)
 
virtual void v_ExtractElmtToBndPhys (const int i, const Array< OneD, NekDouble > &elmt, Array< OneD, NekDouble > &boundary)
 
virtual void v_ExtractPhysToBndElmt (const int i, const Array< OneD, const NekDouble > &phys, Array< OneD, NekDouble > &bndElmt)
 
virtual void v_ExtractPhysToBnd (const int i, const Array< OneD, const NekDouble > &phys, Array< OneD, NekDouble > &bnd)
 
virtual void v_GetBoundaryNormals (int i, Array< OneD, Array< OneD, NekDouble > > &normals)
 
virtual std::vector< LibUtilities::FieldDefinitionsSharedPtrv_GetFieldDefinitions (void)
 
virtual void v_GetFieldDefinitions (std::vector< LibUtilities::FieldDefinitionsSharedPtr > &fielddef)
 
virtual void v_AppendFieldData (LibUtilities::FieldDefinitionsSharedPtr &fielddef, std::vector< NekDouble > &fielddata)
 
virtual void v_AppendFieldData (LibUtilities::FieldDefinitionsSharedPtr &fielddef, std::vector< NekDouble > &fielddata, Array< OneD, NekDouble > &coeffs)
 
virtual void v_ExtractDataToCoeffs (LibUtilities::FieldDefinitionsSharedPtr &fielddef, std::vector< NekDouble > &fielddata, std::string &field, Array< OneD, NekDouble > &coeffs, std::unordered_map< int, int > zIdToPlane)
 Extract data from raw field data into expansion list. More...
 
virtual void v_ExtractCoeffsToCoeffs (const std::shared_ptr< ExpList > &fromExpList, const Array< OneD, const NekDouble > &fromCoeffs, Array< OneD, NekDouble > &toCoeffs)
 
virtual void v_WriteTecplotHeader (std::ostream &outfile, std::string var="")
 
virtual void v_WriteTecplotZone (std::ostream &outfile, int expansion)
 
virtual void v_WriteTecplotField (std::ostream &outfile, int expansion)
 
virtual void v_WriteTecplotConnectivity (std::ostream &outfile, int expansion)
 
virtual void v_WriteVtkPieceData (std::ostream &outfile, int expansion, std::string var)
 
virtual void v_WriteVtkPieceHeader (std::ostream &outfile, int expansion, int istrip)
 
virtual NekDouble v_L2 (const Array< OneD, const NekDouble > &phys, const Array< OneD, const NekDouble > &soln=NullNekDouble1DArray)
 
virtual NekDouble v_Integral (const Array< OneD, const NekDouble > &inarray)
 
virtual NekDouble v_VectorFlux (const Array< OneD, Array< OneD, NekDouble > > &inarray)
 
virtual Array< OneD, const NekDoublev_HomogeneousEnergy (void)
 
virtual LibUtilities::TranspositionSharedPtr v_GetTransposition (void)
 
virtual NekDouble v_GetHomoLen (void)
 
virtual void v_SetHomoLen (const NekDouble lhom)
 
virtual Array< OneD, const unsigned int > v_GetZIDs (void)
 
virtual Array< OneD, const unsigned int > v_GetYIDs (void)
 
virtual void v_PhysInterp1DScaled (const NekDouble scale, const Array< OneD, NekDouble > &inarray, Array< OneD, NekDouble > &outarray)
 
virtual void v_PhysGalerkinProjection1DScaled (const NekDouble scale, const Array< OneD, NekDouble > &inarray, Array< OneD, NekDouble > &outarray)
 
virtual void v_ClearGlobalLinSysManager (void)
 
virtual int v_GetPoolCount (std::string)
 
virtual void v_UnsetGlobalLinSys (GlobalLinSysKey, bool)
 
virtual LibUtilities::NekManager< GlobalLinSysKey, GlobalLinSys > & v_GetGlobalLinSysManager (void)
 
void ExtractFileBCs (const std::string &fileName, LibUtilities::CommSharedPtr comm, const std::string &varName, const std::shared_ptr< ExpList > locExpList)
 
virtual const Array< OneD, const SpatialDomains::BoundaryConditionShPtr > & v_GetBndConditions ()
 
virtual Array< OneD, SpatialDomains::BoundaryConditionShPtr > & v_UpdateBndConditions ()
 
virtual void v_EvaluateBoundaryConditions (const NekDouble time=0.0, const std::string varName="", const NekDouble x2_in=NekConstants::kNekUnsetDouble, const NekDouble x3_in=NekConstants::kNekUnsetDouble)
 
virtual std::map< int, RobinBCInfoSharedPtrv_GetRobinBCInfo (void)
 
virtual void v_GetPeriodicEntities (PeriodicMap &periodicVerts, PeriodicMap &periodicEdges, PeriodicMap &periodicFaces)
 
virtual LibUtilities::BasisSharedPtr v_GetHomogeneousBasis (void)
 
virtual void v_SetHomo1DSpecVanVisc (Array< OneD, NekDouble > visc)
 
virtual std::shared_ptr< ExpList > & v_GetPlane (int n)
 
virtual void v_AddTraceIntegralToOffDiag (const Array< OneD, const NekDouble > &FwdFlux, const Array< OneD, const NekDouble > &BwdFlux, Array< OneD, NekDouble > &outarray)
 

Protected Attributes

size_t m_numDirBndCondExpansions
 The number of boundary segments on which Dirichlet boundary conditions are imposed. More...
 
Array< OneD, SpatialDomains::BoundaryConditionShPtrm_bndConditions
 An array which contains the information about the boundary condition structure definition on the different boundary regions. More...
 
Array< OneD, MultiRegions::ExpListSharedPtrm_bndCondExpansions
 An object which contains the discretised boundary conditions. More...
 
Array< OneD, NekDoublem_bndCondBndWeight
 
InterfaceMapDGSharedPtr m_interfaceMap
 Interfaces mapping for trace space. More...
 
GlobalLinSysMapShPtr m_globalBndMat
 Global boundary matrix. More...
 
ExpListSharedPtr m_trace
 Trace space storage for points between elements. More...
 
AssemblyMapDGSharedPtr m_traceMap
 Local to global DG mapping for trace space. More...
 
std::set< int > m_boundaryTraces
 A set storing the global IDs of any boundary Verts. More...
 
PeriodicMap m_periodicVerts
 A map which identifies groups of periodic vertices. More...
 
PeriodicMap m_periodicEdges
 A map which identifies pairs of periodic edges. More...
 
PeriodicMap m_periodicFaces
 A map which identifies pairs of periodic faces. More...
 
std::vector< int > m_periodicFwdCopy
 A vector indicating degress of freedom which need to be copied from forwards to backwards space in case of a periodic boundary condition. More...
 
std::vector< int > m_periodicBwdCopy
 
std::vector< bool > m_leftAdjacentTraces
 
LocTraceToTraceMapSharedPtr m_locTraceToTraceMap
 
- Protected Attributes inherited from Nektar::MultiRegions::ExpList
ExpansionType m_expType
 Exapnsion type. More...
 
LibUtilities::CommSharedPtr m_comm
 Communicator. More...
 
LibUtilities::SessionReaderSharedPtr m_session
 Session. More...
 
SpatialDomains::MeshGraphSharedPtr m_graph
 Mesh associated with this expansion list. More...
 
int m_ncoeffs
 The total number of local degrees of freedom. m_ncoeffs \(=N_{\mathrm{eof}}=\sum_{e=1}^{{N_{\mathrm{el}}}}N^{e}_l\). More...
 
int m_npoints
 
Array< OneD, NekDoublem_coeffs
 Concatenation of all local expansion coefficients. More...
 
Array< OneD, NekDoublem_phys
 The global expansion evaluated at the quadrature points. More...
 
bool m_physState
 The state of the array m_phys. More...
 
std::shared_ptr< LocalRegions::ExpansionVectorm_exp
 The list of local expansions. More...
 
Collections::CollectionVector m_collections
 
std::vector< bool > m_collectionsDoInit
 Vector of bools to act as an initialise on first call flag. More...
 
std::vector< int > m_coll_coeff_offset
 Offset of elemental data into the array m_coeffs. More...
 
std::vector< int > m_coll_phys_offset
 Offset of elemental data into the array m_phys. More...
 
Array< OneD, int > m_coeff_offset
 Offset of elemental data into the array m_coeffs. More...
 
Array< OneD, int > m_phys_offset
 Offset of elemental data into the array m_phys. More...
 
Array< OneD, std::pair< int, int > > m_coeffsToElmt
 m_coeffs to elemental value map More...
 
BlockMatrixMapShPtr m_blockMat
 
bool m_WaveSpace
 
std::unordered_map< int, int > m_elmtToExpId
 Mapping from geometry ID of element to index inside m_exp. More...
 

Private Member Functions

SpatialDomains::BoundaryConditionsSharedPtr GetDomainBCs (const SpatialDomains::CompositeMap &domain, const SpatialDomains::BoundaryConditions &Allbcs, const std::string &variable)
 

Private Attributes

std::vector< bool > m_negatedFluxNormal
 

Additional Inherited Members

- Static Protected Member Functions inherited from Nektar::MultiRegions::ExpList
static SpatialDomains::BoundaryConditionShPtr GetBoundaryCondition (const SpatialDomains::BoundaryConditionCollection &collection, unsigned int index, const std::string &variable)
 

Detailed Description

This class is the abstractio n of a global discontinuous two- dimensional spectral/hp element expansion which approximates the solution of a set of partial differential equations.

This class augments the list of local expansions inherited from ExpList with boundary conditions. Inter-element boundaries are handled using an discontinuous Galerkin scheme.

Definition at line 55 of file DisContField.h.

Constructor & Destructor Documentation

◆ DisContField() [1/6]

Nektar::MultiRegions::DisContField::DisContField ( )

Default constructor.

Constructs an empty expansion list with no boundary conditions.

Definition at line 62 of file DisContField.cpp.

65{
66}
Array< OneD, SpatialDomains::BoundaryConditionShPtr > m_bndConditions
An array which contains the information about the boundary condition structure definition on the diff...
Definition: DisContField.h:143
ExpListSharedPtr m_trace
Trace space storage for points between elements.
Definition: DisContField.h:167
Array< OneD, MultiRegions::ExpListSharedPtr > m_bndCondExpansions
An object which contains the discretised boundary conditions.
Definition: DisContField.h:156
ExpList(const ExpansionType Type=eNoType)
The default constructor using a type.
Definition: ExpList.cpp:90
static ExpListSharedPtr NullExpListSharedPtr
Definition: ExpList.h:1499

◆ DisContField() [2/6]

Nektar::MultiRegions::DisContField::DisContField ( const LibUtilities::SessionReaderSharedPtr pSession,
const SpatialDomains::MeshGraphSharedPtr graph,
const std::string &  variable,
const bool  SetUpJustDG = true,
const bool  DeclareCoeffPhysArrays = true,
const Collections::ImplementationType  ImpType = Collections::eNoImpType,
const std::string  bcvariable = "NotSet" 
)

Constructs a 1D discontinuous field based on a mesh and boundary conditions.

An expansion list for the boundary expansions is generated first for the field. These are subsequently evaluated for time zero. The trace map is then constructed.

Parameters
graph1DA mesh, containing information about the domain and the spectral/hp element expansions.
bcsInformation about the enforced boundary conditions.
variableThe session variable associated with the boundary conditions to enforce.
solnTypeType of global system to use.

Definition at line 80 of file DisContField.cpp.

86 : ExpList(pSession, graph, DeclareCoeffPhysArrays, variable, ImpType),
88{
89 std::string bcvar;
90 if (bcvariable == "NotSet")
91 {
92 bcvar = variable;
93 }
94 else
95 {
96 bcvar = bcvariable;
97 }
98
99 if (bcvar.compare("DefaultVar") != 0)
100 {
101 SpatialDomains::BoundaryConditions bcs(m_session, graph);
102
103 GenerateBoundaryConditionExpansion(graph, bcs, bcvar,
104 DeclareCoeffPhysArrays);
105 if (DeclareCoeffPhysArrays)
106 {
107 EvaluateBoundaryConditions(0.0, bcvar);
108 }
110 FindPeriodicTraces(bcs, bcvar);
111 }
112
113 int i, cnt;
114 Array<OneD, int> ElmtID, TraceID;
115 GetBoundaryToElmtMap(ElmtID, TraceID);
116
117 for (cnt = i = 0; i < m_bndCondExpansions.size(); ++i)
118 {
120 locExpList = m_bndCondExpansions[i];
121
122 for (int e = 0; e < locExpList->GetExpSize(); ++e)
123 {
124 (*m_exp)[ElmtID[cnt + e]]->SetTraceExp(TraceID[cnt + e],
125 locExpList->GetExp(e));
126 locExpList->GetExp(e)->SetAdjacentElementExp(
127 TraceID[cnt + e], (*m_exp)[ElmtID[cnt + e]]);
128 }
129 cnt += m_bndCondExpansions[i]->GetExpSize();
130 }
131
132 if (SetUpJustDG)
133 {
134 SetUpDG(variable, ImpType);
135 }
136 else
137 {
138 if (m_session->DefinesSolverInfo("PROJECTION"))
139 {
140 std::string ProjectStr = m_session->GetSolverInfo("PROJECTION");
141 if ((ProjectStr == "MixedCGDG") ||
142 (ProjectStr == "Mixed_CG_Discontinuous"))
143 {
144 SetUpDG();
145 }
146 else
147 {
149 }
150 }
151 else
152 {
154 }
155 }
156}
void SetUpDG(const std::string="DefaultVar", const Collections::ImplementationType ImpType=Collections::eNoImpType)
Set up all DG member variables and maps.
void FindPeriodicTraces(const SpatialDomains::BoundaryConditions &bcs, const std::string variable)
Generate a associative map of periodic vertices in a mesh.
void GenerateBoundaryConditionExpansion(const SpatialDomains::MeshGraphSharedPtr &graph1D, const SpatialDomains::BoundaryConditions &bcs, const std::string variable, const bool DeclareCoeffPhysArrays=true)
Discretises the boundary conditions.
void GetBoundaryToElmtMap(Array< OneD, int > &ElmtID, Array< OneD, int > &EdgeID)
Definition: ExpList.h:2266
std::shared_ptr< LocalRegions::ExpansionVector > m_exp
The list of local expansions.
Definition: ExpList.h:1115
void EvaluateBoundaryConditions(const NekDouble time=0.0, const std::string varName="", const NekDouble=NekConstants::kNekUnsetDouble, const NekDouble=NekConstants::kNekUnsetDouble)
Definition: ExpList.h:2255
void ApplyGeomInfo()
Apply geometry information to each expansion.
Definition: ExpList.cpp:3031
LibUtilities::SessionReaderSharedPtr m_session
Session.
Definition: ExpList.h:1055
std::shared_ptr< ExpList > ExpListSharedPtr
Shared pointer to an ExpList object.

References Nektar::MultiRegions::ExpList::ApplyGeomInfo(), Nektar::MultiRegions::ExpList::EvaluateBoundaryConditions(), FindPeriodicTraces(), GenerateBoundaryConditionExpansion(), Nektar::MultiRegions::ExpList::GetBoundaryToElmtMap(), m_bndCondExpansions, Nektar::MultiRegions::ExpList::m_exp, Nektar::MultiRegions::ExpList::m_session, SetUpDG(), and Nektar::MultiRegions::ExpList::SetUpPhysNormals().

◆ DisContField() [3/6]

Nektar::MultiRegions::DisContField::DisContField ( const LibUtilities::SessionReaderSharedPtr pSession,
const SpatialDomains::MeshGraphSharedPtr graph1D,
const SpatialDomains::CompositeMap domain,
const SpatialDomains::BoundaryConditions Allbcs,
const std::string &  variable,
const LibUtilities::CommSharedPtr comm,
bool  SetToOneSpaceDimension = false,
const Collections::ImplementationType  ImpType = Collections::eNoImpType 
)

Constructor for a DisContField from a List of subdomains New Constructor for arterial network.

Constructor for use in multidomain computations where a domain list can be passed instead of graph1D

Parameters
domainSubdomain specified in the inputfile from which the DisContField is set up

Definition at line 607 of file DisContField.cpp.

615 : ExpList(pSession, domain, graph1D, true, variable, SetToOneSpaceDimension,
616 comm, ImpType)
617{
618 if (variable.compare("DefaultVar") != 0)
619 {
621 GetDomainBCs(domain, Allbcs, variable);
622
624 EvaluateBoundaryConditions(0.0, variable);
626 FindPeriodicTraces(*DomBCs, variable);
627 }
628
629 SetUpDG(variable);
630}
SpatialDomains::BoundaryConditionsSharedPtr GetDomainBCs(const SpatialDomains::CompositeMap &domain, const SpatialDomains::BoundaryConditions &Allbcs, const std::string &variable)
SpatialDomains::MeshGraphSharedPtr m_graph
Mesh associated with this expansion list.
Definition: ExpList.h:1057
std::shared_ptr< BoundaryConditions > BoundaryConditionsSharedPtr
Definition: Conditions.h:289

References Nektar::MultiRegions::ExpList::ApplyGeomInfo(), Nektar::MultiRegions::ExpList::EvaluateBoundaryConditions(), FindPeriodicTraces(), GenerateBoundaryConditionExpansion(), GetDomainBCs(), Nektar::MultiRegions::ExpList::m_graph, and SetUpDG().

◆ DisContField() [4/6]

Nektar::MultiRegions::DisContField::DisContField ( const DisContField In,
const bool  DeclareCoeffPhysArrays = true 
)

Constructs a 1D discontinuous field based on an existing field.

Constructs a field as a copy of an existing field.

Parameters
InExisting DisContField object to copy.

Definition at line 636 of file DisContField.cpp.

638 : ExpList(In, DeclareCoeffPhysArrays), m_bndConditions(In.m_bndConditions),
639 m_bndCondExpansions(In.m_bndCondExpansions),
640 m_globalBndMat(In.m_globalBndMat), m_traceMap(In.m_traceMap),
641 m_boundaryTraces(In.m_boundaryTraces),
642 m_periodicVerts(In.m_periodicVerts),
643 m_periodicFwdCopy(In.m_periodicFwdCopy),
644 m_periodicBwdCopy(In.m_periodicBwdCopy),
645 m_leftAdjacentTraces(In.m_leftAdjacentTraces),
646 m_locTraceToTraceMap(In.m_locTraceToTraceMap)
647{
648 if (In.m_trace)
649 {
651 *In.m_trace, DeclareCoeffPhysArrays);
652 }
653}
static std::shared_ptr< DataType > AllocateSharedPtr(const Args &...args)
Allocate a shared pointer from the memory pool.
std::vector< int > m_periodicBwdCopy
Definition: DisContField.h:198
std::set< int > m_boundaryTraces
A set storing the global IDs of any boundary Verts.
Definition: DisContField.h:175
LocTraceToTraceMapSharedPtr m_locTraceToTraceMap
Definition: DisContField.h:210
AssemblyMapDGSharedPtr m_traceMap
Local to global DG mapping for trace space.
Definition: DisContField.h:170
GlobalLinSysMapShPtr m_globalBndMat
Global boundary matrix.
Definition: DisContField.h:164
PeriodicMap m_periodicVerts
A map which identifies groups of periodic vertices.
Definition: DisContField.h:180
std::vector< int > m_periodicFwdCopy
A vector indicating degress of freedom which need to be copied from forwards to backwards space in ca...
Definition: DisContField.h:197
std::vector< bool > m_leftAdjacentTraces
Definition: DisContField.h:204

References Nektar::MemoryManager< DataType >::AllocateSharedPtr(), and m_trace.

◆ DisContField() [5/6]

Nektar::MultiRegions::DisContField::DisContField ( const DisContField In,
const SpatialDomains::MeshGraphSharedPtr graph,
const std::string &  variable,
const bool  SetUpJustDG = false,
const bool  DeclareCoeffPhysArrays = true 
)

Definition at line 659 of file DisContField.cpp.

663 : ExpList(In, DeclareCoeffPhysArrays)
664{
665
667
668 // Set up boundary conditions for this variable.
669 // Do not set up BCs if default variable
670 if (variable.compare("DefaultVar") != 0)
671 {
672 SpatialDomains::BoundaryConditions bcs(m_session, graph);
673 GenerateBoundaryConditionExpansion(graph, bcs, variable);
674
675 if (DeclareCoeffPhysArrays)
676 {
677 EvaluateBoundaryConditions(0.0, variable);
678 }
679
681 {
682 // Find periodic edges for this variable.
683 FindPeriodicTraces(bcs, variable);
684
685 if (SetUpJustDG)
686 {
687 SetUpDG(variable);
688 }
689 else
690 {
691 // set elmt edges to point to robin bc edges if required
692 int i, cnt = 0;
693 Array<OneD, int> ElmtID, TraceID;
694 GetBoundaryToElmtMap(ElmtID, TraceID);
695
696 for (i = 0; i < m_bndCondExpansions.size(); ++i)
697 {
699
700 int e;
701 locExpList = m_bndCondExpansions[i];
702
703 for (e = 0; e < locExpList->GetExpSize(); ++e)
704 {
705 (*m_exp)[ElmtID[cnt + e]]->SetTraceExp(
706 TraceID[cnt + e], locExpList->GetExp(e));
707 locExpList->GetExp(e)->SetAdjacentElementExp(
708 TraceID[cnt + e], (*m_exp)[ElmtID[cnt + e]]);
709 }
710
711 cnt += m_bndCondExpansions[i]->GetExpSize();
712 }
713
714 if (m_session->DefinesSolverInfo("PROJECTION"))
715 {
716 std::string ProjectStr =
717 m_session->GetSolverInfo("PROJECTION");
718
719 if ((ProjectStr == "MixedCGDG") ||
720 (ProjectStr == "Mixed_CG_Discontinuous"))
721 {
722 SetUpDG();
723 }
724 else
725 {
727 }
728 }
729 else
730 {
732 }
733 }
734 }
735 else
736 {
737 m_globalBndMat = In.m_globalBndMat;
738 m_trace = In.m_trace;
739 m_traceMap = In.m_traceMap;
740 m_interfaceMap = In.m_interfaceMap;
741 m_locTraceToTraceMap = In.m_locTraceToTraceMap;
742 m_periodicVerts = In.m_periodicVerts;
743 m_periodicEdges = In.m_periodicEdges;
744 m_periodicFaces = In.m_periodicFaces;
745 m_periodicFwdCopy = In.m_periodicFwdCopy;
746 m_periodicBwdCopy = In.m_periodicBwdCopy;
747 m_boundaryTraces = In.m_boundaryTraces;
748 m_leftAdjacentTraces = In.m_leftAdjacentTraces;
749
750 if (!SetUpJustDG)
751 {
752 // set elmt edges to point to robin bc edges if required
753 int i, cnt = 0;
754 Array<OneD, int> ElmtID, TraceID;
755 GetBoundaryToElmtMap(ElmtID, TraceID);
756
757 for (i = 0; i < m_bndCondExpansions.size(); ++i)
758 {
760
761 int e;
762 locExpList = m_bndCondExpansions[i];
763
764 for (e = 0; e < locExpList->GetExpSize(); ++e)
765 {
766 (*m_exp)[ElmtID[cnt + e]]->SetTraceExp(
767 TraceID[cnt + e], locExpList->GetExp(e));
768 locExpList->GetExp(e)->SetAdjacentElementExp(
769 TraceID[cnt + e], (*m_exp)[ElmtID[cnt + e]]);
770 }
771 cnt += m_bndCondExpansions[i]->GetExpSize();
772 }
773
775 }
776 }
777 }
778}
PeriodicMap m_periodicEdges
A map which identifies pairs of periodic edges.
Definition: DisContField.h:185
PeriodicMap m_periodicFaces
A map which identifies pairs of periodic faces.
Definition: DisContField.h:190
InterfaceMapDGSharedPtr m_interfaceMap
Interfaces mapping for trace space.
Definition: DisContField.h:161
bool SameTypeOfBoundaryConditions(const DisContField &In)
Check to see if expansion has the same BCs as In.

References Nektar::MultiRegions::ExpList::EvaluateBoundaryConditions(), FindPeriodicTraces(), GenerateBoundaryConditionExpansion(), Nektar::MultiRegions::ExpList::GetBoundaryToElmtMap(), m_bndCondExpansions, m_boundaryTraces, Nektar::MultiRegions::ExpList::m_exp, m_globalBndMat, m_interfaceMap, m_leftAdjacentTraces, m_locTraceToTraceMap, m_periodicBwdCopy, m_periodicEdges, m_periodicFaces, m_periodicFwdCopy, m_periodicVerts, Nektar::MultiRegions::ExpList::m_session, m_trace, m_traceMap, Nektar::MultiRegions::NullExpListSharedPtr, SameTypeOfBoundaryConditions(), SetUpDG(), and Nektar::MultiRegions::ExpList::SetUpPhysNormals().

◆ DisContField() [6/6]

Nektar::MultiRegions::DisContField::DisContField ( const ExpList In)

Constructs a 1D discontinuous field based on an existing field. (needed in order to use ContField( const ExpList &In) constructor.

Constructs a field as a copy of an existing explist field.

Parameters
InExisting ExpList object to copy.

Definition at line 784 of file DisContField.cpp.

784 : ExpList(In)
785{
786}

◆ ~DisContField()

Nektar::MultiRegions::DisContField::~DisContField ( )
override

Destructor.

Definition at line 791 of file DisContField.cpp.

792{
793}

Member Function Documentation

◆ EvaluateHDGPostProcessing()

void Nektar::MultiRegions::DisContField::EvaluateHDGPostProcessing ( const Array< OneD, const NekDouble > &  coeffs,
Array< OneD, NekDouble > &  outarray 
)

Evaluate HDG post-processing to increase polynomial order of solution.

This function takes the solution (assumed to be one order lower) in physical space, and postprocesses at the current polynomial order by solving the system:

\[ \begin{aligned} (\nabla w, \nabla u^*) &= (\nabla w, u), \\ \langle \nabla u^*, 1 \rangle &= \langle \nabla u, 1 \rangle \end{aligned} \]

where \( u \) corresponds with the current solution as stored inside m_coeffs.

Parameters
outarrayThe resulting field \( u^* \).

Definition at line 4242 of file DisContField.cpp.

4245{
4246 int i, cnt, e, ncoeff_trace;
4247 Array<OneD, NekDouble> force, out_tmp, qrhs, qrhs1;
4248 Array<OneD, Array<OneD, LocalRegions::ExpansionSharedPtr>> &elmtToTrace =
4249 m_traceMap->GetElmtToTrace();
4250
4252
4253 int nq_elmt, nm_elmt;
4254 int LocBndCoeffs = m_traceMap->GetNumLocalBndCoeffs();
4255 Array<OneD, NekDouble> loc_lambda(LocBndCoeffs), trace_lambda;
4256 Array<OneD, NekDouble> tmp_coeffs;
4257 m_traceMap->GlobalToLocalBnd(m_trace->GetCoeffs(), loc_lambda);
4258
4259 trace_lambda = loc_lambda;
4260
4261 int dim = (m_expType == e2D) ? 2 : 3;
4262
4263 int num_points[] = {0, 0, 0};
4264 int num_modes[] = {0, 0, 0};
4265
4266 // Calculate Q using standard DG formulation.
4267 for (i = cnt = 0; i < GetExpSize(); ++i)
4268 {
4269 nq_elmt = (*m_exp)[i]->GetTotPoints();
4270 nm_elmt = (*m_exp)[i]->GetNcoeffs();
4271 qrhs = Array<OneD, NekDouble>(nq_elmt);
4272 qrhs1 = Array<OneD, NekDouble>(nq_elmt);
4273 force = Array<OneD, NekDouble>(2 * nm_elmt);
4274 out_tmp = force + nm_elmt;
4276
4277 for (int j = 0; j < dim; ++j)
4278 {
4279 num_points[j] = (*m_exp)[i]->GetBasis(j)->GetNumPoints();
4280 num_modes[j] = (*m_exp)[i]->GetBasis(j)->GetNumModes();
4281 }
4282
4283 // Probably a better way of setting up lambda than this. Note
4284 // cannot use PutCoeffsInToElmts since lambda space is mapped
4285 // during the solve.
4286 int nTraces = (*m_exp)[i]->GetNtraces();
4287 Array<OneD, Array<OneD, NekDouble>> traceCoeffs(nTraces);
4288
4289 for (e = 0; e < (*m_exp)[i]->GetNtraces(); ++e)
4290 {
4291 edgedir = (*m_exp)[i]->GetTraceOrient(e);
4292 ncoeff_trace = elmtToTrace[i][e]->GetNcoeffs();
4293 traceCoeffs[e] = Array<OneD, NekDouble>(ncoeff_trace);
4294 Vmath::Vcopy(ncoeff_trace, trace_lambda, 1, traceCoeffs[e], 1);
4295 if (dim == 2)
4296 {
4297 elmtToTrace[i][e]->SetCoeffsToOrientation(
4298 edgedir, traceCoeffs[e], traceCoeffs[e]);
4299 }
4300 else
4301 {
4302 (*m_exp)[i]
4303 ->as<LocalRegions::Expansion3D>()
4304 ->SetFaceToGeomOrientation(e, traceCoeffs[e]);
4305 }
4306 trace_lambda = trace_lambda + ncoeff_trace;
4307 }
4308
4309 // creating orthogonal expansion (checking if we have quads or
4310 // triangles)
4311 LibUtilities::ShapeType shape = (*m_exp)[i]->DetShapeType();
4312 switch (shape)
4313 {
4315 {
4316 const LibUtilities::PointsKey PkeyQ1(
4318 const LibUtilities::PointsKey PkeyQ2(
4320 LibUtilities::BasisKey BkeyQ1(LibUtilities::eOrtho_A,
4321 num_modes[0], PkeyQ1);
4322 LibUtilities::BasisKey BkeyQ2(LibUtilities::eOrtho_A,
4323 num_modes[1], PkeyQ2);
4325 std::dynamic_pointer_cast<SpatialDomains::QuadGeom>(
4326 (*m_exp)[i]->GetGeom());
4328 BkeyQ1, BkeyQ2, qGeom);
4329 }
4330 break;
4332 {
4333 const LibUtilities::PointsKey PkeyT1(
4335 const LibUtilities::PointsKey PkeyT2(
4336 num_points[1], LibUtilities::eGaussRadauMAlpha1Beta0);
4337 LibUtilities::BasisKey BkeyT1(LibUtilities::eOrtho_A,
4338 num_modes[0], PkeyT1);
4339 LibUtilities::BasisKey BkeyT2(LibUtilities::eOrtho_B,
4340 num_modes[1], PkeyT2);
4342 std::dynamic_pointer_cast<SpatialDomains::TriGeom>(
4343 (*m_exp)[i]->GetGeom());
4345 BkeyT1, BkeyT2, tGeom);
4346 }
4347 break;
4349 {
4350 const LibUtilities::PointsKey PkeyH1(
4352 const LibUtilities::PointsKey PkeyH2(
4354 const LibUtilities::PointsKey PkeyH3(
4356 LibUtilities::BasisKey BkeyH1(LibUtilities::eOrtho_A,
4357 num_modes[0], PkeyH1);
4358 LibUtilities::BasisKey BkeyH2(LibUtilities::eOrtho_A,
4359 num_modes[1], PkeyH2);
4360 LibUtilities::BasisKey BkeyH3(LibUtilities::eOrtho_A,
4361 num_modes[2], PkeyH3);
4363 std::dynamic_pointer_cast<SpatialDomains::HexGeom>(
4364 (*m_exp)[i]->GetGeom());
4366 BkeyH1, BkeyH2, BkeyH3, hGeom);
4367 }
4368 break;
4370 {
4371 const LibUtilities::PointsKey PkeyT1(
4373 const LibUtilities::PointsKey PkeyT2(
4374 num_points[1], LibUtilities::eGaussRadauMAlpha1Beta0);
4375 const LibUtilities::PointsKey PkeyT3(
4376 num_points[2], LibUtilities::eGaussRadauMAlpha2Beta0);
4377 LibUtilities::BasisKey BkeyT1(LibUtilities::eOrtho_A,
4378 num_modes[0], PkeyT1);
4379 LibUtilities::BasisKey BkeyT2(LibUtilities::eOrtho_B,
4380 num_modes[1], PkeyT2);
4381 LibUtilities::BasisKey BkeyT3(LibUtilities::eOrtho_C,
4382 num_modes[2], PkeyT3);
4384 std::dynamic_pointer_cast<SpatialDomains::TetGeom>(
4385 (*m_exp)[i]->GetGeom());
4387 BkeyT1, BkeyT2, BkeyT3, tGeom);
4388 }
4389 break;
4390 default:
4392 "Wrong shape type, HDG postprocessing is not "
4393 "implemented");
4394 };
4395
4396 // DGDeriv
4397 // (d/dx w, d/dx q_0)
4398 (*m_exp)[i]->DGDeriv(0, tmp_coeffs = coeffs + m_coeff_offset[i],
4399 elmtToTrace[i], traceCoeffs, out_tmp);
4400 (*m_exp)[i]->BwdTrans(out_tmp, qrhs);
4401 ppExp->IProductWRTDerivBase(0, qrhs, force);
4402
4403 // + (d/dy w, d/dy q_1)
4404 (*m_exp)[i]->DGDeriv(1, tmp_coeffs = coeffs + m_coeff_offset[i],
4405 elmtToTrace[i], traceCoeffs, out_tmp);
4406
4407 (*m_exp)[i]->BwdTrans(out_tmp, qrhs);
4408 ppExp->IProductWRTDerivBase(1, qrhs, out_tmp);
4409
4410 Vmath::Vadd(nm_elmt, force, 1, out_tmp, 1, force, 1);
4411
4412 // determine force[0] = (1,u)
4413 (*m_exp)[i]->BwdTrans(tmp_coeffs = coeffs + m_coeff_offset[i], qrhs);
4414 force[0] = (*m_exp)[i]->Integral(qrhs);
4415
4416 // multiply by inverse Laplacian matrix
4417 // get matrix inverse
4418 LocalRegions::MatrixKey lapkey(StdRegions::eInvLaplacianWithUnityMean,
4419 ppExp->DetShapeType(), *ppExp);
4420 DNekScalMatSharedPtr lapsys = ppExp->GetLocMatrix(lapkey);
4421
4422 NekVector<NekDouble> in(nm_elmt, force, eWrapper);
4423 NekVector<NekDouble> out(nm_elmt);
4424
4425 out = (*lapsys) * in;
4426
4427 // Transforming back to modified basis
4428 Array<OneD, NekDouble> work(nq_elmt);
4429 ppExp->BwdTrans(out.GetPtr(), work);
4430 (*m_exp)[i]->FwdTrans(work, tmp_coeffs = outarray + m_coeff_offset[i]);
4431 }
4432}
#define NEKERROR(type, msg)
Assert Level 0 – Fundamental assert which is used whether in FULLDEBUG, DEBUG or OPT compilation mode...
Definition: ErrorUtil.hpp:202
int GetExpSize(void)
This function returns the number of elements in the expansion.
Definition: ExpList.h:2046
Array< OneD, int > m_coeff_offset
Offset of elemental data into the array m_coeffs.
Definition: ExpList.h:1124
ExpansionType m_expType
Exapnsion type.
Definition: ExpList.h:1048
@ eGaussLobattoLegendre
1D Gauss-Lobatto-Legendre quadrature points
Definition: PointsType.h:51
@ eOrtho_A
Principle Orthogonal Functions .
Definition: BasisType.h:42
@ eOrtho_C
Principle Orthogonal Functions .
Definition: BasisType.h:46
@ eOrtho_B
Principle Orthogonal Functions .
Definition: BasisType.h:44
std::shared_ptr< Expansion > ExpansionSharedPtr
Definition: Expansion.h:66
std::shared_ptr< QuadGeom > QuadGeomSharedPtr
Definition: HexGeom.h:45
std::shared_ptr< HexGeom > HexGeomSharedPtr
Definition: HexGeom.h:84
std::shared_ptr< TetGeom > TetGeomSharedPtr
Definition: TetGeom.h:82
std::shared_ptr< TriGeom > TriGeomSharedPtr
Definition: TriGeom.h:56
std::shared_ptr< DNekScalMat > DNekScalMatSharedPtr
void Vadd(int n, const T *x, const int incx, const T *y, const int incy, T *z, const int incz)
Add vector z = x+y.
Definition: Vmath.hpp:180
void Vcopy(int n, const T *x, const int incx, T *y, const int incy)
Definition: Vmath.hpp:825

References Nektar::MemoryManager< DataType >::AllocateSharedPtr(), Nektar::MultiRegions::e2D, Nektar::ErrorUtil::efatal, Nektar::LibUtilities::eGaussLobattoLegendre, Nektar::LibUtilities::eHexahedron, Nektar::StdRegions::eInvLaplacianWithUnityMean, Nektar::LibUtilities::eOrtho_A, Nektar::LibUtilities::eOrtho_B, Nektar::LibUtilities::eOrtho_C, Nektar::LibUtilities::eQuadrilateral, Nektar::LibUtilities::eTetrahedron, Nektar::LibUtilities::eTriangle, Nektar::eWrapper, Nektar::MultiRegions::ExpList::GetExpSize(), Nektar::NekVector< DataType >::GetPtr(), Nektar::MultiRegions::ExpList::m_coeff_offset, Nektar::MultiRegions::ExpList::m_exp, Nektar::MultiRegions::ExpList::m_expType, m_trace, m_traceMap, NEKERROR, Vmath::Vadd(), and Vmath::Vcopy().

◆ FillBwdWithBoundCond()

void Nektar::MultiRegions::DisContField::FillBwdWithBoundCond ( const Array< OneD, NekDouble > &  Fwd,
Array< OneD, NekDouble > &  Bwd,
const Array< OneD, const SpatialDomains::BoundaryConditionShPtr > &  bndConditions,
const Array< OneD, const ExpListSharedPtr > &  bndCondExpansions,
bool  PutFwdInBwdOnBCs 
)
protected

function allowing different BCs to be passed to routine

Definition at line 3027 of file DisContField.cpp.

3033{
3034
3035 // Fill boundary conditions into missing elements
3036 if (PutFwdInBwdOnBCs) // just set Bwd value to be Fwd value on BCs
3037 {
3038 // Fill boundary conditions into missing elements
3039 for (int n = 0, cnt = 0; n < bndCondExpansions.size(); ++n)
3040 {
3041 if (bndConditions[n]->GetBoundaryConditionType() ==
3043 {
3044 auto ne = bndCondExpansions[n]->GetExpSize();
3045 for (int e = 0; e < ne; ++e)
3046 {
3047 auto npts = bndCondExpansions[n]->GetExp(e)->GetTotPoints();
3048 auto id2 = m_trace->GetPhys_Offset(
3049 m_traceMap->GetBndCondIDToGlobalTraceID(cnt + e));
3050 Vmath::Vcopy(npts, &Fwd[id2], 1, &Bwd[id2], 1);
3051 }
3052
3053 cnt += ne;
3054 }
3055 else if (bndConditions[n]->GetBoundaryConditionType() ==
3057 bndConditions[n]->GetBoundaryConditionType() ==
3059 {
3060 auto ne = bndCondExpansions[n]->GetExpSize();
3061 for (int e = 0; e < ne; ++e)
3062 {
3063 auto npts = bndCondExpansions[n]->GetExp(e)->GetTotPoints();
3064 auto id2 = m_trace->GetPhys_Offset(
3065 m_traceMap->GetBndCondIDToGlobalTraceID(cnt + e));
3066 Vmath::Vcopy(npts, &Fwd[id2], 1, &Bwd[id2], 1);
3067 }
3068 cnt += ne;
3069 }
3070 else if (bndConditions[n]->GetBoundaryConditionType() !=
3072 {
3073 ASSERTL0(false, "Method not set up for this "
3074 "boundary condition.");
3075 }
3076 }
3077 }
3078 else
3079 {
3080 for (int n = 0, cnt = 0; n < bndCondExpansions.size(); ++n)
3081 {
3082 if (bndConditions[n]->GetBoundaryConditionType() ==
3084 {
3085 auto ne = bndCondExpansions[n]->GetExpSize();
3086 for (int e = 0; e < ne; ++e)
3087 {
3088 auto npts = bndCondExpansions[n]->GetExp(e)->GetTotPoints();
3089 auto id1 = bndCondExpansions[n]->GetPhys_Offset(e);
3090 auto id2 = m_trace->GetPhys_Offset(
3091 m_traceMap->GetBndCondIDToGlobalTraceID(cnt + e));
3092
3093 Vmath::Vcopy(npts, &(bndCondExpansions[n]->GetPhys())[id1],
3094 1, &Bwd[id2], 1);
3095 }
3096 cnt += ne;
3097 }
3098 else if (bndConditions[n]->GetBoundaryConditionType() ==
3100 bndConditions[n]->GetBoundaryConditionType() ==
3102 {
3103 auto ne = m_bndCondExpansions[n]->GetExpSize();
3104 for (int e = 0; e < ne; ++e)
3105 {
3106 auto npts = bndCondExpansions[n]->GetExp(e)->GetTotPoints();
3107 auto id1 = bndCondExpansions[n]->GetPhys_Offset(e);
3108
3109 ASSERTL0((bndCondExpansions[n]->GetPhys())[id1] == 0.0,
3110 "Method not set up for non-zero "
3111 "Neumann boundary condition");
3112 auto id2 = m_trace->GetPhys_Offset(
3113 m_traceMap->GetBndCondIDToGlobalTraceID(cnt + e));
3114
3115 Vmath::Vcopy(npts, &Fwd[id2], 1, &Bwd[id2], 1);
3116 }
3117
3118 cnt += ne;
3119 }
3120 else if (bndConditions[n]->GetBoundaryConditionType() ==
3122 {
3123 // Do nothing
3124 }
3125 else if (bndConditions[n]->GetBoundaryConditionType() !=
3127 {
3129 "Method not set up for this boundary "
3130 "condition.");
3131 }
3132 }
3133 }
3134}
#define ASSERTL0(condition, msg)
Definition: ErrorUtil.hpp:208
const Array< OneD, const NekDouble > & GetPhys() const
This function returns (a reference to) the array (implemented as m_phys) containing the function ev...
Definition: ExpList.h:2038

References ASSERTL0, Nektar::SpatialDomains::eDirichlet, Nektar::ErrorUtil::efatal, Nektar::SpatialDomains::eNeumann, Nektar::SpatialDomains::eNotDefined, Nektar::SpatialDomains::ePeriodic, Nektar::SpatialDomains::eRobin, Nektar::MultiRegions::ExpList::GetPhys(), m_bndCondExpansions, m_trace, m_traceMap, NEKERROR, and Vmath::Vcopy().

Referenced by GetFwdBwdTracePhys(), and v_FillBwdWithBoundCond().

◆ FindPeriodicTraces()

void Nektar::MultiRegions::DisContField::FindPeriodicTraces ( const SpatialDomains::BoundaryConditions bcs,
const std::string  variable 
)
protected

Generate a associative map of periodic vertices in a mesh.

Determine the periodic faces, edges and vertices for the given graph.

Parameters
bcsInformation about the boundary conditions.
variableSpecifies the field.

Definition at line 865 of file DisContField.cpp.

867{
869 bcs.GetBoundaryRegions();
871 bcs.GetBoundaryConditions();
872
873 LibUtilities::CommSharedPtr vComm = m_comm->GetRowComm();
874
875 switch (m_expType)
876 {
877 case e1D:
878 {
879 int i, region1ID, region2ID;
880
882 map<int, int> BregionToVertMap;
883
884 // Construct list of all periodic Region and their
885 // global vertex on this process.
886 for (auto &it : bregions)
887 {
888 locBCond =
889 GetBoundaryCondition(bconditions, it.first, variable);
890
891 if (locBCond->GetBoundaryConditionType() !=
893 {
894 continue;
895 }
896 int id =
897 it.second->begin()->second->m_geomVec[0]->GetGlobalID();
898
899 BregionToVertMap[it.first] = id;
900 }
901
902 set<int> islocal;
903
904 int n = vComm->GetSize();
905 int p = vComm->GetRank();
906
907 Array<OneD, int> nregions(n, 0);
908 nregions[p] = BregionToVertMap.size();
909 vComm->AllReduce(nregions, LibUtilities::ReduceSum);
910
911 int totRegions = Vmath::Vsum(n, nregions, 1);
912
913 Array<OneD, int> regOffset(n, 0);
914
915 for (i = 1; i < n; ++i)
916 {
917 regOffset[i] = regOffset[i - 1] + nregions[i - 1];
918 }
919
920 Array<OneD, int> bregmap(totRegions, 0);
921 Array<OneD, int> bregid(totRegions, 0);
922
923 i = regOffset[p];
924 for (auto &iit : BregionToVertMap)
925 {
926 bregid[i] = iit.first;
927 bregmap[i++] = iit.second;
928 islocal.insert(iit.first);
929 }
930
931 vComm->AllReduce(bregmap, LibUtilities::ReduceSum);
932 vComm->AllReduce(bregid, LibUtilities::ReduceSum);
933
934 for (int i = 0; i < totRegions; ++i)
935 {
936 BregionToVertMap[bregid[i]] = bregmap[i];
937 }
938
939 // Construct list of all periodic pairs local to this process.
940 for (auto &it : bregions)
941 {
942 locBCond =
943 GetBoundaryCondition(bconditions, it.first, variable);
944
945 if (locBCond->GetBoundaryConditionType() !=
947 {
948 continue;
949 }
950
951 // Identify periodic boundary region IDs.
952 region1ID = it.first;
953 region2ID =
954 std::static_pointer_cast<
955 SpatialDomains::PeriodicBoundaryCondition>(locBCond)
956 ->m_connectedBoundaryRegion;
957
958 ASSERTL0(BregionToVertMap.count(region1ID) != 0,
959 "Cannot determine vertex of region1ID");
960
961 ASSERTL0(BregionToVertMap.count(region2ID) != 0,
962 "Cannot determine vertex of region2ID");
963
964 PeriodicEntity ent(BregionToVertMap[region2ID],
966 islocal.count(region2ID) != 0);
967
968 m_periodicVerts[BregionToVertMap[region1ID]].push_back(ent);
969 }
970 }
971 break;
972 case e2D:
973 {
974 int region1ID, region2ID, i, j, k, cnt;
976
978 m_graph->GetCompositeOrdering();
980 m_graph->GetBndRegionOrdering();
981 SpatialDomains::CompositeMap compMap = m_graph->GetComposites();
982
983 // Unique collection of pairs of periodic composites
984 // (i.e. if composites 1 and 2 are periodic then this
985 // map will contain either the pair (1,2) or (2,1) but
986 // not both).
987 map<int, int> perComps;
988 map<int, vector<int>> allVerts;
989 set<int> locVerts;
990 map<int, pair<int, StdRegions::Orientation>> allEdges;
991
992 // Set up a set of all local verts and edges.
993 for (i = 0; i < (*m_exp).size(); ++i)
994 {
995 for (j = 0; j < (*m_exp)[i]->GetNverts(); ++j)
996 {
997 int id = (*m_exp)[i]->GetGeom()->GetVid(j);
998 locVerts.insert(id);
999 }
1000 }
1001
1002 // Construct list of all periodic pairs local to this process.
1003 for (auto &it : bregions)
1004 {
1005 locBCond =
1006 GetBoundaryCondition(bconditions, it.first, variable);
1007
1008 if (locBCond->GetBoundaryConditionType() !=
1010 {
1011 continue;
1012 }
1013
1014 // Identify periodic boundary region IDs.
1015 region1ID = it.first;
1016 region2ID =
1017 std::static_pointer_cast<
1018 SpatialDomains::PeriodicBoundaryCondition>(locBCond)
1019 ->m_connectedBoundaryRegion;
1020
1021 // From this identify composites. Note that in
1022 // serial this will be an empty map.
1023 int cId1, cId2;
1024 if (vComm->GetSize() == 1)
1025 {
1026 cId1 = it.second->begin()->first;
1027 cId2 = bregions.find(region2ID)->second->begin()->first;
1028 }
1029 else
1030 {
1031 cId1 = bndRegOrder.find(region1ID)->second[0];
1032 cId2 = bndRegOrder.find(region2ID)->second[0];
1033 }
1034
1035 ASSERTL0(it.second->size() == 1,
1036 "Boundary region " +
1037 boost::lexical_cast<string>(region1ID) +
1038 " should only contain 1 composite.");
1039
1040 vector<unsigned int> tmpOrder;
1041
1042 // Construct set containing all periodic edgesd on
1043 // this process
1045 it.second->begin()->second;
1046
1047 for (i = 0; i < c->m_geomVec.size(); ++i)
1048 {
1050 std::dynamic_pointer_cast<SpatialDomains::SegGeom>(
1051 c->m_geomVec[i]);
1052 ASSERTL0(segGeom, "Unable to cast to shared ptr");
1053
1055 m_graph->GetElementsFromEdge(segGeom);
1056 ASSERTL0(elmt->size() == 1,
1057 "The periodic boundaries belong to "
1058 "more than one element of the mesh");
1059
1061 std::dynamic_pointer_cast<SpatialDomains::Geometry2D>(
1062 elmt->at(0).first);
1063
1064 allEdges[c->m_geomVec[i]->GetGlobalID()] =
1065 make_pair(elmt->at(0).second,
1066 geom->GetEorient(elmt->at(0).second));
1067
1068 // In serial mesh partitioning will not have occurred so
1069 // need to fill composite ordering map manually.
1070 if (vComm->GetSize() == 1)
1071 {
1072 tmpOrder.push_back(c->m_geomVec[i]->GetGlobalID());
1073 }
1074
1075 vector<int> vertList(2);
1076 vertList[0] = segGeom->GetVid(0);
1077 vertList[1] = segGeom->GetVid(1);
1078 allVerts[c->m_geomVec[i]->GetGlobalID()] = vertList;
1079 }
1080
1081 if (vComm->GetSize() == 1)
1082 {
1083 compOrder[it.second->begin()->first] = tmpOrder;
1084 }
1085
1086 // See if we already have either region1 or
1087 // region2 stored in perComps map.
1088 if (perComps.count(cId1) == 0)
1089 {
1090 if (perComps.count(cId2) == 0)
1091 {
1092 perComps[cId1] = cId2;
1093 }
1094 else
1095 {
1096 std::stringstream ss;
1097 ss << "Boundary region " << cId2 << " should be "
1098 << "periodic with " << perComps[cId2] << " but "
1099 << "found " << cId1 << " instead!";
1100 ASSERTL0(perComps[cId2] == cId1, ss.str());
1101 }
1102 }
1103 else
1104 {
1105 std::stringstream ss;
1106 ss << "Boundary region " << cId1 << " should be "
1107 << "periodic with " << perComps[cId1] << " but "
1108 << "found " << cId2 << " instead!";
1109 ASSERTL0(perComps[cId1] == cId1, ss.str());
1110 }
1111 }
1112
1113 // In case of periodic partition being split over many composites
1114 // may not have all periodic matches so check this
1115 int idmax = -1;
1116 for (auto &cIt : perComps)
1117 {
1118 idmax = max(idmax, cIt.first);
1119 idmax = max(idmax, cIt.second);
1120 }
1121 vComm->AllReduce(idmax, LibUtilities::ReduceMax);
1122 idmax++;
1123 Array<OneD, int> perid(idmax, -1);
1124 for (auto &cIt : perComps)
1125 {
1126 perid[cIt.first] = cIt.second;
1127 }
1128 vComm->AllReduce(perid, LibUtilities::ReduceMax);
1129 // update all partitions
1130 for (int i = 0; i < idmax; ++i)
1131 {
1132 if (perid[i] > -1)
1133 {
1134 // skip if complemetary relationship has
1135 // already been speficied in list
1136 if (perComps.count(perid[i]))
1137 {
1138 continue;
1139 }
1140 perComps[i] = perid[i];
1141 }
1142 }
1143
1144 // Process local edge list to obtain relative edge
1145 // orientations.
1146 int n = vComm->GetSize();
1147 int p = vComm->GetRank();
1148 int totEdges;
1149 Array<OneD, int> edgecounts(n, 0);
1150 Array<OneD, int> edgeoffset(n, 0);
1151 Array<OneD, int> vertoffset(n, 0);
1152
1153 edgecounts[p] = allEdges.size();
1154 vComm->AllReduce(edgecounts, LibUtilities::ReduceSum);
1155
1156 edgeoffset[0] = 0;
1157 for (i = 1; i < n; ++i)
1158 {
1159 edgeoffset[i] = edgeoffset[i - 1] + edgecounts[i - 1];
1160 }
1161
1162 totEdges = Vmath::Vsum(n, edgecounts, 1);
1163 Array<OneD, int> edgeIds(totEdges, 0);
1164 Array<OneD, int> edgeIdx(totEdges, 0);
1165 Array<OneD, int> edgeOrient(totEdges, 0);
1166 Array<OneD, int> edgeVerts(totEdges, 0);
1167
1168 auto sIt = allEdges.begin();
1169
1170 for (i = 0; sIt != allEdges.end(); ++sIt)
1171 {
1172 edgeIds[edgeoffset[p] + i] = sIt->first;
1173 edgeIdx[edgeoffset[p] + i] = sIt->second.first;
1174 edgeOrient[edgeoffset[p] + i] = sIt->second.second;
1175 edgeVerts[edgeoffset[p] + i++] = allVerts[sIt->first].size();
1176 }
1177
1178 vComm->AllReduce(edgeIds, LibUtilities::ReduceSum);
1179 vComm->AllReduce(edgeIdx, LibUtilities::ReduceSum);
1180 vComm->AllReduce(edgeOrient, LibUtilities::ReduceSum);
1181 vComm->AllReduce(edgeVerts, LibUtilities::ReduceSum);
1182
1183 // Calculate number of vertices on each processor.
1184 Array<OneD, int> procVerts(n, 0);
1185 int nTotVerts;
1186
1187 // Note if there are no periodic edges at all calling Vsum will
1188 // cause a segfault.
1189 if (totEdges > 0)
1190 {
1191 nTotVerts = Vmath::Vsum(totEdges, edgeVerts, 1);
1192 }
1193 else
1194 {
1195 nTotVerts = 0;
1196 }
1197
1198 for (i = 0; i < n; ++i)
1199 {
1200 if (edgecounts[i] > 0)
1201 {
1202 procVerts[i] = Vmath::Vsum(edgecounts[i],
1203 edgeVerts + edgeoffset[i], 1);
1204 }
1205 else
1206 {
1207 procVerts[i] = 0;
1208 }
1209 }
1210 vertoffset[0] = 0;
1211
1212 for (i = 1; i < n; ++i)
1213 {
1214 vertoffset[i] = vertoffset[i - 1] + procVerts[i - 1];
1215 }
1216
1217 Array<OneD, int> traceIds(nTotVerts, 0);
1218 for (i = 0, sIt = allEdges.begin(); sIt != allEdges.end(); ++sIt)
1219 {
1220 for (j = 0; j < allVerts[sIt->first].size(); ++j)
1221 {
1222 traceIds[vertoffset[p] + i++] = allVerts[sIt->first][j];
1223 }
1224 }
1225
1226 vComm->AllReduce(traceIds, LibUtilities::ReduceSum);
1227
1228 // For simplicity's sake create a map of edge id -> orientation.
1229 map<int, StdRegions::Orientation> orientMap;
1230 map<int, vector<int>> vertMap;
1231
1232 for (cnt = i = 0; i < totEdges; ++i)
1233 {
1234 ASSERTL0(orientMap.count(edgeIds[i]) == 0,
1235 "Already found edge in orientation map!");
1236
1237 // Work out relative orientations. To avoid having
1238 // to exchange vertex locations, we figure out if
1239 // the edges are backwards or forwards orientated
1240 // with respect to a forwards orientation that is
1241 // CCW. Since our local geometries are
1242 // forwards-orientated with respect to the
1243 // Cartesian axes, we need to invert the
1244 // orientation for the top and left edges of a
1245 // quad and the left edge of a triangle.
1247 (StdRegions::Orientation)edgeOrient[i];
1248
1249 if (edgeIdx[i] > 1)
1250 {
1253 }
1254
1255 orientMap[edgeIds[i]] = o;
1256
1257 vector<int> verts(edgeVerts[i]);
1258
1259 for (j = 0; j < edgeVerts[i]; ++j)
1260 {
1261 verts[j] = traceIds[cnt++];
1262 }
1263 vertMap[edgeIds[i]] = verts;
1264 }
1265
1266 // Go through list of composites and figure out which
1267 // edges are parallel from original ordering in
1268 // session file. This includes composites which are
1269 // not necessarily on this process.
1270 map<int, int> allCompPairs;
1271
1272 // Store temporary map of periodic vertices which will hold all
1273 // periodic vertices on the entire mesh so that doubly periodic
1274 // vertices can be counted properly across partitions. Local
1275 // vertices are copied into m_periodicVerts at the end of the
1276 // function.
1277 PeriodicMap periodicVerts;
1278
1279 for (auto &cIt : perComps)
1280 {
1282 const int id1 = cIt.first;
1283 const int id2 = cIt.second;
1284 std::string id1s = boost::lexical_cast<string>(id1);
1285 std::string id2s = boost::lexical_cast<string>(id2);
1286
1287 if (compMap.count(id1) > 0)
1288 {
1289 c[0] = compMap[id1];
1290 }
1291
1292 if (compMap.count(id2) > 0)
1293 {
1294 c[1] = compMap[id2];
1295 }
1296
1297 // Loop over composite ordering to construct list of all
1298 // periodic edges regardless of whether they are on this
1299 // process.
1300 map<int, int> compPairs;
1301
1302 ASSERTL0(compOrder.count(id1) > 0,
1303 "Unable to find composite " + id1s + " in order map.");
1304 ASSERTL0(compOrder.count(id2) > 0,
1305 "Unable to find composite " + id2s + " in order map.");
1306 ASSERTL0(compOrder[id1].size() == compOrder[id2].size(),
1307 "Periodic composites " + id1s + " and " + id2s +
1308 " should have the same number of elements.");
1309 ASSERTL0(compOrder[id1].size() > 0, "Periodic composites " +
1310 id1s + " and " + id2s +
1311 " are empty!");
1312
1313 // TODO: Add more checks.
1314 for (i = 0; i < compOrder[id1].size(); ++i)
1315 {
1316 int eId1 = compOrder[id1][i];
1317 int eId2 = compOrder[id2][i];
1318
1319 ASSERTL0(compPairs.count(eId1) == 0, "Already paired.");
1320
1321 if (compPairs.count(eId2) != 0)
1322 {
1323 ASSERTL0(compPairs[eId2] == eId1, "Pairing incorrect");
1324 }
1325 compPairs[eId1] = eId2;
1326 }
1327
1328 // Construct set of all edges that we have
1329 // locally on this processor.
1330 set<int> locEdges;
1331 for (i = 0; i < 2; ++i)
1332 {
1333 if (!c[i])
1334 {
1335 continue;
1336 }
1337
1338 if (c[i]->m_geomVec.size() > 0)
1339 {
1340 for (j = 0; j < c[i]->m_geomVec.size(); ++j)
1341 {
1342 locEdges.insert(c[i]->m_geomVec[j]->GetGlobalID());
1343 }
1344 }
1345 }
1346
1347 // Loop over all edges in the geometry composite.
1348 for (auto &pIt : compPairs)
1349 {
1350 int ids[2] = {pIt.first, pIt.second};
1351 bool local[2] = {locEdges.count(pIt.first) > 0,
1352 locEdges.count(pIt.second) > 0};
1353
1354 ASSERTL0(orientMap.count(ids[0]) > 0 &&
1355 orientMap.count(ids[1]) > 0,
1356 "Unable to find edge in orientation map.");
1357
1358 allCompPairs[pIt.first] = pIt.second;
1359 allCompPairs[pIt.second] = pIt.first;
1360
1361 for (i = 0; i < 2; ++i)
1362 {
1363 if (!local[i])
1364 {
1365 continue;
1366 }
1367
1368 int other = (i + 1) % 2;
1369
1371 orientMap[ids[i]] == orientMap[ids[other]]
1374
1375 PeriodicEntity ent(ids[other], o, local[other]);
1376 m_periodicEdges[ids[i]].push_back(ent);
1377 }
1378
1379 for (i = 0; i < 2; ++i)
1380 {
1381 int other = (i + 1) % 2;
1382
1384 orientMap[ids[i]] == orientMap[ids[other]]
1387
1388 // Determine periodic vertices.
1389 vector<int> perVerts1 = vertMap[ids[i]];
1390 vector<int> perVerts2 = vertMap[ids[other]];
1391
1392 map<int, pair<int, bool>> tmpMap;
1393 if (o == StdRegions::eForwards)
1394 {
1395 tmpMap[perVerts1[0]] = make_pair(
1396 perVerts2[0], locVerts.count(perVerts2[0]) > 0);
1397 tmpMap[perVerts1[1]] = make_pair(
1398 perVerts2[1], locVerts.count(perVerts2[1]) > 0);
1399 }
1400 else
1401 {
1402 tmpMap[perVerts1[0]] = make_pair(
1403 perVerts2[1], locVerts.count(perVerts2[1]) > 0);
1404 tmpMap[perVerts1[1]] = make_pair(
1405 perVerts2[0], locVerts.count(perVerts2[0]) > 0);
1406 }
1407
1408 for (auto &mIt : tmpMap)
1409 {
1410 // See if this vertex has been recorded already.
1411 PeriodicEntity ent2(mIt.second.first,
1413 mIt.second.second);
1414 auto perIt = periodicVerts.find(mIt.first);
1415
1416 if (perIt == periodicVerts.end())
1417 {
1418 periodicVerts[mIt.first].push_back(ent2);
1419 perIt = periodicVerts.find(mIt.first);
1420 }
1421 else
1422 {
1423 bool doAdd = true;
1424 for (j = 0; j < perIt->second.size(); ++j)
1425 {
1426 if (perIt->second[j].id == mIt.second.first)
1427 {
1428 doAdd = false;
1429 break;
1430 }
1431 }
1432
1433 if (doAdd)
1434 {
1435 perIt->second.push_back(ent2);
1436 }
1437 }
1438 }
1439 }
1440 }
1441 }
1442
1443 // Search for periodic vertices and edges which are not in
1444 // a periodic composite but lie in this process. First, loop
1445 // over all information we have from other processors.
1446 for (cnt = i = 0; i < totEdges; ++i)
1447 {
1448 int edgeId = edgeIds[i];
1449
1450 ASSERTL0(allCompPairs.count(edgeId) > 0,
1451 "Unable to find matching periodic edge.");
1452
1453 int perEdgeId = allCompPairs[edgeId];
1454
1455 for (j = 0; j < edgeVerts[i]; ++j, ++cnt)
1456 {
1457 int vId = traceIds[cnt];
1458
1459 auto perId = periodicVerts.find(vId);
1460
1461 if (perId == periodicVerts.end())
1462 {
1463 // This vertex is not included in the
1464 // map. Figure out which vertex it is
1465 // supposed to be periodic with. perEdgeId
1466 // is the edge ID which is periodic with
1467 // edgeId. The logic is much the same as
1468 // the loop above.
1469 int perVertexId =
1470 orientMap[edgeId] == orientMap[perEdgeId]
1471 ? vertMap[perEdgeId][(j + 1) % 2]
1472 : vertMap[perEdgeId][j];
1473
1474 PeriodicEntity ent(perVertexId,
1476 locVerts.count(perVertexId) > 0);
1477
1478 periodicVerts[vId].push_back(ent);
1479 }
1480 }
1481 }
1482
1483 // Loop over all periodic vertices to complete connectivity
1484 // information.
1485 for (auto &perIt : periodicVerts)
1486 {
1487 // Loop over associated vertices.
1488 for (i = 0; i < perIt.second.size(); ++i)
1489 {
1490 auto perIt2 = periodicVerts.find(perIt.second[i].id);
1491 ASSERTL0(perIt2 != periodicVerts.end(),
1492 "Couldn't find periodic vertex.");
1493
1494 for (j = 0; j < perIt2->second.size(); ++j)
1495 {
1496 if (perIt2->second[j].id == perIt.first)
1497 {
1498 continue;
1499 }
1500
1501 bool doAdd = true;
1502 for (k = 0; k < perIt.second.size(); ++k)
1503 {
1504 if (perIt2->second[j].id == perIt.second[k].id)
1505 {
1506 doAdd = false;
1507 break;
1508 }
1509 }
1510
1511 if (doAdd)
1512 {
1513 perIt.second.push_back(perIt2->second[j]);
1514 }
1515 }
1516 }
1517 }
1518
1519 // Do one final loop over periodic vertices to remove non-local
1520 // vertices from map.
1521 for (auto &perIt : periodicVerts)
1522 {
1523 if (locVerts.count(perIt.first) > 0)
1524 {
1525 m_periodicVerts.insert(perIt);
1526 }
1527 }
1528 }
1529 break;
1530 case e3D:
1531 {
1533 m_graph->GetCompositeOrdering();
1535 m_graph->GetBndRegionOrdering();
1536 SpatialDomains::CompositeMap compMap = m_graph->GetComposites();
1537
1538 // perComps: Stores a unique collection of pairs of periodic
1539 // composites (i.e. if composites 1 and 2 are periodic then this map
1540 // will contain either the pair (1,2) or (2,1) but not both).
1541 //
1542 // The four maps allVerts, allCoord, allEdges and allOrient map a
1543 // periodic face to a vector containing the vertex ids of the face;
1544 // their coordinates; the edge ids of the face; and their
1545 // orientation within that face respectively.
1546 //
1547 // Finally the three sets locVerts, locEdges and locFaces store any
1548 // vertices, edges and faces that belong to a periodic composite and
1549 // lie on this process.
1550 map<int, RotPeriodicInfo> rotComp;
1551 map<int, int> perComps;
1552 map<int, vector<int>> allVerts;
1553 map<int, SpatialDomains::PointGeomVector> allCoord;
1554 map<int, vector<int>> allEdges;
1555 map<int, vector<StdRegions::Orientation>> allOrient;
1556 set<int> locVerts;
1557 set<int> locEdges;
1558 set<int> locFaces;
1559
1560 int region1ID, region2ID, i, j, k, cnt;
1562
1563 // Set up a set of all local verts and edges.
1564 for (i = 0; i < (*m_exp).size(); ++i)
1565 {
1566 for (j = 0; j < (*m_exp)[i]->GetNverts(); ++j)
1567 {
1568 int id = (*m_exp)[i]->GetGeom()->GetVid(j);
1569 locVerts.insert(id);
1570 }
1571
1572 for (j = 0; j < (*m_exp)[i]->GetGeom()->GetNumEdges(); ++j)
1573 {
1574 int id = (*m_exp)[i]->GetGeom()->GetEid(j);
1575 locEdges.insert(id);
1576 }
1577 }
1578
1579 // Begin by populating the perComps map. We loop over all periodic
1580 // boundary conditions and determine the composite associated with
1581 // it, then fill out the all* maps.
1582 for (auto &it : bregions)
1583 {
1584
1585 locBCond =
1586 GetBoundaryCondition(bconditions, it.first, variable);
1587
1588 if (locBCond->GetBoundaryConditionType() !=
1590 {
1591 continue;
1592 }
1593
1594 // Identify periodic boundary region IDs.
1595 region1ID = it.first;
1596 region2ID =
1597 std::static_pointer_cast<
1598 SpatialDomains::PeriodicBoundaryCondition>(locBCond)
1599 ->m_connectedBoundaryRegion;
1600
1601 // Check the region only contains a single composite.
1602 ASSERTL0(it.second->size() == 1,
1603 "Boundary region " +
1604 boost::lexical_cast<string>(region1ID) +
1605 " should only contain 1 composite.");
1606
1607 // From this identify composites by looking at the original
1608 // boundary region ordering. Note that in serial the mesh
1609 // partitioner is not run, so this map will be empty and
1610 // therefore needs to be populated by using the corresponding
1611 // boundary region.
1612 int cId1, cId2;
1613 if (vComm->GetSize() == 1)
1614 {
1615 cId1 = it.second->begin()->first;
1616 cId2 = bregions.find(region2ID)->second->begin()->first;
1617 }
1618 else
1619 {
1620 cId1 = bndRegOrder.find(region1ID)->second[0];
1621 cId2 = bndRegOrder.find(region2ID)->second[0];
1622 }
1623
1624 // check to see if boundary is rotationally aligned
1625 if (boost::icontains(locBCond->GetUserDefined(), "Rotated"))
1626 {
1627 vector<string> tmpstr;
1628
1629 boost::split(tmpstr, locBCond->GetUserDefined(),
1630 boost::is_any_of(":"));
1631
1632 if (boost::iequals(tmpstr[0], "Rotated"))
1633 {
1634 ASSERTL1(tmpstr.size() > 2,
1635 "Expected Rotated user defined string to "
1636 "contain direction and rotation angle "
1637 "and optionally a tolerance, "
1638 "i.e. Rotated:dir:PI/2:1e-6");
1639
1640 ASSERTL1((tmpstr[1] == "x") || (tmpstr[1] == "y") ||
1641 (tmpstr[1] == "z"),
1642 "Rotated Dir is "
1643 "not specified as x,y or z");
1644
1645 RotPeriodicInfo RotInfo;
1646 RotInfo.m_dir = (tmpstr[1] == "x") ? 0
1647 : (tmpstr[1] == "y") ? 1
1648 : 2;
1649
1650 LibUtilities::Interpreter strEval;
1651 int ExprId = strEval.DefineFunction("", tmpstr[2]);
1652 RotInfo.m_angle = strEval.Evaluate(ExprId);
1653
1654 if (tmpstr.size() == 4)
1655 {
1656 try
1657 {
1658 RotInfo.m_tol =
1659 boost::lexical_cast<NekDouble>(tmpstr[3]);
1660 }
1661 catch (...)
1662 {
1664 "failed to cast tolerance input "
1665 "to a double value in Rotated"
1666 "boundary information");
1667 }
1668 }
1669 else
1670 {
1671 RotInfo.m_tol = 1e-8;
1672 }
1673 rotComp[cId1] = RotInfo;
1674 }
1675 }
1676
1678 it.second->begin()->second;
1679
1680 vector<unsigned int> tmpOrder;
1681
1682 // store the rotation info of this
1683
1684 // From the composite, we now construct the allVerts, allEdges
1685 // and allCoord map so that they can be transferred across
1686 // processors. We also populate the locFaces set to store a
1687 // record of all faces local to this process.
1688 for (i = 0; i < c->m_geomVec.size(); ++i)
1689 {
1691 std::dynamic_pointer_cast<SpatialDomains::Geometry2D>(
1692 c->m_geomVec[i]);
1693 ASSERTL1(faceGeom, "Unable to cast to shared ptr");
1694
1695 // Get geometry ID of this face and store in locFaces.
1696 int faceId = c->m_geomVec[i]->GetGlobalID();
1697 locFaces.insert(faceId);
1698
1699 // In serial, mesh partitioning will not have occurred so
1700 // need to fill composite ordering map manually.
1701 if (vComm->GetSize() == 1)
1702 {
1703 tmpOrder.push_back(c->m_geomVec[i]->GetGlobalID());
1704 }
1705
1706 // Loop over vertices and edges of the face to populate
1707 // allVerts, allEdges and allCoord maps.
1708 vector<int> vertList, edgeList;
1710 vector<StdRegions::Orientation> orientVec;
1711 for (j = 0; j < faceGeom->GetNumVerts(); ++j)
1712 {
1713 vertList.push_back(faceGeom->GetVid(j));
1714 edgeList.push_back(faceGeom->GetEid(j));
1715 coordVec.push_back(faceGeom->GetVertex(j));
1716 orientVec.push_back(faceGeom->GetEorient(j));
1717 }
1718
1719 allVerts[faceId] = vertList;
1720 allEdges[faceId] = edgeList;
1721 allCoord[faceId] = coordVec;
1722 allOrient[faceId] = orientVec;
1723 }
1724
1725 // In serial, record the composite ordering in compOrder for
1726 // later in the routine.
1727 if (vComm->GetSize() == 1)
1728 {
1729 compOrder[it.second->begin()->first] = tmpOrder;
1730 }
1731
1732 // See if we already have either region1 or region2 stored in
1733 // perComps map already and do a sanity check to ensure regions
1734 // are mutually periodic.
1735 if (perComps.count(cId1) == 0)
1736 {
1737 if (perComps.count(cId2) == 0)
1738 {
1739 perComps[cId1] = cId2;
1740 }
1741 else
1742 {
1743 std::stringstream ss;
1744 ss << "Boundary region " << cId2 << " should be "
1745 << "periodic with " << perComps[cId2] << " but "
1746 << "found " << cId1 << " instead!";
1747 ASSERTL0(perComps[cId2] == cId1, ss.str());
1748 }
1749 }
1750 else
1751 {
1752 std::stringstream ss;
1753 ss << "Boundary region " << cId1 << " should be "
1754 << "periodic with " << perComps[cId1] << " but "
1755 << "found " << cId2 << " instead!";
1756 ASSERTL0(perComps[cId1] == cId1, ss.str());
1757 }
1758 }
1759
1760 // In case of periodic partition being split over many composites
1761 // may not have all periodic matches so check this
1762 int idmax = -1;
1763 for (auto &cIt : perComps)
1764 {
1765 idmax = max(idmax, cIt.first);
1766 idmax = max(idmax, cIt.second);
1767 }
1768 vComm->AllReduce(idmax, LibUtilities::ReduceMax);
1769 idmax++;
1770 Array<OneD, int> perid(idmax, -1);
1771 for (auto &cIt : perComps)
1772 {
1773 perid[cIt.first] = cIt.second;
1774 }
1775 vComm->AllReduce(perid, LibUtilities::ReduceMax);
1776 // update all partitions
1777 for (int i = 0; i < idmax; ++i)
1778 {
1779 if (perid[i] > -1)
1780 {
1781 // skip if equivlaent relationship has
1782 // already been speficied in list
1783 if (perComps.count(perid[i]))
1784 {
1785 continue;
1786 }
1787 perComps[i] = perid[i];
1788 }
1789 }
1790
1791 // The next routines process local face lists to
1792 // exchange vertices,
1793 // edges and faces.
1794 int n = vComm->GetSize();
1795 int p = vComm->GetRank();
1796 int totFaces;
1797 Array<OneD, int> facecounts(n, 0);
1798 Array<OneD, int> vertcounts(n, 0);
1799 Array<OneD, int> faceoffset(n, 0);
1800 Array<OneD, int> vertoffset(n, 0);
1801
1802 Array<OneD, int> rotcounts(n, 0);
1803 Array<OneD, int> rotoffset(n, 0);
1804
1805 rotcounts[p] = rotComp.size();
1806 vComm->AllReduce(rotcounts, LibUtilities::ReduceSum);
1807 int totrot = Vmath::Vsum(n, rotcounts, 1);
1808
1809 if (totrot)
1810 {
1811 for (i = 1; i < n; ++i)
1812 {
1813 rotoffset[i] = rotoffset[i - 1] + rotcounts[i - 1];
1814 }
1815
1816 Array<OneD, int> compid(totrot, 0);
1817 Array<OneD, int> rotdir(totrot, 0);
1818 Array<OneD, NekDouble> rotangle(totrot, 0.0);
1819 Array<OneD, NekDouble> rottol(totrot, 0.0);
1820
1821 // fill in rotational informaiton
1822 auto rIt = rotComp.begin();
1823
1824 for (i = 0; rIt != rotComp.end(); ++rIt)
1825 {
1826 compid[rotoffset[p] + i] = rIt->first;
1827 rotdir[rotoffset[p] + i] = rIt->second.m_dir;
1828 rotangle[rotoffset[p] + i] = rIt->second.m_angle;
1829 rottol[rotoffset[p] + i++] = rIt->second.m_tol;
1830 }
1831
1832 vComm->AllReduce(compid, LibUtilities::ReduceSum);
1833 vComm->AllReduce(rotdir, LibUtilities::ReduceSum);
1834 vComm->AllReduce(rotangle, LibUtilities::ReduceSum);
1835 vComm->AllReduce(rottol, LibUtilities::ReduceSum);
1836
1837 // Fill in full rotational composite list
1838 for (i = 0; i < totrot; ++i)
1839 {
1840 RotPeriodicInfo rinfo(rotdir[i], rotangle[i], rottol[i]);
1841
1842 rotComp[compid[i]] = rinfo;
1843 }
1844 }
1845
1846 // First exchange the number of faces on each process.
1847 facecounts[p] = locFaces.size();
1848 vComm->AllReduce(facecounts, LibUtilities::ReduceSum);
1849
1850 // Set up an offset map to allow us to distribute face IDs to all
1851 // processors.
1852 faceoffset[0] = 0;
1853 for (i = 1; i < n; ++i)
1854 {
1855 faceoffset[i] = faceoffset[i - 1] + facecounts[i - 1];
1856 }
1857
1858 // Calculate total number of faces.
1859 totFaces = Vmath::Vsum(n, facecounts, 1);
1860
1861 // faceIds holds face IDs for each periodic face. faceVerts holds
1862 // the number of vertices in this face.
1863 Array<OneD, int> faceIds(totFaces, 0);
1864 Array<OneD, int> faceVerts(totFaces, 0);
1865
1866 // Process p writes IDs of its faces into position faceoffset[p] of
1867 // faceIds which allows us to perform an AllReduce to distribute
1868 // information amongst processors.
1869 auto sIt = locFaces.begin();
1870 for (i = 0; sIt != locFaces.end(); ++sIt)
1871 {
1872 faceIds[faceoffset[p] + i] = *sIt;
1873 faceVerts[faceoffset[p] + i++] = allVerts[*sIt].size();
1874 }
1875
1876 vComm->AllReduce(faceIds, LibUtilities::ReduceSum);
1877 vComm->AllReduce(faceVerts, LibUtilities::ReduceSum);
1878
1879 // procVerts holds number of vertices (and also edges since each
1880 // face is 2D) on each process.
1881 Array<OneD, int> procVerts(n, 0);
1882 int nTotVerts;
1883
1884 // Note if there are no periodic faces at all calling Vsum will
1885 // cause a segfault.
1886 if (totFaces > 0)
1887 {
1888 // Calculate number of vertices on each processor.
1889 nTotVerts = Vmath::Vsum(totFaces, faceVerts, 1);
1890 }
1891 else
1892 {
1893 nTotVerts = 0;
1894 }
1895
1896 for (i = 0; i < n; ++i)
1897 {
1898 if (facecounts[i] > 0)
1899 {
1900 procVerts[i] = Vmath::Vsum(facecounts[i],
1901 faceVerts + faceoffset[i], 1);
1902 }
1903 else
1904 {
1905 procVerts[i] = 0;
1906 }
1907 }
1908
1909 // vertoffset is defined in the same manner as edgeoffset
1910 // beforehand.
1911 vertoffset[0] = 0;
1912 for (i = 1; i < n; ++i)
1913 {
1914 vertoffset[i] = vertoffset[i - 1] + procVerts[i - 1];
1915 }
1916
1917 // At this point we exchange all vertex IDs, edge IDs and vertex
1918 // coordinates for each face. The coordinates are necessary because
1919 // we need to calculate relative face orientations between periodic
1920 // faces to determined edge and vertex connectivity.
1921 Array<OneD, int> vertIds(nTotVerts, 0);
1922 Array<OneD, int> edgeIds(nTotVerts, 0);
1923 Array<OneD, int> edgeOrt(nTotVerts, 0);
1924 Array<OneD, NekDouble> vertX(nTotVerts, 0.0);
1925 Array<OneD, NekDouble> vertY(nTotVerts, 0.0);
1926 Array<OneD, NekDouble> vertZ(nTotVerts, 0.0);
1927
1928 for (cnt = 0, sIt = locFaces.begin(); sIt != locFaces.end(); ++sIt)
1929 {
1930 for (j = 0; j < allVerts[*sIt].size(); ++j)
1931 {
1932 int vertId = allVerts[*sIt][j];
1933 vertIds[vertoffset[p] + cnt] = vertId;
1934 vertX[vertoffset[p] + cnt] = (*allCoord[*sIt][j])(0);
1935 vertY[vertoffset[p] + cnt] = (*allCoord[*sIt][j])(1);
1936 vertZ[vertoffset[p] + cnt] = (*allCoord[*sIt][j])(2);
1937 edgeIds[vertoffset[p] + cnt] = allEdges[*sIt][j];
1938 edgeOrt[vertoffset[p] + cnt++] = allOrient[*sIt][j];
1939 }
1940 }
1941
1942 vComm->AllReduce(vertIds, LibUtilities::ReduceSum);
1943 vComm->AllReduce(vertX, LibUtilities::ReduceSum);
1944 vComm->AllReduce(vertY, LibUtilities::ReduceSum);
1945 vComm->AllReduce(vertZ, LibUtilities::ReduceSum);
1946 vComm->AllReduce(edgeIds, LibUtilities::ReduceSum);
1947 vComm->AllReduce(edgeOrt, LibUtilities::ReduceSum);
1948
1949 // Finally now we have all of this information, we construct maps
1950 // which make accessing the information easier. These are
1951 // conceptually the same as all* maps at the beginning of the
1952 // routine, but now hold information for all periodic vertices.
1953 map<int, vector<int>> vertMap;
1954 map<int, vector<int>> edgeMap;
1955 map<int, SpatialDomains::PointGeomVector> coordMap;
1956
1957 // These final two maps are required for determining the relative
1958 // orientation of periodic edges. vCoMap associates vertex IDs with
1959 // their coordinates, and eIdMap maps an edge ID to the two vertices
1960 // which construct it.
1961 map<int, SpatialDomains::PointGeomSharedPtr> vCoMap;
1962 map<int, pair<int, int>> eIdMap;
1963
1964 for (cnt = i = 0; i < totFaces; ++i)
1965 {
1966 vector<int> edges(faceVerts[i]);
1967 vector<int> verts(faceVerts[i]);
1968 SpatialDomains::PointGeomVector coord(faceVerts[i]);
1969
1970 // Keep track of cnt to enable correct edge vertices to be
1971 // inserted into eIdMap.
1972 int tmp = cnt;
1973 for (j = 0; j < faceVerts[i]; ++j, ++cnt)
1974 {
1975 edges[j] = edgeIds[cnt];
1976 verts[j] = vertIds[cnt];
1978 AllocateSharedPtr(3, verts[j], vertX[cnt], vertY[cnt],
1979 vertZ[cnt]);
1980 vCoMap[vertIds[cnt]] = coord[j];
1981
1982 // Try to insert edge into the eIdMap to avoid re-inserting.
1983 auto testIns = eIdMap.insert(make_pair(
1984 edgeIds[cnt],
1985 make_pair(vertIds[tmp + j],
1986 vertIds[tmp + ((j + 1) % faceVerts[i])])));
1987
1988 if (testIns.second == false)
1989 {
1990 continue;
1991 }
1992
1993 // If the edge is reversed with respect to the face, then
1994 // swap the edges so that we have the original ordering of
1995 // the edge in the 3D element. This is necessary to properly
1996 // determine edge orientation. Note that the logic relies on
1997 // the fact that all edge forward directions are CCW
1998 // orientated: we use a tensor product ordering for 2D
1999 // elements so need to reverse this for edge IDs 2 and 3.
2000 StdRegions::Orientation edgeOrient =
2001 static_cast<StdRegions::Orientation>(edgeOrt[cnt]);
2002 if (j > 1)
2003 {
2004 edgeOrient = edgeOrient == StdRegions::eForwards
2007 }
2008
2009 if (edgeOrient == StdRegions::eBackwards)
2010 {
2011 swap(testIns.first->second.first,
2012 testIns.first->second.second);
2013 }
2014 }
2015
2016 vertMap[faceIds[i]] = verts;
2017 edgeMap[faceIds[i]] = edges;
2018 coordMap[faceIds[i]] = coord;
2019 }
2020
2021 // Go through list of composites and figure out which edges are
2022 // parallel from original ordering in session file. This includes
2023 // composites which are not necessarily on this process.
2024
2025 // Store temporary map of periodic vertices which will hold all
2026 // periodic vertices on the entire mesh so that doubly periodic
2027 // vertices/edges can be counted properly across partitions. Local
2028 // vertices/edges are copied into m_periodicVerts and
2029 // m_periodicEdges at the end of the function.
2030 PeriodicMap periodicVerts, periodicEdges;
2031
2032 // Construct two maps which determine how vertices and edges of
2033 // faces connect given a specific face orientation. The key of the
2034 // map is the number of vertices in the face, used to determine
2035 // difference between tris and quads.
2036 map<int, map<StdRegions::Orientation, vector<int>>> vmap;
2037 map<int, map<StdRegions::Orientation, vector<int>>> emap;
2038
2039 map<StdRegions::Orientation, vector<int>> quadVertMap;
2040 quadVertMap[StdRegions::eDir1FwdDir1_Dir2FwdDir2] = {0, 1, 2, 3};
2041 quadVertMap[StdRegions::eDir1FwdDir1_Dir2BwdDir2] = {3, 2, 1, 0};
2042 quadVertMap[StdRegions::eDir1BwdDir1_Dir2FwdDir2] = {1, 0, 3, 2};
2043 quadVertMap[StdRegions::eDir1BwdDir1_Dir2BwdDir2] = {2, 3, 0, 1};
2044 quadVertMap[StdRegions::eDir1FwdDir2_Dir2FwdDir1] = {0, 3, 2, 1};
2045 quadVertMap[StdRegions::eDir1FwdDir2_Dir2BwdDir1] = {1, 2, 3, 0};
2046 quadVertMap[StdRegions::eDir1BwdDir2_Dir2FwdDir1] = {3, 0, 1, 2};
2047 quadVertMap[StdRegions::eDir1BwdDir2_Dir2BwdDir1] = {2, 1, 0, 3};
2048
2049 map<StdRegions::Orientation, vector<int>> quadEdgeMap;
2050 quadEdgeMap[StdRegions::eDir1FwdDir1_Dir2FwdDir2] = {0, 1, 2, 3};
2051 quadEdgeMap[StdRegions::eDir1FwdDir1_Dir2BwdDir2] = {2, 1, 0, 3};
2052 quadEdgeMap[StdRegions::eDir1BwdDir1_Dir2FwdDir2] = {0, 3, 2, 1};
2053 quadEdgeMap[StdRegions::eDir1BwdDir1_Dir2BwdDir2] = {2, 3, 0, 1};
2054 quadEdgeMap[StdRegions::eDir1FwdDir2_Dir2FwdDir1] = {3, 2, 1, 0};
2055 quadEdgeMap[StdRegions::eDir1FwdDir2_Dir2BwdDir1] = {1, 2, 3, 0};
2056 quadEdgeMap[StdRegions::eDir1BwdDir2_Dir2FwdDir1] = {3, 0, 1, 2};
2057 quadEdgeMap[StdRegions::eDir1BwdDir2_Dir2BwdDir1] = {1, 0, 3, 2};
2058
2059 map<StdRegions::Orientation, vector<int>> triVertMap;
2060 triVertMap[StdRegions::eDir1FwdDir1_Dir2FwdDir2] = {0, 1, 2};
2061 triVertMap[StdRegions::eDir1BwdDir1_Dir2FwdDir2] = {1, 0, 2};
2062
2063 map<StdRegions::Orientation, vector<int>> triEdgeMap;
2064 triEdgeMap[StdRegions::eDir1FwdDir1_Dir2FwdDir2] = {0, 1, 2};
2065 triEdgeMap[StdRegions::eDir1BwdDir1_Dir2FwdDir2] = {0, 2, 1};
2066
2067 vmap[3] = triVertMap;
2068 vmap[4] = quadVertMap;
2069 emap[3] = triEdgeMap;
2070 emap[4] = quadEdgeMap;
2071
2072 map<int, int> allCompPairs;
2073
2074 // Collect composite id's of each periodic face for use if rotation
2075 // is required
2076 map<int, int> fIdToCompId;
2077
2078 // Finally we have enough information to populate the periodic
2079 // vertex, edge and face maps. Begin by looping over all pairs of
2080 // periodic composites to determine pairs of periodic faces.
2081 for (auto &cIt : perComps)
2082 {
2084 const int id1 = cIt.first;
2085 const int id2 = cIt.second;
2086 std::string id1s = boost::lexical_cast<string>(id1);
2087 std::string id2s = boost::lexical_cast<string>(id2);
2088
2089 if (compMap.count(id1) > 0)
2090 {
2091 c[0] = compMap[id1];
2092 }
2093
2094 if (compMap.count(id2) > 0)
2095 {
2096 c[1] = compMap[id2];
2097 }
2098
2099 // Loop over composite ordering to construct list of all
2100 // periodic faces, regardless of whether they are on this
2101 // process.
2102 map<int, int> compPairs;
2103
2104 ASSERTL0(compOrder.count(id1) > 0,
2105 "Unable to find composite " + id1s + " in order map.");
2106 ASSERTL0(compOrder.count(id2) > 0,
2107 "Unable to find composite " + id2s + " in order map.");
2108 ASSERTL0(compOrder[id1].size() == compOrder[id2].size(),
2109 "Periodic composites " + id1s + " and " + id2s +
2110 " should have the same number of elements.");
2111 ASSERTL0(compOrder[id1].size() > 0, "Periodic composites " +
2112 id1s + " and " + id2s +
2113 " are empty!");
2114
2115 // Look up composite ordering to determine pairs.
2116 for (i = 0; i < compOrder[id1].size(); ++i)
2117 {
2118 int eId1 = compOrder[id1][i];
2119 int eId2 = compOrder[id2][i];
2120
2121 ASSERTL0(compPairs.count(eId1) == 0, "Already paired.");
2122
2123 // Sanity check that the faces are mutually periodic.
2124 if (compPairs.count(eId2) != 0)
2125 {
2126 ASSERTL0(compPairs[eId2] == eId1, "Pairing incorrect");
2127 }
2128 compPairs[eId1] = eId2;
2129
2130 // store a map of face ids to composite ids
2131 fIdToCompId[eId1] = id1;
2132 fIdToCompId[eId2] = id2;
2133 }
2134
2135 // Now that we have all pairs of periodic faces, loop over the
2136 // ones local on this process and populate face/edge/vertex
2137 // maps.
2138 for (auto &pIt : compPairs)
2139 {
2140 int ids[2] = {pIt.first, pIt.second};
2141 bool local[2] = {locFaces.count(pIt.first) > 0,
2142 locFaces.count(pIt.second) > 0};
2143
2144 ASSERTL0(coordMap.count(ids[0]) > 0 &&
2145 coordMap.count(ids[1]) > 0,
2146 "Unable to find face in coordinate map");
2147
2148 allCompPairs[pIt.first] = pIt.second;
2149 allCompPairs[pIt.second] = pIt.first;
2150
2151 // Loop up coordinates of the faces, check they have the
2152 // same number of vertices.
2154 coordMap[ids[0]], coordMap[ids[1]]};
2155
2156 ASSERTL0(tmpVec[0].size() == tmpVec[1].size(),
2157 "Two periodic faces have different number "
2158 "of vertices!");
2159
2160 // o will store relative orientation of faces. Note that in
2161 // some transpose cases (Dir1FwdDir2_Dir2BwdDir1 and
2162 // Dir1BwdDir1_Dir2FwdDir1) it seems orientation will be
2163 // different going from face1->face2 instead of face2->face1
2164 // (check this).
2166 bool rotbnd = false;
2167 int dir = 0;
2168 NekDouble angle = 0.0;
2169 NekDouble sign = 0.0;
2170 NekDouble tol = 1e-8;
2171
2172 // check to see if perioid boundary is rotated
2173 if (rotComp.count(fIdToCompId[pIt.first]))
2174 {
2175 rotbnd = true;
2176 dir = rotComp[fIdToCompId[pIt.first]].m_dir;
2177 angle = rotComp[fIdToCompId[pIt.first]].m_angle;
2178 tol = rotComp[fIdToCompId[pIt.first]].m_tol;
2179 }
2180
2181 // Record periodic faces.
2182 for (i = 0; i < 2; ++i)
2183 {
2184 if (!local[i])
2185 {
2186 continue;
2187 }
2188
2189 // Reference to the other face.
2190 int other = (i + 1) % 2;
2191
2192 // angle is set up for i = 0 to i = 1
2193 sign = (i == 0) ? 1.0 : -1.0;
2194
2195 // Calculate relative face orientation.
2196 if (tmpVec[0].size() == 3)
2197 {
2199 tmpVec[i], tmpVec[other], rotbnd, dir,
2200 sign * angle, tol);
2201 }
2202 else
2203 {
2205 tmpVec[i], tmpVec[other], rotbnd, dir,
2206 sign * angle, tol);
2207 }
2208
2209 // Record face ID, orientation and whether other face is
2210 // local.
2211 PeriodicEntity ent(ids[other], o, local[other]);
2212 m_periodicFaces[ids[i]].push_back(ent);
2213 }
2214
2215 int nFaceVerts = vertMap[ids[0]].size();
2216
2217 // Determine periodic vertices.
2218 for (i = 0; i < 2; ++i)
2219 {
2220 int other = (i + 1) % 2;
2221
2222 // angle is set up for i = 0 to i = 1
2223 sign = (i == 0) ? 1.0 : -1.0;
2224
2225 // Calculate relative face orientation.
2226 if (tmpVec[0].size() == 3)
2227 {
2229 tmpVec[i], tmpVec[other], rotbnd, dir,
2230 sign * angle, tol);
2231 }
2232 else
2233 {
2235 tmpVec[i], tmpVec[other], rotbnd, dir,
2236 sign * angle, tol);
2237 }
2238
2239 if (nFaceVerts == 3)
2240 {
2241 ASSERTL0(
2244 "Unsupported face orientation for face " +
2245 boost::lexical_cast<string>(ids[i]));
2246 }
2247
2248 // Look up vertices for this face.
2249 vector<int> per1 = vertMap[ids[i]];
2250 vector<int> per2 = vertMap[ids[other]];
2251
2252 // tmpMap will hold the pairs of vertices which are
2253 // periodic.
2254 map<int, pair<int, bool>> tmpMap;
2255
2256 // Use vmap to determine which vertices connect given
2257 // the orientation o.
2258 for (j = 0; j < nFaceVerts; ++j)
2259 {
2260 int v = vmap[nFaceVerts][o][j];
2261 tmpMap[per1[j]] =
2262 make_pair(per2[v], locVerts.count(per2[v]) > 0);
2263 }
2264
2265 // Now loop over tmpMap to associate periodic vertices.
2266 for (auto &mIt : tmpMap)
2267 {
2268 PeriodicEntity ent2(mIt.second.first,
2270 mIt.second.second);
2271
2272 // See if this vertex has been recorded already.
2273 auto perIt = periodicVerts.find(mIt.first);
2274
2275 if (perIt == periodicVerts.end())
2276 {
2277 // Vertex is new - just record this entity as
2278 // usual.
2279 periodicVerts[mIt.first].push_back(ent2);
2280 perIt = periodicVerts.find(mIt.first);
2281 }
2282 else
2283 {
2284 // Vertex is known - loop over the vertices
2285 // inside the record and potentially add vertex
2286 // mIt.second to the list.
2287 for (k = 0; k < perIt->second.size(); ++k)
2288 {
2289 if (perIt->second[k].id == mIt.second.first)
2290 {
2291 break;
2292 }
2293 }
2294
2295 if (k == perIt->second.size())
2296 {
2297 perIt->second.push_back(ent2);
2298 }
2299 }
2300 }
2301 }
2302
2303 // Determine periodic edges. Logic is the same as above,
2304 // and perhaps should be condensed to avoid replication.
2305 for (i = 0; i < 2; ++i)
2306 {
2307 int other = (i + 1) % 2;
2308
2309 // angle is set up for i = 0 to i = 1
2310 sign = (i == 0) ? 1.0 : -1.0;
2311
2312 if (tmpVec[0].size() == 3)
2313 {
2315 tmpVec[i], tmpVec[other], rotbnd, dir,
2316 sign * angle, tol);
2317 }
2318 else
2319 {
2321 tmpVec[i], tmpVec[other], rotbnd, dir,
2322 sign * angle, tol);
2323 }
2324
2325 vector<int> per1 = edgeMap[ids[i]];
2326 vector<int> per2 = edgeMap[ids[other]];
2327
2328 map<int, pair<int, bool>> tmpMap;
2329
2330 for (j = 0; j < nFaceVerts; ++j)
2331 {
2332 int e = emap[nFaceVerts][o][j];
2333 tmpMap[per1[j]] =
2334 make_pair(per2[e], locEdges.count(per2[e]) > 0);
2335 }
2336
2337 for (auto &mIt : tmpMap)
2338 {
2339 // Note we assume orientation of edges is forwards -
2340 // this may be reversed later.
2341 PeriodicEntity ent2(mIt.second.first,
2343 mIt.second.second);
2344 auto perIt = periodicEdges.find(mIt.first);
2345
2346 if (perIt == periodicEdges.end())
2347 {
2348 periodicEdges[mIt.first].push_back(ent2);
2349 perIt = periodicEdges.find(mIt.first);
2350 }
2351 else
2352 {
2353 for (k = 0; k < perIt->second.size(); ++k)
2354 {
2355 if (perIt->second[k].id == mIt.second.first)
2356 {
2357 break;
2358 }
2359 }
2360
2361 if (k == perIt->second.size())
2362 {
2363 perIt->second.push_back(ent2);
2364 }
2365 }
2366 }
2367 }
2368 }
2369 }
2370
2371 // Make sure that the nubmer of face pairs and the
2372 // face Id to composite Id map match in size
2373 ASSERTL1(allCompPairs.size() == fIdToCompId.size(),
2374 "At this point the size of allCompPairs "
2375 "should have been the same as fIdToCompId");
2376
2377 // also will need an edge id to composite id at
2378 // end of routine
2379 map<int, int> eIdToCompId;
2380
2381 // Search for periodic vertices and edges which are not
2382 // in a periodic composite but lie in this process. First,
2383 // loop over all information we have from other
2384 // processors.
2385 for (cnt = i = 0; i < totFaces; ++i)
2386 {
2387 bool rotbnd = false;
2388 int dir = 0;
2389 NekDouble angle = 0.0;
2390 NekDouble tol = 1e-8;
2391
2392 int faceId = faceIds[i];
2393
2394 ASSERTL0(allCompPairs.count(faceId) > 0,
2395 "Unable to find matching periodic face. faceId = " +
2396 boost::lexical_cast<string>(faceId));
2397
2398 int perFaceId = allCompPairs[faceId];
2399
2400 // check to see if periodic boundary is rotated
2401 ASSERTL1((rotComp.size() == 0) || fIdToCompId.count(faceId) > 0,
2402 "Face " + boost::lexical_cast<string>(faceId) +
2403 " not found in fIdtoCompId map");
2404 if (rotComp.count(fIdToCompId[faceId]))
2405 {
2406 rotbnd = true;
2407 dir = rotComp[fIdToCompId[faceId]].m_dir;
2408 angle = rotComp[fIdToCompId[faceId]].m_angle;
2409 tol = rotComp[fIdToCompId[faceId]].m_tol;
2410 }
2411
2412 for (j = 0; j < faceVerts[i]; ++j, ++cnt)
2413 {
2414 int vId = vertIds[cnt];
2415
2416 auto perId = periodicVerts.find(vId);
2417
2418 if (perId == periodicVerts.end())
2419 {
2420
2421 // This vertex is not included in the
2422 // map. Figure out which vertex it is supposed
2423 // to be periodic with. perFaceId is the face
2424 // ID which is periodic with faceId. The logic
2425 // is much the same as the loop above.
2427 coordMap[faceId], coordMap[perFaceId]};
2428
2429 int nFaceVerts = tmpVec[0].size();
2431 nFaceVerts == 3
2433 tmpVec[0], tmpVec[1], rotbnd, dir, angle,
2434 tol)
2435 : SpatialDomains::QuadGeom::GetFaceOrientation(
2436 tmpVec[0], tmpVec[1], rotbnd, dir, angle,
2437 tol);
2438
2439 // Use vmap to determine which vertex of the other face
2440 // should be periodic with this one.
2441 int perVertexId =
2442 vertMap[perFaceId][vmap[nFaceVerts][o][j]];
2443
2444 PeriodicEntity ent(perVertexId,
2446 locVerts.count(perVertexId) > 0);
2447
2448 periodicVerts[vId].push_back(ent);
2449 }
2450
2451 int eId = edgeIds[cnt];
2452
2453 perId = periodicEdges.find(eId);
2454
2455 // this map is required at very end to determine rotation of
2456 // edges.
2457 if (rotbnd)
2458 {
2459 eIdToCompId[eId] = fIdToCompId[faceId];
2460 }
2461
2462 if (perId == periodicEdges.end())
2463 {
2464 // This edge is not included in the map. Figure
2465 // out which edge it is supposed to be periodic
2466 // with. perFaceId is the face ID which is
2467 // periodic with faceId. The logic is much the
2468 // same as the loop above.
2470 coordMap[faceId], coordMap[perFaceId]};
2471
2472 int nFaceEdges = tmpVec[0].size();
2474 nFaceEdges == 3
2476 tmpVec[0], tmpVec[1], rotbnd, dir, angle,
2477 tol)
2478 : SpatialDomains::QuadGeom::GetFaceOrientation(
2479 tmpVec[0], tmpVec[1], rotbnd, dir, angle,
2480 tol);
2481
2482 // Use emap to determine which edge of the other
2483 // face should be periodic with this one.
2484 int perEdgeId =
2485 edgeMap[perFaceId][emap[nFaceEdges][o][j]];
2486
2487 PeriodicEntity ent(perEdgeId, StdRegions::eForwards,
2488 locEdges.count(perEdgeId) > 0);
2489
2490 periodicEdges[eId].push_back(ent);
2491
2492 // this map is required at very end to
2493 // determine rotation of edges.
2494 if (rotbnd)
2495 {
2496 eIdToCompId[perEdgeId] = fIdToCompId[perFaceId];
2497 }
2498 }
2499 }
2500 }
2501
2502 // Finally, we must loop over the periodicVerts and periodicEdges
2503 // map to complete connectivity information.
2504 for (auto &perIt : periodicVerts)
2505 {
2506 // For each vertex that is periodic with this one...
2507 for (i = 0; i < perIt.second.size(); ++i)
2508 {
2509 // Find the vertex in the periodicVerts map...
2510 auto perIt2 = periodicVerts.find(perIt.second[i].id);
2511 ASSERTL0(perIt2 != periodicVerts.end(),
2512 "Couldn't find periodic vertex.");
2513
2514 // Now search through this vertex's list and make sure that
2515 // we have a record of any vertices which aren't in the
2516 // original list.
2517 for (j = 0; j < perIt2->second.size(); ++j)
2518 {
2519 if (perIt2->second[j].id == perIt.first)
2520 {
2521 continue;
2522 }
2523
2524 for (k = 0; k < perIt.second.size(); ++k)
2525 {
2526 if (perIt2->second[j].id == perIt.second[k].id)
2527 {
2528 break;
2529 }
2530 }
2531
2532 if (k == perIt.second.size())
2533 {
2534 perIt.second.push_back(perIt2->second[j]);
2535 }
2536 }
2537 }
2538 }
2539
2540 for (auto &perIt : periodicEdges)
2541 {
2542 for (i = 0; i < perIt.second.size(); ++i)
2543 {
2544 auto perIt2 = periodicEdges.find(perIt.second[i].id);
2545 ASSERTL0(perIt2 != periodicEdges.end(),
2546 "Couldn't find periodic edge.");
2547
2548 for (j = 0; j < perIt2->second.size(); ++j)
2549 {
2550 if (perIt2->second[j].id == perIt.first)
2551 {
2552 continue;
2553 }
2554
2555 for (k = 0; k < perIt.second.size(); ++k)
2556 {
2557 if (perIt2->second[j].id == perIt.second[k].id)
2558 {
2559 break;
2560 }
2561 }
2562
2563 if (k == perIt.second.size())
2564 {
2565 perIt.second.push_back(perIt2->second[j]);
2566 }
2567 }
2568 }
2569 }
2570
2571 // Loop over periodic edges to determine relative edge orientations.
2572 for (auto &perIt : periodicEdges)
2573 {
2574 bool rotbnd = false;
2575 int dir = 0;
2576 NekDouble angle = 0.0;
2577 NekDouble tol = 1e-8;
2578
2579 // Find edge coordinates
2580 auto eIt = eIdMap.find(perIt.first);
2581 SpatialDomains::PointGeom v[2] = {*vCoMap[eIt->second.first],
2582 *vCoMap[eIt->second.second]};
2583
2584 // check to see if perioid boundary is rotated
2585 if (rotComp.count(eIdToCompId[perIt.first]))
2586 {
2587 rotbnd = true;
2588 dir = rotComp[eIdToCompId[perIt.first]].m_dir;
2589 angle = rotComp[eIdToCompId[perIt.first]].m_angle;
2590 tol = rotComp[eIdToCompId[perIt.first]].m_tol;
2591 }
2592
2593 // Loop over each edge, and construct a vector that takes us
2594 // from one vertex to another. Use this to figure out which
2595 // vertex maps to which.
2596 for (i = 0; i < perIt.second.size(); ++i)
2597 {
2598 eIt = eIdMap.find(perIt.second[i].id);
2599
2600 SpatialDomains::PointGeom w[2] = {
2601 *vCoMap[eIt->second.first],
2602 *vCoMap[eIt->second.second]};
2603
2604 int vMap[2] = {-1, -1};
2605 if (rotbnd)
2606 {
2607
2608 SpatialDomains::PointGeom r;
2609
2610 r.Rotate(v[0], dir, angle);
2611
2612 if (r.dist(w[0]) < tol)
2613 {
2614 vMap[0] = 0;
2615 }
2616 else
2617 {
2618 r.Rotate(v[1], dir, angle);
2619 if (r.dist(w[0]) < tol)
2620 {
2621 vMap[0] = 1;
2622 }
2623 else
2624 {
2626 "Unable to align rotationally "
2627 "periodic edge vertex");
2628 }
2629 }
2630 }
2631 else // translation test
2632 {
2633 NekDouble cx =
2634 0.5 * (w[0](0) - v[0](0) + w[1](0) - v[1](0));
2635 NekDouble cy =
2636 0.5 * (w[0](1) - v[0](1) + w[1](1) - v[1](1));
2637 NekDouble cz =
2638 0.5 * (w[0](2) - v[0](2) + w[1](2) - v[1](2));
2639
2640 for (j = 0; j < 2; ++j)
2641 {
2642 NekDouble x = v[j](0);
2643 NekDouble y = v[j](1);
2644 NekDouble z = v[j](2);
2645 for (k = 0; k < 2; ++k)
2646 {
2647 NekDouble x1 = w[k](0) - cx;
2648 NekDouble y1 = w[k](1) - cy;
2649 NekDouble z1 = w[k](2) - cz;
2650
2651 if (sqrt((x1 - x) * (x1 - x) +
2652 (y1 - y) * (y1 - y) +
2653 (z1 - z) * (z1 - z)) < 1e-8)
2654 {
2655 vMap[k] = j;
2656 break;
2657 }
2658 }
2659 }
2660
2661 // Sanity check the map.
2662 ASSERTL0(vMap[0] >= 0 && vMap[1] >= 0,
2663 "Unable to align periodic edge vertex.");
2664 ASSERTL0((vMap[0] == 0 || vMap[0] == 1) &&
2665 (vMap[1] == 0 || vMap[1] == 1) &&
2666 (vMap[0] != vMap[1]),
2667 "Unable to align periodic edge vertex.");
2668 }
2669
2670 // If 0 -> 0 then edges are aligned already; otherwise
2671 // reverse the orientation.
2672 if (vMap[0] != 0)
2673 {
2674 perIt.second[i].orient = StdRegions::eBackwards;
2675 }
2676 }
2677 }
2678
2679 // Do one final loop over periodic vertices/edges to remove
2680 // non-local vertices/edges from map.
2681 for (auto &perIt : periodicVerts)
2682 {
2683 if (locVerts.count(perIt.first) > 0)
2684 {
2685 m_periodicVerts.insert(perIt);
2686 }
2687 }
2688
2689 for (auto &perIt : periodicEdges)
2690 {
2691 if (locEdges.count(perIt.first) > 0)
2692 {
2693 m_periodicEdges.insert(perIt);
2694 }
2695 }
2696 }
2697 break;
2698 default:
2699 ASSERTL1(false, "Not setup for this expansion");
2700 break;
2701 }
2702}
#define ASSERTL1(condition, msg)
Assert Level 1 – Debugging which is used whether in FULLDEBUG or DEBUG compilation mode....
Definition: ErrorUtil.hpp:242
#define sign(a, b)
return the sign(b)*a
Definition: Polylib.cpp:47
static SpatialDomains::BoundaryConditionShPtr GetBoundaryCondition(const SpatialDomains::BoundaryConditionCollection &collection, unsigned int index, const std::string &variable)
Definition: ExpList.cpp:5429
LibUtilities::CommSharedPtr m_comm
Communicator.
Definition: ExpList.h:1053
static StdRegions::Orientation GetFaceOrientation(const QuadGeom &face1, const QuadGeom &face2, bool doRot=false, int dir=0, NekDouble angle=0.0, NekDouble tol=1e-8)
Get the orientation of face1.
Definition: QuadGeom.cpp:135
static StdRegions::Orientation GetFaceOrientation(const TriGeom &face1, const TriGeom &face2, bool doRot, int dir, NekDouble angle, NekDouble tol)
Definition: TriGeom.cpp:115
std::shared_ptr< Comm > CommSharedPtr
Pointer to a Communicator object.
Definition: Comm.h:55
std::map< int, std::vector< PeriodicEntity > > PeriodicMap
std::map< int, BoundaryRegionShPtr > BoundaryRegionCollection
Definition: Conditions.h:210
std::map< int, std::vector< unsigned int > > CompositeOrdering
Definition: MeshGraph.h:107
std::shared_ptr< BoundaryConditionBase > BoundaryConditionShPtr
Definition: Conditions.h:212
std::shared_ptr< std::vector< std::pair< GeometrySharedPtr, int > > > GeometryLinkSharedPtr
Definition: MeshGraph.h:166
std::map< int, std::vector< unsigned int > > BndRegionOrdering
Definition: MeshGraph.h:108
std::shared_ptr< Composite > CompositeSharedPtr
Definition: MeshGraph.h:135
std::vector< PointGeomSharedPtr > PointGeomVector
Definition: Geometry2D.h:61
std::map< int, BoundaryConditionMapShPtr > BoundaryConditionCollection
Definition: Conditions.h:219
std::shared_ptr< SegGeom > SegGeomSharedPtr
Definition: Geometry2D.h:59
std::shared_ptr< Geometry2D > Geometry2DSharedPtr
Definition: Geometry.h:62
std::map< int, CompositeSharedPtr > CompositeMap
Definition: MeshGraph.h:136
std::vector< double > w(NPUPPER)
std::vector< double > z(NPUPPER)
double NekDouble
T Vsum(int n, const T *x, const int incx)
Subtract return sum(x)
Definition: Vmath.hpp:608
scalarT< T > sqrt(scalarT< T > in)
Definition: scalar.hpp:294

References Nektar::MemoryManager< DataType >::AllocateSharedPtr(), ASSERTL0, ASSERTL1, Nektar::LibUtilities::Interpreter::DefineFunction(), Nektar::SpatialDomains::PointGeom::dist(), Nektar::MultiRegions::e1D, Nektar::MultiRegions::e2D, Nektar::MultiRegions::e3D, Nektar::StdRegions::eBackwards, Nektar::StdRegions::eDir1BwdDir1_Dir2BwdDir2, Nektar::StdRegions::eDir1BwdDir1_Dir2FwdDir2, Nektar::StdRegions::eDir1BwdDir2_Dir2BwdDir1, Nektar::StdRegions::eDir1BwdDir2_Dir2FwdDir1, Nektar::StdRegions::eDir1FwdDir1_Dir2BwdDir2, Nektar::StdRegions::eDir1FwdDir1_Dir2FwdDir2, Nektar::StdRegions::eDir1FwdDir2_Dir2BwdDir1, Nektar::StdRegions::eDir1FwdDir2_Dir2FwdDir1, Nektar::ErrorUtil::efatal, Nektar::StdRegions::eForwards, Nektar::StdRegions::eNoOrientation, Nektar::SpatialDomains::ePeriodic, Nektar::LibUtilities::Interpreter::Evaluate(), Nektar::MultiRegions::ExpList::GetBoundaryCondition(), Nektar::SpatialDomains::BoundaryConditions::GetBoundaryConditions(), Nektar::SpatialDomains::BoundaryConditions::GetBoundaryRegions(), Nektar::SpatialDomains::QuadGeom::GetFaceOrientation(), Nektar::SpatialDomains::TriGeom::GetFaceOrientation(), Nektar::MultiRegions::RotPeriodicInfo::m_angle, Nektar::MultiRegions::ExpList::m_comm, Nektar::MultiRegions::RotPeriodicInfo::m_dir, Nektar::MultiRegions::ExpList::m_expType, Nektar::MultiRegions::ExpList::m_graph, m_periodicEdges, m_periodicFaces, m_periodicVerts, Nektar::MultiRegions::RotPeriodicInfo::m_tol, NEKERROR, CellMLToNektar.cellml_metadata::p, Nektar::LibUtilities::ReduceMax, Nektar::LibUtilities::ReduceSum, Nektar::SpatialDomains::PointGeom::Rotate(), sign, tinysimd::sqrt(), Vmath::Vsum(), Nektar::UnitTests::w(), and Nektar::UnitTests::z().

Referenced by DisContField().

◆ GenerateBoundaryConditionExpansion()

void Nektar::MultiRegions::DisContField::GenerateBoundaryConditionExpansion ( const SpatialDomains::MeshGraphSharedPtr graph,
const SpatialDomains::BoundaryConditions bcs,
const std::string  variable,
const bool  DeclareCoeffPhysArrays = true 
)
protected

Discretises the boundary conditions.

This function discretises the boundary conditions by setting up a list of one-dimensions lower boundary expansions.

According to their boundary region, the separate boundary expansions are bundled together in an object of the class

Parameters
graphA mesh, containing information about the domain and the spectral/hp element expansions.
bcsInformation about the enforced boundary conditions.
variableThe session variable associated with the boundary conditions to enforce.
DeclareCoeffPhysArraysbool to identify if array space should be setup. Default is true.

Definition at line 812 of file DisContField.cpp.

816{
817 int cnt = 0;
821 bcs.GetBoundaryRegions();
823 bcs.GetBoundaryConditions();
824
826 Array<OneD, MultiRegions::ExpListSharedPtr>(bregions.size());
828 Array<OneD, SpatialDomains::BoundaryConditionShPtr>(bregions.size());
829
830 m_bndCondBndWeight = Array<OneD, NekDouble>{bregions.size(), 0.0};
831
832 // count the number of non-periodic boundary points
833 for (auto &it : bregions)
834 {
835 bc = GetBoundaryCondition(bconditions, it.first, variable);
836
838 m_session, *(it.second), graph, DeclareCoeffPhysArrays, variable,
839 false, bc->GetComm());
840
841 m_bndCondExpansions[cnt] = locExpList;
842 m_bndConditions[cnt] = bc;
843
844 std::string type = m_bndConditions[cnt]->GetUserDefined();
845
846 // Set up normals on non-Dirichlet boundary conditions. Second
847 // two conditions ideally should be in local solver setup (when
848 // made into factory)
849 if (bc->GetBoundaryConditionType() != SpatialDomains::eDirichlet ||
850 boost::iequals(type, "I") || boost::iequals(type, "CalcBC"))
851 {
853 }
854 cnt++;
855 }
856}
Array< OneD, NekDouble > m_bndCondBndWeight
Definition: DisContField.h:158

References Nektar::MemoryManager< DataType >::AllocateSharedPtr(), Nektar::SpatialDomains::eDirichlet, Nektar::MultiRegions::ExpList::GetBoundaryCondition(), Nektar::SpatialDomains::BoundaryConditions::GetBoundaryConditions(), Nektar::SpatialDomains::BoundaryConditions::GetBoundaryRegions(), m_bndCondBndWeight, m_bndCondExpansions, m_bndConditions, Nektar::MultiRegions::ExpList::m_session, and Nektar::MultiRegions::ExpList::SetUpPhysNormals().

Referenced by DisContField().

◆ GenerateFieldBnd1D()

void Nektar::MultiRegions::DisContField::GenerateFieldBnd1D ( SpatialDomains::BoundaryConditions bcs,
const std::string  variable 
)
protected

◆ GetDomainBCs()

SpatialDomains::BoundaryConditionsSharedPtr Nektar::MultiRegions::DisContField::GetDomainBCs ( const SpatialDomains::CompositeMap domain,
const SpatialDomains::BoundaryConditions Allbcs,
const std::string &  variable 
)
private

Definition at line 517 of file DisContField.cpp.

521{
523
524 returnval =
526
527 map<int, int> GeometryToRegionsMap;
528
530 Allbcs.GetBoundaryRegions();
532 Allbcs.GetBoundaryConditions();
533
534 // Set up a map of all boundary regions
535 for (auto &it : bregions)
536 {
537 for (auto &bregionIt : *it.second)
538 {
539 // can assume that all regions only contain one point in 1D
540 // Really do not need loop above
541 int id = bregionIt.second->m_geomVec[0]->GetGlobalID();
542 GeometryToRegionsMap[id] = it.first;
543 }
544 }
545
546 map<int, SpatialDomains::GeometrySharedPtr> EndOfDomain;
547
548 // Now find out which points in domain have only one vertex
549 for (auto &domIt : domain)
550 {
551 SpatialDomains::CompositeSharedPtr geomvector = domIt.second;
552 for (int i = 0; i < geomvector->m_geomVec.size(); ++i)
553 {
554 for (int j = 0; j < 2; ++j)
555 {
556 int vid = geomvector->m_geomVec[i]->GetVid(j);
557 if (EndOfDomain.count(vid) == 0)
558 {
559 EndOfDomain[vid] = geomvector->m_geomVec[i]->GetVertex(j);
560 }
561 else
562 {
563 EndOfDomain.erase(vid);
564 }
565 }
566 }
567 }
568 ASSERTL1(EndOfDomain.size() == 2, "Did not find two ends of domain");
569
570 for (auto &regIt : EndOfDomain)
571 {
572 if (GeometryToRegionsMap.count(regIt.first) != 0)
573 {
574 // Set up boundary condition up
575 auto iter = GeometryToRegionsMap.find(regIt.first);
576 ASSERTL1(iter != GeometryToRegionsMap.end(),
577 "Failied to find GeometryToRegionMap");
578
579 int regionId = iter->second;
580 auto bregionsIter = bregions.find(regionId);
581 ASSERTL1(bregionsIter != bregions.end(),
582 "Failed to find boundary region");
583
584 SpatialDomains::BoundaryRegionShPtr breg = bregionsIter->second;
585 returnval->AddBoundaryRegions(regionId, breg);
586
587 auto bconditionsIter = bconditions.find(regionId);
588 ASSERTL1(bconditionsIter != bconditions.end(),
589 "Failed to find boundary collection");
590
592 bconditionsIter->second;
593 returnval->AddBoundaryConditions(regionId, bcond);
594 }
595 }
596
597 return returnval;
598}
std::shared_ptr< BoundaryRegion > BoundaryRegionShPtr
Definition: Conditions.h:208
std::shared_ptr< BoundaryConditionMap > BoundaryConditionMapShPtr
Definition: Conditions.h:218

References Nektar::MemoryManager< DataType >::AllocateSharedPtr(), ASSERTL1, Nektar::SpatialDomains::BoundaryConditions::GetBoundaryConditions(), and Nektar::SpatialDomains::BoundaryConditions::GetBoundaryRegions().

Referenced by DisContField().

◆ GetFwdBwdTracePhys()

void Nektar::MultiRegions::DisContField::GetFwdBwdTracePhys ( const Array< OneD, const NekDouble > &  field,
Array< OneD, NekDouble > &  Fwd,
Array< OneD, NekDouble > &  Bwd,
const Array< OneD, const SpatialDomains::BoundaryConditionShPtr > &  BndCond,
const Array< OneD, const ExpListSharedPtr > &  BndCondExp 
)

This method extracts the "forward" and "backward" trace data from the array field and puts the data into output vectors Fwd and Bwd.

We first define the convention which defines "forwards" and "backwards". First an association is made between the vertex/edge/face of each element and its corresponding vertex/edge/face in the trace space using the mapping m_traceMap. The element can either be left-adjacent or right-adjacent to this trace face (see Expansion2D::GetLeftAdjacentElementExp). Boundary faces are always left-adjacent since left-adjacency is populated first.

If the element is left-adjacent we extract the trace data from field into the forward trace space Fwd; otherwise, we place it in the backwards trace space Bwd. In this way, we form a unique set of trace normals since these are always extracted from left-adjacent elements.

Parameters
fieldis a NekDouble array which contains the fielddata from which we wish to extract the backward and forward orientated trace/face arrays.
Returns
Updates a NekDouble array Fwd and Bwd

Definition at line 2910 of file DisContField.cpp.

2915{
2916 ASSERTL1((*m_exp)[0]->GetBasis(0)->GetBasisType() !=
2918 "Routine not set up for Gauss Lagrange points distribution");
2919
2920 // blocked routine
2921 Array<OneD, NekDouble> tracevals(m_locTraceToTraceMap->GetNLocTracePts());
2922
2923 m_locTraceToTraceMap->LocTracesFromField(field, tracevals);
2924 m_locTraceToTraceMap->InterpLocTracesToTrace(0, tracevals, Fwd);
2925
2926 Array<OneD, NekDouble> invals =
2927 tracevals + m_locTraceToTraceMap->GetNFwdLocTracePts();
2928 m_locTraceToTraceMap->InterpLocTracesToTrace(1, invals, Bwd);
2929
2931
2932 FillBwdWithBoundCond(Fwd, Bwd, BndCond, BndCondExp, false);
2933
2934 // Do parallel exchange for forwards/backwards spaces.
2935 m_traceMap->GetAssemblyCommDG()->PerformExchange(Fwd, Bwd);
2936
2937 // Do exchange of interface traces (local and parallel)
2938 // We may have to split this out into separate local and
2939 // parallel for IP method???
2940 m_interfaceMap->ExchangeTrace(Fwd, Bwd);
2941}
void v_PeriodicBwdCopy(const Array< OneD, const NekDouble > &Fwd, Array< OneD, NekDouble > &Bwd) override
void FillBwdWithBoundCond(const Array< OneD, NekDouble > &Fwd, Array< OneD, NekDouble > &Bwd, const Array< OneD, const SpatialDomains::BoundaryConditionShPtr > &bndConditions, const Array< OneD, const ExpListSharedPtr > &BndCondExpansions, bool PutFwdInBwdOnBCs)
@ eGauss_Lagrange
Lagrange Polynomials using the Gauss points.
Definition: BasisType.h:57

References ASSERTL1, Nektar::LibUtilities::eGauss_Lagrange, FillBwdWithBoundCond(), Nektar::MultiRegions::ExpList::m_exp, m_interfaceMap, m_locTraceToTraceMap, m_traceMap, and v_PeriodicBwdCopy().

◆ GetGlobalBndLinSys()

GlobalLinSysSharedPtr Nektar::MultiRegions::DisContField::GetGlobalBndLinSys ( const GlobalLinSysKey mkey)

For a given key, returns the associated global linear system.

Definition at line 2707 of file DisContField.cpp.

2709{
2710 ASSERTL0(mkey.GetMatrixType() == StdRegions::eHybridDGHelmBndLam,
2711 "Routine currently only tested for HybridDGHelmholtz");
2712
2713 ASSERTL1(mkey.GetGlobalSysSolnType() != eDirectFullMatrix,
2714 "Full matrix global systems are not supported for HDG "
2715 "expansions");
2716
2717 ASSERTL1(mkey.GetGlobalSysSolnType() == m_traceMap->GetGlobalSysSolnType(),
2718 "The local to global map is not set up for the requested "
2719 "solution type");
2720
2721 GlobalLinSysSharedPtr glo_matrix;
2722 auto matrixIter = m_globalBndMat->find(mkey);
2723
2724 if (matrixIter == m_globalBndMat->end())
2725 {
2726 glo_matrix = GenGlobalBndLinSys(mkey, m_traceMap);
2727 (*m_globalBndMat)[mkey] = glo_matrix;
2728 }
2729 else
2730 {
2731 glo_matrix = matrixIter->second;
2732 }
2733
2734 return glo_matrix;
2735}
std::shared_ptr< GlobalLinSys > GenGlobalBndLinSys(const GlobalLinSysKey &mkey, const AssemblyMapSharedPtr &locToGloMap)
Generate a GlobalLinSys from information provided by the key "mkey" and the mapping provided in LocTo...
Definition: ExpList.cpp:2800
std::shared_ptr< GlobalLinSys > GlobalLinSysSharedPtr
Pointer to a GlobalLinSys object.
Definition: GlobalLinSys.h:51

References ASSERTL0, ASSERTL1, Nektar::MultiRegions::eDirectFullMatrix, Nektar::StdRegions::eHybridDGHelmBndLam, Nektar::MultiRegions::ExpList::GenGlobalBndLinSys(), Nektar::MultiRegions::GlobalLinSysKey::GetGlobalSysSolnType(), Nektar::MultiRegions::GlobalMatrixKey::GetMatrixType(), m_globalBndMat, and m_traceMap.

Referenced by v_HelmSolve().

◆ GetLocTraceToTraceMap()

void Nektar::MultiRegions::DisContField::GetLocTraceToTraceMap ( LocTraceToTraceMapSharedPtr LocTraceToTraceMap)
inline

Definition at line 123 of file DisContField.h.

125 {
126 LocTraceToTraceMap = m_locTraceToTraceMap;
127 }

References m_locTraceToTraceMap.

◆ GetNegatedFluxNormal()

vector< bool > & Nektar::MultiRegions::DisContField::GetNegatedFluxNormal ( void  )

Definition at line 2771 of file DisContField.cpp.

2772{
2773 if (m_negatedFluxNormal.size() == 0)
2774 {
2775 Array<OneD, Array<OneD, LocalRegions::ExpansionSharedPtr>>
2776 &elmtToTrace = m_traceMap->GetElmtToTrace();
2777
2778 m_negatedFluxNormal.resize(2 * GetExpSize());
2779
2780 for (int i = 0; i < GetExpSize(); ++i)
2781 {
2782
2783 for (int v = 0; v < 2; ++v)
2784 {
2786 elmtToTrace[i][v]->as<LocalRegions::Expansion0D>();
2787
2788 if (vertExp->GetLeftAdjacentElementExp()
2789 ->GetGeom()
2790 ->GetGlobalID() !=
2791 (*m_exp)[i]->GetGeom()->GetGlobalID())
2792 {
2793 m_negatedFluxNormal[2 * i + v] = true;
2794 }
2795 else
2796 {
2797 m_negatedFluxNormal[2 * i + v] = false;
2798 }
2799 }
2800 }
2801 }
2802
2803 return m_negatedFluxNormal;
2804}
std::vector< bool > m_negatedFluxNormal
Definition: DisContField.h:337
std::shared_ptr< Expansion0D > Expansion0DSharedPtr
Definition: Expansion0D.h:47

References Nektar::MultiRegions::ExpList::GetExpSize(), m_negatedFluxNormal, and m_traceMap.

Referenced by v_AddTraceIntegral().

◆ IsLeftAdjacentTrace()

bool Nektar::MultiRegions::DisContField::IsLeftAdjacentTrace ( const int  n,
const int  e 
)
protected

This routine determines if an element is to the "left" of the adjacent trace, which arises from the idea there is a local normal direction between two elements (i.e. on the trace) and one elements would then be the left.

This is typically required since we only define one normal direction along the trace which goes from the left adjacent element to the right adjacent element. It is also useful in DG discretisations to set up a local Riemann problem where we need to have the concept of a local normal direction which is unique between two elements.

There are two cases to be checked:

1) First is the trace on a boundary condition (perioidic or otherwise) or on a partition boundary. If a partition boundary then trace is always considered to be the left adjacent trace and the normal is pointing outward of the soltuion domain. We have to perform an additional case for a periodic boundary where wer chose the element with the lowest global id. If the trace is on a parallel partition we use a member of the traceMap where one side is chosen to contribute to a unique map and have a value which is not -1 so this is the identifier for the left adjacent side

2) If the element is a elemental boundary on one element the left adjacent element is defined by a link to the left element from the trace expansion and this is consistent with the defitiion of the normal which is determined by the largest id (in contrast to the periodic boundary definition !). This reversal of convention does not really matter providing the normals are defined consistently.

Definition at line 476 of file DisContField.cpp.

477{
479 m_traceMap->GetElmtToTrace()[n][e];
480
481 PeriodicMap periodicTraces = (m_expType == e1D) ? m_periodicVerts
484
485 bool fwd = true;
486 if (traceEl->GetLeftAdjacentElementTrace() == -1 ||
487 traceEl->GetRightAdjacentElementTrace() == -1)
488 {
489 // Boundary edge (1 connected element). Do nothing in
490 // serial.
491 auto it = m_boundaryTraces.find(traceEl->GetElmtId());
492
493 // If the edge does not have a boundary condition set on
494 // it, then assume it is a partition edge or periodic.
495 if (it == m_boundaryTraces.end())
496 {
497 fwd = true;
498 }
499 }
500 else if (traceEl->GetLeftAdjacentElementTrace() != -1 &&
501 traceEl->GetRightAdjacentElementTrace() != -1)
502 {
503 // Non-boundary edge (2 connected elements).
504 fwd = (traceEl->GetLeftAdjacentElementExp().get()) == (*m_exp)[n].get();
505 }
506 else
507 {
508 ASSERTL2(false, "Unconnected trace element!");
509 }
510
511 return fwd;
512}
#define ASSERTL2(condition, msg)
Assert Level 2 – Debugging which is used FULLDEBUG compilation mode. This level assert is designed to...
Definition: ErrorUtil.hpp:265

References ASSERTL2, Nektar::MultiRegions::e1D, Nektar::MultiRegions::e2D, m_boundaryTraces, Nektar::MultiRegions::ExpList::m_exp, Nektar::MultiRegions::ExpList::m_expType, m_periodicEdges, m_periodicFaces, m_periodicVerts, and m_traceMap.

Referenced by SetUpDG().

◆ L2_DGDeriv()

NekDouble Nektar::MultiRegions::DisContField::L2_DGDeriv ( const int  dir,
const Array< OneD, const NekDouble > &  coeffs,
const Array< OneD, const NekDouble > &  soln 
)

Calculate the \( L^2 \) error of the \( Q_{\rm dir} \) derivative using the consistent DG evaluation of \( Q_{\rm dir} \).

The solution provided is of the primative variation at the quadrature points and the derivative is compared to the discrete derivative at these points, which is likely to be undesirable unless using a much higher number of quadrature points than the polynomial order used to evaluate \( Q_{\rm dir} \).

Definition at line 4171 of file DisContField.cpp.

4174{
4175 int i, e, ncoeff_edge;
4176 Array<OneD, const NekDouble> tmp_coeffs;
4177 Array<OneD, NekDouble> out_d(m_ncoeffs), out_tmp;
4178
4179 Array<OneD, Array<OneD, LocalRegions::ExpansionSharedPtr>> &elmtToTrace =
4180 m_traceMap->GetElmtToTrace();
4181
4183
4184 int cnt;
4185 int LocBndCoeffs = m_traceMap->GetNumLocalBndCoeffs();
4186 Array<OneD, NekDouble> loc_lambda(LocBndCoeffs), edge_lambda;
4187 m_traceMap->GlobalToLocalBnd(m_trace->GetCoeffs(), loc_lambda);
4188
4189 edge_lambda = loc_lambda;
4190
4191 // Calculate Q using standard DG formulation.
4192 for (i = cnt = 0; i < GetExpSize(); ++i)
4193 {
4194 // Probably a better way of setting up lambda than this.
4195 // Note cannot use PutCoeffsInToElmts since lambda space
4196 // is mapped during the solve.
4197 int nEdges = (*m_exp)[i]->GetGeom()->GetNumEdges();
4198 Array<OneD, Array<OneD, NekDouble>> edgeCoeffs(nEdges);
4199
4200 for (e = 0; e < nEdges; ++e)
4201 {
4202 edgedir = (*m_exp)[i]->GetTraceOrient(e);
4203 ncoeff_edge = elmtToTrace[i][e]->GetNcoeffs();
4204 edgeCoeffs[e] = Array<OneD, NekDouble>(ncoeff_edge);
4205 Vmath::Vcopy(ncoeff_edge, edge_lambda, 1, edgeCoeffs[e], 1);
4206 elmtToTrace[i][e]->SetCoeffsToOrientation(edgedir, edgeCoeffs[e],
4207 edgeCoeffs[e]);
4208 edge_lambda = edge_lambda + ncoeff_edge;
4209 }
4210
4211 (*m_exp)[i]->DGDeriv(dir, tmp_coeffs = coeffs + m_coeff_offset[i],
4212 elmtToTrace[i], edgeCoeffs, out_tmp = out_d + cnt);
4213 cnt += (*m_exp)[i]->GetNcoeffs();
4214 }
4215
4216 Array<OneD, NekDouble> phys(m_npoints);
4217 BwdTrans(out_d, phys);
4218 Vmath::Vsub(m_npoints, phys, 1, soln, 1, phys, 1);
4219 return L2(phys);
4220}
int m_ncoeffs
The total number of local degrees of freedom. m_ncoeffs .
Definition: ExpList.h:1060
NekDouble L2(const Array< OneD, const NekDouble > &inarray, const Array< OneD, const NekDouble > &soln=NullNekDouble1DArray)
This function calculates the error of the global This function calculates the error with respect to...
Definition: ExpList.h:509
void BwdTrans(const Array< OneD, const NekDouble > &inarray, Array< OneD, NekDouble > &outarray)
This function elementally evaluates the backward transformation of the global spectral/hp element exp...
Definition: ExpList.h:1717
void Vsub(int n, const T *x, const int incx, const T *y, const int incy, T *z, const int incz)
Subtract vector z = x-y.
Definition: Vmath.hpp:220

References Nektar::MultiRegions::ExpList::BwdTrans(), Nektar::MultiRegions::ExpList::GetExpSize(), Nektar::MultiRegions::ExpList::L2(), Nektar::MultiRegions::ExpList::m_coeff_offset, Nektar::MultiRegions::ExpList::m_ncoeffs, Nektar::MultiRegions::ExpList::m_npoints, m_trace, m_traceMap, Vmath::Vcopy(), and Vmath::Vsub().

◆ SameTypeOfBoundaryConditions()

bool Nektar::MultiRegions::DisContField::SameTypeOfBoundaryConditions ( const DisContField In)

Check to see if expansion has the same BCs as In.

For each boundary region, checks that the types and number of boundary expansions in that region match.

Parameters
InField to compare with.
Returns
True if boundary conditions match.

Definition at line 2743 of file DisContField.cpp.

2744{
2745 int i;
2746 bool returnval = true;
2747
2748 for (i = 0; i < m_bndConditions.size(); ++i)
2749 {
2750 // check to see if boundary condition type is the same
2751 // and there are the same number of boundary
2752 // conditions in the boundary definition.
2753 if ((m_bndConditions[i]->GetBoundaryConditionType() !=
2754 In.m_bndConditions[i]->GetBoundaryConditionType()) ||
2755 (m_bndCondExpansions[i]->GetExpSize() !=
2756 In.m_bndCondExpansions[i]->GetExpSize()))
2757 {
2758 returnval = false;
2759 break;
2760 }
2761 }
2762
2763 // Compare with all other processes. Return true only if all
2764 // processes report having the same boundary conditions.
2765 int vSame = (returnval ? 1 : 0);
2766 m_comm->GetRowComm()->AllReduce(vSame, LibUtilities::ReduceMin);
2767
2768 return (vSame == 1);
2769}

References m_bndCondExpansions, m_bndConditions, Nektar::MultiRegions::ExpList::m_comm, and Nektar::LibUtilities::ReduceMin.

Referenced by Nektar::MultiRegions::ContField::ContField(), and DisContField().

◆ SetUpDG()

void Nektar::MultiRegions::DisContField::SetUpDG ( const std::string  variable = "DefaultVar",
const Collections::ImplementationType  ImpType = Collections::eNoImpType 
)
protected

Set up all DG member variables and maps.

Definition at line 161 of file DisContField.cpp.

163{
164 // Check for multiple calls
166 {
167 return;
168 }
169
170 // Set up matrix map
172
173 // Set up trace space
176 m_comm, true, "DefaultVar", ImpType);
177
178 PeriodicMap periodicTraces = (m_expType == e1D) ? m_periodicVerts
181
184 m_bndConditions, periodicTraces, variable);
185
186 if (m_session->DefinesCmdLineArgument("verbose"))
187 {
188 m_traceMap->PrintStats(std::cout, variable);
189 }
190
191 Array<OneD, Array<OneD, LocalRegions::ExpansionSharedPtr>> &elmtToTrace =
192 m_traceMap->GetElmtToTrace();
193
194 // Scatter trace to elements. For each element, we find
195 // the trace associated to each elemental trace. The element
196 // then retains a pointer to the elemental trace, to
197 // ensure uniqueness of normals when retrieving from two
198 // adjoining elements which do not lie in a plane.
199 for (int i = 0; i < m_exp->size(); ++i)
200 {
201 for (int j = 0; j < (*m_exp)[i]->GetNtraces(); ++j)
202 {
203 LocalRegions::ExpansionSharedPtr exp = elmtToTrace[i][j];
204 ;
205
206 exp->SetAdjacentElementExp(j, (*m_exp)[i]);
207 (*m_exp)[i]->SetTraceExp(j, exp);
208 }
209 }
210
211 // Set up physical normals
213
214 // Create interface exchange object
217
218 int cnt, n;
219
220 // Identify boundary trace
221 for (cnt = 0, n = 0; n < m_bndCondExpansions.size(); ++n)
222 {
223 if (m_bndConditions[n]->GetBoundaryConditionType() !=
225 {
226 for (int v = 0; v < m_bndCondExpansions[n]->GetExpSize(); ++v)
227 {
228 m_boundaryTraces.insert(
229 m_traceMap->GetBndCondIDToGlobalTraceID(cnt + v));
230 }
231 cnt += m_bndCondExpansions[n]->GetExpSize();
232 }
233 }
234
235 // Set up information for periodic boundary conditions.
236 std::unordered_map<int, pair<int, int>> perTraceToExpMap;
237 for (cnt = n = 0; n < m_exp->size(); ++n)
238 {
239 for (int v = 0; v < (*m_exp)[n]->GetNtraces(); ++v, ++cnt)
240 {
241 auto it = periodicTraces.find((*m_exp)[n]->GetGeom()->GetTid(v));
242
243 if (it != periodicTraces.end())
244 {
245 perTraceToExpMap[it->first] = make_pair(n, v);
246 }
247 }
248 }
249
250 // Set up left-adjacent tracelist.
251 m_leftAdjacentTraces.resize(cnt);
252
253 // count size of trace
254 for (cnt = n = 0; n < m_exp->size(); ++n)
255 {
256 for (int v = 0; v < (*m_exp)[n]->GetNtraces(); ++v, ++cnt)
257 {
259 }
260 }
261
262 // Set up mapping to copy Fwd of periodic bcs to Bwd of other edge.
263 for (cnt = n = 0; n < m_exp->size(); ++n)
264 {
265 for (int v = 0; v < (*m_exp)[n]->GetNtraces(); ++v, ++cnt)
266 {
267 int GeomId = (*m_exp)[n]->GetGeom()->GetTid(v);
268
269 // Check to see if this trace is periodic.
270 auto it = periodicTraces.find(GeomId);
271
272 if (it != periodicTraces.end())
273 {
274 const PeriodicEntity &ent = it->second[0];
275 auto it2 = perTraceToExpMap.find(ent.id);
276
277 if (it2 == perTraceToExpMap.end())
278 {
279 if (m_session->GetComm()->GetRowComm()->GetSize() > 1 &&
280 !ent.isLocal)
281 {
282 continue;
283 }
284 else
285 {
286 ASSERTL1(false, "Periodic trace not found!");
287 }
288 }
289
291 "Periodic trace in non-forward space?");
292
293 int offset = m_trace->GetPhys_Offset(
294 (m_traceMap->GetElmtToTrace())[n][v]->GetElmtId());
295
296 int offset2 = m_trace->GetPhys_Offset(
297 (m_traceMap->GetElmtToTrace())[it2->second.first]
298 [it2->second.second]
299 ->GetElmtId());
300
301 switch (m_expType)
302 {
303 case e1D:
304 {
305 m_periodicFwdCopy.push_back(offset);
306 m_periodicBwdCopy.push_back(offset2);
307 }
308 break;
309 case e2D:
310 {
311 // Calculate relative orientations between trace to
312 // calculate copying map.
313 int nquad = elmtToTrace[n][v]->GetNumPoints(0);
314
315 vector<int> tmpBwd(nquad);
316 vector<int> tmpFwd(nquad);
317
318 if (ent.orient == StdRegions::eForwards)
319 {
320 for (int i = 0; i < nquad; ++i)
321 {
322 tmpBwd[i] = offset2 + i;
323 tmpFwd[i] = offset + i;
324 }
325 }
326 else
327 {
328 for (int i = 0; i < nquad; ++i)
329 {
330 tmpBwd[i] = offset2 + i;
331 tmpFwd[i] = offset + nquad - i - 1;
332 }
333 }
334
335 for (int i = 0; i < nquad; ++i)
336 {
337 m_periodicFwdCopy.push_back(tmpFwd[i]);
338 m_periodicBwdCopy.push_back(tmpBwd[i]);
339 }
340 }
341 break;
342 case e3D:
343 {
344 // Calculate relative orientations between faces to
345 // calculate copying map.
346 int nquad1 = elmtToTrace[n][v]->GetNumPoints(0);
347 int nquad2 = elmtToTrace[n][v]->GetNumPoints(1);
348
349 vector<int> tmpBwd(nquad1 * nquad2);
350 vector<int> tmpFwd(nquad1 * nquad2);
351
352 if (ent.orient ==
354 ent.orient ==
356 ent.orient ==
359 {
360 for (int i = 0; i < nquad2; ++i)
361 {
362 for (int j = 0; j < nquad1; ++j)
363 {
364 tmpBwd[i * nquad1 + j] =
365 offset2 + i * nquad1 + j;
366 tmpFwd[i * nquad1 + j] =
367 offset + j * nquad2 + i;
368 }
369 }
370 }
371 else
372 {
373 for (int i = 0; i < nquad2; ++i)
374 {
375 for (int j = 0; j < nquad1; ++j)
376 {
377 tmpBwd[i * nquad1 + j] =
378 offset2 + i * nquad1 + j;
379 tmpFwd[i * nquad1 + j] =
380 offset + i * nquad1 + j;
381 }
382 }
383 }
384
385 if (ent.orient ==
387 ent.orient ==
389 ent.orient ==
392 {
393 // Reverse x direction
394 for (int i = 0; i < nquad2; ++i)
395 {
396 for (int j = 0; j < nquad1 / 2; ++j)
397 {
398 swap(tmpFwd[i * nquad1 + j],
399 tmpFwd[i * nquad1 + nquad1 - j - 1]);
400 }
401 }
402 }
403
404 if (ent.orient ==
406 ent.orient ==
408 ent.orient ==
411 {
412 // Reverse y direction
413 for (int j = 0; j < nquad1; ++j)
414 {
415 for (int i = 0; i < nquad2 / 2; ++i)
416 {
417 swap(tmpFwd[i * nquad1 + j],
418 tmpFwd[(nquad2 - i - 1) * nquad1 + j]);
419 }
420 }
421 }
422
423 for (int i = 0; i < nquad1 * nquad2; ++i)
424 {
425 m_periodicFwdCopy.push_back(tmpFwd[i]);
426 m_periodicBwdCopy.push_back(tmpBwd[i]);
427 }
428 }
429 break;
430 default:
431 ASSERTL1(false, "not set up");
432 }
433 }
434 }
435 }
436
438 *this, m_trace, elmtToTrace, m_leftAdjacentTraces);
439}
bool IsLeftAdjacentTrace(const int n, const int e)
This routine determines if an element is to the "left" of the adjacent trace, which arises from the i...

References Nektar::MemoryManager< DataType >::AllocateSharedPtr(), ASSERTL1, Nektar::MultiRegions::e1D, Nektar::MultiRegions::e2D, Nektar::MultiRegions::e3D, Nektar::StdRegions::eDir1BwdDir1_Dir2BwdDir2, Nektar::StdRegions::eDir1BwdDir1_Dir2FwdDir2, Nektar::StdRegions::eDir1BwdDir2_Dir2BwdDir1, Nektar::StdRegions::eDir1BwdDir2_Dir2FwdDir1, Nektar::StdRegions::eDir1FwdDir1_Dir2BwdDir2, Nektar::StdRegions::eDir1FwdDir2_Dir2BwdDir1, Nektar::StdRegions::eDir1FwdDir2_Dir2FwdDir1, Nektar::StdRegions::eForwards, Nektar::SpatialDomains::ePeriodic, Nektar::MultiRegions::PeriodicEntity::id, IsLeftAdjacentTrace(), Nektar::MultiRegions::PeriodicEntity::isLocal, m_bndCondExpansions, m_bndConditions, m_boundaryTraces, Nektar::MultiRegions::ExpList::m_comm, Nektar::MultiRegions::ExpList::m_exp, Nektar::MultiRegions::ExpList::m_expType, m_globalBndMat, Nektar::MultiRegions::ExpList::m_graph, m_interfaceMap, m_leftAdjacentTraces, m_locTraceToTraceMap, m_periodicBwdCopy, m_periodicEdges, m_periodicFaces, m_periodicFwdCopy, m_periodicVerts, Nektar::MultiRegions::ExpList::m_session, m_trace, m_traceMap, Nektar::MultiRegions::NullExpListSharedPtr, Nektar::MultiRegions::PeriodicEntity::orient, and Nektar::MultiRegions::ExpList::SetUpPhysNormals().

Referenced by DisContField(), and v_GetTrace().

◆ v_AddFwdBwdTraceIntegral()

void Nektar::MultiRegions::DisContField::v_AddFwdBwdTraceIntegral ( const Array< OneD, const NekDouble > &  Fwd,
const Array< OneD, const NekDouble > &  Bwd,
Array< OneD, NekDouble > &  outarray 
)
overrideprotectedvirtual

Add trace contributions into elemental coefficient spaces.

Given some quantity \( \vec{q} \), calculate the elemental integral

\[ \int_{\Omega^e} \vec{q}, \mathrm{d}S \]

and adds this to the coefficient space provided by outarray. The value of q is determined from the routine IsLeftAdjacentTrace() which if true we use Fwd else we use Bwd

Parameters
FwdThe trace quantities associated with left (fwd) adjancent elmt.
BwdThe trace quantities associated with right (bwd) adjacent elet.
outarrayResulting coefficient space.

Reimplemented from Nektar::MultiRegions::ExpList.

Definition at line 3419 of file DisContField.cpp.

3422{
3423 ASSERTL0(m_expType != e1D, "This method is not setup or "
3424 "tested for 1D expansion");
3425 Array<OneD, NekDouble> Coeffs(m_trace->GetNcoeffs());
3426 m_trace->IProductWRTBase(Fwd, Coeffs);
3427 m_locTraceToTraceMap->AddTraceCoeffsToFieldCoeffs(0, Coeffs, outarray);
3428 m_trace->IProductWRTBase(Bwd, Coeffs);
3429 m_locTraceToTraceMap->AddTraceCoeffsToFieldCoeffs(1, Coeffs, outarray);
3430}

References ASSERTL0, Nektar::MultiRegions::e1D, Nektar::MultiRegions::ExpList::m_expType, m_locTraceToTraceMap, and m_trace.

◆ v_AddTraceIntegral()

void Nektar::MultiRegions::DisContField::v_AddTraceIntegral ( const Array< OneD, const NekDouble > &  Fn,
Array< OneD, NekDouble > &  outarray 
)
overrideprotectedvirtual

Add trace contributions into elemental coefficient spaces.

Given some quantity \( \vec{Fn} \), which conatins this routine calculates the integral

\[ \int_{\Omega^e} \vec{Fn}, \mathrm{d}S \]

and adds this to the coefficient space provided by outarray.

See also
Expansion3D::AddFaceNormBoundaryInt
Parameters
FnThe trace quantities.
outarrayResulting 3D coefficient space.

Reimplemented from Nektar::MultiRegions::ExpList.

Definition at line 3248 of file DisContField.cpp.

3250{
3251 if (m_expType == e1D)
3252 {
3253 int n, offset, t_offset;
3254 Array<OneD, Array<OneD, LocalRegions::ExpansionSharedPtr>>
3255 &elmtToTrace = m_traceMap->GetElmtToTrace();
3256 vector<bool> negatedFluxNormal = GetNegatedFluxNormal();
3257 for (n = 0; n < GetExpSize(); ++n)
3258 {
3259 // Number of coefficients on each element
3260 int e_ncoeffs = (*m_exp)[n]->GetNcoeffs();
3261 offset = GetCoeff_Offset(n);
3262 // Implementation for every points except Gauss points
3263 if ((*m_exp)[n]->GetBasis(0)->GetBasisType() !=
3265 {
3266 t_offset =
3267 GetTrace()->GetCoeff_Offset(elmtToTrace[n][0]->GetElmtId());
3268 if (negatedFluxNormal[2 * n])
3269 {
3270 outarray[offset] -= Fn[t_offset];
3271 }
3272 else
3273 {
3274 outarray[offset] += Fn[t_offset];
3275 }
3276 t_offset =
3277 GetTrace()->GetCoeff_Offset(elmtToTrace[n][1]->GetElmtId());
3278 if (negatedFluxNormal[2 * n + 1])
3279 {
3280 outarray[offset + (*m_exp)[n]->GetVertexMap(1)] -=
3281 Fn[t_offset];
3282 }
3283 else
3284 {
3285 outarray[offset + (*m_exp)[n]->GetVertexMap(1)] +=
3286 Fn[t_offset];
3287 }
3288 }
3289 else
3290 {
3291 int j;
3292 static DNekMatSharedPtr m_Ixm, m_Ixp;
3293 static int sav_ncoeffs = 0;
3294 if (!m_Ixm.get() || e_ncoeffs != sav_ncoeffs)
3295 {
3297 const LibUtilities::PointsKey BS_p(
3299 const LibUtilities::BasisKey BS_k(
3300 LibUtilities::eGauss_Lagrange, e_ncoeffs, BS_p);
3301 BASE = LibUtilities::BasisManager()[BS_k];
3302 Array<OneD, NekDouble> coords(1, 0.0);
3303 coords[0] = -1.0;
3304 m_Ixm = BASE->GetI(coords);
3305 coords[0] = 1.0;
3306 m_Ixp = BASE->GetI(coords);
3307 sav_ncoeffs = e_ncoeffs;
3308 }
3309 t_offset =
3310 GetTrace()->GetCoeff_Offset(elmtToTrace[n][0]->GetElmtId());
3311 if (negatedFluxNormal[2 * n])
3312 {
3313 for (j = 0; j < e_ncoeffs; j++)
3314 {
3315 outarray[offset + j] -=
3316 (m_Ixm->GetPtr())[j] * Fn[t_offset];
3317 }
3318 }
3319 else
3320 {
3321 for (j = 0; j < e_ncoeffs; j++)
3322 {
3323 outarray[offset + j] +=
3324 (m_Ixm->GetPtr())[j] * Fn[t_offset];
3325 }
3326 }
3327 t_offset =
3328 GetTrace()->GetCoeff_Offset(elmtToTrace[n][1]->GetElmtId());
3329 if (negatedFluxNormal[2 * n + 1])
3330 {
3331 for (j = 0; j < e_ncoeffs; j++)
3332 {
3333 outarray[offset + j] -=
3334 (m_Ixp->GetPtr())[j] * Fn[t_offset];
3335 }
3336 }
3337 else
3338 {
3339 for (j = 0; j < e_ncoeffs; j++)
3340 {
3341 outarray[offset + j] +=
3342 (m_Ixp->GetPtr())[j] * Fn[t_offset];
3343 }
3344 }
3345 }
3346 }
3347 }
3348 else // other dimensions
3349 {
3350 // Basis definition on each element
3351 LibUtilities::BasisSharedPtr basis = (*m_exp)[0]->GetBasis(0);
3352 if ((m_expType != e1D) &&
3353 (basis->GetBasisType() != LibUtilities::eGauss_Lagrange))
3354 {
3355 Array<OneD, NekDouble> Fcoeffs(m_trace->GetNcoeffs());
3356 m_trace->IProductWRTBase(Fn, Fcoeffs);
3357 m_locTraceToTraceMap->AddTraceCoeffsToFieldCoeffs(Fcoeffs,
3358 outarray);
3359 }
3360 else
3361 {
3362 int e, n, offset, t_offset;
3363 Array<OneD, NekDouble> e_outarray;
3364 Array<OneD, Array<OneD, LocalRegions::ExpansionSharedPtr>>
3365 &elmtToTrace = m_traceMap->GetElmtToTrace();
3366 if (m_expType == e2D)
3367 {
3368 for (n = 0; n < GetExpSize(); ++n)
3369 {
3370 offset = GetCoeff_Offset(n);
3371 for (e = 0; e < (*m_exp)[n]->GetNtraces(); ++e)
3372 {
3373 t_offset = GetTrace()->GetPhys_Offset(
3374 elmtToTrace[n][e]->GetElmtId());
3375 (*m_exp)[n]->AddEdgeNormBoundaryInt(
3376 e, elmtToTrace[n][e], Fn + t_offset,
3377 e_outarray = outarray + offset);
3378 }
3379 }
3380 }
3381 else if (m_expType == e3D)
3382 {
3383 for (n = 0; n < GetExpSize(); ++n)
3384 {
3385 offset = GetCoeff_Offset(n);
3386 for (e = 0; e < (*m_exp)[n]->GetNtraces(); ++e)
3387 {
3388 t_offset = GetTrace()->GetPhys_Offset(
3389 elmtToTrace[n][e]->GetElmtId());
3390 (*m_exp)[n]->AddFaceNormBoundaryInt(
3391 e, elmtToTrace[n][e], Fn + t_offset,
3392 e_outarray = outarray + offset);
3393 }
3394 }
3395 }
3396 }
3397 }
3398}
std::vector< bool > & GetNegatedFluxNormal(void)
std::shared_ptr< ExpList > & GetTrace()
Definition: ExpList.h:2162
int GetCoeff_Offset(int n) const
Get the start offset position for a local contiguous list of coeffs correspoinding to element n.
Definition: ExpList.h:2087
BasisManagerT & BasisManager(void)
std::shared_ptr< Basis > BasisSharedPtr
@ eGaussGaussLegendre
1D Gauss-Gauss-Legendre quadrature points
Definition: PointsType.h:46
std::shared_ptr< DNekMat > DNekMatSharedPtr
Definition: NekTypeDefs.hpp:75

References Nektar::LibUtilities::BasisManager(), Nektar::MultiRegions::e1D, Nektar::MultiRegions::e2D, Nektar::MultiRegions::e3D, Nektar::LibUtilities::eGauss_Lagrange, Nektar::LibUtilities::eGaussGaussLegendre, Nektar::MultiRegions::ExpList::GetCoeff_Offset(), Nektar::MultiRegions::ExpList::GetExpSize(), GetNegatedFluxNormal(), Nektar::MultiRegions::ExpList::GetTrace(), Nektar::MultiRegions::ExpList::m_exp, Nektar::MultiRegions::ExpList::m_expType, m_locTraceToTraceMap, m_trace, and m_traceMap.

◆ v_AddTraceIntegralToOffDiag()

void Nektar::MultiRegions::DisContField::v_AddTraceIntegralToOffDiag ( const Array< OneD, const NekDouble > &  FwdFlux,
const Array< OneD, const NekDouble > &  BwdFlux,
Array< OneD, NekDouble > &  outarray 
)
overrideprotectedvirtual

Reimplemented from Nektar::MultiRegions::ExpList.

Definition at line 4452 of file DisContField.cpp.

4456{
4457 Array<OneD, NekDouble> FCoeffs(m_trace->GetNcoeffs());
4458
4459 m_trace->IProductWRTBase(FwdFlux, FCoeffs);
4460 m_locTraceToTraceMap->AddTraceCoeffsToFieldCoeffs(1, FCoeffs, outarray);
4461 m_trace->IProductWRTBase(BwdFlux, FCoeffs);
4462 m_locTraceToTraceMap->AddTraceCoeffsToFieldCoeffs(0, FCoeffs, outarray);
4463}

References m_locTraceToTraceMap, and m_trace.

◆ v_AddTraceQuadPhysToField()

void Nektar::MultiRegions::DisContField::v_AddTraceQuadPhysToField ( const Array< OneD, const NekDouble > &  Fwd,
const Array< OneD, const NekDouble > &  Bwd,
Array< OneD, NekDouble > &  field 
)
overrideprotectedvirtual

Reimplemented from Nektar::MultiRegions::ExpList.

Definition at line 3146 of file DisContField.cpp.

3149{
3150 // Basis definition on each element
3151 LibUtilities::BasisSharedPtr basis = (*m_exp)[0]->GetBasis(0);
3152 if (basis->GetBasisType() != LibUtilities::eGauss_Lagrange)
3153 {
3154 Array<OneD, NekDouble> tracevals(
3155 m_locTraceToTraceMap->GetNLocTracePts(), 0.0);
3156
3157 Array<OneD, NekDouble> invals =
3158 tracevals + m_locTraceToTraceMap->GetNFwdLocTracePts();
3159
3160 m_locTraceToTraceMap->InterpTraceToLocTrace(1, Bwd, invals);
3161
3162 m_locTraceToTraceMap->InterpTraceToLocTrace(0, Fwd, tracevals);
3163
3164 m_locTraceToTraceMap->AddLocTracesToField(tracevals, field);
3165 }
3166 else
3167 {
3169 "v_AddTraceQuadPhysToField not coded for eGauss_Lagrange");
3170 }
3171}

References Nektar::ErrorUtil::efatal, Nektar::LibUtilities::eGauss_Lagrange, m_locTraceToTraceMap, and NEKERROR.

◆ v_EvaluateBoundaryConditions()

void Nektar::MultiRegions::DisContField::v_EvaluateBoundaryConditions ( const NekDouble  time = 0.0,
const std::string  varName = "",
const NekDouble  x2_in = NekConstants::kNekUnsetDouble,
const NekDouble  x3_in = NekConstants::kNekUnsetDouble 
)
overrideprotectedvirtual

Evaluate all boundary conditions at a given time..

Reimplemented from Nektar::MultiRegions::ExpList.

Definition at line 3600 of file DisContField.cpp.

3604{
3605 int i;
3606 int npoints;
3607
3609
3610 for (i = 0; i < m_bndCondExpansions.size(); ++i)
3611 {
3612 if (time == 0.0 || m_bndConditions[i]->IsTimeDependent())
3613 {
3614 m_bndCondBndWeight[i] = 1.0;
3615 locExpList = m_bndCondExpansions[i];
3616
3617 npoints = locExpList->GetNpoints();
3618 Array<OneD, NekDouble> x0(npoints, 0.0);
3619 Array<OneD, NekDouble> x1(npoints, 0.0);
3620 Array<OneD, NekDouble> x2(npoints, 0.0);
3621
3622 locExpList->GetCoords(x0, x1, x2);
3623
3624 if (x2_in != NekConstants::kNekUnsetDouble &&
3626 {
3627 Vmath::Fill(npoints, x2_in, x1, 1);
3628 Vmath::Fill(npoints, x3_in, x2, 1);
3629 }
3630 else if (x2_in != NekConstants::kNekUnsetDouble)
3631 {
3632 Vmath::Fill(npoints, x2_in, x2, 1);
3633 }
3634
3635 // treat 1D expansions separately since we only
3636 // require an evaluation at a point rather than
3637 // any projections or inner products that are not
3638 // available in a PointExp
3639 if (m_expType == e1D)
3640 {
3641 if (m_bndConditions[i]->GetBoundaryConditionType() ==
3643 {
3644
3645 m_bndCondExpansions[i]->SetCoeff(
3646 0, (std::static_pointer_cast<
3647 SpatialDomains::DirichletBoundaryCondition>(
3648 m_bndConditions[i])
3649 ->m_dirichletCondition)
3650 .Evaluate(x0[0], x1[0], x2[0], time));
3651 m_bndCondExpansions[i]->SetPhys(
3652 0, m_bndCondExpansions[i]->GetCoeff(0));
3653 }
3654 else if (m_bndConditions[i]->GetBoundaryConditionType() ==
3656 {
3657 m_bndCondExpansions[i]->SetCoeff(
3658 0, (std::static_pointer_cast<
3659 SpatialDomains::NeumannBoundaryCondition>(
3660 m_bndConditions[i])
3661 ->m_neumannCondition)
3662 .Evaluate(x0[0], x1[0], x2[0], time));
3663 }
3664 else if (m_bndConditions[i]->GetBoundaryConditionType() ==
3666 {
3667 m_bndCondExpansions[i]->SetCoeff(
3668 0, (std::static_pointer_cast<
3669 SpatialDomains::RobinBoundaryCondition>(
3670 m_bndConditions[i])
3671 ->m_robinFunction)
3672 .Evaluate(x0[0], x1[0], x2[0], time));
3673 }
3674 else if (m_bndConditions[i]->GetBoundaryConditionType() ==
3676 {
3677 continue;
3678 }
3679 else if (m_bndConditions[i]->GetBoundaryConditionType() ==
3681 {
3682 }
3683 else
3684 {
3686 "This type of BC not implemented yet");
3687 }
3688 }
3689 else // 2D and 3D versions
3690 {
3691 if (m_bndConditions[i]->GetBoundaryConditionType() ==
3693 {
3695 std::static_pointer_cast<
3696 SpatialDomains::DirichletBoundaryCondition>(
3697 m_bndConditions[i]);
3698
3699 Array<OneD, NekDouble> valuesFile(npoints, 1.0),
3700 valuesExp(npoints, 1.0);
3701
3702 string bcfilename = bcPtr->m_filename;
3703 string exprbcs = bcPtr->m_expr;
3704
3705 if (bcfilename != "")
3706 {
3707 locExpList->ExtractCoeffsFromFile(
3708 bcfilename, bcPtr->GetComm(), varName,
3709 locExpList->UpdateCoeffs());
3710 locExpList->BwdTrans(locExpList->GetCoeffs(),
3711 locExpList->UpdatePhys());
3712 valuesFile = locExpList->GetPhys();
3713 }
3714
3715 if (exprbcs != "")
3716 {
3717 LibUtilities::Equation condition =
3718 std::static_pointer_cast<
3719 SpatialDomains::DirichletBoundaryCondition>(
3720 m_bndConditions[i])
3721 ->m_dirichletCondition;
3722
3723 condition.Evaluate(x0, x1, x2, time, valuesExp);
3724 }
3725
3726 Vmath::Vmul(npoints, valuesExp, 1, valuesFile, 1,
3727 locExpList->UpdatePhys(), 1);
3728 locExpList->FwdTransBndConstrained(
3729 locExpList->GetPhys(), locExpList->UpdateCoeffs());
3730 }
3731 else if (m_bndConditions[i]->GetBoundaryConditionType() ==
3733 {
3735 std::static_pointer_cast<
3736 SpatialDomains::NeumannBoundaryCondition>(
3737 m_bndConditions[i]);
3738 string bcfilename = bcPtr->m_filename;
3739
3740 if (bcfilename != "")
3741 {
3742 locExpList->ExtractCoeffsFromFile(
3743 bcfilename, bcPtr->GetComm(), varName,
3744 locExpList->UpdateCoeffs());
3745 locExpList->BwdTrans(locExpList->GetCoeffs(),
3746 locExpList->UpdatePhys());
3747 }
3748 else
3749 {
3750 LibUtilities::Equation condition =
3751 std::static_pointer_cast<
3752 SpatialDomains::NeumannBoundaryCondition>(
3753 m_bndConditions[i])
3754 ->m_neumannCondition;
3755 condition.Evaluate(x0, x1, x2, time,
3756 locExpList->UpdatePhys());
3757 }
3758
3759 locExpList->IProductWRTBase(locExpList->GetPhys(),
3760 locExpList->UpdateCoeffs());
3761 }
3762 else if (m_bndConditions[i]->GetBoundaryConditionType() ==
3764 {
3766 std::static_pointer_cast<
3767 SpatialDomains::RobinBoundaryCondition>(
3768 m_bndConditions[i]);
3769
3770 string bcfilename = bcPtr->m_filename;
3771
3772 if (bcfilename != "")
3773 {
3774 locExpList->ExtractCoeffsFromFile(
3775 bcfilename, bcPtr->GetComm(), varName,
3776 locExpList->UpdateCoeffs());
3777 locExpList->BwdTrans(locExpList->GetCoeffs(),
3778 locExpList->UpdatePhys());
3779 }
3780 else
3781 {
3782 LibUtilities::Equation condition =
3783 std::static_pointer_cast<
3784 SpatialDomains::RobinBoundaryCondition>(
3785 m_bndConditions[i])
3786 ->m_robinFunction;
3787 condition.Evaluate(x0, x1, x2, time,
3788 locExpList->UpdatePhys());
3789 }
3790
3791 locExpList->IProductWRTBase(locExpList->GetPhys(),
3792 locExpList->UpdateCoeffs());
3793 }
3794 else if (m_bndConditions[i]->GetBoundaryConditionType() ==
3796 {
3797 continue;
3798 }
3799 else
3800 {
3802 "This type of BC not implemented yet");
3803 }
3804 }
3805 }
3806 }
3807}
NekDouble GetCoeff(int i)
Get the i th value (coefficient) of m_coeffs.
Definition: ExpList.h:2018
static const NekDouble kNekUnsetDouble
std::shared_ptr< DirichletBoundaryCondition > DirichletBCShPtr
Definition: Conditions.h:213
std::shared_ptr< NeumannBoundaryCondition > NeumannBCShPtr
Definition: Conditions.h:214
std::shared_ptr< RobinBoundaryCondition > RobinBCShPtr
Definition: Conditions.h:215
void Vmul(int n, const T *x, const int incx, const T *y, const int incy, T *z, const int incz)
Multiply vector z = x*y.
Definition: Vmath.hpp:72
void Fill(int n, const T alpha, T *x, const int incx)
Fill a vector with a constant value.
Definition: Vmath.hpp:54

References Nektar::MultiRegions::e1D, Nektar::SpatialDomains::eDirichlet, Nektar::ErrorUtil::efatal, Nektar::SpatialDomains::eNeumann, Nektar::SpatialDomains::eNotDefined, Nektar::SpatialDomains::ePeriodic, Nektar::SpatialDomains::eRobin, Nektar::LibUtilities::Equation::Evaluate(), Vmath::Fill(), Nektar::MultiRegions::ExpList::GetCoeff(), Nektar::NekConstants::kNekUnsetDouble, m_bndCondBndWeight, m_bndCondExpansions, m_bndConditions, Nektar::MultiRegions::ExpList::m_expType, Nektar::SpatialDomains::NeumannBoundaryCondition::m_filename, Nektar::SpatialDomains::RobinBoundaryCondition::m_filename, NEKERROR, and Vmath::Vmul().

◆ v_ExtractTracePhys() [1/2]

void Nektar::MultiRegions::DisContField::v_ExtractTracePhys ( Array< OneD, NekDouble > &  outarray)
overrideprotectedvirtual

Reimplemented from Nektar::MultiRegions::ExpList.

Definition at line 3173 of file DisContField.cpp.

3174{
3175 ASSERTL1(m_physState == true, "local physical space is not true ");
3176 v_ExtractTracePhys(m_phys, outarray);
3177}
void v_ExtractTracePhys(const Array< OneD, const NekDouble > &inarray, Array< OneD, NekDouble > &outarray) override
This method extracts the trace (verts in 1D) from the field inarray and puts the values in outarray.
bool m_physState
The state of the array m_phys.
Definition: ExpList.h:1104
Array< OneD, NekDouble > m_phys
The global expansion evaluated at the quadrature points.
Definition: ExpList.h:1096

References ASSERTL1, Nektar::MultiRegions::ExpList::m_phys, Nektar::MultiRegions::ExpList::m_physState, and v_ExtractTracePhys().

◆ v_ExtractTracePhys() [2/2]

void Nektar::MultiRegions::DisContField::v_ExtractTracePhys ( const Array< OneD, const NekDouble > &  inarray,
Array< OneD, NekDouble > &  outarray 
)
overrideprotectedvirtual

This method extracts the trace (verts in 1D) from the field inarray and puts the values in outarray.

It assumes the field is C0 continuous so that it can overwrite the edge data when visited by the two adjacent elements.

Parameters
inarrayAn array containing the 1D data from which we wish to extract the edge data.
outarrayThe resulting edge information.

This will not work for non-boundary expansions

Reimplemented from Nektar::MultiRegions::ExpList.

Definition at line 3192 of file DisContField.cpp.

3195{
3196 LibUtilities::BasisSharedPtr basis = (*m_exp)[0]->GetBasis(0);
3197 if ((basis->GetBasisType() != LibUtilities::eGauss_Lagrange))
3198 {
3199 Vmath::Zero(outarray.size(), outarray, 1);
3200 Array<OneD, NekDouble> tracevals(
3201 m_locTraceToTraceMap->GetNFwdLocTracePts());
3202 m_locTraceToTraceMap->FwdLocTracesFromField(inarray, tracevals);
3203 m_locTraceToTraceMap->InterpLocTracesToTrace(0, tracevals, outarray);
3204 m_traceMap->GetAssemblyCommDG()->PerformExchange(outarray, outarray);
3205 }
3206 else
3207 {
3208 // Loop over elemente and collect forward expansion
3209 int nexp = GetExpSize();
3210 int n, p, offset, phys_offset;
3211 Array<OneD, NekDouble> t_tmp;
3212 Array<OneD, Array<OneD, LocalRegions::ExpansionSharedPtr>>
3213 &elmtToTrace = m_traceMap->GetElmtToTrace();
3214 ASSERTL1(outarray.size() >= m_trace->GetNpoints(),
3215 "input array is of insufficient length");
3216 for (n = 0; n < nexp; ++n)
3217 {
3218 phys_offset = GetPhys_Offset(n);
3219 for (p = 0; p < (*m_exp)[n]->GetNtraces(); ++p)
3220 {
3221 offset =
3222 m_trace->GetPhys_Offset(elmtToTrace[n][p]->GetElmtId());
3223 (*m_exp)[n]->GetTracePhysVals(p, elmtToTrace[n][p],
3224 inarray + phys_offset,
3225 t_tmp = outarray + offset);
3226 }
3227 }
3228 }
3229}
int GetPhys_Offset(int n) const
Get the start offset position for a local contiguous list of quadrature points in a full array corres...
Definition: ExpList.h:2094
void Zero(int n, T *x, const int incx)
Zero vector.
Definition: Vmath.hpp:273

References ASSERTL1, Nektar::LibUtilities::eGauss_Lagrange, Nektar::MultiRegions::ExpList::GetExpSize(), Nektar::MultiRegions::ExpList::GetPhys_Offset(), m_locTraceToTraceMap, m_trace, m_traceMap, CellMLToNektar.cellml_metadata::p, and Vmath::Zero().

Referenced by v_ExtractTracePhys().

◆ v_FillBwdWithBoundCond()

void Nektar::MultiRegions::DisContField::v_FillBwdWithBoundCond ( const Array< OneD, NekDouble > &  Fwd,
Array< OneD, NekDouble > &  Bwd,
bool  PutFwdInBwdOnBCs 
)
overrideprotectedvirtual

Reimplemented from Nektar::MultiRegions::ExpList.

Definition at line 3017 of file DisContField.cpp.

3020{
3022 PutFwdInBwdOnBCs);
3023}

References FillBwdWithBoundCond(), m_bndCondExpansions, and m_bndConditions.

Referenced by v_GetFwdBwdTracePhys().

◆ v_FillBwdWithBwdWeight()

void Nektar::MultiRegions::DisContField::v_FillBwdWithBwdWeight ( Array< OneD, NekDouble > &  weightave,
Array< OneD, NekDouble > &  weightjmp 
)
overrideprotectedvirtual

Fill the weight with m_bndCondBndWeight.

Reimplemented from Nektar::MultiRegions::ExpList.

Definition at line 3812 of file DisContField.cpp.

3814{
3815 int cnt;
3816 int npts;
3817 int e = 0;
3818
3819 // Fill boundary conditions into missing elements
3820 int id2 = 0;
3821
3822 for (int n = cnt = 0; n < m_bndCondExpansions.size(); ++n)
3823 {
3824
3825 if (m_bndConditions[n]->GetBoundaryConditionType() ==
3827 {
3828 for (e = 0; e < m_bndCondExpansions[n]->GetExpSize(); ++e)
3829 {
3830 npts = m_bndCondExpansions[n]->GetExp(e)->GetTotPoints();
3831 id2 = m_trace->GetPhys_Offset(
3832 m_traceMap->GetBndCondIDToGlobalTraceID(cnt + e));
3833 Vmath::Fill(npts, m_bndCondBndWeight[n], &weightave[id2], 1);
3834 Vmath::Fill(npts, 0.0, &weightjmp[id2], 1);
3835 }
3836
3837 cnt += e;
3838 }
3839 else if (m_bndConditions[n]->GetBoundaryConditionType() ==
3841 m_bndConditions[n]->GetBoundaryConditionType() ==
3843 {
3844 for (e = 0; e < m_bndCondExpansions[n]->GetExpSize(); ++e)
3845 {
3846 npts = m_bndCondExpansions[n]->GetExp(e)->GetTotPoints();
3847 id2 = m_trace->GetPhys_Offset(
3848 m_traceMap->GetBndCondIDToGlobalTraceID(cnt + e));
3849 Vmath::Fill(npts, m_bndCondBndWeight[n], &weightave[id2], 1);
3850 Vmath::Fill(npts, 0.0, &weightjmp[id2], 1);
3851 }
3852
3853 cnt += e;
3854 }
3855 else if (m_bndConditions[n]->GetBoundaryConditionType() !=
3857 {
3859 "Method not set up for this boundary condition.");
3860 }
3861 }
3862}

References Nektar::SpatialDomains::eDirichlet, Nektar::ErrorUtil::efatal, Nektar::SpatialDomains::eNeumann, Nektar::SpatialDomains::ePeriodic, Nektar::SpatialDomains::eRobin, Vmath::Fill(), m_bndCondBndWeight, m_bndCondExpansions, m_bndConditions, m_trace, m_traceMap, and NEKERROR.

◆ v_GetBndCondBwdWeight()

const Array< OneD, const NekDouble > & Nektar::MultiRegions::DisContField::v_GetBndCondBwdWeight ( )
overrideprotectedvirtual

Reimplemented from Nektar::MultiRegions::ExpList.

Definition at line 3136 of file DisContField.cpp.

3137{
3138 return m_bndCondBndWeight;
3139}

References m_bndCondBndWeight.

◆ v_GetBndCondExpansions()

const Array< OneD, const MultiRegions::ExpListSharedPtr > & Nektar::MultiRegions::DisContField::v_GetBndCondExpansions ( void  )
overrideprotectedvirtual

Reimplemented from Nektar::MultiRegions::ExpList.

Definition at line 2836 of file DisContField.cpp.

2837{
2838 return m_bndCondExpansions;
2839}

References m_bndCondExpansions.

◆ v_GetBndConditions()

const Array< OneD, const SpatialDomains::BoundaryConditionShPtr > & Nektar::MultiRegions::DisContField::v_GetBndConditions ( void  )
overrideprotectedvirtual

Reimplemented from Nektar::MultiRegions::ExpList.

Definition at line 2842 of file DisContField.cpp.

2843{
2844 return m_bndConditions;
2845}

References m_bndConditions.

◆ v_GetBndElmtExpansion()

void Nektar::MultiRegions::DisContField::v_GetBndElmtExpansion ( int  i,
std::shared_ptr< ExpList > &  result,
const bool  DeclareCoeffPhysArrays 
)
overrideprotectedvirtual

Reimplemented from Nektar::MultiRegions::ExpList.

Definition at line 4029 of file DisContField.cpp.

4032{
4033 int n, cnt;
4034 std::vector<unsigned int> eIDs;
4035
4036 Array<OneD, int> ElmtID, TraceID;
4037 GetBoundaryToElmtMap(ElmtID, TraceID);
4038
4039 // Skip other boundary regions
4040 for (cnt = n = 0; n < i; ++n)
4041 {
4042 cnt += m_bndCondExpansions[n]->GetExpSize();
4043 }
4044
4045 // Populate eIDs with information from BoundaryToElmtMap
4046 for (n = 0; n < m_bndCondExpansions[i]->GetExpSize(); ++n)
4047 {
4048 eIDs.push_back(ElmtID[cnt + n]);
4049 }
4050
4051 // Create expansion list
4053 *this, eIDs, DeclareCoeffPhysArrays, Collections::eNoCollection);
4054 // Copy phys and coeffs to new explist
4055 if (DeclareCoeffPhysArrays)
4056 {
4057 int nq;
4058 int offsetOld, offsetNew;
4059 Array<OneD, NekDouble> tmp1, tmp2;
4060 for (n = 0; n < result->GetExpSize(); ++n)
4061 {
4062 nq = GetExp(ElmtID[cnt + n])->GetTotPoints();
4063 offsetOld = GetPhys_Offset(ElmtID[cnt + n]);
4064 offsetNew = result->GetPhys_Offset(n);
4065 Vmath::Vcopy(nq, tmp1 = GetPhys() + offsetOld, 1,
4066 tmp2 = result->UpdatePhys() + offsetNew, 1);
4067 nq = GetExp(ElmtID[cnt + n])->GetNcoeffs();
4068 offsetOld = GetCoeff_Offset(ElmtID[cnt + n]);
4069 offsetNew = result->GetCoeff_Offset(n);
4070 Vmath::Vcopy(nq, tmp1 = GetCoeffs() + offsetOld, 1,
4071 tmp2 = result->UpdateCoeffs() + offsetNew, 1);
4072 }
4073 }
4074}
const Array< OneD, const NekDouble > & GetCoeffs() const
This function returns (a reference to) the array (implemented as m_coeffs) containing all local expa...
Definition: ExpList.h:1952
const std::shared_ptr< LocalRegions::ExpansionVector > GetExp() const
This function returns the vector of elements in the expansion.
Definition: ExpList.h:2079

References Nektar::MemoryManager< DataType >::AllocateSharedPtr(), Nektar::Collections::eNoCollection, Nektar::MultiRegions::ExpList::GetBoundaryToElmtMap(), Nektar::MultiRegions::ExpList::GetCoeff_Offset(), Nektar::MultiRegions::ExpList::GetCoeffs(), Nektar::MultiRegions::ExpList::GetExp(), Nektar::MultiRegions::ExpList::GetPhys(), Nektar::MultiRegions::ExpList::GetPhys_Offset(), m_bndCondExpansions, and Vmath::Vcopy().

◆ v_GetBoundaryToElmtMap()

void Nektar::MultiRegions::DisContField::v_GetBoundaryToElmtMap ( Array< OneD, int > &  ElmtID,
Array< OneD, int > &  TraceID 
)
overrideprotectedvirtual

Reimplemented from Nektar::MultiRegions::ExpList.

Definition at line 3866 of file DisContField.cpp.

3868{
3869
3870 if (m_BCtoElmMap.size() == 0)
3871 {
3872 switch (m_expType)
3873 {
3874 case e1D:
3875 {
3876 map<int, int> VertGID;
3877 int i, n, id;
3878 int bid, cnt, Vid;
3879 int nbcs = 0;
3880 // Determine number of boundary condition expansions.
3881 for (i = 0; i < m_bndConditions.size(); ++i)
3882 {
3883 nbcs += m_bndCondExpansions[i]->GetExpSize();
3884 }
3885
3886 // make sure arrays are of sufficient length
3887 m_BCtoElmMap = Array<OneD, int>(nbcs, -1);
3888 m_BCtoTraceMap = Array<OneD, int>(nbcs);
3889
3890 // setup map of all global ids along boundary
3891 cnt = 0;
3892 for (n = 0; n < m_bndCondExpansions.size(); ++n)
3893 {
3894 for (i = 0; i < m_bndCondExpansions[n]->GetExpSize(); ++i)
3895 {
3896 Vid = m_bndCondExpansions[n]
3897 ->GetExp(i)
3898 ->GetGeom()
3899 ->GetVertex(0)
3900 ->GetVid();
3901 VertGID[Vid] = cnt++;
3902 }
3903 }
3904
3905 // Loop over elements and find verts that match;
3907 for (cnt = n = 0; n < GetExpSize(); ++n)
3908 {
3909 exp = (*m_exp)[n];
3910 for (i = 0; i < exp->GetNverts(); ++i)
3911 {
3912 id = exp->GetGeom()->GetVid(i);
3913
3914 if (VertGID.count(id) > 0)
3915 {
3916 bid = VertGID.find(id)->second;
3917 ASSERTL1(m_BCtoElmMap[bid] == -1,
3918 "Edge already set");
3919 m_BCtoElmMap[bid] = n;
3920 m_BCtoTraceMap[bid] = i;
3921 cnt++;
3922 }
3923 }
3924 }
3925 ASSERTL1(cnt == nbcs,
3926 "Failed to visit all boundary condtiions");
3927 }
3928 break;
3929 case e2D:
3930 {
3931 map<int, int> globalIdMap;
3932 int i, n;
3933 int cnt;
3934 int nbcs = 0;
3935
3936 // Populate global ID map (takes global geometry
3937 // ID to local expansion list ID).
3938 for (i = 0; i < GetExpSize(); ++i)
3939 {
3940 globalIdMap[(*m_exp)[i]->GetGeom()->GetGlobalID()] = i;
3941 }
3942
3943 // Determine number of boundary condition expansions.
3944 for (i = 0; i < m_bndConditions.size(); ++i)
3945 {
3946 nbcs += m_bndCondExpansions[i]->GetExpSize();
3947 }
3948
3949 // Initialize arrays
3950 m_BCtoElmMap = Array<OneD, int>(nbcs);
3951 m_BCtoTraceMap = Array<OneD, int>(nbcs);
3952
3954 cnt = 0;
3955 for (n = 0; n < m_bndCondExpansions.size(); ++n)
3956 {
3957 for (i = 0; i < m_bndCondExpansions[n]->GetExpSize();
3958 ++i, ++cnt)
3959 {
3960 exp1d = m_bndCondExpansions[n]
3961 ->GetExp(i)
3962 ->as<LocalRegions::Expansion1D>();
3963
3964 // Use edge to element map from MeshGraph.
3966 m_graph->GetElementsFromEdge(exp1d->GetGeom1D());
3967
3968 m_BCtoElmMap[cnt] =
3969 globalIdMap[(*tmp)[0].first->GetGlobalID()];
3970 m_BCtoTraceMap[cnt] = (*tmp)[0].second;
3971 }
3972 }
3973 }
3974 break;
3975 case e3D:
3976 {
3977 map<int, int> globalIdMap;
3978 int i, n;
3979 int cnt;
3980 int nbcs = 0;
3981
3982 // Populate global ID map (takes global geometry ID to local
3983 // expansion list ID).
3985 for (i = 0; i < GetExpSize(); ++i)
3986 {
3987 globalIdMap[(*m_exp)[i]->GetGeom()->GetGlobalID()] = i;
3988 }
3989
3990 // Determine number of boundary condition expansions.
3991 for (i = 0; i < m_bndConditions.size(); ++i)
3992 {
3993 nbcs += m_bndCondExpansions[i]->GetExpSize();
3994 }
3995
3996 // Initialize arrays
3997 m_BCtoElmMap = Array<OneD, int>(nbcs);
3998 m_BCtoTraceMap = Array<OneD, int>(nbcs);
3999
4001 for (cnt = n = 0; n < m_bndCondExpansions.size(); ++n)
4002 {
4003 for (i = 0; i < m_bndCondExpansions[n]->GetExpSize();
4004 ++i, ++cnt)
4005 {
4006 exp2d = m_bndCondExpansions[n]
4007 ->GetExp(i)
4008 ->as<LocalRegions::Expansion2D>();
4009
4011 m_graph->GetElementsFromFace(exp2d->GetGeom2D());
4012 m_BCtoElmMap[cnt] =
4013 globalIdMap[tmp->at(0).first->GetGlobalID()];
4014 m_BCtoTraceMap[cnt] = tmp->at(0).second;
4015 }
4016 }
4017 }
4018 break;
4019 default:
4020 ASSERTL1(false, "Not setup for this expansion");
4021 break;
4022 }
4023 }
4024
4025 ElmtID = m_BCtoElmMap;
4026 TraceID = m_BCtoTraceMap;
4027}
Array< OneD, int > m_BCtoTraceMap
Definition: DisContField.h:59
std::shared_ptr< Expansion2D > Expansion2DSharedPtr
Definition: Expansion1D.h:46
std::shared_ptr< Expansion1D > Expansion1DSharedPtr
Definition: Expansion1D.h:50
std::shared_ptr< Expansion3D > Expansion3DSharedPtr
Definition: Expansion2D.h:47

References ASSERTL1, Nektar::MultiRegions::e1D, Nektar::MultiRegions::e2D, Nektar::MultiRegions::e3D, Nektar::MultiRegions::ExpList::GetExpSize(), m_BCtoElmMap, m_BCtoTraceMap, m_bndCondExpansions, m_bndConditions, Nektar::MultiRegions::ExpList::m_expType, and Nektar::MultiRegions::ExpList::m_graph.

◆ v_GetFwdBwdTracePhys() [1/2]

void Nektar::MultiRegions::DisContField::v_GetFwdBwdTracePhys ( Array< OneD, NekDouble > &  Fwd,
Array< OneD, NekDouble > &  Bwd 
)
overrideprotectedvirtual

Reimplemented from Nektar::MultiRegions::ExpList.

Definition at line 2867 of file DisContField.cpp.

2869{
2870 v_GetFwdBwdTracePhys(m_phys, Fwd, Bwd);
2871}
void v_GetFwdBwdTracePhys(Array< OneD, NekDouble > &Fwd, Array< OneD, NekDouble > &Bwd) override

References Nektar::MultiRegions::ExpList::m_phys, and v_GetFwdBwdTracePhys().

Referenced by v_GetFwdBwdTracePhys().

◆ v_GetFwdBwdTracePhys() [2/2]

void Nektar::MultiRegions::DisContField::v_GetFwdBwdTracePhys ( const Array< OneD, const NekDouble > &  field,
Array< OneD, NekDouble > &  Fwd,
Array< OneD, NekDouble > &  Bwd,
bool  FillBnd = true,
bool  PutFwdInBwdOnBCs = false,
bool  DoExchange = true 
)
overrideprotectedvirtual

Reimplemented from Nektar::MultiRegions::ExpList.

Definition at line 2943 of file DisContField.cpp.

2948{
2949 // Is this zeroing necessary?
2950 // Zero forward/backward vectors.
2951 Vmath::Zero(Fwd.size(), Fwd, 1);
2952 Vmath::Zero(Bwd.size(), Bwd, 1);
2953
2954 // Basis definition on each element
2955 LibUtilities::BasisSharedPtr basis = (*m_exp)[0]->GetBasis(0);
2956 if ((basis->GetBasisType() != LibUtilities::eGauss_Lagrange))
2957 {
2958 // blocked routine
2959 Array<OneD, NekDouble> tracevals(
2960 m_locTraceToTraceMap->GetNLocTracePts());
2961
2962 m_locTraceToTraceMap->LocTracesFromField(field, tracevals);
2963 m_locTraceToTraceMap->InterpLocTracesToTrace(0, tracevals, Fwd);
2964
2965 Array<OneD, NekDouble> invals =
2966 tracevals + m_locTraceToTraceMap->GetNFwdLocTracePts();
2967 m_locTraceToTraceMap->InterpLocTracesToTrace(1, invals, Bwd);
2968 }
2969 else
2970 {
2971 // Loop over elements and collect forward expansion
2972 auto nexp = GetExpSize();
2973 Array<OneD, NekDouble> e_tmp;
2975
2976 Array<OneD, Array<OneD, LocalRegions::ExpansionSharedPtr>>
2977 &elmtToTrace = m_traceMap->GetElmtToTrace();
2978
2979 for (int n = 0, cnt = 0; n < nexp; ++n)
2980 {
2981 exp = (*m_exp)[n];
2982 auto phys_offset = GetPhys_Offset(n);
2983
2984 for (int e = 0; e < exp->GetNtraces(); ++e, ++cnt)
2985 {
2986 auto offset =
2987 m_trace->GetPhys_Offset(elmtToTrace[n][e]->GetElmtId());
2988
2989 e_tmp =
2990 (m_leftAdjacentTraces[cnt]) ? Fwd + offset : Bwd + offset;
2991
2992 exp->GetTracePhysVals(e, elmtToTrace[n][e], field + phys_offset,
2993 e_tmp);
2994 }
2995 }
2996 }
2997
2999
3000 if (FillBnd)
3001 {
3002 v_FillBwdWithBoundCond(Fwd, Bwd, PutFwdInBwdOnBCs);
3003 }
3004
3005 if (DoExchange)
3006 {
3007 // Do parallel exchange for forwards/backwards spaces.
3008 m_traceMap->GetAssemblyCommDG()->PerformExchange(Fwd, Bwd);
3009
3010 // Do exchange of interface traces (local and parallel)
3011 // We may have to split this out into separate local and
3012 // parallel for IP method???
3013 m_interfaceMap->ExchangeTrace(Fwd, Bwd);
3014 }
3015}
void v_FillBwdWithBoundCond(const Array< OneD, NekDouble > &Fwd, Array< OneD, NekDouble > &Bwd, bool PutFwdInBwdOnBCs) override

References Nektar::LibUtilities::eGauss_Lagrange, Nektar::MultiRegions::ExpList::GetExpSize(), Nektar::MultiRegions::ExpList::GetPhys_Offset(), m_interfaceMap, m_leftAdjacentTraces, m_locTraceToTraceMap, m_trace, m_traceMap, v_FillBwdWithBoundCond(), v_PeriodicBwdCopy(), and Vmath::Zero().

◆ v_GetLeftAdjacentTraces()

std::vector< bool > & Nektar::MultiRegions::DisContField::v_GetLeftAdjacentTraces ( void  )
overrideprotectedvirtual

Reimplemented from Nektar::MultiRegions::ExpList.

Definition at line 2830 of file DisContField.cpp.

2831{
2832 return m_leftAdjacentTraces;
2833}

References m_leftAdjacentTraces.

◆ v_GetLocTraceFromTracePts()

void Nektar::MultiRegions::DisContField::v_GetLocTraceFromTracePts ( const Array< OneD, const NekDouble > &  Fwd,
const Array< OneD, const NekDouble > &  Bwd,
Array< OneD, NekDouble > &  locTraceFwd,
Array< OneD, NekDouble > &  locTraceBwd 
)
overrideprotectedvirtual

Reimplemented from Nektar::MultiRegions::ExpList.

Definition at line 4434 of file DisContField.cpp.

4438{
4439 if (locTraceFwd != NullNekDouble1DArray)
4440 {
4441 m_locTraceToTraceMap->InterpLocTracesToTraceTranspose(0, Fwd,
4442 locTraceFwd);
4443 }
4444
4445 if (locTraceBwd != NullNekDouble1DArray)
4446 {
4447 m_locTraceToTraceMap->InterpLocTracesToTraceTranspose(1, Bwd,
4448 locTraceBwd);
4449 }
4450}
static Array< OneD, NekDouble > NullNekDouble1DArray

References m_locTraceToTraceMap, and Nektar::NullNekDouble1DArray.

◆ v_GetLocTraceToTraceMap()

const LocTraceToTraceMapSharedPtr & Nektar::MultiRegions::DisContField::v_GetLocTraceToTraceMap ( void  ) const
overrideprotectedvirtual

Reimplemented from Nektar::MultiRegions::ExpList.

Definition at line 2821 of file DisContField.cpp.

2823{
2824 return m_locTraceToTraceMap;
2825}

References m_locTraceToTraceMap.

◆ v_GetPeriodicEntities()

void Nektar::MultiRegions::DisContField::v_GetPeriodicEntities ( PeriodicMap periodicVerts,
PeriodicMap periodicEdges,
PeriodicMap periodicFaces 
)
overrideprotectedvirtual

Obtain a copy of the periodic edges and vertices for this field.

Reimplemented from Nektar::MultiRegions::ExpList.

Definition at line 2877 of file DisContField.cpp.

2880{
2881 periodicVerts = m_periodicVerts;
2882 periodicEdges = m_periodicEdges;
2883 periodicFaces = m_periodicFaces;
2884}

References m_periodicEdges, m_periodicFaces, and m_periodicVerts.

◆ v_GetRobinBCInfo()

map< int, RobinBCInfoSharedPtr > Nektar::MultiRegions::DisContField::v_GetRobinBCInfo ( void  )
overrideprotectedvirtual

Search through the edge expansions and identify which ones have Robin/Mixed type boundary conditions. If find a Robin boundary then store the edge id of the boundary condition and the array of points of the physical space boundary condition which are hold the boundary condition primitive variable coefficient at the quatrature points

Returns
std map containing the robin boundary condition info using a key of the element id

There is a next member to allow for more than one Robin boundary condition per element

Reimplemented from Nektar::MultiRegions::ExpList.

Definition at line 4104 of file DisContField.cpp.

4105{
4106 int i, cnt;
4107 map<int, RobinBCInfoSharedPtr> returnval;
4108 Array<OneD, int> ElmtID, TraceID;
4109 GetBoundaryToElmtMap(ElmtID, TraceID);
4110
4111 for (cnt = i = 0; i < m_bndCondExpansions.size(); ++i)
4112 {
4114
4115 if (m_bndConditions[i]->GetBoundaryConditionType() ==
4117 {
4118 int e, elmtid;
4119 Array<OneD, NekDouble> Array_tmp;
4120
4121 locExpList = m_bndCondExpansions[i];
4122
4123 int npoints = locExpList->GetNpoints();
4124 Array<OneD, NekDouble> x0(npoints, 0.0);
4125 Array<OneD, NekDouble> x1(npoints, 0.0);
4126 Array<OneD, NekDouble> x2(npoints, 0.0);
4127 Array<OneD, NekDouble> coeffphys(npoints);
4128
4129 locExpList->GetCoords(x0, x1, x2);
4130
4131 LibUtilities::Equation coeffeqn =
4132 std::static_pointer_cast<
4133 SpatialDomains::RobinBoundaryCondition>(m_bndConditions[i])
4134 ->m_robinPrimitiveCoeff;
4135
4136 // evalaute coefficient
4137 coeffeqn.Evaluate(x0, x1, x2, 0.0, coeffphys);
4138
4139 for (e = 0; e < locExpList->GetExpSize(); ++e)
4140 {
4141 RobinBCInfoSharedPtr rInfo =
4143 TraceID[cnt + e],
4144 Array_tmp = coeffphys + locExpList->GetPhys_Offset(e));
4145
4146 elmtid = ElmtID[cnt + e];
4147 // make link list if necessary
4148 if (returnval.count(elmtid) != 0)
4149 {
4150 rInfo->next = returnval.find(elmtid)->second;
4151 }
4152 returnval[elmtid] = rInfo;
4153 }
4154 }
4155 cnt += m_bndCondExpansions[i]->GetExpSize();
4156 }
4157
4158 return returnval;
4159}
std::shared_ptr< RobinBCInfo > RobinBCInfoSharedPtr

References Nektar::MemoryManager< DataType >::AllocateSharedPtr(), Nektar::SpatialDomains::eRobin, Nektar::LibUtilities::Equation::Evaluate(), Nektar::MultiRegions::ExpList::GetBoundaryToElmtMap(), m_bndCondExpansions, and m_bndConditions.

◆ v_GetTrace()

ExpListSharedPtr & Nektar::MultiRegions::DisContField::v_GetTrace ( )
overrideprotectedvirtual

Reimplemented from Nektar::MultiRegions::ExpList.

Definition at line 2806 of file DisContField.cpp.

2807{
2809 {
2810 SetUpDG();
2811 }
2812
2813 return m_trace;
2814}

References m_trace, Nektar::MultiRegions::NullExpListSharedPtr, and SetUpDG().

◆ v_GetTraceMap()

AssemblyMapDGSharedPtr & Nektar::MultiRegions::DisContField::v_GetTraceMap ( void  )
overrideprotectedvirtual

Reimplemented from Nektar::MultiRegions::ExpList.

Definition at line 2816 of file DisContField.cpp.

2817{
2818 return m_traceMap;
2819}

References m_traceMap.

◆ v_HelmSolve()

GlobalLinSysKey Nektar::MultiRegions::DisContField::v_HelmSolve ( const Array< OneD, const NekDouble > &  inarray,
Array< OneD, NekDouble > &  outarray,
const StdRegions::ConstFactorMap factors,
const StdRegions::VarCoeffMap varcoeff,
const MultiRegions::VarFactorsMap varfactors,
const Array< OneD, const NekDouble > &  dirForcing,
const bool  PhysSpaceForcing 
)
overrideprotectedvirtual

Solve the Helmholtz equation.

Reimplemented from Nektar::MultiRegions::ExpList.

Definition at line 3432 of file DisContField.cpp.

3439{
3440 int i, n, cnt, nbndry;
3441 int nexp = GetExpSize();
3442 Array<OneD, NekDouble> f(m_ncoeffs);
3443 DNekVec F(m_ncoeffs, f, eWrapper);
3444 Array<OneD, NekDouble> e_f, e_l;
3445 //----------------------------------
3446 // Setup RHS Inner product if required
3447 //----------------------------------
3448 if (PhysSpaceForcing)
3449 {
3450 IProductWRTBase(inarray, f);
3451 Vmath::Neg(m_ncoeffs, f, 1);
3452 }
3453 else
3454 {
3455 Vmath::Smul(m_ncoeffs, -1.0, inarray, 1, f, 1);
3456 }
3457 //----------------------------------
3458 // Solve continuous Boundary System
3459 //----------------------------------
3460 int GloBndDofs = m_traceMap->GetNumGlobalBndCoeffs();
3461 int NumDirBCs = m_traceMap->GetNumLocalDirBndCoeffs();
3462 int e_ncoeffs;
3463 GlobalMatrixKey HDGLamToUKey(StdRegions::eHybridDGLamToU,
3465 const DNekScalBlkMatSharedPtr &HDGLamToU = GetBlockMatrix(HDGLamToUKey);
3466 // Retrieve number of local trace space coefficients N_{\lambda},
3467 // and set up local elemental trace solution \lambda^e.
3468 int LocBndCoeffs = m_traceMap->GetNumLocalBndCoeffs();
3469 Array<OneD, NekDouble> bndrhs(LocBndCoeffs, 0.0);
3470 Array<OneD, NekDouble> loclambda(LocBndCoeffs, 0.0);
3471 DNekVec LocLambda(LocBndCoeffs, loclambda, eWrapper);
3472 //----------------------------------
3473 // Evaluate Trace Forcing
3474 // Kirby et al, 2010, P23, Step 5.
3475 //----------------------------------
3476 // Determing <u_lam,f> terms using HDGLamToU matrix
3477 for (cnt = n = 0; n < nexp; ++n)
3478 {
3479 nbndry = (*m_exp)[n]->NumDGBndryCoeffs();
3480 e_ncoeffs = (*m_exp)[n]->GetNcoeffs();
3481 e_f = f + m_coeff_offset[n];
3482 e_l = bndrhs + cnt;
3483 // use outarray as tmp space
3484 DNekVec Floc(nbndry, e_l, eWrapper);
3485 DNekVec ElmtFce(e_ncoeffs, e_f, eWrapper);
3486 Floc = Transpose(*(HDGLamToU->GetBlock(n, n))) * ElmtFce;
3487 cnt += nbndry;
3488 }
3489 Array<OneD, const int> bndCondMap =
3490 m_traceMap->GetBndCondCoeffsToLocalTraceMap();
3491 Array<OneD, const NekDouble> Sign = m_traceMap->GetLocalToGlobalBndSign();
3492 // Copy Dirichlet boundary conditions and weak forcing
3493 // into trace space
3494 int locid;
3495 cnt = 0;
3496 for (i = 0; i < m_bndCondExpansions.size(); ++i)
3497 {
3498 const Array<OneD, const NekDouble> bndcoeffs =
3499 m_bndCondExpansions[i]->GetCoeffs();
3500
3501 if (m_bndConditions[i]->GetBoundaryConditionType() ==
3503 {
3504 for (int j = 0; j < (m_bndCondExpansions[i])->GetNcoeffs(); ++j)
3505 {
3506 locid = bndCondMap[cnt + j];
3507 loclambda[locid] = Sign[locid] * bndcoeffs[j];
3508 }
3509 }
3510 else if (m_bndConditions[i]->GetBoundaryConditionType() ==
3512 m_bndConditions[i]->GetBoundaryConditionType() ==
3514 {
3515 // Add weak boundary condition to trace forcing
3516 for (int j = 0; j < (m_bndCondExpansions[i])->GetNcoeffs(); ++j)
3517 {
3518 locid = bndCondMap[cnt + j];
3519 bndrhs[locid] += Sign[locid] * bndcoeffs[j];
3520 }
3521 }
3522 else if (m_bndConditions[i]->GetBoundaryConditionType() ==
3524 {
3525 // skip increment of cnt if ePeriodic
3526 // because bndCondMap does not include ePeriodic
3527 continue;
3528 }
3529 cnt += (m_bndCondExpansions[i])->GetNcoeffs();
3530 }
3531
3532 //----------------------------------
3533 // Solve trace problem: \Lambda = K^{-1} F
3534 // K is the HybridDGHelmBndLam matrix.
3535 //----------------------------------
3536 if (GloBndDofs - NumDirBCs > 0)
3537 {
3538 GlobalLinSysKey key(StdRegions::eHybridDGHelmBndLam, m_traceMap,
3539 factors, varcoeff);
3541 LinSys->Solve(bndrhs, loclambda, m_traceMap);
3542
3543 // For consistency with previous version put global
3544 // solution into m_trace->m_coeffs
3545 m_traceMap->LocalToGlobal(loclambda, m_trace->UpdateCoeffs());
3546 }
3547
3548 //----------------------------------
3549 // Internal element solves
3550 //----------------------------------
3551 GlobalMatrixKey invHDGhelmkey(StdRegions::eInvHybridDGHelmholtz,
3553
3554 const DNekScalBlkMatSharedPtr &InvHDGHelm = GetBlockMatrix(invHDGhelmkey);
3555 DNekVec out(m_ncoeffs, outarray, eWrapper);
3556 Vmath::Zero(m_ncoeffs, outarray, 1);
3557
3558 // out = u_f + u_lam = (*InvHDGHelm)*f + (LamtoU)*Lam
3559 out = (*InvHDGHelm) * F + (*HDGLamToU) * LocLambda;
3560
3561 // Return empty GlobalLinSysKey
3562 return NullGlobalLinSysKey;
3563}
GlobalLinSysSharedPtr GetGlobalBndLinSys(const GlobalLinSysKey &mkey)
For a given key, returns the associated global linear system.
void IProductWRTBase(const Array< OneD, const NekDouble > &inarray, Array< OneD, NekDouble > &outarray)
This function calculates the inner product of a function with respect to all local expansion modes .
Definition: ExpList.h:1650
int GetNcoeffs(void) const
Returns the total number of local degrees of freedom .
Definition: ExpList.h:1512
const DNekScalBlkMatSharedPtr & GetBlockMatrix(const GlobalMatrixKey &gkey)
Definition: ExpList.cpp:2374
static AssemblyMapSharedPtr NullAssemblyMapSharedPtr
Definition: AssemblyMap.h:51
static GlobalLinSysKey NullGlobalLinSysKey(StdRegions::eNoMatrixType)
StdRegions::ConstFactorMap factors
std::shared_ptr< DNekScalBlkMat > DNekScalBlkMatSharedPtr
Definition: NekTypeDefs.hpp:79
NekMatrix< InnerMatrixType, BlockMatrixTag > Transpose(NekMatrix< InnerMatrixType, BlockMatrixTag > &rhs)
NekVector< NekDouble > DNekVec
Definition: NekTypeDefs.hpp:48
void Neg(int n, T *x, const int incx)
Negate x = -x.
Definition: Vmath.hpp:292
void Smul(int n, const T alpha, const T *x, const int incx, T *y, const int incy)
Scalar multiply y = alpha*x.
Definition: Vmath.hpp:100

References Nektar::SpatialDomains::eDirichlet, Nektar::StdRegions::eHybridDGHelmBndLam, Nektar::StdRegions::eHybridDGLamToU, Nektar::StdRegions::eInvHybridDGHelmholtz, Nektar::SpatialDomains::eNeumann, Nektar::SpatialDomains::ePeriodic, Nektar::SpatialDomains::eRobin, Nektar::eWrapper, Nektar::VarcoeffHashingTest::factors, Nektar::MultiRegions::ExpList::GetBlockMatrix(), Nektar::MultiRegions::ExpList::GetExpSize(), GetGlobalBndLinSys(), Nektar::MultiRegions::ExpList::GetNcoeffs(), Nektar::MultiRegions::ExpList::IProductWRTBase(), m_bndCondExpansions, m_bndConditions, Nektar::MultiRegions::ExpList::m_coeff_offset, Nektar::MultiRegions::ExpList::m_ncoeffs, m_trace, m_traceMap, Vmath::Neg(), Nektar::MultiRegions::NullAssemblyMapSharedPtr, Nektar::MultiRegions::NullGlobalLinSysKey(), Vmath::Smul(), Nektar::Transpose(), and Vmath::Zero().

◆ v_PeriodicBwdCopy()

void Nektar::MultiRegions::DisContField::v_PeriodicBwdCopy ( const Array< OneD, const NekDouble > &  Fwd,
Array< OneD, NekDouble > &  Bwd 
)
overrideprotectedvirtual

Reimplemented from Nektar::MultiRegions::ExpList.

Definition at line 2858 of file DisContField.cpp.

2860{
2861 for (int n = 0; n < m_periodicFwdCopy.size(); ++n)
2862 {
2863 Bwd[m_periodicBwdCopy[n]] = Fwd[m_periodicFwdCopy[n]];
2864 }
2865}

References m_periodicBwdCopy, and m_periodicFwdCopy.

Referenced by GetFwdBwdTracePhys(), and v_GetFwdBwdTracePhys().

◆ v_Reset()

void Nektar::MultiRegions::DisContField::v_Reset ( )
overrideprotectedvirtual

Reset this field, so that geometry information can be updated.

Reimplemented from Nektar::MultiRegions::ExpList.

Definition at line 4079 of file DisContField.cpp.

4080{
4082
4083 // Reset boundary condition expansions.
4084 for (int n = 0; n < m_bndCondExpansions.size(); ++n)
4085 {
4086 m_bndCondExpansions[n]->Reset();
4087 }
4088}
virtual void v_Reset()
Reset geometry information, metrics, matrix managers and geometry information.
Definition: ExpList.cpp:3043

References m_bndCondExpansions, and Nektar::MultiRegions::ExpList::v_Reset().

◆ v_SetBndCondBwdWeight()

void Nektar::MultiRegions::DisContField::v_SetBndCondBwdWeight ( const int  index,
const NekDouble  value 
)
overrideprotectedvirtual

Reimplemented from Nektar::MultiRegions::ExpList.

Definition at line 3141 of file DisContField.cpp.

3142{
3143 m_bndCondBndWeight[index] = value;
3144}

References m_bndCondBndWeight.

◆ v_UpdateBndCondExpansion()

MultiRegions::ExpListSharedPtr & Nektar::MultiRegions::DisContField::v_UpdateBndCondExpansion ( int  i)
overrideprotectedvirtual

Reimplemented from Nektar::MultiRegions::ExpList.

Definition at line 2847 of file DisContField.cpp.

2848{
2849 return m_bndCondExpansions[i];
2850}

References m_bndCondExpansions.

◆ v_UpdateBndConditions()

Array< OneD, SpatialDomains::BoundaryConditionShPtr > & Nektar::MultiRegions::DisContField::v_UpdateBndConditions ( )
overrideprotectedvirtual

Reimplemented from Nektar::MultiRegions::ExpList.

Definition at line 2853 of file DisContField.cpp.

2854{
2855 return m_bndConditions;
2856}

References m_bndConditions.

Member Data Documentation

◆ m_BCtoElmMap

Array<OneD, int> Nektar::MultiRegions::DisContField::m_BCtoElmMap

Definition at line 58 of file DisContField.h.

Referenced by v_GetBoundaryToElmtMap().

◆ m_BCtoTraceMap

Array<OneD, int> Nektar::MultiRegions::DisContField::m_BCtoTraceMap

Definition at line 59 of file DisContField.h.

Referenced by v_GetBoundaryToElmtMap().

◆ m_bndCondBndWeight

Array<OneD, NekDouble> Nektar::MultiRegions::DisContField::m_bndCondBndWeight
protected

◆ m_bndCondExpansions

Array<OneD, MultiRegions::ExpListSharedPtr> Nektar::MultiRegions::DisContField::m_bndCondExpansions
protected

◆ m_bndConditions

Array<OneD, SpatialDomains::BoundaryConditionShPtr> Nektar::MultiRegions::DisContField::m_bndConditions
protected

◆ m_boundaryTraces

std::set<int> Nektar::MultiRegions::DisContField::m_boundaryTraces
protected

A set storing the global IDs of any boundary Verts.

Definition at line 175 of file DisContField.h.

Referenced by DisContField(), IsLeftAdjacentTrace(), and SetUpDG().

◆ m_globalBndMat

GlobalLinSysMapShPtr Nektar::MultiRegions::DisContField::m_globalBndMat
protected

Global boundary matrix.

Definition at line 164 of file DisContField.h.

Referenced by DisContField(), GetGlobalBndLinSys(), and SetUpDG().

◆ m_interfaceMap

InterfaceMapDGSharedPtr Nektar::MultiRegions::DisContField::m_interfaceMap
protected

Interfaces mapping for trace space.

Definition at line 161 of file DisContField.h.

Referenced by DisContField(), GetFwdBwdTracePhys(), SetUpDG(), and v_GetFwdBwdTracePhys().

◆ m_leftAdjacentTraces

std::vector<bool> Nektar::MultiRegions::DisContField::m_leftAdjacentTraces
protected

◆ m_locTraceToTraceMap

LocTraceToTraceMapSharedPtr Nektar::MultiRegions::DisContField::m_locTraceToTraceMap
protected

◆ m_negatedFluxNormal

std::vector<bool> Nektar::MultiRegions::DisContField::m_negatedFluxNormal
private

Definition at line 337 of file DisContField.h.

Referenced by GetNegatedFluxNormal().

◆ m_numDirBndCondExpansions

size_t Nektar::MultiRegions::DisContField::m_numDirBndCondExpansions
protected

The number of boundary segments on which Dirichlet boundary conditions are imposed.

Definition at line 139 of file DisContField.h.

◆ m_periodicBwdCopy

std::vector<int> Nektar::MultiRegions::DisContField::m_periodicBwdCopy
protected

Definition at line 198 of file DisContField.h.

Referenced by DisContField(), SetUpDG(), and v_PeriodicBwdCopy().

◆ m_periodicEdges

PeriodicMap Nektar::MultiRegions::DisContField::m_periodicEdges
protected

A map which identifies pairs of periodic edges.

Definition at line 185 of file DisContField.h.

Referenced by Nektar::MultiRegions::ContField::ContField(), DisContField(), FindPeriodicTraces(), IsLeftAdjacentTrace(), SetUpDG(), and v_GetPeriodicEntities().

◆ m_periodicFaces

PeriodicMap Nektar::MultiRegions::DisContField::m_periodicFaces
protected

A map which identifies pairs of periodic faces.

Definition at line 190 of file DisContField.h.

Referenced by Nektar::MultiRegions::ContField::ContField(), DisContField(), FindPeriodicTraces(), IsLeftAdjacentTrace(), SetUpDG(), and v_GetPeriodicEntities().

◆ m_periodicFwdCopy

std::vector<int> Nektar::MultiRegions::DisContField::m_periodicFwdCopy
protected

A vector indicating degress of freedom which need to be copied from forwards to backwards space in case of a periodic boundary condition.

Definition at line 197 of file DisContField.h.

Referenced by DisContField(), SetUpDG(), and v_PeriodicBwdCopy().

◆ m_periodicVerts

PeriodicMap Nektar::MultiRegions::DisContField::m_periodicVerts
protected

A map which identifies groups of periodic vertices.

Definition at line 180 of file DisContField.h.

Referenced by Nektar::MultiRegions::ContField::ContField(), DisContField(), FindPeriodicTraces(), IsLeftAdjacentTrace(), SetUpDG(), and v_GetPeriodicEntities().

◆ m_trace

ExpListSharedPtr Nektar::MultiRegions::DisContField::m_trace
protected

◆ m_traceMap

AssemblyMapDGSharedPtr Nektar::MultiRegions::DisContField::m_traceMap
protected