v0.16.0
Loading...
Searching...
No Matches
map_disp.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
40 PetscOptionsBegin(PETSC_COMM_WORLD, "", "none", "none");
41 CHKERR PetscOptionsString("-my_file", "mesh file name", "", "mesh.h5m",
42 mesh_file_name, 255, &flg_file);
43
44 CHKERR PetscOptionsString("-my_data_x", "data file name", "", "data_x.h5m",
45 data_file_name1, 255, PETSC_NULLPTR);
46
47 CHKERR PetscOptionsString("-my_data_y", "data file name", "", "data_y.h5m",
48 data_file_name2, 255, PETSC_NULLPTR);
49
50 CHKERR PetscOptionsInt("-my_order", "default approximation order", "", 1,
51 &order, PETSC_NULLPTR);
52
53 CHKERR PetscOptionsInt("-my_nparts", "number of parts", "", 1, &n_partas,
54 &flg_n_part);
55
56 PetscOptionsEnd();
57
58 if (flg_file != PETSC_TRUE) {
59 SETERRQ(PETSC_COMM_SELF, 1, "*** ERROR -my_file (MESH FILE NEEDED)");
60 }
61
62 if (flg_n_part != PETSC_TRUE) {
63 SETERRQ(PETSC_COMM_SELF, 1, "*** ERROR partitioning number not given");
64 }
65
66 const char *option;
67 option = "";
68 CHKERR moab.load_file(mesh_file_name, 0, option);
69 ParallelComm *pcomm = ParallelComm::get_pcomm(&moab, MYPCOMM_INDEX);
70 if (pcomm == nullptr)
71 pcomm = new ParallelComm(&moab, PETSC_COMM_WORLD);
72
73 MoFEM::Core core(moab);
74 MoFEM::Interface &m_field = core;
75 // meshset consisting all entities in mesh
76 EntityHandle root_set = moab.get_root_set();
77
78 // Seed all mesh entities to MoFEM database, those entities can be
79 // potentially used as finite elements or as entities which carry some
80 // approximation field.
81 BitRefLevel bit_level0;
82 bit_level0.set(0);
83 CHKERR m_field.getInterface<BitRefManager>()->setBitRefLevelByDim(
84 root_set, 3, bit_level0);
85 // Add field
86 CHKERR m_field.add_field("DISP_X", H1, AINSWORTH_LEGENDRE_BASE, 1);
87 CHKERR m_field.add_field("DISP_Y", H1, AINSWORTH_LEGENDRE_BASE, 1);
88
89 auto meshsets_manager_ptr = m_field.getInterface<MeshsetsManager>();
90
92 CHKERR meshsets_manager_ptr->getEntitiesByDimension(101, SIDESET, 2,
93 surface, true);
94 CHKERR m_field.add_ents_to_field_by_type(surface, MBTRI, "DISP_X");
95 CHKERR m_field.add_ents_to_field_by_type(surface, MBTRI, "DISP_Y");
96
97 CHKERR m_field.set_field_order(0, MBVERTEX, "DISP_X", 1);
98 CHKERR m_field.set_field_order(0, MBEDGE, "DISP_X", order);
99 CHKERR m_field.set_field_order(0, MBTRI, "DISP_X", order);
100
101 CHKERR m_field.set_field_order(0, MBVERTEX, "DISP_Y", 1);
102 CHKERR m_field.set_field_order(0, MBEDGE, "DISP_Y", order);
103 CHKERR m_field.set_field_order(0, MBTRI, "DISP_Y", order);
104
105 CHKERR m_field.build_fields();
106
107 CHKERR m_field.add_finite_element("DISP_MAP_ELEMENT");
108 CHKERR m_field.modify_finite_element_add_field_row("DISP_MAP_ELEMENT",
109 "DISP_X");
110 CHKERR m_field.modify_finite_element_add_field_col("DISP_MAP_ELEMENT",
111 "DISP_X");
112 CHKERR m_field.modify_finite_element_add_field_data("DISP_MAP_ELEMENT",
113 "DISP_X");
114 CHKERR m_field.modify_finite_element_add_field_data("DISP_MAP_ELEMENT",
115 "DISP_Y");
116
117 // Add entities to that element
119 "DISP_MAP_ELEMENT");
120
121 // build finite elements
123 // build adjacencies between elements and degrees of freedom
124 CHKERR m_field.build_adjacencies(bit_level0);
125
126 // set discrete manager
127 DM dm_disp;
128 DMType dm_name = "DM_DISP";
129 // Register DM problem
130 CHKERR DMRegister_MoFEM(dm_name);
131 CHKERR DMCreate(PETSC_COMM_WORLD, &dm_disp);
132 CHKERR DMSetType(dm_disp, dm_name);
133 // Create DM instance
134 CHKERR DMMoFEMCreateMoFEM(dm_disp, &m_field, dm_name, bit_level0);
135 // Configure DM form line command options (DM itself, solvers,
136 // pre-conditioners, ... )
137 CHKERR DMSetFromOptions(dm_disp);
138 // Add elements to dm (only one here)
139 CHKERR DMMoFEMAddElement(dm_disp, "DISP_MAP_ELEMENT");
140 // Set up problem (number dofs, partition mesh, etc.)
141 CHKERR DMSetUp(dm_disp);
142
143 DispMapFe fe_face(m_field);
144
145 // string file(argv[1]); cout << "argument 1:" << argv[1] <<endl;
146 // string file2(argv[2]); cout << "argument 2:" << argv[2] <<endl;
147
148 string file1(data_file_name1);
149 DataFromFiles data_from_files(file1);
150 CHKERR data_from_files.fromOptions();
151 CHKERR data_from_files.loadFileData();
152
153 string file2(data_file_name2);
154 DataFromFiles data_from_files2(file2);
155 CHKERR data_from_files2.fromOptions();
156 CHKERR data_from_files2.loadFileData();
157
158 auto &list_of_operators = fe_face.getOpPtrVector();
159
160 Mat A;
161 Vec Fx, Dx;
162 CHKERR DMCreateMatrix(dm_disp, &A);
163 CHKERR m_field.getInterface<VecManager>()->vecCreateGhost("DM_DISP", ROW,
164 &Fx);
165 CHKERR m_field.getInterface<VecManager>()->vecCreateGhost("DM_DISP", COL,
166 &Dx);
167 Vec Fy, Dy;
168 CHKERR VecDuplicate(Fx, &Fy);
169 CHKERR VecDuplicate(Dx, &Dy);
170
171 CHKERR MatZeroEntries(A);
172 CHKERR VecZeroEntries(Fx);
173 CHKERR VecZeroEntries(Fy);
174
175 CommonData common_data;
176 common_data.globA = A;
177
178 common_data.globF = Fx;
179
180 auto det_ptr = boost::make_shared<VectorDouble>();
181 auto jac_ptr = boost::make_shared<MatrixDouble>();
182 auto inv_jac_ptr = boost::make_shared<MatrixDouble>();
183 list_of_operators.push_back(new OpCalculateHOJacForFace(jac_ptr));
184 list_of_operators.push_back(
185 new OpInvertMatrix<2>(jac_ptr, det_ptr, inv_jac_ptr));
186 list_of_operators.push_back(new OpSetInvJacH1ForFace(inv_jac_ptr));
187 list_of_operators.push_back(
188 new OpCalculateLhs("DISP_X", "DISP_X", common_data, data_from_files));
189 list_of_operators.push_back(
190 new OpCalulatefRhoAtGaussPts("DISP_X", common_data, data_from_files));
191 list_of_operators.push_back(new OpAssembleRhs("DISP_X", common_data));
192
193 CHKERR DMoFEMLoopFiniteElements(dm_disp, "DISP_MAP_ELEMENT", &fe_face);
194
195 // cout << "error.no !" <<error++ << endl;
196 CHKERR MatAssemblyBegin(A, MAT_FINAL_ASSEMBLY);
197 CHKERR MatAssemblyEnd(A, MAT_FINAL_ASSEMBLY);
198 CHKERR VecGhostUpdateBegin(Fx, ADD_VALUES, SCATTER_REVERSE);
199 CHKERR VecGhostUpdateEnd(Fx, ADD_VALUES, SCATTER_REVERSE);
200 CHKERR VecAssemblyBegin(Fx);
201 CHKERR VecAssemblyEnd(Fx);
202
203 // int error=1;
204 common_data.globF = Fy;
205 list_of_operators.clear();
206 list_of_operators.push_back(new OpCalculateHOJacForFace(jac_ptr));
207 list_of_operators.push_back(
208 new OpInvertMatrix<2>(jac_ptr, det_ptr, inv_jac_ptr));
209 list_of_operators.push_back(new OpSetInvJacH1ForFace(inv_jac_ptr));
210 list_of_operators.push_back(
211 new OpCalulatefRhoAtGaussPts("DISP_X", common_data, data_from_files2));
212 list_of_operators.push_back(new OpAssembleRhs("DISP_X", common_data));
213 // cout << "error.no !"<< error++<< endl;
214
215 CHKERR DMoFEMLoopFiniteElements(dm_disp, "DISP_MAP_ELEMENT", &fe_face);
216 // cout << "error.no !" <<error++ << endl;
217 CHKERR VecGhostUpdateBegin(Fy, ADD_VALUES, SCATTER_REVERSE);
218 CHKERR VecGhostUpdateEnd(Fy, ADD_VALUES, SCATTER_REVERSE);
219 CHKERR VecAssemblyBegin(Fy);
220 CHKERR VecAssemblyEnd(Fy);
221
222 // VecView(F,PETSC_VIEWER_DRAW_WORLD);
223 // MatView(A,PETSC_VIEWER_DRAW_WORLD);
224 // std::string wait;
225 // std::cin >> wait;
226
227 // solve
228 {
229 KSP ksp;
230 CHKERR KSPCreate(PETSC_COMM_WORLD, &ksp);
231 CHKERR KSPSetOperators(ksp, A, A);
232 CHKERR KSPSetFromOptions(ksp);
233 CHKERR KSPSolve(ksp, Fx, Dx);
234 CHKERR KSPSolve(ksp, Fy, Dy);
235 }
236
237 CHKERR VecGhostUpdateBegin(Dx, INSERT_VALUES, SCATTER_FORWARD);
238 CHKERR VecGhostUpdateEnd(Dx, INSERT_VALUES, SCATTER_FORWARD);
239 CHKERR m_field.getInterface<VecManager>()->setGlobalGhostVector(
240 "DM_DISP", COL, Dx, INSERT_VALUES, SCATTER_REVERSE);
241 CHKERR VecGhostUpdateBegin(Dy, INSERT_VALUES, SCATTER_FORWARD);
242 CHKERR VecGhostUpdateEnd(Dy, INSERT_VALUES, SCATTER_FORWARD);
243 CHKERR m_field.getInterface<VecManager>()->setOtherGlobalGhostVector(
244 "DM_DISP", "DISP_X", "DISP_Y", COL, Dy, INSERT_VALUES, SCATTER_REVERSE);
245
246 // Remove rigid translation
247 double sum_dx = 0;
248 int nb_dx = 0;
250 MBVERTEX, dof)) {
251 sum_dx += (*dof)->getFieldData();
252 nb_dx++;
253 }
254 sum_dx /= nb_dx;
256 MBVERTEX, dof)) {
257 (*dof)->getFieldData() -= sum_dx;
258 }
259 double sum_dy = 0;
260 int nb_dy = 0;
262 MBVERTEX, dof)) {
263 sum_dy += (*dof)->getFieldData();
264 nb_dy++;
265 }
266 sum_dy /= nb_dy;
268 MBVERTEX, dof)) {
269 (*dof)->getFieldData() -= sum_dy;
270 }
271
272 using PostProcFace =
275
276 PostProcFace post_proc(m_field);
278
279 auto disp_x_ptr = boost::make_shared<VectorDouble>();
280 auto disp_y_ptr = boost::make_shared<VectorDouble>();
281 post_proc.getOpPtrVector().push_back(
282 new OpCalculateScalarFieldValues("DISP_X", disp_x_ptr));
283 post_proc.getOpPtrVector().push_back(
284 new OpCalculateScalarFieldValues("DISP_Y", disp_y_ptr));
285 post_proc.getOpPtrVector().push_back(new OpPPMap(
286 post_proc.getPostProcMesh(), post_proc.getMapGaussPts(),
287 OpPPMap::DataMapVec{{"DISP_X", disp_x_ptr},
288 {"DISP_Y", disp_y_ptr}},
291
292 CHKERR DMoFEMLoopFiniteElements(dm_disp, "DISP_MAP_ELEMENT", &post_proc);
293 CHKERR post_proc.writeFile("out_disp.h5m");
294
295 CHKERR VecDestroy(&Fx);
296 CHKERR VecDestroy(&Fy);
297 CHKERR VecDestroy(&Dx);
298 CHKERR VecDestroy(&Dy);
299 CHKERR MatDestroy(&A);
300 CHKERR DMDestroy(&dm_disp);
301
302 // Delete element which will be no longer used
303 CHKERR m_field.delete_finite_element("DISP_MAP_ELEMENT");
304
305 {
306 // Add one node to fix
307 auto mmanager_ptr = m_field.getInterface<MeshsetsManager>();
308 Range ents_1st_layer;
309 CHKERR mmanager_ptr->getEntitiesByDimension(202, SIDESET, 2,
310 ents_1st_layer, true);
311 int num_nodes;
312 const EntityHandle *conn;
313 CHKERR moab.get_connectivity(ents_1st_layer[0], conn, num_nodes);
314 Skinner skin(&moab);
315 Range skin_edges;
316 CHKERR skin.find_skin(0, ents_1st_layer, false, skin_edges);
317 Range edges;
318 CHKERR moab.get_adjacencies(&*ents_1st_layer.begin(), 1, 1, false, edges);
319 EntityHandle meshset;
320 CHKERR mmanager_ptr->getMeshset(202, SIDESET, meshset);
321 CHKERR moab.add_entities(meshset, conn, 1);
322 CHKERR moab.add_entities(meshset, skin_edges);
323 }
324
325 {
326 Range tets;
327 CHKERR moab.get_entities_by_type(0, MBTET, tets, false);
328 CHKERR m_field.getInterface<CommInterface>()->partitionMesh(tets, 3, 2,
329 n_partas);
330 }
331
332 CHKERR moab.write_file("analysis_mesh.h5m");
333 }
335
337
338 return 0;
339}
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
#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.
static char help[]
Definition map_disp.cpp:21
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.
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.