v0.15.0
Loading...
Searching...
No Matches
SolutionMapping.hpp
Go to the documentation of this file.
1
2
3/** \file SolutionMapping.hpp
4 * \example SolutionMapping.hpp
5 */
6
8
9 SetEnrichedIntegration(boost::shared_ptr<Range> new_els);
10
11 MoFEMErrorCode operator()(ForcesAndSourcesCore *fe_raw_ptr, int order_row,
12 int order_col, int order_data);
13
14private:
15 struct Fe : public ForcesAndSourcesCore {
16 using ForcesAndSourcesCore::dataOnElement;
17
18 private:
19 using ForcesAndSourcesCore::ForcesAndSourcesCore;
20 };
21
22 boost::shared_ptr<Range> newEls;
23 static inline std::map<long int, MatrixDouble> mapRefCoords;
24};
25
27
29
30 MoFEMErrorCode mapFields(SmartPetscObj<DM> &intermediateDM,
32 Range elsToFlip = Range(), PetscInt numVecs = 1,
33 Vec vecsToMapFrom[] = PETSC_NULLPTR,
34 Vec vecsToMapTo[] = PETSC_NULLPTR);
35 MoFEMErrorCode reSetUp(std::vector<std::string> fIelds,
36 std::vector<int> oRders, BitRefLevel bIt);
37
38private:
43 SmartPetscObj<DM> subDM, intermediateDM;
44
45 boost::shared_ptr<DomainEle> feRhs;
46 boost::shared_ptr<DomainEle> feLhs;
47
48 MoFEMErrorCode setUp(SmartPetscObj<DM> &subDM,
49 SmartPetscObj<DM> &intermediateDM, Range elsToAdd,
51 MoFEMErrorCode removeDofs(Range elsToRemove, Range elsToAdd);
53 Vec vecIn = PETSC_NULLPTR);
54 MoFEMErrorCode solveMap(SmartPetscObj<DM> &subDM,
55 SmartPetscObj<DM> &intermediateDM, PetscInt numVecs,
56 Vec vecsToMapFrom[], Vec vecsToMapTo[]);
57 MoFEMErrorCode postProcess();
58};
59
61 feRhs = boost::make_shared<DomainEle>(m_field);
62 feLhs = boost::make_shared<DomainEle>(m_field);
63}
64
65MoFEMErrorCode SolutionMapping::mapFields(SmartPetscObj<DM> &intermediate_dm,
66 Range els_to_remove, Range els_to_add,
67 Range els_to_flip, PetscInt num_vecs,
68 Vec vecs_to_map_from[],
69 Vec vecs_to_map_to[]) {
71
72 CHKERR pushOperators(els_to_flip, els_to_add);
73 CHKERR setUp(subDM, intermediate_dm, els_to_add, els_to_flip);
74 CHKERR solveMap(subDM, intermediate_dm, num_vecs, vecs_to_map_from,
75 vecs_to_map_to);
76
78};
79
80MoFEMErrorCode SolutionMapping::setUp(SmartPetscObj<DM> &sub_dm,
81 SmartPetscObj<DM> &intermediate_dm,
82 Range els_to_add, Range els_to_flip) {
84
85 MOFEM_LOG("REMESHING", Sev::inform) << "Set up sub DM for mapping";
86
87 Simple *simple = m_field.getInterface<Simple>();
88
89 Range sub_dm_elems;
90
91 auto create_sub_dm = [&]() {
93 sub_dm = createDM(m_field.get_comm(), "DMMOFEM");
94 auto create_impl = [&]() {
96 CHKERR DMSetType(sub_dm, "DMMOFEM");
97 CHKERR DMMoFEMCreateSubDM(sub_dm, intermediate_dm, "SUB_MAPPING");
98 CHKERR DMMoFEMAddElement(sub_dm, simple->getDomainFEName());
99 CHKERR DMMoFEMSetSquareProblem(sub_dm, PETSC_TRUE);
100 CHKERR DMMoFEMSetDestroyProblem(sub_dm, PETSC_TRUE);
101
102 MOFEM_LOG("REMESHING", Sev::inform) << "Created sub DM";
103
104 for (auto f : {"T", "TAU", "EP"}) {
105 CHKERR DMMoFEMAddSubFieldRow(sub_dm, f,
106 boost::make_shared<Range>(els_to_add));
107 CHKERR DMMoFEMAddSubFieldCol(sub_dm, f,
108 boost::make_shared<Range>(els_to_add));
109 }
110
111 auto bit = BitRefLevel().set();
114
115 CHKERR DMMoFEMSetIsPartitioned(sub_dm, is_distributed_mesh);
116 CHKERR DMSubDMSetUp_MoFEM(sub_dm);
117
119 };
120
121 CHKERR create_impl();
123 };
124
125 CHK_THROW_MESSAGE(create_sub_dm(), "failed to create sub dm");
126
127 MOFEM_LOG("REMESHING", Sev::inform) << "Set up sub DM for mapping <= done";
129};
130
131MoFEMErrorCode SolutionMapping::reSetUp(std::vector<std::string> fields,
132 std::vector<int> orders,
133 BitRefLevel bit) {
135
136 Simple *simple = m_field.getInterface<Simple>();
137
138 auto add_ents_order_to_field =
140 const std::initializer_list<std::string> &f,
141 const std::initializer_list<EntityType> &t, int _order) {
143 for (auto _f : f) {
144 for (auto _t : t) {
146 CHKERR m_field.set_field_order(0, _t, _f, _order);
147 }
148 }
150 };
151
152 for (size_t i = 0; i < fields.size(); ++i) {
153 CHKERR add_ents_order_to_field(m_field, {fields[i]}, {MBTRI}, orders[i]);
154 }
155
158 simple->getDomainFEName());
161
163};
164
165MoFEMErrorCode SolutionMapping::removeDofs(Range els_to_remove,
166 Range els_to_add) {
168
169 const Problem *prb_ptr;
170 CHKERR m_field.get_problem("SUB_MAPPING", &prb_ptr);
171 int nb_init_row_dofs = prb_ptr->getNbDofsRow();
172
173 MOFEM_LOG("REMESHING", Sev::verbose)
174 << "Number of initial row dofs: " << nb_init_row_dofs;
175
176 if (is_distributed_mesh == PETSC_FALSE)
177 CHKERR m_field.getInterface<CommInterface>()->synchroniseEntities(
178 els_to_remove);
179
180 auto prb_mng = m_field.getInterface<ProblemsManager>();
181
182 auto remove_dofs_on_ents = [&](std::string field, const Range &ents) {
183 if (is_distributed_mesh == PETSC_TRUE)
184 return prb_mng->removeDofsOnEntities("SUB_MAPPING", field, ents);
185 else
186 return prb_mng->removeDofsOnEntitiesNotDistributed("SUB_MAPPING", field,
187 ents);
188 };
189
190 for (std::string field : {"EP", "TAU", "T"}) {
191 remove_dofs_on_ents(field, els_to_remove);
192
193 nb_init_row_dofs = prb_ptr->getNbDofsRow();
194
195 MOFEM_LOG("REMESHING", Sev::verbose)
196 << "Number of row dofs after removing " << field
197 << " field: " << nb_init_row_dofs;
198 }
199
201};
202
203MoFEMErrorCode SolutionMapping::pushOperators(Range els_to_flip,
204 Range els_to_add, Vec vec_in) {
206
207 SmartPetscObj<Vec> smart_vec_in;
208 if (vec_in)
209 smart_vec_in = SmartPetscObj<Vec>(vec_in, true);
210
211 MOFEM_LOG("REMESHING", Sev::inform) << "Got past smart vector";
212
213 feRhs->getOpPtrVector().clear();
214
215 MOFEM_LOG("REMESHING", Sev::inform) << "Cleared RHS FE";
216
217 Simple *simple = m_field.getInterface<Simple>();
218
219 auto vol_rule = [](int, int, int ao) { return 2 * ao + geom_order; };
220
221 // feRhs->getRuleHook = vol_rule;
222 // feLhs->getRuleHook = vol_rule;
223 feRhs->getRuleHook = [](int, int, int) { return -1; };
224 feRhs->setRuleHook =
225 SetEnrichedIntegration(boost::make_shared<Range>(els_to_add));
226 feLhs->getRuleHook = [](int, int, int) { return -1; };
227 feLhs->setRuleHook =
228 SetEnrichedIntegration(boost::make_shared<Range>(els_to_add));
229
230 auto T_ptr = boost::make_shared<VectorDouble>();
231 auto TAU_ptr = boost::make_shared<VectorDouble>();
232 auto EP_ptr = boost::make_shared<MatrixDouble>();
233
234 auto set_domain_rhs = [&](auto &pip) {
236
238
239 auto old_T_ptr = boost::make_shared<VectorDouble>();
240 auto old_TAU_ptr = boost::make_shared<VectorDouble>();
241 auto old_EP_ptr = boost::make_shared<MatrixDouble>();
242
243 auto old_el_ops = [&](auto &pip) {
245
246 // get old solution
247 if (vec_in) {
248 pip.push_back(
249 new OpCalculateScalarFieldValues("T", old_T_ptr, smart_vec_in));
250 pip.push_back(
251 new OpCalculateScalarFieldValues("TAU", old_TAU_ptr, smart_vec_in));
252 pip.push_back(new OpCalculateTensor2SymmetricFieldValues<SPACE_DIM>(
253 "EP", old_EP_ptr, smart_vec_in));
254 } else {
255 pip.push_back(new OpCalculateScalarFieldValues("T", old_T_ptr));
256 pip.push_back(new OpCalculateScalarFieldValues("TAU", old_TAU_ptr));
257 pip.push_back(new OpCalculateTensor2SymmetricFieldValues<SPACE_DIM>(
258 "EP", old_EP_ptr));
259 }
260 // pip.push_back(new EdgeFlippingOps::filterScalarSolution<AT, IT>(
261 // "T", old_T_ptr, nullptr, nullptr, nullptr));
262 // pip.push_back(new EdgeFlippingOps::filterScalarSolution<AT, IT>(
263 // "TAU", old_TAU_ptr, nullptr, nullptr, nullptr));
264 // pip.push_back(new EdgeFlippingOps::filterSymTensorSolution<AT, IT,
265 // SPACE_DIM>("EP", old_EP_ptr, nullptr, nullptr, nullptr));
266
268 };
269
270 auto new_el_ops = [&](auto &pp_fe, auto &&p) {
272
273 auto new_T_ptr = boost::make_shared<VectorDouble>();
274 auto new_TAU_ptr = boost::make_shared<VectorDouble>();
275 auto new_EP_ptr = boost::make_shared<MatrixDouble>();
276 if (vec_in) {
277 pip.push_back(
278 new OpCalculateScalarFieldValues("T", new_T_ptr, smart_vec_in));
279 pip.push_back(
280 new OpCalculateScalarFieldValues("TAU", new_TAU_ptr, smart_vec_in));
281 pip.push_back(new OpCalculateTensor2SymmetricFieldValues<SPACE_DIM>(
282 "EP", new_EP_ptr, smart_vec_in));
283 } else {
284 MOFEM_LOG("REMESHING", Sev::inform) << "In other branch of child ops";
285 pip.push_back(new OpCalculateScalarFieldValues("T", new_T_ptr));
286 pip.push_back(new OpCalculateScalarFieldValues("TAU", new_TAU_ptr));
287 pip.push_back(new OpCalculateTensor2SymmetricFieldValues<SPACE_DIM>(
288 "EP", new_EP_ptr));
289 }
290
291 pip.push_back(
293 "T", old_T_ptr, nullptr, new_T_ptr, nullptr, m_field));
294 pip.push_back(
296 "TAU", old_TAU_ptr, nullptr, new_TAU_ptr, nullptr, m_field));
297 pip.push_back(
299 SPACE_DIM>(
300 "EP", old_EP_ptr, nullptr, new_EP_ptr, nullptr, m_field));
301
303 };
304
305 // create an OpLoopRange object
306 auto op_range = new OpLoopRange<DomainEleOnRange>(
307 m_field, simple->getDomainFEName(),
308 boost::make_shared<Range>(els_to_flip), Sev::noisy);
309
310 op_range->getRangeFEPtr()->getRuleHook = [](int, int, int) { return -1; };
311
312 // push operator
313 pip.push_back(op_range);
314
315 // call the parent ops from each child pipeline
316 CHK_MOAB_THROW(new_el_ops(pip, old_el_ops(op_range->getOpPtrVector())),
317 "failed to loop over child ops");
318
320 };
321
322 auto set_domain_lhs = [&](auto &pip) {
324
326
327 using OpLhsScalarLeastSquaresProj = FormsIntegrators<DomainEleOp>::Assembly<
329 pip.push_back(new OpLhsScalarLeastSquaresProj("T", "T"));
330 pip.push_back(new OpLhsScalarLeastSquaresProj("TAU", "TAU"));
331 pip.push_back(
333 "EP", "EP"));
334
336 };
337
338 CHKERR set_domain_rhs(feRhs->getOpPtrVector());
339 CHKERR set_domain_lhs(feLhs->getOpPtrVector());
340
342};
343
344MoFEMErrorCode SolutionMapping::solveMap(SmartPetscObj<DM> &sub_dm,
345 SmartPetscObj<DM> &intermediate_dm,
346 PetscInt num_vecs,
347 Vec vecs_to_map_from[],
348 Vec vecs_to_map_to[]) {
350
351 auto simple = m_field.getInterface<Simple>();
352 auto is_mgr = m_field.getInterface<ISManager>();
353
354 auto post_proc = [&](auto dm, std::string file_name) {
356
357 auto T_ptr = boost::make_shared<VectorDouble>();
358 auto TAU_ptr = boost::make_shared<VectorDouble>();
359 auto EP_ptr = boost::make_shared<MatrixDouble>();
360
361 auto post_proc_fe = boost::make_shared<PostProcEle>(m_field);
362
363 using OpPPMap = OpPostProcMapInMoab<SPACE_DIM, SPACE_DIM>;
364
365 post_proc_fe->getOpPtrVector().push_back(
366 new OpCalculateScalarFieldValues("T", T_ptr));
367 post_proc_fe->getOpPtrVector().push_back(
368 new OpCalculateScalarFieldValues("TAU", TAU_ptr));
369 post_proc_fe->getOpPtrVector().push_back(
370 new OpCalculateTensor2SymmetricFieldValues<SPACE_DIM>("EP", EP_ptr));
371 // post_proc_fe->getOpPtrVector().push_back(
372 // new OpCalculateVectorFieldValues<SPACE_DIM>("U", u_ptr));
373 post_proc_fe->getOpPtrVector().push_back(
374
375 new OpPPMap(post_proc_fe->getPostProcMesh(),
376 post_proc_fe->getMapGaussPts(),
377
378 {{"T", T_ptr}, {"TAU", TAU_ptr}},
379
380 {},
381
382 {},
383
384 {{"EP", EP_ptr}}
385
386 )
387
388 );
389
390 CHKERR DMoFEMLoopFiniteElements(dm, simple->getDomainFEName(),
391 post_proc_fe);
392 CHKERR post_proc_fe->writeFile(file_name);
393
395 };
396
397 auto null_fe = boost::shared_ptr<FEMethod>();
398
399 CHKERR DMMoFEMKSPSetComputeOperators(sub_dm, simple->getDomainFEName(), feLhs,
400 null_fe, null_fe);
401 // CHKERR DMMoFEMKSPSetComputeRHS(sub_dm, simple->getDomainFEName(), feRhs,
402 // null_fe, null_fe);
403
404 auto ksp = MoFEM::createKSP(m_field.get_comm());
405 CHKERR KSPSetDM(ksp, sub_dm);
406 CHKERR KSPSetFromOptions(ksp);
407
408 // We create a temp_D to store current state of the mesh. We doing to preserve
409 // whatever is currently stored on entities, we will restore it to keep it as
410 // it was before.
411
412 auto tmp_D = createDMVector(intermediate_dm);
413 CHKERR DMoFEMMeshToLocalVector(intermediate_dm, tmp_D, INSERT_VALUES,
414 SCATTER_FORWARD);
415 CHKERR VecGhostUpdateBegin(tmp_D, INSERT_VALUES, SCATTER_FORWARD);
416 CHKERR VecGhostUpdateEnd(tmp_D, INSERT_VALUES, SCATTER_FORWARD);
417
418 auto D = createDMVector(sub_dm);
419 auto F = vectorDuplicate(D);
420
421 for (int i = 0; i < num_vecs; ++i) {
422 CHKERR VecGhostUpdateBegin(vecs_to_map_from[i], INSERT_VALUES,
423 SCATTER_FORWARD);
424 CHKERR VecGhostUpdateEnd(vecs_to_map_from[i], INSERT_VALUES,
425 SCATTER_FORWARD);
426 CHKERR DMoFEMMeshToLocalVector(intermediate_dm, vecs_to_map_from[i],
427 INSERT_VALUES, SCATTER_REVERSE);
428 // map
429 CHKERR VecZeroEntries(F);
430 CHKERR VecGhostUpdateBegin(F, INSERT_VALUES, SCATTER_FORWARD);
431 CHKERR VecGhostUpdateEnd(F, INSERT_VALUES, SCATTER_FORWARD);
432 feRhs->ksp_f = F;
433 CHKERR DMoFEMLoopFiniteElements(sub_dm, simple->getDomainFEName(), feRhs);
434 CHKERR VecGhostUpdateBegin(F, ADD_VALUES, SCATTER_REVERSE);
435 CHKERR VecGhostUpdateEnd(F, ADD_VALUES, SCATTER_REVERSE);
436 CHKERR VecAssemblyBegin(F);
437 CHKERR VecAssemblyEnd(F);
438 CHKERR KSPSolve(ksp, F, D);
439
440 // update data
441 CHKERR DMoFEMMeshToLocalVector(sub_dm, D, INSERT_VALUES, SCATTER_REVERSE);
442 CHKERR DMoFEMMeshToLocalVector(intermediate_dm, vecs_to_map_to[i],
443 INSERT_VALUES, SCATTER_FORWARD);
444 CHKERR VecGhostUpdateBegin(vecs_to_map_to[i], INSERT_VALUES,
445 SCATTER_FORWARD);
446 CHKERR VecGhostUpdateEnd(vecs_to_map_to[i], INSERT_VALUES, SCATTER_FORWARD);
447
448 CHKERR post_proc(intermediate_dm, "out_map_" + std::to_string(i) + ".h5m");
449 }
450
451 CHKERR DMoFEMMeshToLocalVector(intermediate_dm, tmp_D, INSERT_VALUES,
452 SCATTER_REVERSE);
453
454 MOFEM_LOG("REMESHING", Sev::inform) << "Mapped thermoplastic state variables";
455
457};
458
459// Use example
460
461// CHKERR SolutionMapping(m_field).mapFields();
void simple(double P1[], double P2[], double P3[], double c[], const int N)
Definition acoustic.cpp:69
constexpr int SPACE_DIM
[Define dimension]
#define CHK_THROW_MESSAGE(err, msg)
Check and throw MoFEM exception.
@ L2
field with C-1 continuity
Definition definitions.h:88
#define MoFEMFunctionBegin
First executable line of each MoFEM function, used for error handling. Final line of MoFEM functions ...
#define CHK_MOAB_THROW(err, msg)
Check error code of MoAB function and throw MoFEM exception.
#define MoFEMFunctionReturn(a)
Last executable line of each PETSc function used for error handling. Replaces return()
#define CHKERR
Inline error check.
@ F
PetscErrorCode DMoFEMMeshToLocalVector(DM dm, Vec l, InsertMode mode, ScatterMode scatter_mode)
set local (or ghosted) vector values on mesh for partition only
Definition DMMoFEM.cpp:514
virtual const Problem * get_problem(const std::string problem_name) const =0
Get the problem object.
virtual MoFEMErrorCode build_finite_elements(int verb=DEFAULT_VERBOSITY)=0
Build finite elements.
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 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.
#define MOFEM_LOG(channel, severity)
Log.
virtual MoFEMErrorCode modify_problem_mask_ref_level_set_bit(const std::string &name_problem, const BitRefLevel &bit)=0
set dof mask ref level for problem
virtual MoFEMErrorCode modify_problem_ref_level_set_bit(const std::string &name_problem, const BitRefLevel &bit)=0
set ref level for problem
auto bit
set bit
FTensor::Index< 'i', SPACE_DIM > i
double D
auto createKSP(MPI_Comm comm)
OpPostProcMapInMoab< SPACE_DIM, SPACE_DIM > OpPPMap
constexpr double t
plate stiffness
Definition plate.cpp:58
Rhs for mapping scalar fields with least squares.
Rhs for mapping symmetric tensor fields with least squares.
virtual MoFEMErrorCode build_adjacencies(const Range &ents, int verb=DEFAULT_VERBOSITY)=0
build adjacencies
virtual MPI_Comm & get_comm() const =0
Deprecated interface functions.
Post post-proc data at points from hash maps.
DofIdx getNbDofsRow() const
MoFEMErrorCode getInterface(IFACE *&iface) const
Get interface reference to pointer of interface.
boost::shared_ptr< Range > newEls
MoFEMErrorCode operator()(ForcesAndSourcesCore *fe_raw_ptr, int order_row, int order_col, int order_data)
static std::map< long int, MatrixDouble > mapRefCoords
MoFEMErrorCode postProcess()
SmartPetscObj< DM > intermediateDM
MoFEMErrorCode removeDofs(Range elsToRemove, Range elsToAdd)
MoFEMErrorCode solveMap(SmartPetscObj< DM > &subDM, SmartPetscObj< DM > &intermediateDM, PetscInt numVecs, Vec vecsToMapFrom[], Vec vecsToMapTo[])
SolutionMapping(MoFEM::Interface &m_field)
boost::shared_ptr< DomainEle > feRhs
MoFEMErrorCode reSetUp(std::vector< std::string > fIelds, std::vector< int > oRders, BitRefLevel bIt)
MoFEMErrorCode setUp(SmartPetscObj< DM > &subDM, SmartPetscObj< DM > &intermediateDM, Range elsToAdd, Range elsToFlip)
MoFEM::Interface & m_field
boost::shared_ptr< DomainEle > feLhs
MoFEMErrorCode mapFields(SmartPetscObj< DM > &intermediateDM, Range elsToRemove=Range(), Range elsToAdd=Range(), Range elsToFlip=Range(), PetscInt numVecs=1, Vec vecsToMapFrom[]=PETSC_NULLPTR, Vec vecsToMapTo[]=PETSC_NULLPTR)
MoFEMErrorCode pushOperators(Range elsToFlip, Range elsToAdd, Vec vecIn=PETSC_NULLPTR)
SmartPetscObj< DM > subDM
constexpr AssemblyType AT
constexpr IntegrationType IT
PetscBool is_distributed_mesh
int geom_order
Order if fixed.
Definition plastic.cpp:141