39 #include <boost/core/ignore_unused.hpp>
40 #include <boost/algorithm/string.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.");
192 m_fields[0]->IProductWRTBase(tmp, mod);
193 m_fields[0]->MultiplyByElmtInvMass(mod, mod);
195 Vmath::Vadd(nq, tmp, 1, outarray[1], 1, outarray[1], 1);
200 m_fields[0]->IProductWRTBase(tmp, mod);
201 m_fields[0]->MultiplyByElmtInvMass(mod, mod);
203 Vmath::Vadd(nq, tmp, 1, outarray[2], 1, outarray[2], 1);
211 Vmath::Vadd(nq, tmp, 1, outarray[1], 1, outarray[1], 1);
216 Vmath::Vadd(nq, tmp, 1, outarray[2], 1, outarray[2], 1);
220 ASSERTL0(
false,
"Unknown projection scheme for the NonlinearSWE");
246 m_fields[0]->IProductWRTBase(tmp, mod);
247 m_fields[0]->MultiplyByElmtInvMass(mod, mod);
249 Vmath::Vadd(nq, tmp, 1, outarray[i + 1], 1, outarray[i + 1], 1);
260 Vmath::Vadd(nq, tmp, 1, outarray[i + 1], 1, outarray[i + 1], 1);
265 ASSERTL0(
false,
"Unknown projection scheme for the NonlinearSWE");
276 int nvariables = inarray.num_elements();
289 for (i = 0; i < nvariables; ++i)
307 for (i = 0; i < nvariables - 1; ++i)
327 "Variable depth not supported for the Peregrine "
341 m_fields[0]->IProductWRTBase(outarray[1], modarray[1]);
342 m_fields[0]->IProductWRTBase(outarray[2], modarray[2]);
352 m_fields[0]->MultiplyByElmtInvMass(modarray[1], modarray[1]);
353 m_fields[0]->MultiplyByElmtInvMass(modarray[2], modarray[2]);
365 for (i = 0; i < 2; ++i)
405 m_fields[0]->IProductWRTDerivBase(0, physfield[0], coeffsfield[0]);
406 m_fields[0]->IProductWRTDerivBase(1, physfield[1], coeffsfield[1]);
407 Vmath::Vadd(ncoeffs, coeffsfield[0], 1, coeffsfield[1], 1,
414 m_fields[0]->AddTraceIntegral(upwindX[0], upwindY[0],
416 m_fields[0]->MultiplyByElmtInvMass(coeffsfield[0], coeffsfield[0]);
417 m_fields[0]->BwdTrans(coeffsfield[0], physfield[0]);
419 Vmath::Smul(nq, -invgamma, physfield[0], 1, physfield[0], 1);
447 Vmath::Smul(nq, gamma, physfield[0], 1, physfield[0], 1);
452 m_fields[0]->IProductWRTDerivBase(0, physfield[0], coeffsfield[0]);
453 m_fields[1]->IProductWRTDerivBase(1, physfield[0], coeffsfield[1]);
464 m_fields[0]->AddTraceIntegral(upwindX[0], uptemp,
466 m_fields[0]->AddTraceIntegral(uptemp, upwindY[0],
470 Vmath::Vadd(ncoeffs, f1, 1, coeffsfield[0], 1, modarray[1], 1);
471 Vmath::Vadd(ncoeffs, f2, 1, coeffsfield[1], 1, modarray[2], 1);
473 m_fields[1]->MultiplyByElmtInvMass(modarray[1], modarray[1]);
474 m_fields[2]->MultiplyByElmtInvMass(modarray[2], modarray[2]);
476 m_fields[1]->BwdTrans(modarray[1], outarray[1]);
477 m_fields[2]->BwdTrans(modarray[2], outarray[2]);
486 ASSERTL0(
false,
"Unknown projection scheme for the Peregrine");
489 ASSERTL0(
false,
"Unknown projection scheme for the NonlinearSWE");
500 int nvariables = inarray.num_elements();
510 for (i = 0; i < nvariables; ++i)
525 for (i = 0; i < nvariables; ++i)
527 m_fields[i]->FwdTrans(inarray[i], coeffs);
528 m_fields[i]->BwdTrans_IterPerExp(coeffs, outarray[i]);
533 ASSERTL0(
false,
"Unknown projection scheme");
544 int nvariables =
m_fields.num_elements();
551 for (
int i = 0; i < nvariables; ++i)
554 m_fields[i]->ExtractTracePhys(inarray[i], Fwd[i]);
558 for (
int n = 0; n <
m_fields[0]->GetBndConditions().num_elements(); ++n)
562 if (boost::iequals(
m_fields[0]->GetBndConditions()[n]->GetUserDefined(),
"Wall"))
568 if (
m_fields[0]->GetBndConditions()[n]->IsTimeDependent())
570 for (
int i = 0; i < nvariables; ++i)
572 m_fields[i]->EvaluateBoundaryConditions(time);
575 cnt +=
m_fields[0]->GetBndCondExpansions()[n]->GetExpSize();
588 int nvariables = physarray.num_elements();
592 int e, id1, id2, npts;
594 m_fields[0]->GetBndCondExpansions()[bcRegion];
595 for (e = 0; e < bcexp->GetExpSize(); ++e)
597 npts = bcexp->GetExp(e)->GetTotPoints();
598 id1 = bcexp->GetPhys_Offset(e);
599 id2 =
m_fields[0]->GetTrace()->GetPhys_Offset(
600 m_fields[0]->GetTraceMap()->GetBndCondCoeffsToGlobalCoeffsMap(
610 &tmp[0], 1, &tmp[0], 1);
620 &Fwd[1 + i][id2], 1, &Fwd[1 + i][id2], 1);
624 for (i = 0; i < nvariables; ++i)
626 bcexp =
m_fields[i]->GetBndCondExpansions()[bcRegion];
627 Vmath::Vcopy(npts, &Fwd[i][id2], 1, &(bcexp->UpdatePhys())[id1], 1);
638 boost::ignore_unused(physarray);
645 int e, id1, id2, npts;
647 m_fields[0]->GetBndCondExpansions()[bcRegion];
649 for (e = 0; e < bcexp->GetExpSize();
652 npts = bcexp->GetExp(e)->GetNumPoints(0);
653 id1 = bcexp->GetPhys_Offset(e);
654 id2 =
m_fields[0]->GetTrace()->GetPhys_Offset(
655 m_fields[0]->GetTraceMap()->GetBndCondCoeffsToGlobalCoeffsMap(
674 &tmp_n[0], 1, &tmp_n[0], 1);
679 &tmp_t[0], 1, &tmp_t[0], 1);
688 &Fwd[1][id2], 1, &Fwd[1][id2], 1);
693 &Fwd[2][id2], 1, &Fwd[2][id2], 1);
698 "3D not implemented for Shallow Water Equations");
701 ASSERTL0(
false,
"Illegal expansion dimension");
705 for (i = 0; i < nvariables; ++i)
707 bcexp =
m_fields[i]->GetBndCondExpansions()[bcRegion];
708 Vmath::Vcopy(npts, &Fwd[i][id2], 1, &(bcexp->UpdatePhys())[id1], 1);
719 int nq =
m_fields[0]->GetTotPoints();
735 Vmath::Vmul(nq, physfield[0], 1, physfield[0], 1, tmp, 1);
743 Vmath::Vmul(nq, velocity[j], 1, physfield[i + 1], 1,
748 Vmath::Vadd(nq, flux[i + 1][i], 1, tmp, 1, flux[i + 1][i], 1);
759 if (physin.get() == physout.get())
763 for (
int i = 0; i < 3; ++i)
774 Vmath::Vdiv(nq, tmp[1], 1, tmp[0], 1, physout[1], 1);
777 Vmath::Vdiv(nq, tmp[2], 1, tmp[0], 1, physout[2], 1);
785 Vmath::Vdiv(nq, physin[1], 1, physin[0], 1, physout[1], 1);
788 Vmath::Vdiv(nq, physin[2], 1, physin[0], 1, physout[2], 1);
816 if (physin.get() == physout.get())
820 for (
int i = 0; i < 3; ++i)
831 Vmath::Vmul(nq, physout[0], 1, tmp[1], 1, physout[1], 1);
834 Vmath::Vmul(nq, physout[0], 1, tmp[2], 1, physout[2], 1);
843 Vmath::Vmul(nq, physout[0], 1, physin[1], 1, physout[1], 1);
846 Vmath::Vmul(nq, physout[0], 1, physin[2], 1, physout[2], 1);
880 const int npts = physfield[0].num_elements();
884 Vmath::Vdiv(npts, physfield[1 + i], 1, physfield[0], 1, velocity[i], 1);
905 for (
int j = 0; j < nq; j++)
907 (
m_fields[3]->UpdatePhys())[j] = fce[j];
937 for (i = 0; i < 2; ++i)
948 m_fields[1]->GetFwdBwdTracePhys(inarray[0], Fwd[0], Bwd[0]);
949 m_fields[2]->GetFwdBwdTracePhys(inarray[1], Fwd[1], Bwd[1]);
954 for (i = 0; i < nTraceNumPoints; ++i)
956 numfluxX[i] = 0.5 * (Fwd[0][i] + Bwd[0][i]);
957 numfluxY[i] = 0.5 * (Fwd[1][i] + Bwd[1][i]);
966 boost::ignore_unused(time);
971 for (
int n = 0; n <
m_fields[0]->GetBndConditions().num_elements(); ++n)
975 if (boost::iequals(
m_fields[0]->GetBndConditions()[n]->GetUserDefined(),
"Wall"))
981 if (
m_fields[0]->GetBndConditions()[n]->IsTimeDependent())
983 ASSERTL0(
false,
"time-dependent BC not implemented for Boussinesq");
985 cnt +=
m_fields[0]->GetBndCondExpansions()[n]->GetExpSize();
1003 for (
int i = 0; i < nvariables; ++i)
1006 m_fields[i]->ExtractTracePhys(inarray[i], Fwd[i]);
1011 int e, id1, id2, npts;
1013 m_fields[0]->GetBndCondExpansions()[bcRegion];
1014 for (e = 0; e < bcexp->GetExpSize(); ++e)
1016 npts = bcexp->GetExp(e)->GetTotPoints();
1017 id1 = bcexp->GetPhys_Offset(e);
1018 id2 =
m_fields[0]->GetTrace()->GetPhys_Offset(
1019 m_fields[0]->GetTraceMap()->GetBndCondCoeffsToGlobalCoeffsMap(
1026 ASSERTL0(
false,
"1D not yet implemented for Boussinesq");
1037 &tmp_n[0], 1, &tmp_n[0], 1);
1042 &tmp_t[0], 1, &tmp_t[0], 1);
1051 &Fwd[0][id2], 1, &Fwd[0][id2], 1);
1056 &Fwd[1][id2], 1, &Fwd[1][id2], 1);
1060 ASSERTL0(
false,
"3D not implemented for Boussinesq equations");
1063 ASSERTL0(
false,
"Illegal expansion dimension");
1067 bcexp =
m_fields[1]->GetBndCondExpansions()[bcRegion];
1068 Vmath::Vcopy(npts, &Fwd[0][id2], 1, &(bcexp->UpdatePhys())[id1], 1);
1070 bcexp =
m_fields[2]->GetBndCondExpansions()[bcRegion];
1071 Vmath::Vcopy(npts, &Fwd[1][id2], 1, &(bcexp->UpdatePhys())[id1], 1);
1079 boost::ignore_unused(time);
1084 for (
int n = 0; n <
m_fields[0]->GetBndConditions().num_elements(); ++n)
1088 if(boost::iequals(
m_fields[0]->GetBndConditions()[n]->GetUserDefined(),
"Wall"))
1093 if (
m_fields[0]->GetBndConditions()[n]->IsTimeDependent())
1098 cnt +=
m_fields[0]->GetBndCondExpansions()[n]->GetExpSize() - 1;
1111 m_fields[0]->ExtractTracePhys(inarray, z);
1115 int e, id1, id2, npts;
1117 m_fields[0]->GetBndCondExpansions()[bcRegion];
1119 for (e = 0; e < bcexp->GetExpSize(); ++e)
1121 npts = bcexp->GetExp(e)->GetTotPoints();
1122 id1 = bcexp->GetPhys_Offset(e);
1123 id2 =
m_fields[0]->GetTrace()->GetPhys_Offset(
1124 m_fields[0]->GetTraceMap()->GetBndCondCoeffsToGlobalCoeffsMap(
1128 bcexp =
m_fields[1]->GetBndCondExpansions()[bcRegion];
1129 Vmath::Vcopy(npts, &z[id2], 1, &(bcexp->UpdatePhys())[id1], 1);
1154 m_fields[1]->GetFwdBwdTracePhys(physfield, Fwd[0], Bwd[0]);
1159 for (i = 0; i < nTraceNumPoints; ++i)
1161 outX[i] = 0.5 * (Fwd[0][i] + Bwd[0][i]);
1162 outY[i] = 0.5 * (Fwd[0][i] + Bwd[0][i]);
1187 for (
int i = 0; i < nq; i++)
1189 (
m_fields[0]->UpdatePhys())[i] = amp * pow((1.0 / cosh(
1190 sqrt(0.75 * (amp / (d * d * d))) *
1191 (
A * (x0[i] + x_offset) - C * time))), 2.0);
1192 (
m_fields[1]->UpdatePhys())[i] = (amp / d) * pow((1.0 / cosh(
1193 sqrt(0.75 * (amp / (d * d * d))) *
1194 (
A * (x0[i] + x_offset) - C * time)
1195 )), 2.0) * sqrt(
m_g * d);
1205 for (
int i = 0; i < 4; ++i)
1219 bool dumpInitialConditions,
1222 boost::ignore_unused(domain);
1238 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)
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)
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)
void GetFluxVector(const Array< OneD, const Array< OneD, NekDouble > > &physfield, Array< OneD, Array< OneD, Array< OneD, NekDouble > > > &flux)
virtual void v_PrimitiveToConservative()
virtual void v_GenerateSummary(SolverUtils::SummaryList &s)
Print a summary of time stepping parameters.
virtual void v_InitObject()
Init object for UnsteadySystem class.
virtual void v_ConservativeToPrimitive()
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
virtual void v_SetInitialConditions(NekDouble initialtime=0.0, bool dumpInitialConditions=true, const int domain=0)
Set the initial conditions.
void WallBoundary2D(int bcRegion, int cnt, Array< OneD, Array< OneD, NekDouble > > &Fwd, Array< OneD, Array< OneD, NekDouble > > &physarray)
virtual ~NonlinearPeregrine()
problem type selector
void WCESolve(Array< OneD, NekDouble > &fce, NekDouble lambda)
Base class for unsteady solvers.
virtual void v_InitObject()
Init object for UnsteadySystem class.
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)
Print a summary of time stepping parameters.
Array< OneD, NekDouble > m_coriolis
Coriolis force
Array< OneD, NekDouble > m_depth
Still water depth.
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
const char *const ProblemTypeMap[]
static FlagList NullFlagList
An empty flag list.
@ 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 plus 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*y.
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 vector 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.