Nektar++
Public Member Functions | Static Public Member Functions | Public Attributes | Static Public Attributes | Protected Member Functions | Private Member Functions | Private Attributes | Friends | List of all members
Nektar::CoupledLinearNS Class Reference

#include <CoupledLinearNS.h>

Inheritance diagram for Nektar::CoupledLinearNS:
[legend]

Public Member Functions

void SetUpCoupledMatrix (const NekDouble lambda=0.0, const Array< OneD, Array< OneD, NekDouble >> &Advfield=NullNekDoubleArrayOfArray, bool IsLinearNSEquation=true)
 
const SpatialDomains::ExpansionInfoMapGenPressureExp (const SpatialDomains::ExpansionInfoMap &VelExp)
 
void Solve (void)
 
void SolveLinearNS (const Array< OneD, Array< OneD, NekDouble >> &forcing)
 
void SolveLinearNS (Array< OneD, Array< OneD, NekDouble >> &forcing, Array< OneD, MultiRegions::ExpListSharedPtr > &fields, MultiRegions::ExpListSharedPtr &pressure, const int HomogeneousMode=0)
 
void SolveUnsteadyStokesSystem (const Array< OneD, const Array< OneD, NekDouble >> &inarray, Array< OneD, Array< OneD, NekDouble >> &outarray, const NekDouble time, const NekDouble a_iixDt)
 
void EvaluateAdvection (const Array< OneD, const Array< OneD, NekDouble >> &inarray, Array< OneD, Array< OneD, NekDouble >> &outarray, const NekDouble time)
 
void SolveSteadyNavierStokes (void)
 
void Continuation (void)
 
void EvaluateNewtonRHS (Array< OneD, Array< OneD, NekDouble >> &Velocity, Array< OneD, Array< OneD, NekDouble >> &outarray)
 
void InfNorm (Array< OneD, Array< OneD, NekDouble >> &inarray, Array< OneD, NekDouble > &outarray)
 
void L2Norm (Array< OneD, Array< OneD, NekDouble >> &inarray, Array< OneD, NekDouble > &outarray)
 
void DefineForcingTerm (void)
 
- Public Member Functions inherited from Nektar::IncNavierStokes
virtual ~IncNavierStokes ()
 
int GetNConvectiveFields (void)
 
Array< OneD, int > & GetVelocity (void)
 
void AddForcing (const SolverUtils::ForcingSharedPtr &pForce)
 
virtual void GetPressure (const Array< OneD, const Array< OneD, NekDouble >> &physfield, Array< OneD, NekDouble > &pressure) override
 Extract array with pressure from physfield. More...
 
virtual void GetDensity (const Array< OneD, const Array< OneD, NekDouble >> &physfield, Array< OneD, NekDouble > &density) override
 Extract array with density from physfield. More...
 
virtual bool HasConstantDensity () override
 
virtual void GetVelocity (const Array< OneD, const Array< OneD, NekDouble >> &physfield, Array< OneD, Array< OneD, NekDouble >> &velocity) override
 Extract array with velocity from physfield. More...
 
virtual void SetMovingFrameVelocities (const Array< OneD, NekDouble > &vFrameVels) override
 
virtual void GetMovingFrameVelocities (Array< OneD, NekDouble > &vFrameVels) override
 
virtual void SetMovingFrameAngles (const Array< OneD, NekDouble > &vFrameTheta) override
 
virtual void GetMovingFrameAngles (Array< OneD, NekDouble > &vFrameTheta) override
 
virtual void SetMovingFrameProjectionMat (const bnu::matrix< NekDouble > &vProjMat) override
 
virtual void GetMovingFrameProjectionMat (bnu::matrix< NekDouble > &vProjMat) override
 
virtual bool DefinedForcing (const std::string &sForce)
 
virtual void GetPivotPoint (Array< OneD, NekDouble > &vPivotPoint)
 
- Public Member Functions inherited from Nektar::SolverUtils::AdvectionSystem
SOLVER_UTILS_EXPORT AdvectionSystem (const LibUtilities::SessionReaderSharedPtr &pSession, const SpatialDomains::MeshGraphSharedPtr &pGraph)
 
virtual SOLVER_UTILS_EXPORT ~AdvectionSystem ()
 
SOLVER_UTILS_EXPORT AdvectionSharedPtr GetAdvObject ()
 Returns the advection object held by this instance. More...
 
SOLVER_UTILS_EXPORT Array< OneD, NekDoubleGetElmtCFLVals (const bool FlagAcousticCFL=true)
 
SOLVER_UTILS_EXPORT NekDouble GetCFLEstimate (int &elmtid)
 
- Public Member Functions inherited from Nektar::SolverUtils::UnsteadySystem
virtual SOLVER_UTILS_EXPORT ~UnsteadySystem ()
 Destructor. More...
 
SOLVER_UTILS_EXPORT NekDouble GetTimeStep (const Array< OneD, const Array< OneD, NekDouble >> &inarray)
 Calculate the larger time-step mantaining the problem stable. More...
 
SOLVER_UTILS_EXPORT void SteadyStateResidual (int step, Array< OneD, NekDouble > &L2)
 
- Public Member Functions inherited from Nektar::SolverUtils::EquationSystem
virtual SOLVER_UTILS_EXPORT ~EquationSystem ()
 Destructor. More...
 
SOLVER_UTILS_EXPORT void SetUpTraceNormals (void)
 
SOLVER_UTILS_EXPORT void InitObject (bool DeclareField=true)
 Initialises the members of this object. More...
 
SOLVER_UTILS_EXPORT void DoInitialise ()
 Perform any initialisation necessary before solving the problem. More...
 
SOLVER_UTILS_EXPORT void DoSolve ()
 Solve the problem. More...
 
SOLVER_UTILS_EXPORT void TransCoeffToPhys ()
 Transform from coefficient to physical space. More...
 
SOLVER_UTILS_EXPORT void TransPhysToCoeff ()
 Transform from physical to coefficient space. More...
 
SOLVER_UTILS_EXPORT void Output ()
 Perform output operations after solve. More...
 
SOLVER_UTILS_EXPORT NekDouble LinfError (unsigned int field, const Array< OneD, NekDouble > &exactsoln=NullNekDouble1DArray)
 Linf error computation. More...
 
SOLVER_UTILS_EXPORT std::string GetSessionName ()
 Get Session name. More...
 
template<class T >
std::shared_ptr< T > as ()
 
SOLVER_UTILS_EXPORT void ResetSessionName (std::string newname)
 Reset Session name. More...
 
SOLVER_UTILS_EXPORT LibUtilities::SessionReaderSharedPtr GetSession ()
 Get Session name. More...
 
SOLVER_UTILS_EXPORT MultiRegions::ExpListSharedPtr GetPressure ()
 Get pressure field if available. More...
 
SOLVER_UTILS_EXPORT void ExtraFldOutput (std::vector< Array< OneD, NekDouble >> &fieldcoeffs, std::vector< std::string > &variables)
 
SOLVER_UTILS_EXPORT void PrintSummary (std::ostream &out)
 Print a summary of parameters and solver characteristics. More...
 
SOLVER_UTILS_EXPORT void SetLambda (NekDouble lambda)
 Set parameter m_lambda. More...
 
SOLVER_UTILS_EXPORT SessionFunctionSharedPtr GetFunction (std::string name, const MultiRegions::ExpListSharedPtr &field=MultiRegions::NullExpListSharedPtr, bool cache=false)
 Get a SessionFunction by name. More...
 
SOLVER_UTILS_EXPORT void SetInitialConditions (NekDouble initialtime=0.0, bool dumpInitialConditions=true, const int domain=0)
 Initialise the data in the dependent fields. More...
 
SOLVER_UTILS_EXPORT void EvaluateExactSolution (int field, Array< OneD, NekDouble > &outfield, const NekDouble time)
 Evaluates an exact solution. More...
 
SOLVER_UTILS_EXPORT NekDouble L2Error (unsigned int field, const Array< OneD, NekDouble > &exactsoln, bool Normalised=false)
 Compute the L2 error between fields and a given exact solution. More...
 
SOLVER_UTILS_EXPORT NekDouble L2Error (unsigned int field, bool Normalised=false)
 Compute the L2 error of the fields. More...
 
SOLVER_UTILS_EXPORT Array< OneD, NekDoubleErrorExtraPoints (unsigned int field)
 Compute error (L2 and L_inf) over an larger set of quadrature points return [L2 Linf]. More...
 
SOLVER_UTILS_EXPORT void Checkpoint_Output (const int n)
 Write checkpoint file of m_fields. More...
 
SOLVER_UTILS_EXPORT void Checkpoint_Output (const int n, MultiRegions::ExpListSharedPtr &field, std::vector< Array< OneD, NekDouble >> &fieldcoeffs, std::vector< std::string > &variables)
 Write checkpoint file of custom data fields. More...
 
SOLVER_UTILS_EXPORT void Checkpoint_BaseFlow (const int n)
 Write base flow file of m_fields. More...
 
SOLVER_UTILS_EXPORT void WriteFld (const std::string &outname)
 Write field data to the given filename. More...
 
SOLVER_UTILS_EXPORT void WriteFld (const std::string &outname, MultiRegions::ExpListSharedPtr &field, std::vector< Array< OneD, NekDouble >> &fieldcoeffs, std::vector< std::string > &variables)
 Write input fields to the given filename. More...
 
SOLVER_UTILS_EXPORT void ImportFld (const std::string &infile, Array< OneD, MultiRegions::ExpListSharedPtr > &pFields)
 Input field data from the given file. More...
 
SOLVER_UTILS_EXPORT void ImportFldToMultiDomains (const std::string &infile, Array< OneD, MultiRegions::ExpListSharedPtr > &pFields, const int ndomains)
 Input field data from the given file to multiple domains. More...
 
SOLVER_UTILS_EXPORT void ImportFld (const std::string &infile, std::vector< std::string > &fieldStr, Array< OneD, Array< OneD, NekDouble >> &coeffs)
 Output a field. Input field data into array from the given file. More...
 
SOLVER_UTILS_EXPORT void ImportFld (const std::string &infile, MultiRegions::ExpListSharedPtr &pField, std::string &pFieldName)
 Output a field. Input field data into ExpList from the given file. More...
 
SOLVER_UTILS_EXPORT void SessionSummary (SummaryList &vSummary)
 Write out a session summary. More...
 
SOLVER_UTILS_EXPORT Array< OneD, MultiRegions::ExpListSharedPtr > & UpdateFields ()
 
SOLVER_UTILS_EXPORT LibUtilities::FieldMetaDataMapUpdateFieldMetaDataMap ()
 Get hold of FieldInfoMap so it can be updated. More...
 
SOLVER_UTILS_EXPORT NekDouble GetFinalTime ()
 Return final time. More...
 
SOLVER_UTILS_EXPORT int GetNcoeffs ()
 
SOLVER_UTILS_EXPORT int GetNcoeffs (const int eid)
 
SOLVER_UTILS_EXPORT int GetNumExpModes ()
 
SOLVER_UTILS_EXPORT const Array< OneD, int > GetNumExpModesPerExp ()
 
SOLVER_UTILS_EXPORT int GetNvariables ()
 
SOLVER_UTILS_EXPORT const std::string GetVariable (unsigned int i)
 
SOLVER_UTILS_EXPORT int GetTraceTotPoints ()
 
SOLVER_UTILS_EXPORT int GetTraceNpoints ()
 
SOLVER_UTILS_EXPORT int GetExpSize ()
 
SOLVER_UTILS_EXPORT int GetPhys_Offset (int n)
 
SOLVER_UTILS_EXPORT int GetCoeff_Offset (int n)
 
SOLVER_UTILS_EXPORT int GetTotPoints ()
 
SOLVER_UTILS_EXPORT int GetTotPoints (int n)
 
SOLVER_UTILS_EXPORT int GetNpoints ()
 
SOLVER_UTILS_EXPORT int GetSteps ()
 
SOLVER_UTILS_EXPORT NekDouble GetTimeStep ()
 
SOLVER_UTILS_EXPORT void CopyFromPhysField (const int i, Array< OneD, NekDouble > &output)
 
SOLVER_UTILS_EXPORT void CopyToPhysField (const int i, Array< OneD, NekDouble > &output)
 
SOLVER_UTILS_EXPORT void SetSteps (const int steps)
 
SOLVER_UTILS_EXPORT void ZeroPhysFields ()
 
SOLVER_UTILS_EXPORT void FwdTransFields ()
 
SOLVER_UTILS_EXPORT void SetModifiedBasis (const bool modbasis)
 
SOLVER_UTILS_EXPORT int GetCheckpointNumber ()
 
SOLVER_UTILS_EXPORT void SetCheckpointNumber (int num)
 
SOLVER_UTILS_EXPORT int GetCheckpointSteps ()
 
SOLVER_UTILS_EXPORT void SetCheckpointSteps (int num)
 
SOLVER_UTILS_EXPORT Array< OneD, const Array< OneD, NekDouble > > GetTraceNormals ()
 
SOLVER_UTILS_EXPORT void SetTime (const NekDouble time)
 
SOLVER_UTILS_EXPORT void SetInitialStep (const int step)
 
SOLVER_UTILS_EXPORT void SetBoundaryConditions (NekDouble time)
 Evaluates the boundary conditions at the given time. More...
 
- Public Member Functions inherited from Nektar::SolverUtils::FluidInterface
virtual ~FluidInterface ()=default
 
virtual SOLVER_UTILS_EXPORT void SetMovingFrameProjectionMat (const boost::numeric::ublas::matrix< NekDouble > &vProjMat)
 
virtual SOLVER_UTILS_EXPORT void GetMovingFrameProjectionMat (boost::numeric::ublas::matrix< NekDouble > &vProjMat)
 

Static Public Member Functions

static SolverUtils::EquationSystemSharedPtr create (const LibUtilities::SessionReaderSharedPtr &pSession, const SpatialDomains::MeshGraphSharedPtr &pGraph)
 Creates an instance of this class. More...
 

Public Attributes

Array< OneD, Array< OneD, NekDouble > > m_ForcingTerm
 
Array< OneD, Array< OneD, NekDouble > > m_ForcingTerm_Coeffs
 
Array< OneD, CoupledLocalToGlobalC0ContMapSharedPtrm_locToGloMap
 
- Public Attributes inherited from Nektar::SolverUtils::UnsteadySystem
NekDouble m_cflSafetyFactor
 CFL safety factor (comprise between 0 to 1). More...
 
NekDouble m_cflNonAcoustic
 
NekDouble m_CFLGrowth
 CFL growth rate. More...
 
NekDouble m_CFLEnd
 maximun cfl in cfl growth More...
 

Static Public Attributes

static std::string className
 Name of class. More...
 
- Static Public Attributes inherited from Nektar::SolverUtils::UnsteadySystem
static std::string cmdSetStartTime
 
static std::string cmdSetStartChkNum
 

Protected Member Functions

 CoupledLinearNS (const LibUtilities::SessionReaderSharedPtr &pSesssion, const SpatialDomains::MeshGraphSharedPtr &pGraph)
 
virtual void v_InitObject (bool DeclareField=true)
 Init object for UnsteadySystem class. More...
 
- Protected Member Functions inherited from Nektar::IncNavierStokes
 IncNavierStokes (const LibUtilities::SessionReaderSharedPtr &pSession, const SpatialDomains::MeshGraphSharedPtr &pGraph)
 Constructor. More...
 
EquationType GetEquationType (void)
 
void EvaluateAdvectionTerms (const Array< OneD, const Array< OneD, NekDouble >> &inarray, Array< OneD, Array< OneD, NekDouble >> &outarray, const NekDouble time)
 
void WriteModalEnergy (void)
 
void SetBoundaryConditions (NekDouble time)
 time dependent boundary conditions updating More...
 
void SetRadiationBoundaryForcing (int fieldid)
 Set Radiation forcing term. More...
 
void SetZeroNormalVelocity ()
 Set Normal Velocity Component to Zero. More...
 
void SetWomersleyBoundary (const int fldid, const int bndid)
 Set Womersley Profile if specified. More...
 
void SetUpWomersley (const int fldid, const int bndid, std::string womstr)
 Set Up Womersley details. More...
 
void SetMovingReferenceFrameBCs (const NekDouble &time)
 Set the moving reference frame boundary conditions. More...
 
void SetMRFWallBCs (const NekDouble &time)
 
void SetMRFDomainVelBCs (const NekDouble &time)
 
virtual MultiRegions::ExpListSharedPtr v_GetPressure () override
 
virtual Array< OneD, NekDoublev_GetMaxStdVelocity (const NekDouble SpeedSoundFactor) override
 
virtual bool v_PreIntegrate (int step) override
 
- Protected Member Functions inherited from Nektar::SolverUtils::AdvectionSystem
virtual SOLVER_UTILS_EXPORT bool v_PostIntegrate (int step)
 
- Protected Member Functions inherited from Nektar::SolverUtils::UnsteadySystem
SOLVER_UTILS_EXPORT UnsteadySystem (const LibUtilities::SessionReaderSharedPtr &pSession, const SpatialDomains::MeshGraphSharedPtr &pGraph)
 Initialises UnsteadySystem class members. More...
 
SOLVER_UTILS_EXPORT NekDouble MaxTimeStepEstimator ()
 Get the maximum timestep estimator for cfl control. More...
 
virtual SOLVER_UTILS_EXPORT void v_AppendOutput1D (Array< OneD, Array< OneD, NekDouble >> &solution1D)
 Print the solution at each solution point in a txt file. More...
 
virtual SOLVER_UTILS_EXPORT NekDouble v_GetTimeStep (const Array< OneD, const Array< OneD, NekDouble >> &inarray)
 Return the timestep to be used for the next step in the time-marching loop. More...
 
virtual SOLVER_UTILS_EXPORT bool v_RequireFwdTrans ()
 
virtual SOLVER_UTILS_EXPORT void v_SteadyStateResidual (int step, Array< OneD, NekDouble > &L2)
 
SOLVER_UTILS_EXPORT void CheckForRestartTime (NekDouble &time, int &nchk)
 
SOLVER_UTILS_EXPORT void SVVVarDiffCoeff (const Array< OneD, Array< OneD, NekDouble >> vel, StdRegions::VarCoeffMap &varCoeffMap)
 Evaluate the SVV diffusion coefficient according to Moura's paper where it should proportional to h time velocity. More...
 
virtual SOLVER_UTILS_EXPORT bool UpdateTimeStepCheck ()
 
- Protected Member Functions inherited from Nektar::SolverUtils::EquationSystem
SOLVER_UTILS_EXPORT EquationSystem (const LibUtilities::SessionReaderSharedPtr &pSession, const SpatialDomains::MeshGraphSharedPtr &pGraph)
 Initialises EquationSystem class members. More...
 
virtual SOLVER_UTILS_EXPORT NekDouble v_LinfError (unsigned int field, const Array< OneD, NekDouble > &exactsoln=NullNekDouble1DArray)
 Virtual function for the L_inf error computation between fields and a given exact solution. More...
 
virtual SOLVER_UTILS_EXPORT NekDouble v_L2Error (unsigned int field, const Array< OneD, NekDouble > &exactsoln=NullNekDouble1DArray, bool Normalised=false)
 Virtual function for the L_2 error computation between fields and a given exact solution. More...
 
virtual SOLVER_UTILS_EXPORT void v_SetInitialConditions (NekDouble initialtime=0.0, bool dumpInitialConditions=true, const int domain=0)
 
virtual SOLVER_UTILS_EXPORT void v_EvaluateExactSolution (unsigned int field, Array< OneD, NekDouble > &outfield, const NekDouble time)
 
