v0.16.0
Loading...
Searching...
No Matches
thermal_unsteady.cpp
Go to the documentation of this file.
1/** \file thermal_unsteady.cpp
2 \ingroup mofem_thermal_elem
3 \brief Example of thermal unsteady analyze.
4
5 TODO:
6 \todo Make it work in distributed meshes with multigird solver. At the moment
7 it is not working efficient as can.
8*/
9
10
11
13using namespace MoFEM;
14
15#ifdef __GROUND_SURFACE_TEMPERATURE_HPP
16
17 #include <GenericClimateModel.hpp>
18 #include <GroundSurfaceTemperature.hpp>
19
20 #include <time.h>
21 extern "C" {
22 #include <spa.h>
23 }
24 #include <CrudeClimateModel.hpp>
25
26#endif // __GROUND_SURFACE_TEMPERATURE_HPP
27
30
31static char help[] =
32 "-my_file mesh file\n"
33 "-order set approx. order to all blocks\n"
34 "-my_block_config set block data\n"
35 "-my_ground_analysis_data data for crude climate model\n"
36 "\n";
37
38struct BlockOptionData {
39 int oRder;
41 double cApacity;
42 double initTemp;
44 oRder(-1),
45 cOnductivity(-1),
46 cApacity(-1),
47 initTemp(0) {}
48};
49
50struct MonitorPostProc : public FEMethod {
51
55
56 bool iNit;
57 int pRT;
58 PetscBool saveSkin;
59
61 : FEMethod(), mField(m_field), postProc(m_field), skinPostProc(m_field),
62 iNit(false) {
63
64 PetscBool flg = PETSC_TRUE;
65 CHKERR PetscOptionsGetInt(PETSC_NULLPTR, PETSC_NULLPTR, "-my_output_prt", &pRT,
66 &flg);
67 CHKERRABORT(PETSC_COMM_WORLD, ierr);
68 if (flg != PETSC_TRUE) {
69 pRT = 1;
70 }
71 saveSkin = PETSC_TRUE;
72 CHKERR PetscOptionsGetBool(PETSC_NULLPTR, PETSC_NULLPTR, "-my_save_skin",
73 &saveSkin, PETSC_NULLPTR);
74 }
75
80
85
88
89 if (!iNit) {
91 "MESH_NODE_POSITIONS");
92 auto temp_ptr = boost::make_shared<VectorDouble>();
93 auto temp_rate_ptr = boost::make_shared<VectorDouble>();
94 auto temp_grad_ptr = boost::make_shared<MatrixDouble>();
95 auto mesh_pos_ptr = boost::make_shared<MatrixDouble>();
96 postProc.getOpPtrVector().push_back(
97 new OpCalculateScalarFieldValues("TEMP", temp_ptr));
98 postProc.getOpPtrVector().push_back(
99 new OpCalculateScalarFieldValues("TEMP_RATE", temp_rate_ptr));
100 postProc.getOpPtrVector().push_back(
101 new OpCalculateScalarFieldGradient<3>("TEMP", temp_grad_ptr));
102 postProc.getOpPtrVector().push_back(
103 new OpCalculateVectorFieldValues<3>("MESH_NODE_POSITIONS",
104 mesh_pos_ptr));
106 postProc.getOpPtrVector().push_back(new OpPPMap(
108 {{"TEMP", temp_ptr}, {"TEMP_RATE", temp_rate_ptr}},
109 {{"TEMP_GRAD", temp_grad_ptr},
110 {"MESH_NODE_POSITIONS", mesh_pos_ptr}},
111 {}, {}));
112
114 "MESH_NODE_POSITIONS");
115 auto skin_temp_ptr = boost::make_shared<VectorDouble>();
116 skinPostProc.getOpPtrVector().push_back(
117 new OpCalculateScalarFieldValues("TEMP", skin_temp_ptr));
118 skinPostProc.getOpPtrVector().push_back(new OpPPMap(
120 {{"TEMP", skin_temp_ptr}}, {}, {}, {}));
121
122 iNit = true;
123 }
124 int step;
125 CHKERR TSGetTimeStepNumber(ts, &step);
126
127 if (pRT && (step) % pRT == 0) {
128 // CHKERR mField.loop_finite_elements("DMTHERMAL","THERMAL_FE",postProc);
129 // std::ostringstream sss;
130 // sss << "out_thermal_" << step << ".h5m";
131 // CHKERR postProc.writeFile(sss.str().c_str());
132 if (saveSkin) {
133 CHKERR mField.loop_finite_elements("DMTHERMAL", "POST_PROC_SKIN",
134 skinPostProc);
135 std::ostringstream sss;
136 sss << "out_skin_" << step << ".h5m";
137 CHKERR skinPostProc.writeFile(sss.str().c_str());
138 }
139 }
141 }
142};
143
144int main(int argc, char *argv[]) {
145
146 const string default_options = "-ksp_type fgmres \n"
147 "-pc_type lu \n"
148 "-pc_factor_mat_solver_type mumps \n"
149 "-mat_mumps_icntl_20 0 \n"
150 "-ksp_monitor \n"
151 "-snes_type newtonls \n"
152 "-snes_linesearch_type basic \n"
153 "-snes_max_it 100 \n"
154 "-snes_atol 1e-8 \n"
155 "-snes_rtol 1e-8 \n"
156 "-snes_monitor \n"
157 "-ts_monitor \n"
158 "-ts_type beuler \n"
159 "-ts_exact_final_time stepover \n";
160
161 string param_file = "param_file.petsc";
162 if (!static_cast<bool>(ifstream(param_file))) {
163 std::ofstream file(param_file.c_str(), std::ios::ate);
164 if (file.is_open()) {
165 file << default_options;
166 file.close();
167 }
168 }
169
170 MoFEM::Core::Initialize(&argc, &argv, param_file.c_str(), help);
171
172 auto core_log = logging::core::get();
173 core_log->add_sink(
175 LogManager::setLog("THERMALSYNC");
176 MOFEM_LOG_TAG("THERMALSYNC", "thermal");
177
178 try {
179
180 PetscBool flg = PETSC_TRUE;
181 char mesh_file_name[255];
182 CHKERR PetscOptionsGetString(PETSC_NULLPTR, PETSC_NULLPTR, "-my_file",
183 mesh_file_name, 255, &flg);
184 if(flg != PETSC_TRUE) {
185 SETERRQ(PETSC_COMM_SELF, MOFEM_NOT_FOUND,
186 "*** ERROR -my_file (MESH FILE NEEDED)");
187 }
188
189 char time_data_file_for_ground_surface[255];
190 PetscBool ground_temperature_analysis = PETSC_FALSE;
191 CHKERR PetscOptionsGetString(PETSC_NULLPTR,PETSC_NULLPTR,"-my_ground_analysis_data",
192 time_data_file_for_ground_surface,255,&ground_temperature_analysis);
193 if(ground_temperature_analysis) {
194#ifndef WITH_ADOL_C
195 SETERRQ(PETSC_COMM_SELF, MOFEM_NOT_INSTALLED,
196 "*** ERROR to do ground thermal analysis MoFEM need to be compiled "
197 "with ADOL-C");
198#endif // WITH_ADOL_C
199 }
200
201 //create MoAB database
202 moab::Core mb_instance;
203 moab::Interface& moab = mb_instance;
204 const char *option;
205 option = "";
206 CHKERR moab.load_file(mesh_file_name, 0, option);
207 //create MoFEM database
208 MoFEM::Core core(moab);
209 MoFEM::Interface& m_field = core;
210
211 DMType dm_name = "DMTHERMAL";
212 CHKERR DMRegister_MoFEM(dm_name);
213 // create dm instance
214 DM dm;
215 CHKERR DMCreate(PETSC_COMM_WORLD, &dm);
216 CHKERR DMSetType(dm, dm_name);
217
218 //set entities bit level (this allow to set refinement levels for h-adaptivity)
219 //only one level is used in this example
220 BitRefLevel bit_level0;
221 bit_level0.set(0);
222 CHKERR m_field.getInterface<BitRefManager>()->setBitRefLevelByDim(0, 3,
223 bit_level0);
224
225 //Fields H1 space rank 1
226 CHKERR m_field.add_field("TEMP", H1, AINSWORTH_LEGENDRE_BASE, 1,
227 MB_TAG_SPARSE, MF_ZERO);
228 CHKERR m_field.add_field("TEMP_RATE", H1, AINSWORTH_LEGENDRE_BASE, 1,
229 MB_TAG_SPARSE, MF_ZERO);
230
231 //Add field H1 space rank 3 to approximate geometry using hierarchical basis
232 //For 10 node tets, before use, geometry is projected on that field (see below)
233 CHKERR m_field.add_field(
234 "MESH_NODE_POSITIONS",H1,AINSWORTH_LEGENDRE_BASE,3,MB_TAG_SPARSE,MF_ZERO
235 );
236
237 //meshset consisting all entities in mesh
238 EntityHandle root_set = moab.get_root_set();
239 //add entities to field (root_mesh, i.e. on all mesh etities fields are approx.)
240 CHKERR m_field.add_ents_to_field_by_type(root_set,MBTET,"TEMP");
241 CHKERR m_field.add_ents_to_field_by_type(root_set,MBTET,"TEMP_RATE");
242
243 int order;
244 CHKERR PetscOptionsGetInt(PETSC_NULLPTR, PETSC_NULLPTR, "-my_order", &order, &flg);
245
246 if (flg != PETSC_TRUE) {
247 order = 1;
248 }
249 // set app. order
250 // see Hierarchic Finite Element Bases on Unstructured Tetrahedral Meshes
251 // (Mark Ainsworth & Joe Coyle) for simplicity of example to all entities is
252 // applied the same order
253 CHKERR m_field.set_field_order(root_set,MBTET,"TEMP",order);
254 CHKERR m_field.set_field_order(root_set,MBTRI,"TEMP",order);
255 CHKERR m_field.set_field_order(root_set,MBEDGE,"TEMP",order);
256 CHKERR m_field.set_field_order(root_set,MBVERTEX,"TEMP",1);
257
258 CHKERR m_field.set_field_order(root_set,MBTET,"TEMP_RATE",order);
259 CHKERR m_field.set_field_order(root_set,MBTRI,"TEMP_RATE",order);
260 CHKERR m_field.set_field_order(root_set,MBEDGE,"TEMP_RATE",order);
261 CHKERR m_field.set_field_order(root_set,MBVERTEX,"TEMP_RATE",1);
262
263 //geometry approximation is set to 2nd oreder
264 CHKERR m_field.add_ents_to_field_by_type(root_set, MBTET,
265 "MESH_NODE_POSITIONS");
266 CHKERR m_field.set_field_order(0,MBTET,"MESH_NODE_POSITIONS",2);
267 CHKERR m_field.set_field_order(0,MBTRI,"MESH_NODE_POSITIONS",2);
268 CHKERR m_field.set_field_order(0,MBEDGE,"MESH_NODE_POSITIONS",2);
269 CHKERR m_field.set_field_order(0,MBVERTEX,"MESH_NODE_POSITIONS",1);
270
271 // configure blocks by parsing config file
272 // it allow to set approximation order for each block independently
273 PetscBool block_config;
274 char block_config_file[255];
275 CHKERR PetscOptionsGetString(PETSC_NULLPTR, PETSC_NULLPTR, "-my_block_config",
276 block_config_file, 255, &block_config);
277 std::map<int,BlockOptionData> block_data;
278 bool solar_radiation = false;
279 if (block_config) {
280 try {
281 ifstream ini_file(block_config_file);
282 // std::cerr << block_config_file << std::endl;
283 po::variables_map vm;
284 po::options_description config_file_options;
286
287 std::ostringstream str_order;
288 str_order << "block_" << it->getMeshsetId() << ".temperature_order";
289 config_file_options.add_options()(
290 str_order.str().c_str(),
291 po::value<int>(&block_data[it->getMeshsetId()].oRder)
292 ->default_value(order));
293
294 std::ostringstream str_cond;
295 str_cond << "block_" << it->getMeshsetId() << ".heat_conductivity";
296 config_file_options.add_options()(
297 str_cond.str().c_str(),
298 po::value<double>(&block_data[it->getMeshsetId()].cOnductivity)
299 ->default_value(-1));
300
301 std::ostringstream str_capa;
302 str_capa << "block_" << it->getMeshsetId() << ".heat_capacity";
303 config_file_options.add_options()(
304 str_capa.str().c_str(),
305 po::value<double>(&block_data[it->getMeshsetId()].cApacity)
306 ->default_value(-1));
307
308 std::ostringstream str_init_temp;
309 str_init_temp << "block_" << it->getMeshsetId()
310 << ".initial_temperature";
311 config_file_options.add_options()(
312 str_init_temp.str().c_str(),
313 po::value<double>(&block_data[it->getMeshsetId()].initTemp)
314 ->default_value(0));
315 }
316 config_file_options.add_options()(
317 "climate_model.solar_radiation",
318 po::value<bool>(&solar_radiation)->default_value(false));
319
320 po::parsed_options parsed =
321 parse_config_file(ini_file, config_file_options, true);
322 store(parsed,vm);
323 po::notify(vm);
324
326 if (block_data[it->getMeshsetId()].oRder == -1)
327 continue;
328 if (block_data[it->getMeshsetId()].oRder == order)
329 continue;
330 PetscPrintf(PETSC_COMM_WORLD, "Set block %d oRder to %d\n",
331 it->getMeshsetId(), block_data[it->getMeshsetId()].oRder);
332 Range block_ents;
333 CHKERR moab.get_entities_by_handle(it->meshset, block_ents, true);
334 Range ents_to_set_order;
335 CHKERR moab.get_adjacencies(block_ents, 3, false, ents_to_set_order,
336 moab::Interface::UNION);
337 ents_to_set_order = ents_to_set_order.subset_by_type(MBTET);
338 CHKERR moab.get_adjacencies(block_ents, 2, false, ents_to_set_order,
339 moab::Interface::UNION);
340 CHKERR moab.get_adjacencies(block_ents, 1, false, ents_to_set_order,
341 moab::Interface::UNION);
342 CHKERR m_field.set_field_order(ents_to_set_order, "TEMP",
343 block_data[it->getMeshsetId()].oRder);
344 CHKERR m_field.set_field_order(ents_to_set_order, "TEMP_RATE",
345 block_data[it->getMeshsetId()].oRder);
346 }
347 std::vector<std::string> additional_parameters;
348 additional_parameters =
349 collect_unrecognized(parsed.options, po::include_positional);
350 for (std::vector<std::string>::iterator vit =
351 additional_parameters.begin();
352 vit != additional_parameters.end(); vit++) {
353 CHKERR PetscPrintf(PETSC_COMM_WORLD,
354 "** WARRING Unrecognised option %s\n", vit->c_str());
355 }
356
357 } catch (const std::exception& ex) {
358 std::ostringstream ss;
359 ss << ex.what() << std::endl;
360 SETERRQ(PETSC_COMM_SELF,MOFEM_STD_EXCEPTION_THROW,ss.str().c_str());
361 }
362 }
363
364 // this default class to calculate thermal elements
365 ThermalElement thermal_elements(m_field);
366 CHKERR thermal_elements.addThermalElements("TEMP");
367 CHKERR thermal_elements.addThermalFluxElement("TEMP");
368 CHKERR thermal_elements.addThermalConvectionElement("TEMP");
369 CHKERR thermal_elements.addThermalRadiationElement("TEMP");
370 // add rate of temperature to data field of finite element
371 CHKERR m_field.modify_finite_element_add_field_data("THERMAL_FE",
372 "TEMP_RATE");
373 // and temperature element default element operators at integration (gauss)
374 // points
376 thermal_elements.getLoopFeRhs().getOpPtrVector(), {H1},
377 "MESH_NODE_POSITIONS");
379 thermal_elements.getLoopFeLhs().getOpPtrVector(), {H1},
380 "MESH_NODE_POSITIONS");
381 CHKERR thermal_elements.setTimeSteppingProblem("TEMP", "TEMP_RATE");
382
383 // set block material data from option file
384 std::map<int, ThermalElement::BlockData>::iterator mit;
385 mit = thermal_elements.setOfBlocks.begin();
386 for (; mit != thermal_elements.setOfBlocks.end(); mit++) {
387 // std::cerr << mit->first << std::endl;
388 // std::cerr << block_data[mit->first].cOnductivity << " " <<
389 // block_data[mit->first].cApacity << std::endl;
390 if (block_data[mit->first].cOnductivity != -1) {
391 PetscPrintf(PETSC_COMM_WORLD, "Set block %d heat conductivity to %3.2e\n",
392 mit->first, block_data[mit->first].cOnductivity);
393 for (int dd = 0; dd < 3; dd++) {
394 mit->second.cOnductivity_mat(dd, dd) =
395 block_data[mit->first].cOnductivity;
396 }
397 }
398 if (block_data[mit->first].cApacity != -1) {
399 PetscPrintf(PETSC_COMM_WORLD, "Set block %d heat capacity to %3.2e\n",
400 mit->first, block_data[mit->first].cApacity);
401 mit->second.cApacity = block_data[mit->first].cApacity;
402 }
403 }
404
405#ifdef __GROUND_SURFACE_TEMPERATURE_HPP
406 GroundSurfaceTemperature ground_surface(m_field);
407 CrudeClimateModel time_data(time_data_file_for_ground_surface);
408 GroundSurfaceTemperature::PreProcess exectuteGenericClimateModel(&time_data);
409 if (ground_temperature_analysis) {
410 CHKERR ground_surface.addSurfaces("TEMP");
411 CHKERR ground_surface.setOperators(&time_data, "TEMP");
412 }
413#endif //__GROUND_SURFACE_TEMPERATURE_HPP
414
415 //build database, i.e. declare dofs, elements and adjacencies
416
417 // build field
418 CHKERR m_field.build_fields();
419 // project 10 node tet approximation of geometry on hierarchical basis
420 Projection10NodeCoordsOnField ent_method_material(m_field,
421 "MESH_NODE_POSITIONS");
422 CHKERR m_field.loop_dofs("MESH_NODE_POSITIONS", ent_method_material);
423
424 // set initial temperature from Cubit blocksets
425 mit = thermal_elements.setOfBlocks.begin();
426 for (; mit != thermal_elements.setOfBlocks.end(); mit++) {
427 if (mit->second.initTemp != 0) {
428 Range vertices;
429 CHKERR moab.get_connectivity(mit->second.tEts, vertices, true);
430 CHKERR m_field.getInterface<FieldBlas>()->setField(
431 mit->second.initTemp, MBVERTEX, vertices, "TEMP");
432 }
433 }
434
436 if (std::regex_match(it->getName(), std::regex("INT_THERMAL(.*)"))) {
437 std::vector<double> data;
438 CHKERR it->getAttributes(data);
439 if (data.size() != 1)
440 SETERRQ(PETSC_COMM_SELF, 1, "Data inconsistency");
441 Range block_ents, block_verts;
442 CHKERR moab.get_entities_by_handle(it->getMeshset(), block_ents, true);
443 CHKERR moab.get_connectivity(block_ents, block_verts, true);
444 CHKERR m_field.getInterface<FieldBlas>()->setField(data[0], MBVERTEX,
445 block_verts, "TEMP");
446 }
447 }
448
450 if (block_data[it->getMeshsetId()].initTemp != 0) {
451 Range block_ents;
452 CHKERR moab.get_entities_by_handle(it->meshset, block_ents, true);
453 Range vertices;
454 CHKERR moab.get_connectivity(block_ents, vertices, true);
455 CHKERR m_field.getInterface<FieldBlas>()->setField(
456 block_data[it->getMeshsetId()].initTemp, MBVERTEX, vertices, "TEMP");
457 }
458 }
459
460 MPI_Comm moab_comm_world;
461 MPI_Comm_dup(PETSC_COMM_WORLD, &moab_comm_world);
462 ParallelComm *pcomm = ParallelComm::get_pcomm(&moab, MYPCOMM_INDEX);
463 if (pcomm == NULL)
464 pcomm = new ParallelComm(&moab, moab_comm_world);
465
466 PetscBool is_partitioned = PETSC_FALSE;
467 CHKERR PetscOptionsGetBool(PETSC_NULLPTR, PETSC_NULLPTR, "-dm_is_partitioned",
468 &is_partitioned, PETSC_NULLPTR);
469
470 Range thermal_element_ents;
471 CHKERR m_field.get_finite_element_entities_by_dimension("THERMAL_FE", 3,
472 thermal_element_ents);
473
474 PetscBool save_skin = PETSC_TRUE;
475 CHKERR PetscOptionsGetBool(PETSC_NULLPTR, PETSC_NULLPTR, "-my_save_skin",
476 &save_skin, PETSC_NULLPTR);
477
478 Skinner skin(&m_field.get_moab());
479 Range skin_faces; // skin faces from 3d ents
480 CHKERR skin.find_skin(0, thermal_element_ents, false, skin_faces);
481 Range proc_skin;
482 if (is_partitioned) {
483 CHKERR pcomm->filter_pstatus(skin_faces,
484 PSTATUS_SHARED | PSTATUS_MULTISHARED,
485 PSTATUS_NOT, -1, &proc_skin);
486 } else {
487 proc_skin = skin_faces;
488 }
489
490 if (save_skin) {
491 CHKERR m_field.add_finite_element("POST_PROC_SKIN");
492 CHKERR m_field.modify_finite_element_add_field_row("POST_PROC_SKIN", "TEMP");
493 CHKERR m_field.modify_finite_element_add_field_col("POST_PROC_SKIN", "TEMP");
494 CHKERR m_field.modify_finite_element_add_field_data("POST_PROC_SKIN", "TEMP");
495 CHKERR m_field.modify_finite_element_add_field_data("POST_PROC_SKIN",
496 "MESH_NODE_POSITIONS");
497 CHKERR m_field.add_ents_to_finite_element_by_dim(proc_skin, 2,
498 "POST_PROC_SKIN");
499 }
500
501 // build finite elemnts
503 // build adjacencies
504 CHKERR m_field.build_adjacencies(bit_level0);
505
506 // delete old temperature recorded series
507 SeriesRecorder *recorder_ptr;
508 CHKERR m_field.getInterface(recorder_ptr);
509 if (recorder_ptr->check_series("THEMP_SERIES")) {
510 /*for(_IT_SERIES_STEPS_BY_NAME_FOR_LOOP_(recorder_ptr,"THEMP_SERIES",sit)) {
511 CHKERR
512 recorder_ptr->load_series_data("THEMP_SERIES",sit->get_step_number());
513 }*/
514 CHKERR recorder_ptr->delete_recorder_series("THEMP_SERIES");
515 }
516
517 std::vector<std::array<double, 3>> eval_points;
518 eval_points.resize(0);
519 PetscBool eval_points_flg = PETSC_FALSE;
520 char eval_points_file[255];
521 CHKERR PetscOptionsGetString(PETSC_NULLPTR, PETSC_NULLPTR, "-my_eval_points_file",
522 eval_points_file, 255, &eval_points_flg);
523 if (eval_points_flg) {
524 std::ifstream in_file(eval_points_file, std::ios::in);
525 if (!in_file.is_open()) {
526 SETERRQ(PETSC_COMM_SELF, MOFEM_DATA_INCONSISTENCY, "Cannot open file %s",
527 eval_points_file);
528 }
529 double x, y, z;
530 while (in_file >> x >> y >> z) {
531 eval_points.push_back({x, y, z});
532 }
533 }
534
535 // set dm data structure which created mofem data structures
536 CHKERR DMMoFEMCreateMoFEM(dm, &m_field, dm_name, bit_level0);
537 CHKERR DMSetFromOptions(dm);
538 // add elements to dm
539 CHKERR DMMoFEMAddElement(dm, "THERMAL_FE");
540 CHKERR DMMoFEMAddElement(dm, "THERMAL_FLUX_FE");
541 CHKERR DMMoFEMAddElement(dm, "THERMAL_CONVECTION_FE");
542 CHKERR DMMoFEMAddElement(dm, "THERMAL_RADIATION_FE");
543 if (save_skin)
544 CHKERR DMMoFEMAddElement(dm, "POST_PROC_SKIN");
545
546#ifdef __GROUND_SURFACE_TEMPERATURE_HPP
547 if (ground_temperature_analysis) {
548 CHKERR DMMoFEMAddElement(dm, "GROUND_SURFACE_FE");
549 }
550#endif //__GROUND_SURFACE_TEMPERATURE_HPP
551
552 CHKERR DMSetUp(dm);
553
554 // create matrices
555 Vec T, F;
557 CHKERR VecDuplicate(T, &F);
558 Mat A;
560
561 DirichletTemperatureBc dirichlet_bc(m_field, "TEMP", A, T, F);
562 ThermalElement::UpdateAndControl update_velocities(m_field, "TEMP",
563 "TEMP_RATE");
564 ThermalElement::TimeSeriesMonitor monitor(m_field, "THEMP_SERIES", "TEMP",
565 eval_points);
566 MonitorPostProc post_proc(m_field);
567
568 // Initialize data with values save of on the field
569 CHKERR VecZeroEntries(T);
570 CHKERR DMoFEMMeshToLocalVector(dm, T, INSERT_VALUES, SCATTER_FORWARD);
571 CHKERR DMoFEMPreProcessFiniteElements(dm, &dirichlet_bc);
572 CHKERR DMoFEMMeshToGlobalVector(dm, T, INSERT_VALUES, SCATTER_REVERSE);
573
574 // preprocess
575 CHKERR DMMoFEMTSSetIFunction(dm, DM_NO_ELEMENT, NULL, &update_velocities,
576 NULL);
577 CHKERR DMMoFEMTSSetIFunction(dm, DM_NO_ELEMENT, NULL, &dirichlet_bc, NULL);
578 CHKERR DMMoFEMTSSetIJacobian(dm, DM_NO_ELEMENT, NULL, &dirichlet_bc, NULL);
579#ifdef __GROUND_SURFACE_TEMPERATURE_HPP
581 &exectuteGenericClimateModel, NULL);
582 { // add preprocessor, calculating angle on which sun ray on the surface
583 if (solar_radiation) {
584 boost::ptr_vector<
585 GroundSurfaceTemperature::SolarRadiationPreProcessor>::iterator it,
586 hi_it;
587 it = ground_surface.preProcessShade.begin();
588 hi_it = ground_surface.preProcessShade.end();
589 for (; it != hi_it; it++) {
590 CHKERR DMMoFEMTSSetIFunction(dm, DM_NO_ELEMENT, NULL, &*it, NULL);
591 }
592 }
593 }
594#endif //__GROUND_SURFACE_TEMPERATURE_HPP
595
596 // loops rhs
597 CHKERR DMMoFEMTSSetIFunction(dm, "THERMAL_FE", &thermal_elements.feRhs, NULL,
598 NULL);
599 CHKERR DMMoFEMTSSetIFunction(dm, "THERMAL_FLUX_FE", &thermal_elements.feFlux,
600 NULL, NULL);
601 CHKERR DMMoFEMTSSetIFunction(dm, "THERMAL_CONVECTION_FE",
602 &thermal_elements.feConvectionRhs, NULL, NULL);
603 CHKERR DMMoFEMTSSetIFunction(dm, "THERMAL_RADIATION_FE",
604 &thermal_elements.feRadiationRhs, NULL, NULL);
605#ifdef __GROUND_SURFACE_TEMPERATURE_HPP
606 if (ground_temperature_analysis) {
607 CHKERR DMMoFEMTSSetIFunction(dm, "GROUND_SURFACE_FE",
608 &ground_surface.getFeGroundSurfaceRhs(), NULL,
609 NULL);
610 }
611#endif //__GROUND_SURFACE_TEMPERATURE_HPP
612
613 // loops lhs
614 CHKERR DMMoFEMTSSetIJacobian(dm, "THERMAL_FE", &thermal_elements.feLhs, NULL,
615 NULL);
616 CHKERR DMMoFEMTSSetIJacobian(dm, "THERMAL_CONVECTION_FE",
617 &thermal_elements.feConvectionLhs, NULL, NULL);
618 CHKERR DMMoFEMTSSetIJacobian(dm, "THERMAL_RADIATION_FE",
619 &thermal_elements.feRadiationLhs, NULL, NULL);
620#ifdef __GROUND_SURFACE_TEMPERATURE_HPP
621 if (ground_temperature_analysis) {
622 CHKERR DMMoFEMTSSetIJacobian(dm, "GROUND_SURFACE_FE",
623 &ground_surface.getFeGroundSurfaceLhs(), NULL,
624 NULL);
625 }
626#endif //__GROUND_SURFACE_TEMPERATURE_HPP
627
628 //postprocess
629 CHKERR DMMoFEMTSSetIFunction(dm,DM_NO_ELEMENT,NULL,NULL,&dirichlet_bc);
630 CHKERR DMMoFEMTSSetIJacobian(dm,DM_NO_ELEMENT,NULL,NULL,&dirichlet_bc);
631
632 TsCtx *ts_ctx;
634 //add monitor operator
635 ts_ctx->getPostProcessMonitor().push_back(&monitor);
636 ts_ctx->getPostProcessMonitor().push_back(&post_proc);
637
638 //create time solver
639 TS ts;
640 CHKERR TSCreate(PETSC_COMM_WORLD,&ts);
641 CHKERR TSSetType(ts,TSBEULER);
642
643 CHKERR TSSetIFunction(ts,F,PETSC_NULLPTR,PETSC_NULLPTR);
644 CHKERR TSSetIJacobian(ts,A,A,PETSC_NULLPTR,PETSC_NULLPTR);
645 //add monitor to TS solver
646 CHKERR TSMonitorSet(ts,TsMonitorSet,ts_ctx,PETSC_NULLPTR); // !!!
647
648 CHKERR recorder_ptr->add_series_recorder("THEMP_SERIES");
649 //start to record
650 CHKERR recorder_ptr->initialize_series_recorder("THEMP_SERIES");
651
652 double ftime = 1;
653 CHKERR TSSetDuration(ts,PETSC_DEFAULT,ftime);
654 CHKERR TSSetFromOptions(ts);
655 CHKERR TSSetDM(ts,dm);
656
657 CHKERR TSSolve(ts,T);
658 CHKERR TSGetTime(ts,&ftime);
659
660 //end recoder
661 CHKERR recorder_ptr->finalize_series_recorder("THEMP_SERIES");
662
663 PetscInt steps,snesfails,rejects,nonlinits,linits;
664 CHKERR TSGetTimeStepNumber(ts,&steps);
665 CHKERR TSGetSNESFailures(ts,&snesfails);
666 CHKERR TSGetStepRejections(ts,&rejects);
667 CHKERR TSGetSNESIterations(ts,&nonlinits);
668 CHKERR TSGetKSPIterations(ts,&linits);
669
670 PetscPrintf(PETSC_COMM_WORLD,
671 "steps %D (%D rejected, %D SNES fails), ftime %g, nonlinits %D, "
672 "linits %D\n",
673 steps, rejects, snesfails, ftime, nonlinits, linits);
674
675 // save solution, if boundary conditions are defined you can use that file in
676 // mechanical problem to calculate thermal stresses
677 PetscBool save_solution = PETSC_TRUE;
678 CHKERR PetscOptionsGetBool(PETSC_NULLPTR, PETSC_NULLPTR, "-my_save_solution",
679 &save_solution, PETSC_NULLPTR);
680
681 if (save_solution) {
682 if (is_partitioned) {
683 CHKERR moab.write_file("solution.h5m");
684 } else {
685 if (m_field.get_comm_rank() == 0) {
686 CHKERR moab.write_file("solution.h5m");
687 }
688 }
689 }
690
691 CHKERR MatDestroy(&A);
692 CHKERR VecDestroy(&T);
693 CHKERR VecDestroy(&F);
694
695 CHKERR TSDestroy(&ts);
696
697 }
699
700 return MoFEM::Core::Finalize();
701}
#define DM_NO_ELEMENT
Definition DMMoFEM.hpp:50
int main()
#define CATCH_ERRORS
Catch errors.
@ MF_ZERO
@ AINSWORTH_LEGENDRE_BASE
Ainsworth Cole (Legendre) approx. base .
Definition definitions.h:60
#define MoFEMFunctionReturnHot(a)
Last executable line of each PETSc function used for error handling. Replaces return()
@ H1
continuous field
Definition definitions.h:85
#define MYPCOMM_INDEX
default communicator number PCOMM
#define MoFEMFunctionBegin
First executable line of each MoFEM function, used for error handling. Final line of MoFEM functions ...
@ BLOCKSET
@ MOFEM_NOT_FOUND
Definition definitions.h:33
@ MOFEM_NOT_INSTALLED
Definition definitions.h:37
@ MOFEM_STD_EXCEPTION_THROW
Definition definitions.h:39
@ MOFEM_DATA_INCONSISTENCY
Definition definitions.h:31
#define MoFEMFunctionReturn(a)
Last executable line of each PETSc function used for error handling. Replaces return()
#define CHKERR
Inline error check.
#define MoFEMFunctionBeginHot
First executable line of each MoFEM function, used for error handling. Final line of MoFEM functions ...
constexpr int order
@ F
PetscErrorCode DMoFEMMeshToGlobalVector(DM dm, Vec g, InsertMode mode, ScatterMode scatter_mode, RowColData rc=RowColData::COL)
set ghosted vector values on all existing mesh entities
Definition DMMoFEM.cpp:525
PetscErrorCode DMMoFEMAddElement(DM dm, std::string fe_name)
add element to dm
Definition DMMoFEM.cpp:488
PetscErrorCode DMMoFEMTSSetIFunction(DM dm, const char fe_name[], MoFEM::FEMethod *method, MoFEM::BasicMethod *pre_only, MoFEM::BasicMethod *post_only)
set TS implicit function evaluation function
Definition DMMoFEM.cpp:790
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 DMCreateMatrix_MoFEM(DM dm, Mat *M)
Definition DMMoFEM.cpp:1188
PetscErrorCode DMMoFEMGetTsCtx(DM dm, MoFEM::TsCtx **ts_ctx)
get MoFEM::TsCtx data structure
Definition DMMoFEM.cpp:1132
PetscErrorCode DMoFEMMeshToLocalVector(DM dm, Vec l, InsertMode mode, ScatterMode scatter_mode, RowColData rc=RowColData::COL)
set local (or ghosted) vector values on mesh for partition only
Definition DMMoFEM.cpp:514
PetscErrorCode DMRegister_MoFEM(const char sname[])
Register MoFEM problem.
Definition DMMoFEM.cpp:43
PetscErrorCode DMMoFEMTSSetIJacobian(DM dm, const std::string fe_name, boost::shared_ptr< MoFEM::FEMethod > method, boost::shared_ptr< MoFEM::BasicMethod > pre_only, boost::shared_ptr< MoFEM::BasicMethod > post_only)
set TS Jacobian evaluation function
Definition DMMoFEM.cpp:843
PetscErrorCode DMCreateGlobalVector_MoFEM(DM dm, Vec *g)
DMShellSetCreateGlobalVector.
Definition DMMoFEM.cpp:1157
PetscErrorCode DMoFEMPreProcessFiniteElements(DM dm, MoFEM::FEMethod *method)
execute finite element method for each element in dm (problem)
Definition DMMoFEM.cpp:536
virtual MoFEMErrorCode add_ents_to_finite_element_by_dim(const EntityHandle entities, const int dim, const std::string name, const bool recursive=true)=0
add entities to finite element
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 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 get_finite_element_entities_by_dimension(const std::string name, int dim, Range &ents) const =0
get entities in the finite element by dimension
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 LoggerType & setLog(const std::string channel)
Set ans resset chanel logger.
#define MOFEM_LOG_TAG(channel, tag)
Tag channel.
virtual MoFEMErrorCode loop_dofs(const Problem *problem_ptr, const std::string &field_name, RowColData rc, DofMethod &method, int lower_rank, int upper_rank, int verb=DEFAULT_VERBOSITY)=0
Make a loop over dofs.
#define _IT_CUBITMESHSETS_BY_SET_TYPE_FOR_LOOP_(MESHSET_MANAGER, CUBITBCTYPE, IT)
Iterator that loops over a specific Cubit MeshSet having a particular BC meshset in a moFEM field.
virtual MoFEMErrorCode finalize_series_recorder(const std::string &serie_name)
virtual bool check_series(const std::string &name) const
check if series is in database
virtual MoFEMErrorCode initialize_series_recorder(const std::string &serie_name)
virtual MoFEMErrorCode add_series_recorder(const std::string &series_name)
virtual MoFEMErrorCode delete_recorder_series(const std::string &series_name)
MoFEMErrorCode addThermalElements(const std::string field_name, const std::string mesh_nodals_positions="MESH_NODE_POSITIONS")
add thermal element on tets
MoFEMErrorCode addThermalFluxElement(const std::string field_name, const std::string mesh_nodals_positions="MESH_NODE_POSITIONS")
add heat flux element
MoFEMErrorCode addThermalConvectionElement(const std::string field_name, const std::string mesh_nodals_positions="MESH_NODE_POSITIONS")
add convection element
MoFEMErrorCode addThermalRadiationElement(const std::string field_name, const std::string mesh_nodals_positions="MESH_NODE_POSITIONS")
add Non-linear Radiation element
MoFEMErrorCode setTimeSteppingProblem(string field_name, string rate_name, const std::string mesh_nodals_positions="MESH_NODE_POSITIONS")
set up operators for unsteady heat flux; convection; radiation problem
MoFEM::TsCtx * ts_ctx
static MoFEMErrorCodeGeneric< PetscErrorCode > ierr
PetscErrorCode MoFEMErrorCode
MoFEM/PETSc error code.
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
PetscErrorCode TsMonitorSet(TS ts, PetscInt step, PetscReal t, Vec u, void *ctx)
Set monitor for TS solver.
Definition TsCtx.cpp:263
PetscErrorCode PetscOptionsGetInt(PetscOptions *, const char pre[], const char name[], PetscInt *ivalue, PetscBool *set)
PetscErrorCode PetscOptionsGetBool(PetscOptions *, const char pre[], const char name[], PetscBool *bval, PetscBool *set)
PetscErrorCode PetscOptionsGetString(PetscOptions *, const char pre[], const char name[], char str[], size_t size, PetscBool *set)
constexpr AssemblyType A
OpPostProcMapInMoab< SPACE_DIM, SPACE_DIM > OpPPMap
Add operators pushing bases from local to physical configuration.
Managing BitRefLevels.
virtual moab::Interface & get_moab()=0
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.
virtual int get_comm_rank() const =0
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.
Structure for user loop methods on finite elements.
Basic algebra on fields.
Definition FieldBlas.hpp:21
boost::ptr_deque< UserDataOperator > & getOpPtrVector()
Use to push back operator for row operator.
static boost::shared_ptr< SinkType > createSink(boost::shared_ptr< std::ostream > stream_ptr, std::string comm_filter)
Create a sink object.
static boost::shared_ptr< std::ostream > getStrmSync()
Get the strm sync object.
Get field gradients at integration pts for scalar field rank 0, i.e. vector field.
Specialization for double precision scalar field values calculation.
Specialization for MatrixDouble vector field values calculation.
Post post-proc data at points from hash maps.
auto & getMapGaussPts()
Get vector of vectors associated to integration points.
auto & getPostProcMesh()
Get postprocessing mesh.
Projection of edge entities with one mid-node on hierarchical basis.
Interface for Time Stepping (TS) solver.
Definition TsCtx.hpp:17
BasicMethodsSequence & getPostProcessMonitor()
Get the postProcess to do Monitor object.
Definition TsCtx.hpp:148
MoFEMErrorCode getInterface(IFACE *&iface) const
Get interface reference to pointer of interface.
PostProcBrokenMeshInMoab< VolumeElementForcesAndSourcesCore > postProc
MoFEMErrorCode postProcess()
Post-processing function executed at loop completion.
MoFEMErrorCode operator()()
Main operator function executed for each loop iteration.
MoFEMErrorCode preProcess()
Pre-processing function executed at loop initialization.
MoFEM::Interface & mField
MonitorPostProc(MoFEM::Interface &m_field)
PostProcBrokenMeshInMoab< FaceElementForcesAndSourcesCore > skinPostProc
TS monitore it records temperature at time steps.
this calass is to control time stepping
structure grouping operators and data used for thermal problems
MyVolumeFE feRhs
cauclate right hand side for tetrahedral elements
MyVolumeFE & getLoopFeLhs()
get lhs volume element
MyVolumeFE & getLoopFeRhs()
get rhs volume element
std::map< int, BlockData > setOfBlocks
maps block set id with appropriate BlockData
static char help[]