v0.15.0
Loading...
Searching...
No Matches
MoFEM::ProblemsManager Struct Reference

Problem manager is used to build and partition problems. More...

#include "src/interfaces/ProblemsManager.hpp"

Inheritance diagram for MoFEM::ProblemsManager:
[legend]
Collaboration diagram for MoFEM::ProblemsManager:
[legend]

Public Types

enum  MarkOP { OR , AND }
 

Public Member Functions

MoFEMErrorCode query_interface (boost::typeindex::type_index type_index, UnknownInterface **iface) const
 
 ProblemsManager (const MoFEM::Core &core)
 
virtual ~ProblemsManager ()=default
 
MoFEMErrorCode getOptions ()
 
DEPRECATED MoFEMErrorCode partitionMesh (const Range &ents, const int dim, const int adj_dim, const int n_parts, Tag *th_vertex_weights=nullptr, Tag *th_edge_weights=nullptr, Tag *th_part_weights=nullptr, int verb=VERBOSE, const bool debug=false)
 Set partition tag to each finite element in the problem.
 
MoFEMErrorCode buildProblem (const std::string name, const bool square_matrix, int verb=VERBOSE)
 build problem data structures
 
MoFEMErrorCode buildProblem (Problem *problem_ptr, const bool square_matrix, int verb=VERBOSE)
 build problem data structures
 
MoFEMErrorCode buildProblemOnDistributedMesh (const std::string name, const bool square_matrix, int verb=VERBOSE)
 build problem data structures, assuming that mesh is distributed (collective)
 
MoFEMErrorCode buildProblemOnDistributedMesh (Problem *problem_ptr, const bool square_matrix=true, int verb=VERBOSE)
 build problem data structures, assuming that mesh is distributed (collective)
 
MoFEMErrorCode buildSubProblem (const std::string out_name, const std::vector< std::string > &fields_row, const std::vector< std::string > &fields_col, const std::string main_problem, const bool square_matrix=true, const map< std::string, boost::shared_ptr< Range > > *entityMapRow=nullptr, const map< std::string, boost::shared_ptr< Range > > *entityMapCol=nullptr, int verb=VERBOSE)
 build sub problem
 
MoFEMErrorCode buildComposedProblem (const std::string out_name, const std::vector< std::string > add_row_problems, const std::vector< std::string > add_col_problems, const bool square_matrix=true, int verb=1)
 build composite problem
 
MoFEMErrorCode inheritPartition (const std::string name, const std::string problem_for_rows, bool copy_rows, const std::string problem_for_cols, bool copy_cols, int verb=VERBOSE)
 build indexing and partition problem inheriting indexing and partitioning from two other problems
 
MoFEMErrorCode partitionSimpleProblem (const std::string name, int verb=VERBOSE)
 partition problem dofs
 
MoFEMErrorCode partitionProblem (const std::string name, int verb=VERBOSE)
 partition problem dofs (collective)
 
MoFEMErrorCode printPartitionedProblem (const Problem *problem_ptr, int verb=VERBOSE)
 
MoFEMErrorCode debugPartitionedProblem (const Problem *problem_ptr, int verb=VERBOSE)
 
MoFEMErrorCode partitionFiniteElements (const std::string name, bool part_from_moab=false, int low_proc=-1, int hi_proc=-1, int verb=VERBOSE)
 partition finite elements
 
MoFEMErrorCode partitionGhostDofs (const std::string name, int verb=VERBOSE)
 determine ghost nodes
 
MoFEMErrorCode partitionGhostDofsOnDistributedMesh (const std::string name, int verb=VERBOSE)
 determine ghost nodes on distributed meshes
 
MoFEMErrorCode getFEMeshset (const std::string prb_name, const std::string &fe_name, EntityHandle *meshset) const
 create add entities of finite element in the problem
 
MoFEMErrorCode getProblemElementsLayout (const std::string name, const std::string &fe_name, PetscLayout *layout) const
 Get layout of elements in the problem.
 
MoFEMErrorCode removeDofsOnEntities (const std::string problem_name, const std::string field_name, const Range ents, const int lo_coeff=0, const int hi_coeff=MAX_DOFS_ON_ENTITY, const int lo_order=0, const int hi_order=100, int verb=VERBOSE, const bool debug=false)
 Remove DOFs from problem.
 
MoFEMErrorCode removeDofsOnEntitiesNotDistributed (const std::string problem_name, const std::string field_name, const Range ents, const int lo_coeff=0, const int hi_coeff=MAX_DOFS_ON_ENTITY, const int lo_order=0, const int hi_order=100, int verb=VERBOSE, const bool debug=false)
 Remove DOFs from problem.
 
MoFEMErrorCode removeDofsOnEntities (const std::string problem_name, const std::string field_name, const BitRefLevel bit_ref_level, const BitRefLevel bit_ref_mask, Range *ents_ptr=nullptr, const int lo_coeff=0, const int hi_coeff=MAX_DOFS_ON_ENTITY, const int lo_order=0, const int hi_order=100, int verb=VERBOSE, const bool debug=false)
 Remove DOFs from problem by bit ref level.
 
MoFEMErrorCode removeDofsOnEntitiesNotDistributed (const std::string problem_name, const std::string field_name, const BitRefLevel bit_ref_level, const BitRefLevel bit_ref_mask, Range *ents_ptr=nullptr, const int lo_coeff=0, const int hi_coeff=MAX_DOFS_ON_ENTITY, const int lo_order=0, const int hi_order=100, int verb=VERBOSE, const bool debug=false)
 Remove DOFs from problem.
 
MoFEMErrorCode removeDofs (const std::string problem_name, RowColData rc, std::vector< boost::weak_ptr< NumeredDofEntity > > &vec_dof_view, int verb=VERBOSE, const bool debug=false)
 Remove DOFs from problem on broken space.
 
MoFEMErrorCode getSideDofsOnBrokenSpaceEntities (std::vector< boost::weak_ptr< NumeredDofEntity > > &vec_dof_view, const std::string problem_name, RowColData rc, const std::string field_name, const Range ents, int bridge_dim, const int lo_coeff=0, const int hi_coeff=MAX_DOFS_ON_ENTITY, const int lo_order=0, const int hi_order=100, int verb=VERBOSE, const bool debug=false) const
 Get DOFs on side entities for broke space.
 
MoFEMErrorCode markDofs (const std::string problem_name, RowColData rc, const enum MarkOP op, const Range ents, std::vector< unsigned char > &marker) const
 Create vector with marked indices.
 
DEPRECATED MoFEMErrorCode markDofs (const std::string problem_name, RowColData rc, const Range ents, std::vector< unsigned char > &marker) const
 
MoFEMErrorCode modifyMarkDofs (const std::string problem_name, RowColData rc, const std::string field_name, const int lo, const int hi, const enum MarkOP op, const unsigned char c, std::vector< unsigned char > &marker) const
 Mark DOFs.
 
MoFEMErrorCode markDofs (const std::string problem_name, RowColData rc, std::vector< boost::weak_ptr< NumeredDofEntity > > &vec_dof_view, const enum MarkOP op, std::vector< unsigned char > &marker) const
 Create vector with marked indices.
 
MoFEMErrorCode addFieldToEmptyFieldBlocks (const std::string problem_name, const std::string row_field, const std::string col_field) const
 add empty block to problem
 
- Public Member Functions inherited from MoFEM::UnknownInterface
template<class IFACE >
MoFEMErrorCode registerInterface (bool error_if_registration_failed=true)
 Register interface.
 
template<class IFACE >
MoFEMErrorCode getInterface (IFACE *&iface) const
 Get interface reference to pointer of interface.
 
template<class IFACE >
MoFEMErrorCode getInterface (IFACE **const iface) const
 Get interface pointer to pointer of interface.
 
template<class IFACE , typename boost::enable_if< boost::is_pointer< IFACE >, int >::type = 0>
IFACE getInterface () const
 Get interface pointer to pointer of interface.
 