virtual SOLVER_UTILS_EXPORT void v_ExtraFldOutput (std::vector< Array< OneD, NekDouble >> &fieldcoeffs, std::vector< std::string > &variables)
 

Private Member Functions

void SetUpCoupledMatrix (const NekDouble lambda, const Array< OneD, Array< OneD, NekDouble >> &Advfield, bool IsLinearNSEquation, const int HomogeneousMode, CoupledSolverMatrices &mat, CoupledLocalToGlobalC0ContMapSharedPtr &locToGloMap, const NekDouble lambda_imag=NekConstants::kNekUnsetDouble)
 
virtual void v_GenerateSummary (SolverUtils::SummaryList &s)
 Print a summary of time stepping parameters. More...
 
virtual void v_DoInitialise (void)
 Sets up initial conditions. More...
 
virtual void v_DoSolve (void)
 Solves an unsteady problem. More...
 
virtual bool v_NegatedOp (void)
 
virtual void v_TransCoeffToPhys (void)
 Virtual function for transformation to physical space. More...
 
virtual void v_TransPhysToCoeff (void)
 Virtual function for transformation to coefficient space. More...
 
virtual void v_Output (void)
 
virtual int v_GetForceDimension (void)
 

Private Attributes

bool m_zeroMode
 Id to identify when single mode is mean mode (i.e. beta=0);. More...
 
int m_counter
 
bool m_initialStep
 
NekDouble m_tol
 
int m_maxIt
 
int m_Restart
 
int m_MatrixSetUpStep
 
NekDouble m_kinvisMin
 
NekDouble m_kinvisStep
 
NekDouble m_KinvisPercentage
 
Array< OneD, CoupledSolverMatricesm_mat
 

Friends

class MemoryManager< CoupledLinearNS >
 

Additional Inherited Members

- Protected Types inherited from Nektar::SolverUtils::EquationSystem
enum  HomogeneousType { eHomogeneous1D , eHomogeneous2D , eHomogeneous3D , eNotHomogeneous }
 Parameter for homogeneous expansions. More...
 
- Protected Attributes inherited from Nektar::IncNavierStokes
ExtrapolateSharedPtr m_extrapolation
 
std::ofstream m_mdlFile
 modal energy file More...
 
bool m_SmoothAdvection
 bool to identify if advection term smoothing is requested More...
 
std::vector< SolverUtils::ForcingSharedPtrm_forcing
 Forcing terms. More...
 
int m_nConvectiveFields
 Number of fields to be convected;. More...
 
Array< OneD, int > m_velocity
 int which identifies which components of m_fields contains the velocity (u,v,w); More...
 
MultiRegions::ExpListSharedPtr m_pressure
 Pointer to field holding pressure field. More...
 
NekDouble m_kinvis
 Kinematic viscosity. More...
 
int m_energysteps
 dump energy to file at steps time More...
 
EquationType m_equationType
 equation type; More...
 
Array< OneD, Array< OneD, int > > m_fieldsBCToElmtID
 Mapping from BCs to Elmt IDs. More...
 
Array< OneD, Array< OneD, int > > m_fieldsBCToTraceID
 Mapping from BCs to Elmt Edge IDs. More...
 
Array< OneD, Array< OneD, NekDouble > > m_fieldsRadiationFactor
 RHS Factor for Radiation Condition. More...
 
int m_intSteps
 Number of time integration steps AND Order of extrapolation for pressure boundary conditions. More...
 
Array< OneD, NekDoublem_pivotPoint
 
std::map< int, std::map< int, WomersleyParamsSharedPtr > > m_womersleyParams
 Womersley parameters if required. More...
 
- Protected Attributes inherited from Nektar::SolverUtils::AdvectionSystem
SolverUtils::AdvectionSharedPtr m_advObject
 Advection term. More...
 
- Protected Attributes inherited from Nektar::SolverUtils::UnsteadySystem
int m_infosteps
 Number of time steps between outputting status information. More...
 
int m_abortSteps
 Number of steps between checks for abort conditions. More...
 
int m_filtersInfosteps
 Number of time steps between outputting filters information. More...
 
int m_nanSteps
 
LibUtilities::TimeIntegrationSchemeSharedPtr m_intScheme
 Wrapper to the time integration scheme. More...
 
LibUtilities::TimeIntegrationSchemeOperators m_ode
 The time integration scheme operators to use. More...
 
NekDouble m_epsilon
 
bool m_explicitDiffusion
 Indicates if explicit or implicit treatment of diffusion is used. More...
 
bool m_explicitAdvection
 Indicates if explicit or implicit treatment of advection is used. More...
 
bool m_explicitReaction
 Indicates if explicit or implicit treatment of reaction is used. More...
 
bool m_homoInitialFwd
 Flag to determine if simulation should start in homogeneous forward transformed state. More...
 
NekDouble m_steadyStateTol
 Tolerance to which steady state should be evaluated at. More...
 
int m_steadyStateSteps
 Check for steady state at step interval. More...
 
NekDouble m_steadyStateRes = 1.0
 
NekDouble m_steadyStateRes0 = 1.0
 
Array< OneD, Array< OneD, NekDouble > > m_previousSolution
 Storage for previous solution for steady-state check. More...
 
std::ofstream m_errFile
 
std::vector< int > m_intVariables
 
std::vector< std::pair< std::string, FilterSharedPtr > > m_filters
 
NekDouble m_filterTimeWarning
 Number of time steps between outputting status information. More...
 
NekDouble m_TimeIntegLambda = 0.0
 coefff of spacial derivatives(rhs or m_F in GLM) in calculating the residual of the whole equation(used in unsteady time integrations) More...
 
bool m_flagImplicitItsStatistics
 
bool m_flagImplicitSolver = false
 
Array< OneD, NekDoublem_magnitdEstimat
 estimate the magnitude of each conserved varibles More...
 
Array< OneD, NekDoublem_locTimeStep
 local time step(notice only for jfnk other see m_cflSafetyFactor) More...
 
NekDouble m_inArrayNorm = -1.0
 
int m_TotLinItePerStep = 0
 
int m_StagesPerStep = 1
 
bool m_flagUpdatePreconMat
 
int m_maxLinItePerNewton
 
int m_TotNewtonIts = 0
 
int m_TotLinIts = 0
 
int m_TotImpStages = 0
 
bool m_CalcPhysicalAV = true
 flag to update artificial viscosity More...
 
- Protected Attributes inherited from Nektar::SolverUtils::EquationSystem
LibUtilities::CommSharedPtr m_comm
 Communicator. More...
 
bool m_verbose
 
bool m_root
 
LibUtilities::SessionReaderSharedPtr m_session
 The session reader. More...
 
std::map< std::string, SolverUtils::SessionFunctionSharedPtrm_sessionFunctions
 Map of known SessionFunctions. More...
 
LibUtilities::FieldIOSharedPtr m_fld
 Field input/output. More...
 
Array< OneD, MultiRegions::ExpListSharedPtrm_fields
 Array holding all dependent variables. More...
 
SpatialDomains::BoundaryConditionsSharedPtr m_boundaryConditions
 Pointer to boundary conditions object. More...
 
SpatialDomains::MeshGraphSharedPtr m_graph
 Pointer to graph defining mesh. More...
 
std::string m_sessionName
 Name of the session. More...
 
NekDouble m_time
 Current time of simulation. More...
 
int m_initialStep
 Number of the step where the simulation should begin. More...
 
NekDouble m_fintime
 Finish time of the simulation. More...
 
NekDouble m_timestep
 Time step size. More...
 
NekDouble m_timestepMax = -1.0
 Time step size. More...
 
NekDouble m_lambda
 Lambda constant in real system if one required. More...
 
NekDouble m_checktime
 Time between checkpoints. More...
 
NekDouble m_lastCheckTime
 
NekDouble m_TimeIncrementFactor
 
int m_nchk
 Number of checkpoints written so far. More...
 
int m_steps
 Number of steps to take. More...
 
int m_checksteps
 Number of steps between checkpoints. More...
 
int m_spacedim
 Spatial dimension (>= expansion dim). More...
 
int m_expdim
 Expansion dimension. More...
 
bool m_singleMode
 Flag to determine if single homogeneous mode is used. More...
 
bool m_halfMode
 Flag to determine if half homogeneous mode is used. More...
 
bool m_multipleModes
 Flag to determine if use multiple homogenenous modes are used. More...
 
bool m_useFFT
 Flag to determine if FFT is used for homogeneous transform. More...
 
bool m_homogen_dealiasing
 Flag to determine if dealiasing is used for homogeneous simulations. More...
 
bool m_specHP_dealiasing
 Flag to determine if dealisising is usde for the Spectral/hp element discretisation. More...
 
enum MultiRegions::ProjectionType m_projectionType
 Type of projection; e.g continuous or discontinuous. More...
 
Array< OneD, Array< OneD, NekDouble > > m_traceNormals
 Array holding trace normals for DG simulations in the forwards direction. More...
 
Array< OneD, bool > m_checkIfSystemSingular
 Flag to indicate if the fields should be checked for singularity. More...
 
LibUtilities::FieldMetaDataMap m_fieldMetaDataMap
 Map to identify relevant solver info to dump in output fields. More...
 
Array< OneD, NekDoublem_movingFrameVelsxyz
 Moving frame of reference velocities. More...
 
Array< OneD, NekDoublem_movingFrameTheta
 Moving frame of reference angles with respect to the. More...
 
boost::numeric::ublas::matrix< NekDoublem_movingFrameProjMat
 Projection matrix for transformation between inertial and moving. More...
 
int m_NumQuadPointsError
 Number of Quadrature points used to work out the error. More...
 
enum HomogeneousType m_HomogeneousType
 
NekDouble m_LhomX
 physical length in X direction (if homogeneous) More...
 
NekDouble m_LhomY
 physical length in Y direction (if homogeneous) More...
 
NekDouble m_LhomZ
 physical length in Z direction (if homogeneous) More...
 
int m_npointsX
 number of points in X direction (if homogeneous) More...
 
int m_npointsY
 number of points in Y direction (if homogeneous) More...
 
int m_npointsZ
 number of points in Z direction (if homogeneous) More...
 
int m_HomoDirec
 number of homogenous directions More...
 
- Static Protected Attributes inherited from Nektar::IncNavierStokes
static std::string eqTypeLookupIds []
 
- Static Protected Attributes inherited from Nektar::SolverUtils::EquationSystem
static std::string equationSystemTypeLookupIds []
 

Detailed Description

Set up expansion field for velocity and pressure, the local to global mapping arrays and the basic memory definitions for coupled matrix system

Definition at line 86 of file CoupledLinearNS.h.

Constructor & Destructor Documentation

◆ CoupledLinearNS()

Nektar::CoupledLinearNS::CoupledLinearNS ( const LibUtilities::SessionReaderSharedPtr pSesssion,
const SpatialDomains::MeshGraphSharedPtr pGraph 
)
protected

Definition at line 59 of file CoupledLinearNS.cpp.

62  : UnsteadySystem(pSession, pGraph), IncNavierStokes(pSession, pGraph),
63  m_zeroMode(false)
64 {
65 }
bool m_zeroMode
Id to identify when single mode is mean mode (i.e. beta=0);.
IncNavierStokes(const LibUtilities::SessionReaderSharedPtr &pSession, const SpatialDomains::MeshGraphSharedPtr &pGraph)
Constructor.
SOLVER_UTILS_EXPORT UnsteadySystem(const LibUtilities::SessionReaderSharedPtr &pSession, const SpatialDomains::MeshGraphSharedPtr &pGraph)
Initialises UnsteadySystem class members.

Member Function Documentation

◆ Continuation()

void Nektar::CoupledLinearNS::Continuation ( void  )

Definition at line 1839 of file CoupledLinearNS.cpp.

1840 {
1841  Array<OneD, Array<OneD, NekDouble>> u_N(m_velocity.size());
1842  Array<OneD, Array<OneD, NekDouble>> tmp_RHS(m_velocity.size());
1843  Array<OneD, Array<OneD, NekDouble>> RHS(m_velocity.size());
1844  Array<OneD, Array<OneD, NekDouble>> u_star(m_velocity.size());
1845 
1846  cout << "We apply the continuation method: " << endl;
1847 
1848  for (int i = 0; i < m_velocity.size(); ++i)
1849  {
1850  u_N[i] = Array<OneD, NekDouble>(m_fields[m_velocity[i]]->GetTotPoints(),
1851  0.0);
1852  m_fields[m_velocity[i]]->BwdTrans(m_fields[m_velocity[i]]->GetCoeffs(),
1853  u_N[i]);
1854 
1855  RHS[i] = Array<OneD, NekDouble>(m_fields[m_velocity[i]]->GetTotPoints(),
1856  0.0);
1857  tmp_RHS[i] = Array<OneD, NekDouble>(
1858  m_fields[m_velocity[i]]->GetTotPoints(), 0.0);
1859 
1860  m_fields[m_velocity[i]]->PhysDeriv(i, u_N[i], tmp_RHS[i]);
1861  Vmath::Smul(tmp_RHS[i].size(), m_kinvis, tmp_RHS[i], 1, tmp_RHS[i], 1);
1862 
1863  bool waveSpace = m_fields[m_velocity[i]]->GetWaveSpace();
1864  m_fields[m_velocity[i]]->SetWaveSpace(true);
1865  m_fields[m_velocity[i]]->IProductWRTDerivBase(i, tmp_RHS[i], RHS[i]);
1866  m_fields[m_velocity[i]]->SetWaveSpace(waveSpace);
1867  }
1868 
1869  SetUpCoupledMatrix(0.0, u_N, true);
1870  SolveLinearNS(RHS);
1871 
1872  for (int i = 0; i < m_velocity.size(); ++i)
1873  {
1874  u_star[i] = Array<OneD, NekDouble>(
1875  m_fields[m_velocity[i]]->GetTotPoints(), 0.0);
1876  m_fields[m_velocity[i]]->BwdTrans(m_fields[m_velocity[i]]->GetCoeffs(),
1877  u_star[i]);
1878 
1879  // u_star(k+1) = u_N(k) + DeltaKinvis * u_star(k)
1880  Vmath::Smul(u_star[i].size(), m_kinvis, u_star[i], 1, u_star[i], 1);
1881  Vmath::Vadd(u_star[i].size(), u_star[i], 1, u_N[i], 1, u_star[i], 1);
1882 
1883  m_fields[m_velocity[i]]->FwdTrans(
1884  u_star[i], m_fields[m_velocity[i]]->UpdateCoeffs());
1885  }
1886 
1888 }
void SetUpCoupledMatrix(const NekDouble lambda=0.0, const Array< OneD, Array< OneD, NekDouble >> &Advfield=NullNekDoubleArrayOfArray, bool IsLinearNSEquation=true)
void SolveLinearNS(const Array< OneD, Array< OneD, NekDouble >> &forcing)
NekDouble m_kinvis
Kinematic viscosity.
Array< OneD, int > m_velocity
int which identifies which components of m_fields contains the velocity (u,v,w);
Array< OneD, MultiRegions::ExpListSharedPtr > m_fields
Array holding all dependent variables.
SOLVER_UTILS_EXPORT int GetTotPoints()
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.cpp:359
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.cpp:248

References Nektar::SolverUtils::EquationSystem::GetTotPoints(), Nektar::SolverUtils::EquationSystem::m_fields, Nektar::IncNavierStokes::m_kinvis, m_KinvisPercentage, Nektar::IncNavierStokes::m_velocity, SetUpCoupledMatrix(), Vmath::Smul(), SolveLinearNS(), and Vmath::Vadd().

Referenced by v_DoSolve().

◆ create()

static SolverUtils::EquationSystemSharedPtr Nektar::CoupledLinearNS::create ( const LibUtilities::SessionReaderSharedPtr pSession,
const SpatialDomains::MeshGraphSharedPtr pGraph 
)
inlinestatic

Creates an instance of this class.

Definition at line 92 of file CoupledLinearNS.h.

95  {
98  p->InitObject();
99  return p;
100  }
static std::shared_ptr< DataType > AllocateSharedPtr(const Args &...args)
Allocate a shared pointer from the memory pool.
std::shared_ptr< EquationSystem > EquationSystemSharedPtr
A shared pointer to an EquationSystem object.

References Nektar::MemoryManager< DataType >::AllocateSharedPtr(), and CellMLToNektar.cellml_metadata::p.

◆ DefineForcingTerm()

void Nektar::CoupledLinearNS::DefineForcingTerm ( void  )

Definition at line 1695 of file CoupledLinearNS.cpp.

