39 #ifndef GETFEM_MODELS_H__
40 #define GETFEM_MODELS_H__
51 typedef std::shared_ptr<const virtual_brick>
pbrick;
54 typedef std::shared_ptr<const virtual_dispatcher> pdispatcher;
57 typedef std::shared_ptr<const virtual_time_scheme> ptime_scheme;
89 typedef model_real_plain_vector modeling_standard_plain_vector;
91 typedef model_real_sparse_matrix modeling_standard_sparse_matrix;
92 typedef model_complex_plain_vector modeling_standard_complex_plain_vector;
94 typedef model_complex_sparse_matrix modeling_standard_complex_sparse_matrix;
99 const auto PREFIX_OLD_LENGTH = 4;
102 bool is_old(
const std::string &name);
107 std::string sup_previous_and_dot_to_varname(std::string v);
120 bool complex_version;
124 mutable model_real_sparse_matrix
127 mutable model_complex_sparse_matrix cTM;
128 mutable model_real_plain_vector
132 mutable model_complex_plain_vector crhs;
133 mutable bool act_size_to_be_done;
134 dim_type leading_dim;
135 getfem::lock_factory locks_;
139 enum var_description_filter {
141 VDESCRFILTER_REGION = 1,
143 VDESCRFILTER_INFSUP = 2,
146 VDESCRFILTER_CTERM = 4,
149 VDESCRFILTER_REGION_CTERM = 5,
152 struct var_description {
157 bool is_affine_dependent;
168 var_description_filter filter;
171 std::string filter_var;
176 ppartial_mesh_fem partial_mf;
179 bgeot::multi_index qdims;
182 gmm::uint64_type v_num;
183 std::vector<gmm::uint64_type> v_num_data;
188 std::vector<model_real_plain_vector> real_value;
189 std::vector<model_complex_plain_vector> complex_value;
190 std::vector<gmm::uint64_type> v_num_var_iter;
191 std::vector<gmm::uint64_type> v_num_iter;
194 model_real_plain_vector affine_real_value;
195 model_complex_plain_vector affine_complex_value;
197 std::string org_name;
200 var_description(
bool is_var =
false,
bool is_compl =
false,
203 var_description_filter filter_ = VDESCRFILTER_NO,
205 const std::string &filter_var_ = std::string(
""),
206 mesh_im const *filter_mim_ = 0)
207 : is_variable(is_var), is_disabled(
false), is_complex(is_compl),
208 is_affine_dependent(
false), is_internal(
false),
209 is_fem_dofs(mf_ != 0),
210 n_iter(std::max(
size_type(1), n_it)), n_temp_iter(0),
211 default_iter(0), ptsc(0),
212 filter(filter_), filter_region(filter_reg), filter_var(filter_var_),
213 filter_mim(filter_mim_), mf(mf_), imd(imd_), qdims(),
214 v_num(0), v_num_data(n_iter, act_counter()), I(0,0), alpha(1)
216 if (filter != VDESCRFILTER_NO && mf != 0)
217 partial_mf = std::make_shared<partial_mesh_fem>(*mf);
219 if (qdims.size() == 0) qdims.push_back(1);
220 GMM_ASSERT1(qdim(),
"Attempt to create a null size variable");
223 size_type qdim()
const {
return qdims.total_size(); }
228 size_type add_temporary(gmm::uint64_type id_num);
230 void clear_temporaries();
232 const mesh_fem &associated_mf()
const {
233 GMM_ASSERT1(is_fem_dofs,
"This variable is not linked to a fem");
234 return (filter == VDESCRFILTER_NO) ? *mf : *partial_mf;
237 const mesh_fem *passociated_mf()
const {
239 return (filter == VDESCRFILTER_NO || partial_mf.get() == 0)
240 ? mf : partial_mf.get();
246 return is_complex ? complex_value[0].size()
247 : real_value[0].size();
249 inline bool is_enabled()
const {
return !is_disabled; }
256 typedef std::vector<std::string> varnamelist;
257 typedef std::vector<const mesh_im *> mimlist;
258 typedef std::vector<model_real_sparse_matrix> real_matlist;
259 typedef std::vector<model_complex_sparse_matrix> complex_matlist;
260 typedef std::vector<model_real_plain_vector> real_veclist;
261 typedef std::vector<model_complex_plain_vector> complex_veclist;
263 struct term_description {
267 std::string var1, var2;
269 term_description(
const std::string &v)
270 : is_matrix_term(
false), is_symmetric(
false),
271 is_global(
false), var1(sup_previous_and_dot_to_varname(v)) {}
272 term_description(
const std::string &v1,
const std::string &v2,
274 : is_matrix_term(
true), is_symmetric(issym), is_global(
false),
275 var1(sup_previous_and_dot_to_varname(v1)), var2(v2) {}
276 term_description(
bool ism,
bool issym)
277 : is_matrix_term(ism), is_symmetric(issym), is_global(
true) {}
280 typedef std::vector<term_description> termlist;
286 BUILD_ON_DATA_CHANGE = 4,
288 BUILD_RHS_WITH_LIN = 9,
289 BUILD_WITH_INTERNAL = 16,
290 BUILD_RHS_WITH_INTERNAL = 17,
291 BUILD_MATRIX_CONDENSED = 18,
292 BUILD_ALL_CONDENSED = 19,
299 struct brick_description {
300 mutable bool terms_to_be_computed;
301 mutable gmm::uint64_type v_num;
303 pdispatcher pdispatch;
310 bool is_update_brick;
312 mutable scalar_type external_load;
314 mutable model_real_plain_vector coeffs;
315 mutable scalar_type matrix_coeff = scalar_type(0);
317 mutable real_matlist rmatlist;
319 mutable std::vector<real_veclist> rveclist;
321 mutable std::vector<real_veclist> rveclist_sym;
323 mutable complex_matlist cmatlist;
325 mutable std::vector<complex_veclist> cveclist;
327 mutable std::vector<complex_veclist> cveclist_sym;
329 brick_description() : v_num(0) {}
331 brick_description(
pbrick p,
const varnamelist &vl,
332 const varnamelist &dl,
const termlist &tl,
334 : terms_to_be_computed(
true), v_num(0), pbr(p), pdispatch(0), nbrhs(1),
335 vlist(vl), dlist(dl), tlist(tl), mims(mms), region(reg),
336 is_update_brick(
false), external_load(0),
337 rveclist(1), rveclist_sym(1), cveclist(1),
341 typedef std::map<std::string, var_description> VAR_SET;
342 mutable VAR_SET variables;
343 std::vector<brick_description> bricks;
344 dal::bit_vector valid_bricks, active_bricks;
345 std::map<std::string, pinterpolate_transformation> transformations;
346 std::map<std::string, pelementary_transformation> elem_transformations;
347 std::map<std::string, psecondary_domain> secondary_domains;
350 int time_integration;
352 scalar_type time_step;
353 scalar_type init_time_step;
356 typedef std::map<size_type, scalar_type> real_dof_constraints_var;
357 typedef std::map<size_type, complex_type> complex_dof_constraints_var;
358 mutable std::map<std::string, real_dof_constraints_var>
359 real_dof_constraints;
360 mutable std::map<std::string, complex_dof_constraints_var>
361 complex_dof_constraints;
362 void clear_dof_constraints()
363 { real_dof_constraints.clear(); complex_dof_constraints.clear(); }
370 std::string secondary_domain;
371 gen_expr(
const std::string &expr_,
const mesh_im &mim_,
372 size_type region_,
const std::string &secdom)
373 : expr(expr_), mim(mim_), region(region_), secondary_domain(secdom) {}
377 struct assignement_desc {
385 std::list<assignement_desc> assignments;
387 mutable std::list<gen_expr> generic_expressions;
391 std::map<std::string, std::vector<std::string> > variable_groups;
393 ga_macro_dictionary macro_dict;
396 virtual void actualize_sizes()
const;
397 bool check_name_validity(
const std::string &name,
bool assert=
true)
const;
398 void brick_init(
size_type ib, build_version version,
401 void init() { complex_version =
false; act_size_to_be_done =
false; }
403 void resize_global_system()
const;
406 virtual void post_to_variables_step();
408 scalar_type approx_external_load_;
411 VAR_SET::const_iterator find_variable(
const std::string &name)
const;
412 const var_description &variable_description(
const std::string &name)
const;
416 void add_generic_expression(
const std::string &expr,
const mesh_im &mim,
418 const std::string &secondary_domain =
"")
const {
419 generic_expressions.push_back(gen_expr(expr, mim, region,
422 void add_external_load(
size_type ib, scalar_type e)
const
423 { bricks[ib].external_load = e; }
424 scalar_type approx_external_load() {
return approx_external_load_; }
426 void update_brick(
size_type ib, build_version version)
const;
429 void update_affine_dependent_variables();
430 void brick_call(
size_type ib, build_version version,
432 model_real_plain_vector &rhs_coeffs_of_brick(
size_type ib)
const
433 {
return bricks[ib].coeffs; }
434 scalar_type &matrix_coeff_of_brick(
size_type ib)
const
435 {
return bricks[ib].matrix_coeff; }
436 bool is_var_newer_than_brick(
const std::string &varname,
438 bool is_var_mf_newer_than_brick(
const std::string &varname,
440 bool is_mim_newer_than_brick(
const mesh_im &mim,
444 GMM_ASSERT1(valid_bricks[ib],
"Inexistent brick");
445 return bricks[ib].pbr;
448 void variable_list(varnamelist &vl)
const
449 {
for (
const auto &v : variables) vl.push_back(v.first); }
451 void define_variable_group(
const std::string &group_name,
452 const std::vector<std::string> &nl);
453 bool variable_group_exists(
const std::string &group_name)
const
454 {
return variable_groups.count(group_name) > 0; }
456 const std::vector<std::string> &
457 variable_group(
const std::string &group_name)
const {
458 GMM_ASSERT1(variable_group_exists(group_name),
459 "Undefined variable group " << group_name);
460 return (variable_groups.find(group_name))->second;
463 void clear_assembly_assignments(
void) { assignments.clear(); }
464 void add_assembly_assignments(
const std::string &dataname,
465 const std::string &expr,
468 bool before =
false);
471 void add_real_dof_constraint(
const std::string &varname,
size_type dof,
472 scalar_type val)
const
473 { real_dof_constraints[varname][dof] = val; }
475 void add_complex_dof_constraint(
const std::string &varname,
size_type dof,
476 complex_type val)
const
477 { complex_dof_constraints[varname][dof] = val; }
480 void add_temporaries(
const varnamelist &vl, gmm::uint64_type id_num)
const;
482 const mimlist &mimlist_of_brick(
size_type ib)
const
483 {
return bricks[ib].mims; }
485 const varnamelist &varnamelist_of_brick(
size_type ib)
const
486 {
return bricks[ib].vlist; }
488 const varnamelist &datanamelist_of_brick(
size_type ib)
const
489 {
return bricks[ib].dlist; }
492 {
return bricks[ib].region; }
494 bool temporary_uptodate(
const std::string &varname,
495 gmm::uint64_type id_num,
size_type &ind)
const;
497 size_type n_iter_of_variable(
const std::string &name)
const {
498 return variables.count(name) == 0 ?
size_type(0)
499 : variables[name].n_iter;
502 void set_default_iter_of_variable(
const std::string &varname,
504 void reset_default_iter_of_variables(
const varnamelist &vl)
const;
508 const model_real_sparse_matrix &linear_real_matrix_term
511 const model_complex_sparse_matrix &linear_complex_matrix_term
516 GMM_ASSERT1(valid_bricks[ib],
"Inexistent brick");
517 active_bricks.del(ib);
522 GMM_ASSERT1(valid_bricks[ib],
"Inexistent brick");
523 active_bricks.add(ib);
527 void disable_variable(
const std::string &name);
530 void enable_variable(
const std::string &name,
bool enabled=
true);
533 bool variable_exists(
const std::string &name)
const;
536 bool is_disabled_variable(
const std::string &name)
const;
539 bool is_data(
const std::string &name)
const;
542 bool is_true_data(
const std::string &name)
const;
545 bool is_internal_variable(
const std::string &name)
const;
547 bool is_affine_dependent_variable(
const std::string &name)
const;
549 const std::string &org_variable(
const std::string &name)
const;
551 const scalar_type &factor_of_variable(
const std::string &name)
const;
553 void set_factor_of_variable(
const std::string &name, scalar_type a);
555 bool is_im_data(
const std::string &name)
const;
557 const im_data *pim_data_of_variable(
const std::string &name)
const;
559 const gmm::uint64_type &
560 version_number_of_data_variable(
const std::string &varname,
573 for (
const auto &v : variables)
574 if (v.second.is_internal && !v.second.is_disabled)
return true;
586 size_type nb_dof(
bool with_internal=
false)
const;
595 dim_type leading_dimension()
const {
return leading_dim; }
598 std::string new_name(
const std::string &name);
600 const gmm::sub_interval &
601 interval_of_variable(
const std::string &name)
const;
605 const model_real_plain_vector &
606 real_variable(
const std::string &name,
size_type niter)
const;
610 const model_real_plain_vector &
611 real_variable(
const std::string &name)
const;
615 const model_complex_plain_vector &
616 complex_variable(
const std::string &name,
size_type niter)
const;
620 const model_complex_plain_vector &
621 complex_variable(
const std::string &name)
const;
625 model_real_plain_vector &
626 set_real_variable(
const std::string &name,
size_type niter)
const;
630 model_real_plain_vector &
631 set_real_variable(
const std::string &name)
const;
635 model_complex_plain_vector &
636 set_complex_variable(
const std::string &name,
size_type niter)
const;
640 model_complex_plain_vector &
641 set_complex_variable(
const std::string &name)
const;
643 model_real_plain_vector &
644 set_real_constant_part(
const std::string &name)
const;
646 model_complex_plain_vector &
647 set_complex_constant_part(
const std::string &name)
const;
650 template<
typename VECTOR,
typename T>
651 void from_variables(VECTOR &V,
bool with_internal, T)
const {
652 for (
const auto &v : variables)
653 if (v.second.is_variable && !v.second.is_affine_dependent
654 && !v.second.is_disabled
655 && (with_internal || !v.second.is_internal))
656 gmm::copy(v.second.real_value[0], gmm::sub_vector(V, v.second.I));
659 template<
typename VECTOR,
typename T>
660 void from_variables(VECTOR &V,
bool with_internal, std::complex<T>)
const {
661 for (
const auto &v : variables)
662 if (v.second.is_variable && !v.second.is_affine_dependent
663 && !v.second.is_disabled
664 && (with_internal || !v.second.is_internal))
665 gmm::copy(v.second.complex_value[0], gmm::sub_vector(V, v.second.I));
669 template<
typename VECTOR>
670 void from_variables(VECTOR &V,
bool with_internal=
false)
const {
671 typedef typename gmm::linalg_traits<VECTOR>::value_type T;
672 context_check();
if (act_size_to_be_done) actualize_sizes();
673 from_variables(V, with_internal, T());
677 template<
typename VECTOR,
typename T>
678 void to_variables(
const VECTOR &V,
bool with_internal, T) {
679 for (
auto &&v : variables)
680 if (v.second.is_variable && !v.second.is_affine_dependent
681 && !v.second.is_disabled
682 && (with_internal || !v.second.is_internal)) {
683 gmm::copy(gmm::sub_vector(V, v.second.I), v.second.real_value[0]);
684 v.second.v_num_data[0] = act_counter();
686 update_affine_dependent_variables();
687 this->post_to_variables_step();
690 template<
typename VECTOR,
typename T>
691 void to_variables(
const VECTOR &V,
bool with_internal, std::complex<T>) {
692 for (
auto &&v : variables)
693 if (v.second.is_variable && !v.second.is_affine_dependent
694 && !v.second.is_disabled
695 && (with_internal || !v.second.is_internal)) {
696 gmm::copy(gmm::sub_vector(V, v.second.I), v.second.complex_value[0]);
697 v.second.v_num_data[0] = act_counter();
699 update_affine_dependent_variables();
700 this->post_to_variables_step();
704 template<
typename VECTOR>
705 void to_variables(
const VECTOR &V,
bool with_internal=
false) {
706 typedef typename gmm::linalg_traits<VECTOR>::value_type T;
707 context_check();
if (act_size_to_be_done) actualize_sizes();
708 to_variables(V, with_internal, T());
713 void add_fixed_size_variable(
const std::string &name,
size_type size,
718 void add_fixed_size_variable(
const std::string &name,
719 const bgeot::multi_index &sizes,
724 void add_fixed_size_data(
const std::string &name,
size_type size,
729 void add_fixed_size_data(
const std::string &name,
730 const bgeot::multi_index &sizes,
734 void resize_fixed_size_variable(
const std::string &name,
size_type size);
737 void resize_fixed_size_variable(
const std::string &name,
738 const bgeot::multi_index &sizes);
742 template <
typename VECT>
745 this->add_fixed_size_data(name, gmm::vect_size(v));
746 if (this->is_complex())
747 gmm::copy(v, this->set_complex_variable(name));
749 gmm::copy(gmm::real_part(v), this->set_real_variable(name));
754 template <
typename VECT>
757 const bgeot::multi_index &sizes) {
758 this->add_fixed_size_data(name, sizes);
759 if (this->is_complex())
760 gmm::copy(v, this->set_complex_variable(name));
762 gmm::copy(gmm::real_part(v), this->set_real_variable(name));
767 void add_initialized_matrix_data(
const std::string &name,
768 const base_matrix &M);
769 void add_initialized_matrix_data(
const std::string &name,
770 const base_complex_matrix &M);
774 void add_initialized_tensor_data(
const std::string &name,
775 const base_tensor &t);
776 void add_initialized_tensor_data(
const std::string &name,
777 const base_complex_tensor &t);
781 template <
typename T>
783 this->add_fixed_size_data(name, 1, 1);
784 if (this->is_complex())
785 this->set_complex_variable(name)[0] = e;
787 this->set_real_variable(name)[0] = gmm::real(e);
792 void add_im_variable(
const std::string &name,
const im_data &imd,
795 void add_internal_im_variable(
const std::string &name,
798 void add_im_data(
const std::string &name,
const im_data &imd,
804 void add_fem_variable(
const std::string &name,
const mesh_fem &mf,
811 void add_filtered_fem_variable(
const std::string &name,
const mesh_fem &mf,
819 void add_affine_dependent_variable(
const std::string &name,
820 const std::string &org_name,
821 scalar_type alpha = scalar_type(1));
824 void add_fem_data(
const std::string &name,
const mesh_fem &mf,
828 void add_fem_data(
const std::string &name,
const mesh_fem &mf,
829 const bgeot::multi_index &sizes,
size_type niter = 1);
834 template <
typename VECT>
837 this->add_fem_data(name, mf,
838 dim_type(gmm::vect_size(v) / mf.
nb_dof()), 1);
839 if (this->is_complex())
840 gmm::copy(v, this->set_complex_variable(name));
842 gmm::copy(gmm::real_part(v), this->set_real_variable(name));
847 template <
typename VECT>
850 const bgeot::multi_index &sizes) {
851 this->add_fem_data(name, mf, sizes, 1);
852 if (this->is_complex())
853 gmm::copy(v, this->set_complex_variable(name));
855 gmm::copy(gmm::real_part(v), this->set_real_variable(name));
864 void add_multiplier(
const std::string &name,
const mesh_fem &mf,
865 const std::string &primal_name,
875 void add_multiplier(
const std::string &name,
const mesh_fem &mf,
876 size_type region,
const std::string &primal_name,
885 void add_multiplier(
const std::string &name,
const mesh_fem &mf,
886 const std::string &primal_name,
const mesh_im &mim,
895 void add_macro(
const std::string &name,
const std::string &expr);
898 void del_macro(
const std::string &name);
902 {
return macro_dict.macro_exists(name); }
905 void delete_variable(
const std::string &varname);
909 const mesh_fem &mesh_fem_of_variable(
const std::string &name)
const;
912 const mesh_fem *pmesh_fem_of_variable(
const std::string &name)
const;
915 bgeot::multi_index qdims_of_variable(
const std::string &name)
const;
916 size_type qdim_of_variable(
const std::string &name)
const;
919 const model_real_sparse_matrix &
921 GMM_ASSERT1(!complex_version,
"This model is a complex one");
922 context_check();
if (act_size_to_be_done) actualize_sizes();
923 return internal ? internal_rTM : rTM;
928 GMM_ASSERT1(complex_version,
"This model is a real one");
929 context_check();
if (act_size_to_be_done) actualize_sizes();
935 const model_real_plain_vector &
real_rhs(
bool with_internal=
false)
const {
936 GMM_ASSERT1(!complex_version,
"This model is a complex one");
937 context_check();
if (act_size_to_be_done) actualize_sizes();
938 return (with_internal && gmm::vect_size(full_rrhs)) ? full_rrhs : rrhs;
944 model_real_plain_vector &
set_real_rhs(
bool with_internal=
false)
const {
945 GMM_ASSERT1(!complex_version,
"This model is a complex one");
946 context_check();
if (act_size_to_be_done) actualize_sizes();
947 return (with_internal && gmm::vect_size(full_rrhs)) ? full_rrhs : rrhs;
953 GMM_ASSERT1(!complex_version,
"This model is a complex one");
954 context_check();
if (act_size_to_be_done) actualize_sizes();
962 const model_real_plain_vector &real_brick_term_rhs
966 GMM_ASSERT1(!complex_version,
"This model is a complex one");
967 context_check();
if (act_size_to_be_done) actualize_sizes();
968 GMM_ASSERT1(valid_bricks[ib],
"Inexistent brick");
969 GMM_ASSERT1(ind_term < bricks[ib].tlist.size(),
"Inexistent term");
970 GMM_ASSERT1(ind_iter < bricks[ib].nbrhs,
"Inexistent iter");
971 GMM_ASSERT1(!sym || bricks[ib].tlist[ind_term].is_symmetric,
972 "Term is not symmetric");
974 return bricks[ib].rveclist_sym[ind_iter][ind_term];
976 return bricks[ib].rveclist[ind_iter][ind_term];
982 GMM_ASSERT1(complex_version,
"This model is a real one");
983 context_check();
if (act_size_to_be_done) actualize_sizes();
991 GMM_ASSERT1(complex_version,
"This model is a real one");
992 context_check();
if (act_size_to_be_done) actualize_sizes();
1000 const model_complex_plain_vector &complex_brick_term_rhs
1004 GMM_ASSERT1(!complex_version,
"This model is a complex one");
1005 context_check();
if (act_size_to_be_done) actualize_sizes();
1006 GMM_ASSERT1(valid_bricks[ib],
"Inexistent brick");
1007 GMM_ASSERT1(ind_term < bricks[ib].tlist.size(),
"Inexistent term");
1008 GMM_ASSERT1(ind_iter < bricks[ib].nbrhs,
"Inexistent iter");
1009 GMM_ASSERT1(!sym || bricks[ib].tlist[ind_term].is_symmetric,
1010 "Term is not symmetric");
1012 return bricks[ib].cveclist_sym[ind_iter][ind_term];
1014 return bricks[ib].cveclist[ind_iter][ind_term];
1018 void listvar(std::ostream &ost)
const;
1020 void listresiduals(std::ostream &ost)
const;
1023 void listbricks(std::ostream &ost,
size_type base_id = 0)
const;
1027 return active_bricks;
1032 GMM_ASSERT1(valid_bricks[ib],
"Inexistent brick");
1033 bricks[ib].terms_to_be_computed =
true;
1041 const varnamelist &datanames,
1042 const termlist &terms,
const mimlist &mims,
1052 void change_terms_of_brick(
size_type ib,
const termlist &terms);
1056 void change_variables_of_brick(
size_type ib,
const varnamelist &vl);
1060 void change_data_of_brick(
size_type ib,
const varnamelist &vl);
1064 void change_mims_of_brick(
size_type ib,
const mimlist &ml);
1068 void change_update_flag_of_brick(
size_type ib,
bool flag);
1070 void set_time(scalar_type t = scalar_type(0),
bool to_init =
true);
1072 scalar_type get_time();
1074 void set_time_step(scalar_type dt) { time_step = dt; }
1075 scalar_type get_time_step()
const {
return time_step; }
1076 scalar_type get_init_time_step()
const {
return init_time_step; }
1077 int is_time_integration()
const {
return time_integration; }
1078 void set_time_integration(
int ti) { time_integration = ti; }
1079 bool is_init_step()
const {
return init_step; }
1080 void cancel_init_step() { init_step =
false; }
1081 void call_init_affine_dependent_variables(
int version);
1082 void shift_variables_for_time_integration();
1083 void copy_init_time_derivative();
1084 void add_time_integration_scheme(
const std::string &varname,
1086 void perform_init_time_derivative(scalar_type ddt)
1087 { init_step =
true; init_time_step = ddt; }
1091 void add_time_dispatcher(
size_type ibrick, pdispatcher pdispatch);
1093 void set_dispatch_coeff();
1096 virtual void first_iter();
1101 virtual void next_iter();
1107 pinterpolate_transformation ptrans) {
1108 if (secondary_domain_exists(name))
1109 GMM_ASSERT1(
false,
"An secondary domain with the same "
1110 "name already exists");
1111 if (transformations.count(name) > 0)
1112 GMM_ASSERT1(name.compare(
"neighbor_element"),
"neighbor_element is a "
1113 "reserved interpolate transformation name");
1114 transformations[name] = ptrans;
1119 pinterpolate_transformation
1121 std::map<std::string, pinterpolate_transformation>::const_iterator
1122 it = transformations.find(name);
1123 GMM_ASSERT1(it != transformations.end(),
"Inexistent transformation " << name);
1130 {
return transformations.count(name) > 0; }
1136 pelementary_transformation ptrans) {
1137 elem_transformations[name] = ptrans;
1142 pelementary_transformation
1144 std::map<std::string, pelementary_transformation>::const_iterator
1145 it = elem_transformations.find(name);
1146 GMM_ASSERT1(it != elem_transformations.end(),
1147 "Inexistent elementary transformation " << name);
1154 {
return elem_transformations.count(name) > 0; }
1161 psecondary_domain ptrans) {
1162 if (interpolate_transformation_exists(name))
1163 GMM_ASSERT1(
false,
"An interpolate transformation with the same "
1164 "name already exists");secondary_domains[name] = ptrans;
1171 auto it = secondary_domains.find(name);
1172 GMM_ASSERT1(it != secondary_domains.end(),
1173 "Inexistent transformation " << name);
1180 {
return secondary_domains.count(name) > 0; }
1184 const std::string &varname_of_brick(
size_type ind_brick,
1189 const std::string &dataname_of_brick(
size_type ind_brick,
1194 virtual void assembly(build_version version);
1204 std::string Neumann_term(
const std::string &varname,
size_type region);
1206 virtual void clear();
1208 explicit model(
bool comp_version =
false);
1213 void check_brick_stiffness_rhs(
size_type ind_brick)
const;
1232 virtual void init_affine_dependent_variables(
model &md)
const = 0;
1233 virtual void init_affine_dependent_variables_precomputation(
model &md)
1235 virtual void time_derivative_to_be_initialized
1236 (std::string &name_v, std::string &name_previous_v)
const = 0;
1237 virtual void shift_variables(
model &md)
const = 0;
1241 void add_theta_method_for_first_order(
model &md,
const std::string &varname,
1244 void add_theta_method_for_second_order(
model &md,
const std::string &varname,
1247 void add_Newmark_scheme(
model &md,
const std::string &varname,
1248 scalar_type beta, scalar_type gamma);
1250 void add_Houbolt_scheme(
model &md,
const std::string &varname);
1268 std::vector<std::string> param_names;
1272 size_type nbrhs()
const {
return nbrhs_; }
1274 typedef model::build_version build_version;
1277 { GMM_ASSERT1(
false,
"Time dispatcher with not set_dispatch_coeff !"); }
1279 virtual void next_real_iter
1281 const model::varnamelist &,
1282 model::real_matlist &,
1283 std::vector<model::real_veclist> &,
1284 std::vector<model::real_veclist> &,
1286 GMM_ASSERT1(
false,
"Time dispatcher with not defined first real iter !");
1289 virtual void next_complex_iter
1291 const model::varnamelist &,
1292 model::complex_matlist &,
1293 std::vector<model::complex_veclist> &,
1294 std::vector<model::complex_veclist> &,
1296 GMM_ASSERT1(
false,
"Time dispatcher with not defined first comples iter");
1299 virtual void asm_real_tangent_terms
1301 model::real_matlist &, std::vector<model::real_veclist> &,
1302 std::vector<model::real_veclist> &,
1303 build_version)
const {
1304 GMM_ASSERT1(
false,
"Time dispatcher with not defined real tangent "
1308 virtual void asm_complex_tangent_terms
1310 model::complex_matlist &, std::vector<model::complex_veclist> &,
1311 std::vector<model::complex_veclist> &,
1312 build_version)
const {
1313 GMM_ASSERT1(
false,
"Time dispatcher with not defined complex tangent "
1318 GMM_ASSERT1(_nbrhs > 0,
"Time dispatcher with no rhs");
1334 typedef model::build_version build_version;
1338 template <
typename MATLIST,
typename VECTLIST>
1340 const model::varnamelist &,
1341 const model::varnamelist &,
1343 VECTLIST &vectl, VECTLIST &vectl_sym,
1344 bool first_iter)
const {
1345 if (first_iter) md.update_brick(ib, model::BUILD_RHS);
1348 for (
size_type i = 0; i < vectl[0].size(); ++i)
1349 gmm::copy(vectl[0][i], vectl[1][i]);
1350 for (
size_type i = 0; i < vectl_sym[0].size(); ++i)
1351 gmm::copy(vectl_sym[0][i], vectl_sym[1][i]);
1355 md.linear_brick_add_to_rhs(ib, 1, 0);
1359 (
const model &md,
size_type ib,
const model::varnamelist &vl,
1360 const model::varnamelist &dl, model::real_matlist &matl,
1361 std::vector<model::real_veclist> &vectl,
1362 std::vector<model::real_veclist> &vectl_sym,
bool first_iter)
const;
1364 void next_complex_iter
1365 (
const model &md,
size_type ib,
const model::varnamelist &vl,
1366 const model::varnamelist &dl,
1367 model::complex_matlist &matl,
1368 std::vector<model::complex_veclist> &vectl,
1369 std::vector<model::complex_veclist> &vectl_sym,
1370 bool first_iter)
const;
1372 void asm_real_tangent_terms
1373 (
const model &md,
size_type ib, model::real_matlist &,
1374 std::vector<model::real_veclist> &,
1375 std::vector<model::real_veclist> &,
1376 build_version version)
const;
1378 virtual void asm_complex_tangent_terms
1379 (
const model &md,
size_type ib, model::complex_matlist &,
1380 std::vector<model::complex_veclist> &,
1381 std::vector<model::complex_veclist> &,
1382 build_version version)
const;
1384 theta_method_dispatcher(
const std::string &THETA);
1398 const std::string &THETA);
1406 (model &md,
const std::string &U,
const std::string &V,
1407 const std::string &pdt,
const std::string &ptheta);
1423 (model &md,
size_type id2dt2b,
const std::string &U,
const std::string &V,
1424 const std::string &pdt,
const std::string &ptwobeta,
1425 const std::string &pgamma);
1449 bool compute_each_time;
1457 typedef model::build_version build_version;
1461 void set_flags(
const std::string &bname,
bool islin,
bool issym,
1462 bool iscoer,
bool ire,
bool isco,
bool each_time =
false) {
1464 islinear = islin; issymmetric = issym; iscoercive = iscoer;
1465 isreal = ire; iscomplex = isco; isinit =
true;
1466 compute_each_time = each_time;
1469 # define BRICK_NOT_INIT GMM_ASSERT1(isinit, "Set brick flags !")
1470 bool is_linear()
const { BRICK_NOT_INIT;
return islinear; }
1471 bool is_symmetric()
const { BRICK_NOT_INIT;
return issymmetric; }
1472 bool is_coercive()
const { BRICK_NOT_INIT;
return iscoercive; }
1473 bool is_real()
const { BRICK_NOT_INIT;
return isreal; }
1474 bool is_complex()
const { BRICK_NOT_INIT;
return iscomplex; }
1475 bool is_to_be_computed_each_time()
const
1476 { BRICK_NOT_INIT;
return compute_each_time; }
1477 const std::string &brick_name()
const { BRICK_NOT_INIT;
return name; }
1494 const model::varnamelist &,
1495 const model::varnamelist &,
1496 const model::mimlist &,
1497 model::real_matlist &,
1498 model::real_veclist &,
1499 model::real_veclist &,
1520 const model::varnamelist &,
1521 const model::varnamelist &,
1522 const model::mimlist &,
1523 model::complex_matlist &,
1524 model::complex_veclist &,
1525 model::complex_veclist &,
1538 const model::varnamelist &,
1539 const model::varnamelist &,
1540 const model::mimlist &,
1541 model::real_matlist &,
1542 model::real_veclist &,
1543 model::real_veclist &,
1552 const model::varnamelist &,
1553 const model::varnamelist &,
1554 const model::mimlist &,
1555 model::complex_matlist &,
1556 model::complex_veclist &,
1557 model::complex_veclist &,
1566 const model::varnamelist &,
1567 const model::varnamelist &,
1568 const model::mimlist &,
1569 model::real_matlist &,
1570 model::real_veclist &,
1571 model::real_veclist &,
1580 const model::varnamelist &,
1581 const model::varnamelist &,
1582 const model::mimlist &,
1583 model::complex_matlist &,
1584 model::complex_veclist &,
1585 model::complex_veclist &,
1591 const model::termlist& tlist,
1592 const model::varnamelist &,
1593 const model::varnamelist &,
1594 const model::mimlist &,
1595 model::real_matlist &,
1596 model::real_veclist &,
1598 const scalar_type delta = 1e-8)
const;
1602 virtual std::string declare_volume_assembly_string
1604 const model::varnamelist &)
const {
1605 GMM_ASSERT1(
false,
"No assemby string declared, computation of Neumann "
1606 "term impossible for brick " << name);
1613 const model::varnamelist &,
1614 const model::varnamelist &,
1615 const model::mimlist &,
1616 model::real_matlist &,
1617 model::real_veclist &,
1618 model::real_veclist &,
1646 (model &md,
const mesh_im &mim,
const std::string &expr,
1648 bool is_coercive =
false,
const std::string &brickname =
"",
1649 bool return_if_nonlin =
false);
1651 inline size_type APIDECL add_linear_generic_assembly_brick
1652 (model &md,
const mesh_im &mim,
const std::string &expr,
1654 bool is_coercive =
false,
const std::string &brickname =
"",
1655 bool return_if_nonlin =
false) {
1657 is_coercive, brickname, return_if_nonlin);
1673 (model &md,
const mesh_im &mim,
const std::string &expr,
1675 bool is_coercive =
false,
const std::string &brickname =
"");
1677 inline size_type APIDECL add_nonlinear_generic_assembly_brick
1678 (model &md,
const mesh_im &mim,
const std::string &expr,
1680 bool is_coercive =
false,
const std::string &brickname =
"") {
1682 is_sym, is_coercive, brickname);
1695 (model &md,
const mesh_im &mim,
const std::string &expr,
1697 const std::string &brickname = std::string(),
1698 const std::string &directvarname = std::string(),
1699 const std::string &directdataname = std::string(),
1700 bool return_if_nonlin =
false);
1701 inline size_type APIDECL add_source_term_generic_assembly_brick
1702 (model &md,
const mesh_im &mim,
const std::string &expr,
1704 const std::string &brickname = std::string(),
1705 const std::string &directvarname = std::string(),
1706 const std::string &directdataname = std::string(),
1707 bool return_if_nonlin =
false) {
1709 directvarname, directdataname, return_if_nonlin);
1719 (model &md,
const mesh_im &mim,
const std::string &expr,
1720 size_type region,
const std::string &secondary_domain,
1721 bool is_sym =
false,
bool is_coercive =
false,
1722 const std::string &brickname =
"",
bool return_if_nonlin =
false);
1731 (model &md,
const mesh_im &mim,
const std::string &expr,
1732 size_type region,
const std::string &secondary_domain,
1733 bool is_sym =
false,
bool is_coercive =
false,
1734 const std::string &brickname =
"");
1743 (model &md,
const mesh_im &mim,
const std::string &expr,
1744 size_type region,
const std::string &secondary_domain,
1745 const std::string &brickname = std::string(),
1746 const std::string &directvarname = std::string(),
1747 const std::string &directdataname = std::string(),
1748 bool return_if_nonlin =
false);
1758 (model &md,
const mesh_im &mim,
const std::string &varname,
1784 (model &md,
const mesh_im &mim,
const std::string &varname,
1798 (model &md,
const mesh_im &mim,
const std::string &varname,
1800 const std::string &directdataname = std::string());
1813 (model &md,
const mesh_im &mim,
const std::string &varname,
1814 const std::string &dataexpr,
size_type region);
1836 (model &md,
const std::string &varname,
size_type region,
1837 const std::string &dataname = std::string());
1851 (model &md,
const mesh_im &mim,
const std::string &varname,
1852 const std::string &multname,
size_type region,
1853 const std::string &dataname = std::string());
1862 (model &md,
const mesh_im &mim,
const std::string &varname,
1863 const mesh_fem &mf_mult,
size_type region,
1864 const std::string &dataname = std::string());
1871 (model &md,
const mesh_im &mim,
const std::string &varname,
1873 const std::string &dataname = std::string());
1895 (model &md,
const mesh_im &mim,
const std::string &varname,
1896 scalar_type penalization_coeff,
size_type region,
1897 const std::string &dataname = std::string(),
1898 const mesh_fem *mf_mult = 0);
1918 (model &md,
const mesh_im &mim,
const std::string &varname,
1919 const std::string &Neumannterm,
1920 const std::string &datagamma0,
size_type region,
1921 scalar_type theta = scalar_type(0),
1922 const std::string &datag = std::string());
1939 (model &md,
const mesh_im &mim,
const std::string &varname,
1940 const std::string &multname,
size_type region,
1941 const std::string &dataname = std::string());
1950 (model &md,
const mesh_im &mim,
const std::string &varname,
1951 const mesh_fem &mf_mult,
size_type region,
1952 const std::string &dataname = std::string());
1959 (model &md,
const mesh_im &mim,
const std::string &varname,
1961 const std::string &dataname = std::string());
1978 (model &md,
const mesh_im &mim,
const std::string &varname,
1979 scalar_type penalization_coeff,
size_type region,
1980 const std::string &dataname = std::string(),
1981 const mesh_fem *mf_mult = 0);
2004 (model &md,
const mesh_im &mim,
const std::string &varname,
2005 const std::string &Neumannterm,
const std::string &datagamma0,
2006 size_type region, scalar_type theta = scalar_type(0),
2007 const std::string &datag = std::string());
2027 (model &md,
const std::string &varname,
2028 scalar_type penalisation_coeff,
const std::string &dataname_pt,
2029 const std::string &dataname_unitv = std::string(),
2030 const std::string &dataname_val = std::string());
2052 (model &md,
const std::string &varname,
2053 const std::string &multname,
const std::string &dataname_pt,
2054 const std::string &dataname_unitv = std::string(),
2055 const std::string &dataname_val = std::string());
2074 (model &md,
const std::string &varname,
const std::string &dataname_pt,
2075 const std::string &dataname_unitv = std::string(),
2076 const std::string &dataname_val = std::string());
2084 scalar_type penalisation_coeff);
2100 (model &md,
const mesh_im &mim,
const std::string &varname,
2101 const std::string &multname,
size_type region,
2102 const std::string &dataname,
const std::string &Hname);
2111 (model &md,
const mesh_im &mim,
const std::string &varname,
2112 const mesh_fem &mf_mult,
size_type region,
2113 const std::string &dataname,
const std::string &Hname);
2120 (model &md,
const mesh_im &mim,
const std::string &varname,
2122 const std::string &dataname,
const std::string &Hname);
2141 (model &md,
const mesh_im &mim,
const std::string &varname,
2142 scalar_type penalization_coeff,
size_type region,
2143 const std::string &dataname,
const std::string &Hname,
2144 const mesh_fem *mf_mult = 0);
2167 (model &md,
const mesh_im &mim,
const std::string &varname,
2168 const std::string &Neumannterm,
const std::string &datagamma0,
2170 const std::string &datag,
const std::string &dataH);
2181 const std::string &varname,
2182 const std::string &dataexpr,
2198 const std::string &varname,
2199 const std::string &dataexpr,
2204 model_real_sparse_matrix APIDECL &set_private_data_brick_real_matrix
2206 model_real_plain_vector APIDECL &set_private_data_brick_real_rhs
2208 model_complex_sparse_matrix APIDECL &set_private_data_brick_complex_matrix
2210 model_complex_plain_vector APIDECL &set_private_data_brick_complex_rhs
2212 size_type APIDECL add_constraint_with_penalization
2213 (model &md,
const std::string &varname, scalar_type penalisation_coeff);
2214 size_type APIDECL add_constraint_with_multipliers
2215 (model &md,
const std::string &varname,
const std::string &multname);
2217 void set_private_data_rhs
2218 (model &md,
size_type indbrick,
const std::string &varname);
2220 template <
typename VECT,
typename T>
2221 void set_private_data_rhs(model &md,
size_type ind,
2223 model_real_plain_vector &LL = set_private_data_brick_real_rhs(md, ind);
2228 template <
typename VECT,
typename T>
2229 void set_private_data_rhs(model &md,
size_type ind,
const VECT &L,
2231 model_complex_plain_vector &LL = set_private_data_brick_complex_rhs(md, ind);
2240 template <
typename VECT>
2242 typedef typename gmm::linalg_traits<VECT>::value_type T;
2243 set_private_data_rhs(md, indbrick, L, T());
2246 template <
typename MAT,
typename T>
2247 void set_private_data_matrix(model &md,
size_type ind,
2249 model_real_sparse_matrix &BB = set_private_data_brick_real_matrix(md, ind);
2250 gmm::resize(BB, gmm::mat_nrows(B), gmm::mat_ncols(B));
2254 template <
typename MAT,
typename T>
2255 void set_private_data_matrix(model &md,
size_type ind,
const MAT &B,
2257 model_complex_sparse_matrix &BB
2258 = set_private_data_brick_complex_matrix(md, ind);
2259 gmm::resize(BB, gmm::mat_nrows(B), gmm::mat_ncols(B));
2266 template <
typename MAT>
2269 typedef typename gmm::linalg_traits<MAT>::value_type T;
2270 set_private_data_matrix(md, indbrick, B, T());
2281 template <
typename MAT,
typename VECT>
2282 size_type add_constraint_with_penalization
2283 (
model &md,
const std::string &varname, scalar_type penalisation_coeff,
2284 const MAT &B,
const VECT &L) {
2286 = add_constraint_with_penalization(md, varname, penalisation_coeff);
2287 size_type n = gmm::mat_nrows(B), m = gmm::mat_ncols(B);
2288 set_private_data_rhs(md, ind, L);
2289 set_private_data_matrix(md, ind, B);
2301 template <
typename MAT,
typename VECT>
2302 size_type add_constraint_with_multipliers
2303 (
model &md,
const std::string &varname,
const std::string &multname,
2304 const MAT &B,
const VECT &L) {
2305 size_type ind = add_constraint_with_multipliers(md, varname, multname);
2306 set_private_data_rhs(md, ind, L);
2307 set_private_data_matrix(md, ind, B);
2311 template <
typename MAT>
2312 size_type add_constraint_with_multipliers
2313 (model &md,
const std::string &varname,
const std::string &multname,
2314 const MAT &B,
const std::string &Lname) {
2315 size_type ind = add_constraint_with_multipliers(md, varname, multname);
2316 set_private_data_rhs(md, ind, Lname);
2317 set_private_data_matrix(md, ind, B);
2321 size_type APIDECL add_explicit_matrix(model &md,
const std::string &varname1,
2322 const std::string &varname2,
2323 bool issymmetric,
bool iscoercive);
2324 size_type APIDECL add_explicit_rhs(model &md,
const std::string &varname);
2336 template <
typename MAT>
2338 const std::string &varname2,
const MAT &B,
2339 bool issymmetric =
false,
2340 bool iscoercive =
false) {
2341 size_type ind = add_explicit_matrix(md, varname1, varname2,
2342 issymmetric, iscoercive);
2343 set_private_data_matrix(md, ind, B);
2353 template <
typename VECT>
2356 size_type ind = add_explicit_rhs(md, varname);
2357 set_private_data_rhs(md, ind, L);
2367 (model &md,
const mesh_im &mim,
const std::string &varname,
2368 const std::string &dataname_lambda,
const std::string &dataname_mu,
2370 const std::string &dataname_preconstraint = std::string());
2380 (model &md,
const mesh_im &mim,
const std::string &varname,
2381 const std::string &data_E,
const std::string &data_nu,
2393 (model &md,
const mesh_im &mim,
const std::string &varname,
2394 const std::string &data_E,
const std::string &data_nu,
2397 void APIDECL compute_isotropic_linearized_Von_Mises_or_Tresca
2398 (model &md,
const std::string &varname,
const std::string &dataname_lambda,
2399 const std::string &dataname_mu,
const mesh_fem &mf_vm,
2400 model_real_plain_vector &VM,
bool tresca);
2407 template <
class VECTVM>
2408 void compute_isotropic_linearized_Von_Mises_or_Tresca
2409 (
model &md,
const std::string &varname,
const std::string &dataname_lambda,
2410 const std::string &dataname_mu,
const mesh_fem &mf_vm,
2411 VECTVM &VM,
bool tresca) {
2412 model_real_plain_vector VMM(mf_vm.
nb_dof());
2413 compute_isotropic_linearized_Von_Mises_or_Tresca
2414 (md, varname, dataname_lambda, dataname_mu, mf_vm, VMM, tresca);
2424 (model &md,
const std::string &varname,
const std::string &data_E,
2425 const std::string &data_nu,
const mesh_fem &mf_vm,
2426 model_real_plain_vector &VM);
2434 (model &md,
const std::string &varname,
const std::string &data_E,
2435 const std::string &data_nu,
const mesh_fem &mf_vm,
2436 model_real_plain_vector &VM);
2459 (model &md,
const mesh_im &mim,
const std::string &varname,
2461 const std::string &dataexpr_penal_coeff = std::string());
2468 (model &md,
const mesh_im &mim,
const std::string &varname,
2469 const std::string &dataexpr_rho = std::string(),
2477 (model &md,
const mesh_im &mim,
const std::string &varname,
2478 const std::string &dataexpr_rho = std::string(),
2488 (model &md,
const mesh_im &mim,
const std::string &varname,
2489 const std::string &dataname_dt,
2490 const std::string &dataname_rho = std::string(),
2501 (model &md,
const mesh_im &mim,
const std::string &varnameU,
2502 const std::string &datanameV,
2503 const std::string &dataname_dt,
2504 const std::string &dataname_alpha,
2505 const std::string &dataname_rho = std::string(),