v0.16.0
Loading...
Searching...
No Matches
map_disp_prism.cpp
Go to the documentation of this file.
1/* Copyright (c) 2025 Authors under the MIT License.
2 * See LICENSE.md for details.
3 * SPDX-License-Identifier: MIT
4 */
5
6#include <MoFEM.hpp>
7using namespace MoFEM;
8
9#include <iostream>
10#include <fstream> // fstream
11#include <vector>
12#include <string>
13#include <algorithm> // copy
14#include <iterator> // ostream_operator
15#include <boost/tokenizer.hpp>
16#include <DispMap.hpp>
17
18using namespace boost;
19using namespace CellEngineering;
20
21static char help[] = "\n";
22
23int main(int argc, char *argv[]) {
24 MoFEM::Core::Initialize(&argc, &argv, (char *)0, help);
25
26 try {
27
28 moab::Core mb_instance;
29 moab::Interface &moab = mb_instance;
30
31 // global variables
32 char mesh_file_name[255];
33 char data_file_name1[255];
34 char data_file_name2[255];
35 PetscBool flg_file = PETSC_FALSE;
36 PetscInt order = 1;
37 PetscBool flg_n_part = PETSC_FALSE;
38 PetscInt n_partas = 1;
39 PetscBool flg_thickness = PETSC_FALSE;
40 double thickness = 0;
41
42 PetscOptionsBegin(PETSC_COMM_WORLD, "", "none", "none");
43 CHKERR PetscOptionsString("-my_file", "mesh file name", "", "mesh.h5m",
44 mesh_file_name, 255, &flg_file);
45
46 CHKERR PetscOptionsString("-my_data_x", "data file name", "", "data_x.h5m",
47 data_file_name1, 255, PETSC_NULLPTR);
48
49 CHKERR PetscOptionsString("-my_data_y", "data file name", "", "data_y.h5m",
50 data_file_name2, 255, PETSC_NULLPTR);
51
52 CHKERR PetscOptionsInt("-my_order", "default approximation order", "", 1,
53 &order, PETSC_NULLPTR);
54
55 CHKERR PetscOptionsInt("-my_nparts", "number of parts", "", 1, &n_partas,
56 &flg_n_part);
57
58 CHKERR PetscOptionsScalar("-my_thinckness", "top layer thickness", "",
59 thickness, &thickness, &flg_thickness);
60
61 PetscOptionsEnd();
62
63 if (flg_file != PETSC_TRUE) {
64 SETERRQ(PETSC_COMM_SELF, 1, "*** ERROR -my_file (MESH FILE NEEDED)");
65 }
66
67 if (flg_n_part != PETSC_TRUE) {
68 SETERRQ(PETSC_COMM_SELF, 1, "*** ERROR partitioning number not given");
69 }
70
71 if (flg_thickness != PETSC_TRUE) {
72 SETERRQ(PETSC_COMM_SELF, 1, "*** ERROR thickness of top layer not given");
73 }
74
75 const char *option;
76 option = "";
77 CHKERR moab.load_file(mesh_file_name, 0, option);
78 ParallelComm *pcomm = ParallelComm::get_pcomm(&moab, MYPCOMM_INDEX);
79 if (pcomm == nullptr)
80 pcomm = new ParallelComm(&moab, PETSC_COMM_WORLD);
81
82 MoFEM::Core core(moab);
83 MoFEM::Interface &m_field = core;
84 // meshset consisting all entities in mesh
85 EntityHandle root_set = moab.get_root_set();
86
87 // Seed all mesh entities to MoFEM database, those entities can be
88 // potentially used as finite elements or as entities which carry some
89 // approximation field.
90 BitRefLevel bit_level0;
91 bit_level0.set(0);
92 CHKERR m_field.getInterface<BitRefManager>()->setBitRefLevelByDim(
93 root_set, 3, bit_level0);
94 // Add field
95 CHKERR m_field.add_field("DISP_X", H1, AINSWORTH_LEGENDRE_BASE, 1);
96 CHKERR m_field.add_field("DISP_Y", H1, AINSWORTH_LEGENDRE_BASE, 1);
97
98 auto *meshsets_manager_ptr = m_field.getInterface<MeshsetsManager>();
99
101 CHKERR meshsets_manager_ptr->getEntitiesByDimension(101, SIDESET, 2,
102 surface, true);
103 CHKERR m_field.add_ents_to_field_by_type(surface, MBTRI, "DISP_X");
104 CHKERR m_field.add_ents_to_field_by_type(surface, MBTRI, "DISP_Y");
105
106 CHKERR m_field.set_field_order(0, MBVERTEX, "DISP_X", 1);
107 CHKERR m_field.set_field_order(0, MBEDGE, "DISP_X", order);
108 CHKERR m_field.set_field_order(0, MBTRI, "DISP_X", order);
109
110 CHKERR m_field.set_field_order(0, MBVERTEX, "DISP_Y", 1);
111 CHKERR m_field.set_field_order(0, MBEDGE, "DISP_Y", order);
112 CHKERR m_field.set_field_order(0, MBTRI, "DISP_Y", order);
113
114 CHKERR m_field.build_fields();
115
116 CHKERR m_field.add_finite_element("DISP_MAP_ELEMENT");
117 CHKERR m_field.modify_finite_element_add_field_row("DISP_MAP_ELEMENT",
118 "DISP_X");
119 CHKERR m_field.modify_finite_element_add_field_col("DISP_MAP_ELEMENT",
120 "DISP_X");
121 CHKERR m_field.modify_finite_element_add_field_data("DISP_MAP_ELEMENT",
122 "DISP_X");
123 CHKERR m_field.modify_finite_element_add_field_data("DISP_MAP_ELEMENT",
124 "DISP_Y");
125
126 // Add entities to that element
128 "DISP_MAP_ELEMENT");
129
130 // build finite elements
132 // build adjacencies between elements and degrees of freedom
133 CHKERR m_field.build_adjacencies(bit_level0);
134
135 // set discrete manager
136 DM dm_disp;
137 DMType dm_name = "DM_DISP";
138 // Register DM problem
139 CHKERR DMRegister_MoFEM(dm_name);
140 CHKERR DMCreate(PETSC_COMM_WORLD, &dm_disp);
141 CHKERR DMSetType(dm_disp, dm_name);
142 // Create DM instance
143 CHKERR DMMoFEMCreateMoFEM(dm_disp, &m_field, dm_name, bit_level0);
144 // Configure DM form line command options (DM itself, solvers,
145 // pre-conditioners, ... )
146 CHKERR DMSetFromOptions(dm_disp);
147 // Add elements to dm (only one here)
148 CHKERR DMMoFEMAddElement(dm_disp, "DISP_MAP_ELEMENT");
149 // Set up problem (number dofs, partition mesh, etc.)
150 CHKERR DMSetUp(dm_disp);
151
152 DispMapFe fe_face(m_field);
153
154 // string file(argv[1]); cout << "argument 1:" << argv[1] <<endl;
155 // string file2(argv[2]); cout << "argument 2:" << argv[2] <<endl;
156
157 string file1(data_file_name1);
158 DataFromFiles data_from_files(file1);
159 CHKERR data_from_files.fromOptions();
160 CHKERR data_from_files.loadFileData();
161
162 string file2(data_file_name2);
163 DataFromFiles data_from_files2(file2);
164 CHKERR data_from_files2.fromOptions();
165 CHKERR data_from_files2.loadFileData();
166
167 auto &list_of_operators = fe_face.getOpPtrVector();
168
169 Mat A;
170 Vec Fx, Dx;
171 CHKERR DMCreateMatrix(dm_disp, &A);
172 CHKERR m_field.getInterface<VecManager>()->vecCreateGhost("DM_DISP", ROW,
173 &Fx);
174 CHKERR m_field.getInterface<VecManager>()->vecCreateGhost("DM_DISP", COL,
175 &Dx);
176 Vec Fy, Dy;
177 CHKERR VecDuplicate(Fx, &Fy);
178 CHKERR VecDuplicate(Dx, &Dy);
179
180 CHKERR MatZeroEntries(A);
181 CHKERR VecZeroEntries(Fx);
182 CHKERR VecZeroEntries(Fy);
183
184 CommonData common_data;
185 common_data.globA = A;
186
187 common_data.globF = Fx;
188
189 auto det_ptr = boost::make_shared<VectorDouble>();
190 auto jac_ptr = boost::make_shared<MatrixDouble>();
191 auto inv_jac_ptr = boost::make_shared<MatrixDouble>();
192 list_of_operators.push_back(new OpCalculateHOJacForFace(jac_ptr));
193 list_of_operators.push_back(
194 new OpInvertMatrix<2>(jac_ptr, det_ptr, inv_jac_ptr));
195 list_of_operators.push_back(new OpSetInvJacH1ForFace(inv_jac_ptr));
196 list_of_operators.push_back(
197 new OpCalculateLhs("DISP_X", "DISP_X", common_data, data_from_files));
198 list_of_operators.push_back(
199 new OpCalulatefRhoAtGaussPts("DISP_X", common_data, data_from_files));
200 list_of_operators.push_back(new OpAssembleRhs("DISP_X", common_data));
201
202 CHKERR DMoFEMLoopFiniteElements(dm_disp, "DISP_MAP_ELEMENT", &fe_face);
203
204 // cout << "error.no !" <<error++ << endl;
205 CHKERR MatAssemblyBegin(A, MAT_FINAL_ASSEMBLY);
206 CHKERR MatAssemblyEnd(A, MAT_FINAL_ASSEMBLY);
207 CHKERR VecGhostUpdateBegin(Fx, ADD_VALUES, SCATTER_REVERSE);
208 CHKERR VecGhostUpdateEnd(Fx, ADD_VALUES, SCATTER_REVERSE);
209 CHKERR VecAssemblyBegin(Fx);
210 CHKERR VecAssemblyEnd(Fx);
211
212 // int error=1;
213 common_data.globF = Fy;
214 list_of_operators.clear();
215 list_of_operators.push_back(new OpCalculateHOJacForFace(jac_ptr));
216 list_of_operators.push_back(
217 new OpInvertMatrix<2>(jac_ptr, det_ptr, inv_jac_ptr));
218 list_of_operators.push_back(new OpSetInvJacH1ForFace(inv_jac_ptr));
219 list_of_operators.push_back(
220 new OpCalulatefRhoAtGaussPts("DISP_X", common_data, data_from_files2));
221 list_of_operators.push_back(new OpAssembleRhs("DISP_X", common_data));
222 // cout << "error.no !"<< error++<< endl;
223
224 CHKERR DMoFEMLoopFiniteElements(dm_disp, "DISP_MAP_ELEMENT", &fe_face);
225 // cout << "error.no !" <<error++ << endl;
226 CHKERR VecGhostUpdateBegin(Fy, ADD_VALUES, SCATTER_REVERSE);
227 CHKERR VecGhostUpdateEnd(Fy, ADD_VALUES, SCATTER_REVERSE);
228 CHKERR VecAssemblyBegin(Fy);
229 CHKERR VecAssemblyEnd(Fy);
230
231 // VecView(F,PETSC_VIEWER_DRAW_WORLD);
232 // MatView(A,PETSC_VIEWER_DRAW_WORLD);
233 // std::string wait;
234 // std::cin >> wait;
235
236 // solve
237 {
238 KSP ksp;
239 CHKERR KSPCreate(PETSC_COMM_WORLD, &ksp);
240 CHKERR KSPSetOperators(ksp, A, A);
241 CHKERR KSPSetFromOptions(ksp);
242 CHKERR KSPSolve(ksp, Fx, Dx);
243 CHKERR KSPSolve(ksp, Fy, Dy);
244 }
245
246 CHKERR VecGhostUpdateBegin(Dx, INSERT_VALUES, SCATTER_FORWARD);
247 CHKERR VecGhostUpdateEnd(Dx, INSERT_VALUES, SCATTER_FORWARD);
248 CHKERR m_field.getInterface<VecManager>()->setGlobalGhostVector(
249 "DM_DISP", COL, Dx, INSERT_VALUES, SCATTER_REVERSE);
250 CHKERR VecGhostUpdateBegin(Dy, INSERT_VALUES, SCATTER_FORWARD);
251 CHKERR VecGhostUpdateEnd(Dy, INSERT_VALUES, SCATTER_FORWARD);
252 CHKERR m_field.getInterface<VecManager>()->setOtherGlobalGhostVector(
253 "DM_DISP", "DISP_X", "DISP_Y", COL, Dy, INSERT_VALUES, SCATTER_REVERSE);
254
255 // Remove rigid translation
256 double sum_dx = 0;
257 int nb_dx = 0;
259 MBVERTEX, dof)) {
260 sum_dx += (*dof)->getFieldData();
261 nb_dx++;
262 }
263 sum_dx /= nb_dx;
265 MBVERTEX, dof)) {
266 (*dof)->getFieldData() -= sum_dx;
267 }
268 double sum_dy = 0;
269 int nb_dy = 0;
271 MBVERTEX, dof)) {
272 sum_dy += (*dof)->getFieldData();
273 nb_dy++;
274 }
275 sum_dy /= nb_dy;
277 MBVERTEX, dof)) {
278 (*dof)->getFieldData() -= sum_dy;
279 }
280
281 using PostProcFace =
284
285 PostProcFace post_proc(m_field);
287
288 auto disp_x_ptr = boost::make_shared<VectorDouble>();
289 auto disp_y_ptr = boost::make_shared<VectorDouble>();
290 post_proc.getOpPtrVector().push_back(
291 new OpCalculateScalarFieldValues("DISP_X", disp_x_ptr));
292 post_proc.getOpPtrVector().push_back(
293 new OpCalculateScalarFieldValues("DISP_Y", disp_y_ptr));
294 post_proc.getOpPtrVector().push_back(new OpPPMap(
295 post_proc.getPostProcMesh(), post_proc.getMapGaussPts(),
296 OpPPMap::DataMapVec{{"DISP_X", disp_x_ptr},
297 {"DISP_Y", disp_y_ptr}},
300
301 CHKERR DMoFEMLoopFiniteElements(dm_disp, "DISP_MAP_ELEMENT", &post_proc);
302 CHKERR post_proc.writeFile("out_disp.h5m");
303
304 CHKERR VecDestroy(&Fx);
305 CHKERR VecDestroy(&Fy);
306 CHKERR VecDestroy(&Dx);
307 CHKERR VecDestroy(&Dy);
308 CHKERR MatDestroy(&A);
309 CHKERR DMDestroy(&dm_disp);
310
311 // Delete element which will be no longer used
312 CHKERR m_field.delete_finite_element("DISP_MAP_ELEMENT");
313
314 // Add top layer
315 {
316 auto mmanager_ptr = m_field.getInterface<MeshsetsManager>();
317 Range ents_2nd_layer;
318 CHKERR mmanager_ptr->getEntitiesByDimension(101, SIDESET, 2,
319 ents_2nd_layer, true);
320 Range tris_nodes;
321 CHKERR moab.get_connectivity(ents_2nd_layer, tris_nodes, true);
322 std::map<EntityHandle, EntityHandle> map_nodes;
323 for (Range::iterator nit = tris_nodes.begin(); nit != tris_nodes.end();
324 nit++) {
325 double coords[3];
326 CHKERR moab.get_coords(&*nit, 1, coords);
327 coords[2] += thickness;
328 CHKERR moab.create_vertex(coords, map_nodes[*nit]);
329 }
330
331 Range prisms;
332 Range top_tris;
333 for (Range::iterator tit = ents_2nd_layer.begin();
334 tit != ents_2nd_layer.end(); tit++) {
335 int num_nodes;
336 const EntityHandle *conn;
337 CHKERR moab.get_connectivity(*tit, conn, num_nodes);
338 EntityHandle conn_prism[6];
339 for (int n = 0; n != 3; n++) {
340 conn_prism[n] = conn[n];
341 conn_prism[n + 3] = map_nodes[conn[n]];
342 }
343 EntityHandle prism;
344 CHKERR moab.create_element(MBPRISM, conn_prism, 6, prism);
345 Range adj;
346 CHKERR moab.get_adjacencies(&prism, 1, 2, true, adj);
347 CHKERR moab.get_adjacencies(&prism, 1, 1, true, adj);
348 prisms.insert(prism);
349 EntityHandle tri;
350 CHKERR moab.side_element(prism, 2, 4, tri);
351 top_tris.insert(tri);
352 }
353 CHKERR mmanager_ptr->addMeshset(SIDESET, 202);
354 CHKERR mmanager_ptr->addEntitiesToMeshset(SIDESET, 202, top_tris);
355 CHKERR mmanager_ptr->addMeshset(BLOCKSET, 2, "MAT_ELASTIC_2");
356 CHKERR mmanager_ptr->addEntitiesToMeshset(BLOCKSET, 2, prisms);
357 Mat_Elastic mat_elastic;
358 mat_elastic.data.Young = 1;
359 mat_elastic.data.Poisson = 0;
360 CHKERR mmanager_ptr->setAttributesByDataStructure(BLOCKSET, 2,
361 mat_elastic);
362 }
363
364 {
365 // Add one node to fix
366 auto mmanager_ptr = m_field.getInterface<MeshsetsManager>();
367 Range ents_1st_layer;
368 CHKERR mmanager_ptr->getEntitiesByDimension(202, SIDESET, 2,
369 ents_1st_layer, true);
370 int num_nodes;
371 const EntityHandle *conn;
372 CHKERR moab.get_connectivity(ents_1st_layer[0], conn, num_nodes);
373 Skinner skin(&moab);
374 Range skin_edges;
375 CHKERR skin.find_skin(0, ents_1st_layer, false, skin_edges);
376 Range edges;
377 CHKERR moab.get_adjacencies(&*ents_1st_layer.begin(), 1, 1, false, edges);
378 EntityHandle meshset;
379 CHKERR mmanager_ptr->getMeshset(202, SIDESET, meshset);
380 CHKERR moab.add_entities(meshset, conn, 1);
381 CHKERR moab.add_entities(meshset, skin_edges);
382 }
383
384 {
385 Range ents3d;
386 CHKERR moab.get_entities_by_dimension(0, 3, ents3d, false);
387 CHKERR m_field.getInterface<CommInterface>()->partitionMesh(
388 ents3d, 3, 2, n_partas);
389 }
390
391 CHKERR moab.write_file("analysis_mesh.h5m");
392 }
394
396
397 PetscFunctionReturn(0);
398}
int main()
@ COL
@ ROW
#define CATCH_ERRORS
Catch errors.
@ AINSWORTH_LEGENDRE_BASE
Ainsworth Cole (Legendre) approx. base .
Definition definitions.h:60
@ H1
continuous field
Definition definitions.h:85
#define MYPCOMM_INDEX
default communicator number PCOMM
@ SIDESET
@ BLOCKSET
#define CHKERR
Inline error check.
constexpr int order
PetscErrorCode DMMoFEMAddElement(DM dm, std::string fe_name)
add element to dm
Definition DMMoFEM.cpp:488
PetscErrorCode DMMoFEMCreateMoFEM(DM dm, MoFEM::Interface *m_field_ptr, const char problem_name[], const MoFEM::BitRefLevel bit_level, const MoFEM::BitRefLevel bit_mask=MoFEM::BitRefLevel().set())
Must be called by user to set MoFEM data structures.
Definition DMMoFEM.cpp:114
PetscErrorCode DMRegister_MoFEM(const char sname[])
Register MoFEM problem.
Definition DMMoFEM.cpp:43
PetscErrorCode DMoFEMLoopFiniteElements(DM dm, const char fe_name[], MoFEM::FEMethod *method, CacheTupleWeakPtr cache_ptr=CacheTupleSharedPtr())
Executes FEMethod for finite elements in DM.
Definition DMMoFEM.cpp:576
#define _IT_GET_DOFS_FIELD_BY_NAME_AND_TYPE_FOR_LOOP_(MFIELD, NAME, TYPE, IT)
loop over all dofs from a moFEM field and particular field
virtual MoFEMErrorCode add_finite_element(const std::string &fe_name, enum MoFEMTypes bh=MF_EXCL, int verb=DEFAULT_VERBOSITY)=0
add finite element
virtual MoFEMErrorCode build_finite_elements(int verb=DEFAULT_VERBOSITY)=0
Build finite elements.
virtual MoFEMErrorCode modify_finite_element_add_field_col(const std::string &fe_name, const std::string name_row)=0
set field col which finite element use
virtual MoFEMErrorCode add_ents_to_finite_element_by_type(const EntityHandle entities, const EntityType type, const std::string name, const bool recursive=true)=0
add entities to finite element
virtual MoFEMErrorCode modify_finite_element_add_field_row(const std::string &fe_name, const std::string name_row)=0
set field row which finite element use
virtual MoFEMErrorCode modify_finite_element_add_field_data(const std::string &fe_name, const std::string name_field)=0
set finite element field data
virtual MoFEMErrorCode build_fields(int verb=DEFAULT_VERBOSITY)=0
virtual MoFEMErrorCode set_field_order(const EntityHandle meshset, const EntityType type, const std::string &name, const ApproximationOrder order, int verb=DEFAULT_VERBOSITY)=0
Set order approximation of the entities in the field.
virtual MoFEMErrorCode add_ents_to_field_by_type(const Range &ents, const EntityType type, const std::string &name, int verb=DEFAULT_VERBOSITY)=0
Add entities to field meshset.
const double n
refractive index of diffusive medium
static char help[]
std::bitset< BITREFLEVEL_SIZE > BitRefLevel
Bit structure attached to each entity identifying to what mesh entity is attached.
Definition Types.hpp:40
implementation of Data Operators for Forces and Sources
Definition Common.hpp:10
OpCalculateHOJacForFaceImpl< 2 > OpCalculateHOJacForFace
constexpr AssemblyType A
OpPostProcMapInMoab< SPACE_DIM, SPACE_DIM > OpPPMap
MoFEMErrorCode loadFileData()
Definition DispMap.hpp:30
MoFEMErrorCode fromOptions()
Definition DispMap.hpp:58
Add operators pushing bases from local to physical configuration.
Managing BitRefLevels.
Managing BitRefLevels.
virtual MoFEMErrorCode build_adjacencies(const Range &ents, int verb=DEFAULT_VERBOSITY)=0
build adjacencies
virtual MoFEMErrorCode add_field(const std::string name, const FieldSpace space, const FieldApproximationBase base, const FieldCoefficientsNumber nb_of_coefficients, const TagType tag_type=MB_TAG_SPARSE, const enum MoFEMTypes bh=MF_EXCL, int verb=DEFAULT_VERBOSITY)=0
Add field.
Core (interface) class.
Definition Core.hpp:83
static MoFEMErrorCode Initialize(int *argc, char ***args, const char file[], const char help[])
Initializes the MoFEM database PETSc, MOAB and MPI.
Definition Core.cpp:68
static MoFEMErrorCode Finalize()
Checks for options to be called at the conclusion of the program.
Definition Core.cpp:123
Deprecated interface functions.
boost::ptr_deque< UserDataOperator > & getOpPtrVector()
Use to push back operator for row operator.
Elastic material data structure.
Interface for managing meshsets containing materials and boundary conditions.
Specialization for double precision scalar field values calculation.
Operator for inverting matrices at integration points.
Post post-proc data at points from hash maps.
std::map< std::string, ScalarDataPtr > DataMapVec
std::map< std::string, boost::shared_ptr< MatrixDouble > > DataMapMat
auto & getMapGaussPts()
Get vector of vectors associated to integration points.
auto & getPostProcMesh()
Get postprocessing mesh.
MoFEMErrorCode getInterface(IFACE *&iface) const
Get interface reference to pointer of interface.
Vector manager is used to create vectors \mofem_vectors.