v0.8.19
Public Member Functions | Public Attributes | Private Attributes | List of all members
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 Member Functions

MoFEMErrorCode query_interface (const MOFEMuuid &uuid, UnknownInterface **iface) const
 
 ProblemsManager (const MoFEM::Core &core)
 
 ~ProblemsManager ()
 Destructor. More...
 
MoFEMErrorCode getOptions ()
 
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 problemThis will use one of the mesh partitioning programs available from PETSc See http://www.mcs.anl.gov/petsc/petsc-current/docs/manualpages/Mat/MatPartitioningType.html More...
 
MoFEMErrorCode buildProblem (const std::string &name, const bool square_matrix, int verb=VERBOSE)
 build problem data structures More...
 
MoFEMErrorCode buildProblem (Problem *problem_ptr, const bool square_matrix, int verb=VERBOSE)
 build problem data structures More...
 
MoFEMErrorCode buildProblemOnDistributedMesh (const std::string &name, const bool square_matrix, int verb=VERBOSE)
 build problem data structures, assuming that mesh is distributed (collective)Mesh is distributed, that means that each processor keeps only own part of the mesh and shared entities. More...
 
MoFEMErrorCode buildProblemOnDistributedMesh (Problem *problem_ptr, const bool square_matrix=true, int verb=VERBOSE)
 build problem data structures, assuming that mesh is distributed (collective)Mesh is distributed, that means that each processor keeps only own part of the mesh and shared entities. More...
 
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, int verb=VERBOSE)
 build sub problem More...
 
