v0.16.0
Loading...
Searching...
No Matches
photon_diffusion.cpp
Go to the documentation of this file.
1/**
2 * \file photon_diffusion.cpp
3 * \example mofem/tutorials/scl-10/photon_diffusion.cpp
4 *
5 **/
6
7#include <stdlib.h>
8#include <cmath>
9#include <MoFEM.hpp>
10#include <boost/math/constants/constants.hpp>
11#include <SourceFunction.hpp>
12
13#ifdef ENABLE_PYTHON_BINDING
14 #include <boost/python.hpp>
15 #include <boost/python/def.hpp>
16 #include <boost/python/numpy.hpp>
17
18namespace bp = boost::python;
19namespace np = boost::python::numpy;
20#endif
21
22using namespace MoFEM;
23
24static char help[] = "...\n\n";
25
26template <int DIM> struct ElementsAndOps {};
27
28//! [Define dimension]
29constexpr int SPACE_DIM = 3; //< Space dimension of problem, mesh
30//! [Define dimension]
31
33using DomainEleOp = DomainEle::UserDataOperator;
35using BoundaryEleOp = BoundaryEle::UserDataOperator;
39
41
43
54
61
62const double n = 1.44; ///< refractive index of diffusive medium
63const double c = 30.; ///< speed of light (cm/ns)
64const double v = c / n; ///< phase velocity of light in medium (cm/ns)
65const double inv_v = 1. / v;
66
67double mu_a; ///< absorption coefficient (cm^-1)
68double mu_sp; ///< scattering coefficient (cm^-1)
69double D;
70double A;
71double h;
72
74double beam_radius; //< spot radius
77double flux_magnitude = 1e3; ///< impulse magnitude
78const int kronrod_points =
79 15; ///< number of points for kronrod integration, can be 15, 31, 41, 51, or 61 (from boost library docs)
80///< This has been tested and gives the same result for any number of points. Increasing the number of points will increase the compute time, so 15 is used as default.
81
82double cam_len_x = 5.0;
83double cam_len_y = 5.0;
84
85PetscBool from_initial = PETSC_TRUE;
86PetscBool output_volume = PETSC_FALSE;
87PetscBool output_camera = PETSC_FALSE;
88PetscBool testing = PETSC_FALSE;
89
90int order = 2;
92
93char init_data_file_name[255] = "init_file.dat";
94char interp_file_name[255] = "interp_sensitivity.py";
95char interp_image_name[255] = "sens_image.png";
96PetscBool enable_python = PETSC_FALSE;
97
99
100#include <boost/math/quadrature/gauss_kronrod.hpp>
101using namespace boost::math::quadrature;
102
103struct PhotonDiffusion {
104public:
106
107 // Declaration of the main function to run analysis
109 struct InterpPython;
110
111private:
112 // Declaration of other main functions called in runProgram()
123
124 // Main interfaces
126
127 // Object to mark boundary entities for the assembling of domain elements
128 boost::shared_ptr<std::vector<unsigned char>> boundaryMarker;
129
130 boost::shared_ptr<FEMethod> domainLhsFEPtr;
131 boost::shared_ptr<FEMethod> boundaryLhsFEPtr;
132 boost::shared_ptr<FEMethod> boundaryRhsFEPtr;
133
134#ifdef ENABLE_PYTHON_BINDING
135 boost::shared_ptr<InterpPython> interpPythonPtr;
136#endif
137 struct CommonData {
138 boost::shared_ptr<VectorDouble> approxVals;
139 boost::shared_ptr<VectorDouble> uAtPtsPtr;
143
145 };
146
147 boost::shared_ptr<CommonData> commonDataPtr;
148
149 struct OpError;
150
151 struct OpCameraInteg : public BoundaryEleOp {
152 boost::shared_ptr<CommonData> commonDataPtr;
153 OpCameraInteg(boost::shared_ptr<CommonData> common_data_ptr)
154 : BoundaryEleOp("PHOTON_FLUENCE_RATE", OPROW),
155 commonDataPtr(common_data_ptr) {
156 std::fill(&doEntities[MBVERTEX], &doEntities[MBMAXTYPE], false);
157 doEntities[MBTRI] = doEntities[MBQUAD] = true;
158 }
159 MoFEMErrorCode doWork(int side, EntityType type,
161 };
162
164
165 boost::shared_ptr<VolSideFe> sideOpFe;
166
167 OpGetScalarFieldGradientValuesOnSkin(boost::shared_ptr<VolSideFe> side_fe)
168 : BoundaryEleOp("PHOTON_FLUENCE_RATE", OPROW), sideOpFe(side_fe) {}
169
170 MoFEMErrorCode doWork(int side, EntityType type,
171 DataForcesAndSourcesCore::EntData &data) {
173 if (type != MBVERTEX)
175 CHKERR loopSideVolumes("dFE", *sideOpFe);
177 }
178 };
179
180 struct Monitor : public FEMethod {
181
182 Monitor(SmartPetscObj<DM> dm, boost::shared_ptr<PostProcEle> post_proc,
183 boost::shared_ptr<PostProcFaceEle> skin_post_proc,
184 boost::shared_ptr<BoundaryEle> skin_post_proc_integ,
185 boost::shared_ptr<CommonData> common_data_ptr,
186 MoFEM::Interface &m_field)
187 : dM(dm), postProc(post_proc), skinPostProc(skin_post_proc),
188 skinPostProcInteg(skin_post_proc_integ),
189 commonDataPtr(common_data_ptr), mField(m_field) {}
190
199
202
203 auto vector_update = [&](auto vec) {
205
206 CHKERR VecZeroEntries(vec);
207 CHKERR VecGhostUpdateBegin(vec, INSERT_VALUES, SCATTER_FORWARD);
208 CHKERR VecGhostUpdateEnd(vec, INSERT_VALUES, SCATTER_FORWARD);
210 CHKERR VecAssemblyBegin(vec);
211 CHKERR VecAssemblyEnd(vec);
212 CHKERR VecGhostUpdateBegin(vec, ADD_VALUES, SCATTER_REVERSE);
213 CHKERR VecGhostUpdateEnd(vec, ADD_VALUES, SCATTER_REVERSE);
214 CHKERR VecGhostUpdateBegin(vec, INSERT_VALUES, SCATTER_FORWARD);
215 CHKERR VecGhostUpdateEnd(vec, INSERT_VALUES, SCATTER_FORWARD);
217 };
218
219 if (!testing) {
220 vector_update(commonDataPtr->petscVec);
221 const double *array;
222 CHKERR VecGetArrayRead(commonDataPtr->petscVec, &array);
223 MOFEM_LOG("PHOTON", Sev::inform)
224 << "Fluence rate integral: " << array[0];
225 CHKERR VecRestoreArrayRead(commonDataPtr->petscVec, &array);
226 } else {
227 MOFEM_LOG("PHOTON", Sev::inform) << "Testing";
228 CHKERR VecZeroEntries(commonDataPtr->resVec);
229 vector_update(commonDataPtr->L2Vec);
230 CHKERR VecAssemblyBegin(commonDataPtr->resVec);
231 CHKERR VecAssemblyEnd(commonDataPtr->resVec);
232 double nrm2;
233 CHKERR VecNorm(commonDataPtr->resVec, NORM_2, &nrm2);
234 const double *array2;
235 CHKERR VecGetArrayRead(commonDataPtr->L2Vec, &array2);
236 MOFEM_LOG("PHOTON", Sev::inform)
237 << "Error " << array2[0] << " N of Entities " << nrm2;
238
239 constexpr double eps = 0.02;
240 if (array2[0] / nrm2 > eps)
241 SETERRQ(PETSC_COMM_SELF, MOFEM_DATA_INCONSISTENCY,
242 "Not converged solution");
243 CHKERR VecRestoreArrayRead(commonDataPtr->L2Vec, &array2);
244 }
245
246 if (ts_step % save_every_nth_step == 0) {
247 if (output_volume) {
249 CHKERR postProc->writeFile("out_volume_" +
250 boost::lexical_cast<std::string>(ts_step) +
251 ".h5m");
252 }
255 CHKERR skinPostProc->writeFile(
256 "out_camera_" + boost::lexical_cast<std::string>(ts_step) +
257 ".h5m");
258 }
259 }
261 }
262
263 private:
265 boost::shared_ptr<PostProcEle> postProc;
266 boost::shared_ptr<PostProcFaceEle> skinPostProc;
267 boost::shared_ptr<BoundaryEle> skinPostProcInteg;
268 boost::shared_ptr<CommonData> commonDataPtr;
270 };
271};
272
274 boost::shared_ptr<CommonData> commonDataPtr;
275
276 static inline double sourceFunction(const double x, const double y,
277 const double z, double time) {
280 mu_a, mu_sp, flux_magnitude, time, v, D);
281 };
282
283 OpError(boost::shared_ptr<CommonData> &common_data_ptr)
284 : BoundaryEleOp("PHOTON_FLUENCE_RATE", OPROW),
285 commonDataPtr(common_data_ptr) {}
286
287 MoFEMErrorCode doWork(int side, EntityType type, EntData &data) {
289 const int nb_integration_pts = getGaussPts().size2();
290 auto t_w = getFTensor0IntegrationWeight();
291 auto t_val = getFTensor0FromVec(*(commonDataPtr->uAtPtsPtr));
292 auto t_coords = getFTensor1CoordsAtGaussPts();
293
294 double nf = 1;
295
296 FTensor::Index<'i', 3> i;
297 const double volume = getMeasure();
298
299 double error = 0;
300 for (int gg = 0; gg != nb_integration_pts; ++gg) {
301
302 const double alpha = t_w * volume;
303 double analytical =
304 sourceFunction(t_coords(0), t_coords(1), slab_thickness / 2, 0.01);
305 double diff = t_val - analytical;
306
307 error += alpha * pow(diff, 2) / std::abs(t_val);
308
309 ++t_w;
310 ++t_val;
311 ++t_coords;
312 }
313
314 const int index = 0;
315
316 CHKERR VecSetValue(commonDataPtr->L2Vec, index, error / nb_integration_pts,
317 ADD_VALUES);
318 CHKERR VecSetValue(commonDataPtr->resVec, index, nf, ADD_VALUES);
319
321 }
322};
323
324#ifdef ENABLE_PYTHON_BINDING
325struct PhotonDiffusion::InterpPython {
326 InterpPython() = default;
327 virtual ~InterpPython() = default;
328
329 MoFEMErrorCode InterpInit(const std::string py_file);
330 MoFEMErrorCode evalInterp(const std::string sens_image,
331 np::ndarray gauss_coords_x,
332 np::ndarray gauss_coords_y, double cam_len_x,
333 double cam_len_y, np::ndarray &sens_vals);
334
335 template <typename T>
336 inline std::vector<T>
337 py_list_to_std_vector(const boost::python::object &iterable) {
338 return std::vector<T>(boost::python::stl_input_iterator<T>(iterable),
339 boost::python::stl_input_iterator<T>());
340 }
341
342private:
343 bp::object mainNamespace;
344 bp::object InterpFun;
345};
346
347static boost::weak_ptr<PhotonDiffusion::InterpPython> interpPythonWeakPtr;
348#endif
349
350#ifdef ENABLE_PYTHON_BINDING
352PhotonDiffusion::InterpPython::InterpInit(const std::string py_file) {
354
355 try {
356 bp::object main_module = bp::import("__main__");
357 mainNamespace = main_module.attr("__dict__");
358
359 bp::object ignored = bp::exec_file(py_file.c_str(), mainNamespace);
360
361 InterpFun = mainNamespace
362 ["py_Interpolate"]; // this is the function that will get called in the python script
363
364 } catch (bp::error_already_set const &) {
365 PyErr_Print();
367 }
368
370}
371
372MoFEMErrorCode PhotonDiffusion::InterpPython::evalInterp(
373 const std::string sens_image, np::ndarray gauss_coords_x,
374 np::ndarray gauss_coords_y, double cam_len_x, double cam_len_y,
375 np::ndarray &sens_vals) {
377 try {
378 sens_vals = bp::extract<np::ndarray>(InterpFun(
379 sens_image, gauss_coords_x, gauss_coords_y, cam_len_x, cam_len_y));
380
381 } catch (bp::error_already_set const &) {
382 // print all other errors to stderr
383 PyErr_Print();
385 }
386
388}
389
390inline np::ndarray convert_to_numpy(VectorDouble &data, int nb_gauss_pts,
391 int id) {
392 auto dtype = np::dtype::get_builtin<double>();
393 auto size = bp::make_tuple(nb_gauss_pts);
394 auto stride = bp::make_tuple(3 * sizeof(double));
395 return (np::from_data(&data[id], dtype, size, stride, bp::object()));
396}
397#endif
398
399inline VectorDouble interp_function(const std::string sens_image,
400 MatrixDouble &m_ref_coords,
401 int nb_gauss_pts, double cam_len_x,
402 double cam_len_y,
403 const std::string block_name) {
404#ifdef ENABLE_PYTHON_BINDING
405 if (auto interp_ptr = interpPythonWeakPtr.lock()) {
406 VectorDouble v_ref_coords = m_ref_coords.data();
407
408 bp::list python_coords;
409
410 for (int idx = 0; idx < 3; ++idx) {
411 python_coords.append(convert_to_numpy(v_ref_coords, nb_gauss_pts, idx));
412 }
413
414 np::ndarray np_interp = np::empty(bp::make_tuple(nb_gauss_pts, 3),
415 np::dtype::get_builtin<double>());
416
417 auto interp_block_name = "(.*)INTERPOLATION(.*)";
418 std::regex reg_interp_name(interp_block_name);
419 if (std::regex_match(block_name, reg_interp_name)) {
420 CHK_MOAB_THROW(interp_ptr->evalInterp(
421 sens_image, bp::extract<np::ndarray>(python_coords[0]),
422 bp::extract<np::ndarray>(python_coords[1]), cam_len_x,
423 cam_len_y, np_interp),
424 "Failed py_Interp() python call");
425 } else {
427 }
428
429 // check the shape of returned array
430 if (np_interp.get_shape()[0] != nb_gauss_pts ||
431 np_interp.get_shape()[1] != 1) {
433 "Wrong shape of analytical expression returned from "
434 "python, expected: (" +
435 std::to_string(nb_gauss_pts) + ", 1), got: (" +
436 std::to_string(np_interp.get_shape()[0]) + ", " +
437 std::to_string(np_interp.get_shape()[1]) + ")");
438 }
439 double *interp_val_ptr = reinterpret_cast<double *>(np_interp.get_data());
440
441 VectorDouble v_interp;
442 v_interp.resize(nb_gauss_pts, false);
443 for (size_t gg = 0; gg < nb_gauss_pts; ++gg) {
444 v_interp(gg) = *(interp_val_ptr + gg);
445 }
446 return v_interp;
447 } else {
449 "InterpPython pointer is expired");
450 }
451#endif
452}
453
454PhotonDiffusion::PhotonDiffusion(MoFEM::Interface &m_field) : mField(m_field) {}
455
458
459 auto *simple = mField.getInterface<Simple>();
461 CHKERR simple->getOptions();
462 CHKERR simple->loadFile();
463
465}
466
469 commonDataPtr = boost::make_shared<CommonData>();
470
471 auto *simple = mField.getInterface<Simple>();
472 commonDataPtr->resVec = createDMVector(simple->getDM());
473 commonDataPtr->uAtPtsPtr = boost::make_shared<VectorDouble>();
474
475 PetscInt ghosts[1] = {0};
476 if (!mField.get_comm_rank()) {
477 commonDataPtr->petscVec =
478 createGhostVector(mField.get_comm(), 1, 1, 0, ghosts);
479 commonDataPtr->L2Vec =
480 createGhostVector(mField.get_comm(), 1, 1, 0, ghosts);
481 } else {
482 commonDataPtr->petscVec =
483 createGhostVector(mField.get_comm(), 0, 1, 1, ghosts);
484 commonDataPtr->L2Vec =
485 createGhostVector(mField.get_comm(), 0, 1, 1, ghosts);
486 }
487 commonDataPtr->approxVals = boost::make_shared<VectorDouble>();
488
490}
491
494
495 auto *simple = mField.getInterface<Simple>();
496 CHKERR simple->addDomainField("PHOTON_FLUENCE_RATE", H1,
498 CHKERR simple->addBoundaryField("PHOTON_FLUENCE_RATE", H1,
500
501 CHKERR PetscOptionsGetString(PETSC_NULLPTR, "", "-initial_file",
502 init_data_file_name, 255, PETSC_NULLPTR);
503
504 CHKERR PetscOptionsGetBool(PETSC_NULLPTR, "", "-from_initial", &from_initial,
505 PETSC_NULLPTR);
506 CHKERR PetscOptionsGetBool(PETSC_NULLPTR, "", "-output_volume",
507 &output_volume, PETSC_NULLPTR);
508 CHKERR PetscOptionsGetBool(PETSC_NULLPTR, "", "-output_camera",
509 &output_camera, PETSC_NULLPTR);
510 CHKERR PetscOptionsGetScalar(PETSC_NULLPTR, "", "-mu_a", &mu_a,
511 PETSC_NULLPTR);
512 CHKERR PetscOptionsGetScalar(PETSC_NULLPTR, "", "-mu_sp", &mu_sp,
513 PETSC_NULLPTR);
514 CHKERR PetscOptionsGetScalar(PETSC_NULLPTR, "", "-coef_A", &A, PETSC_NULLPTR);
515
516 CHKERR PetscOptionsGetScalar(PETSC_NULLPTR, "", "-slab_thickness",
517 &slab_thickness, PETSC_NULLPTR);
518 CHKERR PetscOptionsGetScalar(PETSC_NULLPTR, "", "-beam_radius", &beam_radius,
519 PETSC_NULLPTR);
520 CHKERR PetscOptionsGetScalar(PETSC_NULLPTR, "", "-beam_centre_x",
521 &beam_centre_x, PETSC_NULLPTR);
522 CHKERR PetscOptionsGetScalar(PETSC_NULLPTR, "", "-beam_centre_y",
523 &beam_centre_y, PETSC_NULLPTR);
524 CHKERR PetscOptionsGetBool(PETSC_NULLPTR, "", "-testing", &testing,
525 PETSC_NULLPTR);
526 CHKERR PetscOptionsGetScalar(PETSC_NULLPTR, "", "-cam_len_x", &cam_len_x,
527 PETSC_NULLPTR);
528 CHKERR PetscOptionsGetScalar(PETSC_NULLPTR, "", "-cam_len_y", &cam_len_y,
529 PETSC_NULLPTR);
530
531 CHKERR PetscOptionsGetInt(PETSC_NULLPTR, "", "-order", &order, PETSC_NULLPTR);
532 CHKERR PetscOptionsGetInt(PETSC_NULLPTR, "", "-save_step",
533 &save_every_nth_step, PETSC_NULLPTR);
534
535#ifdef ENABLE_PYTHON_BINDING
536 if (enable_python) {
537 auto file_exists = [](std::string myfile) {
538 std::ifstream file(myfile.c_str());
539 if (file) {
540 return true;
541 }
542 return false;
543 };
544 CHKERR PetscOptionsGetString(PETSC_NULLPTR, "", "-interp_file",
545 interp_file_name, 255, PETSC_NULLPTR);
546 CHKERR PetscOptionsGetString(PETSC_NULLPTR, "", "-sens_image",
547 interp_image_name, 255, PETSC_NULLPTR);
548 #ifdef ENABLE_PYTHON_BINDING
549 if (file_exists(interp_file_name)) {
550 MOFEM_LOG("PHOTON", Sev::inform) << interp_file_name << " file found";
551 interpPythonPtr = boost::make_shared<PhotonDiffusion::InterpPython>();
552 CHKERR interpPythonPtr->InterpInit(interp_file_name);
553 interpPythonWeakPtr = interpPythonPtr;
554 } else {
555 MOFEM_LOG("PHOTON", Sev::warning)
556 << interp_file_name << " file NOT found";
557 }
558 }
559 #endif
560#endif
561
562 h = 0.5 / A;
563 D = 1. / (3. * (mu_a + mu_sp));
564
565 MOFEM_LOG("PHOTON", Sev::inform) << "Refractive index: " << n;
566 MOFEM_LOG("PHOTON", Sev::inform) << "Speed of light (cm/ns): " << c;
567 MOFEM_LOG("PHOTON", Sev::inform) << "Phase velocity in medium (cm/ns): " << v;
568 MOFEM_LOG("PHOTON", Sev::inform) << "Inverse velocity : " << inv_v;
569 MOFEM_LOG("PHOTON", Sev::inform)
570 << "Absorption coefficient (cm^-1): " << mu_a;
571 MOFEM_LOG("PHOTON", Sev::inform)
572 << "Scattering coefficient (cm^-1): " << mu_sp;
573 MOFEM_LOG("PHOTON", Sev::inform) << "Diffusion coefficient D : " << D;
574 MOFEM_LOG("PHOTON", Sev::inform) << "Coefficient A : " << A;
575 MOFEM_LOG("PHOTON", Sev::inform) << "Coefficient h : " << h;
576
577 MOFEM_LOG("PHOTON", Sev::inform) << "Approximation order: " << order;
578 MOFEM_LOG("PHOTON", Sev::inform) << "Save step: " << save_every_nth_step;
579
580 CHKERR simple->setFieldOrder("PHOTON_FLUENCE_RATE", order);
581
582 auto set_camera_skin_fe = [&]() {
584
585 Range camera_surface;
586 const std::string block_name = "CAM";
587 bool add_fe = false;
588
590 if (bit->getName().compare(0, block_name.size(), block_name) == 0) {
591 MOFEM_LOG("PHOTON", Sev::inform) << "Found CAM block";
592 CHKERR mField.get_moab().get_entities_by_dimension(
593 bit->getMeshset(), 2, camera_surface, true);
594 add_fe = true;
595 }
596 }
597
598 MOFEM_LOG("PHOTON", Sev::noisy) << "CAM block entities:\n"
599 << camera_surface;
600
601 if (add_fe) {
602 CHKERR mField.add_finite_element("CAMERA_FE");
604 "PHOTON_FLUENCE_RATE");
606 "CAMERA_FE");
607 }
609 };
610
611 auto my_simple_set_up = [&]() {
613 CHKERR simple->defineFiniteElements();
614 CHKERR simple->defineProblem(PETSC_TRUE);
615 CHKERR simple->buildFields();
616 CHKERR simple->buildFiniteElements();
617
618 if (mField.check_finite_element("CAMERA_FE")) {
620 CHKERR DMMoFEMAddElement(simple->getDM(), "CAMERA_FE");
621 }
622
623 CHKERR simple->buildProblem();
625 };
626
627 CHKERR set_camera_skin_fe();
628 CHKERR my_simple_set_up();
629
631}
632
635
637}
638
641 auto bc_mng = mField.getInterface<BcManager>();
642 auto *simple = mField.getInterface<Simple>();
643 CHKERR bc_mng->pushMarkDOFsOnEntities(simple->getProblemName(), "EXT",
644 "PHOTON_FLUENCE_RATE", 0, 0, false);
645
646 // Get boundary faces marked in block named "INT"
647 Range boundary_faces;
649 std::string entity_name = it->getName();
650 if (entity_name.compare(0, 3, "INT") == 0) {
651 CHKERR it->getMeshsetIdEntitiesByDimension(mField.get_moab(), 2,
652 boundary_faces, true);
653 }
654 }
655
656 // If the previous search has not returned anything, assume the boundary has been created as a sideset.
657 if (boundary_faces.empty()) {
659 std::string entity_name = it->getName();
660 CHKERR it->getMeshsetIdEntitiesByDimension(mField.get_moab(), 2,
661 boundary_faces, true);
662 }
663 }
664
665 // Get boundary edges in "INT"
666 Range boundary_ents;
667 CHKERR mField.get_moab().get_adjacencies(
668 boundary_faces, 1, false, boundary_ents, moab::Interface::UNION);
669 // Add vertices to boundary entities
670 Range boundary_verts;
671 CHKERR mField.get_moab().get_adjacencies(
672 boundary_faces, 0, false, boundary_verts, moab::Interface::UNION);
673
674 boundary_faces.merge(boundary_verts);
675 boundary_faces.merge(boundary_ents);
676
677 CHKERR mField.getInterface<CommInterface>()->synchroniseEntities(
678 boundary_faces);
679
680 // Remove DOFs as homogeneous boundary condition is used
681 CHKERR mField.getInterface<ProblemsManager>()->removeDofsOnEntities(
682 simple->getProblemName(), "PHOTON_FLUENCE_RATE", boundary_faces);
683
685}
686
687//! [assembleSystem]
691
692 auto integration_rule = [](int o_row, int o_col, int approx_order) {
693 return 2 * approx_order;
694 };
695
696 auto bc_mng = mField.getInterface<BcManager>();
697 auto &bc_map = bc_mng->getBcMapByBlockName();
698
699 auto set_domain = [&]() {
702 pipeline_mng->getOpDomainLhsPipeline(), {H1});
703
704 pipeline_mng->getOpDomainLhsPipeline().push_back(new OpDomainGradGrad(
705 "PHOTON_FLUENCE_RATE", "PHOTON_FLUENCE_RATE",
706 [](double, double, double) -> double { return D; }));
707
708 auto get_mass_coefficient = [&](const double, const double, const double) {
709 return inv_v * domainLhsFEPtr->ts_a + mu_a;
710 };
711 pipeline_mng->getOpDomainLhsPipeline().push_back(new OpDomainMass(
712 "PHOTON_FLUENCE_RATE", "PHOTON_FLUENCE_RATE", get_mass_coefficient));
713
714 auto grad_u_at_gauss_pts = boost::make_shared<MatrixDouble>();
715 auto u_at_gauss_pts = boost::make_shared<VectorDouble>();
716 auto dot_u_at_gauss_pts = boost::make_shared<VectorDouble>();
717 pipeline_mng->getOpDomainRhsPipeline().push_back(
718 new OpCalculateScalarFieldGradient<SPACE_DIM>("PHOTON_FLUENCE_RATE",
719 grad_u_at_gauss_pts));
720 pipeline_mng->getOpDomainRhsPipeline().push_back(
721 new OpCalculateScalarFieldValues("PHOTON_FLUENCE_RATE",
722 u_at_gauss_pts));
723 pipeline_mng->getOpDomainRhsPipeline().push_back(
724 new OpCalculateScalarFieldValuesDot("PHOTON_FLUENCE_RATE",
725 dot_u_at_gauss_pts));
726 pipeline_mng->getOpDomainRhsPipeline().push_back(new OpDomainGradTimesVec(
727 "PHOTON_FLUENCE_RATE", grad_u_at_gauss_pts,
728 [](double, double, double) -> double { return D; }));
729 pipeline_mng->getOpDomainRhsPipeline().push_back(
731 "PHOTON_FLUENCE_RATE", dot_u_at_gauss_pts,
732 [](const double, const double, const double) { return inv_v; }));
733 pipeline_mng->getOpDomainRhsPipeline().push_back(
735 "PHOTON_FLUENCE_RATE", u_at_gauss_pts,
736 [](const double, const double, const double) { return mu_a; }));
737
741 };
742
743 auto set_boundary = [&]() {
745
746 pipeline_mng->getOpBoundaryLhsPipeline().push_back(
748 pipeline_mng->getOpBoundaryRhsPipeline().push_back(
750
751 auto u_at_gauss_pts = boost::make_shared<VectorDouble>();
752 pipeline_mng->getOpBoundaryRhsPipeline().push_back(
753 new OpCalculateScalarFieldValues("PHOTON_FLUENCE_RATE",
754 u_at_gauss_pts));
755 for (auto b : bc_map) {
756 if (std::regex_match(b.first, std::regex("(.*)EXT(.*)"))) {
757 pipeline_mng->getOpBoundaryLhsPipeline().push_back(new OpBoundaryMass(
758 "PHOTON_FLUENCE_RATE", "PHOTON_FLUENCE_RATE",
759
760 [](const double, const double, const double) { return h; },
761
762 b.second->getBcEntsPtr()));
763
764 pipeline_mng->getOpBoundaryRhsPipeline().push_back(
766 "PHOTON_FLUENCE_RATE", u_at_gauss_pts,
767
768 [](const double, const double, const double) { return h; },
769
770 b.second->getBcEntsPtr()));
771 }
772 }
773
777 };
778
779 CHKERR set_domain();
780 CHKERR set_boundary();
781
782 domainLhsFEPtr = pipeline_mng->getDomainLhsFE();
783 boundaryLhsFEPtr = pipeline_mng->getBoundaryLhsFE();
784 boundaryRhsFEPtr = pipeline_mng->getBoundaryRhsFE();
785
787}
788//! [assembleSystem]
789
792
793 auto *simple = mField.getInterface<Simple>();
794 auto *pipeline_mng = mField.getInterface<PipelineManager>();
795
796 //! [postprocess]
797 auto create_post_process_element = [&]() {
798 auto post_froc_fe = boost::make_shared<PostProcEle>(mField);
799 auto u_ptr = boost::make_shared<VectorDouble>();
800 auto grad_ptr = boost::make_shared<MatrixDouble>();
801 post_froc_fe->getOpPtrVector().push_back(
802 new OpCalculateScalarFieldValues("PHOTON_FLUENCE_RATE", u_ptr));
803 post_froc_fe->getOpPtrVector().push_back(
804 new OpCalculateScalarFieldGradient<SPACE_DIM>("PHOTON_FLUENCE_RATE",
805 grad_ptr));
806 post_froc_fe->getOpPtrVector().push_back(new OpPPMap(
807 post_froc_fe->getPostProcMesh(), post_froc_fe->getMapGaussPts(),
808 {{"PHOTON_FLUENCE_RATE", u_ptr}},
809 {{"GRAD_PHOTON_FLUENCE_RATE", grad_ptr}}, {}, {}));
810 return post_froc_fe;
811 };
812
813 auto create_post_process_camera_element = [&]() {
814 if (mField.check_finite_element("CAMERA_FE")) {
815 auto post_proc_skin = boost::make_shared<PostProcFaceEle>(mField);
816
817 auto u_ptr = boost::make_shared<VectorDouble>();
818 auto grad_ptr = boost::make_shared<MatrixDouble>();
819
821 mField, simple->getDomainFEName(), SPACE_DIM);
822
823 // push operators to side element
825 op_loop_side->getOpPtrVector(), {H1});
826 op_loop_side->getOpPtrVector().push_back(
827 new OpCalculateScalarFieldValues("PHOTON_FLUENCE_RATE", u_ptr));
828 op_loop_side->getOpPtrVector().push_back(
829 new OpCalculateScalarFieldGradient<SPACE_DIM>("PHOTON_FLUENCE_RATE",
830 grad_ptr));
831 // push op to boundary element
832 post_proc_skin->getOpPtrVector().push_back(op_loop_side);
833
834 post_proc_skin->getOpPtrVector().push_back(new OpPPMap(
835 post_proc_skin->getPostProcMesh(), post_proc_skin->getMapGaussPts(),
836 {{"PHOTON_FLUENCE_RATE", u_ptr}},
837 {{"GRAD_PHOTON_FLUENCE_RATE", grad_ptr}}, {}, {}));
838
839 return post_proc_skin;
840 } else {
841 return boost::shared_ptr<PostProcFaceEle>();
842 }
843 };
844
845 auto create_post_process_integ_camera_element = [&]() {
846 if (mField.check_finite_element("CAMERA_FE")) {
847 auto post_proc_integ_skin = boost::make_shared<BoundaryEle>(mField);
848
849 if (!testing) {
850 MOFEM_LOG("PHOTON", Sev::inform)
851 << "Creating post process integ camera element";
852 post_proc_integ_skin->getOpPtrVector().push_back(
854 post_proc_integ_skin->getOpPtrVector().push_back(
855 new OpCalculateScalarFieldValues("PHOTON_FLUENCE_RATE",
856 commonDataPtr->approxVals));
857 post_proc_integ_skin->getOpPtrVector().push_back(
858 new OpCameraInteg(commonDataPtr));
859 } else {
860 MOFEM_LOG("PHOTON", Sev::inform)
861 << "Creating testing camera error element";
862 post_proc_integ_skin->getOpPtrVector().push_back(
864 post_proc_integ_skin->getRuleHook = [](int, int, int approx_order) {
865 return 2 * approx_order;
866 };
868 post_proc_integ_skin->getOpPtrVector(), {NOSPACE});
869 post_proc_integ_skin->getOpPtrVector().push_back(
870 new OpCalculateScalarFieldValues("PHOTON_FLUENCE_RATE",
871 commonDataPtr->uAtPtsPtr));
872 post_proc_integ_skin->getOpPtrVector().push_back(
873 new OpError(commonDataPtr));
874 }
875 return post_proc_integ_skin;
876 } else {
877 return boost::shared_ptr<BoundaryEle>();
878 }
879 };
880 //! [postprocess]
881
882 //! [timesolver]
883 auto set_time_monitor = [&](auto dm, auto solver) {
885 boost::shared_ptr<Monitor> monitor_ptr(new Monitor(
886 dm, create_post_process_element(), create_post_process_camera_element(),
887 create_post_process_integ_camera_element(), commonDataPtr, mField));
888 boost::shared_ptr<ForcesAndSourcesCore> null;
889 CHKERR DMMoFEMTSSetMonitor(dm, solver, simple->getDomainFEName(),
890 monitor_ptr, null, null);
892 };
893
894 auto dm = simple->getDM();
895 auto X = createDMVector(dm);
896
897 if (from_initial) {
898
899 MOFEM_LOG("PHOTON", Sev::inform) << "reading vector in binary from file "
900 << init_data_file_name << " ...";
901 PetscViewer viewer;
902 PetscViewerBinaryOpen(PETSC_COMM_WORLD, init_data_file_name, FILE_MODE_READ,
903 &viewer);
904 VecLoad(X, viewer);
905
906 CHKERR DMoFEMMeshToLocalVector(dm, X, INSERT_VALUES, SCATTER_REVERSE);
907 }
908
909 auto solver = pipeline_mng->createTSIM();
910
911 CHKERR TSSetSolution(solver, X);
912 CHKERR set_time_monitor(dm, solver);
913 CHKERR TSSetSolution(solver, X);
914 CHKERR TSSetFromOptions(solver);
915 auto B = createDMMatrix(dm);
916 CHKERR TSSetIJacobian(solver, B, B, PETSC_NULLPTR, PETSC_NULLPTR);
917 CHKERR TSSetUp(solver);
918 CHKERR TSSolve(solver, NULL);
919
920 CHKERR VecGhostUpdateBegin(X, INSERT_VALUES, SCATTER_FORWARD);
921 CHKERR VecGhostUpdateEnd(X, INSERT_VALUES, SCATTER_FORWARD);
922 CHKERR DMoFEMMeshToLocalVector(dm, X, INSERT_VALUES, SCATTER_REVERSE);
923
925}
926//! [timesolver]
927//! [solveSystem]
928
931
932 // Processes to set output results are integrated in solveSystem()
933
935}
936
939
948
950}
951
952//! [Integral_calc]
957 const int nb_integration_pts = getGaussPts().size2();
958 const double area = getMeasure();
959 auto t_w = getFTensor0IntegrationWeight();
960 auto t_val = getFTensor0FromVec(*(commonDataPtr->approxVals));
961
962 double values_integ = 0;
963
964#ifdef ENABLE_PYTHON_BINDING
965 VectorDouble sens_vals_vec;
966 if (enable_python) {
967 MatrixDouble ref_coords = getCoordsAtGaussPts();
968 sens_vals_vec =
969 interp_function(interp_image_name, ref_coords, nb_integration_pts,
970 cam_len_x, cam_len_y, "(.*)INTERPOLATION(.*)");
971 }
972#endif
973
974 for (int gg = 0; gg != nb_integration_pts; ++gg) {
975
976 double sens = 1;
977#ifdef ENABLE_PYTHON_BINDING
978 if (enable_python) {
979 sens = sens_vals_vec(gg);
980 }
981#endif
982
983 const double alpha = t_w * area * sens;
984
985 values_integ += alpha * t_val;
986
987 ++t_w;
988 ++t_val;
989 }
990
991 constexpr std::array<int, 1> indices = {CommonData::VALUES_INTEG};
992 std::array<double, 1> values;
993 values[0] = values_integ;
994 CHKERR VecSetValues(commonDataPtr->petscVec, 1, indices.data(), values.data(),
995 ADD_VALUES);
997}
998//! [Integral_calc]
999
1000int main(int argc, char *argv[]) {
1001 // Initialisation of MoFEM/PETSc and MOAB data structures
1002 const char param_file[] = "param_file.petsc";
1003 MoFEM::Core::Initialize(&argc, &argv, param_file, help);
1004
1005 // Add logging channel for example
1006 auto core_log = logging::core::get();
1007 core_log->add_sink(
1009 LogManager::setLog("PHOTON");
1010 MOFEM_LOG_TAG("PHOTON", "photon_diffusion")
1011
1012#ifdef ENABLE_PYTHON_BINDING
1013 CHKERR PetscOptionsGetBool(PETSC_NULLPTR, "", "-enable_python",
1014 &enable_python, //this is a flag in case
1015 PETSC_NULLPTR); //the user wishes to not use python
1016 if (enable_python) {
1017 Py_Initialize();
1018 np::initialize();
1019 MOFEM_LOG("PHOTON", Sev::inform) << "Python initialised";
1020 } else {
1021 MOFEM_LOG("PHOTON", Sev::inform) << "Python NOT initialised";
1022 }
1023#endif
1024
1025 // Error handling
1026 try {
1027 // Register MoFEM discrete manager in PETSc
1028 DMType dm_name = "DMMOFEM";
1029 CHKERR DMRegister_MoFEM(dm_name);
1030
1031 // Create MOAB instance
1032 moab::Core mb_instance; // mesh database
1033 moab::Interface &moab = mb_instance; // mesh database interface
1034
1035 // Create MoFEM instance
1036 MoFEM::Core core(moab); // finite element database
1037 MoFEM::Interface &m_field = core; // finite element interface
1038
1039 // Run the main analysis
1040 PhotonDiffusion heat_problem(m_field);
1041 CHKERR heat_problem.runProgram();
1042 }
1044
1045 // Finish work: cleaning memory, getting statistics, etc.
1046
1047#ifdef ENABLE_PYTHON_BINDING
1048 if (enable_python) {
1049 MOFEM_LOG("PHOTON", Sev::inform) << "Finalizing Python";
1050 if (Py_FinalizeEx() < 0) {
1051 exit(120);
1052 }
1053 }
1054#endif
1055
1057
1058 return 0;
1059}
std::string type
void simple(double P1[], double P2[], double P3[], double c[], const int N)
Definition acoustic.cpp:69
int main()
static const double eps
FormsIntegrators< DomainEleOp >::Assembly< PETSC >::LinearForm< GAUSS >::OpSource< 1, FIELD_DIM > OpDomainSource
ElementsAndOps< SPACE_DIM >::DomainEle DomainEle
FormsIntegrators< DomainEleOp >::Assembly< PETSC >::BiLinearForm< GAUSS >::OpMass< 1, FIELD_DIM > OpDomainMass
ElementsAndOps< SPACE_DIM >::BoundaryEle BoundaryEle
#define CATCH_ERRORS
Catch errors.
@ AINSWORTH_LEGENDRE_BASE
Ainsworth Cole (Legendre) approx. base .
Definition definitions.h:60
#define CHK_THROW_MESSAGE(err, msg)
Check and throw MoFEM exception.
#define MoFEMFunctionReturnHot(a)
Last executable line of each PETSc function used for error handling. Replaces return()
@ H1
continuous field
Definition definitions.h:85
#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.
@ SIDESET
@ BLOCKSET
@ MOFEM_OPERATION_UNSUCCESSFUL
Definition definitions.h:34
@ 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.
auto integration_rule
PetscErrorCode DMMoFEMAddElement(DM dm, std::string fe_name)
add element to dm
Definition DMMoFEM.cpp:488
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 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
auto createDMVector(DM dm, RowColData rc=RowColData::COL)
Get smart vector from DM.
Definition DMMoFEM.hpp:1237
auto createDMMatrix(DM dm)
Get smart matrix from DM.
Definition DMMoFEM.hpp:1194
boost::ptr_deque< UserDataOperator > & getOpDomainLhsPipeline()
Get the Op Domain Lhs Pipeline object.
boost::ptr_deque< UserDataOperator > & getOpBoundaryLhsPipeline()
Get the Op Boundary Lhs Pipeline object.
boost::ptr_deque< UserDataOperator > & getOpBoundaryRhsPipeline()
Get the Op Boundary Rhs Pipeline object.
boost::ptr_deque< UserDataOperator > & getOpDomainRhsPipeline()
Get the Op Domain Rhs Pipeline object.
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_data(const std::string &fe_name, const std::string name_field)=0
set finite element field data
@ PETSC
Standard PETSc assembly.
static LoggerType & setLog(const std::string channel)
Set ans resset chanel logger.
#define MOFEM_LOG(channel, severity)
Log.
#define MOFEM_LOG_TAG(channel, tag)
Tag channel.
#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.
BcMapByBlockName & getBcMapByBlockName()
Get the boundary condition map.
auto bit
set bit
FTensor::Index< 'i', SPACE_DIM > i
FormsIntegrators< DomainEleOp >::Assembly< PETSC >::BiLinearForm< GAUSS >::OpGradGrad< 1, 1, SPACE_DIM > OpDomainGradGrad
Definition helmholtz.cpp:25
FormsIntegrators< EdgeEleOp >::Assembly< PETSC >::LinearForm< GAUSS >::OpSource< 1, 1 > OpBoundarySource
Definition helmholtz.cpp:31
FormsIntegrators< DomainEleOp >::Assembly< PETSC >::LinearForm< GAUSS >::OpGradTimesTensor< 1, 1, SPACE_DIM > OpDomainGradTimesVec
PetscErrorCode MoFEMErrorCode
MoFEM/PETSc error code.
UBlasVector< double > VectorDouble
Definition Types.hpp:68
implementation of Data Operators for Forces and Sources
Definition Common.hpp:10
PetscErrorCode DMMoFEMTSSetMonitor(DM dm, TS ts, 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 Monitor To TS solver.
Definition DMMoFEM.cpp:1046
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 PetscOptionsGetScalar(PetscOptions *, const char pre[], const char name[], PetscScalar *dval, PetscBool *set)
OpCalculateScalarFieldValuesFromPetscVecImpl< PetscData::CTX_SET_X_T > OpCalculateScalarFieldValuesDot
auto createGhostVector(MPI_Comm comm, PetscInt n, PetscInt N, PetscInt nghost, const PetscInt ghosts[])
Create smart ghost vector.
PetscErrorCode PetscOptionsGetString(PetscOptions *, const char pre[], const char name[], char str[], size_t size, PetscBool *set)
static auto getFTensor0FromVec(V &data)
Get tensor rank 0 (scalar) form data vector.
MoFEMErrorCode VecSetValues(Vec V, const EntitiesFieldData::EntData &data, const double *ptr, InsertMode iora)
Assemble PETSc vector.
double sourceFunctionEval(const double x, const double y, const double z, const double beam_radius, const double beam_centre_x, const double beam_centre_y, const double slab_thickness, const double mu_a, const double mu_sp, const double flux_magnitude, double initial_time, const double v, const double D)
Pulse is infinitely short.
FormsIntegrators< BoundaryEleOp >::Assembly< PETSC >::LinearForm< GAUSS >::OpBaseTimesScalar< 1 > OpBoundaryTimeScalarField
double mu_sp
scattering coefficient (cm^-1)
FormsIntegrators< DomainEleOp >::Assembly< PETSC >::BiLinearForm< GAUSS >::OpMass< 1, 1 > OpDomainMass
PetscBool enable_python
double A
static char help[]
double flux_magnitude
impulse magnitude
const int kronrod_points
This has been tested and gives the same result for any number of points. Increasing the number of poi...
FormsIntegrators< DomainEleOp >::Assembly< PETSC >::LinearForm< GAUSS >::OpBaseTimesScalar< 1 > OpDomainTimesScalarField
double beam_centre_y
int numHoLevels
constexpr int SPACE_DIM
[Define dimension]
const double inv_v
PetscBool output_camera
PetscBool testing
double beam_centre_x
double h
const double c
speed of light (cm/ns)
double slab_thickness
double beam_radius
char init_data_file_name[255]
FormsIntegrators< DomainEleOp >::Assembly< PETSC >::LinearForm< GAUSS >::OpGradTimesTensor< 1, 1, SPACE_DIM > OpDomainGradTimesVec
FormsIntegrators< DomainEleOp >::Assembly< PETSC >::BiLinearForm< GAUSS >::OpGradGrad< 1, 1, SPACE_DIM > OpDomainGradGrad
int save_every_nth_step
FormsIntegrators< BoundaryEleOp >::Assembly< PETSC >::BiLinearForm< GAUSS >::OpMass< 1, 1 > OpBoundaryMass
int order
PetscBool from_initial
char interp_file_name[255]
double D
OpPostProcMapInMoab< SPACE_DIM, SPACE_DIM > OpPPMap
double cam_len_x
VectorDouble interp_function(const std::string sens_image, MatrixDouble &m_ref_coords, int nb_gauss_pts, double cam_len_x, double cam_len_y, const std::string block_name)
PetscBool output_volume
double mu_a
absorption coefficient (cm^-1)
const double v
phase velocity of light in medium (cm/ns)
char interp_image_name[255]
const double n
refractive index of diffusive medium
double cam_len_y
static constexpr int approx_order
FormsIntegrators< DomainEleOp >::Assembly< PETSC >::LinearForm< GAUSS >::OpBaseTimesScalar< 1 > OpDomainTimesScalarField
Definition seepage.cpp:141
FormsIntegrators< BoundaryEleOp >::Assembly< PETSC >::BiLinearForm< GAUSS >::OpMass< 1, SPACE_DIM > OpBoundaryMass
[Only used with Hencky/nonlinear material]
Definition seepage.cpp:70
[Operators_definition]
Add operators pushing bases from local to physical configuration.
Boundary condition manager for finite element problem setup.
Managing BitRefLevels.
virtual moab::Interface & get_moab()=0
virtual bool check_finite_element(const std::string &name) const =0
Check if finite element is in database.
virtual MPI_Comm & get_comm() const =0
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.
Data on single entity (This is passed as argument to DataOperator::doWork)
Structure for user loop methods on finite elements.
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 > getStrmWorld()
Get the strm world object.
Get field gradients at integration pts for scalar field rank 0, i.e. vector field.
Specialization for double precision scalar field values calculation.
Element used to execute operators on side of the element.
Post post-proc data at points from hash maps.
Modify integration weights on face to take into account higher-order geometry.
PipelineManager interface.
boost::shared_ptr< FEMethod > & getDomainLhsFE()
Get domain left-hand side finite element.
boost::shared_ptr< FEMethod > & getBoundaryLhsFE()
Get boundary left-hand side finite element.
MoFEMErrorCode setDomainRhsIntegrationRule(RuleHookFun rule)
Set integration rule for domain right-hand side finite element.
MoFEMErrorCode setBoundaryLhsIntegrationRule(RuleHookFun rule)
Set integration rule for boundary left-hand side finite element.
MoFEMErrorCode setBoundaryRhsIntegrationRule(RuleHookFun rule)
Set integration rule for boundary right-hand side finite element.
boost::shared_ptr< FEMethod > & getBoundaryRhsFE()
Get boundary right-hand side finite element.
MoFEMErrorCode setDomainLhsIntegrationRule(RuleHookFun rule)
Set integration rule for domain left-hand side finite element.
Problem manager is used to build and partition problems.
Simple interface for fast problem set-up.
Definition Simple.hpp:27
MoFEMErrorCode addDomainField(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_ZERO, int verb=-1)
Add field on domain.
Definition Simple.cpp:261
intrusive_ptr for managing petsc objects
PetscInt ts_step
Current time step number.
MoFEMErrorCode getInterface(IFACE *&iface) const
Get interface reference to pointer of interface.
[Push operators to pipeline]
boost::shared_ptr< VectorDouble > uAtPtsPtr
boost::shared_ptr< VectorDouble > approxVals
MoFEMErrorCode postProcess()
Post-processing function executed at loop completion.
boost::shared_ptr< PostProcFaceEle > skinPostProc
boost::shared_ptr< CommonData > commonDataPtr
MoFEMErrorCode preProcess()
Pre-processing function executed at loop initialization.
MoFEMErrorCode operator()()
Main operator function executed for each loop iteration.
boost::shared_ptr< BoundaryEle > skinPostProcInteg
Monitor(SmartPetscObj< DM > dm, boost::shared_ptr< PostProcEle > post_proc, boost::shared_ptr< PostProcFaceEle > skin_post_proc, boost::shared_ptr< BoundaryEle > skin_post_proc_integ, boost::shared_ptr< CommonData > common_data_ptr, MoFEM::Interface &m_field)
boost::shared_ptr< PostProcEle > postProc
MoFEMErrorCode doWork(int side, EntityType type, EntitiesFieldData::EntData &data)
[Integral_calc]
boost::shared_ptr< CommonData > commonDataPtr
OpCameraInteg(boost::shared_ptr< CommonData > common_data_ptr)
OpError(boost::shared_ptr< CommonData > &common_data_ptr)
static double sourceFunction(const double x, const double y, const double z, double time)
boost::shared_ptr< CommonData > commonDataPtr
MoFEMErrorCode doWork(int side, EntityType type, EntData &data)
MoFEMErrorCode doWork(int side, EntityType type, DataForcesAndSourcesCore::EntData &data)
OpGetScalarFieldGradientValuesOnSkin(boost::shared_ptr< VolSideFe > side_fe)
MoFEMErrorCode assembleSystem()
boost::shared_ptr< FEMethod > boundaryRhsFEPtr
MoFEMErrorCode solveSystem()
MoFEM::Interface & mField
MoFEMErrorCode readMesh()
MoFEMErrorCode outputResults()
MoFEMErrorCode initialCondition()
PhotonDiffusion(MoFEM::Interface &m_field)
boost::shared_ptr< FEMethod > domainLhsFEPtr
MoFEMErrorCode checkResults()
MoFEMErrorCode runProgram()
MoFEMErrorCode createCommonData()
boost::shared_ptr< FEMethod > boundaryLhsFEPtr
MoFEMErrorCode boundaryCondition()
MoFEMErrorCode setIntegrationRules()
MoFEMErrorCode setupProblem()
boost::shared_ptr< CommonData > commonDataPtr
boost::shared_ptr< std::vector< unsigned char > > boundaryMarker