290 DMType dm_name =
"DMMOFEM";
297 auto core_log = logging::core::get();
299 LogManager::createSink(LogManager::getStrmWorld(),
"AT"));
300 LogManager::setLog(
"AT");
311 simple->getAddBoundaryFE() =
true;
323 const char *list_bases[] = {
"ainsworth",
"ainsworth_labatto",
"demkowicz",
326 PetscInt choice_base_value = AINSWORTH;
328 LASBASETOP, &choice_base_value, &flg);
330 if (flg != PETSC_TRUE)
333 if (choice_base_value == AINSWORTH)
335 if (choice_base_value == AINSWORTH_LOBATTO)
337 else if (choice_base_value == DEMKOWICZ)
339 else if (choice_base_value == BERNSTEIN)
342 enum spaces { H1SPACE, L2SPACE, LASBASETSPACE };
343 const char *list_spaces[] = {
"h1",
"l2"};
344 PetscInt choice_space_value = H1SPACE;
346 LASBASETSPACE, &choice_space_value, &flg);
347 if (flg != PETSC_TRUE)
350 if (choice_space_value == H1SPACE)
352 else if (choice_space_value == L2SPACE)
358 CHKERR simple->addDomainField(
"FIELD1", space, base, 1);
362 CHKERR moab.get_entities_by_dimension(0, 1, edges);
363 CHKERR moab.get_entities_by_dimension(0, 2, faces);
365 if (choice_base_value != BERNSTEIN) {
369 for (
auto e : edges) {
371 rise_order.insert(e);
376 for (
auto f : faces) {
378 rise_order.insert(
f);
384 for (
auto e : rise_order) {
386 rise_twice.insert(e);
400 std::vector<EntityHandle> &adjacency) {
403 switch (field.getSpace()) {
405 CHKERR moab.get_connectivity(&fe_ent, 1, adjacency,
true);
407 CHKERR moab.get_adjacencies(&fe_ent, 1, 1,
false, adjacency,
408 moab::Interface::UNION);
411 CHKERR moab.get_adjacencies(&fe_ent, 1, 2,
false, adjacency,
412 moab::Interface::UNION);
413 adjacency.push_back(fe_ent);
415 for (
auto ent : adjacency)
416 fe.getSideNumberPtr(ent);
419 CHKERR moab.get_entities_by_handle(field.getMeshset(), adjacency,
421 for (
auto ent : adjacency) {
424 boost::shared_ptr<SideNumber>(
new SideNumber(ent, -1, 0, 0)));
429 "this field is not implemented for TRI finite element");
436 simple->getDomainFEName(), MBTET, volume_adj);
438 simple->getDomainFEName(), MBHEX, volume_adj);
445 auto dm =
simple->getDM();
448 auto jac_ptr = boost::make_shared<MatrixDouble>();
449 auto inv_jac_ptr = boost::make_shared<MatrixDouble>();
450 auto det_ptr = boost::make_shared<VectorDouble>();
453 auto assemble_matrices_and_vectors = [&]() {
457 PETSC>::LinearForm<GAUSS>::OpSource<1, 1>;
460 pipeline_mng->getOpDomainLhsPipeline(), {NOSPACE});
462 pipeline_mng->getOpDomainRhsPipeline(), {NOSPACE});
467 pipeline_mng->getOpDomainLhsPipeline().push_back(
469 pipeline_mng->getOpDomainLhsPipeline().push_back(
new OpMass(
470 "FIELD1",
"FIELD1", [](
double,
double,
double) {
return 1.; }));
471 pipeline_mng->getOpDomainLhsPipeline().push_back(
474 pipeline_mng->getOpDomainRhsPipeline().push_back(
478 return 2 * p_data + 1;
486 auto solve_problem = [&] {
488 auto solver = pipeline_mng->createKSP();
489 CHKERR KSPSetFromOptions(solver);
492 auto dm =
simple->getDM();
497 CHKERR VecGhostUpdateBegin(
D, INSERT_VALUES, SCATTER_FORWARD);
498 CHKERR VecGhostUpdateEnd(
D, INSERT_VALUES, SCATTER_FORWARD);
504 auto check_solution = [&] {
507 auto ptr_values = boost::make_shared<VectorDouble>();
508 auto ptr_diff_vals = boost::make_shared<MatrixDouble>();
510 pipeline_mng->getDomainLhsFE().reset();
511 pipeline_mng->getOpDomainRhsPipeline().clear();
514 pipeline_mng->getOpDomainRhsPipeline(), {space});
516 pipeline_mng->getOpDomainRhsPipeline().push_back(
518 pipeline_mng->getOpDomainRhsPipeline().push_back(
520 pipeline_mng->getOpDomainRhsPipeline().push_back(
524 vals, diff_vals, ptr_values, ptr_diff_vals,
true));
526 CHKERR pipeline_mng->loopFiniteElements();
531 auto post_proc = [&] {
536 auto get_domain_post_proc_fe = [&](
auto post_proc_mesh_ptr) {
538 boost::make_shared<PostProcBrokenMeshInMoabBaseCont<DomainEle>>(
539 m_field, post_proc_mesh_ptr);
542 post_proc_fe->getOpPtrVector(), {space});
544 auto ptr_values = boost::make_shared<VectorDouble>();
545 auto ptr_diff_vals = boost::make_shared<MatrixDouble>();
547 post_proc_fe->getOpPtrVector().push_back(
549 post_proc_fe->getOpPtrVector().push_back(
553 post_proc_fe->getOpPtrVector().push_back(
557 post_proc_fe->getPostProcMesh(), post_proc_fe->getMapGaussPts(),
559 {{
"FIELD1", ptr_values}},
561 {{
"FIELD1_GRAD", ptr_diff_vals}},
569 auto get_bdy_post_proc_fe = [&](
auto post_proc_mesh_ptr) {
570 auto bdy_post_proc_fe =
571 boost::make_shared<PostProcBrokenMeshInMoabBaseCont<BoundaryEle>>(
572 m_field, post_proc_mesh_ptr);
579 auto ptr_values = boost::make_shared<VectorDouble>();
580 auto ptr_diff_vals = boost::make_shared<MatrixDouble>();
584 op_loop_side->getOpPtrVector(), {space});
585 op_loop_side->getOpPtrVector().push_back(
587 op_loop_side->getOpPtrVector().push_back(
591 bdy_post_proc_fe->getOpPtrVector().push_back(op_loop_side);
593 bdy_post_proc_fe->getOpPtrVector().push_back(
597 bdy_post_proc_fe->getPostProcMesh(),
598 bdy_post_proc_fe->getMapGaussPts(),
600 {{
"FIELD1", ptr_values}},
602 {{
"FIELD1_GRAD", ptr_diff_vals}},
608 return bdy_post_proc_fe;
611 auto post_proc_mesh_ptr = boost::make_shared<moab::Core>();
612 auto post_proc_begin =
613 boost::make_shared<PostProcBrokenMeshInMoabBaseBegin>(
614 m_field, post_proc_mesh_ptr);
616 boost::make_shared<PostProcBrokenMeshInMoabBaseEnd>(
617 m_field, post_proc_mesh_ptr);
618 auto domain_post_proc_fe = get_domain_post_proc_fe(post_proc_mesh_ptr);
619 auto bdy_post_proc_fe = get_bdy_post_proc_fe(post_proc_mesh_ptr);
623 domain_post_proc_fe);
627 CHKERR post_proc_end->writeFile(
"out_post_proc.h5m");
632 CHKERR assemble_matrices_and_vectors();