v0.15.0
Loading...
Searching...
No Matches
FluidLevel.hpp
Go to the documentation of this file.
1/**
2 * @file FluidLevel.hpp
3 * @brief Natural boundary condition applying pressure from fluid.
4 * @date 2024-01-02
5 *
6 * @copyright Copyright (c) 2024
7 *
8 * Fluid level is type of linear pressure boundary condition.
9 *
10 * \todo Implement time depended fluid level.
11 *
12 */
13
14namespace ElasticExample {
15
16template <CubitBC BC> struct FluidLevelType {};
17
18template <CubitBC BC> struct GetFluidLevel;
19
20template <> struct GetFluidLevel<BLOCKSET> {
21 GetFluidLevel() = delete;
22
23 static MoFEMErrorCode getParams(double &density,
24 std::array<double, 3> &gravity,
25 std::array<double, 3> &zero_pressure,
26 boost::shared_ptr<Range> &ents,
27 MoFEM::Interface &m_field, int ms_id) {
29
30 auto cubit_meshset_ptr =
31 m_field.getInterface<MeshsetsManager>()->getCubitMeshsetPtr(ms_id,
32 BLOCKSET);
33 std::vector<double> block_data;
34 CHKERR cubit_meshset_ptr->getAttributes(block_data);
35 if (block_data.size() != 1 + 3 + 3) {
36 SETERRQ(PETSC_COMM_SELF, MOFEM_DATA_INCONSISTENCY,
37 "Expected that block has two attribute");
38 }
39 density = block_data[0];
40 gravity = {block_data[1], block_data[2], block_data[3]};
41 zero_pressure = {block_data[4], block_data[5], block_data[6]};
42
43 MOFEM_LOG_CHANNEL("WORLD");
44 MOFEM_TAG_AND_LOG("WORLD", Sev::inform, "FluidPressure")
45 << "Density " << density;
46 MOFEM_TAG_AND_LOG("WORLD", Sev::inform, "FluidPressure")
47 << "Gravity " << gravity[0] << " " << gravity[1] << " " << gravity[2];
48 MOFEM_TAG_AND_LOG("WORLD", Sev::inform, "FluidPressure")
49 << "Zero pressure " << zero_pressure[0] << " " << zero_pressure[1]
50 << " " << zero_pressure[2];
51
52 ents = boost::make_shared<Range>();
53 CHKERR
54 m_field.get_moab().get_entities_by_handle(cubit_meshset_ptr->meshset,
55 *(ents), true);
56
57 MOFEM_LOG_CHANNEL("SYNC");
58 MOFEM_TAG_AND_LOG("SYNC", Sev::noisy, "FluidPressure") << *ents;
59 MOFEM_LOG_SEVERITY_SYNC(m_field.get_comm(), Sev::noisy);
60
62 }
63};
64
65} // namespace ElasticExample
66
67template <int FIELD_DIM, AssemblyType A, typename EleOp>
68struct OpFluxRhsImpl<ElasticExample::FluidLevelType<BLOCKSET>, 1, FIELD_DIM, A,
69 GAUSS, EleOp> : OpBaseImpl<A, EleOp> {
70
72
73 OpFluxRhsImpl(MoFEM::Interface &m_field, int ms_id, std::string field_name,
74 std::vector<boost::shared_ptr<ScalingMethod>> smv,
75 double scale);
76
77protected:
79 std::array<double, 3> gravityAcceleration;
80 std::array<double, 3> zeroPressure;
81 std::vector<boost::shared_ptr<ScalingMethod>> vecOfTimeScalingMethods;
82 double rhsScale;
83
84 MoFEMErrorCode iNtegrate(EntitiesFieldData::EntData &data);
85};
86
87template <int FIELD_DIM, AssemblyType A, typename EleOp>
88OpFluxRhsImpl<
90 EleOp>::OpFluxRhsImpl(MoFEM::Interface &m_field, int ms_id,
91 std::string field_name,
92 std::vector<boost::shared_ptr<ScalingMethod>> smv,
93 double scale)
95 vecOfTimeScalingMethods(smv), rhsScale(scale) {
97 this->fluidDensity, this->gravityAcceleration,
98 this->zeroPressure, this->entsPtr, m_field, ms_id),
99 "Can not read spring stiffness data from blockset");
100}
101
102template <int FIELD_DIM, AssemblyType A, typename EleOp>
103MoFEMErrorCode
105 GAUSS, EleOp>::iNtegrate(EntitiesFieldData::EntData
106 &row_data) {
110 // get integration weights
111 auto t_w = OpBase::getFTensor0IntegrationWeight();
112 // get base function gradient on rows
113 auto t_row_base = row_data.getFTensor0N();
114
115 // get coordinate at integration points
116 auto t_normal = OpBase::getFTensor1NormalsAtGaussPts();
117 // get coordinate at integration points
118 auto t_coord = OpBase::getFTensor1CoordsAtGaussPts();
119
120 auto t_gravity = getFTensor1FromPtr<FIELD_DIM>(gravityAcceleration.data());
121 auto t_zero_pressure = getFTensor1FromPtr<FIELD_DIM>(zeroPressure.data());
122
123 double s = 1;
124 for (auto &o : vecOfTimeScalingMethods) {
125 s *= o->getScale(OpBase::getTStime());
126 }
127
128 // loop over integration points
129 for (int gg = 0; gg != OpBase::nbIntegrationPts; ++gg) {
130 // take into account Jacobian
131 const double alpha = t_w * rhsScale;
132
134 t_level(i) = t_coord(i) - t_zero_pressure(i);
135 auto dot = t_gravity(i) * t_level(i);
136
138 t_force(i) = -s * fluidDensity * dot * t_normal(i);
139
140 // loop over rows base functions
141 auto t_nf = getFTensor1FromArray<FIELD_DIM, FIELD_DIM>(OpBase::locF);
142 int rr = 0;
143 for (; rr != OpBase::nbRows / FIELD_DIM; ++rr) {
144 t_nf(i) += (alpha * t_row_base) * t_force(i);
145 ++t_row_base;
146 ++t_nf;
147 }
148
149 for (; rr < OpBase::nbRowBaseFunctions; ++rr)
150 ++t_row_base;
151
152 ++t_w;
153 ++t_coord;
154 ++t_normal;
155 }
157}
158
159template <CubitBC BCTYPE, int BASE_DIM, int FIELD_DIM, AssemblyType A,
160 IntegrationType I, typename OpBase>
161struct AddFluxToRhsPipelineImpl<
162
163 OpFluxRhsImpl<ElasticExample::FluidLevelType<BCTYPE>, BASE_DIM, FIELD_DIM,
164 A, I, OpBase>,
165 A, I, OpBase
166
167 > {
168
170
171 static MoFEMErrorCode add(
172
173 boost::ptr_deque<ForcesAndSourcesCore::UserDataOperator> &pipeline,
174 MoFEM::Interface &m_field, std::string field_name,
175 std::vector<boost::shared_ptr<ScalingMethod>> smv, double scale,
176 std::string block_name, Sev sev
177
178 ) {
180
181 using OP = OpFluxRhsImpl<ElasticExample::FluidLevelType<BLOCKSET>, BASE_DIM,
183
184 auto add_op = [&](auto &&meshset_vec_ptr) {
185 for (auto m : meshset_vec_ptr) {
186 MOFEM_TAG_AND_LOG("WORLD", sev, "OFluidLevelRhs") << "Add " << *m;
187 pipeline.push_back(
188 new OP(m_field, m->getMeshsetId(), field_name, smv, scale));
189 }
190 MOFEM_LOG_CHANNEL("WORLD");
191 };
192
193 switch (BCTYPE) {
194 case BLOCKSET:
195 add_op(
196
197 m_field.getInterface<MeshsetsManager>()->getCubitMeshsetPtr(
198 std::regex(
199
200 (boost::format("%s(.*)") % block_name).str()
201
202 ))
203
204 );
205
206 break;
207 default:
208 SETERRQ(PETSC_COMM_SELF, MOFEM_NOT_IMPLEMENTED,
209 "Handling of bc type not implemented");
210 break;
211 }
213 }
214};
#define MOFEM_LOG_SEVERITY_SYNC(comm, severity)
Synchronise "SYNC" on curtain severity level.
#define MOFEM_TAG_AND_LOG(channel, severity, tag)
Tag and log in channel.
constexpr int FIELD_DIM
#define CHK_THROW_MESSAGE(err, msg)
Check and throw MoFEM exception.
#define MoFEMFunctionBegin
First executable line of each MoFEM function, used for error handling. Final line of MoFEM functions ...
CubitBC
Types of sets and boundary conditions.
@ BLOCKSET
@ MOFEM_DATA_INCONSISTENCY
Definition definitions.h:31
@ MOFEM_NOT_IMPLEMENTED
Definition definitions.h:32
#define MoFEMFunctionReturn(a)
Last executable line of each PETSc function used for error handling. Replaces return()
#define CHKERR
Inline error check.
constexpr int BASE_DIM
IntegrationType
Form integrator integration types.
AssemblyType
[Storage and set boundary conditions]
#define MOFEM_LOG_CHANNEL(channel)
Set and reset channel.
FTensor::Index< 'i', SPACE_DIM > i
FTensor::Index< 'j', 3 > j
constexpr IntegrationType I
constexpr AssemblyType A
double scale
Definition plastic.cpp:123
constexpr auto field_name
FTensor::Index< 'm', 3 > m
static MoFEMErrorCode add(boost::ptr_deque< ForcesAndSourcesCore::UserDataOperator > &pipeline, MoFEM::Interface &m_field, std::string field_name, std::vector< boost::shared_ptr< ScalingMethod > > smv, double scale, std::string block_name, Sev sev)
static MoFEMErrorCode getParams(double &density, std::array< double, 3 > &gravity, std::array< double, 3 > &zero_pressure, boost::shared_ptr< Range > &ents, MoFEM::Interface &m_field, int ms_id)
virtual moab::Interface & get_moab()=0
virtual MPI_Comm & get_comm() const =0
Deprecated interface functions.
VectorDouble locF
local entity vector
int nbRows
number of dofs on rows
int nbIntegrationPts
number of integration points
int nbRowBaseFunctions
number or row base functions
MoFEMErrorCode getInterface(IFACE *&iface) const
Get interface reference to pointer of interface.