37 #include <boost/algorithm/string.hpp>
69 IncNavierStokes::IncNavierStokes(
74 m_SmoothAdvection(false)
84 std::string velids[] = {
"u",
"v",
"w"};
91 for(j = 0; j < numfields; ++j)
94 if(boost::iequals(velids[i], var))
100 ASSERTL0(j != numfields,
"Failed to find field: " + var);
117 "EQTYPE not found in SOLVERINFO section");
132 ASSERTL0(
false,
"Unknown or undefined equation type");
138 std::string vConvectiveType;
143 vConvectiveType =
"NoAdvection";
147 vConvectiveType =
"Convective";
150 vConvectiveType =
"Linearised";
157 if (
m_session->DefinesTag(
"AdvectiveType") &&
161 vConvectiveType =
m_session->GetTag(
"AdvectiveType");
166 vConvectiveType, vConvectiveType);
180 for (i = 0; i <
m_fields.size(); ++i)
188 BndConds =
m_fields[i]->GetBndConditions();
189 BndExp =
m_fields[i]->GetBndCondExpansions();
190 for(
int n = 0; n < BndConds.size(); ++n)
192 if(boost::iequals(BndConds[n]->GetUserDefined(),
"Radiation"))
194 ASSERTL0(BndConds[n]->GetBoundaryConditionType() ==
196 "Radiation boundary condition must be of type Robin <R>");
204 radpts += BndExp[n]->GetTotPoints();
206 if(boost::iequals(BndConds[n]->GetUserDefined(),
207 "ZeroNormalComponent"))
209 ASSERTL0(BndConds[n]->GetBoundaryConditionType() ==
211 "Zero Normal Component boundary condition option must be of type Dirichlet <D>");
226 for(
int n = 0; n < BndConds.size(); ++n)
228 if(boost::iequals(BndConds[n]->GetUserDefined(),
"Radiation"))
231 int npoints = BndExp[n]->GetNpoints();
237 BndExp[n]->GetCoords(x0,x1,x2);
240 std::static_pointer_cast<
242 >(BndConds[n])->m_robinPrimitiveCoeff;
253 for (
int i = 0; i <
m_fields.size(); ++i)
255 for(
int n = 0; n <
m_fields[i]->GetBndConditions().size(); ++n)
257 if(boost::istarts_with(
m_fields[i]->GetBndConditions()[n]->GetUserDefined(),
"Womersley"))
265 m_fields[i]->GetBndConditions()[n]->GetUserDefined());
297 int npoints =
m_fields[0]->GetNpoints();
298 for (i = 0; i < VelDim; ++i)
305 x->PreApply(
m_fields, velocity, velocity, time);
309 velocity, inarray, outarray, time);
321 for (i = 0; i < nvariables; ++i)
323 for(n = 0; n <
m_fields[i]->GetBndConditions().size(); ++n)
325 if(
m_fields[i]->GetBndConditions()[n]->IsTimeDependent())
328 m_fields[i]->EvaluateBoundaryConditions(time, varName);
330 else if(boost::istarts_with(
331 m_fields[i]->GetBndConditions()[n]->GetUserDefined(),
355 BndConds =
m_fields[fieldid]->GetBndConditions();
356 BndExp =
m_fields[fieldid]->GetBndCondExpansions();
362 int elmtid,nq,offset, boundary;
366 for(cnt = n = 0; n < BndConds.size(); ++n)
368 std::string type = BndConds[n]->GetUserDefined();
370 if((BndConds[n]->GetBoundaryConditionType() ==
372 (boost::iequals(type,
"Radiation")))
374 for(i = 0; i < BndExp[n]->GetExpSize(); ++i,cnt++)
377 elmt =
m_fields[fieldid]->GetExp(elmtid);
378 offset =
m_fields[fieldid]->GetPhys_Offset(elmtid);
380 U =
m_fields[fieldid]->UpdatePhys() + offset;
381 Bc = BndExp[n]->GetExp(i);
386 nq = Bc->GetTotPoints();
388 elmt->GetTracePhysVals(boundary,Bc,U,ubc);
392 &ubc[0],1,&ubc[0],1);
394 Bvals = BndExp[n]->UpdateCoeffs()+BndExp[n]->
397 Bc->IProductWRTBase(ubc,Bvals);
399 cnt1 += BndExp[n]->GetTotPoints();
403 cnt += BndExp[n]->GetExpSize();
413 static bool Setup =
false;
438 int elmtid,nq, boundary;
445 for(cnt = n = 0; n < BndConds[0].size(); ++n)
447 if((BndConds[0][n]->GetBoundaryConditionType() ==
449 (boost::iequals(BndConds[0][n]->GetUserDefined(),
450 "ZeroNormalComponent")))
452 for(i = 0; i < BndExp[0][n]->GetExpSize(); ++i,cnt++)
458 normals = elmt->GetTraceNormal(boundary);
460 nq = BndExp[0][n]->GetExp(i)->GetTotPoints();
465 Bphys = BndExp[k][n]->UpdatePhys()+
466 BndExp[k][n]->GetPhys_Offset(i);
467 Bc = BndExp[k][n]->GetExp(i);
477 Bphys = BndExp[k][n]->UpdatePhys()+
478 BndExp[k][n]->GetPhys_Offset(i);
479 Bcoeffs = BndExp[k][n]->UpdateCoeffs()+
480 BndExp[k][n]->GetCoeff_Offset(i);
481 Bc = BndExp[k][n]->GetExp(i);
484 Bc->FwdTrans_BndConstrained(Bphys,Bcoeffs);
490 cnt += BndExp[0][n]->GetExpSize();
502 "Womersley parameters for this boundary have not been set up");
508 int M_coeffs = WomParam->m_wom_vel.size();
511 NekDouble axis_normal = WomParam->m_axisnormal[fldid];
521 BndCondExp =
m_fields[fldid]->GetBndCondExpansions()[bndid];
527 int exp_npts = BndCondExp->GetExpSize();
533 for (k=1; k < M_coeffs; k++)
536 zt[k] = std::exp(zi * omega_c * k_c * m_time_c);
540 for(i = 0; i < exp_npts; ++i,cnt++)
543 bc = BndCondExp->GetExp(i);
544 nfq = bc->GetTotPoints();
548 for (j=0; j < nfq; j++)
550 wbc[j] = WomParam->m_poiseuille[i][j];
551 for (k=1; k < M_coeffs; k++)
553 zvel = WomParam->m_zvel[i][j][k] * zt[k];
554 wbc[j] = wbc[j] + zvel.real();
561 Bvals = BndCondExp->UpdateCoeffs()+
562 BndCondExp->GetCoeff_Offset(i);
565 bc->FwdTrans(wbc,Bvals);
572 std::string::size_type indxBeg = womStr.find_first_of(
':') + 1;
573 string filename = womStr.substr(indxBeg,string::npos);
575 TiXmlDocument doc(filename);
577 bool loadOkay = doc.LoadFile();
578 ASSERTL0(loadOkay,(std::string(
"Failed to load file: ") +
581 TiXmlHandle docHandle(&doc);
585 TiXmlElement *nektar = doc.FirstChildElement(
"NEKTAR");
586 ASSERTL0(nektar,
"Unable to find NEKTAR tag in file.");
588 TiXmlElement *wombc = nektar->FirstChildElement(
"WOMERSLEYBC");
589 ASSERTL0(wombc,
"Unable to find WOMERSLEYBC tag in file.");
592 TiXmlElement *womparam = wombc->FirstChildElement(
"WOMPARAMS");
593 ASSERTL0(womparam,
"Unable to find WOMPARAMS tag in file.");
596 TiXmlElement *params = womparam->FirstChildElement(
"W");
597 map<std::string,std::string> Wparams;
604 propstr = params->Attribute(
"PROPERTY");
607 "Failed to read PROPERTY value Womersley BC Parameter");
611 valstr = params->Attribute(
"VALUE");
614 "Failed to read VALUE value Womersley BC Parameter");
616 std::transform(propstr.begin(),propstr.end(),propstr.begin(),
618 Wparams[propstr] = valstr;
620 params = params->NextSiblingElement(
"W");
626 ASSERTL0(Wparams.count(
"RADIUS") == 1,
627 "Failed to find Radius parameter in Womersley boundary conditions");
628 std::vector<NekDouble>
rad;
632 ASSERTL0(Wparams.count(
"PERIOD") == 1,
633 "Failed to find period parameter in Womersley boundary conditions");
634 std::vector<NekDouble> period;
639 ASSERTL0(Wparams.count(
"AXISNORMAL") == 1,
640 "Failed to find axisnormal parameter in Womersley boundary conditions");
641 std::vector<NekDouble> anorm;
648 ASSERTL0(Wparams.count(
"AXISPOINT") == 1,
649 "Failed to find axispoint parameter in Womersley boundary conditions");
650 std::vector<NekDouble> apt;
659 TiXmlElement *coeff = wombc->FirstChildElement(
"FOURIERCOEFFS");
662 TiXmlElement *fval = coeff->FirstChildElement(
"F");
665 int nextFourierCoeff = -1;
671 TiXmlAttribute *fvalAttr = fval->FirstAttribute();
672 std::string attrName(fvalAttr->Name());
675 (std::string(
"Unknown attribute name: ") + attrName).c_str());
677 err = fvalAttr->QueryIntValue(&indx);
678 ASSERTL0(err == TIXML_SUCCESS,
"Unable to read attribute ID.");
680 std::string coeffStr = fval->FirstChild()->ToText()->ValueStr();
681 vector<NekDouble> coeffvals;
685 (std::string(
"Problem reading value of fourier coefficient, ID=") +
686 boost::lexical_cast<string>(indx)).c_str());
688 (std::string(
"Have not read two entries of Fourier coefficicent from ID="+
689 boost::lexical_cast<string>(indx)).c_str()));
693 fval = fval->NextSiblingElement(
"F");
712 BndCondExp =
m_fields[fldid]->GetBndCondExpansions()[bndid];
719 int exp_npts = BndCondExp->GetExpSize();
731 for (k=1; k < M_coeffs; k++)
734 lamda_n[k] = i_pow_3q2 * alpha_c *
sqrt(k_c[k]);
739 for(i = 0; i < exp_npts; ++i,cnt++)
742 bc = BndCondExp->GetExp(i);
743 nfq = bc->GetTotPoints();
748 bc->GetCoords(x,y,z);
756 for (j=0; j < nfq; j++)
759 (y[j]-x0[1])*(y[j]-x0[1]) +
760 (z[j]-x0[2])*(z[j]-x0[2]))/R, 0.0);
765 (1. - rqR.real()*rqR.real());
772 for (k=1; k < M_coeffs; k++)
777 (z1 - (zJ0r / zJ0[k]));
798 boost::ignore_unused(SpeedSoundFactor);
800 int nelmt =
m_fields[0]->GetExpSize();
809 for(
int i = 0; i < 2; ++i)
818 for(
int i = 0; i < nvel; ++i)
846 int nPts = physfield[0].size();
859 velocity[i] = physfield[i];
#define ASSERTL0(condition, msg)
#define ASSERTL1(condition, msg)
Assert Level 1 – Debugging which is used whether in FULLDEBUG or DEBUG compilation mode....
virtual Array< OneD, NekDouble > v_GetMaxStdVelocity(const NekDouble SpeedSoundFactor)
Array< OneD, int > & GetVelocity(void)
Array< OneD, Array< OneD, int > > m_fieldsBCToTraceID
Mapping from BCs to Elmt Edge IDs.
virtual void v_InitObject()
Init object for UnsteadySystem class.
virtual int v_GetForceDimension()=0
void SetWomersleyBoundary(const int fldid, const int bndid)
Set Womersley Profile if specified.
void SetZeroNormalVelocity()
Set Normal Velocity Component to Zero.
void SetBoundaryConditions(NekDouble time)
time dependent boundary conditions updating
virtual bool v_PreIntegrate(int step)
NekDouble m_kinvis
Kinematic viscosity.
virtual ~IncNavierStokes()
virtual void GetDensity(const Array< OneD, const Array< OneD, NekDouble > > &physfield, Array< OneD, NekDouble > &density)
Extract array with density from physfield.
void SetRadiationBoundaryForcing(int fieldid)
Set Radiation forcing term.
Array< OneD, Array< OneD, NekDouble > > m_fieldsRadiationFactor
RHS Factor for Radiation Condition.
void SetUpWomersley(const int fldid, const int bndid, std::string womstr)
Set Up Womersley details.
ExtrapolateSharedPtr m_extrapolation
Array< OneD, int > m_velocity
int which identifies which components of m_fields contains the velocity (u,v,w);
std::map< int, std::map< int, WomersleyParamsSharedPtr > > m_womersleyParams
Womersley parameters if required.
Array< OneD, Array< OneD, int > > m_fieldsBCToElmtID
Mapping from BCs to Elmt IDs.
EquationType m_equationType
equation type;
int m_nConvectiveFields
Number of fields to be convected;.
void AddForcing(const SolverUtils::ForcingSharedPtr &pForce)
std::vector< SolverUtils::ForcingSharedPtr > m_forcing
Forcing terms.
void EvaluateAdvectionTerms(const Array< OneD, const Array< OneD, NekDouble > > &inarray, Array< OneD, Array< OneD, NekDouble > > &outarray, const NekDouble time)
NekDouble Evaluate() const
tBaseSharedPtr CreateInstance(tKey idKey, tParam... args)
Create an instance of the class referred to by idKey.
static std::shared_ptr< DataType > AllocateSharedPtr(const Args &...args)
Allocate a shared pointer from the memory pool.
static bool GenerateVector(const std::string &str, std::vector< T > &out)
Takes a comma-separated string and converts it to entries in a vector.
A base class for PDEs which include an advection component.
SolverUtils::AdvectionSharedPtr m_advObject
Advection term.
virtual SOLVER_UTILS_EXPORT void v_InitObject()
Init object for UnsteadySystem class.
int m_spacedim
Spatial dimension (>= expansion dim).
NekDouble m_timestep
Time step size.
NekDouble m_time
Current time of simulation.
Array< OneD, MultiRegions::ExpListSharedPtr > m_fields
Array holding all dependent variables.
SOLVER_UTILS_EXPORT int GetCoeff_Offset(int n)
LibUtilities::SessionReaderSharedPtr m_session
The session reader.
enum HomogeneousType m_HomogeneousType
SOLVER_UTILS_EXPORT MultiRegions::ExpListSharedPtr GetPressure()
Get pressure field if available.
SOLVER_UTILS_EXPORT int GetPhys_Offset(int n)
LibUtilities::FieldMetaDataMap m_fieldMetaDataMap
Map to identify relevant solver info to dump in output fields.
SpatialDomains::BoundaryConditionsSharedPtr m_boundaryConditions
Pointer to boundary conditions object.
static SOLVER_UTILS_EXPORT std::vector< ForcingSharedPtr > Load(const LibUtilities::SessionReaderSharedPtr &pSession, const std::weak_ptr< EquationSystem > &pEquation, const Array< OneD, MultiRegions::ExpListSharedPtr > &pFields, const unsigned int &pNumForcingFields=0)
Base class for unsteady solvers.
static NekDouble rad(NekDouble x, NekDouble y)
std::shared_ptr< SessionReader > SessionReaderSharedPtr
std::shared_ptr< Expansion > ExpansionSharedPtr
std::shared_ptr< ExpList > ExpListSharedPtr
Shared pointer to an ExpList object.
AdvectionFactory & GetAdvectionFactory()
Gets the factory for initialising advection objects.
SOLVER_UTILS_EXPORT typedef std::shared_ptr< Forcing > ForcingSharedPtr
A shared pointer to an EquationSystem object.
std::shared_ptr< MeshGraph > MeshGraphSharedPtr
std::shared_ptr< StdExpansion > StdExpansionSharedPtr
The above copyright notice and this permission notice shall be included.
std::complex< double > NekComplexDouble
std::shared_ptr< WomersleyParams > WomersleyParamsSharedPtr
const std::string kEquationTypeStr[]
std::complex< Nektar::NekDouble > ImagBesselComp(int n, std::complex< Nektar::NekDouble > y)
Calcualte the bessel function of the first kind with complex double input y. Taken from Numerical Rec...
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 Smul(int n, const T alpha, const T *x, const int incx, T *y, const int incy)
Scalar multiply y = alpha*x.
void Fill(int n, const T alpha, T *x, const int incx)
Fill a vector with a constant value.
void Vcopy(int n, const T *x, const int incx, T *y, const int incy)
scalarT< T > sqrt(scalarT< T > in)