v0.9.1
CoordSystemsManager.cpp
Go to the documentation of this file.
1 /** \file CoordSystemsManager.cpp
2  * \brief Interface managing coordinate systems set to fields
3  *
4  */
5 
6 /*
7  * MoFEM is distributed in the hope that it will be useful, but WITHOUT
8  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
9  * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
10  * License for more details.
11  *
12  * You should have received a copy of the GNU Lesser General Public
13  * License along with MoFEM. If not, see <http://www.gnu.org/licenses/>
14  */
15 
16 /** \file MeshsetsManager.cpp
17  * \brief Interface to manage meshsets which carrying information about boundary
18  * conditions and material blocks
19  *
20  */
21 
22 /**
23  * The MoFEM package is copyrighted by Lukasz Kaczmarczyk.
24  * It can be freely used for educational and research purposes
25  * by other institutions. If you use this softwre pleas cite my work.
26  *
27  * MoFEM is free software: you can redistribute it and/or modify it under
28  * the terms of the GNU Lesser General Public License as published by the
29  * Free Software Foundation, either version 3 of the License, or (at your
30  * option) any later version.
31  *
32  * MoFEM is distributed in the hope that it will be useful, but WITHOUT
33  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
34  * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
35  * License for more details.
36  *
37  * You should have received a copy of the GNU Lesser General Public
38  * License along with MoFEM. If not, see <http://www.gnu.org/licenses/>
39  */
40 
41 namespace MoFEM {
42 
45  UnknownInterface **iface) const {
46 
48  *iface = NULL;
49  if (uuid == IDD_MOFEMMeshsetsManager) {
50  *iface = const_cast<CoordSystemsManager *>(this);
52  }
53  SETERRQ(PETSC_COMM_SELF, MOFEM_DATA_INCONSISTENCY, "unknown interface");
55 }
56 
58  : cOre(const_cast<Core &>(core)) {}
59 
61 
63 
64  Interface &m_field = cOre;
65  moab::Interface &moab = m_field.get_moab();
67  // Coordinate systems
68  const int def_coord_sys_dim[] = {0, 0, 0, 0};
69  CHKERR moab.tag_get_handle("_CoordSysDim", 4, MB_TYPE_INTEGER, th_CoordSysDim,
70  MB_TAG_CREAT | MB_TAG_SPARSE, &def_coord_sys_dim);
71  const int def_val_len = 0;
72  CHKERR moab.tag_get_handle(
73  "_CoordSysName", def_val_len, MB_TYPE_OPAQUE, th_CoordSysName,
74  MB_TAG_CREAT | MB_TAG_BYTES | MB_TAG_VARLEN | MB_TAG_SPARSE, NULL);
76 }
77 
80  coordinateSystems.clear();
82 }
83 
85  Interface &m_field = cOre;
86  moab::Interface &moab = m_field.get_moab();
88 
89  Range meshsets;
90  CHKERR moab.get_entities_by_type(0, MBENTITYSET, meshsets, false);
91 
92  // Iterate all mesh sets to find coordinate system
93  for (auto meshset : meshsets) {
94  const void *cs_name_ptr = nullptr;
95  int cs_name_size = 0;
96  rval = moab.tag_get_by_ptr(th_CoordSysName, &meshset, 1,
97  (const void **)&cs_name_ptr, &cs_name_size);
98  if (rval == MB_SUCCESS && cs_name_size) {
99  std::string cs_name(static_cast<const char *>(cs_name_ptr), cs_name_size);
100 
101  std::array<int, 4> dim;
102  rval = moab.tag_get_data(th_CoordSysDim, &meshset, 1, dim.data());
103  if (rval == MB_SUCCESS && (dim[0] + dim[1] + dim[2] + dim[3]) != 0) {
104 
105  std::pair<CoordSys_multiIndex::iterator, bool> p =
106  coordinateSystems.insert(
107  boost::make_shared<CoordSys>(moab, meshset));
108 
109  if (!p.second) {
110  // Coordinate system is in database. Could be created by another
111  // processor Check consistency of both coordinate systems with the
112  // same name.
113  if (((*p.first)->getDim(0) != dim[0]) ||
114  ((*p.first)->getDim(1) != dim[1]) ||
115  ((*p.first)->getDim(2) != dim[2]) ||
116  ((*p.first)->getDim(3) != dim[3])) {
117  SETERRQ2(PETSC_COMM_SELF, MOFEM_DATA_INCONSISTENCY,
118  "meshset to coord system not inserted "
119  "cs_name %s dim = %d",
120  cs_name.c_str(), dim[0] + dim[1] + dim[2] + dim[3]);
121  } else {
122  // Remove duplicate mesheset
123  CHKERR moab.delete_entities(&meshset, 1);
124  }
125  }
126  }
127  }
128  }
129 
131 }
132 
134  const int cs_dim[], const std::string cs_name, const enum MoFEMTypes bh) {
135 
136  auto check_cs = [&](const std::string cs_name) {
137  auto undefined_cs_it =
138  coordinateSystems.get<CoordSysName_mi_tag>().find(cs_name);
139  if (undefined_cs_it == coordinateSystems.get<CoordSysName_mi_tag>().end())
140  return false;
141  else
142  return true;
143  };
144 
146 
147  if (!check_cs(cs_name)) {
148 
149  Interface &m_field = cOre;
150  moab::Interface &moab = m_field.get_moab();
151  EntityHandle meshset;
152  CHKERR moab.create_meshset(MESHSET_SET | MESHSET_TRACK_OWNER, meshset);
153  CHKERR moab.tag_set_data(th_CoordSysDim, &meshset, 1, cs_dim);
154  void const *cs_name_ptr[] = {cs_name.c_str()};
155  int cs_name_size[1];
156  cs_name_size[0] = cs_name.size();
157  CHKERR moab.tag_set_by_ptr(th_CoordSysName, &meshset, 1, cs_name_ptr,
158  cs_name_size);
159  auto p =
160  coordinateSystems.insert(boost::make_shared<CoordSys>(moab, meshset));
161  if (!p.second)
162  SETERRQ1(PETSC_COMM_SELF, MOFEM_DATA_INCONSISTENCY,
163  "MeshSet to coord system <%s> not inserted", cs_name.c_str());
164 
165  } else if (bh == MF_EXCL)
166 
167  SETERRQ1(PETSC_COMM_SELF, MOFEM_DATA_INCONSISTENCY,
168  "MeshSet to coord system <%s> exist", cs_name.c_str());
169 
170  else {
171 
172  auto cs_ptr = getCoordSysPtr(cs_name);
173  for (auto d : {0, 1, 2, 3})
174  if (cs_ptr->getDim(d) != cs_dim[d])
175  SETERRQ3(PETSC_COMM_SELF, MOFEM_DATA_INCONSISTENCY,
176  "Coord system <%s> has inconsistent dimension %d: %d != %d", d,
177  cs_ptr->getDim(d), cs_dim[d]);
178  }
179 
181 }
182 
185  const std::string cs_name) {
186 
187  Interface &m_field = cOre;
188  const Field_multiIndex *fields_ptr;
190  CHKERR m_field.get_fields(&fields_ptr);
191 
192  // Find field
193  auto field_it = fields_ptr->get<FieldName_mi_tag>().find(field_name);
194  if (field_it == fields_ptr->get<FieldName_mi_tag>().end())
195  SETERRQ1(PETSC_COMM_SELF, MOFEM_DATA_INCONSISTENCY,
196  "Field < %s > not found", field_name.c_str());
197 
198  // Remove field from other coordinate system
199  EntityHandle field_meshest = (*field_it)->getMeshset();
200  for (auto &cs : coordinateSystems)
201  CHKERR m_field.get_moab().remove_entities(cs->getMeshset(), &field_meshest,
202  1);
203 
204  // Find coordinate system
205  auto cs_it = coordinateSystems.get<CoordSysName_mi_tag>().find(cs_name);
206  if (cs_it == coordinateSystems.get<CoordSysName_mi_tag>().end())
207  SETERRQ1(PETSC_COMM_SELF, MOFEM_DATA_INCONSISTENCY,
208  "Coord system < %s > not found", cs_name.c_str());
209 
210  // Add field to coordinate system
211  CHKERR m_field.get_moab().add_entities((*cs_it)->getMeshset(), &field_meshest,
212  1);
213 
214  int dim = 1;
215  for (int alpha = 0; alpha < 4; alpha++) {
216  if ((*cs_it)->getDim(alpha) > 0) {
217  dim *= (*cs_it)->getDim(alpha);
218  }
219  }
220 
221  // Check consistency of field and coordinate system
222  switch ((*field_it)->getSpace()) {
223  case NOSPACE:
224  SETERRQ(PETSC_COMM_SELF, MOFEM_DATA_INCONSISTENCY, "No space given");
225  case H1:
226  if ((*field_it)->getNbOfCoeffs() != dim) {
227  SETERRQ2(PETSC_COMM_SELF, MOFEM_DATA_INCONSISTENCY,
228  "dimension mismatch of field and coordinate system"
229  "cs dim %d field rank %d",
230  dim, (*field_it)->getNbOfCoeffs());
231  }
232  break;
233  case HDIV:
234  case HCURL:
235  if (3 * (*field_it)->getNbOfCoeffs() != dim) {
236  SETERRQ2(PETSC_COMM_SELF, MOFEM_DATA_INCONSISTENCY,
237  "dimension mismatch of field and coordinate system"
238  "cs dim %d field rank %d",
239  dim, (*field_it)->getNbOfCoeffs());
240  }
241  break;
242  case L2:
243  if ((*field_it)->getNbOfCoeffs() != dim) {
244  SETERRQ2(PETSC_COMM_SELF, MOFEM_DATA_INCONSISTENCY,
245  "dimension mismatch of field and coordinate system"
246  "cs dim %d field rank %d",
247  dim, (*field_it)->getNbOfCoeffs());
248  }
249  case NOFIELD:
250  case LASTSPACE:
251  break;
252  default:
253  SETERRQ1(PETSC_COMM_SELF, MOFEM_NOT_IMPLEMENTED,
254  "Not implemented for this space", (*field_it)->getSpace());
255  }
256  bool success = const_cast<Field_multiIndex *>(fields_ptr)
257  ->modify(fields_ptr->project<0>(field_it),
259  if (!success)
260  SETERRQ(PETSC_COMM_SELF, MOFEM_OPERATION_UNSUCCESSFUL,
261  "modification unsuccessful");
262 
264 }
265 
268  boost::shared_ptr<CoordSys> &cs_ptr) {
270  auto cs_it = coordinateSystems.get<Meshset_mi_tag>().find(id);
271  if (cs_it == coordinateSystems.get<Meshset_mi_tag>().end())
272  SETERRQ1(PETSC_COMM_SELF, MOFEM_DATA_INCONSISTENCY,
273  "Unknown Coordinate System ms_id %lu", id);
274  cs_ptr = *cs_it;
276 }
277 
280  boost::shared_ptr<CoordSys> &cs_ptr) {
282  auto cs_it = coordinateSystems.get<CoordSysName_mi_tag>().find(name);
283  if (cs_it == coordinateSystems.get<CoordSysName_mi_tag>().end()) {
284  SETERRQ1(PETSC_COMM_SELF, MOFEM_DATA_INCONSISTENCY,
285  "Unknown Coordinate System <%s>", name.c_str());
286  }
287  cs_ptr = *cs_it;
289 }
290 
291 boost::shared_ptr<CoordSys>
294  auto cs_it = coordinateSystems.get<CoordSysName_mi_tag>().find(name);
295  if (cs_it == coordinateSystems.get<CoordSysName_mi_tag>().end())
296  return boost::shared_ptr<CoordSys>();
297  else
298  return *cs_it;
300 }
301 
302 } // namespace MoFEM
MoFEMErrorCode setFieldCoordinateSystem(const std::string field_name, const std::string cs_name)
Set coordinate system to field.
Deprecated interface functions.
MoFEM interface unique ID.
static const MOFEMuuid IDD_MOFEMMeshsetsManager
field with continuous normal traction
Definition: definitions.h:179
virtual moab::Interface & get_moab()=0
#define MoFEMFunctionBeginHot
First executable line of each MoFEM function, used for error handling. Final line of MoFEM functions ...
Definition: definitions.h:507
scalar or vector of scalars describe (no true field)
Definition: definitions.h:176
base class for all interface classes
#define MoFEMFunctionReturn(a)
Last executable line of each PETSc function used for error handling. Replaces return()
Definition: definitions.h:483
multi_index_container< boost::shared_ptr< Field >, indexed_by< hashed_unique< tag< BitFieldId_mi_tag >, const_mem_fun< Field, const BitFieldId &, &Field::getId >, HashBit< BitFieldId >, EqBit< BitFieldId > >, ordered_unique< tag< Meshset_mi_tag >, member< Field, EntityHandle, &Field::meshSet > >, ordered_unique< tag< FieldName_mi_tag >, const_mem_fun< Field, boost::string_ref, &Field::getNameRef > >, ordered_non_unique< tag< BitFieldId_space_mi_tag >, const_mem_fun< Field, FieldSpace, &Field::getSpace > > > > Field_multiIndex
Field_multiIndex for Field.
Core (interface) class.
Definition: Core.hpp:50
#define MoFEMFunctionReturnHot(a)
Last executable line of each PETSc function used for error handling. Replaces return()
Definition: definitions.h:514
implementation of Data Operators for Forces and Sources
Definition: Common.hpp:21
FieldSpace in [ 0, LASTSPACE )
Definition: definitions.h:181
static MoFEMErrorCodeGeneric< moab::ErrorCode > rval
Definition: Exceptions.hpp:84
const int dim
const Tensor1_Expr< const dTensor0< T, Dim, i >, typename promote< T, double >::V, Dim, i > d(const Tensor0< T * > &a, const Index< i, Dim > index, const Tensor1< int, Dim > &d_ijk, const Tensor1< double, Dim > &d_xyz)
Definition: dTensor0.hpp:27
MoFEMErrorCode getCoordSysPtr(const EntityHandle id, boost::shared_ptr< CoordSys > &cs_ptr)
Get the Coord Sys Ptr object.
MoFEMErrorCode query_interface(const MOFEMuuid &uuid, UnknownInterface **iface) const
MoFEMErrorCode getTags(int verb=-1)
get tags handlers used on meshsets conating information about coordinate systems
CoordSys_multiIndex coordinateSystems
Coordinate systems multi-index.
PetscErrorCode MoFEMErrorCode
MoFEM/PETSc error code.
Definition: Exceptions.hpp:66
MoFEMErrorCode addCoordinateSystem(const int cs_dim[], const std::string name, const enum MoFEMTypes bh=MF_EXCL)
Add coordinate system.
field with continuous tangents
Definition: definitions.h:178
#define CHKERR
Inline error check.
Definition: definitions.h:602
Tag th_CoordSysName
Name of coordinate system.
MultiIndex Tag for field name.
DeprecatedCoreInterface Interface
Definition: Interface.hpp:1788
MoFEMErrorCode clearMap()
clear multi-index container
MoFEMErrorCode initialiseDatabaseFromMesh(int verb=0)
#define MoFEMFunctionBegin
First executable line of each MoFEM function, used for error handling. Final line of MoFEM functions ...
Definition: definitions.h:413
continuous field
Definition: definitions.h:177
virtual MoFEMErrorCode get_fields(const Field_multiIndex **fields_ptr) const =0
Get fields multi-index from database.
CoordSystemsManager(const MoFEM::Core &core)
Set field coordinate system.
MoFEMTypes
Those types control how functions respond on arguments, f.e. error handling.
Definition: definitions.h:189
field with C-1 continuity
Definition: definitions.h:180