1696 {
1697  m_ForcingTerm = Array<OneD, Array<OneD, NekDouble>>(m_velocity.size());
1699  Array<OneD, Array<OneD, NekDouble>>(m_velocity.size());
1700 
1701  for (int i = 0; i < m_velocity.size(); ++i)
1702  {
1703  m_ForcingTerm[i] = Array<OneD, NekDouble>(
1704  m_fields[m_velocity[i]]->GetTotPoints(), 0.0);
1706  Array<OneD, NekDouble>(m_fields[m_velocity[i]]->GetNcoeffs(), 0.0);
1707  }
1708 
1709  if (m_session->DefinesFunction("ForcingTerm"))
1710  {
1711  std::vector<std::string> fieldStr;
1712  for (int i = 0; i < m_velocity.size(); ++i)
1713  {
1714  fieldStr.push_back(
1715  m_boundaryConditions->GetVariable(m_velocity[i]));
1716  }
1717  GetFunction("ForcingTerm")->Evaluate(fieldStr, m_ForcingTerm);
1718  for (int i = 0; i < m_velocity.size(); ++i)
1719  {
1720  m_fields[m_velocity[i]]->FwdTransLocalElmt(m_ForcingTerm[i],
1722  }
1723  }
1724  else
1725  {
1726  cout << "'ForcingTerm' section has not been defined in the input file "
1727  "=> forcing=0"
1728  << endl;
1729  }
1730 }
Array< OneD, Array< OneD, NekDouble > > m_ForcingTerm_Coeffs
Array< OneD, Array< OneD, NekDouble > > m_ForcingTerm
LibUtilities::SessionReaderSharedPtr m_session
The session reader.
SOLVER_UTILS_EXPORT int GetNcoeffs()
SpatialDomains::BoundaryConditionsSharedPtr m_boundaryConditions
Pointer to boundary conditions object.
SOLVER_UTILS_EXPORT SessionFunctionSharedPtr GetFunction(std::string name, const MultiRegions::ExpListSharedPtr &field=MultiRegions::NullExpListSharedPtr, bool cache=false)
Get a SessionFunction by name.

References Nektar::SolverUtils::EquationSystem::GetFunction(), Nektar::SolverUtils::EquationSystem::GetNcoeffs(), Nektar::SolverUtils::EquationSystem::GetTotPoints(), Nektar::SolverUtils::EquationSystem::m_boundaryConditions, Nektar::SolverUtils::EquationSystem::m_fields, m_ForcingTerm, m_ForcingTerm_Coeffs, Nektar::SolverUtils::EquationSystem::m_session, and Nektar::IncNavierStokes::m_velocity.

Referenced by v_DoInitialise().

◆ EvaluateAdvection()

void Nektar::CoupledLinearNS::EvaluateAdvection ( const Array< OneD, const Array< OneD, NekDouble >> &  inarray,
Array< OneD, Array< OneD, NekDouble >> &  outarray,
const NekDouble  time 
)

Definition at line 1510 of file CoupledLinearNS.cpp.

1513 {
1514  // evaluate convection terms
1515  EvaluateAdvectionTerms(inarray, outarray, time);
1516 
1517  for (auto &x : m_forcing)
1518  {
1519  x->Apply(m_fields, outarray, outarray, time);
1520  }
1521 }
void EvaluateAdvectionTerms(const Array< OneD, const Array< OneD, NekDouble >> &inarray, Array< OneD, Array< OneD, NekDouble >> &outarray, const NekDouble time)
std::vector< SolverUtils::ForcingSharedPtr > m_forcing
Forcing terms.

References Nektar::IncNavierStokes::EvaluateAdvectionTerms(), Nektar::SolverUtils::EquationSystem::m_fields, and Nektar::IncNavierStokes::m_forcing.

Referenced by v_DoInitialise().

◆ EvaluateNewtonRHS()

void Nektar::CoupledLinearNS::EvaluateNewtonRHS ( Array< OneD, Array< OneD, NekDouble >> &  Velocity,
Array< OneD, Array< OneD, NekDouble >> &  outarray 
)

Definition at line 1922 of file CoupledLinearNS.cpp.

1925 {
1926  Array<OneD, Array<OneD, NekDouble>> Eval_Adv(m_velocity.size());
1927  Array<OneD, Array<OneD, NekDouble>> tmp_DerVel(m_velocity.size());
1928  Array<OneD, Array<OneD, NekDouble>> AdvTerm(m_velocity.size());
1929  Array<OneD, Array<OneD, NekDouble>> ViscTerm(m_velocity.size());
1930  Array<OneD, Array<OneD, NekDouble>> Forc(m_velocity.size());
1931 
1932  for (int i = 0; i < m_velocity.size(); ++i)
1933  {
1934  Eval_Adv[i] = Array<OneD, NekDouble>(
1935  m_fields[m_velocity[i]]->GetTotPoints(), 0.0);
1936  tmp_DerVel[i] = Array<OneD, NekDouble>(
1937  m_fields[m_velocity[i]]->GetTotPoints(), 0.0);
1938 
1939  AdvTerm[i] = Array<OneD, NekDouble>(
1940  m_fields[m_velocity[i]]->GetTotPoints(), 0.0);
1941  ViscTerm[i] = Array<OneD, NekDouble>(
1942  m_fields[m_velocity[i]]->GetTotPoints(), 0.0);
1943  Forc[i] = Array<OneD, NekDouble>(
1944  m_fields[m_velocity[i]]->GetTotPoints(), 0.0);
1945  outarray[i] = Array<OneD, NekDouble>(
1946  m_fields[m_velocity[i]]->GetTotPoints(), 0.0);
1947 
1948  m_fields[m_velocity[i]]->PhysDeriv(i, Velocity[i], tmp_DerVel[i]);
1949 
1950  Vmath::Smul(tmp_DerVel[i].size(), m_kinvis, tmp_DerVel[i], 1,
1951  tmp_DerVel[i], 1);
1952  }
1953 
1954  EvaluateAdvectionTerms(Velocity, Eval_Adv, m_time);
1955 
1956  for (int i = 0; i < m_velocity.size(); ++i)
1957  {
1958  bool waveSpace = m_fields[m_velocity[i]]->GetWaveSpace();
1959  m_fields[m_velocity[i]]->SetWaveSpace(true);
1960  m_fields[m_velocity[i]]->IProductWRTBase(Eval_Adv[i],
1961  AdvTerm[i]); //(w, (u.grad)u)
1962  m_fields[m_velocity[i]]->IProductWRTDerivBase(
1963  i, tmp_DerVel[i], ViscTerm[i]); //(grad w, grad u)
1964  m_fields[m_velocity[i]]->IProductWRTBase(m_ForcingTerm[i],
1965  Forc[i]); //(w, f)
1966  m_fields[m_velocity[i]]->SetWaveSpace(waveSpace);
1967 
1968  Vmath::Vsub(outarray[i].size(), outarray[i], 1, AdvTerm[i], 1,
1969  outarray[i], 1);
1970  Vmath::Vsub(outarray[i].size(), outarray[i], 1, ViscTerm[i], 1,
1971  outarray[i], 1);
1972 
1973  Vmath::Vadd(outarray[i].size(), outarray[i], 1, Forc[i], 1, outarray[i],
1974  1);
1975  }
1976 }
NekDouble m_time
Current time of simulation.
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.cpp:419

References Nektar::IncNavierStokes::EvaluateAdvectionTerms(), Nektar::SolverUtils::EquationSystem::GetTotPoints(), Nektar::SolverUtils::EquationSystem::m_fields, m_ForcingTerm, Nektar::IncNavierStokes::m_kinvis, Nektar::SolverUtils::EquationSystem::m_time, Nektar::IncNavierStokes::m_velocity, Vmath::Smul(), Vmath::Vadd(), and Vmath::Vsub().

Referenced by SolveSteadyNavierStokes().

◆ GenPressureExp()

const SpatialDomains::ExpansionInfoMap & Nektar::CoupledLinearNS::GenPressureExp ( const SpatialDomains::ExpansionInfoMap VelExp)

Definition at line 1978 of file CoupledLinearNS.cpp.

1980 {
1981  int i;
1983  returnval =
1985 
1986  int nummodes;
1987 
1988  for (auto &expMapIter : VelExp)
1989  {
1991 
1992  for (i = 0; i < expMapIter.second->m_basisKeyVector.size(); ++i)
1993  {
1994  LibUtilities::BasisKey B = expMapIter.second->m_basisKeyVector[i];
1995  nummodes = B.GetNumModes();
1996  ASSERTL0(nummodes > 3,
1997  "Velocity polynomial space not sufficiently high (>= 4)");
1998  // Should probably set to be an orthogonal basis.
1999  LibUtilities::BasisKey newB(B.GetBasisType(), nummodes - 2,
2000  B.GetPointsKey());
2001  BasisVec.push_back(newB);
2002  }
2003 
2004  // Put new expansion into list.
2005  SpatialDomains::ExpansionInfoShPtr expansionElementShPtr =
2007  expMapIter.second->m_geomShPtr, BasisVec);
2008  (*returnval)[expMapIter.first] = expansionElementShPtr;
2009  }
2010 
2011  // Save expansion into graph.
2012  m_graph->SetExpansionInfo("p", returnval);
2013 
2014  return *returnval;
2015 }
#define ASSERTL0(condition, msg)
Definition: ErrorUtil.hpp:215
SpatialDomains::MeshGraphSharedPtr m_graph
Pointer to graph defining mesh.
std::vector< BasisKey > BasisKeyVector
Name for a vector of BasisKeys.
std::shared_ptr< ExpansionInfoMap > ExpansionInfoMapShPtr
Definition: MeshGraph.h:145
std::shared_ptr< ExpansionInfo > ExpansionInfoShPtr
Definition: MeshGraph.h:140

References Nektar::MemoryManager< DataType >::AllocateSharedPtr(), ASSERTL0, Nektar::LibUtilities::BasisKey::GetBasisType(), Nektar::LibUtilities::BasisKey::GetNumModes(), Nektar::LibUtilities::BasisKey::GetPointsKey(), and Nektar::SolverUtils::EquationSystem::m_graph.

Referenced by v_InitObject().

◆ InfNorm()

void Nektar::CoupledLinearNS::InfNorm ( Array< OneD, Array< OneD, NekDouble >> &  inarray,
Array< OneD, NekDouble > &  outarray 
)

Definition at line 1890 of file CoupledLinearNS.cpp.

1892 {
1893  for (int i = 0; i < m_velocity.size(); ++i)
1894  {
1895  outarray[i] = 0.0;
1896  for (int j = 0; j < inarray[i].size(); ++j)
1897  {
1898  if (inarray[i][j] > outarray[i])
1899  {
1900  outarray[i] = inarray[i][j];
1901  }
1902  }
1903  cout << "InfNorm[" << i << "] = " << outarray[i] << endl;
1904  }
1905 }

References Nektar::IncNavierStokes::m_velocity.

◆ L2Norm()

void Nektar::CoupledLinearNS::L2Norm ( Array< OneD, Array< OneD, NekDouble >> &  inarray,
Array< OneD, NekDouble > &  outarray 
)

Definition at line 1907 of file CoupledLinearNS.cpp.

1909 {
1910  for (int i = 0; i < m_velocity.size(); ++i)
1911  {
1912  outarray[i] = 0.0;
1913  for (int j = 0; j < inarray[i].size(); ++j)
1914  {
1915  outarray[i] += inarray[i][j] * inarray[i][j];
1916  }
1917  outarray[i] = sqrt(outarray[i]);
1918  cout << "L2Norm[" << i << "] = " << outarray[i] << endl;
1919  }
1920 }
scalarT< T > sqrt(scalarT< T > in)
Definition: scalar.hpp:291

References Nektar::IncNavierStokes::m_velocity, and tinysimd::sqrt().

Referenced by SolveSteadyNavierStokes().

◆ SetUpCoupledMatrix() [1/2]

void Nektar::CoupledLinearNS::SetUpCoupledMatrix ( const NekDouble  lambda,
const Array< OneD, Array< OneD, NekDouble >> &  Advfield,
bool  IsLinearNSEquation,
const int  HomogeneousMode,
CoupledSolverMatrices mat,
CoupledLocalToGlobalC0ContMapSharedPtr locToGloMap,
const NekDouble  lambda_imag = NekConstants::kNekUnsetDouble 
)
private

Generate the linearised Navier Stokes solver based on the static condensation of the interior velocity space and pressure modes. This call also allows for a Fourier mode to be specified, however if HomogeneneousMode= 0 then can be used for a standared 2D and hopefully 3D (in the future).

Set up a coupled linearised Naviers-Stokes solve in the following manner:

Consider the linearised Navier-Stokes element matrix denoted as

\[ \left [ \begin{array}{ccc} A & -D_{bnd}^T & B\\ -D_{bnd}& 0 & -D_{int}\\ \tilde{B}^T & -D_{int}^T & C \end{array} \right ] \left [ \begin{array}{c} {\bf v}_{bnd} \\ p\\ {\bf v}_{int} \end{array} \right ] = \left [ \begin{array}{c} {\bf f}_{bnd} \\ 0\\ {\bf f}_{int} \end{array} \right ] \]

where \({\bf v}_{bnd}, {\bf f}_{bnd}\) denote the degrees of freedom of the elemental velocities on the boundary of the element, \({\bf v}_{int}, {\bf f}_{int}\) denote the degrees of freedom of the elemental velocities on the interior of the element and \(p\) is the piecewise continuous pressure. The matrices have the interpretation

\[ A[n,m] = (\nabla \phi^b_n, \nu \nabla \phi^b_m) + (\phi^b_n,{\bf U \cdot \nabla} \phi^b_m) + (\phi^b_n \nabla^T {\bf U} \phi^b_m), \]

\[ B[n,m] = (\nabla \phi^b_n, \nu \nabla \phi^i_m) + (\phi^b_n,{\bf U \cdot \nabla} \phi^i_m) + (\phi^b_n \nabla^T {\bf U} \phi^i_m),\]

\[\tilde{B}^T[n,m] = (\nabla \phi^i_n, \nu \nabla \phi^b_m) + (\phi^i_n,{\bf U \cdot \nabla} \phi^b_m) + (\phi^i_n \nabla^T {\bf U} \phi^b_m) \]

\[ C[n,m] = (\nabla \phi^i_n, \nu \nabla \phi^i_m) + (\phi^i_n,{\bf U \cdot \nabla} \phi^i_m) + (\phi^i_n \nabla^T {\bf U} \phi^i_m),\]

\[ D_{bnd}[n,m] = (\psi_m,\nabla \phi^b),\]

\[ D_{int}[n,m] = (\psi_m,\nabla \phi^i) \]

where \(\psi\) is the space of pressures typically at order \(P-2\) and \(\phi\) is the velocity vector space of polynomial order \(P\). (Note the above definitions for the transpose terms shoudl be interpreted with care since we have used a tensor differential for the \(\nabla^T \) terms)

Note \(B = \tilde{B}^T\) if just considering the stokes operator and then \(C\) is also symmetric. Also note that \(A,B\) and \(C\) are block diagonal in the Oseen equation when \(\nabla^T {\bf U}\) are zero.

Since \(C\) is invertible we can premultiply the governing elemental equation by the following matrix:

\[ \left [ \begin{array}{ccc} I & 0 & -BC^{-1}\\ 0& I & D_{int}C^{-1}\\ 0 & 0 & I \end{array} \right ] \left \{ \left [ \begin{array}{ccc} A & -D_{bnd}^T & B\\ -D_{bnd}& 0 & -D_{int}\\ \tilde{B}^T & -D_{int}^T & C \end{array} \right ] \left [ \begin{array}{c} {\bf v}_{bnd} \\ p\\ {\bf v_{int}} \end{array} \right ] = \left [ \begin{array}{c} {\bf f}_{bnd} \\ 0\\ {\bf f_{int}} \end{array} \right ] \right \} \]

which if we multiply out the matrix equation we obtain

\[ \left [ \begin{array}{ccc} A - B C^{-1}\tilde{B}^T & -D_{bnd}^T +B C^{-1} D_{int}^T& 0\\ -D_{bnd}+D_{int} C^{-1} \tilde{B}^T & -D_{int} C^{-1} D_{int}^T & 0\\ \tilde{B}^T & -D_{int}^T & C \end{array} \right ] \left [ \begin{array}{c} {\bf v}_{bnd} \\ p\\ {\bf v_{int}} \end{array} \right ] = \left [ \begin{array}{c} {\bf f}_{bnd} -B C^{-1} {\bf f}_{int}\\ f_p = D_{int} C^{-1} {\bf f}_{int}\\ {\bf f_{int}} \end{array} \right ] \]

In the above equation the \({\bf v}_{int}\) degrees of freedom are decoupled and so we need to solve for the \({\bf v}_{bnd}, p\) degrees of freedom. The final step is to perform a second level of static condensation but where we will lump the mean pressure mode (or a pressure degree of freedom containing a mean component) with the velocity boundary degrees of freedom. To do we define \({\bf b} = [{\bf v}_{bnd}, p_0]\) where \(p_0\) is the mean pressure mode and \(\hat{p}\) to be the remainder of the pressure space. We now repartition the top \(2 \times 2\) block of matrices of previous matrix equation as

\[ \left [ \begin{array}{cc} \hat{A} & \hat{B}\\ \hat{C} & \hat{D} \end{array} \right ] \left [ \begin{array}{c} {\bf b} \\ \hat{p} \end{array} \right ] = \left [ \begin{array}{c} \hat{\bf f}_{bnd} \\ \hat{f}_p \end{array} \right ] \label{eqn.linNS_fac2} \]

where

\[ \hat{A}_{ij} = \left [ \begin{array}{cc} A - B C^{-1}\tilde{B}^T & [-D_{bnd}^T +B C^{-1} D_{int}^T]_{i0}\\ {[}-D_{bnd}+D_{int} C^{-1} \tilde{B}^T]_{0j} & -[D_{int} C^{-1} D_{int}^T ]_{00} \end{array} \right ] \]

\[ \hat{B}_{ij} = \left [ \begin{array}{c} [-D_{bnd}^T +B C^{-1} D_{int}^T]_{i,j+1} \\ {[} -D_{int} C^{-1} D^T_{int} ]_{0j}\end{array} \right ] \]

\[ \hat{C}_{ij} = \left [\begin{array}{cc} -D_{bnd} + D_{int} C^{-1} \tilde{B}^T, & {[} -D_{int} C^{-1} D^T_{int} ]_{i+1,0}\end{array} \right ] \]

\[ \hat{D}_{ij} = \left [\begin{array}{c} {[} -D_{int} C^{-1} D^T_{int} ]_{i+1,j+1}\end{array} \right ] \]

and