MoFEMErrorCode buildCompsedProblem (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 More...
 
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 More...
 
MoFEMErrorCode partitionSimpleProblem (const std::string &name, int verb=VERBOSE)
 partition problem dofs More...
 
MoFEMErrorCode partitionProblem (const std::string &name, int verb=VERBOSE)
 partition problem dofs (collective) More...
 
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 elementsFunction which partition finite elements based on dofs partitioning.
In addition it sets information about local row and cols dofs at given element on partition. More...
 
MoFEMErrorCode partitionGhostDofs (const std::string &name, int verb=VERBOSE)
 determine ghost nodes More...
 
MoFEMErrorCode partitionGhostDofsOnDistributedMesh (const std::string &name, int verb=VERBOSE)
 determine ghost nodes on distributed meshes More...
 
MoFEMErrorCode getFEMeshset (const std::string &prb_name, const std::string &fe_name, EntityHandle *meshset) const
 
MoFEMErrorCode getProblemElementsLayout (const std::string &name, const std::string &fe_name, PetscLayout *layout) const
 Get layout of elements in the problemIn layout is stored information how many elements is on each processor, for more information look int petsc documentation http://www.mcs.anl.gov/petsc/petsc-current/docs/manualpages/IS/PetscLayoutCreate.html#PetscLayoutCreate More...
 
- Public Member Functions inherited from MoFEM::UnknownInterface
template<class IFACE >
MoFEMErrorCode registerInterface (const MOFEMuuid &uuid, bool error_if_registration_failed=true)
 Register interface. More...
 
template<class IFACE , bool VERIFY = false>
MoFEMErrorCode getInterface (const MOFEMuuid &uuid, IFACE *&iface) const
 Get interface by uuid and return reference to pointer of interface. More...
 
template<class IFACE >
MoFEMErrorCode getInterface (IFACE *&iface) const
 Get interface refernce to pointer of interface. More...
 
template<class IFACE >
MoFEMErrorCode getInterface (IFACE **const iface) const
 Get interface pointer to pointer of interface. More...
 
template<class IFACE , typename boost::enable_if< boost::is_pointer< IFACE >, int >::type = 0>
IFACE getInterface () const
 Get interface pointer to pointer of interface. More...
 
template<class IFACE , typename boost::enable_if< boost::is_reference< IFACE >, int >::type = 0>
IFACE getInterface () const
 Get reference to interface. More...
 
template<class IFACE >
IFACE * getInterface () const
 Function returning pointer to interface. More...
 
virtual ~UnknownInterface ()
 
virtual MoFEMErrorCode getLibVersion (Version &version) const
 Get library version. More...
 
virtual const MoFEMErrorCode getFileVersion (moab::Interface &moab, Version &version) const
 Get database major version. More...
 
virtual MoFEMErrorCode getInterfaceVersion (Version &version) const
 Get database major version. More...
 
template<>
MoFEMErrorCode getInterface (const MOFEMuuid &uuid, UnknownInterface *&iface) const
 

Public Attributes

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

Private Attributes

PetscLogEvent MOFEM_EVENT_ProblemsManager
 

Additional Inherited Members

- Protected Member Functions inherited from MoFEM::UnknownInterface
boost::typeindex::type_index getClassIdx (const MOFEMuuid &uid) const
 Get type name for interface Id. More...
 
MOFEMuuid getUId (const boost::typeindex::type_index &class_idx) const
 Get interface Id for class name. More...
 

Detailed Description

Problem manager is used to build and partition problems .

Examples:
build_problems.cpp, forces_and_sources_testing_edge_element.cpp, forces_and_sources_testing_users_base.cpp, and Remodeling.cpp.

Definition at line 34 of file ProblemsManager.hpp.

Constructor & Destructor Documentation

◆ ProblemsManager()

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

Definition at line 74 of file ProblemsManager.cpp.

75  : cOre(const_cast<MoFEM::Core &>(core)),
76  buildProblemFromFields(PETSC_FALSE),
77  synchroniseProblemEntities(PETSC_FALSE) {
78  PetscLogEventRegister("ProblemsManager", 0, &MOFEM_EVENT_ProblemsManager);
79 }
PetscLogEvent MOFEM_EVENT_ProblemsManager
PetscBool synchroniseProblemEntities
DOFs in fields, not from DOFs on elements.

◆ ~ProblemsManager()

MoFEM::ProblemsManager::~ProblemsManager ( )

Destructor.

Definition at line 80 of file ProblemsManager.cpp.

80 {}

Member Function Documentation

◆ buildCompsedProblem()

MoFEMErrorCode MoFEM::ProblemsManager::buildCompsedProblem ( 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

Parameters
out_namename of build problem
add_row_problemsvector of add row problems
add_col_problemsvector of add col problems
square_matrixtrue if structurally squared matrix
verbverbosity level
Returns
error code

Definition at line 1414 of file ProblemsManager.cpp.

1418  {
1420  SETERRQ(PETSC_COMM_SELF, MOFEM_DATA_INCONSISTENCY, "fields not build");
1421  if (!(cOre.getBuildMoFEM() & Core::BUILD_FE))
1422  SETERRQ(PETSC_COMM_SELF, MOFEM_DATA_INCONSISTENCY, "FEs not build");
1423  if (!(cOre.getBuildMoFEM() & Core::BUILD_ADJ))
1424  SETERRQ(PETSC_COMM_SELF, MOFEM_DATA_INCONSISTENCY, "adjacencies not build");
1425  MoFEM::Interface &m_field = cOre;
1426  const Problem_multiIndex *problems_ptr;
1428 
1429  CHKERR m_field.clear_problem(out_name);
1430  CHKERR m_field.get_problems(&problems_ptr);
1431  // get reference to all problems
1432  typedef Problem_multiIndex::index<Problem_mi_tag>::type ProblemByName;
1433  ProblemByName &problems_by_name =
1434  const_cast<ProblemByName &>(problems_ptr->get<Problem_mi_tag>());
1435 
1436  // Get iterators to out problem, i.e. build problem
1437  ProblemByName::iterator out_problem_it = problems_by_name.find(out_name);
1438  if (out_problem_it == problems_by_name.end()) {
1439  SETERRQ1(PETSC_COMM_SELF, MOFEM_DATA_INCONSISTENCY,
1440  "problem with name < %s > not defined (top tip check spelling)",
1441  out_name.c_str());
1442  }
1443  // Make data structure for composed-problem data
1444  out_problem_it->composedProblemsData =
1445  boost::make_shared<ComposedProblemsData>();
1446  boost::shared_ptr<ComposedProblemsData> cmp_prb_data =
1447  out_problem_it->getComposedProblemsData();
1448 
1449  const std::vector<std::string> *add_prb[] = {&add_row_problems,
1450  &add_col_problems};
1451  std::vector<const Problem *> *add_prb_ptr[] = {&cmp_prb_data->rowProblemsAdd,
1452  &cmp_prb_data->colProblemsAdd};
1453  std::vector<IS> *add_prb_is[] = {&cmp_prb_data->rowIs, &cmp_prb_data->colIs};
1454 
1455  // Get local indices counter
1456  int *nb_local_dofs[] = {&out_problem_it->nbLocDofsRow,
1457  &out_problem_it->nbLocDofsCol};
1458  // Get global indices counter
1459  int *nb_dofs[] = {&out_problem_it->nbDofsRow, &out_problem_it->nbDofsCol};
1460 
1461  // Set number of ghost nodes to zero
1462  {
1463  out_problem_it->nbDofsRow = 0;
1464  out_problem_it->nbDofsCol = 0;
1465  out_problem_it->nbLocDofsRow = 0;
1466  out_problem_it->nbLocDofsCol = 0;
1467  out_problem_it->nbGhostDofsRow = 0;
1468  out_problem_it->nbGhostDofsCol = 0;
1469  }
1470  int nb_dofs_reserve[] = {0, 0};
1471 
1472  // Loop over rows and columns in the main problem and sub-problems
1473  for (int ss = 0; ss != ((square_matrix) ? 1 : 2); ss++) {
1474  // cerr << "SS " << ss << endl;
1475  // cerr << add_prb[ss]->size() << endl;
1476  // cerr << add_prb_ptr[ss]->size() << endl;
1477  add_prb_ptr[ss]->reserve(add_prb[ss]->size());
1478  add_prb_is[ss]->reserve(add_prb[ss]->size());
1479  for (std::vector<std::string>::const_iterator vit = add_prb[ss]->begin();
1480  vit != add_prb[ss]->end(); vit++) {
1481  ProblemByName::iterator prb_it = problems_by_name.find(*vit);
1482  if (prb_it == problems_by_name.end()) {
1483  SETERRQ1(
1484  PETSC_COMM_SELF, MOFEM_DATA_INCONSISTENCY,
1485  "problem with name < %s > not defined (top tip check spelling)",
1486  vit->c_str());
1487  }
1488  add_prb_ptr[ss]->push_back(&*prb_it);
1489  // set number of dofs on rows and columns
1490  if (ss == 0) {
1491  // row
1492  *nb_dofs[ss] += add_prb_ptr[ss]->back()->getNbDofsRow();
1493  *nb_local_dofs[ss] += add_prb_ptr[ss]->back()->getNbLocalDofsRow();
1494  nb_dofs_reserve[ss] += add_prb_ptr[ss]->back()->numeredDofsRows->size();
1495  } else {
1496  // column
1497  *nb_dofs[ss] += add_prb_ptr[ss]->back()->getNbDofsCol();
1498  *nb_local_dofs[ss] += add_prb_ptr[ss]->back()->getNbLocalDofsCol();
1499  nb_dofs_reserve[ss] += add_prb_ptr[ss]->back()->numeredDofsCols->size();
1500  }
1501  }
1502  }
1503  // if squre problem, rows and columns are the same
1504  if (square_matrix) {
1505  add_prb_ptr[1]->reserve(add_prb_ptr[0]->size());
1506  add_prb_is[1]->reserve(add_prb_ptr[0]->size());
1507  out_problem_it->numeredDofsCols = out_problem_it->numeredDofsRows;
1508  *nb_dofs[1] = *nb_dofs[0];
1509  *nb_local_dofs[1] = *nb_local_dofs[0];
1510  }
1511 
1512  // reserve memory for dofs
1513  boost::shared_ptr<std::vector<NumeredDofEntity>> dofs_array[2];
1514  // Reserve memory
1515  for (int ss = 0; ss != ((square_matrix) ? 1 : 2); ss++) {
1516  dofs_array[ss] = boost::make_shared<std::vector<NumeredDofEntity>>();
1517  dofs_array[ss]->reserve(nb_dofs_reserve[ss]);
1518  if (!ss)
1519  out_problem_it->getRowDofsSequence()->emplace_back(dofs_array[ss]);
1520  else
1521  out_problem_it->getColDofsSequence()->emplace_back(dofs_array[ss]);
1522  }
1523 
1524  // Push back DOFs
1525  for (int ss = 0; ss != ((square_matrix) ? 1 : 2); ss++) {
1526  NumeredDofEntity_multiIndex::index<PetscGlobalIdx_mi_tag>::type::iterator
1527  dit,
1528  hi_dit;
1529  int shift_glob = 0;
1530  int shift_loc = 0;
1531  for (unsigned int pp = 0; pp != add_prb_ptr[ss]->size(); pp++) {
1532  PetscInt *dofs_out_idx_ptr;
1533  int nb_local_dofs = (*add_prb_ptr[ss])[pp]->getNbLocalDofsRow();
1534  CHKERR PetscMalloc(nb_local_dofs * sizeof(int), &dofs_out_idx_ptr);
1535  if (ss == 0) {
1536  dit = (*add_prb_ptr[ss])[pp]
1537  ->numeredDofsRows->get<PetscGlobalIdx_mi_tag>()
1538  .begin();
1539  hi_dit = (*add_prb_ptr[ss])[pp]
1540  ->numeredDofsRows->get<PetscGlobalIdx_mi_tag>()
1541  .end();
1542  } else {
1543  dit = (*add_prb_ptr[ss])[pp]
1544  ->numeredDofsCols->get<PetscGlobalIdx_mi_tag>()
1545  .begin();
1546  hi_dit = (*add_prb_ptr[ss])[pp]
1547  ->numeredDofsCols->get<PetscGlobalIdx_mi_tag>()
1548  .end();
1549  }
1550  int is_nb = 0;
1551  for (; dit != hi_dit; dit++) {
1552  BitRefLevel prb_bit = out_problem_it->getBitRefLevel();
1553  BitRefLevel prb_mask = out_problem_it->getMaskBitRefLevel();
1554  BitRefLevel dof_bit = dit->get()->getBitRefLevel();
1555  if ((dof_bit & prb_bit).none() || ((dof_bit & prb_mask) != dof_bit))
1556  continue;
1557  const int rank = m_field.get_comm_rank();
1558  const int part = dit->get()->getPart();
1559  const int glob_idx = shift_glob + dit->get()->getPetscGlobalDofIdx();
1560  const int loc_idx =
1561  (part == rank) ? (shift_loc + dit->get()->getPetscLocalDofIdx())
1562  : -1;
1563  dofs_array[ss]->emplace_back(dit->get()->getDofEntityPtr(), glob_idx,
1564  glob_idx, loc_idx, part);
1565  if (part == rank) {
1566  dofs_out_idx_ptr[is_nb++] = glob_idx;
1567  }
1568  }
1569  if (is_nb > nb_local_dofs) {
1570  SETERRQ(m_field.get_comm(), MOFEM_DATA_INCONSISTENCY,
1571  "Data inconsistency");
1572  }
1573  IS is;
1574  CHKERR ISCreateGeneral(m_field.get_comm(), is_nb, dofs_out_idx_ptr,
1575  PETSC_OWN_POINTER, &is);
1576  (*add_prb_is[ss]).push_back(is);
1577  if (ss == 0) {
1578  shift_glob += (*add_prb_ptr[ss])[pp]->getNbDofsRow();
1579  shift_loc += (*add_prb_ptr[ss])[pp]->getNbLocalDofsRow();
1580  } else {
1581  shift_glob += (*add_prb_ptr[ss])[pp]->getNbDofsCol();
1582  shift_loc += (*add_prb_ptr[ss])[pp]->getNbLocalDofsCol();
1583  }
1584  if (square_matrix) {
1585  (*add_prb_ptr[1]).push_back((*add_prb_ptr[0])[pp]);
1586  (*add_prb_is[1]).push_back(is);
1587  CHKERR PetscObjectReference((PetscObject)is);
1588  }
1589  }
1590  }
1591 
1592  if ((*add_prb_is[1]).size() != (*add_prb_is[0]).size()) {
1593  SETERRQ(m_field.get_comm(), MOFEM_DATA_INCONSISTENCY, "Data inconsistency");
1594  }
1595 
1596  // Insert DOFs to problem multi-index
1597  for (int ss = 0; ss != ((square_matrix) ? 1 : 2); ss++) {
1598  auto hint = (ss == 0) ? out_problem_it->numeredDofsRows->end()
1599  : out_problem_it->numeredDofsCols->end();
1600  for (auto &v : *dofs_array[ss])
1601  hint = (ss == 0) ? out_problem_it->numeredDofsRows->emplace_hint(
1602  hint, dofs_array[ss], &v)
1603  : out_problem_it->numeredDofsCols->emplace_hint(
1604  hint, dofs_array[ss], &v);
1605  }
1606 
1607  // Compress DOFs
1608  *nb_dofs[0] = 0;
1609  *nb_dofs[1] = 0;
1610  *nb_local_dofs[0] = 0;
1611  *nb_local_dofs[1] = 0;
1612  for (int ss = 0; ss != ((square_matrix) ? 1 : 2); ss++) {
1613 
1614  boost::shared_ptr<NumeredDofEntity_multiIndex> dofs_ptr;
1615  if (ss == 0) {
1616  dofs_ptr = out_problem_it->numeredDofsRows;
1617  } else {
1618  dofs_ptr = out_problem_it->numeredDofsCols;
1619  }
1620  NumeredDofEntityByUId::iterator dit, hi_dit;
1621  dit = dofs_ptr->get<Unique_mi_tag>().begin();
1622  hi_dit = dofs_ptr->get<Unique_mi_tag>().end();
1623  std::vector<int> idx;
1624  idx.reserve(std::distance(dit, hi_dit));
1625  // set dofs in order entity and dof number on entity
1626  for (; dit != hi_dit; dit++) {
1627  if (dit->get()->getPart() == (unsigned int)m_field.get_comm_rank()) {
1628  bool success = dofs_ptr->get<Unique_mi_tag>().modify(
1629  dit, NumeredDofEntity_local_idx_change((*nb_local_dofs[ss])++));
1630  if (!success) {
1631  SETERRQ(m_field.get_comm(), MOFEM_OPERATION_UNSUCCESSFUL,
1632  "modification unsuccessful");
1633  }
1634  idx.push_back(dit->get()->getPetscGlobalDofIdx());
1635  } else {
1636  if (dit->get()->getPetscLocalDofIdx() != -1) {
1637  SETERRQ(m_field.get_comm(), MOFEM_DATA_INCONSISTENCY,
1638  "local index should be negative");
1639  }
1640  }
1641  }
1642  if (square_matrix) {
1643  *nb_local_dofs[1] = *nb_local_dofs[0];
1644  }
1645 
1646  // set new dofs mapping
1647  IS is;
1648  CHKERR ISCreateGeneral(m_field.get_comm(), idx.size(), &*idx.begin(),
1649  PETSC_USE_POINTER, &is);
1650  CHKERR ISGetSize(is, nb_dofs[ss]);
1651  if (square_matrix) {
1652  *nb_dofs[1] = *nb_dofs[0];
1653  }
1654  // {
1655  // PetscSynchronizedPrintf(m_field.get_comm(),"nb dofs %d %d
1656  // %d\n",*nb_local_dofs[0],idx.size(),*nb_dofs[0]);
1657  // PetscSynchronizedFlush(m_field.get_comm(),PETSC_STDOUT);
1658  // }
1659  AO ao;
1660  CHKERR AOCreateMappingIS(is, PETSC_NULL, &ao);
1661  for (unsigned int pp = 0; pp != (*add_prb_is[ss]).size(); pp++)
1662  CHKERR AOApplicationToPetscIS(ao, (*add_prb_is[ss])[pp]);
1663 
1664  // Set DOFs numeration
1665  {
1666  std::vector<int> idx_new;
1667  idx_new.reserve(dofs_ptr->size());
1668  for (NumeredDofEntityByUId::iterator dit =
1669  dofs_ptr->get<Unique_mi_tag>().begin();
1670  dit != dofs_ptr->get<Unique_mi_tag>().end(); dit++) {
1671  idx_new.push_back(dit->get()->getPetscGlobalDofIdx());
1672  }
1673  // set new global dofs numeration
1674  IS is_new;
1675  CHKERR ISCreateGeneral(m_field.get_comm(), idx_new.size(),
1676  &*idx_new.begin(), PETSC_USE_POINTER, &is_new);
1677  CHKERR AOApplicationToPetscIS(ao, is_new);
1678  // set global indices to multi-index
1679  std::vector<int>::iterator vit = idx_new.begin();
1680  for (NumeredDofEntityByUId::iterator dit =
1681  dofs_ptr->get<Unique_mi_tag>().begin();
1682  dit != dofs_ptr->get<Unique_mi_tag>().end(); dit++) {
1683  bool success =
1684  dofs_ptr->modify(dit, NumeredDofEntity_part_and_glob_idx_change(
1685  dit->get()->getPart(), *(vit++)));
1686  if (!success) {
1687  SETERRQ(m_field.get_comm(), MOFEM_OPERATION_UNSUCCESSFUL,
1688  "modification unsuccessful");
1689  }
1690  }
1691  CHKERR ISDestroy(&is_new);
1692  }
1693  CHKERR ISDestroy(&is);
1694  CHKERR AODestroy(&ao);
1695  }
1696 
1697  CHKERR printPartitionedProblem(&*out_problem_it, verb);
1698  CHKERR debugPartitionedProblem(&*out_problem_it, verb);
1699 
1700  // Inidcate that porble has been build
1703 
1705 }
virtual MoFEMErrorCode clear_problem(const std::string &name, int verb=DEFAULT_VERBOSITY)=0
clear problem
#define MoFEMFunctionReturn(a)
Last executable line of each PETSc function used for error handling. Replaces return() ...
Definition: definitions.h:475
int & getBuildMoFEM() const
Get flags/semaphores for different stages.
Definition: Core.hpp:179
MoFEMErrorCode debugPartitionedProblem(const Problem *problem_ptr, int verb=VERBOSE)
MoFEMErrorCode printPartitionedProblem(const Problem *problem_ptr, int verb=VERBOSE)
std::bitset< BITREFLEVEL_SIZE > BitRefLevel
Bit structure attached to each entity identifying to what mesh entity is attached.
Definition: Common.hpp:147
virtual int get_comm_rank() const =0
virtual MoFEMErrorCode get_problems(const Problem_multiIndex **problems_ptr) const =0
Get pointer to problems multi-index.
multi_index_container< Problem, indexed_by< ordered_unique< tag< Meshset_mi_tag >, member< Problem, EntityHandle, &Problem::meshset > >, hashed_unique< tag< BitProblemId_mi_tag >, const_mem_fun< Problem, BitProblemId, &Problem::getId >, HashBit< BitProblemId >, EqBit< BitProblemId > >, hashed_unique< tag< Problem_mi_tag >, const_mem_fun< Problem, std::string, &Problem::getName > > > > Problem_multiIndex
MultiIndex for entities for Problem.
#define CHKERR
Inline error check.
Definition: definitions.h:594
#define MoFEMFunctionBegin
First executable line of each MoFEM function, used for error handling. Final line of MoFEM functions ...
Definition: definitions.h:405
virtual MPI_Comm & get_comm() const =0

◆ buildSubProblem()

MoFEMErrorCode MoFEM::ProblemsManager::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,
int  verb = VERBOSE 
)

build sub problem

Parameters
out_nameproblem
fields_rowvector of fields composing problem
fields_colvector of fields composing problem
main_problemmain problem
Returns
error code

Definition at line 1190 of file ProblemsManager.cpp.

1193  {
1194  MoFEM::Interface &m_field = cOre;
1195  const Problem_multiIndex *problems_ptr;
1197 
1198  CHKERR m_field.clear_problem(out_name);
1199  CHKERR m_field.get_problems(&problems_ptr);
1200 
1201  // get reference to all problems
1202  typedef Problem_multiIndex::index<Problem_mi_tag>::type ProblemByName;
1203  ProblemByName &problems_by_name =
1204  const_cast<ProblemByName &>(problems_ptr->get<Problem_mi_tag>());
1205 
1206  // get iterators to out problem, i.e. build problem
1207  ProblemByName::iterator out_problem_it = problems_by_name.find(out_name);
1208  if (out_problem_it == problems_by_name.end()) {
1209  SETERRQ1(PETSC_COMM_SELF, MOFEM_DATA_INCONSISTENCY,
1210  "subproblem with name < %s > not defined (top tip check spelling)",
1211  out_name.c_str());
1212  }
1213  // get iterator to main problem, i.e. out problem is subproblem of main
1214  // problem
1215  ProblemByName::iterator main_problem_it = problems_by_name.find(main_problem);
1216  if (main_problem_it == problems_by_name.end()) {
1217  SETERRQ1(PETSC_COMM_SELF, MOFEM_DATA_INCONSISTENCY,
1218  "problem of subproblem with name < %s > not defined (top tip "
1219  "check spelling)",
1220  main_problem.c_str());
1221  }
1222 
1223  // get dofs for row & columns for out problem,
1224  boost::shared_ptr<NumeredDofEntity_multiIndex> out_problem_dofs[] = {
1225  out_problem_it->numeredDofsRows, out_problem_it->numeredDofsCols};
1226  // get dofs for row & columns for main problem
1227  boost::shared_ptr<NumeredDofEntity_multiIndex> main_problem_dofs[] = {
1228  main_problem_it->numeredDofsRows, main_problem_it->numeredDofsCols};
1229  // get local indices counter
1230  int *nb_local_dofs[] = {&out_problem_it->nbLocDofsRow,
1231  &out_problem_it->nbLocDofsCol};
1232  // get global indices counter
1233  int *nb_dofs[] = {&out_problem_it->nbDofsRow, &out_problem_it->nbDofsCol};
1234 
1235  // set number of ghost nodes to zero
1236  {
1237  out_problem_it->nbGhostDofsRow = 0;
1238  out_problem_it->nbGhostDofsCol = 0;
1239  }
1240 
1241  // put rows & columns field names in array
1242  std::vector<std::string> fields[] = {fields_row, fields_col};
1243 
1244  // make data structure fos sub-problem data
1245  out_problem_it->subProblemData =
1246  boost::make_shared<Problem::SubProblemData>();
1247 
1248  // Loop over rows and columns
1249  for (int ss = 0; ss != (square_matrix ? 1 : 2); ++ss) {
1250 
1251  // reset dofs and columns counters
1252  (*nb_local_dofs[ss]) = 0;
1253  (*nb_dofs[ss]) = 0;
1254  // clear arrays
1255  out_problem_dofs[ss]->clear();
1256 
1257  // If DOFs are cleared clear finite elements too.
1258  out_problem_it->numeredFiniteElements.clear();
1259 
1260  // get dofs by field name and insert them in out problem multi-indices
1261  for (auto field : fields[ss]) {
1262 
1263  // Following reserve memory in sequences, only two allocations are here,
1264  // once for array of objects, next for array of shared pointers
1265 
1266  // aliased sequence of pointer is killed with element
1267  boost::shared_ptr<std::vector<NumeredDofEntity>> dofs_array =
1268  boost::make_shared<std::vector<NumeredDofEntity>>();
1269  // reserve memory for field dofs
1270  if (!ss)
1271  out_problem_it->getRowDofsSequence()->emplace_back(dofs_array);
1272  else
1273  out_problem_it->getColDofsSequence()->emplace_back(dofs_array);
1274 
1275  // create elements objects
1276  auto dit =
1277  main_problem_dofs[ss]->get<FieldName_mi_tag>().lower_bound(field);
1278  auto hi_dit =
1279  main_problem_dofs[ss]->get<FieldName_mi_tag>().upper_bound(field);
1280  dofs_array->reserve(std::distance(dit, hi_dit));
1281  for (; dit != hi_dit; dit++)
1282  dofs_array->emplace_back(
1283  dit->get()->getDofEntityPtr(), dit->get()->getPetscGlobalDofIdx(),
1284  dit->get()->getPetscGlobalDofIdx(),
1285  dit->get()->getPetscLocalDofIdx(), dit->get()->getPart());
1286 
1287  // fill multi-index
1288  auto hint = out_problem_dofs[ss]->end();
1289  for (auto &v : *dofs_array)
1290  hint = out_problem_dofs[ss]->emplace_hint(hint, dofs_array, &v);
1291  }
1292  // Set local indexes
1293  {
1294  auto dit = out_problem_dofs[ss]->get<Idx_mi_tag>().begin();
1295  auto hi_dit = out_problem_dofs[ss]->get<Idx_mi_tag>().end();
1296  for (; dit != hi_dit; dit++) {
1297  int idx = -1; // if dof is not part of partition, set local index to -1
1298  if (dit->get()->getPart() == (unsigned int)m_field.get_comm_rank()) {
1299  idx = (*nb_local_dofs[ss])++;
1300  }
1301  bool success = out_problem_dofs[ss]->modify(
1302  out_problem_dofs[ss]->project<0>(dit),
1303  NumeredDofEntity_local_idx_change(idx));
1304  if (!success) {
1305  SETERRQ(PETSC_COMM_WORLD, MOFEM_ATOM_TEST_INVALID,
1306  "operation unsuccessful");
1307  }
1308  };
1309  }
1310  // Set global indexes, compress global indices
1311  {
1312  auto dit =
1313  out_problem_dofs[ss]->get<PetscLocalIdx_mi_tag>().lower_bound(0);
1314  auto hi_dit =
1315  out_problem_dofs[ss]->get<PetscLocalIdx_mi_tag>().upper_bound(
1316  out_problem_dofs[ss]->size());
1317  const int nb = std::distance(dit, hi_dit);
1318  // get main problem global indices
1319  std::vector<int> main_indices(nb);
1320  for (auto it = main_indices.begin(); dit != hi_dit; dit++, it++) {
1321  *it = dit->get()->getPetscGlobalDofIdx();
1322  }
1323  // create is with global dofs
1324  IS is;
1325  CHKERR ISCreateGeneral(m_field.get_comm(), nb, &*main_indices.begin(),
1326  PETSC_USE_POINTER, &is);
1327  // create map form main problem global indices to out problem global
1328  // indices
1329  AO ao;
1330  CHKERR AOCreateMappingIS(is, PETSC_NULL, &ao);
1331  if (ss == 0) {
1332  CHKERR ISDuplicate(is, &(out_problem_it->getSubData()->rowIs));
1333  // CHKERR ISSort(out_problem_it->getSubData()->rowIs);
1334  out_problem_it->getSubData()->rowMap = ao;
1335  CHKERR PetscObjectReference((PetscObject)ao);
1336  } else {
1337  CHKERR ISDuplicate(is, &(out_problem_it->getSubData()->colIs));
1338  // CHKERR ISSort(out_problem_it->getSubData()->colIs);
1339  out_problem_it->getSubData()->colMap = ao;
1340  CHKERR PetscObjectReference((PetscObject)ao);
1341  }
1342  CHKERR AOApplicationToPetscIS(ao, is);
1343  // set global number of DOFs
1344  CHKERR ISGetSize(is, nb_dofs[ss]);
1345  CHKERR ISDestroy(&is);
1346  // set out problem global indices after applying map
1347  dit = out_problem_dofs[ss]->get<PetscLocalIdx_mi_tag>().lower_bound(0);
1348  for (std::vector<int>::iterator it = main_indices.begin(); dit != hi_dit;
1349  dit++, it++) {
1350  bool success = out_problem_dofs[ss]->modify(
1351  out_problem_dofs[ss]->project<0>(dit),
1352  NumeredDofEntity_part_and_all_indices_change(
1353  dit->get()->getPart(), *it, *it,
1354  dit->get()->getPetscLocalDofIdx()));
1355  if (!success) {
1356  SETERRQ(PETSC_COMM_WORLD, MOFEM_ATOM_TEST_INVALID,
1357  "operation unsuccessful");
1358  }
1359  }
1360  // set global indices to nodes not on this part
1361  {
1362  NumeredDofEntityByLocalIdx::iterator dit =
1363  out_problem_dofs[ss]->get<PetscLocalIdx_mi_tag>().lower_bound(-1);
1364  NumeredDofEntityByLocalIdx::iterator hi_dit =
1365  out_problem_dofs[ss]->get<PetscLocalIdx_mi_tag>().upper_bound(-1);
1366  const int nb = std::distance(dit, hi_dit);
1367  std::vector<int> main_indices_non_local(nb);
1368  for (auto it = main_indices_non_local.begin(); dit != hi_dit;
1369  dit++, it++) {
1370  *it = dit->get()->getPetscGlobalDofIdx();
1371  }
1372  IS is;
1373  CHKERR ISCreateGeneral(m_field.get_comm(), nb,
1374  &*main_indices_non_local.begin(),
1375  PETSC_USE_POINTER, &is);
1376  CHKERR AOApplicationToPetscIS(ao, is);
1377  CHKERR ISDestroy(&is);
1378  dit = out_problem_dofs[ss]->get<PetscLocalIdx_mi_tag>().lower_bound(-1);
1379  for (auto it = main_indices_non_local.begin(); dit != hi_dit;
1380  dit++, it++) {
1381  bool success = out_problem_dofs[ss]->modify(
1382  out_problem_dofs[ss]->project<0>(dit),
1383  NumeredDofEntity_part_and_all_indices_change(
1384  dit->get()->getPart(), dit->get()->getDofIdx(), *it,
1385  dit->get()->getPetscLocalDofIdx()));
1386  if (!success) {
1387  SETERRQ(PETSC_COMM_WORLD, MOFEM_ATOM_TEST_INVALID,
1388  "operation unsuccessful");
1389  }
1390  }
1391  }
1392  CHKERR AODestroy(&ao);
1393  }
1394  }
1395 
1396  if (square_matrix) {
1397  out_problem_it->numeredDofsCols = out_problem_it->numeredDofsRows;
1398  out_problem_it->nbLocDofsCol = out_problem_it->nbLocDofsRow;
1399  out_problem_it->nbDofsCol = out_problem_it->nbDofsRow;
1400  out_problem_it->getSubData()->colIs = out_problem_it->getSubData()->rowIs;
1401  out_problem_it->getSubData()->colMap = out_problem_it->getSubData()->rowMap;
1402  CHKERR PetscObjectReference(
1403  (PetscObject)out_problem_it->getSubData()->rowIs);
1404  CHKERR PetscObjectReference(
1405  (PetscObject)out_problem_it->getSubData()->rowMap);
1406  }
1407 
1408  CHKERR printPartitionedProblem(&*out_problem_it, verb);
1409  CHKERR debugPartitionedProblem(&*out_problem_it, verb);
1410 
1412 }
virtual MoFEMErrorCode clear_problem(const std::string &name, int verb=DEFAULT_VERBOSITY)=0
clear problem
#define MoFEMFunctionReturn(a)
Last executable line of each PETSc function used for error handling. Replaces return() ...
Definition: definitions.h:475
MoFEMErrorCode debugPartitionedProblem(const Problem *problem_ptr, int verb=VERBOSE)
MoFEMErrorCode printPartitionedProblem(const Problem *problem_ptr, int verb=VERBOSE)
virtual int get_comm_rank() const =0
virtual MoFEMErrorCode get_problems(const Problem_multiIndex **problems_ptr) const =0
Get pointer to problems multi-index.
multi_index_container< Problem, indexed_by< ordered_unique< tag< Meshset_mi_tag >, member< Problem, EntityHandle, &Problem::meshset > >, hashed_unique< tag< BitProblemId_mi_tag >, const_mem_fun< Problem, BitProblemId, &Problem::getId >, HashBit< BitProblemId >, EqBit< BitProblemId > >, hashed_unique< tag< Problem_mi_tag >, const_mem_fun< Problem, std::string, &Problem::getName > > > > Problem_multiIndex
MultiIndex for entities for Problem.
#define CHKERR
Inline error check.
Definition: definitions.h:594
#define MoFEMFunctionBegin
First executable line of each MoFEM function, used for error handling. Final line of MoFEM functions ...
Definition: definitions.h:405
virtual MPI_Comm & get_comm() const =0

◆ debugPartitionedProblem()

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

Definition at line 2258 of file ProblemsManager.cpp.

2258  {
2259  MoFEM::Interface &m_field = cOre;
2261  if (debug > 0) {
2262 
2263  typedef NumeredDofEntity_multiIndex::index<Idx_mi_tag>::type
2264  NumeredDofEntitysByIdx;
2265  NumeredDofEntitysByIdx::iterator dit, hi_dit;
2266  const NumeredDofEntitysByIdx *numered_dofs_ptr[] = {
2267  &(problem_ptr->numeredDofsRows->get<Idx_mi_tag>()),
2268  &(problem_ptr->numeredDofsCols->get<Idx_mi_tag>())};
2269 
2270  int *nbdof_ptr[] = {&problem_ptr->nbDofsRow, &problem_ptr->nbDofsCol};
2271  int *local_nbdof_ptr[] = {&problem_ptr->nbLocDofsRow,
2272  &problem_ptr->nbLocDofsCol};
2273 
2274  for (int ss = 0; ss < 2; ss++) {
2275 
2276  dit = numered_dofs_ptr[ss]->begin();
2277  hi_dit = numered_dofs_ptr[ss]->end();
2278  for (; dit != hi_dit; dit++) {
2279  if ((*dit)->getPart() == (unsigned int)m_field.get_comm_rank()) {
2280  if ((*dit)->getPetscLocalDofIdx() < 0) {
2281  std::ostringstream zz;
2282  zz << "rank " << m_field.get_comm_rank() << " " << **dit;
2283  SETERRQ2(PETSC_COMM_SELF, MOFEM_IMPOSIBLE_CASE,
2284  "local dof index for %d (0-row, 1-col) not set, i.e. has "
2285  "negative value\n %s",
2286  ss, zz.str().c_str());
2287  }
2288  if ((*dit)->getPetscLocalDofIdx() >= *local_nbdof_ptr[ss]) {
2289  std::ostringstream zz;
2290  zz << "rank " << m_field.get_comm_rank() << " " << **dit;
2291  SETERRQ2(PETSC_COMM_SELF, MOFEM_IMPOSIBLE_CASE,
2292  "local dofs for %d (0-row, 1-col) out of range\n %s", ss,
2293  zz.str().c_str());
2294  }
2295  } else {
2296  if ((*dit)->getPetscGlobalDofIdx() < 0) {
2297  std::ostringstream zz;
2298  zz << "rank " << m_field.get_comm_rank() << " "
2299  << dit->get()->getBitRefLevel() << " " << **dit;
2300  SETERRQ2(PETSC_COMM_SELF, MOFEM_IMPOSIBLE_CASE,
2301  "global dof index for %d (0-row, 1-col) row not set, i.e. "
2302  "has negative value\n %s",
2303  ss, zz.str().c_str());
2304  }
2305  if ((*dit)->getPetscGlobalDofIdx() >= *nbdof_ptr[ss]) {
2306  std::ostringstream zz;
2307  zz << "rank " << m_field.get_comm_rank() << " nb_dofs "
2308  << *nbdof_ptr[ss] << " " << **dit;
2309  SETERRQ2(PETSC_COMM_SELF, MOFEM_IMPOSIBLE_CASE,
2310  "global dofs for %d (0-row, 1-col) out of range\n %s", ss,
2311  zz.str().c_str());
2312  }
2313  }
2314  }
2315  }
2316  }
2318 }
#define MoFEMFunctionBeginHot
First executable line of each MoFEM function, used for error handling. Final line of MoFEM functions ...
Definition: definitions.h:499
#define MoFEMFunctionReturnHot(a)
Last executable line of each PETSc function used for error handling. Replaces return() ...
Definition: definitions.h:506
virtual int get_comm_rank() const =0
static const bool debug

◆ getFEMeshset()

MoFEMErrorCode MoFEM::ProblemsManager::getFEMeshset ( const std::string &  prb_name,
const std::string &  fe_name,
EntityHandle meshset 
) const

meshset problem finite elements

Definition at line 2785 of file ProblemsManager.cpp.

2787  {
2788  MoFEM::Interface &m_field = cOre;
2789  const Problem *problem_ptr;
2791  CHKERR m_field.get_moab().create_meshset(MESHSET_SET, *meshset);
2792  CHKERR m_field.get_problem(prb_name, &problem_ptr);
2793  auto fit = problem_ptr->numeredFiniteElements.get<FiniteElement_name_mi_tag>()
2794  .lower_bound(fe_name);
2795  auto hi_fe_it =
2796  problem_ptr->numeredFiniteElements.get<FiniteElement_name_mi_tag>()
2797  .upper_bound(fe_name);
2798  std::vector<EntityHandle> fe_vec;
2799  fe_vec.reserve(std::distance(fit, hi_fe_it));
2800  for (; fit != hi_fe_it; fit++)
2801  fe_vec.push_back(fit->get()->getEnt());
2802  rval = m_field.get_moab().add_entities(*meshset, &*fe_vec.begin(),
2803  fe_vec.size());
2805 }
virtual moab::Interface & get_moab()=0
#define MoFEMFunctionReturn(a)
Last executable line of each PETSc function used for error handling. Replaces return() ...
Definition: definitions.h:475
static MoFEMErrorCodeGeneric< moab::ErrorCode > rval
Definition: Common.hpp:78
virtual MoFEMErrorCode get_problem(const std::string &problem_name, const Problem **problem_ptr) const =0
Get problem database (data structure)
#define CHKERR
Inline error check.
Definition: definitions.h:594
#define MoFEMFunctionBegin
First executable line of each MoFEM function, used for error handling. Final line of MoFEM functions ...
Definition: definitions.h:405

◆ getOptions()

MoFEMErrorCode MoFEM::ProblemsManager::getOptions ( )

Definition at line 82 of file ProblemsManager.cpp.

82  {
83  MoFEM::Interface &m_field = cOre;
85  CHKERR PetscOptionsBegin(m_field.get_comm(), "", "Problem manager", "none");
86  {
87  CHKERR PetscOptionsBool(
88  "-problem_build_from_fields",
89  "Add DOFs to problem directly from fields not through DOFs on elements",
91  }
92  ierr = PetscOptionsEnd();
93  CHKERRG(ierr);
95 }
#define MoFEMFunctionBeginHot
First executable line of each MoFEM function, used for error handling. Final line of MoFEM functions ...
Definition: definitions.h:499
#define CHKERRG(n)
Check error code of MoFEM/MOAB/PETSc function.
Definition: definitions.h:542
#define MoFEMFunctionReturnHot(a)
Last executable line of each PETSc function used for error handling. Replaces return() ...
Definition: definitions.h:506
static MoFEMErrorCodeGeneric< PetscErrorCode > ierr
Definition: Common.hpp:80
#define CHKERR
Inline error check.
Definition: definitions.h:594
virtual MPI_Comm & get_comm() const =0

◆ printPartitionedProblem()

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

Definition at line 2214 of file ProblemsManager.cpp.

2214  {
2215  MoFEM::Interface &m_field = cOre;
2217  if (verb > 0) {
2218  std::ostringstream ss;
2219  ss << "partition_problem: rank = " << m_field.get_comm_rank()
2220  << " FEs row ghost dofs " << *problem_ptr << " Nb. local dof "
2221  << problem_ptr->getNbLocalDofsRow() << " nb global row dofs "
2222  << problem_ptr->getNbDofsRow() << std::endl;
2223  ss << "partition_problem: rank = " << m_field.get_comm_rank()
2224  << " FEs col ghost dofs " << *problem_ptr << " Nb. local dof "
2225  << problem_ptr->getNbLocalDofsCol() << " nb global col dofs "
2226  << problem_ptr->getNbDofsCol() << std::endl;
2227  PetscSynchronizedPrintf(m_field.get_comm(), ss.str().c_str());
2228  PetscSynchronizedFlush(m_field.get_comm(), PETSC_STDOUT);
2229  }
2230  if (verb > 1) {
2231  // FIXME mess if printed on more than one processors
2232  // std::ostringstream ss;
2233  std::cout << "rank = " << m_field.get_comm_rank() << " FEs row dofs "
2234  << *problem_ptr << " Nb. row dof " << problem_ptr->getNbDofsRow()
2235  << " Nb. local dof " << problem_ptr->getNbLocalDofsRow()
2236  << std::endl;
2237  NumeredDofEntity_multiIndex::iterator miit_dd_row =
2238  problem_ptr->numeredDofsRows->begin();
2239  for (; miit_dd_row != problem_ptr->numeredDofsRows->end(); miit_dd_row++) {
2240  std::cout << **miit_dd_row << std::endl;
2241  }
2242  std::cout << "rank = " << m_field.get_comm_rank() << " FEs col dofs "
2243  << *problem_ptr << " Nb. col dof " << problem_ptr->getNbDofsCol()
2244  << " Nb. local dof " << problem_ptr->getNbLocalDofsCol()
2245  << std::endl;
2246  NumeredDofEntity_multiIndex::iterator miit_dd_col =
2247  problem_ptr->numeredDofsCols->begin();
2248  for (; miit_dd_col != problem_ptr->numeredDofsCols->end(); miit_dd_col++) {
2249  std::cout << **miit_dd_col << std::endl;
2250  }
2251  // PetscSynchronizedPrintf(comm,ss.str().c_str());
2252  // PetscSynchronizedFlush(comm,PETSC_STDOUT);
2253  }
2255 }
#define MoFEMFunctionBeginHot
First executable line of each MoFEM function, used for error handling. Final line of MoFEM functions ...
Definition: definitions.h:499
#define MoFEMFunctionReturnHot(a)
Last executable line of each PETSc function used for error handling. Replaces return() ...
Definition: definitions.h:506
virtual int get_comm_rank() const =0
virtual MPI_Comm & get_comm() const =0

◆ query_interface()

MoFEMErrorCode MoFEM::ProblemsManager::query_interface ( const MOFEMuuid uuid,
UnknownInterface **  iface 
) const
virtual

Implements MoFEM::UnknownInterface.

Definition at line 62 of file ProblemsManager.cpp.

63  {
65  *iface = NULL;
66  if (uuid == IDD_MOFEMProblemsManager) {
67  *iface = const_cast<ProblemsManager *>(this);
69  }
70  SETERRQ(PETSC_COMM_SELF, MOFEM_DATA_INCONSISTENCY, "unknown interface");
72 }
static const MOFEMuuid IDD_MOFEMProblemsManager
#define MoFEMFunctionBeginHot
First executable line of each MoFEM function, used for error handling. Final line of MoFEM functions ...
Definition: definitions.h:499
#define MoFEMFunctionReturnHot(a)
Last executable line of each PETSc function used for error handling. Replaces return() ...
Definition: definitions.h:506
ProblemsManager(const MoFEM::Core &core)

Member Data Documentation

◆ buildProblemFromFields

PetscBool MoFEM::ProblemsManager::buildProblemFromFields

If set to true, problem is build from

Definition at line 47 of file ProblemsManager.hpp.

◆ cOre

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

Definition at line 39 of file ProblemsManager.hpp.

◆ MOFEM_EVENT_ProblemsManager

PetscLogEvent MoFEM::ProblemsManager::MOFEM_EVENT_ProblemsManager
private

Definition at line 289 of file ProblemsManager.hpp.

◆ synchroniseProblemEntities

PetscBool MoFEM::ProblemsManager::synchroniseProblemEntities

DOFs in fields, not from DOFs on elements.

Definition at line 50 of file ProblemsManager.hpp.


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