39 #include <boost/algorithm/string.hpp>
40 #include <boost/core/ignore_unused.hpp>
50 string NonlinearPeregrine::className =
52 "NonlinearPeregrine", NonlinearPeregrine::create,
53 "Nonlinear Peregrine equations in conservative variables.");
55 NonlinearPeregrine::NonlinearPeregrine(
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)
401 m_fields[0]->IProductWRTDerivBase(0, physfield[0], coeffsfield[0]);
402 m_fields[0]->IProductWRTDerivBase(1, physfield[1], coeffsfield[1]);
403 Vmath::Vadd(ncoeffs, coeffsfield[0], 1, coeffsfield[1], 1,
410 m_fields[0]->AddTraceIntegral(upwindX[0], upwindY[0],
412 m_fields[0]->MultiplyByElmtInvMass(coeffsfield[0], coeffsfield[0]);
413 m_fields[0]->BwdTrans(coeffsfield[0], physfield[0]);
415 Vmath::Smul(nq, -invgamma, physfield[0], 1, physfield[0], 1);
443 Vmath::Smul(nq, gamma, physfield[0], 1, physfield[0], 1);
448 m_fields[0]->IProductWRTDerivBase(0, physfield[0], coeffsfield[0]);
449 m_fields[1]->IProductWRTDerivBase(1, physfield[0], coeffsfield[1]);
460 m_fields[0]->AddTraceIntegral(upwindX[0], uptemp,
462 m_fields[0]->AddTraceIntegral(uptemp, upwindY[0],
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();
505 for (i = 0; i < nvariables; ++i)
520 for (i = 0; i < nvariables; ++i)
522 m_fields[i]->FwdTrans(inarray[i], coeffs);
523 m_fields[i]->BwdTrans(coeffs, outarray[i]);
528 ASSERTL0(
false,
"Unknown projection scheme");
545 for (
int i = 0; i < nvariables; ++i)
548 m_fields[i]->ExtractTracePhys(inarray[i], Fwd[i]);
552 for (
int n = 0; n <
m_fields[0]->GetBndConditions().size(); ++n)
556 if (boost::iequals(
m_fields[0]->GetBndConditions()[n]->GetUserDefined(),
563 if (
m_fields[0]->GetBndConditions()[n]->IsTimeDependent())
565 for (
int i = 0; i < nvariables; ++i)
567 m_fields[i]->EvaluateBoundaryConditions(time);
570 cnt +=
m_fields[0]->GetBndCondExpansions()[n]->GetExpSize();
583 int nvariables = physarray.size();
587 int e, id1, id2, npts;
589 m_fields[0]->GetBndCondExpansions()[bcRegion];
590 for (e = 0; e < bcexp->GetExpSize(); ++e)
592 npts = bcexp->GetExp(e)->GetTotPoints();
593 id1 = bcexp->GetPhys_Offset(e);
594 id2 =
m_fields[0]->GetTrace()->GetPhys_Offset(
595 m_fields[0]->GetTraceMap()->GetBndCondIDToGlobalTraceID(cnt + e));
604 &tmp[0], 1, &tmp[0], 1);
614 &Fwd[1 + i][id2], 1, &Fwd[1 + i][id2], 1);
618 for (i = 0; i < nvariables; ++i)
620 bcexp =
m_fields[i]->GetBndCondExpansions()[bcRegion];
621 Vmath::Vcopy(npts, &Fwd[i][id2], 1, &(bcexp->UpdatePhys())[id1], 1);
630 boost::ignore_unused(physarray);
637 int e, id1, id2, npts;
639 m_fields[0]->GetBndCondExpansions()[bcRegion];
641 for (e = 0; e < bcexp->GetExpSize(); ++e)
643 npts = bcexp->GetExp(e)->GetNumPoints(0);
644 id1 = bcexp->GetPhys_Offset(e);
645 id2 =
m_fields[0]->GetTrace()->GetPhys_Offset(
646 m_fields[0]->GetTraceMap()->GetBndCondIDToGlobalTraceID(cnt + e));
664 &tmp_n[0], 1, &tmp_n[0], 1);
669 &tmp_t[0], 1, &tmp_t[0], 1);
678 &Fwd[1][id2], 1, &Fwd[1][id2], 1);
683 &Fwd[2][id2], 1, &Fwd[2][id2], 1);
688 "3D not implemented for Shallow Water Equations");
691 ASSERTL0(
false,
"Illegal expansion dimension");
695 for (i = 0; i < nvariables; ++i)
697 bcexp =
m_fields[i]->GetBndCondExpansions()[bcRegion];
698 Vmath::Vcopy(npts, &Fwd[i][id2], 1, &(bcexp->UpdatePhys())[id1], 1);
709 int nq =
m_fields[0]->GetTotPoints();
725 Vmath::Vmul(nq, physfield[0], 1, physfield[0], 1, tmp, 1);
733 Vmath::Vmul(nq, velocity[j], 1, physfield[i + 1], 1, flux[i + 1][j],
738 Vmath::Vadd(nq, flux[i + 1][i], 1, tmp, 1, flux[i + 1][i], 1);
748 if (physin.get() == physout.get())
752 for (
int i = 0; i < 3; ++i)
763 Vmath::Vdiv(nq, tmp[1], 1, tmp[0], 1, physout[1], 1);
766 Vmath::Vdiv(nq, tmp[2], 1, tmp[0], 1, physout[2], 1);
774 Vmath::Vdiv(nq, physin[1], 1, physin[0], 1, physout[1], 1);
777 Vmath::Vdiv(nq, physin[2], 1, physin[0], 1, physout[2], 1);
805 if (physin.get() == physout.get())
809 for (
int i = 0; i < 3; ++i)
820 Vmath::Vmul(nq, physout[0], 1, tmp[1], 1, physout[1], 1);
823 Vmath::Vmul(nq, physout[0], 1, tmp[2], 1, physout[2], 1);
831 Vmath::Vmul(nq, physout[0], 1, physin[1], 1, physout[1], 1);
834 Vmath::Vmul(nq, physout[0], 1, physin[2], 1, physout[2], 1);
866 const int npts = physfield[0].size();
870 Vmath::Vdiv(npts, physfield[1 + i], 1, physfield[0], 1, velocity[i], 1);
889 for (
int j = 0; j < nq; j++)
891 (
m_fields[3]->UpdatePhys())[j] = fce[j];
918 for (i = 0; i < 2; ++i)
929 m_fields[1]->GetFwdBwdTracePhys(inarray[0], Fwd[0], Bwd[0]);
930 m_fields[2]->GetFwdBwdTracePhys(inarray[1], Fwd[1], Bwd[1]);
935 for (i = 0; i < nTraceNumPoints; ++i)
937 numfluxX[i] = 0.5 * (Fwd[0][i] + Bwd[0][i]);
938 numfluxY[i] = 0.5 * (Fwd[1][i] + Bwd[1][i]);
946 boost::ignore_unused(time);
951 for (
int n = 0; n <
m_fields[0]->GetBndConditions().size(); ++n)
955 if (boost::iequals(
m_fields[0]->GetBndConditions()[n]->GetUserDefined(),
962 if (
m_fields[0]->GetBndConditions()[n]->IsTimeDependent())
964 ASSERTL0(
false,
"time-dependent BC not implemented for Boussinesq");
966 cnt +=
m_fields[0]->GetBndCondExpansions()[n]->GetExpSize();
982 for (
int i = 0; i < nvariables; ++i)
985 m_fields[i]->ExtractTracePhys(inarray[i], Fwd[i]);
990 int e, id1, id2, npts;
992 m_fields[0]->GetBndCondExpansions()[bcRegion];
993 for (e = 0; e < bcexp->GetExpSize(); ++e)
995 npts = bcexp->GetExp(e)->GetTotPoints();
996 id1 = bcexp->GetPhys_Offset(e);
997 id2 =
m_fields[0]->GetTrace()->GetPhys_Offset(
998 m_fields[0]->GetTraceMap()->GetBndCondIDToGlobalTraceID(cnt + e));
1004 ASSERTL0(
false,
"1D not yet implemented for Boussinesq");
1015 &tmp_n[0], 1, &tmp_n[0], 1);
1020 &tmp_t[0], 1, &tmp_t[0], 1);
1029 &Fwd[0][id2], 1, &Fwd[0][id2], 1);
1034 &Fwd[1][id2], 1, &Fwd[1][id2], 1);
1038 ASSERTL0(
false,
"3D not implemented for Boussinesq equations");
1041 ASSERTL0(
false,
"Illegal expansion dimension");
1045 bcexp =
m_fields[1]->GetBndCondExpansions()[bcRegion];
1046 Vmath::Vcopy(npts, &Fwd[0][id2], 1, &(bcexp->UpdatePhys())[id1], 1);
1048 bcexp =
m_fields[2]->GetBndCondExpansions()[bcRegion];
1049 Vmath::Vcopy(npts, &Fwd[1][id2], 1, &(bcexp->UpdatePhys())[id1], 1);
1056 boost::ignore_unused(time);
1061 for (
int n = 0; n <
m_fields[0]->GetBndConditions().size(); ++n)
1065 if (boost::iequals(
m_fields[0]->GetBndConditions()[n]->GetUserDefined(),
1071 if (
m_fields[0]->GetBndConditions()[n]->IsTimeDependent())
1076 cnt +=
m_fields[0]->GetBndCondExpansions()[n]->GetExpSize() - 1;
1087 m_fields[0]->ExtractTracePhys(inarray, z);
1091 int e, id1, id2, npts;
1093 m_fields[0]->GetBndCondExpansions()[bcRegion];
1095 for (e = 0; e < bcexp->GetExpSize(); ++e)
1097 npts = bcexp->GetExp(e)->GetTotPoints();
1098 id1 = bcexp->GetPhys_Offset(e);
1099 id2 =
m_fields[0]->GetTrace()->GetPhys_Offset(
1100 m_fields[0]->GetTraceMap()->GetBndCondIDToGlobalTraceID(cnt + e));
1104 bcexp =
m_fields[1]->GetBndCondExpansions()[bcRegion];
1105 Vmath::Vcopy(npts, &z[id2], 1, &(bcexp->UpdatePhys())[id1], 1);
1129 m_fields[1]->GetFwdBwdTracePhys(physfield, Fwd[0], Bwd[0]);
1134 for (i = 0; i < nTraceNumPoints; ++i)
1136 outX[i] = 0.5 * (Fwd[0][i] + Bwd[0][i]);
1137 outY[i] = 0.5 * (Fwd[0][i] + Bwd[0][i]);
1159 for (
int i = 0; i < nq; i++)
1162 amp * pow((1.0 / cosh(
sqrt(0.75 * (amp / (d * d * d))) *
1163 (
A * (x0[i] + x_offset) - C * time))),
1167 pow((1.0 / cosh(
sqrt(0.75 * (amp / (d * d * d))) *
1168 (
A * (x0[i] + x_offset) - C * time))),
1180 for (
int i = 0; i < 4; ++i)
1192 bool dumpInitialConditions,
1195 boost::ignore_unused(domain);
1211 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)
virtual void v_SetInitialConditions(NekDouble initialtime=0.0, bool dumpInitialConditions=true, const int domain=0) override
Set the initial conditions.
void SetBoundaryConditions(Array< OneD, Array< OneD, NekDouble >> &physarray, NekDouble time)
virtual void v_PrimitiveToConservative() override
void AddVariableDepth(const Array< OneD, const Array< OneD, NekDouble >> &physarray, Array< OneD, Array< OneD, NekDouble >> &outarray)
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 WallBoundary(int bcRegion, int cnt, Array< OneD, Array< OneD, NekDouble >> &Fwd, Array< OneD, Array< OneD, NekDouble >> &physarray)
Wall boundary condition.
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 DoOdeRhs(const Array< OneD, const Array< OneD, NekDouble >> &inarray, Array< OneD, Array< OneD, NekDouble >> &outarray, const NekDouble time)
void SetBoundaryConditionsContVariables(Array< OneD, NekDouble > &inarray, NekDouble time)
void GetVelocityVector(const Array< OneD, Array< OneD, NekDouble >> &physfield, Array< OneD, Array< OneD, NekDouble >> &velocity)
Compute the velocity field given the momentum .
void AddCoriolis(const Array< OneD, const Array< OneD, NekDouble >> &physarray, Array< OneD, Array< OneD, NekDouble >> &outarray)
void WallBoundaryForcing(int bcRegion, int cnt, Array< OneD, Array< OneD, NekDouble >> &inarray)
void WallBoundaryContVariables(int bcRegion, int cnt, Array< OneD, NekDouble > &inarray)
void NumericalFluxConsVariables(Array< OneD, NekDouble > &physfield, Array< OneD, NekDouble > &outX, Array< OneD, NekDouble > &outY)
void GetFluxVector(const Array< OneD, const Array< OneD, NekDouble >> &physfield, Array< OneD, Array< OneD, Array< OneD, NekDouble >>> &flux)
StdRegions::ConstFactorMap m_factors
virtual void v_InitObject(bool DeclareFields=true) override
Init object for UnsteadySystem class.
void SetBoundaryConditionsForcing(Array< OneD, Array< OneD, NekDouble >> &inarray, NekDouble time)
void WallBoundary2D(int bcRegion, int cnt, Array< OneD, Array< OneD, NekDouble >> &Fwd, Array< OneD, Array< OneD, NekDouble >> &physarray)
virtual ~NonlinearPeregrine()
problem type selector
void NumericalFluxForcing(const Array< OneD, const Array< OneD, NekDouble >> &inarray, Array< OneD, NekDouble > &numfluxX, Array< OneD, NekDouble > &numfluxY)
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()
const Array< OneD, const Array< OneD, NekDouble > > & GetNormals()
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.
void ConservativeToPrimitive()
const Array< OneD, const Array< OneD, NekDouble > > & GetVecLocs()
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()
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
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 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)