39 #include <boost/algorithm/string.hpp>
50 "Nonlinear Peregrine equations in conservative variables.");
66 if (
m_session->DefinesSolverInfo(
"PROBLEMTYPE"))
69 std::string ProblemTypeStr =
m_session->GetSolverInfo(
"PROBLEMTYPE");
91 ASSERTL0(
false,
"Implicit Peregrine not set up.");
96 if (
m_session->DefinesParameter(
"ConstDepth"))
102 ASSERTL0(
false,
"Constant Depth not specified");
112 "Continuous projection type not supported for Peregrine.");
126 m_session->LoadSolverInfo(
"AdvectionType", advName,
"WeakDG");
135 m_session->LoadSolverInfo(
"UpwindType", riemName,
"NoSolver");
158 ASSERTL0(
false,
"Unsupported projection type.");
172 const Array<
OneD,
const Array<OneD, NekDouble> > &physarray,
173 Array<
OneD, Array<OneD, NekDouble> > &outarray)
179 Array<OneD, NekDouble> tmp(nq);
180 Array<OneD, NekDouble> mod(ncoeffs);
188 m_fields[0]->IProductWRTBase(tmp, mod);
189 m_fields[0]->MultiplyByElmtInvMass(mod, mod);
191 Vmath::Vadd(nq, tmp, 1, outarray[1], 1, outarray[1], 1);
196 m_fields[0]->IProductWRTBase(tmp, mod);
197 m_fields[0]->MultiplyByElmtInvMass(mod, mod);
199 Vmath::Vadd(nq, tmp, 1, outarray[2], 1, outarray[2], 1);
207 Vmath::Vadd(nq, tmp, 1, outarray[1], 1, outarray[1], 1);
212 Vmath::Vadd(nq, tmp, 1, outarray[2], 1, outarray[2], 1);
216 ASSERTL0(
false,
"Unknown projection scheme for the NonlinearSWE");
224 const Array<
OneD,
const Array<OneD, NekDouble> > &physarray,
225 Array<
OneD, Array<OneD, NekDouble> > &outarray)
231 Array<OneD, NekDouble> tmp(nq);
232 Array<OneD, NekDouble> mod(ncoeffs);
242 m_fields[0]->IProductWRTBase(tmp, mod);
243 m_fields[0]->MultiplyByElmtInvMass(mod, mod);
245 Vmath::Vadd(nq, tmp, 1, outarray[i + 1], 1, outarray[i + 1], 1);
256 Vmath::Vadd(nq, tmp, 1, outarray[i + 1], 1, outarray[i + 1], 1);
261 ASSERTL0(
false,
"Unknown projection scheme for the NonlinearSWE");
268 const Array<
OneD,
const Array<OneD, NekDouble> >&inarray,
269 Array<
OneD, Array<OneD, NekDouble> >&outarray,
const NekDouble time)
272 int nvariables = inarray.num_elements();
284 Array<OneD, Array<OneD, NekDouble> > modarray(nvariables);
285 for (i = 0; i < nvariables; ++i)
287 modarray[i] = Array<OneD, NekDouble>(ncoeffs, 0.0);
295 Array<OneD, Array<OneD, NekDouble> > advVel;
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]);
341 Array<OneD, NekDouble> f1(ncoeffs);
342 Array<OneD, NekDouble> f2(ncoeffs);
348 m_fields[0]->MultiplyByElmtInvMass(modarray[1], modarray[1]);
349 m_fields[0]->MultiplyByElmtInvMass(modarray[2], modarray[2]);
358 Array<OneD, Array<OneD, NekDouble> > coeffsfield(2);
359 Array<OneD, Array<OneD, NekDouble> > physfield(2);
361 for (i = 0; i < 2; ++i)
363 coeffsfield[i] = Array<OneD, NekDouble>(ncoeffs);
364 physfield[i] = Array<OneD, NekDouble>(nq);
387 Array<OneD, Array<OneD, NekDouble> > upwindX(1);
388 Array<OneD, Array<OneD, NekDouble> > upwindY(1);
389 upwindX[0] = Array<OneD, NekDouble>(nTraceNumPoints);
390 upwindY[0] = Array<OneD, NekDouble>(nTraceNumPoints);
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]);
458 Array<OneD, NekDouble> uptemp(nTraceNumPoints, 0.0);
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");
491 const Array<
OneD,
const Array<OneD, NekDouble> >&inarray,
492 Array<
OneD, Array<OneD, NekDouble> >&outarray,
496 int nvariables = inarray.num_elements();
506 for (i = 0; i < nvariables; ++i)
521 for (i = 0; i < nvariables; ++i)
523 m_fields[i]->FwdTrans(inarray[i], coeffs);
524 m_fields[i]->BwdTrans_IterPerExp(coeffs, outarray[i]);
529 ASSERTL0(
false,
"Unknown projection scheme");
536 Array<
OneD, Array<OneD, NekDouble> > &inarray,
540 int nvariables =
m_fields.num_elements();
544 for (
int n = 0; n <
m_fields[0]->GetBndConditions().num_elements(); ++n)
548 if (
m_fields[0]->GetBndConditions()[n]->GetUserDefined()
555 if (
m_fields[0]->GetBndConditions()[n]->GetUserDefined()
558 for (
int i = 0; i < nvariables; ++i)
560 m_fields[i]->EvaluateBoundaryConditions(time);
563 cnt +=
m_fields[0]->GetBndCondExpansions()[n]->GetExpSize();
572 Array<
OneD, Array<OneD, NekDouble> > &physarray)
576 int nvariables = physarray.num_elements();
579 Array<OneD, Array<OneD, NekDouble> > Fwd(nvariables);
580 for (i = 0; i < nvariables; ++i)
582 Fwd[i] = Array<OneD, NekDouble>(nTracePts);
583 m_fields[i]->ExtractTracePhys(physarray[i], Fwd[i]);
588 int e, id1, id2,
npts;
590 m_fields[0]->GetBndCondExpansions()[bcRegion];
591 for (e = 0; e < bcexp->GetExpSize(); ++e)
593 npts = bcexp->GetExp(e)->GetTotPoints();
594 id1 = bcexp->GetPhys_Offset(e);
595 id2 =
m_fields[0]->GetTrace()->GetPhys_Offset(
596 m_fields[0]->GetTraceMap()->GetBndCondCoeffsToGlobalCoeffsMap(
600 Array<OneD, NekDouble> tmp(npts, 0.0);
606 &tmp[0], 1, &tmp[0], 1);
616 &Fwd[1 + i][id2], 1, &Fwd[1 + i][id2], 1);
620 for (i = 0; i < nvariables; ++i)
622 bcexp =
m_fields[i]->GetBndCondExpansions()[bcRegion];
623 Vmath::Vcopy(npts, &Fwd[i][id2], 1, &(bcexp->UpdatePhys())[id1], 1);
631 Array<
OneD, Array<OneD, NekDouble> > &physarray)
639 Array<OneD, Array<OneD, NekDouble> > Fwd(nvariables);
640 for (i = 0; i < nvariables; ++i)
642 Fwd[i] = Array<OneD, NekDouble>(nTraceNumPoints);
643 m_fields[i]->ExtractTracePhys(physarray[i], Fwd[i]);
648 int e, id1, id2,
npts;
650 m_fields[0]->GetBndCondExpansions()[bcRegion];
652 for (e = 0; e < bcexp->GetExpSize();
655 npts = bcexp->GetExp(e)->GetNumPoints(0);
656 id1 = bcexp->GetPhys_Offset(e);
657 id2 =
m_fields[0]->GetTrace()->GetPhys_Offset(
658 m_fields[0]->GetTraceMap()->GetBndCondCoeffsToGlobalCoeffsMap(
671 Array<OneD, NekDouble> tmp_n(npts);
672 Array<OneD, NekDouble> tmp_t(npts);
677 &tmp_n[0], 1, &tmp_n[0], 1);
682 &tmp_t[0], 1, &tmp_t[0], 1);
691 &Fwd[1][id2], 1, &Fwd[1][id2], 1);
696 &Fwd[2][id2], 1, &Fwd[2][id2], 1);
701 "3D not implemented for Shallow Water Equations");
704 ASSERTL0(
false,
"Illegal expansion dimension");
708 for (i = 0; i < nvariables; ++i)
710 bcexp =
m_fields[i]->GetBndCondExpansions()[bcRegion];
711 Vmath::Vcopy(npts, &Fwd[i][id2], 1, &(bcexp->UpdatePhys())[id1], 1);
718 const Array<
OneD,
const Array<OneD, NekDouble> > &physfield,
719 Array<
OneD, Array<
OneD, Array<OneD, NekDouble> > > &flux)
722 int nq =
m_fields[0]->GetTotPoints();
725 Array<OneD, Array<OneD, NekDouble> > velocity(
m_spacedim);
730 velocity[i] = Array<OneD, NekDouble>(nq);
737 Array<OneD, NekDouble> tmp(nq);
738 Vmath::Vmul(nq, physfield[0], 1, physfield[0], 1, tmp, 1);
746 Vmath::Vmul(nq, velocity[j], 1, physfield[i + 1], 1,
751 Vmath::Vadd(nq, flux[i + 1][i], 1, tmp, 1, flux[i + 1][i], 1);
757 const Array<
OneD,
const Array<OneD, NekDouble> >&physin,
758 Array<
OneD, Array<OneD, NekDouble> >&physout)
762 if (physin.get() == physout.get())
765 Array<OneD, Array<OneD, NekDouble> > tmp(3);
766 for (
int i = 0; i < 3; ++i)
769 tmp[i] = Array<OneD, NekDouble>(nq);
777 Vmath::Vdiv(nq, tmp[1], 1, tmp[0], 1, physout[1], 1);
780 Vmath::Vdiv(nq, tmp[2], 1, tmp[0], 1, physout[2], 1);
788 Vmath::Vdiv(nq, physin[1], 1, physin[0], 1, physout[1], 1);
791 Vmath::Vdiv(nq, physin[2], 1, physin[0], 1, physout[2], 1);
813 const Array<
OneD,
const Array<OneD, NekDouble> >&physin,
814 Array<
OneD, Array<OneD, NekDouble> >&physout)
819 if (physin.get() == physout.get())
822 Array<OneD, Array<OneD, NekDouble> > tmp(3);
823 for (
int i = 0; i < 3; ++i)
826 tmp[i] = Array<OneD, NekDouble>(nq);
834 Vmath::Vmul(nq, physout[0], 1, tmp[1], 1, physout[1], 1);
837 Vmath::Vmul(nq, physout[0], 1, tmp[2], 1, physout[2], 1);
846 Vmath::Vmul(nq, physout[0], 1, physin[1], 1, physout[1], 1);
849 Vmath::Vmul(nq, physout[0], 1, physin[2], 1, physout[2], 1);
880 const Array<
OneD, Array<OneD, NekDouble> > &physfield,
881 Array<
OneD, Array<OneD, NekDouble> > &velocity)
883 const int npts = physfield[0].num_elements();
887 Vmath::Vdiv(npts, physfield[1 + i], 1, physfield[0], 1, velocity[i], 1);
901 Array<OneD, NekDouble> &fce,
908 for (
int j = 0; j < nq; j++)
910 (
m_fields[3]->UpdatePhys())[j] = fce[j];
928 const Array<
OneD,
const Array<OneD, NekDouble> > &inarray,
929 Array<OneD, NekDouble> &numfluxX,
930 Array<OneD, NekDouble> &numfluxY)
937 Array<OneD, Array<OneD, NekDouble> > Fwd(2);
938 Array<OneD, Array<OneD, NekDouble> > Bwd(2);
940 for (i = 0; i < 2; ++i)
942 Fwd[i] = Array<OneD, NekDouble>(nTraceNumPoints);
943 Bwd[i] = Array<OneD, NekDouble>(nTraceNumPoints);
951 m_fields[1]->GetFwdBwdTracePhys(inarray[0], Fwd[0], Bwd[0]);
952 m_fields[2]->GetFwdBwdTracePhys(inarray[1], Fwd[1], Bwd[1]);
957 for (i = 0; i < nTraceNumPoints; ++i)
959 numfluxX[i] = 0.5 * (Fwd[0][i] + Bwd[0][i]);
960 numfluxY[i] = 0.5 * (Fwd[1][i] + Bwd[1][i]);
966 Array<
OneD, Array<OneD, NekDouble> > &inarray,
972 for (
int n = 0; n <
m_fields[0]->GetBndConditions().num_elements(); ++n)
976 if (
m_fields[0]->GetBndConditions()[n]->GetUserDefined()
983 if (
m_fields[0]->GetBndConditions()[n]->GetUserDefined()
986 ASSERTL0(
false,
"time-dependent BC not implemented for Boussinesq");
988 cnt +=
m_fields[0]->GetBndCondExpansions()[n]->GetExpSize();
996 Array<
OneD, Array<OneD, NekDouble> >&inarray)
1005 Array<OneD, Array<OneD, NekDouble> > Fwd(nvariables);
1006 for (
int i = 0; i < nvariables; ++i)
1008 Fwd[i] = Array<OneD, NekDouble>(nTraceNumPoints);
1009 m_fields[i]->ExtractTracePhys(inarray[i], Fwd[i]);
1014 int e, id1, id2,
npts;
1016 m_fields[0]->GetBndCondExpansions()[bcRegion];
1017 for (e = 0; e < bcexp->GetExpSize(); ++e)
1019 npts = bcexp->GetExp(e)->GetTotPoints();
1020 id1 = bcexp->GetPhys_Offset(e);
1021 id2 =
m_fields[0]->GetTrace()->GetPhys_Offset(
1022 m_fields[0]->GetTraceMap()->GetBndCondCoeffsToGlobalCoeffsMap(
1029 ASSERTL0(
false,
"1D not yet implemented for Boussinesq");
1034 Array<OneD, NekDouble> tmp_n(npts);
1035 Array<OneD, NekDouble> tmp_t(npts);
1040 &tmp_n[0], 1, &tmp_n[0], 1);
1045 &tmp_t[0], 1, &tmp_t[0], 1);
1054 &Fwd[0][id2], 1, &Fwd[0][id2], 1);
1059 &Fwd[1][id2], 1, &Fwd[1][id2], 1);
1063 ASSERTL0(
false,
"3D not implemented for Boussinesq equations");
1066 ASSERTL0(
false,
"Illegal expansion dimension");
1070 bcexp =
m_fields[1]->GetBndCondExpansions()[bcRegion];
1071 Vmath::Vcopy(npts, &Fwd[0][id2], 1, &(bcexp->UpdatePhys())[id1], 1);
1073 bcexp =
m_fields[2]->GetBndCondExpansions()[bcRegion];
1074 Vmath::Vcopy(npts, &Fwd[1][id2], 1, &(bcexp->UpdatePhys())[id1], 1);
1079 Array<OneD, NekDouble> &inarray,
1085 for (
int n = 0; n <
m_fields[0]->GetBndConditions().num_elements(); ++n)
1089 if (
m_fields[0]->GetBndConditions()[n]->GetUserDefined()
1095 if (
m_fields[0]->GetBndConditions()[n]->GetUserDefined()
1101 cnt +=
m_fields[0]->GetBndCondExpansions()[n]->GetExpSize() - 1;
1108 Array<OneD, NekDouble>&inarray)
1113 Array<OneD, NekDouble> z(nTraceNumPoints);
1114 m_fields[0]->ExtractTracePhys(inarray, z);
1118 int e, id1, id2,
npts;
1120 m_fields[0]->GetBndCondExpansions()[bcRegion];
1122 for (e = 0; e < bcexp->GetExpSize(); ++e)
1124 npts = bcexp->GetExp(e)->GetTotPoints();
1125 id1 = bcexp->GetPhys_Offset(e);
1126 id2 =
m_fields[0]->GetTrace()->GetPhys_Offset(
1127 m_fields[0]->GetTraceMap()->GetBndCondCoeffsToGlobalCoeffsMap(
1131 bcexp =
m_fields[1]->GetBndCondExpansions()[bcRegion];
1132 Vmath::Vcopy(npts, &z[id2], 1, &(bcexp->UpdatePhys())[id1], 1);
1138 Array<OneD, NekDouble> &physfield, Array<OneD, NekDouble> &outX,
1139 Array<OneD, NekDouble> &outY)
1146 Array<OneD, Array<OneD, NekDouble> > Fwd(1);
1147 Array<OneD, Array<OneD, NekDouble> > Bwd(1);
1149 Fwd[0] = Array<OneD, NekDouble>(nTraceNumPoints);
1150 Bwd[0] = Array<OneD, NekDouble>(nTraceNumPoints);
1157 m_fields[1]->GetFwdBwdTracePhys(physfield, Fwd[0], Bwd[0]);
1162 for (i = 0; i < nTraceNumPoints; ++i)
1164 outX[i] = 0.5 * (Fwd[0][i] + Bwd[0][i]);
1165 outY[i] = 0.5 * (Fwd[0][i] + Bwd[0][i]);
1182 Array<OneD, NekDouble> x0(nq);
1183 Array<OneD, NekDouble> x1(nq);
1184 Array<OneD, NekDouble> zeros(nq, 0.0);
1190 for (
int i = 0; i < nq; i++)
1192 (
m_fields[0]->UpdatePhys())[i] = amp * pow((1.0 / cosh(
1193 sqrt(0.75 * (amp / (d * d * d))) *
1194 (A * (x0[i] + x_offset) - C * time))), 2.0);
1195 (
m_fields[1]->UpdatePhys())[i] = (amp / d) * pow((1.0 / cosh(
1196 sqrt(0.75 * (amp / (d * d * d))) *
1197 (A * (x0[i] + x_offset) - C * time)
1198 )), 2.0) * sqrt(
m_g * d);
1208 for (
int i = 0; i < 4; ++i)
1222 bool dumpInitialConditions,
1240 if (dumpInitialConditions)