\[ fh\_{bnd} = \left [ \begin{array}{c} {\bf f}_{bnd} -B C^{-1} {\bf f}_{int}\\ {[}D_{int} C^{-1} {\bf f}_{int}]_0 \end{array}\right ] \hspace{1cm} [fh\_p_{i} = \left [ \begin{array}{c} {[}D_{int} C^{-1} {\bf f}_{iint}]_{i+1} \end{array}\right ] \]

Since the \(\hat{D}\) is decoupled and invertible we can now statically condense the previous matrix equationto decouple \({\bf b}\) from \(\hat{p}\) by solving the following system

\[ \left [ \begin{array}{cc} \hat{A} - \hat{B} \hat{D}^{-1} \hat{C} & 0 \\ \hat{C} & \hat{D} \end{array} \right ] \left [ \begin{array}{c} {\bf b} \\ \hat{p} \end{array} \right ] = \left [ \begin{array}{c} \hat{\bf f}_{bnd} - \hat{B} \hat{D}^{-1} \hat{f}_p\\ \hat{f}_p \end{array} \right ] \]

The matrix \(\hat{A} - \hat{B} \hat{D}^{-1} \hat{C}\) has to be globally assembled and solved iteratively or directly. One we obtain the solution to \({\bf b}\) we can use the second row of equation fourth matrix equation to solve for \(\hat{p}\) and finally the last row of equation second matrix equation to solve for \({\bf v}_{int}\).

Definition at line 400 of file CoupledLinearNS.cpp.

406 {
407  int n, i, j, k;
408  int nel = m_fields[m_velocity[0]]->GetNumElmts();
409  int nvel = m_velocity.size();
410 
411  // if Advfield is defined can assume it is an Oseen or LinearNS equation
412  bool AddAdvectionTerms =
413  (Advfield == NullNekDoubleArrayOfArray) ? false : true;
414  // bool AddAdvectionTerms = true; // Temporary debugging trip
415 
416  // call velocity space Static condensation and fill block
417  // matrices. Need to set this up differently for Oseen and
418  // Lin NS. Ideally should make block diagonal for Stokes and
419  // Oseen problems.
420  DNekScalMatSharedPtr loc_mat;
422  NekDouble one = 1.0;
423  int nint, nbndry;
424  int rows, cols;
425  NekDouble zero = 0.0;
426  Array<OneD, unsigned int> bmap, imap;
427 
428  Array<OneD, unsigned int> nsize_bndry(nel);
429  Array<OneD, unsigned int> nsize_bndry_p1(nel);
430  Array<OneD, unsigned int> nsize_int(nel);
431  Array<OneD, unsigned int> nsize_p(nel);
432  Array<OneD, unsigned int> nsize_p_m1(nel);
433 
434  int nz_loc;
435 
436  if (HomogeneousMode) // Homogeneous mode flag
437  {
438  nz_loc = 2;
439  }
440  else
441  {
442  if (m_singleMode)
443  {
444  nz_loc = 2;
445  }
446  else
447  {
448  nz_loc = 1;
449  }
450  }
451 
452  // Set up block matrix sizes -
453  for (n = 0; n < nel; ++n)
454  {
455  nsize_bndry[n] = nvel *
456  m_fields[m_velocity[0]]->GetExp(n)->NumBndryCoeffs() *
457  nz_loc;
458  nsize_bndry_p1[n] = nsize_bndry[n] + nz_loc;
459  nsize_int[n] =
460  (nvel * m_fields[m_velocity[0]]->GetExp(n)->GetNcoeffs() * nz_loc -
461  nsize_bndry[n]);
462  nsize_p[n] = m_pressure->GetExp(n)->GetNcoeffs() * nz_loc;
463  nsize_p_m1[n] = nsize_p[n] - nz_loc;
464  }
465 
466  MatrixStorage blkmatStorage = eDIAGONAL;
469  nsize_bndry_p1, nsize_bndry_p1, blkmatStorage);
471  nsize_bndry, nsize_int, blkmatStorage);
473  nsize_bndry, nsize_int, blkmatStorage);
475  nsize_int, nsize_int, blkmatStorage);
476 
478  nsize_p, nsize_bndry, blkmatStorage);
479 
481  nsize_p, nsize_int, blkmatStorage);
482 
483  // Final level static condensation matrices.
486  nsize_bndry_p1, nsize_p_m1, blkmatStorage);
489  nsize_p_m1, nsize_bndry_p1, blkmatStorage);
492  blkmatStorage);
493 
494  LibUtilities::Timer timer;
495  timer.Start();
496 
497  for (n = 0; n < nel; ++n)
498  {
499  nbndry = nsize_bndry[n];
500  nint = nsize_int[n];
501  k = nsize_bndry_p1[n];
502  DNekMatSharedPtr Ah =
504  Array<OneD, NekDouble> Ah_data = Ah->GetPtr();
505  int AhRows = k;
506  DNekMatSharedPtr B =
507  MemoryManager<DNekMat>::AllocateSharedPtr(nbndry, nint, zero);
508  Array<OneD, NekDouble> B_data = B->GetPtr();
509  DNekMatSharedPtr C =
510  MemoryManager<DNekMat>::AllocateSharedPtr(nbndry, nint, zero);
511  Array<OneD, NekDouble> C_data = C->GetPtr();
512  DNekMatSharedPtr D =
514  Array<OneD, NekDouble> D_data = D->GetPtr();
515 
517  nsize_p[n], nsize_bndry[n], zero);
519  nsize_p[n], nsize_int[n], zero);
520 
521  locExp = m_fields[m_velocity[0]]->GetExp(n);
522  locExp->GetBoundaryMap(bmap);
523  locExp->GetInteriorMap(imap);
525  factors[StdRegions::eFactorLambda] = lambda / m_kinvis;
526  LocalRegions::MatrixKey helmkey(
527  StdRegions::eHelmholtz, locExp->DetShapeType(), *locExp, factors);
528 
529  int ncoeffs = m_fields[m_velocity[0]]->GetExp(n)->GetNcoeffs();
530  int nphys = m_fields[m_velocity[0]]->GetExp(n)->GetTotPoints();
531  int nbmap = bmap.size();
532  int nimap = imap.size();
533 
534  Array<OneD, NekDouble> coeffs(ncoeffs);
535  Array<OneD, NekDouble> phys(nphys);
536  int psize = m_pressure->GetExp(n)->GetNcoeffs();
537  int pqsize = m_pressure->GetExp(n)->GetTotPoints();
538 
539  Array<OneD, NekDouble> deriv(pqsize);
540  Array<OneD, NekDouble> pcoeffs(psize);
541 
542  if (AddAdvectionTerms == false) // use static condensed managed matrices
543  {
544  // construct velocity matrices using statically
545  // condensed elemental matrices and then construct
546  // pressure matrix systems
547  DNekScalBlkMatSharedPtr CondMat;
548  CondMat = locExp->GetLocStaticCondMatrix(helmkey);
549 
550  for (k = 0; k < nvel * nz_loc; ++k)
551  {
552  DNekScalMat &SubBlock = *CondMat->GetBlock(0, 0);
553  rows = SubBlock.GetRows();
554  cols = SubBlock.GetColumns();
555  for (i = 0; i < rows; ++i)
556  {
557  for (j = 0; j < cols; ++j)
558  {
559  (*Ah)(i + k * rows, j + k * cols) =
560  m_kinvis * SubBlock(i, j);
561  }
562  }
563  }
564 
565  for (k = 0; k < nvel * nz_loc; ++k)
566  {
567  DNekScalMat &SubBlock = *CondMat->GetBlock(0, 1);
568  DNekScalMat &SubBlock1 = *CondMat->GetBlock(1, 0);
569  rows = SubBlock.GetRows();
570  cols = SubBlock.GetColumns();
571  for (i = 0; i < rows; ++i)
572  {
573  for (j = 0; j < cols; ++j)
574  {
575  (*B)(i + k * rows, j + k * cols) = SubBlock(i, j);
576  (*C)(i + k * rows, j + k * cols) =
577  m_kinvis * SubBlock1(j, i);
578  }
579  }
580  }
581 
582  for (k = 0; k < nvel * nz_loc; ++k)
583  {
584  DNekScalMat &SubBlock = *CondMat->GetBlock(1, 1);
585  NekDouble inv_kinvis = 1.0 / m_kinvis;
586  rows = SubBlock.GetRows();
587  cols = SubBlock.GetColumns();
588  for (i = 0; i < rows; ++i)
589  {
590  for (j = 0; j < cols; ++j)
591  {
592  (*D)(i + k * rows, j + k * cols) =
593  inv_kinvis * SubBlock(i, j);
594  }
595  }
596  }
597 
598  // Loop over pressure space and construct boundary block matrices.
599  for (i = 0; i < bmap.size(); ++i)
600  {
601  // Fill element with mode
602  Vmath::Zero(ncoeffs, coeffs, 1);
603  coeffs[bmap[i]] = 1.0;
604  m_fields[m_velocity[0]]->GetExp(n)->BwdTrans(coeffs, phys);
605 
606  // Differentiation & Inner product wrt base.
607  for (j = 0; j < nvel; ++j)
608  {
609  if ((nz_loc == 2) && (j == 2)) // handle d/dz derivative
610  {
611  NekDouble beta = -2 * M_PI * HomogeneousMode / m_LhomZ;
612 
613  Vmath::Smul(
614  m_fields[m_velocity[0]]->GetExp(n)->GetTotPoints(),
615  beta, phys, 1, deriv, 1);
616 
617  m_pressure->GetExp(n)->IProductWRTBase(deriv, pcoeffs);
618 
619  Blas::Dcopy(psize, &(pcoeffs)[0], 1,
620  Dbnd->GetRawPtr() +
621  ((nz_loc * j + 1) * bmap.size() + i) *
622  nsize_p[n],
623  1);
624 
625  Vmath::Neg(psize, pcoeffs, 1);
626  Blas::Dcopy(psize, &(pcoeffs)[0], 1,
627  Dbnd->GetRawPtr() +
628  ((nz_loc * j) * bmap.size() + i) *
629  nsize_p[n] +
630  psize,
631  1);
632  }
633  else
634  {
635  if (j < 2) // required for mean mode of homogeneous
636  // expansion
637  {
638  locExp->PhysDeriv(MultiRegions::DirCartesianMap[j],
639  phys, deriv);
640  m_pressure->GetExp(n)->IProductWRTBase(deriv,
641  pcoeffs);
642  // copy into column major storage.
643  for (k = 0; k < nz_loc; ++k)
644  {
645  Blas::Dcopy(
646  psize, &(pcoeffs)[0], 1,
647  Dbnd->GetRawPtr() +
648  ((nz_loc * j + k) * bmap.size() + i) *
649  nsize_p[n] +
650  k * psize,
651  1);
652  }
653  }
654  }
655  }
656  }
657 
658  for (i = 0; i < imap.size(); ++i)
659  {
660  // Fill element with mode
661  Vmath::Zero(ncoeffs, coeffs, 1);
662  coeffs[imap[i]] = 1.0;
663  m_fields[m_velocity[0]]->GetExp(n)->BwdTrans(coeffs, phys);
664 
665  // Differentiation & Inner product wrt base.
666  for (j = 0; j < nvel; ++j)
667  {
668  if ((nz_loc == 2) && (j == 2)) // handle d/dz derivative
669  {
670  NekDouble beta = -2 * M_PI * HomogeneousMode / m_LhomZ;
671 
672  Vmath::Smul(
673  m_fields[m_velocity[0]]->GetExp(n)->GetTotPoints(),
674  beta, phys, 1, deriv, 1);
675 
676  m_pressure->GetExp(n)->IProductWRTBase(deriv, pcoeffs);
677 
678  Blas::Dcopy(psize, &(pcoeffs)[0], 1,
679  Dint->GetRawPtr() +
680  ((nz_loc * j + 1) * imap.size() + i) *
681  nsize_p[n],
682  1);
683 
684  Vmath::Neg(psize, pcoeffs, 1);
685  Blas::Dcopy(psize, &(pcoeffs)[0], 1,
686  Dint->GetRawPtr() +
687  ((nz_loc * j) * imap.size() + i) *
688  nsize_p[n] +
689  psize,
690  1);
691  }
692  else
693  {
694  if (j < 2) // required for mean mode of homogeneous
695  // expansion
696  {
697  // m_fields[m_velocity[0]]->GetExp(n)->PhysDeriv(j,phys,
698  // deriv);
699  locExp->PhysDeriv(MultiRegions::DirCartesianMap[j],
700  phys, deriv);
701 
702  m_pressure->GetExp(n)->IProductWRTBase(deriv,
703  pcoeffs);
704 
705  // copy into column major storage.
706  for (k = 0; k < nz_loc; ++k)
707  {
708  Blas::Dcopy(
709  psize, &(pcoeffs)[0], 1,
710  Dint->GetRawPtr() +
711  ((nz_loc * j + k) * imap.size() + i) *
712  nsize_p[n] +
713  k * psize,
714  1);
715  }
716  }
717  }
718  }
719  }
720  }
721  else
722  {
723  // construct velocity matrices and pressure systems at
724  // the same time resusing differential of velocity
725  // space
726 
727  DNekScalMat &HelmMat =
728  *(locExp->as<LocalRegions::Expansion>()->GetLocMatrix(helmkey));
729  DNekScalMatSharedPtr MassMat;
730 
731  Array<OneD, const NekDouble> HelmMat_data =
732  HelmMat.GetOwnedMatrix()->GetPtr();
733  NekDouble HelmMatScale = HelmMat.Scale();
734  int HelmMatRows = HelmMat.GetRows();
735 
736  if ((lambda_imag != NekConstants::kNekUnsetDouble) && (nz_loc == 2))
737  {
738  LocalRegions::MatrixKey masskey(
739  StdRegions::eMass, locExp->DetShapeType(), *locExp);
740  MassMat = locExp->as<LocalRegions::Expansion>()->GetLocMatrix(
741  masskey);
742  }
743 
744  Array<OneD, NekDouble> Advtmp;
745  Array<OneD, Array<OneD, NekDouble>> AdvDeriv(nvel * nvel);
746  // Use ExpList phys array for temporaary storage
747  Array<OneD, NekDouble> tmpphys = m_fields[0]->UpdatePhys();
748  int phys_offset = m_fields[m_velocity[0]]->GetPhys_Offset(n);
749  int nv;
750  int npoints = locExp->GetTotPoints();
751 
752  // Calculate derivative of base flow
753  if (IsLinearNSEquation)
754  {
755  int nv1;
756  int cnt = 0;
757  AdvDeriv[0] = Array<OneD, NekDouble>(nvel * nvel * npoints);
758  for (nv = 0; nv < nvel; ++nv)
759  {
760  for (nv1 = 0; nv1 < nvel; ++nv1)
761  {
762  if (cnt < nvel * nvel - 1)
763  {
764  AdvDeriv[cnt + 1] = AdvDeriv[cnt] + npoints;
765  ++cnt;
766  }
767 
768  if ((nv1 == 2) && (m_HomogeneousType == eHomogeneous1D))
769  {
770  Vmath::Zero(npoints, AdvDeriv[nv * nvel + nv1],
771  1); // dU/dz = 0
772  }
773  else
774  {
775  locExp->PhysDeriv(
777  Advfield[nv] + phys_offset,
778  AdvDeriv[nv * nvel + nv1]);
779  }
780  }
781  }
782  }
783 
784  for (i = 0; i < nbmap; ++i)
785  {
786 
787  // Fill element with mode
788  Vmath::Zero(ncoeffs, coeffs, 1);
789  coeffs[bmap[i]] = 1.0;
790  locExp->BwdTrans(coeffs, phys);
791 
792  for (k = 0; k < nvel * nz_loc; ++k)
793  {
794  for (j = 0; j < nbmap; ++j)
795  {
796  // Ah_data[i+k*nbmap +
797  // (j+k*nbmap)*AhRows] +=
798  // m_kinvis*HelmMat(bmap[i],bmap[j]);
799  Ah_data[i + k * nbmap + (j + k * nbmap) * AhRows] +=
800  m_kinvis * HelmMatScale *
801  HelmMat_data[bmap[i] + HelmMatRows * bmap[j]];
802  }
803 
804  for (j = 0; j < nimap; ++j)
805  {
806  B_data[i + k * nbmap + (j + k * nimap) * nbndry] +=
807  m_kinvis * HelmMatScale *
808  HelmMat_data[bmap[i] + HelmMatRows * imap[j]];
809  }
810  }
811 
812  if ((lambda_imag != NekConstants::kNekUnsetDouble) &&
813  (nz_loc == 2))
814  {
815  for (k = 0; k < nvel; ++k)
816  {
817  for (j = 0; j < nbmap; ++j)
818  {
819  Ah_data[i + 2 * k * nbmap +
820  (j + (2 * k + 1) * nbmap) * AhRows] -=
821  lambda_imag * (*MassMat)(bmap[i], bmap[j]);
822  }
823 
824  for (j = 0; j < nbmap; ++j)
825  {
826  Ah_data[i + (2 * k + 1) * nbmap +
827  (j + 2 * k * nbmap) * AhRows] +=
828  lambda_imag * (*MassMat)(bmap[i], bmap[j]);
829  }
830 
831  for (j = 0; j < nimap; ++j)
832  {
833  B_data[i + 2 * k * nbmap +
834  (j + (2 * k + 1) * nimap) * nbndry] -=
835  lambda_imag * (*MassMat)(bmap[i], imap[j]);
836  }
837 
838  for (j = 0; j < nimap; ++j)
839  {
840  B_data[i + (2 * k + 1) * nbmap +
841  (j + 2 * k * nimap) * nbndry] +=
842  lambda_imag * (*MassMat)(bmap[i], imap[j]);
843  }
844  }
845  }
846 
847  for (k = 0; k < nvel; ++k)
848  {
849  if ((nz_loc == 2) && (k == 2)) // handle d/dz derivative
850  {
851  NekDouble beta = -2 * M_PI * HomogeneousMode / m_LhomZ;
852 
853  // Real Component
854  Vmath::Smul(npoints, beta, phys, 1, deriv, 1);
855 
856  m_pressure->GetExp(n)->IProductWRTBase(deriv, pcoeffs);
857  Blas::Dcopy(psize, &(pcoeffs)[0], 1,
858  Dbnd->GetRawPtr() +
859  ((nz_loc * k + 1) * bmap.size() + i) *
860  nsize_p[n],
861  1);
862 
863  // Imaginary Component
864  Vmath::Neg(psize, pcoeffs, 1);
865  Blas::Dcopy(psize, &(pcoeffs)[0], 1,
866  Dbnd->GetRawPtr() +
867  ((nz_loc * k) * bmap.size() + i) *
868  nsize_p[n] +
869  psize,
870  1);
871 
872  // now do advection terms
873  Vmath::Vmul(npoints, Advtmp = Advfield[k] + phys_offset,
874  1, deriv, 1, tmpphys, 1);
875 
876  locExp->IProductWRTBase(tmpphys, coeffs);
877 
878  // real contribution
879  for (nv = 0; nv < nvel; ++nv)
880  {
881  for (j = 0; j < nbmap; ++j)
882  {
883  Ah_data[j + 2 * nv * nbmap +
884  (i + (2 * nv + 1) * nbmap) * AhRows] +=
885  coeffs[bmap[j]];
886  }
887 
888  for (j = 0; j < nimap; ++j)
889  {
890  C_data[i + (2 * nv + 1) * nbmap +
891  (j + 2 * nv * nimap) * nbndry] +=
892  coeffs[imap[j]];
893  }
894  }
895 
896  Vmath::Neg(ncoeffs, coeffs, 1);
897  // imaginary contribution
898  for (nv = 0; nv < nvel; ++nv)
899  {
900  for (j = 0; j < nbmap; ++j)
901  {
902  Ah_data[j + (2 * nv + 1) * nbmap +
903  (i + 2 * nv * nbmap) * AhRows] +=
904  coeffs[bmap[j]];
905  }
906 
907  for (j = 0; j < nimap; ++j)
908  {
909  C_data[i + 2 * nv * nbmap +
910  (j + (2 * nv + 1) * nimap) * nbndry] +=
911  coeffs[imap[j]];
912  }
913  }
914  }
915  else
916  {
917  if (k < 2)
918  {
919  locExp->PhysDeriv(MultiRegions::DirCartesianMap[k],
920  phys, deriv);
921  Vmath::Vmul(npoints,
922  Advtmp = Advfield[k] + phys_offset, 1,
923  deriv, 1, tmpphys, 1);
924  locExp->IProductWRTBase(tmpphys, coeffs);
925 
926  for (nv = 0; nv < nvel * nz_loc; ++nv)
927  {
928  for (j = 0; j < nbmap; ++j)
929  {
930  Ah_data[j + nv * nbmap +
931  (i + nv * nbmap) * AhRows] +=
932  coeffs[bmap[j]];
933  }
934 
935  for (j = 0; j < nimap; ++j)
936  {
937  C_data[i + nv * nbmap +
938  (j + nv * nimap) * nbndry] +=
939  coeffs[imap[j]];
940  }
941  }
942 
943  // copy into column major storage.
944  m_pressure->GetExp(n)->IProductWRTBase(deriv,
945  pcoeffs);
946  for (j = 0; j < nz_loc; ++j)
947  {
948  Blas::Dcopy(
949  psize, &(pcoeffs)[0], 1,
950  Dbnd->GetRawPtr() +
951  ((nz_loc * k + j) * bmap.size() + i) *
952  nsize_p[n] +
953  j * psize,
954  1);
955  }
956  }
957  }
958 
959  if (IsLinearNSEquation)
960  {
961  for (nv = 0; nv < nvel; ++nv)
962  {
963  // u' . Grad U terms
964  Vmath::Vmul(npoints, phys, 1,
965  AdvDeriv[k * nvel + nv], 1, tmpphys, 1);
966  locExp->IProductWRTBase(tmpphys, coeffs);
967 
968  for (int n1 = 0; n1 < nz_loc; ++n1)
969  {
970  for (j = 0; j < nbmap; ++j)
971  {
972  Ah_data[j + (k * nz_loc + n1) * nbmap +
973  (i + (nv * nz_loc + n1) * nbmap) *
974  AhRows] += coeffs[bmap[j]];
975  }
976 
977  for (j = 0; j < nimap; ++j)
978  {
979  C_data[i + (nv * nz_loc + n1) * nbmap +
980  (j + (k * nz_loc + n1) * nimap) *
981  nbndry] += coeffs[imap[j]];
982  }
983  }
984  }
985  }
986  }
987  }
988 
989  for (i = 0; i < nimap; ++i)
990  {
991  // Fill element with mode
992  Vmath::Zero(ncoeffs, coeffs, 1);
993  coeffs[imap[i]] = 1.0;
994  locExp->BwdTrans(coeffs, phys);
995 
996  for (k = 0; k < nvel * nz_loc; ++k)
997  {
998  for (j = 0; j < nbmap; ++j) // C set up as transpose
999  {
1000  C_data[j + k * nbmap + (i + k * nimap) * nbndry] +=
1001  m_kinvis * HelmMatScale *
1002  HelmMat_data[imap[i] + HelmMatRows * bmap[j]];
1003  }
1004 
1005  for (j = 0; j < nimap; ++j)
1006  {
1007  D_data[i + k * nimap + (j + k * nimap) * nint] +=
1008  m_kinvis * HelmMatScale *
1009  HelmMat_data[imap[i] + HelmMatRows * imap[j]];
1010  }
1011  }
1012 
1013  if ((lambda_imag != NekConstants::kNekUnsetDouble) &&
1014  (nz_loc == 2))
1015  {
1016  for (k = 0; k < nvel; ++k)
1017  {
1018  for (j = 0; j < nbmap; ++j) // C set up as transpose
1019  {
1020  C_data[j + 2 * k * nbmap +
1021  (i + (2 * k + 1) * nimap) * nbndry] +=
1022  lambda_imag * (*MassMat)(bmap[j], imap[i]);
1023  }
1024 
1025  for (j = 0; j < nbmap; ++j) // C set up as transpose
1026  {
1027  C_data[j + (2 * k + 1) * nbmap +
1028  (i + 2 * k * nimap) * nbndry] -=
1029  lambda_imag * (*MassMat)(bmap[j], imap[i]);
1030  }
1031 
1032  for (j = 0; j < nimap; ++j)
1033  {
1034  D_data[i + 2 * k * nimap +
1035  (j + (2 * k + 1) * nimap) * nint] -=
1036  lambda_imag * (*MassMat)(imap[i], imap[j]);
1037  }
1038 
1039  for (j = 0; j < nimap; ++j)
1040  {
1041  D_data[i + (2 * k + 1) * nimap +
1042  (j + 2 * k * nimap) * nint] +=
1043  lambda_imag * (*MassMat)(imap[i], imap[j]);
1044  }
1045  }
1046  }
1047 
1048  for (k = 0; k < nvel; ++k)
1049  {
1050  if ((nz_loc == 2) && (k == 2)) // handle d/dz derivative
1051  {
1052  NekDouble beta = -2 * M_PI * HomogeneousMode / m_LhomZ;
1053 
1054  // Real Component
1055  Vmath::Smul(npoints, beta, phys, 1, deriv, 1);
1056  m_pressure->GetExp(n)->IProductWRTBase(deriv, pcoeffs);
1057  Blas::Dcopy(psize, &(pcoeffs)[0], 1,
1058  Dint->GetRawPtr() +
1059  ((nz_loc * k + 1) * imap.size() + i) *
1060  nsize_p[n],
1061  1);
1062  // Imaginary Component
1063  Vmath::Neg(psize, pcoeffs, 1);
1064  Blas::Dcopy(psize, &(pcoeffs)[0], 1,
1065  Dint->GetRawPtr() +
1066  ((nz_loc * k) * imap.size() + i) *
1067  nsize_p[n] +
1068  psize,
1069  1);
1070 
1071  // Advfield[k] *d/dx_k to all velocity
1072  // components on diagonal
1073  Vmath::Vmul(npoints, Advtmp = Advfield[k] + phys_offset,
1074  1, deriv, 1, tmpphys, 1);
1075  locExp->IProductWRTBase(tmpphys, coeffs);
1076 
1077  // Real Components
1078  for (nv = 0; nv < nvel; ++nv)
1079  {
1080  for (j = 0; j < nbmap; ++j)
1081  {
1082  B_data[j + 2 * nv * nbmap +
1083  (i + (2 * nv + 1) * nimap) * nbndry] +=
1084  coeffs[bmap[j]];
1085  }
1086 
1087  for (j = 0; j < nimap; ++j)
1088  {
1089  D_data[j + 2 * nv * nimap +
1090  (i + (2 * nv + 1) * nimap) * nint] +=
1091  coeffs[imap[j]];
1092  }
1093  }
1094  Vmath::Neg(ncoeffs, coeffs, 1);
1095  // Imaginary
1096  for (nv = 0; nv < nvel; ++nv)
1097  {
1098  for (j = 0; j < nbmap; ++j)
1099  {
1100  B_data[j + (2 * nv + 1) * nbmap +
1101  (i + 2 * nv * nimap) * nbndry] +=
1102  coeffs[bmap[j]];
1103  }
1104 
1105  for (j = 0; j < nimap; ++j)
1106  {
1107  D_data[j + (2 * nv + 1) * nimap +
1108  (i + 2 * nv * nimap) * nint] +=
1109  coeffs[imap[j]];
1110  }
1111  }
1112  }
1113  else
1114  {
1115  if (k < 2)
1116  {
1117  // Differentiation & Inner product wrt base.
1118  // locExp->PhysDeriv(k,phys, deriv);
1119  locExp->PhysDeriv(MultiRegions::DirCartesianMap[k],
1120  phys, deriv);
1121  Vmath::Vmul(npoints,
1122  Advtmp = Advfield[k] + phys_offset, 1,
1123  deriv, 1, tmpphys, 1);
1124  locExp->IProductWRTBase(tmpphys, coeffs);
1125 
1126  for (nv = 0; nv < nvel * nz_loc; ++nv)
1127  {
1128  for (j = 0; j < nbmap; ++j)
1129  {
1130  B_data[j + nv * nbmap +
1131  (i + nv * nimap) * nbndry] +=
1132  coeffs[bmap[j]];
1133  }
1134 
1135  for (j = 0; j < nimap; ++j)
1136  {
1137  D_data[j + nv * nimap +
1138  (i + nv * nimap) * nint] +=
1139  coeffs[imap[j]];
1140  }
1141  }
1142  // copy into column major storage.
1143  m_pressure->GetExp(n)->IProductWRTBase(deriv,
1144  pcoeffs);
1145  for (j = 0; j < nz_loc; ++j)
1146  {
1147  Blas::Dcopy(
1148  psize, &(pcoeffs)[0], 1,
1149  Dint->GetRawPtr() +
1150  ((nz_loc * k + j) * imap.size() + i) *
1151  nsize_p[n] +
1152  j * psize,
1153  1);
1154  }
1155  }
1156  }
1157 
1158  if (IsLinearNSEquation)
1159  {
1160  int n1;
1161  for (nv = 0; nv < nvel; ++nv)
1162  {
1163  // u'.Grad U terms
1164  Vmath::Vmul(npoints, phys, 1,
1165  AdvDeriv[k * nvel + nv], 1, tmpphys, 1);
1166  locExp->IProductWRTBase(tmpphys, coeffs);
1167 
1168  for (n1 = 0; n1 < nz_loc; ++n1)
1169  {
1170  for (j = 0; j < nbmap; ++j)
1171  {
1172  B_data[j + (k * nz_loc + n1) * nbmap +
1173  (i + (nv * nz_loc + n1) * nimap) *
1174  nbndry] += coeffs[bmap[j]];
1175  }
1176 
1177  for (j = 0; j < nimap; ++j)
1178  {
1179  D_data[j + (k * nz_loc + n1) * nimap +
1180  (i + (nv * nz_loc + n1) * nimap) *
1181  nint] += coeffs[imap[j]];
1182  }
1183  }
1184  }
1185  }
1186  }
1187  }
1188 
1189  D->Invert();
1190  (*B) = (*B) * (*D);
1191 
1192  // perform (*Ah) = (*Ah) - (*B)*(*C) but since size of
1193  // Ah is larger than (*B)*(*C) easier to call blas
1194  // directly
1195  Blas::Dgemm('N', 'T', B->GetRows(), C->GetRows(), B->GetColumns(),
1196  -1.0, B->GetRawPtr(), B->GetRows(), C->GetRawPtr(),
1197  C->GetRows(), 1.0, Ah->GetRawPtr(), Ah->GetRows());
1198  }
1199 
1200  mat.m_BCinv->SetBlock(
1201  n, n,
1203  mat.m_Btilde->SetBlock(
1204  n, n,
1206  mat.m_Cinv->SetBlock(
1207  n, n,
1209  mat.m_D_bnd->SetBlock(
1210  n, n,
1211  loc_mat = MemoryManager<DNekScalMat>::AllocateSharedPtr(one, Dbnd));
1212  mat.m_D_int->SetBlock(
1213  n, n,
1214  loc_mat = MemoryManager<DNekScalMat>::AllocateSharedPtr(one, Dint));
1215 
1216  // Do matrix manipulations and get final set of block matries
1217  // reset boundary to put mean mode into boundary system.
1218 
1219  DNekMatSharedPtr Cinv, BCinv, Btilde;
1220  DNekMat DintCinvDTint, BCinvDTint_m_DTbnd, DintCinvBTtilde_m_Dbnd;
1221 
1222  Cinv = D;
1223  BCinv = B;
1224  Btilde = C;
1225 
1226  DintCinvDTint = (*Dint) * (*Cinv) * Transpose(*Dint);
1227  BCinvDTint_m_DTbnd = (*BCinv) * Transpose(*Dint) - Transpose(*Dbnd);
1228 
1229  // This could be transpose of BCinvDint in some cases
1230  DintCinvBTtilde_m_Dbnd =
1231  (*Dint) * (*Cinv) * Transpose(*Btilde) - (*Dbnd);
1232 
1233  // Set up final set of matrices.
1235  nsize_bndry_p1[n], nsize_p_m1[n], zero);
1237  nsize_p_m1[n], nsize_bndry_p1[n], zero);
1239  nsize_p_m1[n], nsize_p_m1[n], zero);
1240  Array<OneD, NekDouble> Dh_data = Dh->GetPtr();
1241 
1242  // Copy matrices into final structures.
1243  int n1, n2;
1244  for (n1 = 0; n1 < nz_loc; ++n1)
1245  {
1246  for (i = 0; i < psize - 1; ++i)
1247  {
1248  for (n2 = 0; n2 < nz_loc; ++n2)
1249  {
1250  for (j = 0; j < psize - 1; ++j)
1251  {
1252  //(*Dh)(i+n1*(psize-1),j+n2*(psize-1)) =
1253  //-DintCinvDTint(i+1+n1*psize,j+1+n2*psize);
1254  Dh_data[(i + n1 * (psize - 1)) +
1255  (j + n2 * (psize - 1)) * Dh->GetRows()] =
1256  -DintCinvDTint(i + 1 + n1 * psize,
1257  j + 1 + n2 * psize);
1258  }
1259  }
1260  }
1261  }
1262 
1263  for (n1 = 0; n1 < nz_loc; ++n1)
1264  {
1265  for (i = 0; i < nsize_bndry_p1[n] - nz_loc; ++i)
1266  {
1267  (*Ah)(i, nsize_bndry_p1[n] - nz_loc + n1) =
1268  BCinvDTint_m_DTbnd(i, n1 * psize);
1269  (*Ah)(nsize_bndry_p1[n] - nz_loc + n1, i) =
1270  DintCinvBTtilde_m_Dbnd(n1 * psize, i);
1271  }
1272  }
1273 
1274  for (n1 = 0; n1 < nz_loc; ++n1)
1275  {
1276  for (n2 = 0; n2 < nz_loc; ++n2)
1277  {
1278  (*Ah)(nsize_bndry_p1[n] - nz_loc + n1,
1279  nsize_bndry_p1[n] - nz_loc + n2) =
1280  -DintCinvDTint(n1 * psize, n2 * psize);
1281  }
1282  }
1283 
1284  for (n1 = 0; n1 < nz_loc; ++n1)
1285  {
1286  for (j = 0; j < psize - 1; ++j)
1287  {
1288  for (i = 0; i < nsize_bndry_p1[n] - nz_loc; ++i)
1289  {
1290  (*Bh)(i, j + n1 * (psize - 1)) =
1291  BCinvDTint_m_DTbnd(i, j + 1 + n1 * psize);
1292  (*Ch)(j + n1 * (psize - 1), i) =
1293  DintCinvBTtilde_m_Dbnd(j + 1 + n1 * psize, i);
1294  }
1295  }
1296  }
1297 
1298  for (n1 = 0; n1 < nz_loc; ++n1)
1299  {
1300  for (n2 = 0; n2 < nz_loc; ++n2)
1301  {
1302  for (j = 0; j < psize - 1; ++j)
1303  {
1304  (*Bh)(nsize_bndry_p1[n] - nz_loc + n1,
1305  j + n2 * (psize - 1)) =
1306  -DintCinvDTint(n1 * psize, j + 1 + n2 * psize);
1307  (*Ch)(j + n2 * (psize - 1),
1308  nsize_bndry_p1[n] - nz_loc + n1) =
1309  -DintCinvDTint(j + 1 + n2 * psize, n1 * psize);
1310  }
1311  }
1312  }
1313 
1314  // Do static condensation
1315  Dh->Invert();
1316  (*Bh) = (*Bh) * (*Dh);
1317  //(*Ah) = (*Ah) - (*Bh)*(*Ch);
1318  Blas::Dgemm('N', 'N', Bh->GetRows(), Ch->GetColumns(), Bh->GetColumns(),
1319  -1.0, Bh->GetRawPtr(), Bh->GetRows(), Ch->GetRawPtr(),
1320  Ch->GetRows(), 1.0, Ah->GetRawPtr(), Ah->GetRows());
1321 
1322  // Set matrices for later inversion. Probably do not need to be
1323  // attached to class
1324  pAh->SetBlock(
1325  n, n,
1327  pBh->SetBlock(
1328  n, n,
1330  pCh->SetBlock(
1331  n, n,
1333  pDh->SetBlock(
1334  n, n,
1336  }
1337  timer.Stop();
1338  cout << "Matrix Setup Costs: " << timer.TimePerTest(1) << endl;
1339 
1340  timer.Start();
1341  // Set up global coupled boundary solver.
1342  // This is a key to define the solution matrix type
1343  // currently we are giving it a argument of eLInearAdvectionReaction
1344  // since this then makes the matrix storage of type eFull
1345  MultiRegions::GlobalLinSysKey key(StdRegions::eLinearAdvectionReaction,
1346  locToGloMap);
1347  mat.m_CoupledBndSys =
1349  AllocateSharedPtr(key, m_fields[0], pAh, pBh, pCh, pDh,
1350  locToGloMap);
1351  mat.m_CoupledBndSys->Initialise(locToGloMap);
1352 }
MultiRegions::ExpListSharedPtr m_pressure
Pointer to field holding pressure field.
bool m_singleMode
Flag to determine if single homogeneous mode is used.
enum HomogeneousType m_HomogeneousType
NekDouble m_LhomZ
physical length in Z direction (if homogeneous)
static void Dcopy(const int &n, const double *x, const int &incx, double *y, const int &incy)
BLAS level 1: Copy x to y.
Definition: Blas.hpp:147
static void Dgemm(const char &transa, const char &transb, const int &m, const int &n, const int &k, const double &alpha, const double *a, const int &lda, const double *b, const int &ldb, const double &beta, double *c, const int &ldc)
BLAS level 3: Matrix-matrix multiply C = A x B where op(A)[m x k], op(B)[k x n], C[m x n] DGEMM perfo...
Definition: Blas.hpp:368
@ beta
Gauss Radau pinned at x=-1,.
Definition: PointsType.h:61
MultiRegions::Direction const DirCartesianMap[]
Definition: ExpList.h:89
static const NekDouble kNekUnsetDouble
std::shared_ptr< StdExpansion > StdExpansionSharedPtr
std::map< ConstFactorType, NekDouble > ConstFactorMap
Definition: StdRegions.hpp:282
NekMatrix< NekMatrix< NekDouble, StandardMatrixTag >, ScaledMatrixTag > DNekScalMat
std::shared_ptr< DNekScalMat > DNekScalMatSharedPtr
NekMatrix< NekDouble, StandardMatrixTag > DNekMat
Definition: NekTypeDefs.hpp:50
NekMatrix< InnerMatrixType, BlockMatrixTag > Transpose(NekMatrix< InnerMatrixType, BlockMatrixTag > &rhs)
static Array< OneD, Array< OneD, NekDouble > > NullNekDoubleArrayOfArray
std::shared_ptr< DNekScalBlkMat > DNekScalBlkMatSharedPtr
Definition: NekTypeDefs.hpp:79
std::shared_ptr< DNekMat > DNekMatSharedPtr
Definition: NekTypeDefs.hpp:75
double NekDouble
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.cpp:209
void Neg(int n, T *x, const int incx)
Negate x = -x.
Definition: Vmath.cpp:518
void Zero(int n, T *x, const int incx)
Zero vector.
Definition: Vmath.cpp:492

References Nektar::MemoryManager< DataType >::AllocateSharedPtr(), Nektar::LibUtilities::beta, Blas::Dcopy(), Blas::Dgemm(), Nektar::MultiRegions::DirCartesianMap, Nektar::eDIAGONAL, Nektar::StdRegions::eFactorLambda, Nektar::StdRegions::eHelmholtz, Nektar::SolverUtils::EquationSystem::eHomogeneous1D, Nektar::StdRegions::eLinearAdvectionReaction, Nektar::StdRegions::eMass, Nektar::SolverUtils::EquationSystem::GetTotPoints(), Nektar::NekConstants::kNekUnsetDouble, Nektar::coupledSolverMatrices::m_BCinv, Nektar::coupledSolverMatrices::m_Btilde, Nektar::coupledSolverMatrices::m_Cinv, Nektar::coupledSolverMatrices::m_CoupledBndSys, Nektar::coupledSolverMatrices::m_D_bnd, Nektar::coupledSolverMatrices::m_D_int, Nektar::SolverUtils::EquationSystem::m_fields, Nektar::SolverUtils::EquationSystem::m_HomogeneousType, Nektar::IncNavierStokes::m_kinvis, Nektar::SolverUtils::EquationSystem::m_LhomZ, Nektar::IncNavierStokes::m_pressure, Nektar::SolverUtils::EquationSystem::m_singleMode, Nektar::IncNavierStokes::m_velocity, Vmath::Neg(), Nektar::NullNekDoubleArrayOfArray, Vmath::Smul(), Nektar::LibUtilities::Timer::Start(), Nektar::LibUtilities::Timer::Stop(), Nektar::LibUtilities::Timer::TimePerTest(), Nektar::Transpose(), Vmath::Vmul(), and Vmath::Zero().

◆ SetUpCoupledMatrix() [2/2]

void Nektar::CoupledLinearNS::SetUpCoupledMatrix ( const NekDouble  lambda = 0.0,
const Array< OneD, Array< OneD, NekDouble >> &  Advfield = NullNekDoubleArrayOfArray,
bool  IsLinearNSEquation = true 
)

Generate the linearised Navier Stokes solver based on the static condensation of the interior velocity space and pressure modes.

Set up a coupled linearised Naviers-Stokes solve. Primarily a wrapper fuction around the full mode by mode version of SetUpCoupledMatrix.

Definition at line 198 of file CoupledLinearNS.cpp.

201 {
202 
203  int nz;
204  if (m_singleMode)
205  {
206 
207  NekDouble lambda_imag;
208 
209  // load imaginary component of any potential shift
210  // Probably should be called from DriverArpack but not yet
211  // clear how to do this
212  m_session->LoadParameter("imagShift", lambda_imag,
214  nz = 1;
215  m_mat = Array<OneD, CoupledSolverMatrices>(nz);
216 
217  ASSERTL1(m_npointsZ <= 2, "Only expected a maxmimum of two planes in "
218  "single mode linear NS solver");
219 
220  if (m_zeroMode)
221  {
222  SetUpCoupledMatrix(lambda, Advfield, IsLinearNSEquation, 0,
223  m_mat[0], m_locToGloMap[0], lambda_imag);
224  }
225  else
226  {
227  NekDouble beta = 2 * M_PI / m_LhomZ;
228  NekDouble lam = lambda + m_kinvis * beta * beta;
229 
230  SetUpCoupledMatrix(lam, Advfield, IsLinearNSEquation, 1, m_mat[0],
231  m_locToGloMap[0], lambda_imag);
232  }
233  }
234  else
235  {
236  int n;
237  if (m_npointsZ > 1)
238  {
239  nz = m_npointsZ / 2;
240  }
241  else
242  {
243  nz = 1;
244  }
245 
246  m_mat = Array<OneD, CoupledSolverMatrices>(nz);
247 
248  // mean mode or 2D mode.
249  SetUpCoupledMatrix(lambda, Advfield, IsLinearNSEquation, 0, m_mat[0],
250  m_locToGloMap[0]);
251 
252  for (n = 1; n < nz; ++n)
253  {
254  NekDouble beta = 2 * M_PI * n / m_LhomZ;
255 
256  NekDouble lam = lambda + m_kinvis * beta * beta;
257 
258  SetUpCoupledMatrix(lam, Advfield, IsLinearNSEquation, n, m_mat[n],
259  m_locToGloMap[n]);
260  }
261  }
262 }
#define ASSERTL1(condition, msg)
Assert Level 1 – Debugging which is used whether in FULLDEBUG or DEBUG compilation mode....
Definition: ErrorUtil.hpp:249
Array< OneD, CoupledLocalToGlobalC0ContMapSharedPtr > m_locToGloMap
Array< OneD, CoupledSolverMatrices > m_mat
int m_npointsZ
number of points in Z direction (if homogeneous)

References ASSERTL1, Nektar::LibUtilities::beta, Nektar::NekConstants::kNekUnsetDouble, Nektar::IncNavierStokes::m_kinvis, Nektar::SolverUtils::EquationSystem::m_LhomZ, m_locToGloMap, m_mat, Nektar::SolverUtils::EquationSystem::m_npointsZ, Nektar::SolverUtils::EquationSystem::m_session, Nektar::SolverUtils::EquationSystem::m_singleMode, and m_zeroMode.

Referenced by Continuation(), SolveSteadyNavierStokes(), SolveUnsteadyStokesSystem(), and v_DoInitialise().

◆ Solve()

void Nektar::CoupledLinearNS::Solve ( void  )

Definition at line 1665 of file CoupledLinearNS.cpp.

1666 {
1667  const unsigned int ncmpt = m_velocity.size();
1668  Array<OneD, Array<OneD, NekDouble>> forcing_phys(ncmpt);
1669  Array<OneD, Array<OneD, NekDouble>> forcing(ncmpt);
1670 
1671  for (int i = 0; i < ncmpt; ++i)
1672  {
1673  forcing_phys[i] =
1674  Array<OneD, NekDouble>(m_fields[m_velocity[0]]->GetNpoints(), 0.0);
1675  forcing[i] =
1676  Array<OneD, NekDouble>(m_fields[m_velocity[0]]->GetNcoeffs(), 0.0);
1677  }
1678 
1679  for (auto &x : m_forcing)
1680  {
1681  const NekDouble time = 0;
1682  x->Apply(m_fields, forcing_phys, forcing_phys, time);
1683  }
1684  for (unsigned int i = 0; i < ncmpt; ++i)
1685  {
1686  bool waveSpace = m_fields[m_velocity[i]]->GetWaveSpace();
1687  m_fields[i]->SetWaveSpace(true);
1688  m_fields[i]->IProductWRTBase(forcing_phys[i], forcing[i]);
1689  m_fields[i]->SetWaveSpace(waveSpace);
1690  }
1691 
1692  SolveLinearNS(forcing);
1693 }
SOLVER_UTILS_EXPORT int GetNpoints()

References Nektar::SolverUtils::EquationSystem::GetNcoeffs(), Nektar::SolverUtils::EquationSystem::GetNpoints(), Nektar::SolverUtils::EquationSystem::m_fields, Nektar::IncNavierStokes::m_forcing, Nektar::IncNavierStokes::m_velocity, and SolveLinearNS().

Referenced by v_DoInitialise(), and v_DoSolve().

◆ SolveLinearNS() [1/2]

void Nektar::CoupledLinearNS::SolveLinearNS ( Array< OneD, Array< OneD, NekDouble >> &  forcing,
Array< OneD, MultiRegions::ExpListSharedPtr > &  fields,
MultiRegions::ExpListSharedPtr pressure,
const int  HomogeneousMode = 0 
)

Definition at line 2128 of file CoupledLinearNS.cpp.

2132 {
2133  int i, j, k, n, cnt, cnt1;
2134  int nbnd, nint, offset;
2135  int nvel = m_velocity.size();
2136  int nel = fields[0]->GetNumElmts();
2137  Array<OneD, unsigned int> bmap, imap;
2138 
2139  Array<OneD, NekDouble> f_bnd(m_mat[mode].m_BCinv->GetRows());
2140  NekVector<NekDouble> F_bnd(f_bnd.size(), f_bnd, eWrapper);
2141  Array<OneD, NekDouble> f_int(m_mat[mode].m_BCinv->GetColumns());
2142  NekVector<NekDouble> F_int(f_int.size(), f_int, eWrapper);
2143 
2144  int nz_loc;
2145  int nplanecoeffs =
2146  fields[m_velocity[0]]
2147  ->GetNcoeffs(); // this is fine since we pass the nplane coeff data.
2148 
2149  if (mode) // Homogeneous mode flag
2150  {
2151  nz_loc = 2;
2152  }
2153  else
2154  {
2155  if (m_singleMode)
2156  {
2157  nz_loc = 2;
2158  }
2159  else
2160  {
2161  nz_loc = 1;
2163  {
2164  Array<OneD, NekDouble> tmp;
2165  // Zero fields to set complex mode to zero;
2166  for (i = 0; i < fields.size(); ++i)
2167  {
2168  Vmath::Zero(nplanecoeffs,
2169  tmp = fields[i]->UpdateCoeffs() + nplanecoeffs,
2170  1);
2171  }
2172  Vmath::Zero(2 * pressure->GetNcoeffs(),
2173  pressure->UpdateCoeffs(), 1);
2174  }
2175  }
2176  }
2177 
2178  for (k = 0; k < nvel; ++k)
2179  {
2181  std::dynamic_pointer_cast<MultiRegions::ContField>(fields[k]);
2182 
2183  Array<OneD, NekDouble> sign =
2184  cfield->GetLocalToGlobalMap()->GetBndCondCoeffsToLocalCoeffsSign();
2185  const Array<OneD, const int> map =
2186  cfield->GetLocalToGlobalMap()->GetBndCondCoeffsToLocalCoeffsMap();
2187 
2188  // Add weak boundary conditions to forcing
2189  const Array<OneD, SpatialDomains::BoundaryConditionShPtr> bndConds =
2190  fields[k]->GetBndConditions();
2191  Array<OneD, const MultiRegions::ExpListSharedPtr> bndCondExp;
2192 
2194  {
2195  bndCondExp =
2196  m_fields[k]->GetPlane(2 * mode)->GetBndCondExpansions();
2197  }
2198  else
2199  {
2200  bndCondExp = m_fields[k]->GetBndCondExpansions();
2201  }
2202 
2203  for (n = 0; n < nz_loc; ++n)
2204  {
2205  int bndcnt = 0;
2206  for (i = 0; i < bndCondExp.size(); ++i)
2207  {
2208  const Array<OneD, const NekDouble> bndcoeffs =
2209  bndCondExp[i]->GetCoeffs();
2210 
2211  cnt = 0;
2212  if (bndConds[i]->GetBoundaryConditionType() ==
2214  bndConds[i]->GetBoundaryConditionType() ==
2216  {
2217  if (m_locToGloMap[mode]->GetSignChange())
2218  {
2219  for (j = 0; j < (bndCondExp[i])->GetNcoeffs(); j++)
2220  {
2221  forcing[k][n * nplanecoeffs + map[bndcnt + j]] +=
2222  sign[bndcnt + j] * bndcoeffs[j];
2223  }
2224  }
2225  else
2226  {
2227  for (j = 0; j < (bndCondExp[i])->GetNcoeffs(); j++)
2228  {
2229  forcing[k][n * nplanecoeffs + map[bndcnt + j]] +=
2230  bndcoeffs[j];
2231  }
2232  }
2233  }
2234 
2235  bndcnt += bndCondExp[i]->GetNcoeffs();
2236  }
2237  }
2238  }
2239 
2240  Array<OneD, NekDouble> bnd(m_locToGloMap[mode]->GetNumLocalCoeffs(), 0.0);
2241 
2242  // Construct f_bnd and f_int and fill in bnd from inarray
2243  // (with Dirichlet BCs imposed)
2244  int bndoffset = 0;
2245  cnt = cnt1 = 0;
2246  for (i = 0; i < nel; ++i) // loop over elements
2247  {
2248  fields[m_velocity[0]]->GetExp(i)->GetBoundaryMap(bmap);
2249  fields[m_velocity[0]]->GetExp(i)->GetInteriorMap(imap);
2250  nbnd = bmap.size();
2251  nint = imap.size();
2252  offset = fields[m_velocity[0]]->GetCoeff_Offset(i);
2253 
2254  for (j = 0; j < nvel; ++j) // loop over velocity fields
2255  {
2256  Array<OneD, NekDouble> incoeffs = fields[j]->UpdateCoeffs();
2257 
2258  for (n = 0; n < nz_loc; ++n)
2259  {
2260  for (k = 0; k < nbnd; ++k)
2261  {
2262  f_bnd[cnt + k] =
2263  forcing[j][n * nplanecoeffs + offset + bmap[k]];
2264 
2265  bnd[bndoffset + (n + j * nz_loc) * nbnd + k] =
2266  incoeffs[n * nplanecoeffs + offset + bmap[k]];
2267  }
2268  for (k = 0; k < nint; ++k)
2269  {
2270  f_int[cnt1 + k] =
2271  forcing[j][n * nplanecoeffs + offset + imap[k]];
2272  }
2273 
2274  cnt += nbnd;
2275  cnt1 += nint;
2276  }
2277  }
2278  bndoffset +=
2279  nvel * nz_loc * nbnd + nz_loc * (pressure->GetExp(i)->GetNcoeffs());
2280  }
2281 
2282  Array<OneD, NekDouble> f_p(m_mat[mode].m_D_int->GetRows());
2283  NekVector<NekDouble> F_p(f_p.size(), f_p, eWrapper);
2284  NekVector<NekDouble> F_p_tmp(m_mat[mode].m_Cinv->GetRows());
2285 
2286  // fbnd does not currently hold the pressure mean
2287  F_bnd = F_bnd - (*m_mat[mode].m_BCinv) * F_int;
2288  F_p_tmp = (*m_mat[mode].m_Cinv) * F_int;
2289  F_p = (*m_mat[mode].m_D_int) * F_p_tmp;
2290 
2291  // construct inner forcing
2292  Array<OneD, NekDouble> fh_bnd(m_locToGloMap[mode]->GetNumLocalCoeffs(),
2293  0.0);
2294 
2295  offset = cnt = 0;
2296  for (i = 0; i < nel; ++i)
2297  {
2298  nbnd = nz_loc * fields[0]->GetExp(i)->NumBndryCoeffs();
2299 
2300  for (j = 0; j < nvel; ++j)
2301  {
2302  for (k = 0; k < nbnd; ++k)
2303  {
2304  fh_bnd[offset + j * nbnd + k] = f_bnd[cnt + k];
2305  }
2306  cnt += nbnd;
2307  }
2308 
2309  nint = pressure->GetExp(i)->GetNcoeffs();
2310  offset += nvel * nbnd + nint * nz_loc;
2311  }
2312 
2313  offset = cnt1 = 0;
2314  for (i = 0; i < nel; ++i)
2315  {
2316  nbnd = nz_loc * fields[0]->GetExp(i)->NumBndryCoeffs();
2317  nint = pressure->GetExp(i)->GetNcoeffs();
2318 
2319  for (n = 0; n < nz_loc; ++n)
2320  {
2321  for (j = 0; j < nint; ++j)
2322  {
2323  fh_bnd[offset + nvel * nbnd + n * nint + j] = f_p[cnt1 + j];
2324  }
2325  cnt1 += nint;
2326  }
2327  offset += nvel * nbnd + nz_loc * nint;
2328  }
2329  m_mat[mode].m_CoupledBndSys->Solve(fh_bnd, bnd, m_locToGloMap[mode]);
2330 
2331  // unpack pressure and velocity boundary systems.
2332  offset = cnt = 0;
2333  int totpcoeffs = pressure->GetNcoeffs();
2334  Array<OneD, NekDouble> p_coeffs = pressure->UpdateCoeffs();
2335  for (i = 0; i < nel; ++i)
2336  {
2337  nbnd = nz_loc * fields[0]->GetExp(i)->NumBndryCoeffs();
2338  nint = pressure->GetExp(i)->GetNcoeffs();
2339  for (j = 0; j < nvel; ++j)
2340  {
2341  for (k = 0; k < nbnd; ++k)
2342  {
2343  f_bnd[cnt + k] = bnd[offset + j * nbnd + k];
2344  }
2345  cnt += nbnd;
2346  }
2347  offset += nvel * nbnd + nint * nz_loc;
2348  }
2349 
2350  pressure->SetPhysState(false);
2351 
2352  offset = cnt = cnt1 = 0;
2353  for (i = 0; i < nel; ++i)
2354  {
2355  nint = pressure->GetExp(i)->GetNcoeffs();
2356  nbnd = fields[0]->GetExp(i)->NumBndryCoeffs();
2357  cnt1 = pressure->GetCoeff_Offset(i);
2358 
2359  for (n = 0; n < nz_loc; ++n)
2360  {
2361  for (j = 0; j < nint; ++j)
2362  {
2363  p_coeffs[n * totpcoeffs + cnt1 + j] = f_p[cnt + j] =
2364  bnd[offset + nvel * nz_loc * nbnd + n * nint + j];
2365  }
2366  cnt += nint;
2367  }
2368  offset += (nvel * nbnd + nint) * nz_loc;
2369  }
2370 
2371  // Back solve first level of static condensation for interior
2372  // velocity space and store in F_int
2373  F_int = F_int + Transpose(*m_mat[mode].m_D_int) * F_p -
2374  Transpose(*m_mat[mode].m_Btilde) * F_bnd;
2375  F_int = (*m_mat[mode].m_Cinv) * F_int;
2376 
2377  // Unpack solution from Bnd and F_int to v_coeffs
2378  cnt = cnt1 = 0;
2379  for (i = 0; i < nel; ++i) // loop over elements
2380  {
2381  fields[0]->GetExp(i)->GetBoundaryMap(bmap);
2382  fields[0]->GetExp(i)->GetInteriorMap(imap);
2383  nbnd = bmap.size();
2384  nint = imap.size();
2385  offset = fields[0]->GetCoeff_Offset(i);
2386 
2387  for (j = 0; j < nvel; ++j) // loop over velocity fields
2388  {
2389  for (n = 0; n < nz_loc; ++n)
2390  {
2391  for (k = 0; k < nbnd; ++k)
2392  {
2393  fields[j]->SetCoeff(n * nplanecoeffs + offset + bmap[k],
2394  f_bnd[cnt + k]);
2395  }
2396 
2397  for (k = 0; k < nint; ++k)
2398  {
2399  fields[j]->SetCoeff(n * nplanecoeffs + offset + imap[k],
2400  f_int[cnt1 + k]);
2401  }
2402  cnt += nbnd;
2403  cnt1 += nint;
2404  }
2405  }
2406  }
2407 
2408  for (j = 0; j < nvel; ++j)
2409  {
2410  fields[j]->SetPhysState(false);
2411  }
2412 }
#define sign(a, b)
return the sign(b)*a
Definition: Polylib.cpp:15
std::shared_ptr< ContField > ContFieldSharedPtr
Definition: ContField.h:277

References Nektar::SolverUtils::EquationSystem::eHomogeneous1D, Nektar::SpatialDomains::eNeumann, Nektar::SpatialDomains::eRobin, Nektar::eWrapper, Nektar::SolverUtils::EquationSystem::GetNcoeffs(), Nektar::SolverUtils::EquationSystem::m_fields, Nektar::SolverUtils::EquationSystem::m_HomogeneousType, m_locToGloMap, m_mat, Nektar::SolverUtils::EquationSystem::m_singleMode, Nektar::IncNavierStokes::m_velocity, CG_Iterations::pressure, sign, Nektar::Transpose(), and Vmath::Zero().

◆ SolveLinearNS() [2/2]

void Nektar::CoupledLinearNS::SolveLinearNS ( const Array< OneD, Array< OneD, NekDouble >> &  forcing)

Solve the coupled linear Navier-Stokes solve using matrix systems set up at construction. The solution is stored in m_velocity and m_pressure.

Parameters
forcingA list of forcing functions for each velocity component

The routine involves two levels of static condensations. Initially we require a statically condensed forcing function which requires the following manipulation

\[ {F\_bnd} = {\bf f}_{bnd} -m\_B \,m\_Cinv\, {\bf f}_{int}, \hspace{1cm} F\_p = m\_D\_{int}\, m\_Cinv\, {\bf f}_{int} \]

Where \({\bf f}_{bnd}\) denote the forcing degrees of freedom of the elemental velocities on the boundary of the element, \({\bf f}_{int}\) denote the forcing degrees of freedom of the elemental velocities on the interior of the element. (see detailed description for more details).

This vector is further manipulated into

\[ Fh\_{bnd} = \left [ \begin{array}{c} f\_{bnd} -m\_B \, m\_Cinv\, {\bf f}_{int}\\ \left [m\_D\_{int} \, m\_Cinv \,{\bf f}_{int} \right]_0 \end{array}\right ] \hspace{1cm} [Fh\_p]_{i} = \begin{array}{c} [m\_D\_{int} \, m\_Cinv \, {\bf f}_{int}]_{i+1} \end{array} \]

where \(-{[}m\_D\_{int}^T\, m\_Cinv \,{\bf f}_{int}]_0\) which is corresponds to the mean mode of the pressure degrees of freedom and is now added to the boundary system and the remainder of the block becomes the interior forcing for the inner static condensation (see detailed description for more details) which is set up in a GlobalLinSysDirectStaticCond class.

Finally we perform the final maniplation of the forcing to using hte

\[ Fh\_{bnd} = Fh\_{bnd} - m\_Bh \,m\_Chinv \, Fh\_p \]

We can now call the solver to the global coupled boundary system (through the call to #m_CoupledBndSys->Solve) to obtain the velocity boundary solution as the mean pressure solution, i.e.

\[ {\cal A}^T(\hat{A} - \hat{C}^T \hat{D}^{-1} \hat{B} ){\cal A} \, Bnd = Fh\_{bnd} \]

Once we know the solution to the above the rest of the pressure modes are recoverable thorugh

\[ Ph = m\_Dhinv\, (Bnd - m\_Ch^T \, Fh_{bnd}) \]

We can now unpack \( Fh\_{bnd} \) (last elemental mode) and \( Ph \) into m_pressure and \( F_p\) and \( Fh\_{bnd}\) into a closed pack list of boundary velocoity degrees of freedom stored in \( F\_bnd\).

Finally the interior velocity degrees of freedom are then obtained through the relationship

\[ F\_{int} = m\_Cinv\ ( F\_{int} + m\_D\_{int}^T\, F\_p - m\_Btilde^T\, Bnd) \]

We then unpack the solution back to the MultiRegion structures m_velocity and m_pressure

Definition at line 2081 of file CoupledLinearNS.cpp.

2083 {
2084  int i, n;
2085  Array<OneD, MultiRegions::ExpListSharedPtr> vel_fields(m_velocity.size());
2086  Array<OneD, Array<OneD, NekDouble>> force(m_velocity.size());
2087 
2088  // Impose Dirichlet conditions on velocity fields
2089  for (i = 0; i < m_velocity.size(); ++i)
2090  {
2091  Vmath::Zero(m_fields[i]->GetNcoeffs(), m_fields[i]->UpdateCoeffs(), 1);
2092  m_fields[i]->ImposeDirichletConditions(m_fields[i]->UpdateCoeffs());
2093  }
2094 
2096  {
2097  int ncoeffsplane = m_fields[m_velocity[0]]->GetPlane(0)->GetNcoeffs();
2098  for (n = 0; n < m_npointsZ / 2; ++n)
2099  {
2100  // Get the a Fourier mode of velocity and forcing components.
2101  for (i = 0; i < m_velocity.size(); ++i)
2102  {
2103  vel_fields[i] = m_fields[m_velocity[i]]->GetPlane(2 * n);
2104  // Note this needs to correlate with how we pass forcing
2105  force[i] = forcing[i] + 2 * n * ncoeffsplane;
2106  }
2107 
2108  SolveLinearNS(force, vel_fields, m_pressure->GetPlane(2 * n), n);
2109  }
2110  for (i = 0; i < m_velocity.size(); ++i)
2111  {
2112  m_fields[m_velocity[i]]->SetPhysState(false);
2113  }
2114  m_pressure->SetPhysState(false);
2115  }
2116  else
2117  {
2118  for (i = 0; i < m_velocity.size(); ++i)
2119  {
2120  vel_fields[i] = m_fields[m_velocity[i]];
2121  // Note this needs to correlate with how we pass forcing
2122  force[i] = forcing[i];
2123  }
2124  SolveLinearNS(force, vel_fields, m_pressure);
2125  }
2126 }

References Nektar::SolverUtils::EquationSystem::eHomogeneous1D, Nektar::SolverUtils::EquationSystem::GetNcoeffs(), Nektar::SolverUtils::EquationSystem::m_fields, Nektar::SolverUtils::EquationSystem::m_HomogeneousType, Nektar::SolverUtils::EquationSystem::m_npointsZ, Nektar::IncNavierStokes::m_pressure, Nektar::IncNavierStokes::m_velocity, and Vmath::Zero().

Referenced by Continuation(), Solve(), SolveSteadyNavierStokes(), and SolveUnsteadyStokesSystem().

◆ SolveSteadyNavierStokes()

void Nektar::CoupledLinearNS::SolveSteadyNavierStokes ( void  )

Definition at line 1732 of file CoupledLinearNS.cpp.

1733 {
1734  LibUtilities::Timer Newtontimer;
1735  Newtontimer.Start();
1736 
1737  Array<OneD, Array<OneD, NekDouble>> RHS_Coeffs(m_velocity.size());
1738  Array<OneD, Array<OneD, NekDouble>> RHS_Phys(m_velocity.size());
1739  Array<OneD, Array<OneD, NekDouble>> delta_velocity_Phys(m_velocity.size());
1740  Array<OneD, Array<OneD, NekDouble>> Velocity_Phys(m_velocity.size());
1741  Array<OneD, NekDouble> L2_norm(m_velocity.size(), 1.0);
1742  Array<OneD, NekDouble> Inf_norm(m_velocity.size(), 1.0);
1743 
1744  for (int i = 0; i < m_velocity.size(); ++i)
1745  {
1746  delta_velocity_Phys[i] = Array<OneD, NekDouble>(
1747  m_fields[m_velocity[i]]->GetTotPoints(), 1.0);
1748  Velocity_Phys[i] = Array<OneD, NekDouble>(
1749  m_fields[m_velocity[i]]->GetTotPoints(), 0.0);
1750  }
1751 
1752  m_counter = 1;
1753 
1754  L2Norm(delta_velocity_Phys, L2_norm);
1755 
1756  // while(max(Inf_norm[0], Inf_norm[1]) > m_tol)
1757  while (max(L2_norm[0], L2_norm[1]) > m_tol)
1758  {
1759  if (m_counter == 1)
1760  // At the first Newton step, we use the solution of the
1761  // Stokes problem (if Restart=0 in input file) Or the
1762  // solution of the .rst file (if Restart=1 in input
1763  // file)
1764  {
1765  for (int i = 0; i < m_velocity.size(); ++i)
1766  {
1767  RHS_Coeffs[i] = Array<OneD, NekDouble>(
1768  m_fields[m_velocity[i]]->GetNcoeffs(), 0.0);
1769  RHS_Phys[i] = Array<OneD, NekDouble>(
1770  m_fields[m_velocity[i]]->GetTotPoints(), 0.0);
1771  }
1772 
1773  for (int i = 0; i < m_velocity.size(); ++i)
1774  {
1775  m_fields[m_velocity[i]]->BwdTrans(
1776  m_fields[m_velocity[i]]->GetCoeffs(), Velocity_Phys[i]);
1777  }
1778 
1779  m_initialStep = true;
1780  EvaluateNewtonRHS(Velocity_Phys, RHS_Coeffs);
1781  SetUpCoupledMatrix(0.0, Velocity_Phys, true);
1782  SolveLinearNS(RHS_Coeffs);
1783  m_initialStep = false;
1784  }
1785  if (m_counter > 1)
1786  {
1787  EvaluateNewtonRHS(Velocity_Phys, RHS_Coeffs);
1788 
1789  if (m_counter % m_MatrixSetUpStep ==
1790  0) // Setting Up the matrix is expensive. We do it at each
1791  // "m_MatrixSetUpStep" step.
1792  {
1793  SetUpCoupledMatrix(0.0, Velocity_Phys, true);
1794  }
1795  SolveLinearNS(RHS_Coeffs);
1796  }
1797 
1798  for (int i = 0; i < m_velocity.size(); ++i)
1799  {
1800  m_fields[m_velocity[i]]->BwdTrans(RHS_Coeffs[i], RHS_Phys[i]);
1801  m_fields[m_velocity[i]]->BwdTrans(
1802  m_fields[m_velocity[i]]->GetCoeffs(), delta_velocity_Phys[i]);
1803  }
1804 
1805  for (int i = 0; i < m_velocity.size(); ++i)
1806  {
1807  Vmath::Vadd(Velocity_Phys[i].size(), Velocity_Phys[i], 1,
1808  delta_velocity_Phys[i], 1, Velocity_Phys[i], 1);
1809  }
1810 
1811  // InfNorm(delta_velocity_Phys, Inf_norm);
1812  L2Norm(delta_velocity_Phys, L2_norm);
1813 
1814  if (max(Inf_norm[0], Inf_norm[1]) > 100)
1815  {
1816  cout << "\nThe Newton method has failed at m_kinvis = " << m_kinvis
1817  << " (<=> Re = " << 1 / m_kinvis << ")" << endl;
1818  ASSERTL0(0, "The Newton method has failed... \n");
1819  }
1820 
1821  cout << "\n";
1822  m_counter++;
1823  }
1824 
1825  if (m_counter > 1) // We save u:=u+\delta u in u->Coeffs
1826  {
1827  for (int i = 0; i < m_velocity.size(); ++i)
1828  {
1829  m_fields[m_velocity[i]]->FwdTrans(
1830  Velocity_Phys[i], m_fields[m_velocity[i]]->UpdateCoeffs());
1831  }
1832  }
1833 
1834  Newtontimer.Stop();
1835  cout << "We have done " << m_counter - 1 << " iteration(s) in "
1836  << Newtontimer.TimePerTest(1) / 60 << " minute(s). \n\n";
1837 }
void EvaluateNewtonRHS(Array< OneD, Array< OneD, NekDouble >> &Velocity, Array< OneD, Array< OneD, NekDouble >> &outarray)
void L2Norm(Array< OneD, Array< OneD, NekDouble >> &inarray, Array< OneD, NekDouble > &outarray)

References ASSERTL0, EvaluateNewtonRHS(), Nektar::SolverUtils::EquationSystem::GetNcoeffs(), Nektar::SolverUtils::EquationSystem::GetTotPoints(), L2Norm(), m_counter, Nektar::SolverUtils::EquationSystem::m_fields, m_initialStep, Nektar::IncNavierStokes::m_kinvis, m_MatrixSetUpStep, m_tol, Nektar::IncNavierStokes::m_velocity, SetUpCoupledMatrix(), SolveLinearNS(), Nektar::LibUtilities::Timer::Start(), Nektar::LibUtilities::Timer::Stop(), Nektar::LibUtilities::Timer::TimePerTest(), and Vmath::Vadd().

Referenced by v_DoSolve().

◆ SolveUnsteadyStokesSystem()

void Nektar::CoupledLinearNS::SolveUnsteadyStokesSystem ( const Array< OneD, const Array< OneD, NekDouble >> &  inarray,
Array< OneD, Array< OneD, NekDouble >> &  outarray,
const NekDouble  time,
const NekDouble  a_iixDt 
)

Definition at line 1523 of file CoupledLinearNS.cpp.

1527 {
1528  int i;
1529  Array<OneD, Array<OneD, NekDouble>> F(m_nConvectiveFields);
1530  NekDouble lambda = 1.0 / aii_Dt;
1531  static NekDouble lambda_store;
1532  Array<OneD, Array<OneD, NekDouble>> forcing(m_velocity.size());
1533  // Matrix solution
1534  if (fabs(lambda_store - lambda) > 1e-10)
1535  {
1536  SetUpCoupledMatrix(lambda);
1537  lambda_store = lambda;
1538  }
1539 
1540  // Forcing for advection solve
1541  for (i = 0; i < m_velocity.size(); ++i)
1542  {
1543  bool waveSpace = m_fields[m_velocity[i]]->GetWaveSpace();
1544  m_fields[m_velocity[i]]->SetWaveSpace(true);
1545  m_fields[m_velocity[i]]->IProductWRTBase(
1546  inarray[i], m_fields[m_velocity[i]]->UpdateCoeffs());
1547  m_fields[m_velocity[i]]->SetWaveSpace(waveSpace);
1548  Vmath::Smul(m_fields[m_velocity[i]]->GetNcoeffs(), lambda,
1549  m_fields[m_velocity[i]]->GetCoeffs(), 1,
1550  m_fields[m_velocity[i]]->UpdateCoeffs(), 1);
1551  forcing[i] = m_fields[m_velocity[i]]->GetCoeffs();
1552  }
1553 
1554  SolveLinearNS(forcing);
1555 
1556  for (i = 0; i < m_velocity.size(); ++i)
1557  {
1558  m_fields[m_velocity[i]]->BwdTrans(m_fields[m_velocity[i]]->GetCoeffs(),
1559  outarray[i]);
1560  }
1561 }
int m_nConvectiveFields
Number of fields to be convected;.

References Nektar::SolverUtils::EquationSystem::GetNcoeffs(), Nektar::SolverUtils::EquationSystem::m_fields, Nektar::IncNavierStokes::m_nConvectiveFields, Nektar::IncNavierStokes::m_velocity, SetUpCoupledMatrix(), Vmath::Smul(), and SolveLinearNS().

Referenced by v_DoInitialise().

◆ v_DoInitialise()

void Nektar::CoupledLinearNS::v_DoInitialise ( void  )
privatevirtual

Sets up initial conditions.

Sets the initial conditions.

Reimplemented from Nektar::SolverUtils::UnsteadySystem.

Definition at line 1359 of file CoupledLinearNS.cpp.

1360 {
1361  switch (m_equationType)
1362  {
1363  case eUnsteadyStokes:
1364  case eUnsteadyNavierStokes:
1365  {
1366  // LibUtilities::TimeIntegrationMethod intMethod;
1367  // std::string TimeIntStr =
1368  // m_session->GetSolverInfo("TIMEINTEGRATIONMETHOD");
1369  // int i;
1370  // for(i = 0; i < (int)
1371  // LibUtilities::SIZE_TimeIntegrationMethod; ++i)
1372  // {
1373  // if(boost::iequals(LibUtilities::TimeIntegrationMethodMap[i],TimeIntStr))
1374  // {
1375  // intMethod =
1376  // (LibUtilities::TimeIntegrationMethod)i;
1377  // break;
1378  // }
1379  // }
1380  //
1381  // ASSERTL0(i != (int)
1382  // LibUtilities::SIZE_TimeIntegrationMethod, "Invalid
1383  // time integration type.");
1384  //
1385  // m_integrationScheme =
1386  // LibUtilities::GetTimeIntegrationWrapperFactory().CreateInstance(LibUtilities::TimeIntegrationMethodMap[intMethod]);
1387 
1388  // Could defind this from IncNavierStokes class?
1390 
1393 
1394  // Set initial condition using time t=0
1395 
1396  SetInitialConditions(0.0);
1397  }
1398  case eSteadyStokes:
1399  SetUpCoupledMatrix(0.0);
1400  break;
1401  case eSteadyOseen:
1402  {
1403  Array<OneD, Array<OneD, NekDouble>> AdvField(m_velocity.size());
1404  for (int i = 0; i < m_velocity.size(); ++i)
1405  {
1406  AdvField[i] = Array<OneD, NekDouble>(
1407  m_fields[m_velocity[i]]->GetTotPoints(), 0.0);
1408  }
1409 
1410  ASSERTL0(m_session->DefinesFunction("AdvectionVelocity"),
1411  "Advection Velocity section must be defined in "
1412  "session file.");
1413 
1414  std::vector<std::string> fieldStr;
1415  for (int i = 0; i < m_velocity.size(); ++i)
1416  {
1417  fieldStr.push_back(
1418  m_boundaryConditions->GetVariable(m_velocity[i]));
1419  }
1420  GetFunction("AdvectionVelocity")->Evaluate(fieldStr, AdvField);
1421 
1422  SetUpCoupledMatrix(0.0, AdvField, false);
1423  }
1424  break;
1425  case eSteadyNavierStokes:
1426  {
1427  m_session->LoadParameter("KinvisMin", m_kinvisMin);
1428  m_session->LoadParameter("KinvisPercentage", m_KinvisPercentage);
1429  m_session->LoadParameter("Tolerence", m_tol);
1430  m_session->LoadParameter("MaxIteration", m_maxIt);
1431  m_session->LoadParameter("MatrixSetUpStep", m_MatrixSetUpStep);
1432  m_session->LoadParameter("Restart", m_Restart);
1433 
1435 
1436  if (m_Restart == 1)
1437  {
1438  ASSERTL0(m_session->DefinesFunction("Restart"),
1439  "Restart section must be defined in session file.");
1440 
1441  Array<OneD, Array<OneD, NekDouble>> Restart(m_velocity.size());
1442  for (int i = 0; i < m_velocity.size(); ++i)
1443  {
1444  Restart[i] = Array<OneD, NekDouble>(
1445  m_fields[m_velocity[i]]->GetTotPoints(), 0.0);
1446  }
1447  std::vector<std::string> fieldStr;
1448  for (int i = 0; i < m_velocity.size(); ++i)
1449  {
1450  fieldStr.push_back(
1451  m_boundaryConditions->GetVariable(m_velocity[i]));
1452  }
1453  GetFunction("Restart")->Evaluate(fieldStr, Restart);
1454 
1455  for (int i = 0; i < m_velocity.size(); ++i)
1456  {
1457  m_fields[m_velocity[i]]->FwdTransLocalElmt(
1458  Restart[i], m_fields[m_velocity[i]]->UpdateCoeffs());
1459  }
1460  cout << "Saving the RESTART file for m_kinvis = " << m_kinvis
1461  << " (<=> Re = " << 1 / m_kinvis << ")" << endl;
1462  }
1463  else // We solve the Stokes Problem
1464  {
1465 
1466  SetUpCoupledMatrix(0.0);
1467  m_initialStep = true;
1468  m_counter = 1;
1469  // SolveLinearNS(m_ForcingTerm_Coeffs);
1470  Solve();
1471  m_initialStep = false;
1472  cout << "Saving the Stokes Flow for m_kinvis = " << m_kinvis
1473  << " (<=> Re = " << 1 / m_kinvis << ")" << endl;
1474  }
1475  }
1476  break;
1477  case eSteadyLinearisedNS:
1478  {
1479  SetInitialConditions(0.0);
1480 
1481  Array<OneD, Array<OneD, NekDouble>> AdvField(m_velocity.size());
1482  for (int i = 0; i < m_velocity.size(); ++i)
1483  {
1484  AdvField[i] = Array<OneD, NekDouble>(
1485  m_fields[m_velocity[i]]->GetTotPoints(), 0.0);
1486  }
1487 
1488  ASSERTL0(m_session->DefinesFunction("AdvectionVelocity"),
1489  "Advection Velocity section must be defined in "
1490  "session file.");
1491 
1492  std::vector<std::string> fieldStr;
1493  for (int i = 0; i < m_velocity.size(); ++i)
1494  {
1495  fieldStr.push_back(
1496  m_boundaryConditions->GetVariable(m_velocity[i]));
1497  }
1498  GetFunction("AdvectionVelocity")->Evaluate(fieldStr, AdvField);
1499 
1500  SetUpCoupledMatrix(m_lambda, AdvField, true);
1501  }
1502  break;
1503  case eNoEquationType:
1504  default:
1505  ASSERTL0(false,
1506  "Unknown or undefined equation type for CoupledLinearNS");
1507  }
1508 }
void EvaluateAdvection(const Array< OneD, const Array< OneD, NekDouble >> &inarray, Array< OneD, Array< OneD, NekDouble >> &outarray, const NekDouble time)
void SolveUnsteadyStokesSystem(const Array< OneD, const Array< OneD, NekDouble >> &inarray, Array< OneD, Array< OneD, NekDouble >> &outarray, const NekDouble time, const NekDouble a_iixDt)
EquationType m_equationType
equation type;
void DefineOdeRhs(FuncPointerT func, ObjectPointerT obj)
void DefineImplicitSolve(FuncPointerT func, ObjectPointerT obj)
NekDouble m_lambda
Lambda constant in real system if one required.
SOLVER_UTILS_EXPORT void SetInitialConditions(NekDouble initialtime=0.0, bool dumpInitialConditions=true, const int domain=0)
Initialise the data in the dependent fields.
LibUtilities::TimeIntegrationSchemeOperators m_ode
The time integration scheme operators to use.
@ eSteadyNavierStokes
@ eUnsteadyStokes
@ eUnsteadyNavierStokes
@ eSteadyLinearisedNS
@ eNoEquationType

References ASSERTL0, DefineForcingTerm(), Nektar::LibUtilities::TimeIntegrationSchemeOperators::DefineImplicitSolve(), Nektar::LibUtilities::TimeIntegrationSchemeOperators::DefineOdeRhs(), Nektar::eNoEquationType, Nektar::eSteadyLinearisedNS, Nektar::eSteadyNavierStokes, Nektar::eSteadyOseen, Nektar::eSteadyStokes, Nektar::eUnsteadyNavierStokes, Nektar::eUnsteadyStokes, EvaluateAdvection(), Nektar::SolverUtils::EquationSystem::GetFunction(), Nektar::SolverUtils::EquationSystem::GetTotPoints(), Nektar::SolverUtils::EquationSystem::m_boundaryConditions, m_counter, Nektar::IncNavierStokes::m_equationType, Nektar::SolverUtils::EquationSystem::m_fields, m_initialStep, Nektar::IncNavierStokes::m_kinvis, m_kinvisMin, m_KinvisPercentage, Nektar::SolverUtils::EquationSystem::m_lambda, m_MatrixSetUpStep, m_maxIt, Nektar::SolverUtils::UnsteadySystem::m_ode, m_Restart, Nektar::SolverUtils::EquationSystem::m_session, m_tol, Nektar::IncNavierStokes::m_velocity, Nektar::SolverUtils::EquationSystem::SetInitialConditions(), SetUpCoupledMatrix(), Solve(), and SolveUnsteadyStokesSystem().

◆ v_DoSolve()

void Nektar::CoupledLinearNS::v_DoSolve ( void  )
privatevirtual

Solves an unsteady problem.

Initialises the time integration scheme (as specified in the session file), and perform the time integration.

Reimplemented from Nektar::SolverUtils::UnsteadySystem.

Definition at line 1585 of file CoupledLinearNS.cpp.

1586 {
1587  switch (m_equationType)
1588  {
1589  case eUnsteadyStokes:
1590  case eUnsteadyNavierStokes:
1591  // AdvanceInTime(m_steps);
1593  break;
1594  case eSteadyStokes:
1595  case eSteadyOseen:
1596  case eSteadyLinearisedNS:
1597  {
1598  Solve();
1599  break;
1600  }
1601  case eSteadyNavierStokes:
1602  {
1603  LibUtilities::Timer Generaltimer;
1604  Generaltimer.Start();
1605 
1606  int Check(0);
1607 
1608  // Saving the init datas
1609  Checkpoint_Output(Check);
1610  Check++;
1611 
1612  cout << "We execute INITIALLY SolveSteadyNavierStokes for m_kinvis "
1613  "= "
1614  << m_kinvis << " (<=> Re = " << 1 / m_kinvis << ")" << endl;
1616 
1617  while (m_kinvis > m_kinvisMin)
1618  {
1619  if (Check == 1)
1620  {
1621  cout << "We execute SolveSteadyNavierStokes for m_kinvis = "
1622  << m_kinvis << " (<=> Re = " << 1 / m_kinvis << ")"
1623  << endl;
1625  Checkpoint_Output(Check);
1626  Check++;
1627  }
1628 
1629  Continuation();
1630 
1631  if (m_kinvis > m_kinvisMin)
1632  {
1633  cout << "We execute SolveSteadyNavierStokes for m_kinvis = "
1634  << m_kinvis << " (<=> Re = " << 1 / m_kinvis << ")"
1635  << endl;
1637  Checkpoint_Output(Check);
1638  Check++;
1639  }
1640  }
1641 
1642  Generaltimer.Stop();
1643  cout << "\nThe total calculation time is : "
1644  << Generaltimer.TimePerTest(1) / 60 << " minute(s). \n\n";
1645 
1646  break;
1647  }
1648  case eNoEquationType:
1649  default:
1650  ASSERTL0(false,
1651  "Unknown or undefined equation type for CoupledLinearNS");
1652  }
1653 }
SOLVER_UTILS_EXPORT void Checkpoint_Output(const int n)
Write checkpoint file of m_fields.
virtual SOLVER_UTILS_EXPORT void v_DoSolve()
Solves an unsteady problem.

References ASSERTL0, Nektar::SolverUtils::EquationSystem::Checkpoint_Output(), Continuation(), Nektar::eNoEquationType, Nektar::eSteadyLinearisedNS, Nektar::eSteadyNavierStokes, Nektar::eSteadyOseen, Nektar::eSteadyStokes, Nektar::eUnsteadyNavierStokes, Nektar::eUnsteadyStokes, Nektar::IncNavierStokes::m_equationType, Nektar::IncNavierStokes::m_kinvis, m_kinvisMin, Solve(), SolveSteadyNavierStokes(), Nektar::LibUtilities::Timer::Start(), Nektar::LibUtilities::Timer::Stop(), Nektar::LibUtilities::Timer::TimePerTest(), and Nektar::SolverUtils::UnsteadySystem::v_DoSolve().

◆ v_GenerateSummary()

void Nektar::CoupledLinearNS::v_GenerateSummary ( SolverUtils::SummaryList s)
privatevirtual

Print a summary of time stepping parameters.

Prints a summary with some information regards the time-stepping.

Reimplemented from Nektar::SolverUtils::UnsteadySystem.

Definition at line 1354 of file CoupledLinearNS.cpp.

1355 {
1356  SolverUtils::AddSummaryItem(s, "Solver Type", "Coupled Linearised NS");
1357 }
void AddSummaryItem(SummaryList &l, const std::string &name, const std::string &value)
Adds a summary item to the summary info list.
Definition: Misc.cpp:49

References Nektar::SolverUtils::AddSummaryItem().

◆ v_GetForceDimension()

int Nektar::CoupledLinearNS::v_GetForceDimension ( void  )
privatevirtual

Implements Nektar::IncNavierStokes.

Definition at line 2459 of file CoupledLinearNS.cpp.

2460 {
2461  return m_session->GetVariables().size();
2462 }

References Nektar::SolverUtils::EquationSystem::m_session.

◆ v_InitObject()

void Nektar::CoupledLinearNS::v_InitObject ( bool  DeclareField = true)
protectedvirtual

Init object for UnsteadySystem class.

Initialization object for UnsteadySystem class.

Reimplemented from Nektar::IncNavierStokes.

Definition at line 67 of file CoupledLinearNS.cpp.

68 {
69  IncNavierStokes::v_InitObject(DeclareField);
70 
71  int i;
72  int expdim = m_graph->GetMeshDimension();
73 
74  // Get Expansion list for orthogonal expansion at p-2
75  const SpatialDomains::ExpansionInfoMap &pressure_exp =
76  GenPressureExp(m_graph->GetExpansionInfo("u"));
77 
79  if (boost::iequals(
80  m_boundaryConditions->GetVariable(m_nConvectiveFields - 1), "p"))
81  {
82  ASSERTL0(false, "Last field is defined as pressure but this is not "
83  "suitable for this solver, please remove this field as "
84  "it is implicitly defined");
85  }
86  // Decide how to declare explist for pressure.
87  if (expdim == 2)
88  {
89  int nz;
90 
92  {
93  ASSERTL0(m_fields.size() > 2, "Expect to have three at least three "
94  "components of velocity variables");
95  LibUtilities::BasisKey Homo1DKey =
96  m_fields[0]->GetHomogeneousBasis()->GetBasisKey();
97 
100  m_homogen_dealiasing, pressure_exp);
101 
102  ASSERTL1(m_npointsZ % 2 == 0,
103  "Non binary number of planes have been specified");
104  nz = m_npointsZ / 2;
105  }
106  else
107  {
108  m_pressure =
110  m_session, pressure_exp);
111  nz = 1;
112  }
113 
114  Array<OneD, MultiRegions::ExpListSharedPtr> velocity(m_velocity.size());
115  for (i = 0; i < m_velocity.size(); ++i)
116  {
117  velocity[i] = m_fields[m_velocity[i]];
118  }
119 
120  // Set up Array of mappings
121  m_locToGloMap = Array<OneD, CoupledLocalToGlobalC0ContMapSharedPtr>(nz);
122 
123  if (m_singleMode)
124  {
125 
126  ASSERTL0(nz <= 2,
127  "For single mode calculation can only have nz <= 2");
128  if (m_session->DefinesSolverInfo("BetaZero"))
129  {
130  m_zeroMode = true;
131  }
132  int nz_loc = 2;
133  m_locToGloMap[0] =
136  m_pressure, nz_loc, m_zeroMode);
137  }
138  else
139  {
140  // base mode
141  int nz_loc = 1;
142  m_locToGloMap[0] =
145  m_pressure, nz_loc);
146 
147  if (nz > 1)
148  {
149  nz_loc = 2;
150  // Assume all higher modes have the same boundary conditions and
151  // re-use mapping
152  m_locToGloMap[1] =
156  m_pressure->GetPlane(2), nz_loc, false);
157  // Note high order modes cannot be singular
158  for (i = 2; i < nz; ++i)
159  {
161  }
162  }
163  }
164  }
165  else if (expdim == 3)
166  {
167  // m_pressure =
168  // MemoryManager<MultiRegions::ExpList3D>::AllocateSharedPtr(pressure_exp);
169  ASSERTL0(false, "Setup mapping aray");
170  }
171  else
172  {
173  ASSERTL0(false, "Exp dimension not recognised");
174  }
175 
176  // creation of the extrapolation object
178  {
179  std::string vExtrapolation = "Standard";
180 
181  if (m_session->DefinesSolverInfo("Extrapolation"))
182  {
183  vExtrapolation = m_session->GetSolverInfo("Extrapolation");
184  }
185 
187  vExtrapolation, m_session, m_fields, m_pressure, m_velocity,
188  m_advObject);
189  }
190 }
const SpatialDomains::ExpansionInfoMap & GenPressureExp(const SpatialDomains::ExpansionInfoMap &VelExp)
virtual void v_InitObject(bool DeclareField=true) override
Init object for UnsteadySystem class.
ExtrapolateSharedPtr m_extrapolation
tBaseSharedPtr CreateInstance(tKey idKey, tParam... args)
Create an instance of the class referred to by idKey.
Definition: NekFactory.hpp:144
SolverUtils::AdvectionSharedPtr m_advObject
Advection term.
bool m_useFFT
Flag to determine if FFT is used for homogeneous transform.
bool m_homogen_dealiasing
Flag to determine if dealiasing is used for homogeneous simulations.
std::map< int, ExpansionInfoShPtr > ExpansionInfoMap
Definition: MeshGraph.h:143
ExtrapolateFactory & GetExtrapolateFactory()
Definition: Extrapolate.cpp:48

