GetFEM  5.5
getfem_mesh_im.cc
1 /*===========================================================================
2 
3  Copyright (C) 2005-2026 Yves Renard
4 
5  This file is a part of GetFEM
6 
7  GetFEM is free software; you can redistribute it and/or modify it
8  under the terms of the GNU Lesser General Public License as published
9  by the Free Software Foundation; either version 3 of the License, or
10  (at your option) any later version along with the GCC Runtime Library
11  Exception either version 3.1 or (at your option) any later version.
12  This program is distributed in the hope that it will be useful, but
13  WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
14  or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
15  License and GCC Runtime Library Exception for more details.
16  You should have received a copy of the GNU Lesser General Public License
17  along with this program. If not, see https://www.gnu.org/licenses/.
18 
19 ===========================================================================*/
20 
21 #include "getfem/getfem_mesh_im.h"
22 
23 
24 namespace getfem {
25 
26  void mesh_im::update_from_context(void) const {
27  for (dal::bv_visitor i(im_convexes); !i.finished(); ++i) {
28  if (linked_mesh_->convex_index().is_in(i)) {
29  if (v_num_update < linked_mesh_->convex_version_number(i))
30  const_cast<mesh_im *>(this)
31  ->set_integration_method(i, auto_add_elt_pim);
32  }
33  else const_cast<mesh_im *>(this)->set_integration_method(i, 0);
34  }
35  for (dal::bv_visitor i(linked_mesh_->convex_index());
36  !i.finished(); ++i) {
37  if (!im_convexes.is_in(i)
38  && v_num_update < linked_mesh_->convex_version_number(i)) {
39  if (auto_add_elt_pim != 0)
40  const_cast<mesh_im *>(this)
41  ->set_integration_method(i, auto_add_elt_pim);
42  }
43  }
44  v_num_update = v_num = act_counter();
45  }
46 
47 
48  void mesh_im::set_integration_method(size_type cv, pintegration_method pim) {
49  GMM_ASSERT1(linked_mesh_ != 0, "Uninitialized mesh_im");
50  context_check();
51  if (pim == NULL)
52  { if (im_convexes.is_in(cv))
53  { im_convexes.sup(cv); touch(); v_num = act_counter(); } }
54  else if (!im_convexes.is_in(cv) || ims[cv] != pim) {
55  GMM_ASSERT1
56  (pim->type() == IM_NONE ||
57  *key_of_stored_object(basic_structure(linked_mesh_->structure_of_convex(cv)))
58  == *key_of_stored_object(pim->structure()),
59  "Incompatibility between integration method "
60  << getfem::name_of_int_method(pim) << " and mesh element " <<
61  bgeot::name_of_geometric_trans(linked_mesh_->trans_of_convex(cv)));
62  im_convexes.add(cv);
63  ims[cv] = pim;
64  touch(); v_num = act_counter();
65  }
66  }
67 
68  void mesh_im::set_integration_method(const dal::bit_vector &cvs,
69  pintegration_method pim) {
70  for (dal::bv_visitor cv(cvs); !cv.finished(); ++cv)
71  set_integration_method(cv, pim);
72  }
73 
74  void mesh_im::set_integration_method(pintegration_method pim) {
76  set_auto_add(pim);
77  }
78 
79  void mesh_im::set_integration_method(const dal::bit_vector &cvs,
80  dim_type im_degree) {
81  GMM_ASSERT1(im_degree != dim_type(-1), "im_degree==-1");
82  for (dal::bv_visitor cv(cvs); !cv.finished(); ++cv) {
83  pintegration_method pim =
84  getfem::classical_approx_im(linked_mesh().trans_of_convex(cv), im_degree);
85  set_integration_method(cv, pim);
86  }
87  }
88 
89  void mesh_im::set_integration_method(dim_type im_degree) {
90  GMM_ASSERT1(im_degree != dim_type(-1), "im_degree==-1");
91  size_type i = 0;
92  for (dal::bv_visitor cv(linked_mesh().convex_index());
93  !cv.finished(); ++cv, ++i) {
94  pintegration_method pim =
95  getfem::classical_approx_im(linked_mesh().trans_of_convex(cv),
96  im_degree);
97  set_integration_method(cv, pim);
98  if (i == 0)
99  set_auto_add(pim);
100  else {
101  if (pim != auto_add_elt_pim) auto_add_elt_pim = 0;
102  }
103  }
104  }
105 
106  void mesh_im::clear(void) {
107  ims.clear(); im_convexes.clear();
108  touch(); v_num = act_counter();
109  }
110 
111 
112  void mesh_im::init_with_mesh(const mesh &me) {
113  GMM_ASSERT1(linked_mesh_ == 0, "Mesh im already initialized");
114  linked_mesh_ = &me;
115  this->add_dependency(me);
116  auto_add_elt_pim = 0;
117  v_num_update = v_num = act_counter();
118  }
119 
120  mesh_im::mesh_im() {
121  linked_mesh_ = 0; auto_add_elt_pim = 0;
122  is_lower_dim = false;
123  v_num_update = v_num = act_counter();
124  }
125 
126  void mesh_im::copy_from(const mesh_im &mim) {
127  clear_dependencies();
128  linked_mesh_ = 0;
129  init_with_mesh(*(mim.linked_mesh_));
130  is_lower_dim = mim.is_lower_dim;
131  im_convexes = mim.im_convexes;
132  v_num_update = mim.v_num_update;
133  v_num = mim.v_num;
134  ims = mim.ims;
135  auto_add_elt_pim = mim.auto_add_elt_pim;
136  }
137 
138  mesh_im::mesh_im(const mesh_im &mim) : context_dependencies() {
139  linked_mesh_ = 0; copy_from(mim);
140  }
141 
142  mesh_im &mesh_im::operator=(const mesh_im &mim) {
143  copy_from(mim);
144  return *this;
145  }
146 
147  mesh_im::mesh_im(const mesh &me)
148  { linked_mesh_ = 0; init_with_mesh(me); is_lower_dim = false; }
149 
150  mesh_im::~mesh_im() {}
151 
152 
153  void mesh_im::read_from_file(std::istream &ist) {
154  GMM_ASSERT1(linked_mesh_ != 0, "Uninitialized mesh_im");
155  gmm::stream_standard_locale sl(ist);
156  dal::bit_vector npt;
158  std::string tmp;
159  ist.precision(16);
160  clear();
161  ist.seekg(0);ist.clear();
162  bgeot::read_until(ist, "BEGIN MESH_IM");
163 
164  while (true)
165  {
166  ist >> std::ws; bgeot::get_token(ist, tmp);
167  if (bgeot::casecmp(tmp, "END")==0) {
168  break;
169  } else if (bgeot::casecmp(tmp, "CONVEX")==0) {
170  bgeot::get_token(ist, tmp);
171  size_type ic = atoi(tmp.c_str());
172  GMM_ASSERT1(linked_mesh().convex_index().is_in(ic), "Convex " << ic <<
173  " does not exist, are you sure "
174  "that the mesh attached to this object is right one ?");
175 
176  int rgt = bgeot::get_token(ist, tmp);
177  if (rgt != 3) { // for backward compatibility with version 1.7
178  char c; ist.get(c);
179  while (!isspace(c)) { tmp.push_back(c); ist.get(c); }
180  }
181  getfem::pintegration_method pfi = getfem::int_method_descriptor(tmp);
182  GMM_ASSERT1(pfi, "could not create the integration method '"
183  << tmp << "'");
184 
185  set_integration_method(ic, pfi);
186  } else if (tmp.size()) {
187  GMM_ASSERT1(false, "Unexpected token '" << tmp <<
188  "' [pos=" << std::streamoff(ist.tellg()) << "]");
189  } else if (ist.eof()) {
190  GMM_ASSERT1(false, "Unexpected end of stream "
191  << "(missing BEGIN MESH_IM/END MESH_IM ?)");
192  }
193  }
194  }
195 
196  void mesh_im::read_from_file(const std::string &name)
197  {
198  std::ifstream o(name.c_str());
199  GMM_ASSERT1(o, "mesh_im file '" << name << "' does not exist");
200  read_from_file(o);
201  o.close();
202  }
203 
204  void mesh_im::write_to_file(std::ostream &ost) const {
205  context_check();
206  gmm::stream_standard_locale sl(ost);
207  ost << '\n' << "BEGIN MESH_IM" << '\n' << '\n';
208  for (dal::bv_visitor cv(convex_index()); !cv.finished(); ++cv) {
209  ost << " CONVEX " << cv;
210  ost << " \'" << name_of_int_method(int_method_of_element(cv));
211  ost << "\'\n";
212  }
213 
214  ost << "END MESH_IM" << '\n';
215  }
216 
217  void mesh_im::write_to_file(const std::string &name, bool with_mesh) const
218  {
219  std::ofstream o(name.c_str());
220  GMM_ASSERT1(o, "impossible to open file '" << name << "'");
221  o << "% GETFEM MESH_IM FILE " << '\n';
222  o << "% GETFEM VERSION " << GETFEM_VERSION << '\n' << '\n' << '\n';
223  if (with_mesh) linked_mesh().write_to_file(o);
224  write_to_file(o);
225  o.close();
226  }
227 
228  struct dummy_mesh_im_ {
229  mesh_im mim;
230  dummy_mesh_im_() : mim() {}
231  };
232 
235 
236 } /* end of namespace getfem. */
237 
238 
239 
const dal::bit_vector & convex_index() const
Return the list of valid convex IDs.
pconvex_structure structure_of_convex(size_type ic) const
Return the pconvex_structure of the convex ic.
Dynamic Array.
Definition: dal_basic.h:195
void clear(void)
Clear and desallocate all the elements.
Definition: dal_basic.h:303
static T & instance()
Instance from the current thread.
bool context_check() const
return true if update_from_context was called
Describe an integration method linked to a mesh.
void write_to_file(std::ostream &ost) const
Write the mesh_im to a stream.
virtual pintegration_method int_method_of_element(size_type cv) const
return the integration method associated with an element (in no integration is associated,...
void update_from_context(void) const
this function has to be defined and should update the object when the context is modified.
const mesh & linked_mesh() const
Give a reference to the linked mesh of type mesh.
void set_auto_add(pintegration_method pim)
Set the im for automatic addition of element option.
const dal::bit_vector & convex_index(void) const
Get the set of convexes where an integration method has been assigned.
void read_from_file(std::istream &ist)
Read the mesh_im from a stream.
void set_integration_method(size_type cv, pintegration_method pim)
Set the integration method of a convex.
void write_to_file(const std::string &name) const
Write the mesh to a file.
Definition: getfem_mesh.cc:708
gmm::uint64_type convex_version_number(size_type ic) const
return the version number of the convex ic.
Definition: getfem_mesh.h:214
Define the getfem::mesh_im class (integration of getfem::mesh_fem).
std::string name_of_geometric_trans(pgeometric_trans p)
Get the string name of a geometric transformation.
int get_token(std::istream &ist, std::string &st, bool ignore_cr, bool to_up, bool read_un_pm, int *linenb)
Very simple lexical analysis of general interest for reading small languages with a "MATLAB like" syn...
Definition: bgeot_ftool.cc:49
size_t size_type
used as the common size type in the library
Definition: bgeot_poly.h:48
pconvex_structure basic_structure(pconvex_structure cv)
Original structure (if concerned)
GEneric Tool for Finite Element Methods.
std::string name_of_int_method(pintegration_method p)
Get the string name of an integration method .
pintegration_method classical_approx_im(bgeot::pgeometric_trans pgt, dim_type degree)
try to find an approximate integration method for the geometric transformation pgt which is able to i...
const mesh_im & dummy_mesh_im()
Dummy mesh_im for default parameter of functions.
pintegration_method int_method_descriptor(std::string name, bool throw_if_not_found=true)
Get an integration method from its name .