GetFEM  5.4.2
getfem_mat_elem_type.cc
1 /*===========================================================================
2 
3  Copyright (C) 2000-2020 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/dal_singleton.h"
24 #include "getfem/dal_tree_sorted.h"
25 #include "getfem/getfem_mat_elem.h" /* for mat_elem_forget_mat_elem_type */
26 
27 namespace getfem {
28 
29  bool operator < (const constituant &m, const constituant &n) {
30  if (m.t < n.t) return true;
31  if (m.t > n.t) return false;
32  if (m.t == GETFEM_NONLINEAR_) {
33  if (m.nlt < n.nlt) return true;
34  if (n.nlt < m.nlt) return false;
35  if (m.nl_part < n.nl_part) return true;
36  if (m.nl_part > n.nl_part) return false;
37  }
38  if (m.pfi < n.pfi) return true;
39  return false;
40  }
41 
42  bool operator == (const constituant &m, const constituant &n) {
43  if (&m == &n) return true;
44  if (m.t != n.t) return false;
45  if (m.t == GETFEM_NONLINEAR_) {
46  if (m.nlt != n.nlt) return false;
47  if (m.nl_part != n.nl_part) return false;
48  }
49  if (m.pfi == n.pfi) return true;
50  auto pmfi_key = dal::key_of_stored_object(m.pfi);
51  auto pnfi_key = dal::key_of_stored_object(n.pfi);
52  if (*pmfi_key != *pnfi_key) return false;
53 
54  return true;
55  }
56 
57  struct mat_elem_type_key : virtual public dal::static_stored_object_key {
58  const mat_elem_type *pmet;
59  public :
60  bool compare(const static_stored_object_key &oo) const override{
61  auto &o = dynamic_cast<const mat_elem_type_key &>(oo);
62  if (gmm::lexicographical_less<mat_elem_type>()(*pmet, *(o.pmet)) < 0)
63  return true;
64  return false;
65  }
66  bool equal(const static_stored_object_key &oo) const override{
67  auto &o = dynamic_cast<const mat_elem_type_key &>(oo);
68  return *o.pmet == *pmet;
69  }
70  mat_elem_type_key(const mat_elem_type *p) : pmet(p) {}
71  };
72 
73  static pmat_elem_type add_to_met_tab(const mat_elem_type &f) {
74  dal::pstatic_stored_object_key pk = std::make_shared<mat_elem_type_key>(&f);
75  dal::pstatic_stored_object o = dal::search_stored_object(pk);
76  if (o) return std::dynamic_pointer_cast<const mat_elem_type>(o);
77  pmat_elem_type p = std::make_shared<mat_elem_type>(f);
78  pk = std::make_shared<mat_elem_type_key>(p.get());
79  dal::add_stored_object(pk, p, dal::AUTODELETE_STATIC_OBJECT);
80  for (size_type i=0; i < f.size(); ++i) {
81  if (f[i].pfi) dal::add_dependency(p, f[i].pfi);
82  if (f[i].t == GETFEM_NONLINEAR_ && f[i].nl_part==0)
83  f[i].nlt->register_mat_elem(p);
84  }
85  return p;
86  }
87 
88  /* on destruction, all occurences of the nonlinear term are removed
89  from the mat_elem_type cache; */
90  nonlinear_elem_term::~nonlinear_elem_term() {
91  for (std::set<pmat_elem_type>::iterator it=melt_list.begin();
92  it != melt_list.end(); ++it)
94  }
95 
96  pmat_elem_type mat_elem_base(pfem pfi) {
97  mat_elem_type f; f.resize(1); f[0].t = GETFEM_BASE_; f[0].pfi = pfi;
98  f[0].nlt = 0;
99  if (pfi->target_dim() == 1)
100  { f.get_mi().resize(1); f.get_mi()[0] = 1; }
101  else {
102  f.get_mi().resize(2); f.get_mi()[0] = 1;
103  f.get_mi()[1] = pfi->target_dim();
104  }
105  return add_to_met_tab(f);
106  }
107 
108  pmat_elem_type mat_elem_unit_normal(void) {
109  mat_elem_type f; f.resize(1); f[0].t = GETFEM_UNIT_NORMAL_;
110  f[0].pfi = 0; f[0].nlt = 0;
111  f.get_mi().resize(1); f.get_mi()[0] = 1;
112  return add_to_met_tab(f);
113  }
114 
115  pmat_elem_type mat_elem_grad_geotrans(bool inverted) {
116  mat_elem_type f; f.resize(1);
117  f[0].t = (!inverted) ? GETFEM_GRAD_GEOTRANS_ : GETFEM_GRAD_GEOTRANS_INV_;
118  f[0].pfi = 0; f[0].nlt = 0;
119  f.get_mi().resize(2); f.get_mi()[0] = f.get_mi()[1] = 1;
120  return add_to_met_tab(f);
121  }
122 
123  pmat_elem_type mat_elem_grad(pfem pfi) {
124  mat_elem_type f; f.resize(1); f[0].t = GETFEM_GRAD_; f[0].pfi = pfi;
125  f[0].nlt = 0;
126  if (pfi->target_dim() == 1) {
127  f.get_mi().resize(2); f.get_mi()[0] = 1;
128  f.get_mi()[1] = pfi->dim();
129  }
130  else {
131  f.get_mi().resize(3); f.get_mi()[0] = 1;
132  f.get_mi()[1] = pfi->target_dim();
133  f.get_mi()[2] = pfi->dim();
134  }
135  return add_to_met_tab(f);
136  }
137 
138  pmat_elem_type mat_elem_hessian(pfem pfi) {
139  mat_elem_type f; f.resize(1); f[0].t = GETFEM_HESSIAN_; f[0].pfi = pfi;
140  f[0].nlt = 0;
141  if (pfi->target_dim() == 1) {
142  f.get_mi().resize(2); f.get_mi()[0] = 1;
143  f.get_mi()[1] = gmm::sqr(pfi->dim());
144  }
145  else {
146  f.get_mi().resize(3); f.get_mi()[0] = 1;
147  f.get_mi()[1] = pfi->target_dim();
148  f.get_mi()[2] = gmm::sqr(pfi->dim());
149  }
150  return add_to_met_tab(f);
151  }
152 
153  static pmat_elem_type mat_elem_nonlinear_(pnonlinear_elem_term nlt,
154  pfem pfi, unsigned nl_part) {
155  mat_elem_type f; f.resize(1);
156  f[0].t = GETFEM_NONLINEAR_; f[0].nl_part = nl_part;
157  f[0].pfi = pfi;
158  f[0].nlt = nlt;
159  if (nl_part) {
160  f.get_mi().resize(1); f.get_mi()[0] = 1;
161  } else f.get_mi() = nlt->sizes(size_type(-1));
162  pmat_elem_type ret = add_to_met_tab(f);
163  return ret;
164  }
165 
167  std::vector<pfem> pfi) {
168  GMM_ASSERT1(pfi.size() != 0, "mat_elem_nonlinear with no pfem!");
169  pmat_elem_type me = mat_elem_nonlinear_(nlt, pfi[0], 0);
170  for (unsigned i=1; i < pfi.size(); ++i)
171  me = mat_elem_product(mat_elem_nonlinear_(nlt, pfi[i], i),me);
172  return me;
173  }
174 
175  pmat_elem_type mat_elem_product(pmat_elem_type a, pmat_elem_type b) {
176  mat_elem_type f; f.reserve(a->size() + b->size());
177  f.get_mi().reserve(a->get_mi().size() + b->get_mi().size());
178  f.insert(f.end(), (*a).begin(), (*a).end());
179  f.insert(f.end(), (*b).begin(), (*b).end());
180  f.get_mi().insert(f.get_mi().end(), (*a).get_mi().begin(),
181  (*a).get_mi().end());
182  f.get_mi().insert(f.get_mi().end(), (*b).get_mi().begin(),
183  (*b).get_mi().end());
184  return add_to_met_tab(f);
185  }
186 
187  pmat_elem_type mat_elem_empty() {
188  return add_to_met_tab(mat_elem_type());
189  }
190 
191  bgeot::multi_index mat_elem_type::sizes(size_type cv) const {
192  bgeot::multi_index mii = mi;
193  for (size_type i = 0, j = 0; i < size(); ++i, ++j) {
194  switch ((*this)[i].t) {
195  case GETFEM_BASE_ :
196  mii[j] = short_type((*this)[i].pfi->nb_base(cv));
197  if ((*this)[i].pfi->target_dim() != 1) ++j;
198  break;
199  case GETFEM_GRAD_ :
200  mii[j] = short_type((*this)[i].pfi->nb_base(cv)); ++j;
201  if ((*this)[i].pfi->target_dim() != 1) ++j;
202  break;
203  case GETFEM_HESSIAN_ :
204  mii[j] = short_type((*this)[i].pfi->nb_base(cv)); ++j;
205  if ((*this)[i].pfi->target_dim() != 1) ++j;
206  break;
207  case GETFEM_UNIT_NORMAL_ :
208  break;
209  case GETFEM_NONLINEAR_ :
210  if ((*this)[i].nl_part == 0)
211  { j+=(*this)[i].nlt->sizes(size_type(-1)).size(); --j; }
212  break;
213  case GETFEM_GRAD_GEOTRANS_:
214  case GETFEM_GRAD_GEOTRANS_INV_:
215  ++j;
216  break;
217  }
218  }
219  return mii;
220  }
221 
222 } /* end of namespace getfem. */
223 
bgeot::size_type
size_t size_type
used as the common size type in the library
Definition: bgeot_poly.h:49
dal_singleton.h
A simple singleton implementation.
getfem::mat_elem_type
Description of an elementary matrix.
Definition: getfem_mat_elem_type.h:105
getfem_mat_elem.h
elementary computations (used by the generic assembly).
dal::del_stored_object
void del_stored_object(const pstatic_stored_object &o, bool ignore_unstored)
Delete an object and the object which depend on it.
Definition: dal_static_stored_objects.cc:369
getfem::mat_elem_unit_normal
pmat_elem_type mat_elem_unit_normal(void)
Give a pointer to the structure describing the elementary matrix which compute the unit normal on the...
Definition: getfem_mat_elem_type.cc:108
getfem::mat_elem_nonlinear
pmat_elem_type mat_elem_nonlinear(pnonlinear_elem_term, std::vector< pfem > pfi)
Give a pointer to the structure describing the elementary matrix which compute the integral of a nonl...
Definition: getfem_mat_elem_type.cc:166
bgeot::short_type
gmm::uint16_type short_type
used as the common short type integer in the library
Definition: bgeot_config.h:72
dal_tree_sorted.h
a balanced tree stored in a dal::dynamic_array
getfem
GEneric Tool for Finite Element Methods.
Definition: getfem_accumulated_distro.h:46
dal::search_stored_object
pstatic_stored_object search_stored_object(pstatic_stored_object_key k)
Gives a pointer to an object from a key pointer.
Definition: dal_static_stored_objects.cc:177
getfem::mat_elem_hessian
pmat_elem_type mat_elem_hessian(pfem pfi)
Give a pointer to the structure describing the elementary matrix which compute the integral of the he...
Definition: getfem_mat_elem_type.cc:138
getfem::mat_elem_grad
pmat_elem_type mat_elem_grad(pfem pfi)
Give a pointer to the structure describing the elementary matrix which compute the integral of the gr...
Definition: getfem_mat_elem_type.cc:123
dal::exists_stored_object
bool exists_stored_object(pstatic_stored_object o)
Test if an object is stored.
Definition: dal_static_stored_objects.cc:171
getfem::mat_elem_base
pmat_elem_type mat_elem_base(pfem pfi)
Give a pointer to the structure describing the elementary matrix which compute the integral of the ba...
Definition: getfem_mat_elem_type.cc:96
getfem::pfem
std::shared_ptr< const getfem::virtual_fem > pfem
type of pointer on a fem description
Definition: getfem_fem.h:244
getfem::mat_elem_grad_geotrans
pmat_elem_type mat_elem_grad_geotrans(bool inverted)
Return the gradient of the geometrical transformation ("K" in the getfem++ kernel doc....
Definition: getfem_mat_elem_type.cc:115
getfem::mat_elem_product
pmat_elem_type mat_elem_product(pmat_elem_type a, pmat_elem_type b)
Give a pointer to the structure describing the elementary matrix which computes the integral of produ...
Definition: getfem_mat_elem_type.cc:175
dal::add_stored_object
void add_stored_object(pstatic_stored_object_key k, pstatic_stored_object o, permanence perm)
Add an object with two optional dependencies.
Definition: dal_static_stored_objects.cc:284
getfem::nonlinear_elem_term
abstract class for integration of non-linear terms into the mat_elem computations the nonlinear term ...
Definition: getfem_mat_elem_type.h:67
dal::add_dependency
void add_dependency(pstatic_stored_object o1, pstatic_stored_object o2)
Add a dependency, object o1 will depend on object o2.
Definition: dal_static_stored_objects.cc:230
getfem_mat_elem_type.h
Build elementary tensors descriptors, used by generic assembly.