References Nektar::MemoryManager< DataType >::AllocateSharedPtr(), ASSERTL0, ASSERTL1, Nektar::LibUtilities::NekFactory< tKey, tBase, tParam >::CreateInstance(), Nektar::SolverUtils::EquationSystem::eHomogeneous1D, Nektar::eUnsteadyNavierStokes, GenPressureExp(), Nektar::GetExtrapolateFactory(), Nektar::SolverUtils::AdvectionSystem::m_advObject, Nektar::SolverUtils::EquationSystem::m_boundaryConditions, Nektar::IncNavierStokes::m_equationType, Nektar::IncNavierStokes::m_extrapolation, Nektar::SolverUtils::EquationSystem::m_fields, Nektar::SolverUtils::EquationSystem::m_graph, Nektar::SolverUtils::EquationSystem::m_homogen_dealiasing, Nektar::SolverUtils::EquationSystem::m_HomogeneousType, Nektar::SolverUtils::EquationSystem::m_LhomZ, m_locToGloMap, Nektar::IncNavierStokes::m_nConvectiveFields, Nektar::SolverUtils::EquationSystem::m_npointsZ, Nektar::IncNavierStokes::m_pressure, Nektar::SolverUtils::EquationSystem::m_session, Nektar::SolverUtils::EquationSystem::m_singleMode, Nektar::SolverUtils::EquationSystem::m_useFFT, Nektar::IncNavierStokes::m_velocity, m_zeroMode, and Nektar::IncNavierStokes::v_InitObject().