template<class IFACE , typename boost::enable_if< boost::is_reference< IFACE >, int >::type = 0>
IFACE getInterface () const
 Get reference to interface.
 
template<class IFACE >
IFACE * getInterface () const
 Function returning pointer to interface.
 
virtual ~UnknownInterface ()=default
 

Public Attributes

MoFEM::CorecOre
 
PetscBool buildProblemFromFields
 
PetscBool synchroniseProblemEntities
 DOFs in fields, not from DOFs on elements.
 

Private Attributes

PetscLogEvent MOFEM_EVENT_ProblemsManager
 

Additional Inherited Members

- Static Public Member Functions inherited from MoFEM::UnknownInterface
static MoFEMErrorCode getLibVersion (Version &version)
 Get library version.
 
static MoFEMErrorCode getFileVersion (moab::Interface &moab, Version &version)
 Get database major version.
 
static MoFEMErrorCode setFileVersion (moab::Interface &moab, Version version=Version(MoFEM_VERSION_MAJOR, MoFEM_VERSION_MINOR, MoFEM_VERSION_BUILD))
 Get database major version.
 
static MoFEMErrorCode getInterfaceVersion (Version &version)
 Get database major version.
 

Detailed Description

Member Enumeration Documentation

◆ MarkOP

Constructor & Destructor Documentation

◆ ProblemsManager()

MoFEM::ProblemsManager::ProblemsManager ( const MoFEM::Core & core)

Definition at line 55 of file ProblemsManager.cpp.

56 : cOre(const_cast<MoFEM::Core &>(core)),
57 buildProblemFromFields(PETSC_FALSE),
58 synchroniseProblemEntities(PETSC_FALSE) {
59 PetscLogEventRegister("ProblemsManager", 0, &MOFEM_EVENT_ProblemsManager);
60}
Core (interface) class.
Definition Core.hpp:82
PetscLogEvent MOFEM_EVENT_ProblemsManager
PetscBool synchroniseProblemEntities
DOFs in fields, not from DOFs on elements.

◆ ~ProblemsManager()

virtual MoFEM::ProblemsManager::~ProblemsManager ( )
virtualdefault

Member Function Documentation

◆ addFieldToEmptyFieldBlocks()

MoFEMErrorCode MoFEM::ProblemsManager::addFieldToEmptyFieldBlocks ( const std::string problem_name,
const std::string row_field,
const std::string col_field ) const

add empty block to problem

MatrixManager assumes that all blocks, i.e. all fields combinations are non zero. This is not always the case, to optimise code and reduce memory usage user can specify which blocks are empty.

Parameters
problem_nameproblem name
row_fieldrow field name
col_fieldcol field name
Returns
MoFEMErrorCode

Definition at line 3686 of file ProblemsManager.cpp.

3688 {
3689
3690 Interface &m_field = cOre;
3692
3693 const auto problem_ptr = m_field.get_problem(problem_name);
3694 auto get_field_id = [&](const std::string field_name) {
3695 return m_field.get_field_structure(field_name)->getId();
3696 };
3697 const auto row_id = get_field_id(row_field);
3698 const auto col_id = get_field_id(col_field);
3699
3700 problem_ptr->addFieldToEmptyFieldBlocks(BlockFieldPair(row_id, col_id));
3701
3703}
#define MoFEMFunctionBegin
First executable line of each MoFEM function, used for error handling. Final line of MoFEM functions ...
#define MoFEMFunctionReturn(a)
Last executable line of each PETSc function used for error handling. Replaces return()
Problem::BlockFieldPair BlockFieldPair
DeprecatedCoreInterface Interface
constexpr auto field_name
MoFEMErrorCode get_problem(const std::string &problem_name, const Problem **problem_ptr) const
Get problem database (data structure)
Definition Core.cpp:822

◆ debugPartitionedProblem()

MoFEMErrorCode MoFEM::ProblemsManager::debugPartitionedProblem ( const Problem * problem_ptr,
int verb = VERBOSE )

Definition at line 2080 of file ProblemsManager.cpp.

2080 {
2081 MoFEM::Interface &m_field = cOre;
2083
2084 auto save_ent = [](moab::Interface &moab, const std::string name,
2085 const EntityHandle ent) {
2087 EntityHandle out_meshset;
2088 CHKERR moab.create_meshset(MESHSET_SET, out_meshset);
2089 CHKERR moab.add_entities(out_meshset, &ent, 1);
2090 CHKERR moab.write_file(name.c_str(), "VTK", "", &out_meshset, 1);
2091 CHKERR moab.delete_entities(&out_meshset, 1);
2093 };
2094
2095 if (debug > 0) {
2096
2097 typedef NumeredDofEntity_multiIndex::index<Idx_mi_tag>::type
2098 NumeredDofEntitysByIdx;
2099 NumeredDofEntitysByIdx::iterator dit, hi_dit;
2100 const NumeredDofEntitysByIdx *numered_dofs_ptr[] = {
2101 &(problem_ptr->numeredRowDofsPtr->get<Idx_mi_tag>()),
2102 &(problem_ptr->numeredColDofsPtr->get<Idx_mi_tag>())};
2103
2104 int *nbdof_ptr[] = {&problem_ptr->nbDofsRow, &problem_ptr->nbDofsCol};
2105 int *local_nbdof_ptr[] = {&problem_ptr->nbLocDofsRow,
2106 &problem_ptr->nbLocDofsCol};
2107
2108 for (int ss = 0; ss < 2; ss++) {
2109
2110 dit = numered_dofs_ptr[ss]->begin();
2111 hi_dit = numered_dofs_ptr[ss]->end();
2112 for (; dit != hi_dit; dit++) {
2113 if ((*dit)->getPart() == (unsigned int)m_field.get_comm_rank()) {
2114 if ((*dit)->getPetscLocalDofIdx() < 0) {
2115 std::ostringstream zz;
2116 zz << "rank " << m_field.get_comm_rank() << " " << **dit;
2117 SETERRQ(PETSC_COMM_SELF, MOFEM_IMPOSSIBLE_CASE,
2118 "local dof index for %d (0-row, 1-col) not set, i.e. has "
2119 "negative value\n %s",
2120 ss, zz.str().c_str());
2121 }
2122 if ((*dit)->getPetscLocalDofIdx() >= *local_nbdof_ptr[ss]) {
2123 std::ostringstream zz;
2124 zz << "rank " << m_field.get_comm_rank() << " " << **dit;
2125 SETERRQ(PETSC_COMM_SELF, MOFEM_IMPOSSIBLE_CASE,
2126 "local dofs for %d (0-row, 1-col) out of range\n %s", ss,
2127 zz.str().c_str());
2128 }
2129 } else {
2130 if ((*dit)->getPetscGlobalDofIdx() < 0) {
2131
2132 const EntityHandle ent = (*dit)->getEnt();
2133 CHKERR save_ent(
2134 m_field.get_moab(),
2135 "debug_part" +
2136 boost::lexical_cast<std::string>(m_field.get_comm_rank()) +
2137 "_negative_global_index.vtk",
2138 ent);
2139
2140 std::ostringstream zz;
2141 zz << "rank " << m_field.get_comm_rank() << " "
2142 << dit->get()->getBitRefLevel() << " " << **dit;
2143 SETERRQ(PETSC_COMM_SELF, MOFEM_IMPOSSIBLE_CASE,
2144 "global dof index for %d (0-row, 1-col) row not set, i.e. "
2145 "has negative value\n %s",
2146 ss, zz.str().c_str());
2147 }
2148 if ((*dit)->getPetscGlobalDofIdx() >= *nbdof_ptr[ss]) {
2149 std::ostringstream zz;
2150 zz << "rank " << m_field.get_comm_rank() << " nb_dofs "
2151 << *nbdof_ptr[ss] << " " << **dit;
2152 SETERRQ(PETSC_COMM_SELF, MOFEM_IMPOSSIBLE_CASE,
2153 "global dofs for %d (0-row, 1-col) out of range\n %s", ss,
2154 zz.str().c_str());
2155 }
2156 }
2157 }
2158 }
2159 }
2161}
#define MoFEMFunctionReturnHot(a)
Last executable line of each PETSc function used for error handling. Replaces return()
@ MOFEM_IMPOSSIBLE_CASE
Definition definitions.h:35
#define CHKERR
Inline error check.
#define MoFEMFunctionBeginHot
First executable line of each MoFEM function, used for error handling. Final line of MoFEM functions ...
static const bool debug
virtual moab::Interface & get_moab()=0
virtual int get_comm_rank() const =0
Deprecated interface functions.

