39 #ifndef GETFEM_GENERIC_ASSEMBLY_H__
40 #define GETFEM_GENERIC_ASSEMBLY_H__
52 #define INFINITY std::numeric_limits<scalar_type>::infinity()
63 typedef std::vector<scalar_type> model_real_plain_vector;
64 typedef std::vector<complex_type> model_complex_plain_vector;
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;
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;
78 int ga_check_name_validity(
const std::string &name);
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);
90 var_trans_pair() : varname(), transname() {}
91 var_trans_pair(
const std::string &v,
const std::string &t)
92 : varname(v), transname(t) {}
95 class APIDECL virtual_interpolate_transformation {
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,
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(); }
113 virtual ~virtual_interpolate_transformation() {}
116 typedef std::shared_ptr<const virtual_interpolate_transformation>
117 pinterpolate_transformation;
123 class APIDECL virtual_elementary_transformation {
127 virtual void give_transformation(
const mesh_fem &mf1,
const mesh_fem &mf2,
129 virtual ~virtual_elementary_transformation() {}
132 typedef std::shared_ptr<const virtual_elementary_transformation>
133 pelementary_transformation;
139 class APIDECL virtual_secondary_domain {
142 const mesh_region region;
146 const mesh_im &mim()
const {
return mim_; }
147 virtual const mesh_region &give_region(
const mesh &m,
152 virtual_secondary_domain(
const mesh_im &mim__,
const mesh_region ®ion_)
153 : mim_(mim__), region(region_) {}
154 virtual ~virtual_secondary_domain() {}
157 typedef std::shared_ptr<const virtual_secondary_domain> psecondary_domain;
167 std::string macro_name_;
172 ga_macro(
const std::string &name,
const ga_tree &t,
size_type nbp_);
173 ga_macro(
const ga_macro &);
175 ga_macro &operator =(
const ga_macro &);
177 const std::string &name()
const {
return macro_name_; }
178 std::string &name() {
return macro_name_; }
179 size_type nb_params()
const {
return nbp; }
181 const ga_tree& tree()
const {
return *ptree; }
182 ga_tree& tree() {
return *ptree; }
186 class ga_macro_dictionary {
189 const ga_macro_dictionary *parent;
190 std::map<std::string, ga_macro> macros;
193 bool macro_exists(
const std::string &name)
const;
194 const ga_macro &get_macro(
const std::string &name)
const;
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);
200 ga_macro_dictionary() : parent(0) {}
201 ga_macro_dictionary(
bool,
const ga_macro_dictionary& gamd)
211 struct ga_nonlinear_operator {
213 typedef std::vector<const base_tensor *> arg_list;
215 virtual bool result_size(
const arg_list &args,
216 bgeot::multi_index &sizes)
const = 0;
218 virtual void value(
const arg_list &args, base_tensor &result)
const = 0;
220 virtual void derivative(
const arg_list &args,
size_type i,
221 base_tensor &result)
const = 0;
223 virtual void second_derivative(
const arg_list &args,
size_type i,
224 size_type j, base_tensor &result)
const = 0;
226 virtual ~ga_nonlinear_operator() {}
229 struct ga_predef_operator_tab {
230 typedef std::map<std::string, std::shared_ptr<ga_nonlinear_operator>> T;
233 void add_method(
const std::string &name,
234 const std::shared_ptr<ga_nonlinear_operator> &pt)
236 ga_predef_operator_tab();
243 typedef scalar_type (*pscalar_func_onearg)(scalar_type);
244 typedef scalar_type (*pscalar_func_twoargs)(scalar_type, scalar_type);
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=
"");
255 void ga_undefine_function(
const std::string &name);
256 bool ga_function_exists(
const std::string &name);
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;
272 struct var_description {
274 const bool is_variable;
275 const bool is_fem_dofs;
279 const model_real_plain_vector *V;
280 bgeot::multi_index qdims;
283 const bool is_internal;
287 for (
size_type i = 0; i < qdims.size(); ++i) q *= qdims[i];
291 var_description(
bool is_var,
const mesh_fem *mf_,
const im_data *imd_,
292 gmm::sub_interval I_,
const model_real_plain_vector *V_,
294 : is_variable(is_var), is_fem_dofs(mf_ != 0), mf(mf_), imd(imd_),
295 I(I_), V(V_), qdims(1), is_internal(is_intern_)
297 GMM_ASSERT1(Q > 0,
"Bad dimension");
304 enum operation_type {ASSEMBLY,
308 struct tree_description {
313 operation_type operation;
314 std::string varname_interpolation;
315 std::string name_test1, name_test2;
316 std::string interpolate_name_test1, interpolate_name_test2;
317 std::string secondary_domain;
320 const mesh_region *rg;
323 : operation(ASSEMBLY), varname_interpolation(
""),
324 name_test1(
""), name_test2(
""),
325 interpolate_name_test1(
""), interpolate_name_test2(
""),
326 mim(0), m(0), rg(0), ptree(0) {}
327 void copy(
const tree_description& td);
328 tree_description(
const tree_description& td) {
copy(td); }
329 tree_description &operator =(
const tree_description& td);
333 mutable std::set<var_trans_pair> test1, test2;
334 var_trans_pair selected_test1, selected_test2;
339 std::map<const mesh *, std::list<mesh_region> > registred_mesh_regions;
341 const mesh_region ®ister_region(
const mesh &m,
const mesh_region &rg);
344 typedef std::map<std::string, var_description> VAR_SET;
347 std::map<std::string, gmm::sub_interval> reenabled_var_intervals,
350 std::map<std::string, pinterpolate_transformation> transformations;
351 std::map<std::string, pelementary_transformation> elem_transformations;
352 std::map<std::string, psecondary_domain> secondary_domains;
354 std::vector<tree_description> trees;
356 std::map<std::string, std::vector<std::string> > variable_groups;
358 ga_macro_dictionary macro_dict;
362 void add_tree(ga_tree &tree,
const mesh &m,
const mesh_im &mim,
363 const mesh_region &rg,
364 const std::string &expr,
size_type add_derivative_order,
365 bool scalar_expr, operation_type op_type=ASSEMBLY,
366 const std::string varname_interpolation=
"");
368 std::shared_ptr<model_real_sparse_matrix> K, KQJpr;
369 std::shared_ptr<base_vector> V;
372 model_real_sparse_matrix col_unreduced_K,
375 base_vector unreduced_V, cached_V;
376 base_tensor assemb_t;
377 bool include_empty_int_pts =
false;
381 void set_assembled_matrix(model_real_sparse_matrix &K_) {
382 K = std::shared_ptr<model_real_sparse_matrix>
383 (std::shared_ptr<model_real_sparse_matrix>(), &K_);
385 void set_assembled_vector(base_vector &V_) {
386 V = std::shared_ptr<base_vector>
387 (std::shared_ptr<base_vector>(), &V_);
390 const model_real_sparse_matrix &assembled_matrix()
const {
return *K; }
391 model_real_sparse_matrix &assembled_matrix() {
return *K; }
392 const base_vector &assembled_vector()
const {
return *V; }
393 base_vector &assembled_vector() {
return *V; }
394 const base_vector &cached_vector()
const {
return cached_V; }
395 const base_tensor &assembled_tensor()
const {
return assemb_t; }
396 base_tensor &assembled_tensor() {
return assemb_t; }
397 const scalar_type &assembled_potential()
const {
398 GMM_ASSERT1(assemb_t.size() == 1,
"Bad result size");
401 scalar_type &assembled_potential() {
402 GMM_ASSERT1(assemb_t.size() == 1,
"Bad result size");
405 model_real_sparse_matrix &row_unreduced_matrix()
406 {
return row_unreduced_K; }
407 model_real_sparse_matrix &col_unreduced_matrix()
408 {
return col_unreduced_K; }
409 model_real_sparse_matrix &row_col_unreduced_matrix()
410 {
return row_col_unreduced_K; }
411 base_vector &unreduced_vector() {
return unreduced_V; }
413 void set_internal_coupling_matrix(model_real_sparse_matrix &KQJpr_) {
414 KQJpr = std::shared_ptr<model_real_sparse_matrix>
415 (std::shared_ptr<model_real_sparse_matrix>(), &KQJpr_);
420 const model_real_sparse_matrix &internal_coupling_matrix()
const
422 model_real_sparse_matrix &internal_coupling_matrix() {
return *KQJpr; }
428 size_type add_expression(
const std::string &expr,
const mesh_im &mim,
431 const std::string &secondary_dom =
"");
433 void add_function_expression(
const std::string &expr);
435 void add_interpolation_expression
436 (
const std::string &expr,
const mesh &m,
438 void add_interpolation_expression
439 (
const std::string &expr,
const mesh_im &mim,
441 void add_assignment_expression
442 (
const std::string &dataname,
const std::string &expr,
444 size_type order = 1,
bool before =
false);
447 void clear_expressions();
450 void print(std::ostream &str);
453 tree_description &tree_info(
size_type i);
456 void add_fem_variable(
const std::string &name,
const mesh_fem &mf,
457 const gmm::sub_interval &I,
458 const model_real_plain_vector &VV);
459 void add_im_variable(
const std::string &name,
const im_data &imd,
460 const gmm::sub_interval &I,
461 const model_real_plain_vector &VV);
462 void add_internal_im_variable(
const std::string &name,
const im_data &imd,
463 const gmm::sub_interval &I,
464 const model_real_plain_vector &VV);
465 void add_fixed_size_variable(
const std::string &name,
466 const gmm::sub_interval &I,
467 const model_real_plain_vector &VV);
468 void add_fem_constant(
const std::string &name,
const mesh_fem &mf,
469 const model_real_plain_vector &VV);
470 void add_fixed_size_constant(
const std::string &name,
471 const model_real_plain_vector &VV);
472 void add_im_data(
const std::string &name,
const im_data &imd,
473 const model_real_plain_vector &VV);
475 bool used_variables(std::vector<std::string> &vl,
476 std::vector<std::string> &vl_test1,
477 std::vector<std::string> &vl_test2,
478 std::vector<std::string> &dl,
482 bool variable_exists(
const std::string &name)
const;
484 bool is_internal_variable(
const std::string &name)
const;
486 const std::string &variable_in_group(
const std::string &group_name,
487 const mesh &m)
const;
489 void define_variable_group(
const std::string &group_name,
490 const std::vector<std::string> &nl);
492 bool variable_group_exists(
const std::string &name)
const;
494 bool variable_or_group_exists(
const std::string &name)
const
495 {
return variable_exists(name) || variable_group_exists(name); }
497 const std::vector<std::string> &
498 variable_group(
const std::string &group_name)
const;
500 const std::string& first_variable_of_group(
const std::string &name)
const;
502 bool is_constant(
const std::string &name)
const;
504 bool is_disabled_variable(
const std::string &name)
const;
506 const scalar_type &factor_of_variable(
const std::string &name)
const;
508 const gmm::sub_interval &
509 interval_of_variable(
const std::string &name)
const;
511 const mesh_fem *associated_mf(
const std::string &name)
const;
513 const im_data *associated_im_data(
const std::string &name)
const;
515 size_type qdim(
const std::string &name)
const;
517 bgeot::multi_index qdims(
const std::string &name)
const;
519 const model_real_plain_vector &value(
const std::string &name)
const;
520 scalar_type get_time_step()
const;
523 bool macro_exists(
const std::string &name)
const
524 {
return macro_dict.macro_exists(name); }
526 void add_macro(
const std::string &name,
const std::string &expr)
527 { macro_dict.add_macro(name, expr); }
529 void del_macro(
const std::string &name) { macro_dict.del_macro(name); }
531 const std::string& get_macro(
const std::string &name)
const;
533 const ga_macro_dictionary ¯o_dictionary()
const {
return macro_dict; }
537 void add_interpolate_transformation(
const std::string &name,
538 pinterpolate_transformation ptrans);
540 bool interpolate_transformation_exists(
const std::string &name)
const;
542 pinterpolate_transformation
543 interpolate_transformation(
const std::string &name)
const;
545 void add_elementary_transformation(
const std::string &name,
546 pelementary_transformation ptrans)
547 { elem_transformations[name] = ptrans; }
549 bool elementary_transformation_exists(
const std::string &name)
const;
551 pelementary_transformation
552 elementary_transformation(
const std::string &name)
const;
554 void add_secondary_domain(
const std::string &name,
555 psecondary_domain psecdom);
557 bool secondary_domain_exists(
const std::string &name)
const;
559 psecondary_domain secondary_domain(
const std::string &name)
const;
562 std::string extract_constant_term(
const mesh &m);
563 std::string extract_order1_term(
const std::string &varname);
564 std::string extract_order0_term();
565 std::string extract_Neumann_term(
const std::string &varname);
567 void assembly(
size_type order,
bool condensation=
false);
569 void set_include_empty_int_points(
bool include);
570 bool include_empty_int_points()
const;
572 size_type nb_primary_dof()
const {
return nb_prim_dof; }
573 size_type nb_internal_dof()
const {
return nb_intern_dof; }
574 size_type first_internal_dof()
const {
return first_intern_dof; }
575 size_type nb_temporary_dof()
const {
return nb_tmp_dof; }
577 void add_temporary_interval_for_unreduced_variable(
const std::string &name);
579 void clear_temporary_variable_intervals() {
580 tmp_var_intervals.clear();
584 const gmm::sub_interval &
585 temporary_interval_of_variable(
const std::string &name)
const {
586 static const gmm::sub_interval empty_interval;
587 const auto it = tmp_var_intervals.find(name);
588 return (it != tmp_var_intervals.end()) ? it->second : empty_interval;
591 enum class inherit { NONE, ENABLED, ALL };
594 const inherit var_inherit=inherit::ENABLED);
595 explicit ga_workspace(
const ga_workspace &gaw,
596 const inherit var_inherit);
603 std::string ga_substitute(
const std::string &expr,
604 const std::map<std::string, std::string> &dict);
606 inline std::string ga_substitute(
const std::string &expr,
607 const std::string &o1,
const std::string &s1) {
608 std::map<std::string, std::string> dict;
610 return ga_substitute(expr, dict);
613 inline std::string ga_substitute(
const std::string &expr,
614 const std::string &o1,
const std::string &s1,
615 const std::string &o2,
const std::string &s2) {
616 std::map<std::string, std::string> dict;
617 dict[o1] = s1; dict[o2] = s2;
618 return ga_substitute(expr, dict);
621 inline std::string ga_substitute(
const std::string &expr,
622 const std::string &o1,
const std::string &s1,
623 const std::string &o2,
const std::string &s2,
624 const std::string &o3,
const std::string &s3) {
625 std::map<std::string, std::string> dict;
626 dict[o1] = s1; dict[o2] = s2; dict[o3] = s3;
627 return ga_substitute(expr, dict);
630 inline std::string ga_substitute(
const std::string &expr,
631 const std::string &o1,
const std::string &s1,
632 const std::string &o2,
const std::string &s2,
633 const std::string &o3,
const std::string &s3,
634 const std::string &o4,
const std::string &s4) {
635 std::map<std::string, std::string> dict;
636 dict[o1] = s1; dict[o2] = s2; dict[o3] = s3; dict[o4] = s4;
637 return ga_substitute(expr, dict);
645 struct ga_instruction_set;
648 mutable ga_workspace local_workspace;
650 mutable ga_instruction_set *gis;
653 ga_function() : local_workspace(), expr(
""), gis(0) {}
654 ga_function(
const model &md,
const std::string &e);
655 ga_function(
const ga_workspace &workspace_,
const std::string &e);
656 ga_function(
const std::string &e);
657 ga_function(
const ga_function &gaf);
658 ga_function &operator =(
const ga_function &gaf);
660 const std::string &expression()
const {
return expr; }
661 const base_tensor &eval()
const;
662 void derivative(
const std::string &variable);
663 void compile()
const;
664 ga_workspace &workspace()
const {
return local_workspace; }
672 struct ga_interpolation_context {
674 virtual bgeot::pstored_point_tab
676 std::vector<size_type> &ind)
const = 0;
679 {
return *ppoints_for_element(cv, f, ind); }
680 virtual bool use_pgp(
size_type cv)
const = 0;
681 virtual bool use_mim()
const = 0;
683 virtual void finalize() = 0;
684 virtual const mesh &linked_mesh() = 0;
685 virtual ~ga_interpolation_context() {}
692 void ga_interpolation(ga_workspace &workspace,
693 ga_interpolation_context &gic);
695 void ga_interpolation_Lagrange_fem
696 (ga_workspace &workspace,
const mesh_fem &mf, base_vector &result);
698 void ga_interpolation_Lagrange_fem
699 (
const getfem::model &md,
const std::string &expr,
const mesh_fem &mf,
702 void ga_interpolation_mti
703 (
const getfem::model &md,
const std::string &expr, mesh_trans_inv &mti,
705 int extrapolation = 0,
709 void ga_interpolation_im_data
710 (ga_workspace &workspace,
const im_data &imd, base_vector &result);
712 void ga_interpolation_im_data
713 (
const getfem::model &md,
const std::string &expr,
const im_data &imd,
716 void ga_interpolation_mesh_slice
717 (ga_workspace &workspace,
const stored_mesh_slice &sl, base_vector &result);
719 void ga_interpolation_mesh_slice
720 (
const getfem::model &md,
const std::string &expr,
const stored_mesh_slice &sl,
735 const std::string &expr,
const mesh_fem &mf,
753 (ga_workspace &workspace,
const std::string &transname,
754 const mesh &source_mesh,
const mesh &target_mesh,
const std::string &expr);
756 (ga_workspace &workspace,
const std::string &transname,
757 const mesh &source_mesh,
const mesh &target_mesh,
758 size_type target_region,
const std::string &expr);
760 (model &md,
const std::string &transname,
761 const mesh &source_mesh,
const mesh &target_mesh,
const std::string &expr);
763 (model &md,
const std::string &transname,
764 const mesh &source_mesh,
const mesh &target_mesh,
765 size_type target_region,
const std::string &expr);
776 (ga_workspace &workspace,
const std::string &transname,
777 const mesh &source_mesh,
const std::string &source_displacements,
778 const mesh_region &source_region,
const mesh &target_mesh,
779 const std::string &target_displacements,
const mesh_region &target_region);
784 (model &md,
const std::string &transname,
785 const mesh &source_mesh,
const std::string &source_displacements,
786 const mesh_region &source_region,
const mesh &target_mesh,
787 const std::string &target_displacements,
const mesh_region &target_region);
805 void add_element_extrapolation_transformation
806 (model &md,
const std::string &name,
const mesh &sm,
807 std::map<size_type, size_type> &elt_corr);
809 void add_element_extrapolation_transformation
810 (ga_workspace &workspace,
const std::string &name,
const mesh &sm,
811 std::map<size_type, size_type> &elt_corr);
816 void set_element_extrapolation_correspondence
817 (model &md,
const std::string &name,
818 std::map<size_type, size_type> &elt_corr);
820 void set_element_extrapolation_correspondence
821 (ga_workspace &workspace,
const std::string &name,
822 std::map<size_type, size_type> &elt_corr);
828 void add_standard_secondary_domain
829 (model &md,
const std::string &name,
const mesh_im &mim,
832 void add_standard_secondary_domain
833 (ga_workspace &workspace,
const std::string &name,
const mesh_im &mim,