39#include <boost/algorithm/string.hpp>
40#include <boost/core/ignore_unused.hpp>
53 "Nonlinear Peregrine equations in conservative variables.");
70 if (
m_session->DefinesSolverInfo(
"PROBLEMTYPE"))
73 std::string ProblemTypeStr =
m_session->GetSolverInfo(
"PROBLEMTYPE");
95 ASSERTL0(
false,
"Implicit Peregrine not set up.");
100 if (
m_session->DefinesParameter(
"ConstDepth"))
106 ASSERTL0(
false,
"Constant Depth not specified");
116 "Continuous projection type not supported for Peregrine.");
130 m_session->LoadSolverInfo(
"AdvectionType", advName,
"WeakDG");
139 m_session->LoadSolverInfo(
"UpwindType", riemName,
"NoSolver");
162 ASSERTL0(
false,
"Unsupported projection type.");
190 m_fields[0]->IProductWRTBase(tmp, mod);
191 m_fields[0]->MultiplyByElmtInvMass(mod, mod);
193 Vmath::Vadd(nq, tmp, 1, outarray[1], 1, outarray[1], 1);
198 m_fields[0]->IProductWRTBase(tmp, mod);
199 m_fields[0]->MultiplyByElmtInvMass(mod, mod);
201 Vmath::Vadd(nq, tmp, 1, outarray[2], 1, outarray[2], 1);
209 Vmath::Vadd(nq, tmp, 1, outarray[1], 1, outarray[1], 1);
214 Vmath::Vadd(nq, tmp, 1, outarray[2], 1, outarray[2], 1);
218 ASSERTL0(
false,
"Unknown projection scheme for the NonlinearSWE");
243 m_fields[0]->IProductWRTBase(tmp, mod);
244 m_fields[0]->MultiplyByElmtInvMass(mod, mod);
246 Vmath::Vadd(nq, tmp, 1, outarray[i + 1], 1, outarray[i + 1], 1);
257 Vmath::Vadd(nq, tmp, 1, outarray[i + 1], 1, outarray[i + 1], 1);
262 ASSERTL0(
false,
"Unknown projection scheme for the NonlinearSWE");
272 int nvariables = inarray.size();
285 for (i = 0; i < nvariables; ++i)
303 for (i = 0; i < nvariables - 1; ++i)
323 "Variable depth not supported for the Peregrine "
337 m_fields[0]->IProductWRTBase(outarray[1], modarray[1]);
338 m_fields[0]->IProductWRTBase(outarray[2], modarray[2]);
348 m_fields[0]->MultiplyByElmtInvMass(modarray[1], modarray[1]);
349 m_fields[0]->MultiplyByElmtInvMass(modarray[2], modarray[2]);
361 for (i = 0; i < 2; ++i)
399 m_fields[0]->IProductWRTDerivBase(0, physfield[0], coeffsfield[0]);
400 m_fields[0]->IProductWRTDerivBase(1, physfield[1], coeffsfield[1]);
401 Vmath::Vadd(ncoeffs, coeffsfield[0], 1, coeffsfield[1], 1,
410 m_fields[0]->AddTraceIntegral(normflux, coeffsfield[0]);
411 m_fields[0]->MultiplyByElmtInvMass(coeffsfield[0], coeffsfield[0]);
412 m_fields[0]->BwdTrans(coeffsfield[0], physfield[0]);
414 Vmath::Smul(nq, -invgamma, physfield[0], 1, physfield[0], 1);
442 Vmath::Smul(nq, gamma, physfield[0], 1, physfield[0], 1);
447 m_fields[0]->IProductWRTDerivBase(0, physfield[0], coeffsfield[0]);
448 m_fields[1]->IProductWRTDerivBase(1, physfield[0], coeffsfield[1]);
460 m_fields[0]->AddTraceIntegral(normflux, coeffsfield[0]);
463 m_fields[0]->AddTraceIntegral(normflux, coeffsfield[1]);
466 Vmath::Vadd(ncoeffs, f1, 1, coeffsfield[0], 1, modarray[1], 1);
467 Vmath::Vadd(ncoeffs, f2, 1, coeffsfield[1], 1, modarray[2], 1);
469 m_fields[1]->MultiplyByElmtInvMass(modarray[1], modarray[1]);
470 m_fields[2]->MultiplyByElmtInvMass(modarray[2], modarray[2]);
472 m_fields[1]->BwdTrans(modarray[1], outarray[1]);
473 m_fields[2]->BwdTrans(modarray[2], outarray[2]);
482 ASSERTL0(
false,
"Unknown projection scheme for the Peregrine");
485 ASSERTL0(
false,
"Unknown projection scheme for the NonlinearSWE");
495 int nvariables = inarray.size();
503 if (inarray != outarray)
507 for (i = 0; i < nvariables; ++i)
523 for (i = 0; i < nvariables; ++i)
525 m_fields[i]->FwdTrans(inarray[i], coeffs);
526 m_fields[i]->BwdTrans(coeffs, outarray[i]);
531 ASSERTL0(
false,
"Unknown projection scheme");
548 for (
int i = 0; i < nvariables; ++i)
551 m_fields[i]->ExtractTracePhys(inarray[i], Fwd[i]);
555 for (
int n = 0; n <
m_fields[0]->GetBndConditions().size(); ++n)
559 if (boost::iequals(
m_fields[0]->GetBndConditions()[n]->GetUserDefined(),
566 if (
m_fields[0]->GetBndConditions()[n]->IsTimeDependent())
568 for (
int i = 0; i < nvariables; ++i)
570 m_fields[i]->EvaluateBoundaryConditions(time);
573 cnt +=
m_fields[0]->GetBndCondExpansions()[n]->GetExpSize();
586 int nvariables = physarray.size();
590 int e, id1, id2, npts;
592 m_fields[0]->GetBndCondExpansions()[bcRegion];
593 for (e = 0; e < bcexp->GetExpSize(); ++e)
595 npts = bcexp->GetExp(e)->GetTotPoints();
596 id1 = bcexp->GetPhys_Offset(e);
597 id2 =
m_fields[0]->GetTrace()->GetPhys_Offset(
598 m_fields[0]->GetTraceMap()->GetBndCondIDToGlobalTraceID(cnt + e));
607 &tmp[0], 1, &tmp[0], 1);
617 &Fwd[1 + i][id2], 1, &Fwd[1 + i][id2], 1);
621 for (i = 0; i < nvariables; ++i)
623 bcexp =
m_fields[i]->GetBndCondExpansions()[bcRegion];
624 Vmath::Vcopy(npts, &Fwd[i][id2], 1, &(bcexp->UpdatePhys())[id1], 1);
633 boost::ignore_unused(physarray);
640 int e, id1, id2, npts;
642 m_fields[0]->GetBndCondExpansions()[bcRegion];
644 for (e = 0; e < bcexp->GetExpSize(); ++e)
646 npts = bcexp->GetExp(e)->GetNumPoints(0);
647 id1 = bcexp->GetPhys_Offset(e);
648 id2 =
m_fields[0]->GetTrace()->GetPhys_Offset(
649 m_fields[0]->GetTraceMap()->GetBndCondIDToGlobalTraceID(cnt + e));
667 &tmp_n[0], 1, &tmp_n[0], 1);
672 &tmp_t[0], 1, &tmp_t[0], 1);
681 &Fwd[1][id2], 1, &Fwd[1][id2], 1);
686 &Fwd[2][id2], 1, &Fwd[2][id2], 1);
691 "3D not implemented for Shallow Water Equations");
694 ASSERTL0(
false,
"Illegal expansion dimension");
698 for (i = 0; i < nvariables; ++i)
700 bcexp =
m_fields[i]->GetBndCondExpansions()[bcRegion];
701 Vmath::Vcopy(npts, &Fwd[i][id2], 1, &(bcexp->UpdatePhys())[id1], 1);
712 int nq =
m_fields[0]->GetTotPoints();
728 Vmath::Vmul(nq, physfield[0], 1, physfield[0], 1, tmp, 1);
736 Vmath::Vmul(nq, velocity[j], 1, physfield[i + 1], 1, flux[i + 1][j],
741 Vmath::Vadd(nq, flux[i + 1][i], 1, tmp, 1, flux[i + 1][i], 1);
751 if (physin.get() == physout.get())
755 for (
int i = 0; i < 3; ++i)
766 Vmath::Vdiv(nq, tmp[1], 1, tmp[0], 1, physout[1], 1);
769 Vmath::Vdiv(nq, tmp[2], 1, tmp[0], 1, physout[2], 1);
777 Vmath::Vdiv(nq, physin[1], 1, physin[0], 1, physout[1], 1);
780 Vmath::Vdiv(nq, physin[2], 1, physin[0], 1, physout[2], 1);
808 if (physin.get() == physout.get())
812 for (
int i = 0; i < 3; ++i)
823 Vmath::Vmul(nq, physout[0], 1, tmp[1], 1, physout[1], 1);
826 Vmath::Vmul(nq, physout[0], 1, tmp[2], 1, physout[2], 1);
834 Vmath::Vmul(nq, physout[0], 1, physin[1], 1, physout[1], 1);
837 Vmath::Vmul(nq, physout[0], 1, physin[2], 1, physout[2], 1);
869 const int npts = physfield[0].size();
873 Vmath::Vdiv(npts, physfield[1 + i], 1, physfield[0], 1, velocity[i], 1);
892 for (
int j = 0; j < nq; j++)
894 (
m_fields[3]->UpdatePhys())[j] = fce[j];
921 for (i = 0; i < 2; ++i)
932 m_fields[1]->GetFwdBwdTracePhys(inarray[0], Fwd[0], Bwd[0]);
933 m_fields[2]->GetFwdBwdTracePhys(inarray[1], Fwd[1], Bwd[1]);
938 for (i = 0; i < nTraceNumPoints; ++i)
940 numfluxX[i] = 0.5 * (Fwd[0][i] + Bwd[0][i]);
941 numfluxY[i] = 0.5 * (Fwd[1][i] + Bwd[1][i]);
949 boost::ignore_unused(time);
954 for (
int n = 0; n <
m_fields[0]->GetBndConditions().size(); ++n)
958 if (boost::iequals(
m_fields[0]->GetBndConditions()[n]->GetUserDefined(),
965 if (
m_fields[0]->GetBndConditions()[n]->IsTimeDependent())
967 ASSERTL0(
false,
"time-dependent BC not implemented for Boussinesq");
969 cnt +=
m_fields[0]->GetBndCondExpansions()[n]->GetExpSize();
985 for (
int i = 0; i < nvariables; ++i)
988 m_fields[i]->ExtractTracePhys(inarray[i], Fwd[i]);
993 int e, id1, id2, npts;
995 m_fields[0]->GetBndCondExpansions()[bcRegion];
996 for (e = 0; e < bcexp->GetExpSize(); ++e)
998 npts = bcexp->GetExp(e)->GetTotPoints();
999 id1 = bcexp->GetPhys_Offset(e);
1000 id2 =
m_fields[0]->GetTrace()->GetPhys_Offset(
1001 m_fields[0]->GetTraceMap()->GetBndCondIDToGlobalTraceID(cnt + e));
1007 ASSERTL0(
false,
"1D not yet implemented for Boussinesq");
1018 &tmp_n[0], 1, &tmp_n[0], 1);
1023 &tmp_t[0], 1, &tmp_t[0], 1);
1032 &Fwd[0][id2], 1, &Fwd[0][id2], 1);
1037 &Fwd[1][id2], 1, &Fwd[1][id2], 1);
1041 ASSERTL0(
false,
"3D not implemented for Boussinesq equations");
1044 ASSERTL0(
false,
"Illegal expansion dimension");
1048 bcexp =
m_fields[1]->GetBndCondExpansions()[bcRegion];
1049 Vmath::Vcopy(npts, &Fwd[0][id2], 1, &(bcexp->UpdatePhys())[id1], 1);
1051 bcexp =
m_fields[2]->GetBndCondExpansions()[bcRegion];
1052 Vmath::Vcopy(npts, &Fwd[1][id2], 1, &(bcexp->UpdatePhys())[id1], 1);
1059 boost::ignore_unused(time);
1064 for (
int n = 0; n <
m_fields[0]->GetBndConditions().size(); ++n)
1068 if (boost::iequals(
m_fields[0]->GetBndConditions()[n]->GetUserDefined(),
1074 if (
m_fields[0]->GetBndConditions()[n]->IsTimeDependent())
1079 cnt +=
m_fields[0]->GetBndCondExpansions()[n]->GetExpSize() - 1;
1090 m_fields[0]->ExtractTracePhys(inarray,
z);
1094 int e, id1, id2, npts;
1096 m_fields[0]->GetBndCondExpansions()[bcRegion];
1098 for (e = 0; e < bcexp->GetExpSize(); ++e)
1100 npts = bcexp->GetExp(e)->GetTotPoints();
1101 id1 = bcexp->GetPhys_Offset(e);
1102 id2 =
m_fields[0]->GetTrace()->GetPhys_Offset(
1103 m_fields[0]->GetTraceMap()->GetBndCondIDToGlobalTraceID(cnt + e));
1107 bcexp =
m_fields[1]->GetBndCondExpansions()[bcRegion];
1108 Vmath::Vcopy(npts, &
z[id2], 1, &(bcexp->UpdatePhys())[id1], 1);
1132 m_fields[1]->GetFwdBwdTracePhys(physfield, Fwd[0], Bwd[0]);
1137 for (i = 0; i < nTraceNumPoints; ++i)
1139 outX[i] = 0.5 * (Fwd[0][i] + Bwd[0][i]);
1140 outY[i] = 0.5 * (Fwd[0][i] + Bwd[0][i]);
1162 for (
int i = 0; i < nq; i++)
1165 amp * pow((1.0 / cosh(
sqrt(0.75 * (amp / (
d *
d *
d))) *
1166 (
A * (x0[i] + x_offset) - C * time))),
1170 pow((1.0 / cosh(
sqrt(0.75 * (amp / (
d *
d *
d))) *
1171 (
A * (x0[i] + x_offset) - C * time))),
1183 for (
int i = 0; i < 4; ++i)
1195 bool dumpInitialConditions,
1198 boost::ignore_unused(domain);
1215 if (dumpInitialConditions)
#define ASSERTL0(condition, msg)
tKey RegisterCreatorFunction(tKey idKey, CreatorFunction classCreator, std::string pDesc="")
Register a class with the factory.
tBaseSharedPtr CreateInstance(tKey idKey, tParam... args)
Create an instance of the class referred to by idKey.
void DefineProjection(FuncPointerT func, ObjectPointerT obj)
void DefineOdeRhs(FuncPointerT func, ObjectPointerT obj)
void DoOdeRhs(const Array< OneD, const Array< OneD, NekDouble > > &inarray, Array< OneD, Array< OneD, NekDouble > > &outarray, const NekDouble time)
virtual void v_SetInitialConditions(NekDouble initialtime=0.0, bool dumpInitialConditions=true, const int domain=0) override
Set the initial conditions.
virtual void v_PrimitiveToConservative() override
static SolverUtils::EquationSystemSharedPtr create(const LibUtilities::SessionReaderSharedPtr &pSession, const SpatialDomains::MeshGraphSharedPtr &pGraph)
Creates an instance of this class.
virtual void v_ConservativeToPrimitive() override
void DoOdeProjection(const Array< OneD, const Array< OneD, NekDouble > > &inarray, Array< OneD, Array< OneD, NekDouble > > &outarray, const NekDouble time)
void SetBoundaryConditionsForcing(Array< OneD, Array< OneD, NekDouble > > &inarray, NekDouble time)
void SetBoundaryConditions(Array< OneD, Array< OneD, NekDouble > > &physarray, NekDouble time)
void WallBoundaryForcing(int bcRegion, int cnt, Array< OneD, Array< OneD, NekDouble > > &inarray)
virtual void v_GenerateSummary(SolverUtils::SummaryList &s) override
Print a summary of time stepping parameters.
ProblemType m_problemType
void LaitoneSolitaryWave(NekDouble amp, NekDouble d, NekDouble time, NekDouble x_offset)
void AddVariableDepth(const Array< OneD, const Array< OneD, NekDouble > > &physarray, Array< OneD, Array< OneD, NekDouble > > &outarray)
static std::string className
Name of class.
void GetFluxVector(const Array< OneD, const Array< OneD, NekDouble > > &physfield, Array< OneD, Array< OneD, Array< OneD, NekDouble > > > &flux)
void WallBoundary(int bcRegion, int cnt, Array< OneD, Array< OneD, NekDouble > > &Fwd, Array< OneD, Array< OneD, NekDouble > > &physarray)
Wall boundary condition.
void NumericalFluxForcing(const Array< OneD, const Array< OneD, NekDouble > > &inarray, Array< OneD, NekDouble > &numfluxX, Array< OneD, NekDouble > &numfluxY)
void SetBoundaryConditionsContVariables(Array< OneD, NekDouble > &inarray, NekDouble time)
void AddCoriolis(const Array< OneD, const Array< OneD, NekDouble > > &physarray, Array< OneD, Array< OneD, NekDouble > > &outarray)
void GetVelocityVector(const Array< OneD, Array< OneD, NekDouble > > &physfield, Array< OneD, Array< OneD, NekDouble > > &velocity)
Compute the velocity field given the momentum .
void WallBoundaryContVariables(int bcRegion, int cnt, Array< OneD, NekDouble > &inarray)
void NumericalFluxConsVariables(Array< OneD, NekDouble > &physfield, Array< OneD, NekDouble > &outX, Array< OneD, NekDouble > &outY)
StdRegions::ConstFactorMap m_factors
void WallBoundary2D(int bcRegion, int cnt, Array< OneD, Array< OneD, NekDouble > > &Fwd, Array< OneD, Array< OneD, NekDouble > > &physarray)
virtual void v_InitObject(bool DeclareFields=true) override
Init object for UnsteadySystem class.
NonlinearPeregrine(const LibUtilities::SessionReaderSharedPtr &pSession, const SpatialDomains::MeshGraphSharedPtr &pGraph)
virtual ~NonlinearPeregrine()
problem type selector
void WCESolve(Array< OneD, NekDouble > &fce, NekDouble lambda)
Base class for unsteady solvers.
NekDouble m_g
Acceleration of gravity.
SolverUtils::RiemannSolverSharedPtr m_riemannSolver
Array< OneD, Array< OneD, NekDouble > > m_bottomSlope
const Array< OneD, NekDouble > & GetDepth()
SolverUtils::AdvectionSharedPtr m_advection
void PrimitiveToConservative()
bool m_constantDepth
Indicates if constant depth case.
virtual void v_GenerateSummary(SolverUtils::SummaryList &s) override
Print a summary of time stepping parameters.
Array< OneD, NekDouble > m_coriolis
Coriolis force.
Array< OneD, NekDouble > m_depth
Still water depth.
virtual void v_InitObject(bool DeclareFields=true) override
Init object for UnsteadySystem class.
const Array< OneD, const Array< OneD, NekDouble > > & GetNormals()
const Array< OneD, const Array< OneD, NekDouble > > & GetVecLocs()
void ConservativeToPrimitive()
int m_spacedim
Spatial dimension (>= expansion dim).
int m_expdim
Expansion dimension.
virtual SOLVER_UTILS_EXPORT void v_SetInitialConditions(NekDouble initialtime=0.0, bool dumpInitialConditions=true, const int domain=0)
SOLVER_UTILS_EXPORT int GetTraceTotPoints()
Array< OneD, MultiRegions::ExpListSharedPtr > m_fields
Array holding all dependent variables.
SOLVER_UTILS_EXPORT void Checkpoint_Output(const int n)
Write checkpoint file of m_fields.
LibUtilities::SessionReaderSharedPtr m_session
The session reader.
Array< OneD, Array< OneD, NekDouble > > m_traceNormals
Array holding trace normals for DG simulations in the forwards direction.
SOLVER_UTILS_EXPORT int GetNpoints()
SOLVER_UTILS_EXPORT int GetNcoeffs()
int m_nchk
Number of checkpoints written so far.
enum MultiRegions::ProjectionType m_projectionType
Type of projection; e.g continuous or discontinuous.
SOLVER_UTILS_EXPORT void SetBoundaryConditions(NekDouble time)
Evaluates the boundary conditions at the given time.
SOLVER_UTILS_EXPORT int GetTotPoints()
LibUtilities::TimeIntegrationSchemeOperators m_ode
The time integration scheme operators to use.
bool m_explicitAdvection
Indicates if explicit or implicit treatment of advection is used.
std::shared_ptr< SessionReader > SessionReaderSharedPtr
@ eMixed_CG_Discontinuous
std::shared_ptr< ExpList > ExpListSharedPtr
Shared pointer to an ExpList object.
AdvectionFactory & GetAdvectionFactory()
Gets the factory for initialising advection objects.
std::vector< std::pair< std::string, std::string > > SummaryList
EquationSystemFactory & GetEquationSystemFactory()
void AddSummaryItem(SummaryList &l, const std::string &name, const std::string &value)
Adds a summary item to the summary info list.
RiemannSolverFactory & GetRiemannSolverFactory()
std::shared_ptr< MeshGraph > MeshGraphSharedPtr
std::vector< double > z(NPUPPER)
std::vector< double > d(NPUPPER *NPUPPER)
The above copyright notice and this permission notice shall be included.
const char *const ProblemTypeMap[]
@ SIZE_ProblemType
Length of enum list.
@ eSolitaryWave
First order Laitone solitary wave.
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.
void Neg(int n, T *x, const int incx)
Negate x = -x.
void Vvtvp(int n, const T *w, const int incw, const T *x, const int incx, const T *y, const int incy, T *z, const int incz)
vvtvp (vector times vector plus vector): z = w*x + y
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.
void Vvtvm(int n, const T *w, const int incw, const T *x, const int incx, const T *y, const int incy, T *z, const int incz)
vvtvm (vector times vector minus vector): z = w*x - y
void Smul(int n, const T alpha, const T *x, const int incx, T *y, const int incy)
Scalar multiply y = alpha*x.
void Vdiv(int n, const T *x, const int incx, const T *y, const int incy, T *z, const int incz)
Multiply vector z = x/y.
void Sadd(int n, const T alpha, const T *x, const int incx, T *y, const int incy)
Add scalar y = alpha + x.
void Vvtvvtp(int n, const T *v, int incv, const T *w, int incw, const T *x, int incx, const T *y, int incy, T *z, int incz)
vvtvvtp (vector times vector plus vector times vector):
void Vcopy(int n, const T *x, const int incx, T *y, const int incy)
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.
scalarT< T > sqrt(scalarT< T > in)