v0.15.5
Loading...
Searching...
No Matches
DirichletBC.hpp
Go to the documentation of this file.
1/* \file Dirichlet.hpp
2 * \brief Implementation of Dirichlet boundary conditions
3 * \ingroup Dirichlet_bc
4 *
5 * Structures and method in this file erase rows and column, set value on
6 * matrix diagonal and on the right hand side vector to enforce boundary
7 * condition.
8 *
9 * Current implementation is suboptimal, classes name too long. Need to
10 * rethinking and improved, more elegant and more efficient implementation.
11 *
12 */
13
14/* Notes:
15
16 DirichletSetFieldFromBlock implemented by Zahur Ullah
17 (Zahur.Ullah@glasgow.ac.uk)
18
19 */
20
21
22
23#ifndef __DIRICHLET_HPP__
24#define __DIRICHLET_HPP__
25
26using namespace boost::numeric;
27
28/** \brief Data from Cubit blocksets
29 * \ingroup Dirichlet_bc
30 */
31struct DataFromBc {
32 VectorDouble scaled_values;
33 VectorDouble initial_values;
34 VectorInt bc_flags;
36
37 // for rotation
41 double theta;
42
45
46 MoFEMErrorCode getBcData(DisplacementCubitBcData &mydata,
47 const MoFEM::CubitMeshSets *it);
48 MoFEMErrorCode getBcData(std::vector<double> &mydata,
49 const MoFEM::CubitMeshSets *it);
50 MoFEMErrorCode getEntitiesFromBc(MoFEM::Interface &mField,
51 const MoFEM::CubitMeshSets *it);
52};
53
54/** \brief Set Dirichlet boundary conditions on displacements
55 * \ingroup Dirichlet_bc
56 */
58
60 const std::string fieldName; ///< field name to set Dirichlet BC
61 double dIag; ///< diagonal value set on zeroed column and rows
62
64 const std::string &field_name, Mat Aij, Vec X, Vec F,
65 string blockset_name = "DISPLACEMENT");
67 const std::string &field_name,
68 string blockset_name = "DISPLACEMENT");
69
70 std::map<DofIdx, FieldData> mapZeroRows;
71 std::vector<int> dofsIndices;
72 std::vector<double> dofsValues;
73 std::vector<double> dofsXValues;
74 const std::string blocksetName;
75
76 boost::ptr_vector<MethodForForceScaling> methodsOp;
77 virtual MoFEMErrorCode iNitialize();
78
79 MoFEMErrorCode preProcess();
80 MoFEMErrorCode operator()() { return 0; }
81 MoFEMErrorCode postProcess();
82 /**
83 * @brief Get the Bc Data From Sets And Blocks object
84 * Use DISPLACEMENT blockset name (default)
85 * with 6 atributes:
86 * 1,2,3 are values of displacements x,y,z
87 * 4,5,6 are flags for x,y,z (0 or 1)
88 * @param bc_data
89 * @return MoFEMErrorCode
90 */
91 MoFEMErrorCode getBcDataFromSetsAndBlocks(std::vector<DataFromBc> &bc_data);
92 /**
93 * @brief Get the Rotation Bc From Block object
94 * Use ROTATION blockset name
95 * with 7 atributes:
96 * 1,2,3 are x,y,z coords of the center of rotation
97 * 4,5,6 are are angular velocities in x,y,z
98 * @param bc_data
99 * @return MoFEMErrorCode
100 */
101 MoFEMErrorCode getRotationBcFromBlock(std::vector<DataFromBc> &bc_data);
102
103 /**
104 * @brief Calculate displacements from rotation for particular dof
105 * @param dof
106 * @param bc_data
107 * @return MoFEMErrorCode
108 */
109 MoFEMErrorCode calculateRotationForDof(VectorDouble3 &coords,
110 DataFromBc &bc_data);
111 MoFEMErrorCode calculateRotationForDof(EntityHandle ent,
112 DataFromBc &bc_data);
113 MoFEMErrorCode applyScaleBcData(DataFromBc &bc_data);
114};
115
120 DataFromBc &data_from_dirichlet_bc)
121 : dirichletBcPtr(dirichlet_bc_ptr), dataFromDirichletBc(data_from_dirichlet_bc) {}
122
123 MoFEMErrorCode preProcess() { return 0; }
124 MoFEMErrorCode postProcess() { return 0; }
125 MoFEMErrorCode operator()() {
127 auto &bc_it = dataFromDirichletBc;
128
129 EntityHandle v = entPtr->getEnt();
130 int coeff = fieldPtr->getNbOfCoeffs();
132 for (int i = 0; i != coeff; i++) {
133 if (bc_it.bc_flags[i]) {
134 if (entPtr->getEntType() == MBVERTEX) {
135 entPtr->getEntFieldData()[i] = bc_it.scaled_values[i];
136 } else if (!entPtr->getEntFieldData().empty()) {
137 entPtr->getEntFieldData()[i] = 0;
138 }
139 }
140 }
141
143 }
144};
145
147 // using BcEntMethodDisp::BcEntMethodDisp;
152 DataFromBc &data_from_dirichlet_bc,
153 string material_positions)
154 : dirichletBcPtr(dirichlet_bc_ptr),
155 dataFromDirichletBc(data_from_dirichlet_bc),
156 materialPositions(material_positions) {}
157
158 MoFEMErrorCode preProcess() { return 0; }
159 MoFEMErrorCode postProcess() { return 0; }
160
161 MoFEMErrorCode operator()() {
163 EntityHandle ent = entPtr->getEnt();
164 auto &mField = dirichletBcPtr->mField;
165 auto &bc_it = dataFromDirichletBc;
166 EntityHandle v = entPtr->getEnt();
167
168 const FieldEntity_multiIndex *field_ents;
169 CHKERR mField.get_field_ents(&field_ents);
170 auto &field_ents_by_uid = field_ents->get<Unique_mi_tag>();
171
172 auto get_coords = [&]() {
173 VectorDouble coords({0, 0, 0});
174 if (entPtr->getEntType() == MBVERTEX) {
175 auto eit =
176 field_ents_by_uid.find(FieldEntity::getLocalUniqueIdCalculate(
177 mField.get_field_bit_number(materialPositions), ent));
178 if (eit != field_ents_by_uid.end())
179 noalias(coords) = (*eit)->getEntFieldData();
180 else
181 CHKERR mField.get_moab().get_coords(&ent, 1, &*coords.data().begin());
182 }
183 return coords;
184 };
185
186 int coeff = fieldPtr->getNbOfCoeffs();
187 auto coords = get_coords();
188
190 for (int i = 0; i != coeff; i++) {
191 if (bc_it.bc_flags[i]) {
192 if (entPtr->getEntType() == MBVERTEX) {
193 entPtr->getEntFieldData()[i] = coords(i) + bc_it.scaled_values[i];
194 } else if (!entPtr->getEntFieldData().empty()) {
195 entPtr->getEntFieldData()[i] = 0;
196 }
197 }
198 }
199
201 }
202};
203
204/// \deprecated use DirichletDisplacementBc
206
207/** \brief Set Dirichlet boundary conditions on spatial displacements
208 * \ingroup Dirichlet_bc
209 */
211
213 MoFEM::Interface &m_field, const std::string &field_name, Mat aij, Vec x,
214 Vec f, const std::string material_positions = "MESH_NODE_POSITIONS",
215 const std::string blockset_name = "DISPLACEMENT")
216 : DirichletDisplacementBc(m_field, field_name, aij, x, f, blockset_name),
217 materialPositions(material_positions) {}
218
220 MoFEM::Interface &m_field, const std::string &field_name,
221 const std::string material_positions = "MESH_NODE_POSITIONS",
222 const std::string blockset_name = "DISPLACEMENT")
223 : DirichletDisplacementBc(m_field, field_name, blockset_name),
224 materialPositions(material_positions) {}
225
226 std::string materialPositions; ///< name of the field with reference material
227 ///< positions
228 std::vector<std::string> fixFields; ///<
229
230 VectorDouble cOords;
231 MoFEMErrorCode iNitialize();
232};
233
234/// \deprecated use DirichletSpatialPositionsBc
237
239
241 const std::string &field_name, Mat aij, Vec x, Vec f)
242 : DirichletDisplacementBc(m_field, field_name, aij, x, f) {}
243
245 const std::string &field_name)
247
248 MoFEMErrorCode iNitialize();
249};
250
251/// \deprecated use DirichletTemperatureBc
253
254/** \brief Fix dofs on entities
255 * \ingroup Dirichlet_bc
256 */
258
260 std::vector<std::string> fieldNames;
262 const std::string field_name, Mat aij, Vec x,
263 Vec f, Range &ents)
264 : DirichletDisplacementBc(m_field, field_name, aij, x, f), eNts(ents) {
265 fieldNames.push_back(fieldName);
266 }
267
269 const std::string field_name, Range &ents)
270 : DirichletDisplacementBc(m_field, field_name), eNts(ents) {
271 fieldNames.push_back(fieldName);
272 }
273
274 MoFEMErrorCode iNitialize();
275 MoFEMErrorCode preProcess();
276 MoFEMErrorCode postProcess();
277};
278
279/** \brief Set Dirichlet boundary conditions on displacements by removing dofs
280 * \ingroup Dirichlet_bc
281 */
283
284 boost::shared_ptr<vector<DataFromBc>> bcDataPtr;
287
289 const std::string &field_name,
290 const std::string &problem_name,
291 string blockset_name = "DISPLACEMENT",
292 bool is_partitioned = false)
293 : DirichletDisplacementBc(m_field, field_name, blockset_name),
294 problemName(problem_name), isPartitioned(is_partitioned) {}
295
296 MoFEMErrorCode iNitialize();
297
298 virtual boost::shared_ptr<EntityMethod> getEntMethodPtr(DataFromBc &data) {
299 return boost::make_shared<BcEntMethodDisp>(this, data);
300 }
301
302 MoFEMErrorCode preProcess();
303 MoFEMErrorCode operator()() { return 0; }
304 MoFEMErrorCode postProcess() { return 0; }
305};
306
307/** \brief Set Dirichlet boundary conditions on spatial positions by removing dofs
308 * \ingroup Dirichlet_bc
309 */
311
312 std::string materialPositions;
313
315 MoFEM::Interface &m_field, const std::string &field_name,
316 const std::string &problem_name,
317 const std::string material_positions = "MESH_NODE_POSITIONS",
318 string blockset_name = "DISPLACEMENT", bool is_partitioned = false)
319 : DirichletDisplacementRemoveDofsBc(m_field, field_name, problem_name, blockset_name,
320 is_partitioned),
321 materialPositions(material_positions) {}
322
323 boost::shared_ptr<EntityMethod> getEntMethodPtr(DataFromBc &data) override {
324 return boost::make_shared<BcEntMethodSpatial>(this, data,
326 }
327};
328
329/// \deprecated use DirichletFixFieldAtEntitiesBc
331
332/**
333 * \brief Add boundary conditions form block set having 6 attributes
334 *
335 * First 3 values are magnitudes of dofs e.g. in x,y,z direction and next 3 are
336 flags, respectively.
337 * If flag is false ( = 0), particular dof is not taken into account.
338 Usage in Cubit for displacement:
339 block 1 tri 28 32
340 block 1 name "DISPLACEMENT_1"
341 block 1 attribute count 6
342 block 1 attribute index 1 97 # any value
343 block 1 attribute index 2 0
344 block 1 attribute index 3 0
345 block 1 attribute index 4 0 # flag for x dir
346 block 1 attribute index 5 1 # flag for y dir
347 block 1 attribute index 6 1 # flag for z dir
348 This means that we set zero displacement on y and z dir and on x set
349 direction freely. (value 97 is irrelevant because flag for 1 value is 0
350 (false)) It can be usefull if we want to set boundary conditions directly to
351 triangles e.g, since standard boundary conditions in Cubit allow only using
352 nodeset or surface which might not work with mesh based on facet engine (e.g.
353 STL file)
354 */
356
358 const std::string &field_name,
359 const std::string &blockset_name, Mat aij,
360 Vec x, Vec f)
361 : DirichletDisplacementBc(m_field, field_name, aij, x, f, blockset_name) {
362 }
363
365 const std::string &field_name,
366 const std::string &blockset_name)
367 : DirichletDisplacementBc(m_field, field_name, blockset_name) {}
368};
369
370/// \deprecated use DirichletSetFieldFromBlockWithFlags
373
374/// \deprecated use DirichletSetFieldFromBlockWithFlags
377
378/// \deprecated use DirichletSetFieldFromBlockWithFlags
381/**
382 * @brief calculate reactions from vector of internal forces on meshsets
383 *
384 * example usage
385 *
386 * \code
387 Vec F_int;
388 DMCreateGlobalVector_MoFEM(dm, &F_int);
389
390 feRhs->snes_ctx = FEMethod::CTX_SNESSETFUNCTION;
391 feRhs->snes_f = F_int;
392 DMoFEMLoopFiniteElements(dm, "ELASTIC", feRhs);
393
394 VecAssemblyBegin(F_int);
395 VecAssemblyEnd(F_int);
396 VecGhostUpdateBegin(F_int, INSERT_VALUES, SCATTER_FORWARD);
397 VecGhostUpdateEnd(F_int, INSERT_VALUES, SCATTER_FORWARD);
398
399 Reactions my_react(m_field, "DM_ELASTIC", "U");
400 my_react.calculateReactions(F_int);
401 int fix_nodes_meshset_id = 1;
402 cout << my_react.getReactionsFromSet(fix_nodes_meshset_id) << endl;
403
404* \endcode
405 */
406struct Reactions {
407
408 Reactions(MoFEM::Interface &m_field, string problem_name, string field_name)
409 : mField(m_field), problemName(problem_name), fieldName(field_name) {}
410
411 typedef std::map<int, VectorDouble> ReactionsMap;
413 /**
414 * @brief Get the Reactions Map
415 *
416 * @return const ReactionsMap&
417 */
418 inline const ReactionsMap &getReactionsMap() const { return reactionsMap; }
419 /**
420 * @brief Get the Reactions at specified meshset id
421 *
422 * @param id meshset id (from Cubit)
423 * @return const VectorDouble&
424 */
425 inline const VectorDouble &getReactionsFromSet(const int &id) const {
426 return reactionsMap.at(id);
427 }
428 /**
429 * @brief calculate reactions from a given vector
430 *
431 * @param internal forces vector
432 * @return MoFEMErrorCode
433 */
434 MoFEMErrorCode calculateReactions(Vec &internal);
435
436private:
437 std::string problemName;
438 std::string fieldName;
440};
441
442#endif //__DIRICHLET_HPP__
443
444/**
445 * \defgroup Dirichlet_bc Dirichlet boundary conditions
446 * \ingroup user_modules
447 **/
DEPRECATED typedef DirichletSetFieldFromBlockWithFlags DirichletSetFieldFromBlock
DEPRECATED typedef DirichletFixFieldAtEntitiesBc FixBcAtEntities
DEPRECATED typedef DirichletDisplacementBc DisplacementBCFEMethodPreAndPostProc
DEPRECATED typedef DirichletSetFieldFromBlockWithFlags DirichletBCFromBlockSetFEMethodPreAndPostProc
DEPRECATED typedef DirichletSetFieldFromBlockWithFlags DirichletBCFromBlockSetFEMethodPreAndPostProcWithFlags
DEPRECATED typedef DirichletTemperatureBc TemperatureBCFEMethodPreAndPostProc
DEPRECATED typedef DirichletSpatialPositionsBc SpatialPositionsBCFEMethodPreAndPostProc
#define MoFEMFunctionBegin
First executable line of each MoFEM function, used for error handling. Final line of MoFEM functions ...
#define DEPRECATED
Definition definitions.h:17
#define MoFEMFunctionReturn(a)
Last executable line of each PETSc function used for error handling. Replaces return()
#define CHKERR
Inline error check.
@ F
multi_index_container< boost::shared_ptr< FieldEntity >, indexed_by< ordered_unique< tag< Unique_mi_tag >, member< FieldEntity, UId, &FieldEntity::localUId > >, ordered_non_unique< tag< Ent_mi_tag >, const_mem_fun< FieldEntity::interface_type_RefEntity, EntityHandle, &FieldEntity::getEnt > > > > FieldEntity_multiIndex
MultiIndex container keeps FieldEntity.
FTensor::Index< 'i', SPACE_DIM > i
const double v
phase velocity of light in medium (cm/ns)
constexpr auto field_name
MoFEMErrorCode postProcess()
Post-processing function executed at loop completion.
DirichletDisplacementBc * dirichletBcPtr
MoFEMErrorCode operator()()
Main operator function executed for each loop iteration.
BcEntMethodDisp(DirichletDisplacementBc *dirichlet_bc_ptr, DataFromBc &data_from_dirichlet_bc)
DataFromBc & dataFromDirichletBc
MoFEMErrorCode preProcess()
Pre-processing function executed at loop initialization.
DataFromBc & dataFromDirichletBc
MoFEMErrorCode postProcess()
Post-processing function executed at loop completion.
BcEntMethodSpatial(DirichletDisplacementBc *dirichlet_bc_ptr, DataFromBc &data_from_dirichlet_bc, string material_positions)
MoFEMErrorCode preProcess()
Pre-processing function executed at loop initialization.
DirichletDisplacementBc * dirichletBcPtr
MoFEMErrorCode operator()()
Main operator function executed for each loop iteration.
Data from Cubit blocksets.
VectorInt bc_flags
FTensor::Tensor1< double, 3 > t_centr
MoFEMErrorCode getBcData(DisplacementCubitBcData &mydata, const MoFEM::CubitMeshSets *it)
MoFEMErrorCode getEntitiesFromBc(MoFEM::Interface &mField, const MoFEM::CubitMeshSets *it)
VectorDouble scaled_values
FTensor::Tensor1< double, 3 > t_normal
VectorDouble initial_values
Range bc_ents[3]
Set Dirichlet boundary conditions on displacements.
const std::string blocksetName
MoFEMErrorCode postProcess()
Post-processing function executed at loop completion.
std::map< DofIdx, FieldData > mapZeroRows
MoFEMErrorCode getRotationBcFromBlock(std::vector< DataFromBc > &bc_data)
Get the Rotation Bc From Block object Use ROTATION blockset name with 7 atributes: 1,...
const std::string fieldName
field name to set Dirichlet BC
MoFEMErrorCode operator()()
Main operator function executed for each loop iteration.
double dIag
diagonal value set on zeroed column and rows
std::vector< int > dofsIndices
MoFEMErrorCode preProcess()
Pre-processing function executed at loop initialization.
MoFEMErrorCode getBcDataFromSetsAndBlocks(std::vector< DataFromBc > &bc_data)
Get the Bc Data From Sets And Blocks object Use DISPLACEMENT blockset name (default) with 6 atributes...
MoFEMErrorCode applyScaleBcData(DataFromBc &bc_data)
std::vector< double > dofsXValues
boost::ptr_vector< MethodForForceScaling > methodsOp
std::vector< double > dofsValues
MoFEM::Interface & mField
virtual MoFEMErrorCode iNitialize()
MoFEMErrorCode calculateRotationForDof(VectorDouble3 &coords, DataFromBc &bc_data)
Calculate displacements from rotation for particular dof.
Set Dirichlet boundary conditions on displacements by removing dofs.
MoFEMErrorCode preProcess()
Pre-processing function executed at loop initialization.
virtual boost::shared_ptr< EntityMethod > getEntMethodPtr(DataFromBc &data)
DirichletDisplacementRemoveDofsBc(MoFEM::Interface &m_field, const std::string &field_name, const std::string &problem_name, string blockset_name="DISPLACEMENT", bool is_partitioned=false)
boost::shared_ptr< vector< DataFromBc > > bcDataPtr
MoFEMErrorCode operator()()
Main operator function executed for each loop iteration.
MoFEMErrorCode postProcess()
Post-processing function executed at loop completion.
Fix dofs on entities.
std::vector< std::string > fieldNames
DirichletFixFieldAtEntitiesBc(MoFEM::Interface &m_field, const std::string field_name, Mat aij, Vec x, Vec f, Range &ents)
DirichletFixFieldAtEntitiesBc(MoFEM::Interface &m_field, const std::string field_name, Range &ents)
MoFEMErrorCode postProcess()
Post-processing function executed at loop completion.
MoFEMErrorCode preProcess()
Pre-processing function executed at loop initialization.
Add boundary conditions form block set having 6 attributes.
DirichletSetFieldFromBlockWithFlags(MoFEM::Interface &m_field, const std::string &field_name, const std::string &blockset_name)
DirichletSetFieldFromBlockWithFlags(MoFEM::Interface &m_field, const std::string &field_name, const std::string &blockset_name, Mat aij, Vec x, Vec f)
Set Dirichlet boundary conditions on spatial displacements.
std::vector< std::string > fixFields
DirichletSpatialPositionsBc(MoFEM::Interface &m_field, const std::string &field_name, Mat aij, Vec x, Vec f, const std::string material_positions="MESH_NODE_POSITIONS", const std::string blockset_name="DISPLACEMENT")
DirichletSpatialPositionsBc(MoFEM::Interface &m_field, const std::string &field_name, const std::string material_positions="MESH_NODE_POSITIONS", const std::string blockset_name="DISPLACEMENT")
Set Dirichlet boundary conditions on spatial positions by removing dofs.
boost::shared_ptr< EntityMethod > getEntMethodPtr(DataFromBc &data) override
DirichletSpatialRemoveDofsBc(MoFEM::Interface &m_field, const std::string &field_name, const std::string &problem_name, const std::string material_positions="MESH_NODE_POSITIONS", string blockset_name="DISPLACEMENT", bool is_partitioned=false)
DirichletTemperatureBc(MoFEM::Interface &m_field, const std::string &field_name, Mat aij, Vec x, Vec f)
MoFEMErrorCode iNitialize()
DirichletTemperatureBc(MoFEM::Interface &m_field, const std::string &field_name)
this struct keeps basic methods for moab meshset about material and boundary conditions
Deprecated interface functions.
Data structure for user loop methods on entities.
boost::shared_ptr< Field > fieldPtr
Shared pointer to field information.
boost::shared_ptr< FieldEntity > entPtr
Shared pointer to field entity data.
Structure for user loop methods on finite elements.
Vec f
PETSc residual vector.
Vec x
PETSc solution vector.
calculate reactions from vector of internal forces on meshsets
std::string problemName
const ReactionsMap & getReactionsMap() const
Get the Reactions Map.
MoFEM::Interface & mField
ReactionsMap reactionsMap
MoFEMErrorCode calculateReactions(Vec &internal)
calculate reactions from a given vector
std::string fieldName
Reactions(MoFEM::Interface &m_field, string problem_name, string field_name)
std::map< int, VectorDouble > ReactionsMap
const VectorDouble & getReactionsFromSet(const int &id) const
Get the Reactions at specified meshset id.