◆ getOptions()

MoFEMErrorCode MoFEM::ProblemsManager::getOptions ( )

Definition at line 62 of file ProblemsManager.cpp.

62 {
63 MoFEM::Interface &m_field = cOre;
65 PetscOptionsBegin(m_field.get_comm(), "", "Problem manager", "none");
66 {
67 CHKERR PetscOptionsBool(
68 "-problem_build_from_fields",
69 "Add DOFs to problem directly from fields not through DOFs on elements",
71 }
72 PetscOptionsEnd();
74}
virtual MPI_Comm & get_comm() const =0

◆ getSideDofsOnBrokenSpaceEntities()

MoFEMErrorCode MoFEM::ProblemsManager::getSideDofsOnBrokenSpaceEntities ( std::vector< boost::weak_ptr< NumeredDofEntity > > & vec_dof_view,
const std::string problem_name,
RowColData rc,
const std::string field_name,
const Range ents,
int bridge_dim,
const int lo_coeff = 0,
const int hi_coeff = MAX_DOFS_ON_ENTITY,
const int lo_order = 0,
const int hi_order = 100,
int verb = VERBOSE,
const bool debug = false ) const

Get DOFs on side entities for broke space.

Parameters
dof_view
problem_name
rcrow or column
field_name
entsside entities
bridge_dimdimension of bridge entity (dofs are on iterator by have associated side entity)
lo_coeff
hi_coeff
lo_order
hi_order
verb
debug
Returns
MoFEMErrorCode

Definition at line 2610 of file ProblemsManager.cpp.

2618 {
2619 MoFEM::Interface &m_field = cOre;
2621
2622 switch (rc) {
2623 case ROW:
2624 case COL:
2625 break;
2626 default:
2627 SETERRQ(m_field.get_comm(), MOFEM_INVALID_DATA, "invalid RowColData");
2628 break;
2629 }
2630
2631 const Problem *prb_ptr;
2632 CHKERR m_field.get_problem(problem_name, &prb_ptr);
2633
2634 decltype(prb_ptr->numeredRowDofsPtr) numered_dofs[2] = {
2635 prb_ptr->numeredRowDofsPtr, nullptr};
2636 if (prb_ptr->numeredRowDofsPtr != prb_ptr->numeredColDofsPtr)
2637 numered_dofs[1] = prb_ptr->numeredColDofsPtr;
2638
2639 Range bridge_ents;
2640 CHKERR m_field.get_moab().get_adjacencies(
2641 ents, bridge_dim, false, bridge_ents, moab::Interface::UNION);
2642
2643 auto &moab = m_field.get_moab();
2644 const auto bit_number = m_field.get_field_bit_number(field_name);
2645 const auto nb_coeffs =
2647 const auto &side_dof_map = m_field.get_field_structure(field_name)
2648 ->getDofSideMap();
2649
2650 using NumeredDofEntity_it_view_multiIndex = multi_index_container<
2651
2652 NumeredDofEntity_multiIndex::iterator, indexed_by<sequenced<>>
2653
2654 >;
2655 NumeredDofEntity_it_view_multiIndex dofs_it_view;
2656
2657 for (auto pit = bridge_ents.const_pair_begin();
2658 pit != bridge_ents.const_pair_end(); ++pit) {
2659 auto lo = numered_dofs[rc]->get<Unique_mi_tag>().lower_bound(
2660 DofEntity::getLoFieldEntityUId(bit_number, pit->first));
2661 auto hi = numered_dofs[rc]->get<Unique_mi_tag>().upper_bound(
2662 DofEntity::getHiFieldEntityUId(bit_number, pit->second));
2663
2664 auto bride_type = moab.type_from_handle(pit->first);
2665
2666 for (; lo != hi; ++lo) {
2667 if ((*lo)->getDofCoeffIdx() >= lo_coeff &&
2668 (*lo)->getDofCoeffIdx() <= hi_coeff &&
2669 (*lo)->getDofOrder() >= lo_order &&
2670 (*lo)->getDofOrder() <= hi_order) {
2671 auto ent_dof_index = (*lo)->getEntDofIdx();
2672 auto side_it = side_dof_map.at(bride_type)
2673 .get<EntDofIdx_mi_tag>()
2674 .find(std::floor(static_cast<double>(ent_dof_index) /
2675 nb_coeffs));
2676 if (side_it !=
2677 side_dof_map.at(bride_type).get<EntDofIdx_mi_tag>().end()) {
2678 auto bridge_ent = (*lo)->getEnt();
2679 auto type = side_it->type;
2680 auto side = side_it->side;
2681 auto dim = CN::Dimension(type);
2682 EntityHandle side_ent = 0;
2683 CHKERR moab.side_element(bridge_ent, dim, side, side_ent);
2684 if (ents.find(side_ent) != ents.end()) {
2685 dofs_it_view.emplace_back(numered_dofs[rc]->project<0>(lo));
2686 }
2687 } else {
2688#ifndef NDEBUG
2689 MOFEM_LOG("SELF", Sev::error)
2690 << *m_field.get_field_structure(field_name);
2691 MOFEM_LOG("SELF", Sev::error)
2692 << "side not found for entity " << CN::EntityTypeName(bride_type);
2693 MOFEM_LOG("SELF", Sev::error)
2694 << "ent_dof_index / nb_coeffs "
2695 << std::floor(static_cast<double>(ent_dof_index) / nb_coeffs);
2696 MOFEM_LOG("SELF", Sev::error)
2697 << "side_dof_map.size() " << side_dof_map.size();
2698#endif // NDEBUG
2699 SETERRQ(m_field.get_comm(), MOFEM_DATA_INCONSISTENCY,
2700 "side not found - you will get more information in debug");
2701 }
2702 }
2703 }
2704 }
2705
2706 if (verb > QUIET) {
2707 for (auto &dof : dofs_it_view)
2708 MOFEM_LOG("SYNC", Sev::noisy) << **dof;
2709 MOFEM_LOG_SEVERITY_SYNC(m_field.get_comm(), Sev::noisy);
2710 }
2711
2712 vec_dof_view.reserve(vec_dof_view.size() + dofs_it_view.size());
2713 for (auto dit : dofs_it_view)
2714 vec_dof_view.push_back(*dit);
2715
2717}
#define MOFEM_LOG_SEVERITY_SYNC(comm, severity)
Synchronise "SYNC" on curtain severity level.
#define ProblemManagerFunctionBegin
@ QUIET
@ COL
@ ROW
@ MOFEM_DATA_INCONSISTENCY
Definition definitions.h:31
@ MOFEM_INVALID_DATA
Definition definitions.h:36
virtual const Problem * get_problem(const std::string problem_name) const =0
Get the problem object.
virtual const Field * get_field_structure(const std::string &name, enum MoFEMTypes bh=MF_EXIST) const =0
get field structure
#define MOFEM_LOG(channel, severity)
Log.
virtual FieldBitNumber get_field_bit_number(const std::string name) const =0
get field bit number
static UId getLoFieldEntityUId(const FieldBitNumber bit, const EntityHandle ent)
static UId getHiFieldEntityUId(const FieldBitNumber bit, const EntityHandle ent)
FieldCoefficientsNumber getNbOfCoeffs() const
Get number of field coefficients.
std::map< int, BaseFunction::DofsSideMap > & getDofSideMap() const
Get the dofs side map.
boost::shared_ptr< NumeredDofEntity_multiIndex > numeredColDofsPtr
store DOFs on columns for this problem

◆ markDofs() [1/3]

MoFEMErrorCode MoFEM::ProblemsManager::markDofs ( const std::string problem_name,
RowColData rc,
const enum MarkOP op,
const Range ents,
std::vector< unsigned char > & marker ) const

Create vector with marked indices.

Vector with local DOFs marked by entities

Parameters
problem_name
row
ents
marker
Returns
MoFEMErrorCode
Examples
boundary_marker.cpp, helmholtz.cpp, and test_cache_on_entities.cpp.

Definition at line 3553 of file ProblemsManager.cpp.

3555 {
3556
3557 Interface &m_field = cOre;
3558 const Problem *problem_ptr;
3560 CHKERR m_field.get_problem(problem_name, &problem_ptr);
3561 boost::shared_ptr<NumeredDofEntity_multiIndex> dofs;
3562 switch (rc) {
3563 case ROW:
3564 dofs = problem_ptr->getNumeredRowDofsPtr();
3565 break;
3566 case COL:
3567 dofs = problem_ptr->getNumeredColDofsPtr();
3568 default:
3569 SETERRQ(PETSC_COMM_SELF, MOFEM_IMPOSSIBLE_CASE, "Should be row or column");
3570 }
3571 marker.resize(dofs->size(), 0);
3572 std::vector<unsigned char> marker_tmp;
3573
3574 switch (op) {
3575 case MarkOP::OR:
3576 for (auto p = ents.pair_begin(); p != ents.pair_end(); ++p) {
3577 auto lo = dofs->get<Ent_mi_tag>().lower_bound(p->first);
3578 auto hi = dofs->get<Ent_mi_tag>().upper_bound(p->second);
3579 for (; lo != hi; ++lo)
3580 marker[(*lo)->getPetscLocalDofIdx()] |= 1;
3581 }
3582 break;
3583 case MarkOP::AND:
3584 marker_tmp.resize(dofs->size(), 0);
3585 for (auto p = ents.pair_begin(); p != ents.pair_end(); ++p) {
3586 auto lo = dofs->get<Ent_mi_tag>().lower_bound(p->first);
3587 auto hi = dofs->get<Ent_mi_tag>().upper_bound(p->second);
3588 for (; lo != hi; ++lo)
3589 marker_tmp[(*lo)->getPetscLocalDofIdx()] = 1;
3590 }
3591 for (int i = 0; i != marker.size(); ++i) {
3592 marker[i] &= marker_tmp[i];
3593 }
3594 break;
3595 }
3596
3598}
auto marker
set bit to marker
FTensor::Index< 'i', SPACE_DIM > i

◆ markDofs() [2/3]

DEPRECATED MoFEMErrorCode MoFEM::ProblemsManager::markDofs ( const std::string problem_name,
RowColData rc,
const Range ents,
std::vector< unsigned char > & marker ) const
inline
Deprecated
use function with MarkOP

Definition at line 438 of file ProblemsManager.hpp.

439 {
440 return markDofs(problem_name, rc, MarkOP::OR, ents, marker);
441 }
MoFEMErrorCode markDofs(const std::string problem_name, RowColData rc, const enum MarkOP op, const Range ents, std::vector< unsigned char > &marker) const
Create vector with marked indices.

◆ markDofs() [3/3]

MoFEMErrorCode MoFEM::ProblemsManager::markDofs ( const std::string problem_name,
RowColData rc,
std::vector< boost::weak_ptr< NumeredDofEntity > > & vec_dof_view,
const enum MarkOP op,
std::vector< unsigned char > & marker ) const

Create vector with marked indices.

Vector with local DOFs marked by entities

Parameters
problem_name
row
ents
marker
Returns
MoFEMErrorCode

Definition at line 3648 of file ProblemsManager.cpp.

3654 {
3655 Interface &m_field = cOre;
3657
3658 const Problem *problem_ptr;
3659 CHKERR m_field.get_problem(problem_name, &problem_ptr);
3660 boost::shared_ptr<NumeredDofEntity_multiIndex> dofs;
3661 switch (rc) {
3662 case ROW:
3663 dofs = problem_ptr->getNumeredRowDofsPtr();
3664 break;
3665 case COL:
3666 dofs = problem_ptr->getNumeredColDofsPtr();
3667 break;
3668 default:
3669 SETERRQ(PETSC_COMM_SELF, MOFEM_IMPOSSIBLE_CASE, "Should be row or column");
3670 }
3671 marker.resize(dofs->size(), 0);
3672
3673 for (auto &dof : vec_dof_view) {
3674 if (auto dof_ptr = dof.lock()) {
3675 if (op == MarkOP::OR)
3676 marker[dof_ptr->getPetscLocalDofIdx()] |= 1;
3677 else
3678 marker[dof_ptr->getPetscLocalDofIdx()] &= 1;
3679 }
3680 }
3681
3683}

◆ modifyMarkDofs()

MoFEMErrorCode MoFEM::ProblemsManager::modifyMarkDofs ( const std::string problem_name,
RowColData rc,
const std::string field_name,
const int lo,
const int hi,
const enum MarkOP op,
const unsigned char c,
std::vector< unsigned char > & marker ) const

Mark DOFs.

Parameters
problem_name
rc
field_name
lo
hi
op
marker
Returns
MoFEMErrorCode

Definition at line 3600 of file ProblemsManager.cpp.

3603 {
3604
3605 Interface &m_field = cOre;
3606 const Problem *problem_ptr;
3608 CHKERR m_field.get_problem(problem_name, &problem_ptr);
3609 boost::shared_ptr<NumeredDofEntity_multiIndex> dofs;
3610 switch (rc) {
3611 case ROW:
3612 dofs = problem_ptr->getNumeredRowDofsPtr();
3613 break;
3614 case COL:
3615 dofs = problem_ptr->getNumeredColDofsPtr();
3616 default:
3617 SETERRQ(PETSC_COMM_SELF, MOFEM_IMPOSSIBLE_CASE, "Should be row or column");
3618 }
3619 marker.resize(dofs->size(), 0);
3620
3621 auto dof_lo = dofs->get<Unique_mi_tag>().lower_bound(
3622 FieldEntity::getLoBitNumberUId(m_field.get_field_bit_number(field_name)));
3623 auto dof_hi = dofs->get<Unique_mi_tag>().upper_bound(
3624 FieldEntity::getHiBitNumberUId(m_field.get_field_bit_number(field_name)));
3625
3626 auto marker_ref = [marker](auto &it) -> unsigned int & {
3627 return marker[(*it)->getPetscLocalDofIdx()];
3628 };
3629
3630 switch (op) {
3631 case MarkOP::OR:
3632 for (; dof_lo != dof_hi; ++dof_lo)
3633 if ((*dof_lo)->getDofCoeffIdx() >= lo &&
3634 (*dof_lo)->getDofCoeffIdx() <= hi)
3635 marker[(*dof_lo)->getPetscLocalDofIdx()] |= c;
3636 break;
3637 case MarkOP::AND:
3638 for (; dof_lo != dof_hi; ++dof_lo)
3639 if ((*dof_lo)->getDofCoeffIdx() >= lo &&
3640 (*dof_lo)->getDofCoeffIdx() <= hi)
3641 marker[(*dof_lo)->getPetscLocalDofIdx()] &= c;
3642 break;
3643 }
3644
3646}
const double c
speed of light (cm/ns)
static UId getHiBitNumberUId(const FieldBitNumber bit_number)
static UId getLoBitNumberUId(const FieldBitNumber bit_number)

◆ printPartitionedProblem()

MoFEMErrorCode MoFEM::ProblemsManager::printPartitionedProblem ( const Problem * problem_ptr,
int verb = VERBOSE )

Definition at line 2061 of file ProblemsManager.cpp.

2061 {
2062 MoFEM::Interface &m_field = cOre;
2064
2065 if (verb > QUIET) {
2066
2067 MOFEM_LOG("SYNC", Sev::inform)
2068 << problem_ptr->getName() << " Nb. local dof "
2069 << problem_ptr->getNbLocalDofsRow() << " by "
2070 << problem_ptr->getNbLocalDofsCol() << " nb global dofs "
2071 << problem_ptr->getNbDofsRow() << " by " << problem_ptr->getNbDofsCol();
2072
2074 }
2075
2077}
#define MOFEM_LOG_SYNCHRONISE(comm)
Synchronise "SYNC" channel.

◆ query_interface()

MoFEMErrorCode MoFEM::ProblemsManager::query_interface ( boost::typeindex::type_index type_index,
UnknownInterface ** iface ) const
virtual

Implements MoFEM::UnknownInterface.

Definition at line 49 of file ProblemsManager.cpp.

50 {
51 *iface = const_cast<ProblemsManager *>(this);
52 return 0;
53}
ProblemsManager(const MoFEM::Core &core)

◆ removeDofs()

MoFEMErrorCode MoFEM::ProblemsManager::removeDofs ( const std::string problem_name,
RowColData rc,
std::vector< boost::weak_ptr< NumeredDofEntity > > & vec_dof_view,
int verb = VERBOSE,
const bool debug = false )

Remove DOFs from problem on broken space.

Parameters
problem_name
field_name
ents
lo_coeff
hi_coeff
lo_order
hi_order
verb
debug
Returns
MoFEMErrorCode

Definition at line 2719 of file ProblemsManager.cpp.

2722 {
2723
2724 MoFEM::Interface &m_field = cOre;
2726
2727 switch (rc) {
2728 case ROW:
2729 case COL:
2730 break;
2731 default:
2732 SETERRQ(PETSC_COMM_SELF, MOFEM_IMPOSSIBLE_CASE, "Should be row or column");
2733 }
2734
2735 const Problem *prb_ptr;
2736 CHKERR m_field.get_problem(problem_name, &prb_ptr);
2737
2738 decltype(prb_ptr->numeredRowDofsPtr) numered_dofs[2] = {
2739 prb_ptr->numeredRowDofsPtr, nullptr};
2740 if (prb_ptr->numeredRowDofsPtr != prb_ptr->numeredColDofsPtr)
2741 numered_dofs[1] = prb_ptr->numeredColDofsPtr;
2742
2743 int *nbdof_ptr[] = {&prb_ptr->nbDofsRow, &prb_ptr->nbDofsCol};
2744 int *local_nbdof_ptr[] = {&prb_ptr->nbLocDofsRow, &prb_ptr->nbLocDofsCol};
2745 int *ghost_nbdof_ptr[] = {&prb_ptr->nbGhostDofsRow, &prb_ptr->nbGhostDofsCol};
2746
2747 const int nb_init_row_dofs = prb_ptr->getNbDofsRow();
2748 const int nb_init_col_dofs = prb_ptr->getNbDofsCol();
2749 const int nb_init_loc_row_dofs = prb_ptr->getNbLocalDofsRow();
2750 const int nb_init_ghost_row_dofs = prb_ptr->getNbGhostDofsRow();
2751 const int nb_init_ghost_col_dofs = prb_ptr->getNbGhostDofsCol();
2752
2753 if (numered_dofs[rc]) {
2754
2755 if (verb >= NOISY)
2756 MOFEM_LOG_C("SYNC", Sev::noisy,
2757 "Number of DOFs in multi-index %d and to delete %d\n",
2758 numered_dofs[rc]->size(), vec_dof_view.size());
2759
2760 // erase dofs from problem
2761 for (auto weak_dit : vec_dof_view)
2762 if (auto dit = weak_dit.lock()) {
2763 numered_dofs[rc]->erase(dit->getLocalUniqueId());
2764 }
2765
2766 if (verb >= NOISY)
2767 MOFEM_LOG_C("SYNC", Sev::noisy,
2768 "Number of DOFs in multi-index after delete %d\n",
2769 numered_dofs[rc]->size());
2770
2771 // get current number of ghost dofs
2772 int nb_local_dofs = 0;
2773 int nb_ghost_dofs = 0;
2774 for (auto dit = numered_dofs[rc]->get<PetscLocalIdx_mi_tag>().begin();
2775 dit != numered_dofs[rc]->get<PetscLocalIdx_mi_tag>().end(); ++dit) {
2776 if ((*dit)->getPetscLocalDofIdx() >= 0 &&
2777 (*dit)->getPetscLocalDofIdx() < *(local_nbdof_ptr[rc]))
2778 ++nb_local_dofs;
2779 else if ((*dit)->getPetscLocalDofIdx() >= *(local_nbdof_ptr[rc]))
2780 ++nb_ghost_dofs;
2781 else
2782 SETERRQ(PETSC_COMM_SELF, MOFEM_DATA_INCONSISTENCY,
2783 "Impossible case. You could run problem on no distributed "
2784 "mesh. That is not implemented. Dof local index is %d",
2785 (*dit)->getPetscLocalDofIdx());
2786 }
2787
2788 // get indices
2789 auto get_indices_by_tag = [&](auto tag, auto &indices, bool only_local) {
2790 const int nb_dofs = numered_dofs[rc]->size();
2791 indices.clear();
2792 indices.reserve(nb_dofs);
2793 for (auto dit = numered_dofs[rc]->get<decltype(tag)>().begin();
2794 dit != numered_dofs[rc]->get<decltype(tag)>().end(); ++dit) {
2795 bool add = true;
2796 if (only_local) {
2797 if ((*dit)->getPetscLocalDofIdx() < 0 ||
2798 (*dit)->getPetscLocalDofIdx() >= *(local_nbdof_ptr[rc])) {
2799 add = false;
2800 }
2801 }
2802 if (add)
2803 indices.push_back(decltype(tag)::get_index(dit));
2804 }
2805 };
2806
2807 auto get_indices_by_uid = [&](auto tag, auto &indices) {
2808 const int nb_dofs = numered_dofs[rc]->size();
2809 indices.clear();
2810 indices.reserve(nb_dofs);
2811 for (auto dit = numered_dofs[rc]->begin(); dit != numered_dofs[rc]->end();
2812 ++dit)
2813 indices.push_back(decltype(tag)::get_index(dit));
2814 };
2815
2816 auto get_sub_ao = [&](auto sub_data) {
2817 if (rc == 0) {
2818 return sub_data->getSmartRowMap();
2819 } else {
2820 return sub_data->getSmartColMap();
2821 }
2822 };
2823
2824 auto set_sub_is_and_ao = [&rc, &prb_ptr](auto sub_data, auto is, auto ao) {
2825 if (rc == ROW) {
2826 sub_data->rowIs = is;
2827 sub_data->rowMap = ao;
2828 sub_data->colIs = is; // if square problem col is equal to row
2829 sub_data->colMap = ao;
2830 } else {
2831 sub_data->colIs = is;
2832 sub_data->colMap = ao;
2833 }
2834 };
2835
2836 auto apply_symmetry = [&rc, &prb_ptr](auto sub_data) {
2837 if (rc == ROW) {
2838 if (prb_ptr->numeredRowDofsPtr == prb_ptr->numeredColDofsPtr) {
2839 sub_data->colIs = sub_data->getSmartRowIs();
2840 sub_data->colMap = sub_data->getSmartRowMap();
2841 }
2842 }
2843 };
2844
2845 auto concatenate_dofs = [&](auto tag, auto &indices,
2846 const auto local_only) {
2848 get_indices_by_tag(tag, indices, local_only);
2849
2850 SmartPetscObj<AO> ao;
2851 // Create AO from app indices (i.e. old), to pestc indices (new after
2852 // remove)
2853 if (local_only)
2854 ao = createAOMapping(m_field.get_comm(), indices.size(),
2855 &*indices.begin(), PETSC_NULLPTR);
2856 else
2857 ao = createAOMapping(PETSC_COMM_SELF, indices.size(), &*indices.begin(),
2858 PETSC_NULLPTR);
2859
2860 // Set mapping to sub dm data
2861 if (local_only) {
2862 if (auto sub_data = prb_ptr->getSubData()) {
2863 // create is and then map it to main problem of sub-problem
2864 auto sub_is = createISGeneral(m_field.get_comm(), indices.size(),
2865 &*indices.begin(), PETSC_COPY_VALUES);
2866 // get old app, i.e. oroginal befor sub indices, and ao, from app,
2867 // to petsc sub indices.
2868 auto sub_ao = get_sub_ao(sub_data);
2869 CHKERR AOPetscToApplicationIS(sub_ao, sub_is);
2870 sub_ao = createAOMappingIS(sub_is, PETSC_NULLPTR);
2871 // set new sub ao
2872 set_sub_is_and_ao(sub_data, sub_is, sub_ao);
2873 apply_symmetry(sub_data);
2874 } else {
2875 // create sub data
2876 prb_ptr->getSubData() = boost::make_shared<Problem::SubProblemData>();
2877 auto sub_is = createISGeneral(m_field.get_comm(), indices.size(),
2878 &*indices.begin(), PETSC_COPY_VALUES);
2879 // set sub is ao
2880 set_sub_is_and_ao(prb_ptr->getSubData(), sub_is, ao);
2881 apply_symmetry(prb_ptr->getSubData());
2882 }
2883 }
2884
2885 get_indices_by_uid(tag, indices);
2886 CHKERR AOApplicationToPetsc(ao, indices.size(), &*indices.begin());
2887
2889 };
2890
2891 // set indices index
2892 auto set_concatenated_indices = [&]() {
2893 std::vector<int> global_indices;
2894 std::vector<int> local_indices;
2896 CHKERR concatenate_dofs(PetscGlobalIdx_mi_tag(), global_indices, true);
2897 CHKERR concatenate_dofs(PetscLocalIdx_mi_tag(), local_indices, false);
2898 auto gi = global_indices.begin();
2899 auto li = local_indices.begin();
2900 for (auto dit = numered_dofs[rc]->begin(); dit != numered_dofs[rc]->end();
2901 ++dit) {
2902 auto mod = NumeredDofEntity_part_and_all_indices_change(
2903 (*dit)->getPart(), (*dit)->getDofIdx(), *gi, *li);
2904 bool success = numered_dofs[rc]->modify(dit, mod);
2905 if (!success)
2906 SETERRQ(PETSC_COMM_SELF, MOFEM_OPERATION_UNSUCCESSFUL,
2907 "can not set negative indices");
2908 ++gi;
2909 ++li;
2910 }
2912 };
2913 CHKERR set_concatenated_indices();
2914
2915 MPI_Allreduce(&nb_local_dofs, nbdof_ptr[rc], 1, MPI_INT, MPI_SUM,
2916 m_field.get_comm());
2917 *(local_nbdof_ptr[rc]) = nb_local_dofs;
2918 *(ghost_nbdof_ptr[rc]) = nb_ghost_dofs;
2919
2920 if (debug)
2921 for (auto dof : (*numered_dofs[rc])) {
2922 if (dof->getPetscGlobalDofIdx() < 0) {
2923 SETERRQ(m_field.get_comm(), MOFEM_DATA_INCONSISTENCY,
2924 "Negative global idx");
2925 }
2926 if (dof->getPetscLocalDofIdx() < 0) {
2927 SETERRQ(m_field.get_comm(), MOFEM_DATA_INCONSISTENCY,
2928 "Negative local idx");
2929 }
2930 }
2931
2932 } else {
2933
2934 *(nbdof_ptr[1]) = *(nbdof_ptr[0]);
2935 *(local_nbdof_ptr[1]) = *(local_nbdof_ptr[0]);
2936 *(ghost_nbdof_ptr[1]) = *(ghost_nbdof_ptr[0]);
2937 }
2938
2939 if (verb > QUIET) {
2941 "WORLD", Sev::inform,
2942 "Removed DOFs from problem %s dofs [%d / %d (before %d / %d) global]",
2943 prb_ptr->getName().c_str(), prb_ptr->getNbDofsRow(),
2944 prb_ptr->getNbDofsCol(), nb_init_row_dofs, nb_init_col_dofs);
2945 MOFEM_LOG_C("SYNC", Sev::verbose,
2946 "Removed DOFs from problem %s dofs [ %d / %d "
2947 "(before %d / %d) local, %d / %d (before %d / %d)]",
2948 prb_ptr->getName().c_str(), prb_ptr->getNbLocalDofsRow(),
2949 prb_ptr->getNbLocalDofsCol(), nb_init_loc_row_dofs,
2950 nb_init_loc_row_dofs, prb_ptr->getNbGhostDofsRow(),
2951 prb_ptr->getNbGhostDofsCol(), nb_init_ghost_row_dofs,
2952 nb_init_ghost_col_dofs);
2953 MOFEM_LOG_SEVERITY_SYNC(m_field.get_comm(), Sev::verbose);
2954 }
2955
2957}
#define MOFEM_LOG_C(channel, severity, format,...)
@ NOISY
@ MOFEM_OPERATION_UNSUCCESSFUL
Definition definitions.h:34
auto createISGeneral(MPI_Comm comm, PetscInt n, const PetscInt idx[], PetscCopyMode mode)
Creates a data structure for an index set containing a list of integers.
auto createAOMapping(MPI_Comm comm, PetscInt napp, const PetscInt myapp[], const PetscInt mypetsc[])
Creates an application mapping using two integer arrays.
auto createAOMappingIS(IS isapp, IS ispetsc)
Creates an application mapping using two index sets.

