GetFEM  5.4.3
getfem_generic_assembly.h
Go to the documentation of this file.
1 /* -*- c++ -*- (enables emacs c++ mode) */
2 /*===========================================================================
3 
4  Copyright (C) 2013-2020 Yves Renard
5 
6  This file is a part of GetFEM
7 
8  GetFEM is free software; you can redistribute it and/or modify it
9  under the terms of the GNU Lesser General Public License as published
10  by the Free Software Foundation; either version 3 of the License, or
11  (at your option) any later version along with the GCC Runtime Library
12  Exception either version 3.1 or (at your option) any later version.
13  This program is distributed in the hope that it will be useful, but
14  WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
15  or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
16  License and GCC Runtime Library Exception for more details.
17  You should have received a copy of the GNU Lesser General Public License
18  along with this program; if not, write to the Free Software Foundation,
19  Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
20 
21  As a special exception, you may use this file as it is a part of a free
22  software library without restriction. Specifically, if other files
23  instantiate templates or use macros or inline functions from this file,
24  or you compile this file and link it with other files to produce an
25  executable, this file does not by itself cause the resulting executable
26  to be covered by the GNU Lesser General Public License. This exception
27  does not however invalidate any other reasons why the executable file
28  might be covered by the GNU Lesser General Public License.
29 
30 ===========================================================================*/
31 
32 /** @file getfem_generic_assembly.h
33  @author Yves Renard <Yves.Renard@insa-lyon.fr>
34  @date November 18, 2013.
35  @brief A language for generic assembly of pde boundary value problems.
36  */
37 
38 
39 #ifndef GETFEM_GENERIC_ASSEMBLY_H__
40 #define GETFEM_GENERIC_ASSEMBLY_H__
41 
42 #include <map>
45 
46 
47 #ifdef _WIN32
48 #include <limits>
49 #if defined(INFINITY)
50 #undef INFINITY
51 #endif
52 #define INFINITY std::numeric_limits<scalar_type>::infinity()
53 #endif
54 
55 namespace getfem {
56 
57  struct ga_tree;
58  class model;
59  class ga_workspace;
60 
61  typedef gmm::rsvector<scalar_type> model_real_sparse_vector;
62  typedef gmm::rsvector<complex_type> model_complex_sparse_vector;
63  typedef std::vector<scalar_type> model_real_plain_vector;
64  typedef std::vector<complex_type> model_complex_plain_vector;
65 
66  typedef gmm::col_matrix<model_real_sparse_vector> model_real_sparse_matrix;
67  typedef gmm::col_matrix<model_complex_sparse_vector>
68  model_complex_sparse_matrix;
69 
70  typedef gmm::row_matrix<model_real_sparse_vector>
71  model_real_row_sparse_matrix;
72  typedef gmm::row_matrix<model_complex_sparse_vector>
73  model_complex_row_sparse_matrix;
74 
75  // 0 : ok
76  // 1 : function or operator name or "X"
77  // 2 : reserved prefix Grad, Hess, Div, Test and Test2
78  int ga_check_name_validity(const std::string &name);
79 
80  //=========================================================================
81  // Virtual interpolate_transformation object.
82  //=========================================================================
83 
84  struct var_trans_pair {
85  std::string varname, transname;
86  bool operator <(const var_trans_pair &vt) const {
87  return (varname < vt.varname) ||
88  (!(varname > vt.varname) && transname < vt.transname);
89  }
90  var_trans_pair() : varname(), transname() {}
91  var_trans_pair(const std::string &v, const std::string &t)
92  : varname(v), transname(t) {}
93  };
94 
95  class APIDECL virtual_interpolate_transformation {
96 
97  public:
98  virtual void extract_variables
99  (const ga_workspace &workspace, std::set<var_trans_pair> &vars,
100  bool ignore_data, const mesh &m,
101  const std::string &interpolate_name) const = 0;
102  virtual void init(const ga_workspace &workspace) const = 0;
103  virtual int transform
104  (const ga_workspace &workspace, const mesh &m,
105  fem_interpolation_context &ctx_x, const base_small_vector &Normal,
106  const mesh **m_t, size_type &cv, short_type &face_num,
107  base_node &P_ref, base_small_vector &N_y,
108  std::map<var_trans_pair, base_tensor> &derivatives,
109  bool compute_derivatives) const = 0;
110  virtual void finalize() const = 0;
111  virtual std::string expression() const { return std::string(); }
112 
113  virtual ~virtual_interpolate_transformation() {}
114  };
115 
116  typedef std::shared_ptr<const virtual_interpolate_transformation>
117  pinterpolate_transformation;
118 
119  //=========================================================================
120  // Virtual elementary_transformation object.
121  //=========================================================================
122 
123  class APIDECL virtual_elementary_transformation {
124 
125  public:
126 
127  virtual void give_transformation(const mesh_fem &mf1, const mesh_fem &mf2,
128  size_type cv, base_matrix &M) const = 0;
129  virtual ~virtual_elementary_transformation() {}
130  };
131 
132  typedef std::shared_ptr<const virtual_elementary_transformation>
133  pelementary_transformation;
134 
135  //=========================================================================
136  // Virtual secondary_domain object.
137  //=========================================================================
138 
139  class APIDECL virtual_secondary_domain {
140  protected:
141  const mesh_im &mim_;
142  const mesh_region region;
143 
144  public:
145 
146  const mesh_im &mim() const { return mim_; }
147  virtual const mesh_region &give_region(const mesh &m,
148  size_type cv, short_type f) const = 0;
149  // virtual void init(const ga_workspace &workspace) const = 0;
150  // virtual void finalize() const = 0;
151 
152  virtual_secondary_domain(const mesh_im &mim__, const mesh_region &region_)
153  : mim_(mim__), region(region_) {}
154  virtual ~virtual_secondary_domain() {}
155  };
156 
157  typedef std::shared_ptr<const virtual_secondary_domain> psecondary_domain;
158 
159  //=========================================================================
160  // Structure dealing with macros.
161  //=========================================================================
162 
163  class ga_macro {
164 
165  protected:
166  ga_tree *ptree;
167  std::string macro_name_;
168  size_type nbp;
169 
170  public:
171  ga_macro();
172  ga_macro(const std::string &name, const ga_tree &t, size_type nbp_);
173  ga_macro(const ga_macro &);
174  ~ga_macro();
175  ga_macro &operator =(const ga_macro &);
176 
177  const std::string &name() const { return macro_name_; }
178  std::string &name() { return macro_name_; }
179  size_type nb_params() const { return nbp; }
180  size_type &nb_params() { return nbp; }
181  const ga_tree& tree() const { return *ptree; }
182  ga_tree& tree() { return *ptree; }
183  };
184 
185 
186  class ga_macro_dictionary {
187 
188  protected:
189  const ga_macro_dictionary *parent;
190  std::map<std::string, ga_macro> macros;
191 
192  public:
193  bool macro_exists(const std::string &name) const;
194  const ga_macro &get_macro(const std::string &name) const;
195 
196  void add_macro(const ga_macro &gam);
197  void add_macro(const std::string &name, const std::string &expr);
198  void del_macro(const std::string &name);
199 
200  ga_macro_dictionary() : parent(0) {}
201  ga_macro_dictionary(bool, const ga_macro_dictionary& gamd)
202  : parent(&gamd) {}
203 
204  };
205 
206  //=========================================================================
207  // Structure dealing with predefined operators.
208  //=========================================================================
209 
210 
211  struct ga_nonlinear_operator {
212 
213  typedef std::vector<const base_tensor *> arg_list;
214 
215  virtual bool result_size(const arg_list &args,
216  bgeot::multi_index &sizes) const = 0;
217 
218  virtual void value(const arg_list &args, base_tensor &result) const = 0;
219 
220  virtual void derivative(const arg_list &args, size_type i,
221  base_tensor &result) const = 0;
222 
223  virtual void second_derivative(const arg_list &args, size_type i,
224  size_type j, base_tensor &result) const = 0;
225 
226  virtual ~ga_nonlinear_operator() {}
227  };
228 
229  struct ga_predef_operator_tab {
230  typedef std::map<std::string, std::shared_ptr<ga_nonlinear_operator>> T;
231  T tab;
232 
233  void add_method(const std::string &name,
234  const std::shared_ptr<ga_nonlinear_operator> &pt)
235  { tab[name] = pt; }
236  ga_predef_operator_tab();
237  };
238 
239  //=========================================================================
240  // For user predefined scalar functions.
241  //=========================================================================
242 
243  typedef scalar_type (*pscalar_func_onearg)(scalar_type);
244  typedef scalar_type (*pscalar_func_twoargs)(scalar_type, scalar_type);
245 
246  void ga_define_function(const std::string &name, size_type nb_args,
247  const std::string &expr, const std::string &der1="",
248  const std::string &der2="");
249  void ga_define_function(const std::string &name, pscalar_func_onearg f,
250  const std::string &der1="");
251  void ga_define_function(const std::string &name, pscalar_func_twoargs f2,
252  const std::string &der1="",
253  const std::string &der2="");
254 
255  void ga_undefine_function(const std::string &name);
256  bool ga_function_exists(const std::string &name);
257 
258  //=========================================================================
259  // Structure dealing with user defined environment : constant, variables,
260  // functions, operators.
261  //=========================================================================
262 
263  class ga_workspace {
264 
265  const model *md;
266  const ga_workspace *parent_workspace;
267  bool with_parent_variables;
268  size_type nb_prim_dof, nb_intern_dof, first_intern_dof, nb_tmp_dof;
269 
270  void init();
271 
272  struct var_description {
273 
274  bool is_variable;
275  const mesh_fem *mf;
276  const im_data *imd;
277  gmm::sub_interval I;
278  const model_real_plain_vector *V;
279  bgeot::multi_index qdims; // For data having a qdim different than the
280  // qdim of the fem or im_data (dim per dof for
281  // dof data) and for constant variables.
282  bool is_internal;
283 
284  size_type qdim() const {
285  size_type q = 1;
286  for (size_type i = 0; i < qdims.size(); ++i) q *= qdims[i];
287  return q;
288  }
289 
290  var_description(bool is_var, const mesh_fem *mf_, const im_data *imd_,
291  gmm::sub_interval I_, const model_real_plain_vector *V_,
292  size_type Q, bool is_intern_=false)
293  : is_variable(is_var), mf(mf_), imd(imd_),
294  I(I_), V(V_), qdims(1), is_internal(is_intern_)
295  {
296  GMM_ASSERT1(Q > 0, "Bad dimension");
297  qdims[0] = Q;
298  }
299  };
300 
301  public:
302 
303  enum operation_type {ASSEMBLY,
304  PRE_ASSIGNMENT,
305  POST_ASSIGNMENT};
306 
307  struct tree_description { // CAUTION: Specific copy constructor
308  size_type order; // 0 : potential
309  // 1 : residual
310  // 2 : tangent operator
311  // -1 : any
312  operation_type operation;
313  std::string varname_interpolation; // Where to interpolate
314  std::string name_test1, name_test2;
315  std::string interpolate_name_test1, interpolate_name_test2;
316  std::string secondary_domain;
317  const mesh_im *mim;
318  const mesh *m;
319  const mesh_region *rg;
320  ga_tree *ptree;
321  tree_description()
322  : operation(ASSEMBLY), varname_interpolation(""),
323  name_test1(""), name_test2(""),
324  interpolate_name_test1(""), interpolate_name_test2(""),
325  mim(0), m(0), rg(0), ptree(0) {}
326  void copy(const tree_description& td);
327  tree_description(const tree_description& td) { copy(td); }
328  tree_description &operator =(const tree_description& td);
329  ~tree_description();
330  };
331 
332  mutable std::set<var_trans_pair> test1, test2;
333  var_trans_pair selected_test1, selected_test2;
334 
335  private:
336 
337  // mesh regions
338  std::map<const mesh *, std::list<mesh_region> > registred_mesh_regions;
339 
340  const mesh_region &register_region(const mesh &m, const mesh_region &rg);
341 
342  // variables and variable groups
343  typedef std::map<std::string, var_description> VAR_SET;
344  VAR_SET variables;
345 
346  std::map<std::string, gmm::sub_interval> reenabled_var_intervals,
347  tmp_var_intervals;
348 
349  std::map<std::string, pinterpolate_transformation> transformations;
350  std::map<std::string, pelementary_transformation> elem_transformations;
351  std::map<std::string, psecondary_domain> secondary_domains;
352 
353  std::vector<tree_description> trees;
354 
355  std::map<std::string, std::vector<std::string> > variable_groups;
356 
357  ga_macro_dictionary macro_dict;
358 
359  // Adds a tree to the workspace. The argument tree is consumed by the
360  // function and cannot be reused afterwards.
361  void add_tree(ga_tree &tree, const mesh &m, const mesh_im &mim,
362  const mesh_region &rg,
363  const std::string &expr, size_type add_derivative_order,
364  bool scalar_expr, operation_type op_type=ASSEMBLY,
365  const std::string varname_interpolation="");
366 
367  std::shared_ptr<model_real_sparse_matrix> K, KQJpr;
368  std::shared_ptr<base_vector> V; // reduced residual vector (primary vars + internal vars)
369  // after condensation it partially holds the condensed residual
370  // and the internal solution
371  model_real_sparse_matrix col_unreduced_K,
372  row_unreduced_K,
373  row_col_unreduced_K;
374  base_vector unreduced_V, cached_V;
375  base_tensor assemb_t;
376  bool include_empty_int_pts = false;
377 
378  public:
379  // setter functions
380  void set_assembled_matrix(model_real_sparse_matrix &K_) {
381  K = std::shared_ptr<model_real_sparse_matrix>
382  (std::shared_ptr<model_real_sparse_matrix>(), &K_); // alias
383  }
384  void set_assembled_vector(base_vector &V_) {
385  V = std::shared_ptr<base_vector>
386  (std::shared_ptr<base_vector>(), &V_); // alias
387  }
388  // getter functions
389  const model_real_sparse_matrix &assembled_matrix() const { return *K; }
390  model_real_sparse_matrix &assembled_matrix() { return *K; }
391  const base_vector &assembled_vector() const { return *V; }
392  base_vector &assembled_vector() { return *V; }
393  const base_vector &cached_vector() const { return cached_V; }
394  const base_tensor &assembled_tensor() const { return assemb_t; }
395  base_tensor &assembled_tensor() { return assemb_t; }
396  const scalar_type &assembled_potential() const {
397  GMM_ASSERT1(assemb_t.size() == 1, "Bad result size");
398  return assemb_t[0];
399  }
400  scalar_type &assembled_potential() {
401  GMM_ASSERT1(assemb_t.size() == 1, "Bad result size");
402  return assemb_t[0];
403  }
404  model_real_sparse_matrix &row_unreduced_matrix()
405  { return row_unreduced_K; }
406  model_real_sparse_matrix &col_unreduced_matrix()
407  { return col_unreduced_K; }
408  model_real_sparse_matrix &row_col_unreduced_matrix()
409  { return row_col_unreduced_K; }
410  base_vector &unreduced_vector() { return unreduced_V; }
411  // setter function for condensation matrix
412  void set_internal_coupling_matrix(model_real_sparse_matrix &KQJpr_) {
413  KQJpr = std::shared_ptr<model_real_sparse_matrix>
414  (std::shared_ptr<model_real_sparse_matrix>(), &KQJpr_); // alias
415  }
416  /** getter function for condensation matrix
417  Its size is (nb_primary_dof()+nb_internal_dof()) x nb_primary_dof()
418  but its first nb_primary_dof() rows are empty */
419  const model_real_sparse_matrix &internal_coupling_matrix() const
420  { return *KQJpr; }
421  model_real_sparse_matrix &internal_coupling_matrix() { return *KQJpr; }
422 
423  /** Add an expression, perform the semantic analysis, split into
424  * terms in separated test functions, derive if necessary to obtain
425  * the tangent terms. Return the maximal order found in the expression.
426  */
427  size_type add_expression(const std::string &expr, const mesh_im &mim,
428  const mesh_region &rg=mesh_region::all_convexes(),
429  size_type add_derivative_order = 2,
430  const std::string &secondary_dom = "");
431  /* Internal use */
432  void add_function_expression(const std::string &expr);
433  /* Internal use */
434  void add_interpolation_expression
435  (const std::string &expr, const mesh &m,
436  const mesh_region &rg = mesh_region::all_convexes());
437  void add_interpolation_expression
438  (const std::string &expr, const mesh_im &mim,
439  const mesh_region &rg = mesh_region::all_convexes());
440  void add_assignment_expression
441  (const std::string &dataname, const std::string &expr,
442  const mesh_region &rg_ = mesh_region::all_convexes(),
443  size_type order = 1, bool before = false);
444 
445  /** Delete all previously added expressions. */
446  void clear_expressions();
447 
448  /** Print some information about all previously added expressions. */
449  void print(std::ostream &str);
450 
451  size_type nb_trees() const;
452  tree_description &tree_info(size_type i);
453 
454  // variables and variable groups
455  void add_fem_variable(const std::string &name, const mesh_fem &mf,
456  const gmm::sub_interval &I,
457  const model_real_plain_vector &VV);
458  void add_im_variable(const std::string &name, const im_data &imd,
459  const gmm::sub_interval &I,
460  const model_real_plain_vector &VV);
461  void add_internal_im_variable(const std::string &name, const im_data &imd,
462  const gmm::sub_interval &I,
463  const model_real_plain_vector &VV);
464  void add_fixed_size_variable(const std::string &name,
465  const gmm::sub_interval &I,
466  const model_real_plain_vector &VV);
467  void add_fem_constant(const std::string &name, const mesh_fem &mf,
468  const model_real_plain_vector &VV);
469  void add_fixed_size_constant(const std::string &name,
470  const model_real_plain_vector &VV);
471  void add_im_data(const std::string &name, const im_data &imd,
472  const model_real_plain_vector &VV);
473 
474  bool used_variables(std::vector<std::string> &vl,
475  std::vector<std::string> &vl_test1,
476  std::vector<std::string> &vl_test2,
477  std::vector<std::string> &dl,
478  size_type order);
479  bool is_linear(size_type order);
480 
481  bool variable_exists(const std::string &name) const;
482 
483  bool is_internal_variable(const std::string &name) const;
484 
485  const std::string &variable_in_group(const std::string &group_name,
486  const mesh &m) const;
487 
488  void define_variable_group(const std::string &group_name,
489  const std::vector<std::string> &nl);
490 
491  bool variable_group_exists(const std::string &name) const;
492 
493  bool variable_or_group_exists(const std::string &name) const
494  { return variable_exists(name) || variable_group_exists(name); }
495 
496  const std::vector<std::string> &
497  variable_group(const std::string &group_name) const;
498 
499  const std::string& first_variable_of_group(const std::string &name) const;
500 
501  bool is_constant(const std::string &name) const;
502 
503  bool is_disabled_variable(const std::string &name) const;
504 
505  const scalar_type &factor_of_variable(const std::string &name) const;
506 
507  const gmm::sub_interval &
508  interval_of_variable(const std::string &name) const;
509 
510  const mesh_fem *associated_mf(const std::string &name) const;
511 
512  const im_data *associated_im_data(const std::string &name) const;
513 
514  size_type qdim(const std::string &name) const;
515 
516  bgeot::multi_index qdims(const std::string &name) const;
517 
518  const model_real_plain_vector &value(const std::string &name) const;
519  scalar_type get_time_step() const;
520 
521  // macros
522  bool macro_exists(const std::string &name) const
523  { return macro_dict.macro_exists(name); }
524 
525  void add_macro(const std::string &name, const std::string &expr)
526  { macro_dict.add_macro(name, expr); }
527 
528  void del_macro(const std::string &name) { macro_dict.del_macro(name); }
529 
530  const std::string& get_macro(const std::string &name) const;
531 
532  const ga_macro_dictionary &macro_dictionary() const { return macro_dict; }
533 
534 
535  // interpolate and elementary transformations
536  void add_interpolate_transformation(const std::string &name,
537  pinterpolate_transformation ptrans);
538 
539  bool interpolate_transformation_exists(const std::string &name) const;
540 
541  pinterpolate_transformation
542  interpolate_transformation(const std::string &name) const;
543 
544  void add_elementary_transformation(const std::string &name,
545  pelementary_transformation ptrans)
546  { elem_transformations[name] = ptrans; }
547 
548  bool elementary_transformation_exists(const std::string &name) const;
549 
550  pelementary_transformation
551  elementary_transformation(const std::string &name) const;
552 
553  void add_secondary_domain(const std::string &name,
554  psecondary_domain psecdom);
555 
556  bool secondary_domain_exists(const std::string &name) const;
557 
558  psecondary_domain secondary_domain(const std::string &name) const;
559 
560  // extract terms
561  std::string extract_constant_term(const mesh &m);
562  std::string extract_order1_term(const std::string &varname);
563  std::string extract_order0_term();
564  std::string extract_Neumann_term(const std::string &varname);
565 
566  void assembly(size_type order, bool condensation=false);
567 
568  void set_include_empty_int_points(bool include);
569  bool include_empty_int_points() const;
570 
571  size_type nb_primary_dof() const { return nb_prim_dof; }
572  size_type nb_internal_dof() const { return nb_intern_dof; }
573  size_type first_internal_dof() const { return first_intern_dof; }
574  size_type nb_temporary_dof() const { return nb_tmp_dof; }
575 
576  void add_temporary_interval_for_unreduced_variable(const std::string &name);
577 
578  void clear_temporary_variable_intervals() {
579  tmp_var_intervals.clear();
580  nb_tmp_dof = 0;
581  }
582 
583  const gmm::sub_interval &
584  temporary_interval_of_variable(const std::string &name) const {
585  static const gmm::sub_interval empty_interval;
586  const auto it = tmp_var_intervals.find(name);
587  return (it != tmp_var_intervals.end()) ? it->second : empty_interval;
588  }
589 
590  enum class inherit { NONE, ENABLED, ALL };
591 
592  explicit ga_workspace(const getfem::model &md_,
593  const inherit var_inherit=inherit::ENABLED);
594  explicit ga_workspace(const ga_workspace &gaw, // compulsory 2nd arg to avoid
595  const inherit var_inherit); // conflict with copy constructor
596  ga_workspace();
597  ~ga_workspace();
598 
599  };
600 
601  // Small tool to make basic substitutions into an assembly string
602  std::string ga_substitute(const std::string &expr,
603  const std::map<std::string, std::string> &dict);
604 
605  inline std::string ga_substitute(const std::string &expr,
606  const std::string &o1,const std::string &s1) {
607  std::map<std::string, std::string> dict;
608  dict[o1] = s1;
609  return ga_substitute(expr, dict);
610  }
611 
612  inline std::string ga_substitute(const std::string &expr,
613  const std::string &o1,const std::string &s1,
614  const std::string &o2,const std::string &s2) {
615  std::map<std::string, std::string> dict;
616  dict[o1] = s1; dict[o2] = s2;
617  return ga_substitute(expr, dict);
618  }
619 
620  inline std::string ga_substitute(const std::string &expr,
621  const std::string &o1,const std::string &s1,
622  const std::string &o2,const std::string &s2,
623  const std::string &o3,const std::string &s3) {
624  std::map<std::string, std::string> dict;
625  dict[o1] = s1; dict[o2] = s2; dict[o3] = s3;
626  return ga_substitute(expr, dict);
627  }
628 
629  inline std::string ga_substitute(const std::string &expr,
630  const std::string &o1,const std::string &s1,
631  const std::string &o2,const std::string &s2,
632  const std::string &o3,const std::string &s3,
633  const std::string &o4,const std::string &s4) {
634  std::map<std::string, std::string> dict;
635  dict[o1] = s1; dict[o2] = s2; dict[o3] = s3; dict[o4] = s4;
636  return ga_substitute(expr, dict);
637  }
638 
639 
640  //=========================================================================
641  // Intermediate structure for user function manipulation
642  //=========================================================================
643 
644  struct ga_instruction_set;
645 
646  class ga_function {
647  mutable ga_workspace local_workspace;
648  std::string expr;
649  mutable ga_instruction_set *gis;
650 
651  public:
652  ga_function() : local_workspace(), expr(""), gis(0) {}
653  ga_function(const model &md, const std::string &e);
654  ga_function(const ga_workspace &workspace_, const std::string &e);
655  ga_function(const std::string &e);
656  ga_function(const ga_function &gaf);
657  ga_function &operator =(const ga_function &gaf);
658  ~ga_function();
659  const std::string &expression() const { return expr; }
660  const base_tensor &eval() const;
661  void derivative(const std::string &variable);
662  void compile() const;
663  ga_workspace &workspace() const { return local_workspace; }
664 
665  };
666 
667  //=========================================================================
668  // Intermediate structure for interpolation functions
669  //=========================================================================
670 
671  struct ga_interpolation_context {
672 
673  virtual bgeot::pstored_point_tab
674  ppoints_for_element(size_type cv, short_type f,
675  std::vector<size_type> &ind) const = 0;
676  inline const bgeot::stored_point_tab &points_for_element
677  (size_type cv, short_type f, std::vector<size_type> &ind) const
678  { return *ppoints_for_element(cv, f, ind); }
679  virtual bool use_pgp(size_type cv) const = 0;
680  virtual bool use_mim() const = 0;
681  virtual void store_result(size_type cv, size_type i, base_tensor &t) = 0;
682  virtual void finalize() = 0;
683  virtual const mesh &linked_mesh() = 0;
684  virtual ~ga_interpolation_context() {}
685  };
686 
687  //=========================================================================
688  // Interpolation functions
689  //=========================================================================
690 
691  void ga_interpolation(ga_workspace &workspace,
692  ga_interpolation_context &gic);
693 
694  void ga_interpolation_Lagrange_fem
695  (ga_workspace &workspace, const mesh_fem &mf, base_vector &result);
696 
697  void ga_interpolation_Lagrange_fem
698  (const getfem::model &md, const std::string &expr, const mesh_fem &mf,
699  base_vector &result, const mesh_region &rg=mesh_region::all_convexes());
700 
701  void ga_interpolation_mti
702  (const getfem::model &md, const std::string &expr, mesh_trans_inv &mti,
703  base_vector &result, const mesh_region &rg=mesh_region::all_convexes(),
704  int extrapolation = 0,
705  const mesh_region &rg_source=mesh_region::all_convexes(),
706  size_type nbdof_ = size_type(-1));
707 
708  void ga_interpolation_im_data
709  (ga_workspace &workspace, const im_data &imd, base_vector &result);
710 
711  void ga_interpolation_im_data
712  (const getfem::model &md, const std::string &expr, const im_data &imd,
713  base_vector &result, const mesh_region &rg=mesh_region::all_convexes());
714 
715  void ga_interpolation_mesh_slice
716  (ga_workspace &workspace, const stored_mesh_slice &sl, base_vector &result);
717 
718  void ga_interpolation_mesh_slice
719  (const getfem::model &md, const std::string &expr, const stored_mesh_slice &sl,
720  base_vector &result, const mesh_region &rg=mesh_region::all_convexes());
721 
722 
723  //=========================================================================
724  // Local projection functions
725  //=========================================================================
726 
727  /** Make an elementwise L2 projection of an expression with respect
728  to the mesh_fem `mf`. This mesh_fem has to be a discontinuous one.
729  The expression has to be valid according to the high-level generic
730  assembly language possibly including references to the variables
731  and data of the model.
732  */
733  void ga_local_projection(const getfem::model &md, const mesh_im &mim,
734  const std::string &expr, const mesh_fem &mf,
735  base_vector &result,
736  const mesh_region &rg=mesh_region::all_convexes());
737 
738  //=========================================================================
739  // Interpolate transformations
740  //=========================================================================
741 
742  /** Add a transformation to a workspace `workspace` or a model `md` mapping
743  point in mesh `source_mesh` to mesh `target_mesh`, optionally restricted
744  to the region `target_region`. The transformation is defined by the
745  expression `expr`, which has to be in the high-level generic assembly
746  syntax and may contain some variables of the workspace/model.
747  CAUTION: For the moment, the derivative of the transformation with
748  respect to any of these variables is not taken into account in the model
749  solve.
750  */
752  (ga_workspace &workspace, const std::string &transname,
753  const mesh &source_mesh, const mesh &target_mesh, const std::string &expr);
755  (ga_workspace &workspace, const std::string &transname,
756  const mesh &source_mesh, const mesh &target_mesh,
757  size_type target_region, const std::string &expr);
759  (model &md, const std::string &transname,
760  const mesh &source_mesh, const mesh &target_mesh, const std::string &expr);
762  (model &md, const std::string &transname,
763  const mesh &source_mesh, const mesh &target_mesh,
764  size_type target_region, const std::string &expr);
765 
766  /** Add a transformation to the workspace that creates an identity mapping
767  between two meshes in deformed state. Conceptually, it can be viewed
768  as a transformation from expression Xsource + Usource - Utarget,
769  except such an expression cannot be used directly in the transformation
770  from expression (function above), as Utarget needs to be interpolated
771  though an inversion of the transformation of the target domain.
772  Thread safe if added to thread local workspace.
773  */
775  (ga_workspace &workspace, const std::string &transname,
776  const mesh &source_mesh, const std::string &source_displacements,
777  const mesh_region &source_region, const mesh &target_mesh,
778  const std::string &target_displacements, const mesh_region &target_region);
779 
780  /** The same as above, but adding transformation to the model.
781  Note, this version is not thread safe.*/
783  (model &md, const std::string &transname,
784  const mesh &source_mesh, const std::string &source_displacements,
785  const mesh_region &source_region, const mesh &target_mesh,
786  const std::string &target_displacements, const mesh_region &target_region);
787 
788  /** Create a new instance of a transformation corresponding to the
789  interpolation on the neighbor element. Can only be applied to the
790  computation on some internal faces of a mesh.
791  (mainly for internal use in the constructor of getfem::model)
792  */
793  pinterpolate_transformation interpolate_transformation_neighbor_instance();
794 
795  /* Add a special interpolation transformation which represents the identity
796  transformation but allows to evaluate the expression on another element
797  than the current element by polynomial extrapolation. It is used for
798  stabilization term in fictitious domain applications. the map elt_cor
799  list the element concerned by the transformation and associate them
800  to the element on which the extrapolation has to be made. If an element
801  is not listed in elt_cor the evaluation is just made on the current
802  element.
803  */
804  void add_element_extrapolation_transformation
805  (model &md, const std::string &name, const mesh &sm,
806  std::map<size_type, size_type> &elt_corr);
807 
808  void add_element_extrapolation_transformation
809  (ga_workspace &workspace, const std::string &name, const mesh &sm,
810  std::map<size_type, size_type> &elt_corr);
811 
812  /* Change the correspondence map of an element extrapolation interpolate
813  transformation.
814  */
815  void set_element_extrapolation_correspondence
816  (model &md, const std::string &name,
817  std::map<size_type, size_type> &elt_corr);
818 
819  void set_element_extrapolation_correspondence
820  (ga_workspace &workspace, const std::string &name,
821  std::map<size_type, size_type> &elt_corr);
822 
823  //=========================================================================
824  // Secondary domains
825  //=========================================================================
826 
827  void add_standard_secondary_domain
828  (model &md, const std::string &name, const mesh_im &mim,
829  const mesh_region &rg=mesh_region::all_convexes());
830 
831  void add_standard_secondary_domain
832  (ga_workspace &workspace, const std::string &name, const mesh_im &mim,
833  const mesh_region &rg=mesh_region::all_convexes());
834 
835 
836 } /* end of namespace getfem. */
837 
838 
839 #endif /* GETFEM_GENERIC_ASSEMBLY_H__ */
static mesh_region all_convexes()
provide a default value for the mesh_region parameters of assembly procedures etc.
`‘Model’' variables store the variables, the data and the description of a model.
sparse vector built upon std::vector.
Definition: gmm_vector.h:963
Interpolation of fields from a mesh_fem onto another.
Define the class getfem::stored_mesh_slice.
void copy(const L1 &l1, L2 &l2)
*‍/
Definition: gmm_blas.h:978
gmm::uint16_type short_type
used as the common short type integer in the library
Definition: bgeot_config.h:73
size_t size_type
used as the common size type in the library
Definition: bgeot_poly.h:49
GEneric Tool for Finite Element Methods.
pinterpolate_transformation interpolate_transformation_neighbor_instance()
Create a new instance of a transformation corresponding to the interpolation on the neighbor element.
void add_interpolate_transformation_on_deformed_domains(ga_workspace &workspace, const std::string &transname, const mesh &source_mesh, const std::string &source_displacements, const mesh_region &source_region, const mesh &target_mesh, const std::string &target_displacements, const mesh_region &target_region)
Add a transformation to the workspace that creates an identity mapping between two meshes in deformed...
void add_interpolate_transformation_from_expression(ga_workspace &workspace, const std::string &transname, const mesh &source_mesh, const mesh &target_mesh, const std::string &expr)
Add a transformation to a workspace workspace or a model md mapping point in mesh source_mesh to mesh...
void ga_local_projection(const getfem::model &md, const mesh_im &mim, const std::string &expr, const mesh_fem &mf, base_vector &result, const mesh_region &rg=mesh_region::all_convexes())
Make an elementwise L2 projection of an expression with respect to the mesh_fem mf.
Point tab storage.