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)
Array< OneD, NekDouble > m_coriolis
Coriolis force.
void SetBoundaryConditionsContVariables(Array< OneD, NekDouble > &inarray, NekDouble time)
#define ASSERTL0(condition, msg)
std::shared_ptr< MeshGraph > MeshGraphSharedPtr
void NumericalFluxForcing(const Array< OneD, const Array< OneD, NekDouble > > &inarray, Array< OneD, NekDouble > &numfluxX, Array< OneD, NekDouble > &numfluxY)
void PrimitiveToConservative()
Base class for unsteady solvers.
Array< OneD, NekDouble > m_depth
Still water depth.
void GetFluxVector(const Array< OneD, const Array< OneD, NekDouble > > &physfield, Array< OneD, Array< OneD, Array< OneD, NekDouble > > > &flux)
std::shared_ptr< ExpList > ExpListSharedPtr
Shared pointer to an ExpList object.
LibUtilities::TimeIntegrationSchemeOperators m_ode
The time integration scheme operators to use.
void WallBoundaryForcing(int bcRegion, int cnt, Array< OneD, Array< OneD, NekDouble > > &inarray)
std::vector< std::pair< std::string, std::string > > SummaryList
int m_expdim
Expansion dimension.
ProblemType m_problemType
SOLVER_UTILS_EXPORT void Checkpoint_Output(const int n)
Write checkpoint file of m_fields.
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
enum MultiRegions::ProjectionType m_projectionType
Type of projection; e.g continuous or discontinuous.
const Array< OneD, const Array< OneD, NekDouble > > & GetVecLocs()
SolverUtils::AdvectionSharedPtr m_advection
void DoOdeProjection(const Array< OneD, const Array< OneD, NekDouble > > &inarray, Array< OneD, Array< OneD, NekDouble > > &outarray, const NekDouble time)
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 SetBoundaryConditions(Array< OneD, Array< OneD, NekDouble > > &physarray, NekDouble time)
const Array< OneD, const Array< OneD, NekDouble > > & GetNormals()
const Array< OneD, NekDouble > & GetDepth()
SOLVER_UTILS_EXPORT int GetTotPoints()
StdRegions::ConstFactorMap m_factors
virtual void v_SetInitialConditions(NekDouble initialtime=0.0, bool dumpInitialConditions=true, const int domain=0)
Set the initial conditions.
void ConservativeToPrimitive()
void NumericalFluxConsVariables(Array< OneD, NekDouble > &physfield, Array< OneD, NekDouble > &outX, Array< OneD, NekDouble > &outY)
Array< OneD, Array< OneD, NekDouble > > m_traceNormals
Array holding trace normals for DG simulations in the forwards direction.
virtual void v_GenerateSummary(SolverUtils::SummaryList &s)
Print a summary of time stepping parameters.
void DefineProjection(FuncPointerT func, ObjectPointerT obj)
Array< OneD, Array< OneD, NekDouble > > m_bottomSlope
virtual ~NonlinearPeregrine()
problem type selector
tBaseSharedPtr CreateInstance(tKey idKey, tParam... args)
Create an instance of the class referred to by idKey.
virtual void v_InitObject()
Init object for UnsteadySystem class.
void WallBoundary(int bcRegion, int cnt, Array< OneD, Array< OneD, NekDouble > > &Fwd, Array< OneD, Array< OneD, NekDouble > > &physarray)
Wall boundary condition.
void Smul(int n, const T alpha, const T *x, const int incx, T *y, const int incy)
Scalar multiply y = alpha*y.
bool m_explicitAdvection
Indicates if explicit or implicit treatment of advection is used.
virtual void v_ConservativeToPrimitive()
void DefineOdeRhs(FuncPointerT func, ObjectPointerT obj)
virtual void v_InitObject()
Init object for UnsteadySystem class.
const char *const ProblemTypeMap[]
void AddSummaryItem(SummaryList &l, const std::string &name, const std::string &value)
Adds a summary item to the summary info list.
RiemannSolverFactory & GetRiemannSolverFactory()
void WCESolve(Array< OneD, NekDouble > &fce, NekDouble lambda)
SolverUtils::RiemannSolverSharedPtr m_riemannSolver
int m_spacedim
Spatial dimension (>= expansion dim).
AdvectionFactory & GetAdvectionFactory()
Gets the factory for initialising advection objects.
virtual void v_GenerateSummary(SolverUtils::SummaryList &s)
Print a summary of time stepping parameters.
void DoOdeRhs(const Array< OneD, const Array< OneD, NekDouble > > &inarray, Array< OneD, Array< OneD, NekDouble > > &outarray, const NekDouble time)
void Neg(int n, T *x, const int incx)
Negate x = -x.
virtual SOLVER_UTILS_EXPORT void v_SetInitialConditions(NekDouble initialtime=0.0, bool dumpInitialConditions=true, const int domain=0)
void SetBoundaryConditionsForcing(Array< OneD, Array< OneD, NekDouble > > &inarray, NekDouble time)
void Sadd(int n, const T alpha, const T *x, const int incx, T *y, const int incy)
Add vector y = alpha + x.
EquationSystemFactory & GetEquationSystemFactory()
void AddVariableDepth(const Array< OneD, const Array< OneD, NekDouble > > &physarray, Array< OneD, Array< OneD, NekDouble > > &outarray)
SOLVER_UTILS_EXPORT void SetBoundaryConditions(NekDouble time)
Evaluates the boundary conditions at the given time.
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.
SOLVER_UTILS_EXPORT int GetTraceTotPoints()
void WallBoundary2D(int bcRegion, int cnt, Array< OneD, Array< OneD, NekDouble > > &Fwd, Array< OneD, Array< OneD, NekDouble > > &physarray)
SOLVER_UTILS_EXPORT int GetNpoints()
Array< OneD, MultiRegions::ExpListSharedPtr > m_fields
Array holding all dependent variables.
LibUtilities::SessionReaderSharedPtr m_session
The session reader.
void GetVelocityVector(const Array< OneD, Array< OneD, NekDouble > > &physfield, Array< OneD, Array< OneD, NekDouble > > &velocity)
Compute the velocity field given the momentum .
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
virtual void v_PrimitiveToConservative()
SOLVER_UTILS_EXPORT int GetNcoeffs()
First order Laitone solitary wave.
bool m_constantDepth
Indicates if constant depth case.
tKey RegisterCreatorFunction(tKey idKey, CreatorFunction classCreator, std::string pDesc="")
Register a class with the factory.
void WallBoundaryContVariables(int bcRegion, int cnt, Array< OneD, NekDouble > &inarray)
void AddCoriolis(const Array< OneD, const Array< OneD, NekDouble > > &physarray, Array< OneD, Array< OneD, NekDouble > > &outarray)
NekDouble m_g
Acceleration of gravity.
void Vcopy(int n, const T *x, const int incx, T *y, const int incy)
std::shared_ptr< SessionReader > SessionReaderSharedPtr
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 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.
static FlagList NullFlagList
An empty flag list.
void LaitoneSolitaryWave(NekDouble amp, NekDouble d, NekDouble time, NekDouble x_offset)