◆ removeDofsOnEntitiesNotDistributed() [1/2]

MoFEMErrorCode MoFEM::ProblemsManager::removeDofsOnEntitiesNotDistributed ( const std::string problem_name,
const std::string field_name,
const BitRefLevel bit_ref_level,
const BitRefLevel bit_ref_mask,
Range * ents_ptr = nullptr,
const int lo_coeff = 0,
const int hi_coeff = MAX_DOFS_ON_ENTITY,
const int lo_order = 0,
const int hi_order = 100,
int verb = VERBOSE,
const bool debug = false )

Remove DOFs from problem.

Remove DOFs from problem which are on entities on the given range and given field name. On the finite element level, DOFs can be still accessed however local PETSc indices and global PETSc indices are marked with the index -1.

Note
If the index is marked -1 it is not assembled and dropped by VecSetValues and MatSetValues.
Todo
Not yet implemented update for AO maps and IS ranges if removed entities in composite problem or sub-problem
Parameters
problem_namename of the problem
field_namename of the field
entsentities on which DOFs are removed
lo_coefflow dof coefficient (rank)
hi_coeffhigh dof coefficient (rank)
verbverbosity level
debugto debug and seek for inconsistencies set to true
Returns
MoFEMErrorCode
Note
Use this function for non distributed meshes

