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.size();
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.size();
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");
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().size(); ++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.size();
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()->GetBndCondIDToGlobalTraceID(cnt + e));
609 &tmp[0], 1, &tmp[0], 1);
619 &Fwd[1 + i][id2], 1, &Fwd[1 + i][id2], 1);
623 for (i = 0; i < nvariables; ++i)
625 bcexp =
m_fields[i]->GetBndCondExpansions()[bcRegion];
626 Vmath::Vcopy(npts, &Fwd[i][id2], 1, &(bcexp->UpdatePhys())[id1], 1);
637 boost::ignore_unused(physarray);
644 int e, id1, id2, npts;
646 m_fields[0]->GetBndCondExpansions()[bcRegion];
648 for (e = 0; e < bcexp->GetExpSize();
651 npts = bcexp->GetExp(e)->GetNumPoints(0);
652 id1 = bcexp->GetPhys_Offset(e);
653 id2 =
m_fields[0]->GetTrace()->GetPhys_Offset(
654 m_fields[0]->GetTraceMap()->GetBndCondIDToGlobalTraceID(cnt + e));
672 &tmp_n[0], 1, &tmp_n[0], 1);
677 &tmp_t[0], 1, &tmp_t[0], 1);
686 &Fwd[1][id2], 1, &Fwd[1][id2], 1);
691 &Fwd[2][id2], 1, &Fwd[2][id2], 1);
696 "3D not implemented for Shallow Water Equations");
699 ASSERTL0(
false,
"Illegal expansion dimension");
703 for (i = 0; i < nvariables; ++i)
705 bcexp =
m_fields[i]->GetBndCondExpansions()[bcRegion];
706 Vmath::Vcopy(npts, &Fwd[i][id2], 1, &(bcexp->UpdatePhys())[id1], 1);
717 int nq =
m_fields[0]->GetTotPoints();
733 Vmath::Vmul(nq, physfield[0], 1, physfield[0], 1, tmp, 1);
741 Vmath::Vmul(nq, velocity[j], 1, physfield[i + 1], 1,
746 Vmath::Vadd(nq, flux[i + 1][i], 1, tmp, 1, flux[i + 1][i], 1);
757 if (physin.get() == physout.get())
761 for (
int i = 0; i < 3; ++i)
772 Vmath::Vdiv(nq, tmp[1], 1, tmp[0], 1, physout[1], 1);
775 Vmath::Vdiv(nq, tmp[2], 1, tmp[0], 1, physout[2], 1);
783 Vmath::Vdiv(nq, physin[1], 1, physin[0], 1, physout[1], 1);
786 Vmath::Vdiv(nq, physin[2], 1, physin[0], 1, physout[2], 1);
814 if (physin.get() == physout.get())
818 for (
int i = 0; i < 3; ++i)
829 Vmath::Vmul(nq, physout[0], 1, tmp[1], 1, physout[1], 1);
832 Vmath::Vmul(nq, physout[0], 1, tmp[2], 1, physout[2], 1);
841 Vmath::Vmul(nq, physout[0], 1, physin[1], 1, physout[1], 1);
844 Vmath::Vmul(nq, physout[0], 1, physin[2], 1, physout[2], 1);
878 const int npts = physfield[0].size();
882 Vmath::Vdiv(npts, physfield[1 + i], 1, physfield[0], 1, velocity[i], 1);
903 for (
int j = 0; j < nq; j++)
905 (
m_fields[3]->UpdatePhys())[j] = fce[j];
934 for (i = 0; i < 2; ++i)
945 m_fields[1]->GetFwdBwdTracePhys(inarray[0], Fwd[0], Bwd[0]);
946 m_fields[2]->GetFwdBwdTracePhys(inarray[1], Fwd[1], Bwd[1]);
951 for (i = 0; i < nTraceNumPoints; ++i)
953 numfluxX[i] = 0.5 * (Fwd[0][i] + Bwd[0][i]);
954 numfluxY[i] = 0.5 * (Fwd[1][i] + Bwd[1][i]);
963 boost::ignore_unused(time);
968 for (
int n = 0; n <
m_fields[0]->GetBndConditions().size(); ++n)
972 if (boost::iequals(
m_fields[0]->GetBndConditions()[n]->GetUserDefined(),
"Wall"))
978 if (
m_fields[0]->GetBndConditions()[n]->IsTimeDependent())
980 ASSERTL0(
false,
"time-dependent BC not implemented for Boussinesq");
982 cnt +=
m_fields[0]->GetBndCondExpansions()[n]->GetExpSize();
1000 for (
int i = 0; i < nvariables; ++i)
1003 m_fields[i]->ExtractTracePhys(inarray[i], Fwd[i]);
1008 int e, id1, id2, npts;
1010 m_fields[0]->GetBndCondExpansions()[bcRegion];
1011 for (e = 0; e < bcexp->GetExpSize(); ++e)
1013 npts = bcexp->GetExp(e)->GetTotPoints();
1014 id1 = bcexp->GetPhys_Offset(e);
1015 id2 =
m_fields[0]->GetTrace()->GetPhys_Offset(
1016 m_fields[0]->GetTraceMap()->GetBndCondIDToGlobalTraceID(cnt + e));
1022 ASSERTL0(
false,
"1D not yet implemented for Boussinesq");
1033 &tmp_n[0], 1, &tmp_n[0], 1);
1038 &tmp_t[0], 1, &tmp_t[0], 1);
1047 &Fwd[0][id2], 1, &Fwd[0][id2], 1);
1052 &Fwd[1][id2], 1, &Fwd[1][id2], 1);
1056 ASSERTL0(
false,
"3D not implemented for Boussinesq equations");
1059 ASSERTL0(
false,
"Illegal expansion dimension");
1063 bcexp =
m_fields[1]->GetBndCondExpansions()[bcRegion];
1064 Vmath::Vcopy(npts, &Fwd[0][id2], 1, &(bcexp->UpdatePhys())[id1], 1);
1066 bcexp =
m_fields[2]->GetBndCondExpansions()[bcRegion];
1067 Vmath::Vcopy(npts, &Fwd[1][id2], 1, &(bcexp->UpdatePhys())[id1], 1);
1075 boost::ignore_unused(time);
1080 for (
int n = 0; n <
m_fields[0]->GetBndConditions().size(); ++n)
1084 if(boost::iequals(
m_fields[0]->GetBndConditions()[n]->GetUserDefined(),
"Wall"))
1089 if (
m_fields[0]->GetBndConditions()[n]->IsTimeDependent())
1094 cnt +=
m_fields[0]->GetBndCondExpansions()[n]->GetExpSize() - 1;
1107 m_fields[0]->ExtractTracePhys(inarray, z);
1111 int e, id1, id2, npts;
1113 m_fields[0]->GetBndCondExpansions()[bcRegion];
1115 for (e = 0; e < bcexp->GetExpSize(); ++e)
1117 npts = bcexp->GetExp(e)->GetTotPoints();
1118 id1 = bcexp->GetPhys_Offset(e);
1119 id2 =
m_fields[0]->GetTrace()->GetPhys_Offset(
1120 m_fields[0]->GetTraceMap()->GetBndCondIDToGlobalTraceID(cnt + e));
1124 bcexp =
m_fields[1]->GetBndCondExpansions()[bcRegion];
1125 Vmath::Vcopy(npts, &z[id2], 1, &(bcexp->UpdatePhys())[id1], 1);
1150 m_fields[1]->GetFwdBwdTracePhys(physfield, Fwd[0], Bwd[0]);
1155 for (i = 0; i < nTraceNumPoints; ++i)
1157 outX[i] = 0.5 * (Fwd[0][i] + Bwd[0][i]);
1158 outY[i] = 0.5 * (Fwd[0][i] + Bwd[0][i]);
1183 for (
int i = 0; i < nq; i++)
1185 (
m_fields[0]->UpdatePhys())[i] = amp * pow((1.0 / cosh(
1186 sqrt(0.75 * (amp / (d * d * d))) *
1187 (
A * (x0[i] + x_offset) - C * time))), 2.0);
1188 (
m_fields[1]->UpdatePhys())[i] = (amp / d) * pow((1.0 / cosh(
1189 sqrt(0.75 * (amp / (d * d * d))) *
1190 (
A * (x0[i] + x_offset) - C * time)
1201 for (
int i = 0; i < 4; ++i)
1215 bool dumpInitialConditions,
1218 boost::ignore_unused(domain);
1234 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
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 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*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 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.
scalarT< T > sqrt(scalarT< T > in)