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