◆ v_NegatedOp()

bool Nektar::CoupledLinearNS::v_NegatedOp ( void  )
privatevirtual

Virtual function to define if operator in DoSolve is negated with regard to the strong form. This is currently only used in Arnoldi solves. For Coupledd solver this is true since Stokes operator is set up as a LHS rather than RHS operation

Reimplemented from Nektar::SolverUtils::EquationSystem.

Definition at line 1660 of file CoupledLinearNS.cpp.

1661 {
1662  return true;
1663 }

◆ v_Output()

void Nektar::CoupledLinearNS::v_Output ( void  )
privatevirtual

Write the field data to file. The file is named according to the session name with the extension .fld appended.

Reimplemented from Nektar::SolverUtils::EquationSystem.

Definition at line 2414 of file CoupledLinearNS.cpp.

2415 {
2416  std::vector<Array<OneD, NekDouble>> fieldcoeffs(m_fields.size() + 1);
2417  std::vector<std::string> variables(m_fields.size() + 1);
2418  int i;
2419 
2420  for (i = 0; i < m_fields.size(); ++i)
2421  {
2422  fieldcoeffs[i] = m_fields[i]->UpdateCoeffs();
2423  variables[i] = m_boundaryConditions->GetVariable(i);
2424  }
2425 
2426  fieldcoeffs[i] = Array<OneD, NekDouble>(m_fields[0]->GetNcoeffs());
2427  // project pressure field to velocity space
2428  if (m_singleMode == true)
2429  {
2430  Array<OneD, NekDouble> tmpfieldcoeffs(m_fields[0]->GetNcoeffs() / 2);
2431  m_pressure->GetPlane(0)->BwdTrans(
2432  m_pressure->GetPlane(0)->GetCoeffs(),
2433  m_pressure->GetPlane(0)->UpdatePhys());
2434  m_pressure->GetPlane(1)->BwdTrans(
2435  m_pressure->GetPlane(1)->GetCoeffs(),
2436  m_pressure->GetPlane(1)->UpdatePhys());
2437  m_fields[0]->GetPlane(0)->FwdTransLocalElmt(
2438  m_pressure->GetPlane(0)->GetPhys(), fieldcoeffs[i]);
2439  m_fields[0]->GetPlane(1)->FwdTransLocalElmt(
2440  m_pressure->GetPlane(1)->GetPhys(), tmpfieldcoeffs);
2441  for (int e = 0; e < m_fields[0]->GetNcoeffs() / 2; e++)
2442  {
2443  fieldcoeffs[i][e + m_fields[0]->GetNcoeffs() / 2] =
2444  tmpfieldcoeffs[e];
2445  }
2446  }
2447  else
2448  {
2449  m_pressure->BwdTrans(m_pressure->GetCoeffs(), m_pressure->UpdatePhys());
2450  m_fields[0]->FwdTransLocalElmt(m_pressure->GetPhys(), fieldcoeffs[i]);
2451  }
2452  variables[i] = "p";
2453 
2454  std::string outname = m_sessionName + ".fld";
2455 
2456  WriteFld(outname, m_fields[0], fieldcoeffs, variables);
2457 }
SOLVER_UTILS_EXPORT void WriteFld(const std::string &outname)
Write field data to the given filename.
std::string m_sessionName
Name of the session.