Definition at line 3525 of file ProblemsManager.cpp.

3529 {
3530 MoFEM::Interface &m_field = cOre;
3532
3533 auto bit_manager = m_field.getInterface<BitRefManager>();
3534
3535 Range ents;
3536 if (ents_ptr) {
3537 ents = *ents_ptr;
3538 CHKERR bit_manager->filterEntitiesByRefLevel(bit_ref_level, bit_ref_mask,
3539 ents, verb);
3540 } else {
3541 CHKERR bit_manager->getEntitiesByRefLevel(bit_ref_level, bit_ref_mask, ents,
3542 verb);
3543 }
3544
3546 lo_coeff, hi_coeff, lo_order,
3547 hi_order, verb, debug);
3548
3550}
MoFEMErrorCode removeDofsOnEntitiesNotDistributed(const std::string problem_name, const std::string field_name, const Range ents, const int lo_coeff=0, const int hi_coeff=MAX_DOFS_ON_ENTITY, const int lo_order=0, const int hi_order=100, int verb=VERBOSE, const bool debug=false)
Remove DOFs from problem.
MoFEMErrorCode getInterface(IFACE *&iface) const
Get interface reference to pointer of interface.

◆ removeDofsOnEntitiesNotDistributed() [2/2]

MoFEMErrorCode MoFEM::ProblemsManager::removeDofsOnEntitiesNotDistributed ( const std::string problem_name,
const std::string field_name,
const Range ents,
const int lo_coeff = 0,
const int hi_coeff = MAX_DOFS_ON_ENTITY,
const int lo_order = 0,
const int hi_order = 100,
int verb = VERBOSE,
const bool debug = false )

