64 PulseWaveSystem::PulseWaveSystem(
97 "Pulse solver only set up for Discontinuous projections");
100 "Pulse wave solver only set up for expansion dimension equal to 1");
113 if (
m_session->DefinesSolverInfo(
"PressureArea"))
130 const std::vector<SpatialDomains::CompositeMap> domain =
m_graph->GetDomain();
136 bool SetToOneSpaceDimension =
true;
138 if (
m_session->DefinesCmdLineArgument(
"SetToOneSpaceDimension"))
140 std::string cmdline =
141 m_session->GetCmdLineArgument<std::string>(
"SetToOneSpaceDimension");
142 if (boost::to_upper_copy(cmdline) ==
"FALSE")
144 SetToOneSpaceDimension =
false;
155 m_session->GetVariable(j), SetToOneSpaceDimension);
193 for (
int i = 0; i < 2; ++i)
238 for (
int omega = 0; omega <
m_nDomains; omega++)
250 if (
m_session->DefinesFunction(
"Viscoelasticity"))
257 for (
int j = 0; j < nq; ++j)
268 if (
m_session->DefinesFunction(
"StrainStiffening"))
275 for (
int j = 0; j < nq; ++j)
295 if (SetToOneSpaceDimension)
300 int nelmt_trace = trace->GetExpSize();
304 for (
int i = 0; i < nelmt_trace; ++i)
311 trace->GetExp(0)->GetGeom()->SetCoordim(1);
313 trace->GetNormals(normals);
322 map<int, std::vector<InterfacePointShPtr> > VidToDomain;
329 for (
int omega = 0; omega <
m_nDomains; ++omega)
333 for (
int i = 0; i < 2; ++i)
336 ->GetBndConditions()[i]
341 ->UpdateBndCondExpansion(i)
345 cout <<
"Shared vertex ID: " << vid << endl;
351 for (
int n = 0; n <
m_vessels[vesselID]->GetExpSize(); ++n)
353 for (
int p = 0;
p < 2; ++
p)
357 ->GetElmtToTrace()[n][
p]
358 ->as<LocalRegions::Expansion>()
364 ->GetElmtToTrace()[n][
p]
368 m_vessels[vesselID]->GetTrace()->GetCoeff_Offset(
372 vid, omega, n,
p, tid, i);
374 cout <<
"Global VID of interface point: " << vid << endl;
375 cout <<
"Domain interface point belongs to: " << omega << endl;
376 cout <<
"Element ID of vertex: " << n << endl;
377 cout <<
"Vertex ID within local element: " <<
p << endl;
378 cout <<
"Element ID within the trace: " << tid << endl;
379 cout <<
"Position of boundary condition in region: " << i << endl;
391 VidToDomain[vid].push_back(Ipt);
394 m_vessels[vesselID]->GetBndConditions()[i]->SetBoundaryConditionType(
398 ->GetBndConditions()[i]
405 for (
auto &iter : VidToDomain)
407 if (iter.second.size() == 2)
411 else if (iter.second.size() == 3)
420 for (
int i = 0; i < 3; ++i)
422 if (iter.second[i]->m_elmtVert == 0)
436 if (iter.second[0]->m_elmtVert ==
446 if (iter.second[1]->m_elmtVert == 1)
449 iter.second[0] = iter.second[1];
452 else if (iter.second[2]->m_elmtVert == 1)
455 iter.second[0] = iter.second[2];
459 "This routine has not been checked");
465 if (iter.second[0]->m_elmtVert == 0)
474 if (iter.second[1]->m_elmtVert == 0)
477 iter.second[0] = iter.second[1];
480 else if (iter.second[2]->m_elmtVert == 0)
483 iter.second[0] = iter.second[2];
487 "This routine has not been checked");
494 ASSERTL0(
false,
"Unknown junction type");
508 if (
m_session->GetComm()->GetRank() == 0)
510 cout <<
"Initial Conditions: " << endl;
515 for (
int omega = 0; omega <
m_nDomains; omega++)
517 for (
int i = 0; i < 2; ++i)
522 if (
m_session->GetComm()->GetRank() == 0)
524 cout <<
"Subdomain: " << omega << endl;
531 for (
int i = 0; i < 2; ++i)
584 cout <<
"Steps: " << n + 1 <<
"\t Time: " <<
m_time
585 <<
"\t Time-step: " <<
m_timestep <<
"\t" << endl;
594 for (
int omega = 0; omega <
m_nDomains; omega++)
614 cout <<
"Time-integration timing: " << IntegrationTime <<
" s" << endl
623 int omega = I->m_domain;
624 int traceId = I->m_traceId;
626 int vert = I->m_elmtVert;
628 int phys_offset =
m_vessels[vesselID]->GetPhys_Offset(eid);
632 m_vessels[vesselID]->GetExp(eid)->GetTracePhysVals(
635 m_vessels[vesselID]->GetExp(eid)->GetTracePhysVals(
657 for (
int i = 0; i < 3; ++i)
660 uu[i], beta[i], A_0[i], alpha[i]);
666 for (
int i = 0; i < 3; ++i)
671 ->UpdateBndCondExpansion(bcpos)
672 ->UpdatePhys()[0] = Au[i];
674 ->UpdateBndCondExpansion(bcpos)
675 ->UpdatePhys()[0] = uu[i];
683 for (
int i = 0; i < 3; ++i)
686 uu[i], beta[i], A_0[i], alpha[i]);
693 for (
int i = 0; i < 3; ++i)
698 ->UpdateBndCondExpansion(bcpos)
699 ->UpdatePhys()[0] = Au[i];
701 ->UpdateBndCondExpansion(bcpos)
702 ->UpdatePhys()[0] = uu[i];
708 for (
int i = 0; i < 2; ++i)
711 beta[i], A_0[i], alpha[i]);
717 for (
int i = 0; i < 2; ++i)
722 ->UpdateBndCondExpansion(bcpos)
723 ->UpdatePhys()[0] = Au[i];
725 ->UpdateBndCondExpansion(bcpos)
726 ->UpdatePhys()[0] = uu[i];
760 m_pressureArea->GetW1(W[0], uu[0], beta[0], Au[0], A_0[0], alpha[0]);
763 for (
int i = 1; i < 3; ++i)
765 m_pressureArea->GetW2(W[i], uu[i], beta[i], Au[i], A_0[i], alpha[i]);
772 while ((proceed) && (iter < MAX_ITER))
789 for (
int i = 0; i < 3; ++i)
791 m_pressureArea->GetPressure(P_Au[i], beta[i], Au[i], A_0[i], 0, 0,
795 m_pressureArea->GetW1(W_Au[0], uu[0], beta[0], Au[0], A_0[0], alpha[0]);
796 m_pressureArea->GetW2(W_Au[1], uu[1], beta[1], Au[1], A_0[1], alpha[1]);
797 m_pressureArea->GetW2(W_Au[2], uu[2], beta[2], Au[2], A_0[2], alpha[2]);
800 f[0] = W_Au[0] - W[0];
801 f[1] = W_Au[1] - W[1];
802 f[2] = W_Au[2] - W[2];
803 f[3] = Au[0] * uu[0] - Au[1] * uu[1] - Au[2] * uu[2];
804 f[4] = uu[0] * uu[0] + 2 * P_Au[0] / rho -
805 uu[1] * uu[1] - 2 * P_Au[1] / rho;
806 f[5] = uu[0] * uu[0] + 2 * P_Au[0] / rho -
807 uu[2] * uu[2] - 2 * P_Au[2] / rho;
810 m_pressureArea->GetJacobianInverse(invJ, Au, uu, beta, A_0, alpha,
816 for (
int i = 0; i < 3; ++i)
823 if (
Dot(dx, dx) < Tol)
829 if (iter >= MAX_ITER)
831 ASSERTL0(
false,
"Riemann solver for Bifurcation did not converge.");
864 m_pressureArea->GetW2(W[0], uu[0], beta[0], Au[0], A_0[0], alpha[0]);
867 for (
int i = 1; i < 3; ++i)
869 m_pressureArea->GetW1(W[i], uu[i], beta[i], Au[i], A_0[i], alpha[i]);
876 while ((proceed) && (iter < MAX_ITER))
893 for (
int i = 0; i < 3; ++i)
895 m_pressureArea->GetPressure(P_Au[i], beta[i], Au[i], A_0[i], 0, 0,
899 m_pressureArea->GetW2(W_Au[0], uu[0], beta[0], Au[0], A_0[0], alpha[0]);
900 m_pressureArea->GetW1(W_Au[1], uu[1], beta[1], Au[1], A_0[1], alpha[1]);
901 m_pressureArea->GetW1(W_Au[2], uu[2], beta[2], Au[2], A_0[2], alpha[2]);
904 f[0] = W_Au[0] - W[0];
905 f[1] = W_Au[1] - W[1];
906 f[2] = W_Au[2] - W[2];
907 f[3] = Au[0] * uu[0] - Au[1] * uu[1] - Au[2] * uu[2];
908 f[4] = uu[0] * uu[0] + 2 * P_Au[0] / rho -
909 uu[1] * uu[1] - 2 * P_Au[1] / rho;
910 f[5] = uu[0] * uu[0] + 2 * P_Au[0] / rho -
911 uu[2] * uu[2] - 2 * P_Au[2] / rho;
914 m_pressureArea->GetJacobianInverse(invJ, Au, uu, beta, A_0, alpha,
920 for (
int i = 0; i < 3; ++i)
927 if (
Dot(dx, dx) < Tol)
933 if (iter >= MAX_ITER)
935 ASSERTL0(
false,
"Riemann solver for Merging Flow did not converge");
969 m_pressureArea->GetW1(W[0], uu[0], beta[0], Au[0], A_0[0], alpha[0]);
970 m_pressureArea->GetW2(W[1], uu[1], beta[1], Au[1], A_0[1], alpha[1]);
972 while ((proceed) && (iter < MAX_ITER))
985 for (
int i = 0; i < 2; ++i)
987 m_pressureArea->GetPressure(P_Au[i], beta[i], Au[i], A_0[i], 0, 0,
991 m_pressureArea->GetW1(W_Au[0], uu[0], beta[0], Au[0], A_0[0], alpha[0]);
992 m_pressureArea->GetW2(W_Au[1], uu[1], beta[1], Au[1], A_0[1], alpha[1]);
995 f[0] = W_Au[0] - W[0];
996 f[1] = W_Au[1] - W[1];
997 f[2] = Au[0] * uu[0] - Au[1] * uu[1];
998 f[3] = uu[0] * uu[0] + 2 * P_Au[0] / rho -
999 uu[1] * uu[1] - 2 * P_Au[1] / rho;
1002 m_pressureArea->GetJacobianInverse(invJ, Au, uu, beta, A_0, alpha,
1008 for (
int i = 0; i < 2; ++i)
1015 if (
Dot(dx, dx) < Tol)
1021 if (iter >= MAX_ITER)
1023 ASSERTL0(
false,
"Riemann solver for Junction did not converge");
1048 std::stringstream outname;
1060 std::vector<LibUtilities::FieldDefinitionsSharedPtr> FieldDef;
1061 std::vector<std::string> variables =
m_session->GetVariables();
1068 std::vector<std::vector<NekDouble> > FieldData(FieldDef.size());
1070 int nFieldDefPerDomain = FieldDef.size() /
m_nDomains;
1079 for (
int i = 0; i < nFieldDefPerDomain; ++i)
1081 cnt = n * nFieldDefPerDomain + i;
1083 FieldDef[cnt]->m_fields.push_back(variables[j]);
1086 FieldDef[cnt], FieldData[cnt],
1096 for (
int i = 0; i < nFieldDefPerDomain; ++i)
1098 cnt = n * nFieldDefPerDomain + i;
1100 FieldDef[cnt]->m_fields.push_back(
"P");
1103 FieldData[cnt], PFwd);
1119 for (
int i = 0; i < nFieldDefPerDomain; ++i)
1121 cnt = n * nFieldDefPerDomain + i;
1123 FieldDef[cnt]->m_fields.push_back(
"c");
1124 FieldDef[cnt]->m_fields.push_back(
"W1");
1125 FieldDef[cnt]->m_fields.push_back(
"W2");
1128 FieldData[cnt], PWVFwd);
1130 FieldData[cnt], W1Fwd);
1132 FieldData[cnt], W2Fwd);
1162 for (
int omega = 0; omega <
m_nDomains; omega++)
1166 if (
m_vessels[vesselid]->GetPhysState() ==
false)
1172 if (exactsoln.size())
1175 m_vessels[vesselid]->GetPhys(), exactsoln);
1177 else if (
m_session->DefinesFunction(
"ExactSolution"))
1183 m_session->GetFunction(
"ExactSolution", field, omega);
1185 ->Evaluate(
m_session->GetVariable(field), exactsoln,
1189 m_vessels[vesselid]->GetPhys(), exactsoln);
1197 L2error += L2error_dom * L2error_dom;
1199 if (Normalised ==
true)
1204 Vol +=
m_vessels[vesselid]->Integral(one);
1213 if (Normalised ==
true)
1217 L2error =
sqrt(L2error / Vol);
1221 L2error =
sqrt(L2error);
1236 NekDouble LinferrorDom, Linferror = -1.0;
1238 for (
int omega = 0; omega <
m_nDomains; ++omega)
1244 if (
m_vessels[vesselid]->GetPhysState() ==
false)
1250 if (exactsoln.size())
1256 else if (
m_session->DefinesFunction(
"ExactSolution"))
1273 Linferror = (Linferror > LinferrorDom) ? Linferror : LinferrorDom;
1277 ASSERTL0(
false,
"ErrorExtraPoints not allowed for this solver");
#define ASSERTL0(condition, msg)
#define NEKERROR(type, msg)
Assert Level 0 – Fundamental assert which is used whether in FULLDEBUG, DEBUG or OPT compilation mode...
tBaseSharedPtr CreateInstance(tKey idKey, tParam... args)
Create an instance of the class referred to by idKey.
NekDouble TimePerTest(unsigned int n)
Returns amount of seconds per iteration in a test with n iterations.
static std::shared_ptr< DataType > AllocateSharedPtr(const Args &...args)
Allocate a shared pointer from the memory pool.
Array< OneD, Array< OneD, NekDouble > > m_A_0
Array< OneD, int > m_fieldPhysOffset
Array< OneD, Array< OneD, NekDouble > > m_beta_trace
Array< OneD, Array< OneD, NekDouble > > m_W2
Array< OneD, Array< OneD, NekDouble > > m_trace_fwd_normal
PulseWavePressureAreaSharedPtr m_pressureArea
virtual void v_Output(void)
void CheckPoint_Output(const int n)
NekDouble v_LinfError(unsigned int field, const Array< OneD, NekDouble > &exactsoln=NullNekDouble1DArray)
Compute the L_inf error between fields and a given exact solution.
Array< OneD, Array< OneD, NekDouble > > m_W1
void JunctionRiemann(Array< OneD, NekDouble > &Au, Array< OneD, NekDouble > &uu, Array< OneD, NekDouble > &beta, Array< OneD, NekDouble > &A_0, Array< OneD, NekDouble > &alpha)
Riemann Problem for Junction.
void MergingRiemann(Array< OneD, NekDouble > &Au, Array< OneD, NekDouble > &uu, Array< OneD, NekDouble > &beta, Array< OneD, NekDouble > &A_0, Array< OneD, NekDouble > &alpha)
Riemann Problem for Merging Flow.
Array< OneD, Array< OneD, NekDouble > > m_alpha_trace
UpwindTypePulse m_upwindTypePulse
Array< OneD, Array< OneD, NekDouble > > m_A_0_trace
Array< OneD, Array< OneD, NekDouble > > m_pressure
virtual ~PulseWaveSystem()
Destructor.
NekDouble v_L2Error(unsigned int field, const Array< OneD, NekDouble > &exactsoln=NullNekDouble1DArray, bool Normalised=false)
Compute the L2 error between fields and a given exact solution.
virtual void v_InitObject()
Array< OneD, Array< OneD, NekDouble > > m_gamma
void WriteVessels(const std::string &outname)
Write input fields to the given filename.
Array< OneD, Array< OneD, NekDouble > > m_alpha
virtual void v_DoInitialise()
Sets up initial conditions.
Array< OneD, Array< OneD, NekDouble > > m_PWV
Array< OneD, MultiRegions::ExpListSharedPtr > m_vessels
virtual void v_DoSolve()
Solves an unsteady problem.
void FillDataFromInterfacePoint(InterfacePointShPtr &I, const Array< OneD, const Array< OneD, NekDouble > > &field, NekDouble &A, NekDouble &u, NekDouble &beta, NekDouble &A_0, NekDouble &alpha)
std::vector< std::vector< InterfacePointShPtr > > m_bifurcations
std::vector< std::vector< InterfacePointShPtr > > m_vesselJcts
std::vector< std::vector< InterfacePointShPtr > > m_mergingJcts
void SetUpDomainInterfaces(void)
void EnforceInterfaceConditions(const Array< OneD, const Array< OneD, NekDouble > > &fields)
Array< OneD, Array< OneD, NekDouble > > m_beta
void BifurcationRiemann(Array< OneD, NekDouble > &Au, Array< OneD, NekDouble > &uu, Array< OneD, NekDouble > &beta, Array< OneD, NekDouble > &A_0, Array< OneD, NekDouble > &alpha)
Riemann Problem for Bifurcation.
SpatialDomains::MeshGraphSharedPtr m_graph
Pointer to graph defining mesh.
LibUtilities::CommSharedPtr m_comm
Communicator.
NekDouble m_timestep
Time step size.
NekDouble m_time
Current time of simulation.
SOLVER_UTILS_EXPORT int GetTraceTotPoints()
Array< OneD, MultiRegions::ExpListSharedPtr > m_fields
Array holding all dependent variables.
std::string m_sessionName
Name of the session.
LibUtilities::SessionReaderSharedPtr m_session
The session reader.
SOLVER_UTILS_EXPORT void ZeroPhysFields()
SOLVER_UTILS_EXPORT int GetNpoints()
SOLVER_UTILS_EXPORT int GetNcoeffs()
enum MultiRegions::ProjectionType m_projectionType
Type of projection; e.g continuous or discontinuous.
int m_steps
Number of steps to take.
int m_NumQuadPointsError
Number of Quadrature points used to work out the error.
LibUtilities::FieldMetaDataMap m_fieldMetaDataMap
Map to identify relevant solver info to dump in output fields.
int m_checksteps
Number of steps between checkpoints.
SOLVER_UTILS_EXPORT void SetInitialConditions(NekDouble initialtime=0.0, bool dumpInitialConditions=true, const int domain=0)
Initialise the data in the dependent fields.
SOLVER_UTILS_EXPORT SessionFunctionSharedPtr GetFunction(std::string name, const MultiRegions::ExpListSharedPtr &field=MultiRegions::NullExpListSharedPtr, bool cache=false)
Get a SessionFunction by name.
Base class for unsteady solvers.
LibUtilities::TimeIntegrationSchemeOperators m_ode
The time integration scheme operators to use.
LibUtilities::TimeIntegrationSchemeSharedPtr m_intScheme
Wrapper to the time integration scheme.
virtual SOLVER_UTILS_EXPORT void v_InitObject()
Init object for UnsteadySystem class.
int m_infosteps
Number of time steps between outputting status information.
std::shared_ptr< SessionReader > SessionReaderSharedPtr
std::shared_ptr< Equation > EquationSharedPtr
void Write(const std::string &outFile, std::vector< FieldDefinitionsSharedPtr > &fielddefs, std::vector< std::vector< NekDouble > > &fielddata, const FieldMetaDataMap &fieldinfomap, const bool backup)
This function allows for data to be written to an FLD file when a session and/or communicator is not ...
std::shared_ptr< Expansion > ExpansionSharedPtr
std::shared_ptr< ExpList > ExpListSharedPtr
Shared pointer to an ExpList object.
std::shared_ptr< MeshGraph > MeshGraphSharedPtr
The above copyright notice and this permission notice shall be included.
std::shared_ptr< InterfacePoint > InterfacePointShPtr
PressureAreaFactory & GetPressureAreaFactory()
void Multiply(NekMatrix< ResultDataType, StandardMatrixTag > &result, const NekMatrix< LhsDataType, LhsMatrixType > &lhs, const ResultDataType &rhs)
@ SIZE_UpwindTypePulse
Length of enum list.
const char *const UpwindTypeMapPulse[]
DataType Dot(const NekVector< DataType > &lhs, const NekVector< DataType > &rhs)
void Vcopy(int n, const T *x, const int incx, T *y, const int incy)
scalarT< T > sqrt(scalarT< T > in)