References Nektar::SolverUtils::EquationSystem::GetNcoeffs(), Nektar::SolverUtils::EquationSystem::m_boundaryConditions, Nektar::SolverUtils::EquationSystem::m_fields, Nektar::IncNavierStokes::m_pressure, Nektar::SolverUtils::EquationSystem::m_sessionName, Nektar::SolverUtils::EquationSystem::m_singleMode, and Nektar::SolverUtils::EquationSystem::WriteFld().

◆ v_TransCoeffToPhys()

void Nektar::CoupledLinearNS::v_TransCoeffToPhys ( void  )
privatevirtual

Virtual function for transformation to physical space.

Reimplemented from Nektar::IncNavierStokes.

Definition at line 1563 of file CoupledLinearNS.cpp.

1564 {
1565  int nfields = m_fields.size();
1566  for (int k = 0; k < nfields; ++k)
1567  {
1568  // Backward Transformation in physical space for time evolution
1569  m_fields[k]->BwdTrans(m_fields[k]->GetCoeffs(),
1570  m_fields[k]->UpdatePhys());
1571  }
1572 }

References Nektar::SolverUtils::EquationSystem::m_fields.

◆ v_TransPhysToCoeff()

void Nektar::CoupledLinearNS::v_TransPhysToCoeff ( void  )
privatevirtual

