11 using namespace MoFEM;
13 static char help[] =
"...\n\n";
38 PETSC>::LinearForm<GAUSS>::OpBaseTimesScalar<1>;
42 PETSC>::LinearForm<GAUSS>::OpSource<1, 1>;
47 PETSC>::LinearForm<GAUSS>::OpBaseTimesScalar<1>;
49 PETSC>::LinearForm<GAUSS>::OpSource<1, 1>;
51 const double n = 1.44;
53 const double v =
c /
n;
118 commonDataPtr(common_data_ptr) {
119 std::fill(&doEntities[MBVERTEX], &doEntities[MBMAXTYPE],
false);
120 doEntities[MBTRI] = doEntities[MBQUAD] =
true;
130 :
BoundaryEleOp(
"PHOTON_FLUENCE_RATE", OPROW), sideOpFe(side_fe) {}
135 if (
type != MBVERTEX)
137 CHKERR loopSideVolumes(
"dFE", *sideOpFe);
145 boost::shared_ptr<PostProcFaceEle> skin_post_proc,
146 boost::shared_ptr<BoundaryEle> skin_post_proc_integ,
147 boost::shared_ptr<CommonData> common_data_ptr)
148 : dM(dm), postProc(post_proc), skinPostProc(skin_post_proc),
149 skinPostProcInteg(skin_post_proc_integ),
150 commonDataPtr(common_data_ptr){};
164 CHKERR VecZeroEntries(commonDataPtr->petscVec);
165 CHKERR VecGhostUpdateBegin(commonDataPtr->petscVec, INSERT_VALUES,
167 CHKERR VecGhostUpdateEnd(commonDataPtr->petscVec, INSERT_VALUES,
170 CHKERR VecAssemblyBegin(commonDataPtr->petscVec);
171 CHKERR VecAssemblyEnd(commonDataPtr->petscVec);
172 CHKERR VecGhostUpdateBegin(commonDataPtr->petscVec, ADD_VALUES,
174 CHKERR VecGhostUpdateEnd(commonDataPtr->petscVec, ADD_VALUES,
176 CHKERR VecGhostUpdateBegin(commonDataPtr->petscVec, INSERT_VALUES,
178 CHKERR VecGhostUpdateEnd(commonDataPtr->petscVec, INSERT_VALUES,
181 CHKERR VecGetArrayRead(commonDataPtr->petscVec, &array);
182 MOFEM_LOG(
"PHOTON", Sev::inform) <<
"Fluence rate integral: " << array[0];
187 CHKERR postProc->writeFile(
"out_volume_" +
188 boost::lexical_cast<std::string>(ts_step) +
193 CHKERR skinPostProc->writeFile(
194 "out_camera_" + boost::lexical_cast<std::string>(ts_step) +
226 PetscInt ghosts[1] = {0};
233 commonDataPtr->approxVals = boost::make_shared<VectorDouble>();
266 MOFEM_LOG(
"PHOTON", Sev::inform) <<
"Refractive index: " <<
n;
267 MOFEM_LOG(
"PHOTON", Sev::inform) <<
"Speed of light (cm/ns): " <<
c;
268 MOFEM_LOG(
"PHOTON", Sev::inform) <<
"Phase velocity in medium (cm/ns): " <<
v;
269 MOFEM_LOG(
"PHOTON", Sev::inform) <<
"Inverse velocity : " <<
inv_v;
271 <<
"Absorption coefficient (cm^-1): " <<
mu_a;
273 <<
"Scattering coefficient (cm^-1): " <<
mu_sp;
274 MOFEM_LOG(
"PHOTON", Sev::inform) <<
"Diffusion coefficient D : " <<
D;
275 MOFEM_LOG(
"PHOTON", Sev::inform) <<
"Coefficient A : " <<
A;
276 MOFEM_LOG(
"PHOTON", Sev::inform) <<
"Coefficient h : " <<
h;
278 MOFEM_LOG(
"PHOTON", Sev::inform) <<
"Approximation order: " <<
order;
283 auto set_camera_skin_fe = [&]() {
287 Range camera_surface;
288 const std::string block_name =
"CAM";
292 if (
bit->getName().compare(0, block_name.size(), block_name) == 0) {
293 MOFEM_LOG(
"PHOTON", Sev::inform) <<
"Found CAM block";
295 bit->getMeshset(), 2, camera_surface,
true);
300 MOFEM_LOG(
"PHOTON", Sev::noisy) <<
"CAM block entities:\n"
306 "PHOTON_FLUENCE_RATE");
313 auto my_simple_set_up = [&]() {
329 CHKERR set_camera_skin_fe();
330 CHKERR my_simple_set_up();
361 CHKERR bc_mng->pushMarkDOFsOnEntities(
simple->getProblemName(),
"EXT",
362 "PHOTON_FLUENCE_RATE", 0, 0,
false);
367 std::string entity_name = it->getName();
368 if (entity_name.compare(0, 3,
"INT") == 0) {
370 boundary_ents,
true);
374 Range boundary_verts;
377 boundary_ents.merge(boundary_verts);
381 simple->getProblemName(),
"PHOTON_FLUENCE_RATE", boundary_ents);
392 auto add_domain_base_ops = [&](
auto &pipeline) {
393 auto jac_ptr = boost::make_shared<MatrixDouble>();
394 auto inv_jac_ptr = boost::make_shared<MatrixDouble>();
395 auto det_ptr = boost::make_shared<VectorDouble>();
402 auto add_domain_lhs_ops = [&](
auto &pipeline) {
404 "PHOTON_FLUENCE_RATE",
"PHOTON_FLUENCE_RATE",
405 [](
double,
double,
double) ->
double {
return D; }));
410 "PHOTON_FLUENCE_RATE",
"PHOTON_FLUENCE_RATE", get_mass_coefficient));
413 auto add_domain_rhs_ops = [&](
auto &pipeline) {
414 auto grad_u_at_gauss_pts = boost::make_shared<MatrixDouble>();
415 auto u_at_gauss_pts = boost::make_shared<VectorDouble>();
416 auto dot_u_at_gauss_pts = boost::make_shared<VectorDouble>();
418 "PHOTON_FLUENCE_RATE", grad_u_at_gauss_pts));
422 "PHOTON_FLUENCE_RATE", dot_u_at_gauss_pts));
424 "PHOTON_FLUENCE_RATE", grad_u_at_gauss_pts,
425 [](
double,
double,
double) ->
double {
return D; }));
427 "PHOTON_FLUENCE_RATE", dot_u_at_gauss_pts,
428 [](
const double,
const double,
const double) {
return inv_v; }));
430 "PHOTON_FLUENCE_RATE", u_at_gauss_pts,
431 [](
const double,
const double,
const double) {
return mu_a; }));
434 auto add_boundary_base_ops = [&](
auto &pipeline) {
438 auto add_boundary_lhs_ops = [&](
auto &pipeline) {
439 for (
auto b : bc_map) {
440 if (std::regex_match(b.first, std::regex(
"(.*)EXT(.*)"))) {
442 "PHOTON_FLUENCE_RATE",
"PHOTON_FLUENCE_RATE",
444 [](
const double,
const double,
const double) {
return h; },
446 b.second->getBcEntsPtr()));
451 auto add_boundary_rhs_ops = [&](
auto &pipeline) {
452 auto u_at_gauss_pts = boost::make_shared<VectorDouble>();
455 for (
auto b : bc_map) {
456 if (std::regex_match(b.first, std::regex(
"(.*)EXT(.*)"))) {
458 "PHOTON_FLUENCE_RATE", u_at_gauss_pts,
460 [](
const double,
const double,
const double) {
return h; },
462 b.second->getBcEntsPtr()));
468 add_domain_base_ops(pipeline_mng->getOpDomainLhsPipeline());
469 add_domain_base_ops(pipeline_mng->getOpDomainRhsPipeline());
470 add_domain_lhs_ops(pipeline_mng->getOpDomainLhsPipeline());
471 add_domain_rhs_ops(pipeline_mng->getOpDomainRhsPipeline());
473 add_boundary_base_ops(pipeline_mng->getOpBoundaryLhsPipeline());
474 add_boundary_base_ops(pipeline_mng->getOpBoundaryRhsPipeline());
475 add_boundary_lhs_ops(pipeline_mng->getOpBoundaryLhsPipeline());
476 add_boundary_rhs_ops(pipeline_mng->getOpBoundaryRhsPipeline());
491 auto create_post_process_element = [&]() {
492 auto post_froc_fe = boost::make_shared<PostProcEle>(
mField);
493 auto u_ptr = boost::make_shared<VectorDouble>();
494 auto grad_ptr = boost::make_shared<MatrixDouble>();
495 post_froc_fe->getOpPtrVector().push_back(
497 post_froc_fe->getOpPtrVector().push_back(
500 post_froc_fe->getOpPtrVector().push_back(
new OpPPMap(
501 post_froc_fe->getPostProcMesh(), post_froc_fe->getMapGaussPts(),
502 {{
"PHOTON_FLUENCE_RATE", u_ptr}},
503 {{
"GRAD_PHOTON_FLUENCE_RATE", grad_ptr}}, {}, {}));
507 auto create_post_process_camera_element = [&]() {
510 auto post_proc_skin = boost::make_shared<PostProcFaceEle>(
mField);
512 auto u_ptr = boost::make_shared<VectorDouble>();
513 auto grad_ptr = boost::make_shared<MatrixDouble>();
518 auto jac_ptr = boost::make_shared<MatrixDouble>();
519 auto inv_jac_ptr = boost::make_shared<MatrixDouble>();
520 auto det_ptr = boost::make_shared<VectorDouble>();
523 op_loop_side->getOpPtrVector().push_back(
525 op_loop_side->getOpPtrVector().push_back(
527 op_loop_side->getOpPtrVector().push_back(
529 op_loop_side->getOpPtrVector().push_back(
531 op_loop_side->getOpPtrVector().push_back(
534 post_proc_skin->getOpPtrVector().push_back(op_loop_side);
536 post_proc_skin->getOpPtrVector().push_back(
new OpPPMap(
537 post_proc_skin->getPostProcMesh(), post_proc_skin->getMapGaussPts(),
538 {{
"PHOTON_FLUENCE_RATE", u_ptr}},
539 {{
"GRAD_PHOTON_FLUENCE_RATE", grad_ptr}}, {}, {}));
541 return post_proc_skin;
543 return boost::shared_ptr<PostProcFaceEle>();
547 auto create_post_process_integ_camera_element = [&]() {
548 if (mField.check_finite_element(
"CAMERA_FE")) {
550 auto post_proc_integ_skin = boost::make_shared<BoundaryEle>(mField);
551 post_proc_integ_skin->getOpPtrVector().push_back(
553 post_proc_integ_skin->getOpPtrVector().push_back(
555 commonDataPtr->approxVals));
556 post_proc_integ_skin->getOpPtrVector().push_back(
557 new OpCameraInteg(commonDataPtr));
559 return post_proc_integ_skin;
561 return boost::shared_ptr<BoundaryEle>();
565 auto set_time_monitor = [&](
auto dm,
auto solver) {
567 boost::shared_ptr<Monitor> monitor_ptr(
new Monitor(
568 dm, create_post_process_element(), create_post_process_camera_element(),
569 create_post_process_integ_camera_element(), commonDataPtr));
570 boost::shared_ptr<ForcesAndSourcesCore>
null;
572 monitor_ptr,
null,
null);
576 auto dm =
simple->getDM();
581 MOFEM_LOG(
"PHOTON", Sev::inform) <<
"reading vector in binary from file "
591 auto solver = pipeline_mng->createTS();
593 CHKERR TSSetSolution(solver, X);
594 CHKERR set_time_monitor(dm, solver);
595 CHKERR TSSetSolution(solver, X);
596 CHKERR TSSetFromOptions(solver);
598 CHKERR TSSolve(solver, NULL);
600 CHKERR VecGhostUpdateBegin(X, INSERT_VALUES, SCATTER_FORWARD);
601 CHKERR VecGhostUpdateEnd(X, INSERT_VALUES, SCATTER_FORWARD);
634 const int nb_integration_pts = getGaussPts().size2();
635 const double area = getMeasure();
636 auto t_w = getFTensor0IntegrationWeight();
639 double values_integ = 0;
641 for (
int gg = 0; gg != nb_integration_pts; ++gg) {
642 const double alpha = t_w * area;
644 values_integ += alpha * t_val;
651 std::array<double, 1> values;
652 values[0] = values_integ;
658 int main(
int argc,
char *argv[]) {
661 const char param_file[] =
"param_file.petsc";
665 auto core_log = logging::core::get();
667 LogManager::createSink(LogManager::getStrmWorld(),
"PHOTON"));
668 LogManager::setLog(
"PHOTON");
674 DMType dm_name =
"DMMOFEM";