Remove DOFs from problem.

Remove DOFs from problem which are on entities on the given range and given field name. On the finite element level, DOFs can be still accessed however local PETSc indices and global PETSc indices are marked with the index -1.

Note
If the index is marked -1 it is not assembled and dropped by VecSetValues and MatSetValues.
Todo
Not yet implemented update for AO maps and IS ranges if removed entities in composite problem or sub-problem
Parameters
problem_namename of the problem
field_namename of the field
entsentities on which DOFs are removed
lo_coefflow dof coefficient (rank)
hi_coeffhigh dof coefficient (rank)
verbverbosity level
debugto debug and seek for inconsistencies set to true
Returns
MoFEMErrorCode
Note
Use this function for non-distributed meshes
Examples
remove_entities_from_problem_not_partitioned.cpp.

Definition at line 3231 of file ProblemsManager.cpp.

3234 {
3235
3236 MoFEM::Interface &m_field = cOre;
3238
3239 const Problem *prb_ptr;
3240 CHKERR m_field.get_problem(problem_name, &prb_ptr);
3241
3242 decltype(prb_ptr->numeredRowDofsPtr) numered_dofs[2] = {
3243 prb_ptr->numeredRowDofsPtr, nullptr};
3244 if (prb_ptr->numeredRowDofsPtr != prb_ptr->numeredColDofsPtr)
3245 numered_dofs[1] = prb_ptr->numeredColDofsPtr;
3246
3247 int *nbdof_ptr[] = {&prb_ptr->nbDofsRow, &prb_ptr->nbDofsCol};
3248 int *local_nbdof_ptr[] = {&prb_ptr->nbLocDofsRow, &prb_ptr->nbLocDofsCol};
3249 int *ghost_nbdof_ptr[] = {&prb_ptr->nbGhostDofsRow, &prb_ptr->nbGhostDofsCol};
3250
3251 const int nb_init_row_dofs = prb_ptr->getNbDofsRow();
3252 const int nb_init_col_dofs = prb_ptr->getNbDofsCol();
3253 const int nb_init_loc_row_dofs = prb_ptr->getNbLocalDofsRow();
3254 // const int nb_init_loc_col_dofs = prb_ptr->getNbLocalDofsCol();
3255 const int nb_init_ghost_row_dofs = prb_ptr->getNbGhostDofsRow();
3256 const int nb_init_ghost_col_dofs = prb_ptr->getNbGhostDofsCol();
3257
3258 const std::array<int, 2> nb_init_dofs = {nb_init_row_dofs, nb_init_col_dofs};
3259
3260 for (int s = 0; s != 2; ++s)
3261 if (numered_dofs[s]) {
3262
3263 typedef multi_index_container<
3264
3265 NumeredDofEntity_multiIndex::iterator, indexed_by<sequenced<>>
3266
3267 >
3268 NumeredDofEntity_it_view_multiIndex;
3269
3270 const auto bit_number = m_field.get_field_bit_number(field_name);
3271 NumeredDofEntity_it_view_multiIndex dofs_it_view;
3272
3273 // Set -1 to global and local dofs indices
3274 for (auto pit = ents.const_pair_begin(); pit != ents.const_pair_end();
3275 ++pit) {
3276 auto lo = numered_dofs[s]->get<Unique_mi_tag>().lower_bound(
3277 DofEntity::getLoFieldEntityUId(bit_number, pit->first));
3278 auto hi = numered_dofs[s]->get<Unique_mi_tag>().upper_bound(
3279 DofEntity::getHiFieldEntityUId(bit_number, pit->second));
3280
3281 for (; lo != hi; ++lo)
3282 if ((*lo)->getDofCoeffIdx() >= lo_coeff &&
3283 (*lo)->getDofCoeffIdx() <= hi_coeff &&
3284 (*lo)->getDofOrder() >= lo_order &&
3285 (*lo)->getDofOrder() <= hi_order)
3286 dofs_it_view.emplace_back(numered_dofs[s]->project<0>(lo));
3287 }
3288
3289 if (verb > QUIET) {
3290 for (auto &dof : dofs_it_view)
3291 MOFEM_LOG("SYNC", Sev::noisy) << **dof;
3292 }
3293
3294 // set negative index
3295 auto mod = NumeredDofEntity_part_and_all_indices_change(-1, -1, -1, -1);
3296 for (auto dit : dofs_it_view) {
3297 bool success = numered_dofs[s]->modify(dit, mod);
3298 if (!success)
3299 SETERRQ(PETSC_COMM_SELF, MOFEM_OPERATION_UNSUCCESSFUL,
3300 "can not set negative indices");
3301 }
3302
3303 // create weak view
3304 std::vector<boost::weak_ptr<NumeredDofEntity>> dosf_weak_view;
3305 dosf_weak_view.reserve(dofs_it_view.size());
3306 for (auto dit : dofs_it_view)
3307 dosf_weak_view.push_back(*dit);
3308
3309 if (verb >= NOISY)
3310 MOFEM_LOG_C("SYNC", Sev::noisy,
3311 "Number of DOFs in multi-index %d and to delete %d\n",
3312 numered_dofs[s]->size(), dofs_it_view.size());
3313
3314 // erase dofs from problem
3315 for (auto weak_dit : dosf_weak_view)
3316 if (auto dit = weak_dit.lock()) {
3317 numered_dofs[s]->erase(dit->getLocalUniqueId());
3318 }
3319
3320 if (verb >= NOISY)
3321 MOFEM_LOG_C("SYNC", Sev::noisy,
3322 "Number of DOFs in multi-index after delete %d\n",
3323 numered_dofs[s]->size());
3324
3325 // get current number of ghost dofs
3326 int nb_global_dof = 0;
3327 int nb_local_dofs = 0;
3328 int nb_ghost_dofs = 0;
3329
3330 for (auto dit = numered_dofs[s]->begin(); dit != numered_dofs[s]->end();
3331 ++dit) {
3332
3333 if ((*dit)->getDofIdx() >= 0) {
3334
3335 if ((*dit)->getPetscLocalDofIdx() >= 0 &&
3336 (*dit)->getPetscLocalDofIdx() < *(local_nbdof_ptr[s]))
3337 ++nb_local_dofs;
3338 else if ((*dit)->getPetscLocalDofIdx() >= *(local_nbdof_ptr[s]))
3339 ++nb_ghost_dofs;
3340
3341 ++nb_global_dof;
3342 }
3343 }
3344
3345 if (debug) {
3346 MPI_Allreduce(&nb_local_dofs, nbdof_ptr[s], 1, MPI_INT, MPI_SUM,
3347 m_field.get_comm());
3348 if (*(nbdof_ptr[s]) != nb_global_dof)
3349 SETERRQ(PETSC_COMM_SELF, MOFEM_DATA_INCONSISTENCY,
3350 "Number of local DOFs do not add up %d != %d",
3351 *(nbdof_ptr[s]), nb_global_dof);
3352 }
3353
3354 *(nbdof_ptr[s]) = nb_global_dof;
3355 *(local_nbdof_ptr[s]) = nb_local_dofs;
3356 *(ghost_nbdof_ptr[s]) = nb_ghost_dofs;
3357
3358 // get indices
3359 auto get_indices_by_tag = [&](auto tag) {
3360 std::vector<int> indices;
3361 indices.resize(nb_init_dofs[s], -1);
3362 for (auto dit = numered_dofs[s]->get<Idx_mi_tag>().lower_bound(0);
3363 dit != numered_dofs[s]->get<Idx_mi_tag>().end(); ++dit) {
3364 indices[(*dit)->getDofIdx()] = decltype(tag)::get_index(dit);
3365 }
3366 return indices;
3367 };
3368
3369 auto renumber = [&](auto tag, auto &indices) {
3371 int idx = 0;
3372 for (auto dit = numered_dofs[s]->get<decltype(tag)>().lower_bound(0);
3373 dit != numered_dofs[s]->get<decltype(tag)>().end(); ++dit) {
3374 indices[(*dit)->getDofIdx()] = idx++;
3375 }
3377 };
3378
3379 auto get_sub_ao = [&](auto sub_data) {
3380 if (s == 0) {
3381 return sub_data->getSmartRowMap();
3382 } else {
3383 return sub_data->getSmartColMap();
3384 }
3385 };
3386
3387 auto set_sub_is_and_ao = [&s, &prb_ptr](auto sub_data, auto is, auto ao) {
3388 if (s == 0) {
3389 sub_data->rowIs = is;
3390 sub_data->rowMap = ao;
3391 sub_data->colIs = is;
3392 sub_data->colMap = ao;
3393 } else {
3394 sub_data->colIs = is;
3395 sub_data->colMap = ao;
3396 }
3397 };
3398
3399 auto apply_symmetry = [&s, &prb_ptr](auto sub_data) {
3400 if (s == 0) {
3401 if (prb_ptr->numeredRowDofsPtr == prb_ptr->numeredColDofsPtr) {
3402 sub_data->colIs = sub_data->getSmartRowIs();
3403 sub_data->colMap = sub_data->getSmartRowMap();
3404 }
3405 }
3406 };
3407
3408 auto set_sub_data = [&](auto &indices) {
3410 if (auto sub_data = prb_ptr->getSubData()) {
3411 // create is and then map it to main problem of sub-problem
3412 auto sub_is = createISGeneral(m_field.get_comm(), indices.size(),
3413 &*indices.begin(), PETSC_COPY_VALUES);
3414 // get old app, i.e. oroginal befor sub indices, and ao, from
3415 // app, to petsc sub indices.
3416 auto sub_ao = get_sub_ao(sub_data);
3417 CHKERR AOPetscToApplicationIS(sub_ao, sub_is);
3418 sub_ao = createAOMappingIS(sub_is, PETSC_NULLPTR);
3419 // set new sub ao
3420 set_sub_is_and_ao(sub_data, sub_is, sub_ao);
3421 apply_symmetry(sub_data);
3422 } else {
3423 prb_ptr->getSubData() = boost::make_shared<Problem::SubProblemData>();
3424 auto sub_is = createISGeneral(m_field.get_comm(), indices.size(),
3425 &*indices.begin(), PETSC_COPY_VALUES);
3426 auto sub_ao = createAOMappingIS(sub_is, PETSC_NULLPTR);
3427 // set sub is ao
3428 set_sub_is_and_ao(prb_ptr->getSubData(), sub_is, sub_ao);
3429 apply_symmetry(prb_ptr->getSubData());
3430 }
3432 };
3433
3434 auto global_indices = get_indices_by_tag(PetscGlobalIdx_mi_tag());
3435 auto local_indices = get_indices_by_tag(PetscLocalIdx_mi_tag());
3436 CHKERR set_sub_data(global_indices);
3437 CHKERR renumber(PetscGlobalIdx_mi_tag(), global_indices);
3438 CHKERR renumber(PetscLocalIdx_mi_tag(), local_indices);
3439
3440 int i = 0;
3441 for (auto dit = numered_dofs[s]->begin(); dit != numered_dofs[s]->end();
3442 ++dit) {
3443 auto idx = (*dit)->getDofIdx();
3444 if (idx >= 0) {
3445 auto mod = NumeredDofEntity_part_and_all_indices_change(
3446 (*dit)->getPart(), i++, global_indices[idx], local_indices[idx]);
3447 bool success = numered_dofs[s]->modify(dit, mod);
3448 if (!success)
3449 SETERRQ(PETSC_COMM_SELF, MOFEM_OPERATION_UNSUCCESSFUL,
3450 "can not set negative indices");
3451 } else {
3452 auto mod = NumeredDofEntity_part_and_all_indices_change(
3453 (*dit)->getPart(), -1, -1, -1);
3454 bool success = numered_dofs[s]->modify(dit, mod);
3455 if (!success)
3456 SETERRQ(PETSC_COMM_SELF, MOFEM_OPERATION_UNSUCCESSFUL,
3457 "can not set negative indices");
3458 }
3459 };
3460
3461 if (debug) {
3462 for (auto dof : (*numered_dofs[s])) {
3463 if (dof->getDofIdx() >= 0 && dof->getPetscGlobalDofIdx() < 0) {
3464 SETERRQ(PETSC_COMM_SELF, MOFEM_DATA_INCONSISTENCY,
3465 "Negative global idx");
3466 }
3467 }
3468 }
3469
3470 } else {
3471
3472 *(nbdof_ptr[1]) = *(nbdof_ptr[0]);
3473 *(local_nbdof_ptr[1]) = *(local_nbdof_ptr[0]);
3474 *(ghost_nbdof_ptr[1]) = *(ghost_nbdof_ptr[0]);
3475 }
3476
3477 if (verb >= NOISY)
3479
3480 if (verb > QUIET) {
3482 "WORLD", Sev::inform,
3483 "Removed DOFs from problem %s dofs [%d / %d (before %d / %d) global]",
3484 prb_ptr->getName().c_str(), prb_ptr->getNbDofsRow(),
3485 prb_ptr->getNbDofsCol(), nb_init_row_dofs, nb_init_col_dofs);
3486 MOFEM_LOG_C("SYNC", Sev::verbose,
3487 "Removed DOFs from problem %s dofs [ %d / %d "
3488 "(before %d / %d) local, %d / %d (before %d / %d)]",
3489 prb_ptr->getName().c_str(), prb_ptr->getNbLocalDofsRow(),
3490 prb_ptr->getNbLocalDofsCol(), nb_init_loc_row_dofs,
3491 nb_init_loc_row_dofs, prb_ptr->getNbGhostDofsRow(),
3492 prb_ptr->getNbGhostDofsCol(), nb_init_ghost_row_dofs,
3493 nb_init_ghost_col_dofs);
3495 }
3497}

Member Data Documentation

◆ buildProblemFromFields

PetscBool MoFEM::ProblemsManager::buildProblemFromFields

If set to true, problem is build from

Definition at line 30 of file ProblemsManager.hpp.

◆ cOre

MoFEM::Core& MoFEM::ProblemsManager::cOre

Definition at line 26 of file ProblemsManager.hpp.

◆ MOFEM_EVENT_ProblemsManager

PetscLogEvent MoFEM::ProblemsManager::MOFEM_EVENT_ProblemsManager
private

Definition at line 495 of file ProblemsManager.hpp.

◆ synchroniseProblemEntities

PetscBool MoFEM::ProblemsManager::synchroniseProblemEntities

DOFs in fields, not from DOFs on elements.

Definition at line 33 of file ProblemsManager.hpp.


The documentation for this struct was generated from the following files: