GetFEM++  5.3
getfem_mesh_im.cc
1 /*===========================================================================
2 
3  Copyright (C) 2005-2017 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, write to the Free Software Foundation,
18  Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
19 
20 ===========================================================================*/
21 
22 #include "getfem/getfem_mesh_im.h"
23 
24 
25 namespace getfem {
26 
27  void mesh_im::update_from_context(void) const {
28  for (dal::bv_visitor i(im_convexes); !i.finished(); ++i) {
29  if (linked_mesh_->convex_index().is_in(i)) {
30  if (v_num_update < linked_mesh_->convex_version_number(i))
31  const_cast<mesh_im *>(this)
32  ->set_integration_method(i, auto_add_elt_pim);
33  }
34  else const_cast<mesh_im *>(this)->set_integration_method(i, 0);
35  }
36  for (dal::bv_visitor i(linked_mesh_->convex_index());
37  !i.finished(); ++i) {
38  if (!im_convexes.is_in(i)
39  && v_num_update < linked_mesh_->convex_version_number(i)) {
40  if (auto_add_elt_pim != 0)
41  const_cast<mesh_im *>(this)
42  ->set_integration_method(i, auto_add_elt_pim);
43  }
44  }
45  v_num_update = v_num = act_counter();
46  }
47 
48 
49  void mesh_im::set_integration_method(size_type cv, pintegration_method pim) {
50  GMM_ASSERT1(linked_mesh_ != 0, "Uninitialized mesh_im");
51  context_check();
52  if (pim == NULL)
53  { if (im_convexes.is_in(cv))
54  { im_convexes.sup(cv); touch(); v_num = act_counter(); } }
55  else if (!im_convexes.is_in(cv) || ims[cv] != pim) {
56  GMM_ASSERT1
57  (pim->type() == IM_NONE ||
58  basic_structure(linked_mesh_->structure_of_convex(cv))
59  == pim->structure(),
60  "Incompatibility between integration method "
61  << getfem::name_of_int_method(pim) << " and mesh element " <<
62  bgeot::name_of_geometric_trans(linked_mesh_->trans_of_convex(cv)));
63  im_convexes.add(cv);
64  ims[cv] = pim;
65  touch(); v_num = act_counter();
66  }
67  }
68 
69  void mesh_im::set_integration_method(const dal::bit_vector &cvs,
70  pintegration_method pim) {
71  for (dal::bv_visitor cv(cvs); !cv.finished(); ++cv)
72  set_integration_method(cv, pim);
73  }
74 
75  void mesh_im::set_integration_method(pintegration_method pim) {
77  set_auto_add(pim);
78  }
79 
80  void mesh_im::set_integration_method(const dal::bit_vector &cvs,
81  dim_type im_degree) {
82  GMM_ASSERT1(im_degree != dim_type(-1), "im_degree==-1");
83  for (dal::bv_visitor cv(cvs); !cv.finished(); ++cv) {
84  pintegration_method pim =
85  getfem::classical_approx_im(linked_mesh().trans_of_convex(cv), im_degree);
86  set_integration_method(cv, pim);
87  }
88  }
89 
90  void mesh_im::set_integration_method(dim_type im_degree) {
91  GMM_ASSERT1(im_degree != dim_type(-1), "im_degree==-1");
92  size_type i = 0;
93  for (dal::bv_visitor cv(linked_mesh().convex_index());
94  !cv.finished(); ++cv, ++i) {
95  pintegration_method pim =
96  getfem::classical_approx_im(linked_mesh().trans_of_convex(cv),
97  im_degree);
98  set_integration_method(cv, pim);
99  if (i == 0)
100  set_auto_add(pim);
101  else {
102  if (pim != auto_add_elt_pim) auto_add_elt_pim = 0;
103  }
104  }
105  }
106 
107  void mesh_im::clear(void) {
108  ims.clear(); im_convexes.clear();
109  touch(); v_num = act_counter();
110  }
111 
112 
113  void mesh_im::init_with_mesh(const mesh &me) {
114  GMM_ASSERT1(linked_mesh_ == 0, "Mesh im already initialized");
115  linked_mesh_ = &me;
116  this->add_dependency(me);
117  auto_add_elt_pim = 0;
118  v_num_update = v_num = act_counter();
119  }
120 
121  mesh_im::mesh_im() {
122  linked_mesh_ = 0; auto_add_elt_pim = 0;
123  is_lower_dim = false;
124  v_num_update = v_num = act_counter();
125  }
126 
127  void mesh_im::copy_from(const mesh_im &mim) {
128  clear_dependencies();
129  linked_mesh_ = 0;
130  init_with_mesh(*(mim.linked_mesh_));
131  is_lower_dim = mim.is_lower_dim;
132  im_convexes = mim.im_convexes;
133  v_num_update = mim.v_num_update;
134  v_num = mim.v_num;
135  ims = mim.ims;
136  auto_add_elt_pim = mim.auto_add_elt_pim;
137  }
138 
139  mesh_im::mesh_im(const mesh_im &mim) : context_dependencies() {
140  linked_mesh_ = 0; copy_from(mim);
141  }
142 
143  mesh_im &mesh_im::operator=(const mesh_im &mim) {
144  copy_from(mim);
145  return *this;
146  }
147 
148  mesh_im::mesh_im(const mesh &me)
149  { linked_mesh_ = 0; init_with_mesh(me); is_lower_dim = false; }
150 
151  mesh_im::~mesh_im() {}
152 
153 
154  void mesh_im::read_from_file(std::istream &ist) {
155  GMM_ASSERT1(linked_mesh_ != 0, "Uninitialized mesh_im");
156  gmm::stream_standard_locale sl(ist);
157  dal::bit_vector npt;
159  std::string tmp;
160  ist.precision(16);
161  clear();
162  ist.seekg(0);ist.clear();
163  bgeot::read_until(ist, "BEGIN MESH_IM");
164 
165  while (true)
166  {
167  ist >> std::ws; bgeot::get_token(ist, tmp);
168  if (bgeot::casecmp(tmp, "END")==0) {
169  break;
170  } else if (bgeot::casecmp(tmp, "CONVEX")==0) {
171  bgeot::get_token(ist, tmp);
172  size_type ic = atoi(tmp.c_str());
173  GMM_ASSERT1(linked_mesh().convex_index().is_in(ic), "Convex " << ic <<
174  " does not exist, are you sure "
175  "that the mesh attached to this object is right one ?");
176 
177  int rgt = bgeot::get_token(ist, tmp);
178  if (rgt != 3) { // for backward compatibility with version 1.7
179  char c; ist.get(c);
180  while (!isspace(c)) { tmp.push_back(c); ist.get(c); }
181  }
182  getfem::pintegration_method pfi = getfem::int_method_descriptor(tmp);
183  GMM_ASSERT1(pfi, "could not create the integration method '"
184  << tmp << "'");
185 
186  set_integration_method(ic, pfi);
187  } else if (tmp.size()) {
188  GMM_ASSERT1(false, "Unexpected token '" << tmp <<
189  "' [pos=" << std::streamoff(ist.tellg()) << "]");
190  } else if (ist.eof()) {
191  GMM_ASSERT1(false, "Unexpected end of stream "
192  << "(missing BEGIN MESH_IM/END MESH_IM ?)");
193  }
194  }
195  }
196 
197  void mesh_im::read_from_file(const std::string &name)
198  {
199  std::ifstream o(name.c_str());
200  GMM_ASSERT1(o, "mesh_im file '" << name << "' does not exist");
201  read_from_file(o);
202  o.close();
203  }
204 
205  void mesh_im::write_to_file(std::ostream &ost) const {
206  context_check();
207  gmm::stream_standard_locale sl(ost);
208  ost << '\n' << "BEGIN MESH_IM" << '\n' << '\n';
209  for (dal::bv_visitor cv(convex_index()); !cv.finished(); ++cv) {
210  ost << " CONVEX " << cv;
211  ost << " \'" << name_of_int_method(int_method_of_element(cv));
212  ost << "\'\n";
213  }
214 
215  ost << "END MESH_IM" << '\n';
216  }
217 
218  void mesh_im::write_to_file(const std::string &name, bool with_mesh) const
219  {
220  std::ofstream o(name.c_str());
221  GMM_ASSERT1(o, "impossible to open file '" << name << "'");
222  o << "% GETFEM MESH_IM FILE " << '\n';
223  o << "% GETFEM VERSION " << GETFEM_VERSION << '\n' << '\n' << '\n';
224  if (with_mesh) linked_mesh().write_to_file(o);
225  write_to_file(o);
226  o.close();
227  }
228 
229  struct dummy_mesh_im_ {
230  mesh_im mim;
231  dummy_mesh_im_() : mim() {}
232  };
233 
236 
237 } /* end of namespace getfem. */
238 
239 
240 
void read_from_file(std::istream &ist)
Read the mesh_im from 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, the function will crash! use the convex_index() of the mesh_im to check that a fem is associated to a given convex)
void write_to_file(const std::string &name) const
Write the mesh to a file.
Definition: getfem_mesh.cc:667
const mesh_im & dummy_mesh_im()
Dummy mesh_im for default parameter of functions.
void set_integration_method(size_type cv, pintegration_method pim)
Set the integration method of a convex.
void write_to_file(std::ostream &ost) const
Write the mesh_im to a stream.
Define the getfem::mesh_im class (integration of getfem::mesh_fem).
Describe a mesh (collection of convexes (elements) and points).
Definition: getfem_mesh.h:95
pconvex_structure structure_of_convex(size_type ic) const
Return the pconvex_structure of the convex ic.
pintegration_method int_method_descriptor(std::string name, bool throw_if_not_found=true)
Get an integration method from its name .
Describe an integration method linked to a mesh.
static T & instance()
Instance from the current thread.
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 langages with a "MATLAB like" synt...
Definition: bgeot_ftool.cc:49
size_t size_type
used as the common size type in the library
Definition: bgeot_poly.h:49
void set_auto_add(pintegration_method pim)
Set the im for automatic addition of element option.
Dynamic Array.
Definition: dal_basic.h:47
std::string name_of_int_method(pintegration_method p)
Get the string name of an integration method .
Deal with interdependencies of objects.
GEneric Tool for Finite Element Methods.
std::string name_of_geometric_trans(pgeometric_trans p)
Get the string name of a geometric transformation.
const dal::bit_vector & convex_index(void) const
Get the set of convexes where an integration method has been assigned.
void update_from_context(void) const
this function has to be defined and should update the object when the context is modified.
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...
pconvex_structure basic_structure(pconvex_structure cv)
Original structure (if concerned)
const mesh & linked_mesh() const
Give a reference to the linked mesh of type mesh.
bool context_check() const
return true if update_from_context was called
void clear(void)
Clear and desallocate all the elements.
Definition: dal_basic.h:298
gmm::uint64_type convex_version_number(size_type ic) const
return the version number of the convex ic.
Definition: getfem_mesh.h:215
const dal::bit_vector & convex_index() const
Return the list of valid convex IDs.