v0.9.0
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  // loop all meshset 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  SETERRQ2(PETSC_COMM_SELF, MOFEM_DATA_INCONSISTENCY,
111  "meshset to coord system not inserted "
112  "cs_name %s dim = %d",
113  cs_name.c_str(), dim[0] + dim[1] + dim[2] + dim[3]);
114  }
115  }
116  }
117 
119 }
120 
122  const int cs_dim[], const std::string cs_name, const enum MoFEMTypes bh) {
123 
124  auto check_cs = [&](const std::string cs_name) {
125  auto undefined_cs_it =
126  coordinateSystems.get<CoordSysName_mi_tag>().find(cs_name);
127  if (undefined_cs_it == coordinateSystems.get<CoordSysName_mi_tag>().end())
128  return false;
129  else
130  return true;
131  };
132 
134 
135  if (!check_cs(cs_name)) {
136 
137  Interface &m_field = cOre;
138  moab::Interface &moab = m_field.get_moab();
139  EntityHandle meshset;
140  CHKERR moab.create_meshset(MESHSET_SET | MESHSET_TRACK_OWNER, meshset);
141  CHKERR moab.tag_set_data(th_CoordSysDim, &meshset, 1, cs_dim);
142  void const *cs_name_ptr[] = {cs_name.c_str()};
143  int cs_name_size[1];
144  cs_name_size[0] = cs_name.size();
145  CHKERR moab.tag_set_by_ptr(th_CoordSysName, &meshset, 1, cs_name_ptr,
146  cs_name_size);
147  auto p =
148  coordinateSystems.insert(boost::make_shared<CoordSys>(moab, meshset));
149  if (!p.second)
150  SETERRQ1(PETSC_COMM_SELF, MOFEM_DATA_INCONSISTENCY,
151  "MeshSet to coord system <%s> not inserted", cs_name.c_str());
152 
153  } else if (bh == MF_EXCL)
154 
155  SETERRQ1(PETSC_COMM_SELF, MOFEM_DATA_INCONSISTENCY,
156  "MeshSet to coord system <%s> exist", cs_name.c_str());
157 
158  else {
159 
160  auto cs_ptr = getCoordSysPtr(cs_name);
161  for (auto d : {0, 1, 2, 3})
162  if (cs_ptr->getDim(d) != cs_dim[d])
163  SETERRQ3(PETSC_COMM_SELF, MOFEM_DATA_INCONSISTENCY,
164  "Coord system <%s> has inconsistent dimension %d: %d != %d", d,
165  cs_ptr->getDim(d), cs_dim[d]);
166  }
167 
169 }
170 
173  const std::string cs_name) {
174 
175  Interface &m_field = cOre;
176  const Field_multiIndex *fields_ptr;
178  CHKERR m_field.get_fields(&fields_ptr);
179 
180  auto field_it = fields_ptr->get<FieldName_mi_tag>().find(field_name);
181  if (field_it == fields_ptr->get<FieldName_mi_tag>().end())
182  SETERRQ1(PETSC_COMM_SELF, MOFEM_DATA_INCONSISTENCY,
183  "Field < %s > not found", field_name.c_str());
184 
185  auto cs_it = coordinateSystems.get<CoordSysName_mi_tag>().find(cs_name);
186  if (cs_it == coordinateSystems.get<CoordSysName_mi_tag>().end())
187  SETERRQ1(PETSC_COMM_SELF, MOFEM_DATA_INCONSISTENCY,
188  "Coord system < %s > not found", cs_name.c_str());
189 
190  int dim = 1;
191  for (int alpha = 0; alpha < 4; alpha++) {
192  if ((*cs_it)->getDim(alpha) > 0) {
193  dim *= (*cs_it)->getDim(alpha);
194  }
195  }
196 
197  switch ((*field_it)->getSpace()) {
198  case NOSPACE:
199  SETERRQ(PETSC_COMM_SELF, MOFEM_DATA_INCONSISTENCY, "No space given");
200  case H1:
201  if ((*field_it)->getNbOfCoeffs() != dim) {
202  SETERRQ2(PETSC_COMM_SELF, MOFEM_DATA_INCONSISTENCY,
203  "dimension mismatch of field and coordinate system"
204  "cs dim %d field rank %d",
205  dim, (*field_it)->getNbOfCoeffs());
206  }
207  break;
208  case HDIV:
209  case HCURL:
210  if (3 * (*field_it)->getNbOfCoeffs() != dim) {
211  SETERRQ2(PETSC_COMM_SELF, MOFEM_DATA_INCONSISTENCY,
212  "dimension mismatch of field and coordinate system"
213  "cs dim %d field rank %d",
214  dim, (*field_it)->getNbOfCoeffs());
215  }
216  break;
217  case L2:
218  if ((*field_it)->getNbOfCoeffs() != dim) {
219  SETERRQ2(PETSC_COMM_SELF, MOFEM_DATA_INCONSISTENCY,
220  "dimension mismatch of field and coordinate system"
221  "cs dim %d field rank %d",
222  dim, (*field_it)->getNbOfCoeffs());
223  }
224  case NOFIELD:
225  case LASTSPACE:
226  break;
227  default:
228  SETERRQ1(PETSC_COMM_SELF, MOFEM_NOT_IMPLEMENTED,
229  "Not implemented for this space", (*field_it)->getSpace());
230  }
231  bool success = const_cast<Field_multiIndex *>(fields_ptr)
232  ->modify(fields_ptr->project<0>(field_it),
234  if (!success)
235  SETERRQ(PETSC_COMM_SELF, MOFEM_OPERATION_UNSUCCESSFUL,
236  "modification unsuccessful");
237 
239 }
240 
243  boost::shared_ptr<CoordSys> &cs_ptr) {
245  auto cs_it = coordinateSystems.get<Meshset_mi_tag>().find(id);
246  if (cs_it == coordinateSystems.get<Meshset_mi_tag>().end())
247  SETERRQ1(PETSC_COMM_SELF, MOFEM_DATA_INCONSISTENCY,
248  "Unknown Coordinate System ms_id %lu", id);
249  cs_ptr = *cs_it;
251 }
252 
255  boost::shared_ptr<CoordSys> &cs_ptr) {
257  auto cs_it = coordinateSystems.get<CoordSysName_mi_tag>().find(name);
258  if (cs_it == coordinateSystems.get<CoordSysName_mi_tag>().end()) {
259  SETERRQ1(PETSC_COMM_SELF, MOFEM_DATA_INCONSISTENCY,
260  "Unknown Coordinate System <%s>", name.c_str());
261  }
262  cs_ptr = *cs_it;
264 }
265 
266 boost::shared_ptr<CoordSys>
269  auto cs_it = coordinateSystems.get<CoordSysName_mi_tag>().find(name);
270  if (cs_it == coordinateSystems.get<CoordSysName_mi_tag>().end())
271  return boost::shared_ptr<CoordSys>();
272  else
273  return *cs_it;
275 }
276 
277 } // namespace MoFEM
MoFEMErrorCode setFieldCoordinateSystem(const std::string field_name, const std::string cs_name)
Set coordinate system to field.
MoFEM interface unique ID.
static const MOFEMuuid IDD_MOFEMMeshsetsManager
field with continuous normal traction
Definition: definitions.h:173
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:501
scalar or vector of scalars describe (no true field)
Definition: definitions.h:170
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:477
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:508
implementation of Data Operators for Forces and Sources
Definition: Common.hpp:21
FieldSpace in [ 0, LASTSPACE )
Definition: definitions.h:175
static MoFEMErrorCodeGeneric< moab::ErrorCode > rval
Definition: Exceptions.hpp:84
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:172
#define CHKERR
Inline error check.
Definition: definitions.h:596
Tag th_CoordSysName
Name of coordinate system.
MultiIndex Tag for field name.
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:407
continuous field
Definition: definitions.h:171
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:183
field with C-1 continuity
Definition: definitions.h:174