37 #include <boost/algorithm/string.hpp> 68 IncNavierStokes::IncNavierStokes(
73 m_SmoothAdvection(false)
82 int numfields =
m_fields.num_elements();
83 std::string velids[] = {
"u",
"v",
"w"};
90 for(j = 0; j < numfields; ++j)
93 if(boost::iequals(velids[i], var))
99 ASSERTL0(j != numfields,
"Failed to find field: " + var);
116 "EQTYPE not found in SOLVERINFO section");
131 ASSERTL0(
false,
"Unknown or undefined equation type");
137 std::string vConvectiveType;
142 vConvectiveType =
"NoAdvection";
146 vConvectiveType =
"Convective";
149 vConvectiveType =
"Linearised";
156 if (
m_session->DefinesTag(
"AdvectiveType") &&
160 vConvectiveType =
m_session->GetTag(
"AdvectiveType");
165 vConvectiveType, vConvectiveType);
179 for (i = 0; i <
m_fields.num_elements(); ++i)
187 BndConds =
m_fields[i]->GetBndConditions();
188 BndExp =
m_fields[i]->GetBndCondExpansions();
189 for(
int n = 0; n < BndConds.num_elements(); ++n)
191 if(boost::iequals(BndConds[n]->GetUserDefined(),
"Radiation"))
193 ASSERTL0(BndConds[n]->GetBoundaryConditionType() ==
195 "Radiation boundary condition must be of type Robin <R>");
203 radpts += BndExp[n]->GetTotPoints();
205 if(boost::iequals(BndConds[n]->GetUserDefined(),
206 "ZeroNormalComponent"))
208 ASSERTL0(BndConds[n]->GetBoundaryConditionType() ==
210 "Zero Normal Component boundary condition option must be of type Dirichlet <D>");
225 for(
int n = 0; n < BndConds.num_elements(); ++n)
227 if(boost::iequals(BndConds[n]->GetUserDefined(),
"Radiation"))
230 int npoints = BndExp[n]->GetNpoints();
236 BndExp[n]->GetCoords(x0,x1,x2);
239 std::static_pointer_cast<
241 >(BndConds[n])->m_robinPrimitiveCoeff;
244 tmpArray = m_fieldsRadiationFactor[i]+ radpts);
252 for (
int i = 0; i <
m_fields.num_elements(); ++i)
254 for(
int n = 0; n <
m_fields[i]->GetBndConditions().num_elements(); ++n)
256 if(boost::istarts_with(
m_fields[i]->GetBndConditions()[n]->GetUserDefined(),
"Womersley"))
264 m_fields[i]->GetBndConditions()[n]->GetUserDefined());
295 for(i = 0; i < VelDim; ++i)
301 velocity, inarray, outarray,
m_time);
311 int nvariables =
m_fields.num_elements();
313 for (i = 0; i < nvariables; ++i)
315 for(n = 0; n <
m_fields[i]->GetBndConditions().num_elements(); ++n)
317 if(
m_fields[i]->GetBndConditions()[n]->IsTimeDependent())
320 m_fields[i]->EvaluateBoundaryConditions(time, varName);
322 else if(boost::istarts_with(
323 m_fields[i]->GetBndConditions()[n]->GetUserDefined(),
347 BndConds =
m_fields[fieldid]->GetBndConditions();
348 BndExp =
m_fields[fieldid]->GetBndCondExpansions();
354 int elmtid,nq,offset, boundary;
358 for(cnt = n = 0; n < BndConds.num_elements(); ++n)
360 std::string type = BndConds[n]->GetUserDefined();
362 if((BndConds[n]->GetBoundaryConditionType() ==
364 (boost::iequals(type,
"Radiation")))
366 for(i = 0; i < BndExp[n]->GetExpSize(); ++i,cnt++)
369 elmt =
m_fields[fieldid]->GetExp(elmtid);
370 offset =
m_fields[fieldid]->GetPhys_Offset(elmtid);
372 U =
m_fields[fieldid]->UpdatePhys() + offset;
373 Bc = BndExp[n]->GetExp(i);
378 nq = Bc->GetTotPoints();
380 elmt->GetTracePhysVals(boundary,Bc,U,ubc);
384 &ubc[0],1,&ubc[0],1);
386 Bvals = BndExp[n]->UpdateCoeffs()+BndExp[n]->
389 Bc->IProductWRTBase(ubc,Bvals);
391 cnt1 += BndExp[n]->GetTotPoints();
395 cnt += BndExp[n]->GetExpSize();
405 static bool Setup =
false;
430 int elmtid,nq, boundary;
437 for(cnt = n = 0; n < BndConds[0].num_elements(); ++n)
439 if((BndConds[0][n]->GetBoundaryConditionType() ==
441 (boost::iequals(BndConds[0][n]->GetUserDefined(),
442 "ZeroNormalComponent")))
444 for(i = 0; i < BndExp[0][n]->GetExpSize(); ++i,cnt++)
450 normals = elmt->GetSurfaceNormal(boundary);
452 nq = BndExp[0][n]->GetExp(i)->GetTotPoints();
457 Bphys = BndExp[k][n]->UpdatePhys()+
458 BndExp[k][n]->GetPhys_Offset(i);
459 Bc = BndExp[k][n]->GetExp(i);
469 Bphys = BndExp[k][n]->UpdatePhys()+
470 BndExp[k][n]->GetPhys_Offset(i);
471 Bcoeffs = BndExp[k][n]->UpdateCoeffs()+
472 BndExp[k][n]->GetCoeff_Offset(i);
473 Bc = BndExp[k][n]->GetExp(i);
476 Bc->FwdTrans_BndConstrained(Bphys,Bcoeffs);
482 cnt += BndExp[0][n]->GetExpSize();
494 "Womersley parameters for this boundary have not been set up");
500 int M_coeffs = WomParam->m_wom_vel.size();
503 NekDouble axis_normal = WomParam->m_axisnormal[fldid];
513 BndCondExp =
m_fields[fldid]->GetBndCondExpansions()[bndid];
519 int exp_npts = BndCondExp->GetExpSize();
525 for (k=1; k < M_coeffs; k++)
528 zt[k] = std::exp(zi * omega_c * k_c * m_time_c);
532 for(i = 0; i < exp_npts; ++i,cnt++)
535 bc = BndCondExp->GetExp(i);
536 nfq = bc->GetTotPoints();
540 for (j=0; j < nfq; j++)
542 wbc[j] = WomParam->m_poiseuille[i][j];
543 for (k=1; k < M_coeffs; k++)
545 zvel = WomParam->m_zvel[i][j][k] * zt[k];
546 wbc[j] = wbc[j] + zvel.real();
553 Bvals = BndCondExp->UpdateCoeffs()+
554 BndCondExp->GetCoeff_Offset(i);
557 bc->FwdTrans(wbc,Bvals);
564 std::string::size_type indxBeg = womStr.find_first_of(
':') + 1;
565 string filename = womStr.substr(indxBeg,string::npos);
567 TiXmlDocument doc(filename);
569 bool loadOkay = doc.LoadFile();
570 ASSERTL0(loadOkay,(std::string(
"Failed to load file: ") +
573 TiXmlHandle docHandle(&doc);
577 TiXmlElement *nektar = doc.FirstChildElement(
"NEKTAR");
578 ASSERTL0(nektar,
"Unable to find NEKTAR tag in file.");
580 TiXmlElement *wombc = nektar->FirstChildElement(
"WOMERSLEYBC");
581 ASSERTL0(wombc,
"Unable to find WOMERSLEYBC tag in file.");
584 TiXmlElement *womparam = wombc->FirstChildElement(
"WOMPARAMS");
585 ASSERTL0(womparam,
"Unable to find WOMPARAMS tag in file.");
588 TiXmlElement *params = womparam->FirstChildElement(
"W");
589 map<std::string,std::string> Wparams;
596 propstr = params->Attribute(
"PROPERTY");
599 "Failed to read PROPERTY value Womersley BC Parameter");
603 valstr = params->Attribute(
"VALUE");
606 "Failed to read VALUE value Womersley BC Parameter");
608 std::transform(propstr.begin(),propstr.end(),propstr.begin(),
610 Wparams[propstr] = valstr;
612 params = params->NextSiblingElement(
"W");
618 ASSERTL0(Wparams.count(
"RADIUS") == 1,
619 "Failed to find Radius parameter in Womersley boundary conditions");
620 std::vector<NekDouble>
rad;
624 ASSERTL0(Wparams.count(
"PERIOD") == 1,
625 "Failed to find period parameter in Womersley boundary conditions");
626 std::vector<NekDouble> period;
631 ASSERTL0(Wparams.count(
"AXISNORMAL") == 1,
632 "Failed to find axisnormal parameter in Womersley boundary conditions");
633 std::vector<NekDouble> anorm;
640 ASSERTL0(Wparams.count(
"AXISPOINT") == 1,
641 "Failed to find axispoint parameter in Womersley boundary conditions");
642 std::vector<NekDouble> apt;
651 TiXmlElement *coeff = wombc->FirstChildElement(
"FOURIERCOEFFS");
654 TiXmlElement *fval = coeff->FirstChildElement(
"F");
657 int nextFourierCoeff = -1;
663 TiXmlAttribute *fvalAttr = fval->FirstAttribute();
664 std::string attrName(fvalAttr->Name());
667 (std::string(
"Unknown attribute name: ") + attrName).c_str());
669 err = fvalAttr->QueryIntValue(&indx);
670 ASSERTL0(err == TIXML_SUCCESS,
"Unable to read attribute ID.");
672 std::string coeffStr = fval->FirstChild()->ToText()->ValueStr();
673 vector<NekDouble> coeffvals;
677 (std::string(
"Problem reading value of fourier coefficient, ID=") +
678 boost::lexical_cast<string>(indx)).c_str());
680 (std::string(
"Have not read two entries of Fourier coefficicent from ID="+
681 boost::lexical_cast<string>(indx)).c_str()));
685 fval = fval->NextSiblingElement(
"F");
704 BndCondExp =
m_fields[fldid]->GetBndCondExpansions()[bndid];
711 int exp_npts = BndCondExp->GetExpSize();
723 for (k=1; k < M_coeffs; k++)
726 lamda_n[k] = i_pow_3q2 * alpha_c * sqrt(k_c[k]);
731 for(i = 0; i < exp_npts; ++i,cnt++)
734 bc = BndCondExp->GetExp(i);
735 nfq = bc->GetTotPoints();
740 bc->GetCoords(x,y,z);
748 for (j=0; j < nfq; j++)
751 (y[j]-x0[1])*(y[j]-x0[1]) +
752 (z[j]-x0[2])*(z[j]-x0[2]))/R, 0.0);
757 (1. - rqR.real()*rqR.real());
764 for (k=1; k < M_coeffs; k++)
769 (z1 - (zJ0r / zJ0[k]));
790 int nelmt =
m_fields[0]->GetExpSize();
799 for(
int i = 0; i < 2; ++i)
808 for(
int i = 0; i < nvel; ++i)
836 int nPts = physfield[0].num_elements();
849 velocity[i] = physfield[i];
EquationType m_equationType
equation type;
void SetZeroNormalVelocity()
Set Normal Velocity Component to Zero.
#define ASSERTL0(condition, msg)
SOLVER_UTILS_EXPORT typedef std::shared_ptr< Forcing > ForcingSharedPtr
A shared pointer to an EquationSystem object.
std::complex< double > NekComplexDouble
std::shared_ptr< MeshGraph > MeshGraphSharedPtr
void SetBoundaryConditions(NekDouble time)
time dependent boundary conditions updating
Array< OneD, Array< OneD, int > > m_fieldsBCToTraceID
Mapping from BCs to Elmt Edge IDs.
std::map< int, std::map< int, WomersleyParamsSharedPtr > > m_womersleyParams
Womersley parameters if required.
SolverUtils::AdvectionSharedPtr m_advObject
Advection term.
virtual bool v_PreIntegrate(int step)
NekDouble m_time
Current time of simulation.
std::shared_ptr< ExpList > ExpListSharedPtr
Shared pointer to an ExpList object.
void SetRadiationBoundaryForcing(int fieldid)
Set Radiation forcing term.
NekDouble m_kinvis
Kinematic viscosity.
NekDouble m_timestep
Time step size.
void Fill(int n, const T alpha, T *x, const int incx)
Fill a vector with a constant value.
Array< OneD, int > m_velocity
int which identifies which components of m_fields contains the velocity (u,v,w);
ExtrapolateSharedPtr m_extrapolation
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
virtual void GetDensity(const Array< OneD, const Array< OneD, NekDouble > > &physfield, Array< OneD, NekDouble > &density)
Extract array with density from physfield.
void EvaluateAdvectionTerms(const Array< OneD, const Array< OneD, NekDouble > > &inarray, Array< OneD, Array< OneD, NekDouble > > &outarray)
virtual ~IncNavierStokes()
int m_nConvectiveFields
Number of fields to be convected;.
SOLVER_UTILS_EXPORT int GetCoeff_Offset(int n)
void SetUpWomersley(const int fldid, const int bndid, std::string womstr)
Set Up Womersley details.
std::shared_ptr< StdExpansion > StdExpansionSharedPtr
tBaseSharedPtr CreateInstance(tKey idKey, tParam... args)
Create an instance of the class referred to by idKey.
Array< OneD, Array< OneD, NekDouble > > m_fieldsRadiationFactor
RHS Factor for Radiation Condition.
void Smul(int n, const T alpha, const T *x, const int incx, T *y, const int incy)
Scalar multiply y = alpha*y.
virtual Array< OneD, NekDouble > v_GetMaxStdVelocity()
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)
std::vector< SolverUtils::ForcingSharedPtr > m_forcing
Forcing terms.
Base class for unsteady solvers.
SpatialDomains::BoundaryConditionsSharedPtr m_boundaryConditions
Pointer to boundary conditions object.
int m_spacedim
Spatial dimension (>= expansion dim).
static std::shared_ptr< DataType > AllocateSharedPtr(const Args &...args)
Allocate a shared pointer from the memory pool.
LibUtilities::FieldMetaDataMap m_fieldMetaDataMap
Map to identify relevant solver info to dump in output fields.
AdvectionFactory & GetAdvectionFactory()
Gets the factory for initialising advection objects.
void Neg(int n, T *x, const int incx)
Negate x = -x.
NekDouble Evaluate() const
static bool GenerateVector(const std::string &str, std::vector< T > &out)
Takes a comma-separated string and converts it to entries in a vector.
Array< OneD, int > & GetVelocity(void)
SOLVER_UTILS_EXPORT int GetPhys_Offset(int n)
static NekDouble rad(NekDouble x, NekDouble y)
void AddForcing(const SolverUtils::ForcingSharedPtr &pForce)
Array< OneD, Array< OneD, int > > m_fieldsBCToElmtID
Mapping from BCs to Elmt IDs.
Array< OneD, MultiRegions::ExpListSharedPtr > m_fields
Array holding all dependent variables.
LibUtilities::SessionReaderSharedPtr m_session
The session reader.
SOLVER_UTILS_EXPORT MultiRegions::ExpListSharedPtr GetPressure()
Get pressure field if available.
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...
const std::string kEquationTypeStr[]
void SetWomersleyBoundary(const int fldid, const int bndid)
Set Womersley Profile if specified.
virtual SOLVER_UTILS_EXPORT void v_InitObject()
Init object for UnsteadySystem class.
A base class for PDEs which include an advection component.
#define ASSERTL1(condition, msg)
Assert Level 1 – Debugging which is used whether in FULLDEBUG or DEBUG compilation mode...
std::shared_ptr< WomersleyParams > WomersleyParamsSharedPtr
LibUtilities::TimeIntegrationSolutionSharedPtr m_intSoln
virtual void v_InitObject()
Init object for UnsteadySystem class.
std::shared_ptr< SessionReader > SessionReaderSharedPtr
virtual int v_GetForceDimension()=0
enum HomogeneousType m_HomogeneousType
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.