Virtual function for transformation to coefficient space.

Reimplemented from Nektar::IncNavierStokes.

Definition at line 1574 of file CoupledLinearNS.cpp.

1575 {
1576  int nfields = m_fields.size();
1577  for (int k = 0; k < nfields; ++k)
1578  {
1579  // Forward Transformation in physical space for time evolution
1580  m_fields[k]->FwdTransLocalElmt(m_fields[k]->GetPhys(),
1581  m_fields[k]->UpdateCoeffs());
1582  }
1583 }

References Nektar::SolverUtils::EquationSystem::m_fields.

Friends And Related Function Documentation

◆ MemoryManager< CoupledLinearNS >

friend class MemoryManager< CoupledLinearNS >
friend

Definition at line 83 of file CoupledLinearNS.h.

Member Data Documentation

◆ className

string Nektar::CoupledLinearNS::className
static
Initial value:
=
"CoupledLinearisedNS", CoupledLinearNS::create)
static SolverUtils::EquationSystemSharedPtr create(const LibUtilities::SessionReaderSharedPtr &pSession, const SpatialDomains::MeshGraphSharedPtr &pGraph)
Creates an instance of this class.
tKey RegisterCreatorFunction(tKey idKey, CreatorFunction classCreator, std::string pDesc="")
Register a class with the factory.
Definition: NekFactory.hpp:198
EquationSystemFactory & GetEquationSystemFactory()

Name of class.

Definition at line 102 of file CoupledLinearNS.h.

◆ m_counter

int Nektar::CoupledLinearNS::m_counter
private

Definition at line 174 of file CoupledLinearNS.h.

Referenced by SolveSteadyNavierStokes(), and v_DoInitialise().

◆ m_ForcingTerm

Array<OneD, Array<OneD, NekDouble> > Nektar::CoupledLinearNS::m_ForcingTerm

Definition at line 159 of file CoupledLinearNS.h.

Referenced by DefineForcingTerm(), and EvaluateNewtonRHS().

◆ m_ForcingTerm_Coeffs

Array<OneD, Array<OneD, NekDouble> > Nektar::CoupledLinearNS::m_ForcingTerm_Coeffs

Definition at line 160 of file CoupledLinearNS.h.

Referenced by DefineForcingTerm().

◆ m_initialStep

bool Nektar::CoupledLinearNS::m_initialStep
private

Definition at line 175 of file CoupledLinearNS.h.

Referenced by SolveSteadyNavierStokes(), and v_DoInitialise().

◆ m_kinvisMin

NekDouble Nektar::CoupledLinearNS::m_kinvisMin
private

Definition at line 181 of file CoupledLinearNS.h.

Referenced by v_DoInitialise(), and v_DoSolve().

◆ m_KinvisPercentage

NekDouble Nektar::CoupledLinearNS::m_KinvisPercentage
private

Definition at line 183 of file CoupledLinearNS.h.

Referenced by Continuation(), and v_DoInitialise().

◆ m_kinvisStep

NekDouble Nektar::CoupledLinearNS::m_kinvisStep
private

Definition at line 182 of file CoupledLinearNS.h.

◆ m_locToGloMap

Array<OneD, CoupledLocalToGlobalC0ContMapSharedPtr> Nektar::CoupledLinearNS::m_locToGloMap

Definition at line 162 of file CoupledLinearNS.h.

Referenced by SetUpCoupledMatrix(), SolveLinearNS(), and v_InitObject().

◆ m_mat

Array<OneD, CoupledSolverMatrices> Nektar::CoupledLinearNS::m_mat
private

Definition at line 185 of file CoupledLinearNS.h.

Referenced by SetUpCoupledMatrix(), and SolveLinearNS().

◆ m_MatrixSetUpStep

int Nektar::CoupledLinearNS::m_MatrixSetUpStep
private

Definition at line 180 of file CoupledLinearNS.h.

Referenced by SolveSteadyNavierStokes(), and v_DoInitialise().

◆ m_maxIt

int Nektar::CoupledLinearNS::m_maxIt
private

Definition at line 177 of file CoupledLinearNS.h.

Referenced by v_DoInitialise().

◆ m_Restart

int Nektar::CoupledLinearNS::m_Restart
private

Definition at line 178 of file CoupledLinearNS.h.

Referenced by v_DoInitialise().

◆ m_tol

NekDouble Nektar::CoupledLinearNS::m_tol
private

Definition at line 176 of file CoupledLinearNS.h.

Referenced by SolveSteadyNavierStokes(), and v_DoInitialise().

◆ m_zeroMode

bool Nektar::CoupledLinearNS::m_zeroMode
private

Id to identify when single mode is mean mode (i.e. beta=0);.

Definition at line 172 of file CoupledLinearNS.h.

Referenced by SetUpCoupledMatrix(), and v_InitObject().