24 #include "getfem/getfem_generic_assembly_compile_and_exec.h" 25 #include "getfem/getfem_generic_assembly_functions_and_operators.h" 34 void ga_workspace::init() {
37 K = std::make_shared<model_real_sparse_matrix>(2,2);
38 V = std::make_shared<base_vector>(2);
40 add_interpolate_transformation
45 void ga_workspace::add_fem_variable
46 (
const std::string &name,
const mesh_fem &mf,
47 const gmm::sub_interval &I,
const model_real_plain_vector &VV) {
48 variables[name] = var_description(
true,
true, &mf, I, &VV, 0, 1);
51 void ga_workspace::add_fixed_size_variable
52 (
const std::string &name,
53 const gmm::sub_interval &I,
const model_real_plain_vector &VV) {
54 variables[name] = var_description(
true,
false, 0, I, &VV, 0,
55 dim_type(gmm::vect_size(VV)));
58 void ga_workspace::add_fem_constant
59 (
const std::string &name,
const mesh_fem &mf,
60 const model_real_plain_vector &VV) {
61 GMM_ASSERT1(mf.nb_dof(),
"The provided mesh_fem of variable" << name
62 <<
"has zero degrees of freedom.");
63 size_type Q = gmm::vect_size(VV)/mf.nb_dof();
65 variables[name] = var_description(
false,
true, &mf,
66 gmm::sub_interval(), &VV, 0, Q);
69 void ga_workspace::add_fixed_size_constant
70 (
const std::string &name,
const model_real_plain_vector &VV) {
71 variables[name] = var_description(
false,
false, 0,
72 gmm::sub_interval(), &VV, 0,
76 void ga_workspace::add_im_data(
const std::string &name,
const im_data &imd,
77 const model_real_plain_vector &VV) {
78 variables[name] = var_description
79 (
false,
false, 0, gmm::sub_interval(), &VV, &imd,
80 gmm::vect_size(VV)/(imd.nb_filtered_index() * imd.nb_tensor_elem()));
84 bool ga_workspace::variable_exists(
const std::string &name)
const {
85 return (md && md->variable_exists(name)) ||
86 (parent_workspace && parent_workspace->variable_exists(name)) ||
87 (variables.find(name) != variables.end());
90 bool ga_workspace::variable_group_exists(
const std::string &name)
const {
91 return (variable_groups.find(name) != variable_groups.end()) ||
92 (md && md->variable_group_exists(name)) ||
93 (parent_workspace && parent_workspace->variable_group_exists(name));
96 const std::vector<std::string>&
97 ga_workspace::variable_group(
const std::string &group_name)
const {
98 std::map<std::string, std::vector<std::string> >::const_iterator
99 it = variable_groups.find(group_name);
100 if (it != variable_groups.end())
101 return (variable_groups.find(group_name))->second;
102 if (md && md->variable_group_exists(group_name))
103 return md->variable_group(group_name);
104 if (parent_workspace &&
105 parent_workspace->variable_group_exists(group_name))
106 return parent_workspace->variable_group(group_name);
107 GMM_ASSERT1(
false,
"Undefined variable group " << group_name);
111 ga_workspace::first_variable_of_group(
const std::string &name)
const {
112 const std::vector<std::string> &t = variable_group(name);
113 GMM_ASSERT1(t.size(),
"Variable group " << name <<
" is empty");
117 bool ga_workspace::is_constant(
const std::string &name)
const {
118 VAR_SET::const_iterator it = variables.find(name);
119 if (it != variables.end())
return !(it->second.is_variable);
120 if (variable_group_exists(name))
121 return is_constant(first_variable_of_group(name));
122 if (md && md->variable_exists(name)) {
123 if (enable_all_md_variables)
return md->is_true_data(name);
124 return md->is_data(name);
126 if (parent_workspace && parent_workspace->variable_exists(name))
127 return parent_workspace->is_constant(name);
128 GMM_ASSERT1(
false,
"Undefined variable " << name);
131 bool ga_workspace::is_disabled_variable(
const std::string &name)
const {
132 VAR_SET::const_iterator it = variables.find(name);
133 if (it != variables.end())
return false;
134 if (variable_group_exists(name))
135 return is_disabled_variable(first_variable_of_group(name));
136 if (md && md->variable_exists(name)) {
137 if (enable_all_md_variables)
return false;
138 return md->is_disabled_variable(name);
140 if (parent_workspace && parent_workspace->variable_exists(name))
141 return parent_workspace->is_disabled_variable(name);
142 GMM_ASSERT1(
false,
"Undefined variable " << name);
146 ga_workspace::factor_of_variable(
const std::string &name)
const {
147 static const scalar_type one(1);
148 VAR_SET::const_iterator it = variables.find(name);
149 if (it != variables.end())
return one;
150 if (variable_group_exists(name))
152 if (md && md->variable_exists(name))
return md->factor_of_variable(name);
153 if (parent_workspace && parent_workspace->variable_exists(name))
154 return parent_workspace->factor_of_variable(name);
155 GMM_ASSERT1(
false,
"Undefined variable " << name);
158 const gmm::sub_interval &
159 ga_workspace::interval_of_disabled_variable(
const std::string &name)
const {
160 std::map<std::string, gmm::sub_interval>::const_iterator
161 it1 = int_disabled_variables.find(name);
162 if (it1 != int_disabled_variables.end())
return it1->second;
163 if (md->is_affine_dependent_variable(name))
164 return interval_of_disabled_variable(md->org_variable(name));
167 for (
const std::pair<std::string, gmm::sub_interval> &p
168 : int_disabled_variables)
169 first = std::max(first, p.second.last());
171 int_disabled_variables[name]
172 = gmm::sub_interval(first, gmm::vect_size(value(name)));
173 return int_disabled_variables[name];
176 const gmm::sub_interval &
177 ga_workspace::interval_of_variable(
const std::string &name)
const {
178 VAR_SET::const_iterator it = variables.find(name);
179 if (it != variables.end())
return it->second.I;
180 if (md && md->variable_exists(name)) {
181 if (enable_all_md_variables && md->is_disabled_variable(name))
182 return interval_of_disabled_variable(name);
183 return md->interval_of_variable(name);
185 if (parent_workspace && parent_workspace->variable_exists(name))
186 return parent_workspace->interval_of_variable(name);
187 GMM_ASSERT1(
false,
"Undefined variable " << name);
191 ga_workspace::associated_mf(
const std::string &name)
const {
192 VAR_SET::const_iterator it = variables.find(name);
193 if (it != variables.end())
194 return it->second.is_fem_dofs ? it->second.mf : 0;
195 if (md && md->variable_exists(name))
196 return md->pmesh_fem_of_variable(name);
197 if (parent_workspace && parent_workspace->variable_exists(name))
198 return parent_workspace->associated_mf(name);
199 if (variable_group_exists(name))
200 return associated_mf(first_variable_of_group(name));
201 GMM_ASSERT1(
false,
"Undefined variable or group " << name);
205 ga_workspace::associated_im_data(
const std::string &name)
const {
206 VAR_SET::const_iterator it = variables.find(name);
207 if (it != variables.end())
return it->second.imd;
208 if (md && md->variable_exists(name))
209 return md->pim_data_of_variable(name);
210 if (parent_workspace && parent_workspace->variable_exists(name))
211 return parent_workspace->associated_im_data(name);
212 if (variable_group_exists(name))
return 0;
213 GMM_ASSERT1(
false,
"Undefined variable " << name);
216 size_type ga_workspace::qdim(
const std::string &name)
const {
217 VAR_SET::const_iterator it = variables.find(name);
218 if (it != variables.end()) {
219 const mesh_fem *mf = it->second.is_fem_dofs ? it->second.mf : 0;
220 const im_data *imd = it->second.imd;
223 return n * mf->get_qdim();
225 return n * imd->tensor_size().total_size();
229 if (md && md->variable_exists(name))
230 return md->qdim_of_variable(name);
231 if (parent_workspace && parent_workspace->variable_exists(name))
232 return parent_workspace->qdim(name);
233 if (variable_group_exists(name))
234 return qdim(first_variable_of_group(name));
235 GMM_ASSERT1(
false,
"Undefined variable or group " << name);
239 ga_workspace::qdims(
const std::string &name)
const {
240 VAR_SET::const_iterator it = variables.find(name);
241 if (it != variables.end()) {
242 const mesh_fem *mf = it->second.is_fem_dofs ? it->second.mf : 0;
243 const im_data *imd = it->second.imd;
246 bgeot::multi_index mi = mf->get_qdims();
247 if (n > 1 || it->second.qdims.size() > 1) {
249 if (mi.back() == 1) { mi.back() *= it->second.qdims[0]; ++i; }
250 for (; i < it->second.qdims.size(); ++i)
251 mi.push_back(it->second.qdims[i]);
255 bgeot::multi_index mi = imd->tensor_size();
256 size_type q = n / imd->nb_filtered_index();
257 GMM_ASSERT1(q % imd->nb_tensor_elem() == 0,
258 "Invalid mesh im data vector");
259 if (n > 1 || it->second.qdims.size() > 1) {
261 if (mi.back() == 1) { mi.back() *= it->second.qdims[0]; ++i; }
262 for (; i < it->second.qdims.size(); ++i)
263 mi.push_back(it->second.qdims[i]);
267 return it->second.qdims;
269 if (md && md->variable_exists(name))
270 return md->qdims_of_variable(name);
271 if (parent_workspace && parent_workspace->variable_exists(name))
272 return parent_workspace->qdims(name);
273 if (variable_group_exists(name))
274 return qdims(first_variable_of_group(name));
275 GMM_ASSERT1(
false,
"Undefined variable or group " << name);
278 const model_real_plain_vector &
279 ga_workspace::value(
const std::string &name)
const {
280 VAR_SET::const_iterator it = variables.find(name);
281 if (it != variables.end())
282 return *(it->second.V);
283 if (md && md->variable_exists(name))
284 return md->real_variable(name);
285 if (parent_workspace && parent_workspace->variable_exists(name))
286 return parent_workspace->value(name);
287 if (variable_group_exists(name))
288 return value(first_variable_of_group(name));
289 GMM_ASSERT1(
false,
"Undefined variable or group " << name);
292 scalar_type ga_workspace::get_time_step()
const {
293 if (md)
return md->get_time_step();
294 if (parent_workspace)
return parent_workspace->get_time_step();
295 GMM_ASSERT1(
false,
"No time step defined here");
298 void ga_workspace::add_interpolate_transformation
299 (
const std::string &name, pinterpolate_transformation ptrans) {
300 if (transformations.find(name) != transformations.end())
301 GMM_ASSERT1(name.compare(
"neighbour_elt"),
"neighbour_elt is a " 302 "reserved interpolate transformation name");
303 transformations[name] = ptrans;
306 bool ga_workspace::interpolate_transformation_exists
307 (
const std::string &name)
const {
308 return (md && md->interpolate_transformation_exists(name)) ||
310 parent_workspace->interpolate_transformation_exists(name)) ||
311 (transformations.find(name) != transformations.end());
314 pinterpolate_transformation
315 ga_workspace::interpolate_transformation(
const std::string &name)
const {
316 std::map<std::string, pinterpolate_transformation>::const_iterator
317 it = transformations.find(name);
318 if (it != transformations.end())
return it->second;
319 if (md && md->interpolate_transformation_exists(name))
320 return md->interpolate_transformation(name);
321 if (parent_workspace &&
322 parent_workspace->interpolate_transformation_exists(name))
323 return parent_workspace->interpolate_transformation(name);
324 GMM_ASSERT1(
false,
"Inexistent transformation " << name);
327 bool ga_workspace::elementary_transformation_exists
328 (
const std::string &name)
const {
329 return (md && md->elementary_transformation_exists(name)) ||
331 parent_workspace->elementary_transformation_exists(name)) ||
332 (elem_transformations.find(name) != elem_transformations.end());
335 pelementary_transformation
336 ga_workspace::elementary_transformation(
const std::string &name)
const {
337 std::map<std::string, pelementary_transformation>::const_iterator
338 it = elem_transformations.find(name);
339 if (it != elem_transformations.end())
return it->second;
340 if (md && md->elementary_transformation_exists(name))
341 return md->elementary_transformation(name);
342 if (parent_workspace &&
343 parent_workspace->elementary_transformation_exists(name))
344 return parent_workspace->elementary_transformation(name);
345 GMM_ASSERT1(
false,
"Inexistent elementary transformation " << name);
349 ga_workspace::register_region(
const mesh &m,
const mesh_region ®ion) {
350 if (&m == &dummy_mesh())
351 return dummy_mesh_region();
353 std::list<mesh_region> &lmr = registred_mesh_regions[&m];
354 for (
const mesh_region &rg : lmr)
355 if (rg.compare(m, region, m))
return rg;
356 lmr.push_back(region);
361 void ga_workspace::add_tree(ga_tree &tree,
const mesh &m,
362 const mesh_im &mim,
const mesh_region &rg,
363 const std::string &expr,
365 bool function_expr,
size_type for_interpolation,
366 const std::string varname_interpolation) {
370 if ((tree.root->test_function_type >= 1 &&
371 is_disabled_variable(tree.root->name_test1)) ||
372 (tree.root->test_function_type >= 2 &&
373 is_disabled_variable(tree.root->name_test2))) {
383 if (for_interpolation)
384 order =
size_type(-1) - add_derivative_order;
386 switch(tree.root->test_function_type) {
387 case 0: order = 0;
break;
388 case 1: order = 1;
break;
389 case 3: order = 2;
break;
390 default: GMM_ASSERT1(
false,
"Inconsistent term " 391 << tree.root->test_function_type);
396 for (
size_type i = 0; i < trees.size(); ++i) {
397 if (trees[i].mim == &mim && trees[i].m == &m &&
398 trees[i].order == order &&
399 trees[i].name_test1.compare(tree.root->name_test1) == 0 &&
400 trees[i].interpolate_name_test1.compare
401 (tree.root->interpolate_name_test1) == 0 &&
402 trees[i].name_test2.compare(tree.root->name_test2) == 0 &&
403 trees[i].interpolate_name_test2.compare
404 (tree.root->interpolate_name_test2) == 0 &&
405 trees[i].rg == &rg && trees[i].interpolation == for_interpolation &&
406 trees[i].varname_interpolation.compare(varname_interpolation)==0) {
407 ga_tree &ftree = *(trees[i].ptree);
409 ftree.insert_node(ftree.root, GA_NODE_OP);
410 ftree.root->op_type = GA_PLUS;
411 ftree.root->children.resize(2,
nullptr);
412 ftree.copy_node(tree.root, ftree.root, ftree.root->children[1]);
413 ga_semantic_analysis(ftree, *
this, m,
414 ref_elt_dim_of_mesh(m),
false, function_expr);
421 ind_tree = trees.size(); remain =
false;
422 trees.push_back(tree_description());
423 trees.back().mim = &mim; trees.back().m = &m;
424 trees.back().rg = &rg;
425 trees.back().ptree =
new ga_tree;
426 trees.back().ptree->swap(tree);
427 pga_tree_node root = trees.back().ptree->root;
428 trees.back().name_test1 = root->name_test1;
429 trees.back().name_test2 = root->name_test2;
430 trees.back().interpolate_name_test1 = root->interpolate_name_test1;
431 trees.back().interpolate_name_test2 = root->interpolate_name_test2;
432 trees.back().order = order;
433 trees.back().interpolation = for_interpolation;
434 trees.back().varname_interpolation = varname_interpolation;
437 if (for_interpolation == 0 && order < add_derivative_order) {
438 std::set<var_trans_pair> expr_variables;
439 ga_extract_variables((remain ? tree : *(trees[ind_tree].ptree)).root,
440 *
this, m, expr_variables,
true);
441 for (
const var_trans_pair &var : expr_variables) {
442 if (!(is_constant(var.varname))) {
443 ga_tree dtree = (remain ? tree : *(trees[ind_tree].ptree));
447 ga_derivative(dtree, *
this, m, var.varname, var.transname, 1+order);
449 GA_TOCTIC(
"Derivative time");
450 ga_semantic_analysis(dtree, *
this, m,
451 ref_elt_dim_of_mesh(m),
false, function_expr);
452 GA_TOCTIC(
"Analysis after Derivative time");
454 add_tree(dtree, m, mim, rg, expr, add_derivative_order,
455 function_expr, for_interpolation, varname_interpolation);
462 ga_workspace::m_tree::~m_tree() {
if (ptree)
delete ptree; }
463 ga_workspace::m_tree::m_tree(
const m_tree& o)
464 : ptree(o.ptree), meshdim(o.meshdim), ignore_X(o.ignore_X)
465 {
if (o.ptree) ptree =
new ga_tree(*(o.ptree)); }
466 ga_workspace::m_tree &ga_workspace::m_tree::operator =(
const m_tree& o) {
467 if (ptree)
delete ptree;
468 ptree = o.ptree; meshdim = o.meshdim; ignore_X = o.ignore_X;
469 if (o.ptree) ptree =
new ga_tree(*(o.ptree));
473 size_type ga_workspace::add_expression(
const std::string &expr,
475 const mesh_region &rg_,
477 const mesh_region &rg = register_region(mim.linked_mesh(), rg_);
481 std::vector<ga_tree> ltrees(1);
482 ga_read_string(expr, ltrees[0], macro_dictionnary());
484 ga_semantic_analysis(ltrees[0], *
this, mim.linked_mesh(),
485 ref_elt_dim_of_mesh(mim.linked_mesh()),
488 GA_TOC(
"First analysis time");
489 if (ltrees[0].root) {
490 if (test1.size() > 1 || test2.size() > 1) {
492 size_type nb_ltrees = test1.size()*ntest2;
493 ltrees.resize(nb_ltrees);
494 for (
size_type i = 1; i < nb_ltrees; ++i) ltrees[i] = ltrees[0];
495 std::set<var_trans_pair>::iterator it1 = test1.begin();
496 for (
size_type i = 0; i < test1.size(); ++i, ++it1) {
497 std::set<var_trans_pair>::iterator it2 = test2.begin();
499 selected_test1 = *it1;
500 if (test2.size()) selected_test2 = *it2++;
502 ga_semantic_analysis(ltrees[i*ntest2+j], *
this,
504 ref_elt_dim_of_mesh(mim.linked_mesh()),
511 for (
size_type i = 0; i < ltrees.size(); ++i) {
512 if (ltrees[i].root) {
514 max_order = std::max(ltrees[i].root->nb_test_functions(), max_order);
515 add_tree(ltrees[i], mim.linked_mesh(), mim, rg, expr,
516 add_derivative_order,
true, 0,
"");
520 GA_TOC(
"Time for add expression");
524 void ga_workspace::add_function_expression(
const std::string &expr) {
526 ga_read_string(expr, tree, macro_dictionnary());
527 ga_semantic_analysis(tree, *
this, *((
const mesh *)(0)), 1,
false,
true);
531 add_tree(tree, dummy_mesh(),
dummy_mesh_im(), dummy_mesh_region(),
532 expr, 0,
true, 0,
"");
536 void ga_workspace::add_interpolation_expression(
const std::string &expr,
538 const mesh_region &rg_) {
539 const mesh_region &rg = register_region(m, rg_);
541 ga_read_string(expr, tree, macro_dictionnary());
542 ga_semantic_analysis(tree, *
this, m, ref_elt_dim_of_mesh(m),
547 add_tree(tree, m,
dummy_mesh_im(), rg, expr, 0,
false, 1,
"");
551 void ga_workspace::add_interpolation_expression(
const std::string &expr,
553 const mesh_region &rg_) {
554 const mesh &m = mim.linked_mesh();
555 const mesh_region &rg = register_region(m, rg_);
557 ga_read_string(expr, tree, macro_dictionnary());
558 ga_semantic_analysis(tree, *
this, m, ref_elt_dim_of_mesh(m),
561 GMM_ASSERT1(tree.root->nb_test_functions() == 0,
562 "Invalid expression containing test functions");
563 add_tree(tree, m, mim, rg, expr, 0,
false, 1,
"");
567 void ga_workspace::add_assignment_expression
568 (
const std::string &varname,
const std::string &expr,
const mesh_region &rg_,
570 const im_data *imd = associated_im_data(varname);
571 GMM_ASSERT1(imd != 0,
"Only applicable to im_data");
572 const mesh_im &mim = imd->linked_mesh_im();
573 const mesh &m = mim.linked_mesh();
574 const mesh_region &rg = register_region(m, rg_);
576 ga_read_string(expr, tree, macro_dictionnary());
577 ga_semantic_analysis(tree, *
this, m, ref_elt_dim_of_mesh(m),
false,
false);
579 GMM_ASSERT1(tree.root->nb_test_functions() == 0,
580 "Invalid expression containing test functions");
581 add_tree(tree, m, mim, rg, expr, order+1,
false, (before ? 1 : 2),
586 size_type ga_workspace::nb_trees()
const {
return trees.size(); }
588 ga_workspace::tree_description &ga_workspace::tree_info(
size_type i)
591 bool ga_workspace::used_variables(std::vector<std::string> &vl,
592 std::vector<std::string> &vl_test1,
593 std::vector<std::string> &vl_test2,
594 std::vector<std::string> &dl,
597 std::set<var_trans_pair> vll, dll;
598 for (
size_type i = 0; i < vl.size(); ++i)
599 vll.insert(var_trans_pair(vl[i],
""));
600 for (
size_type i = 0; i < dl.size(); ++i)
601 dll.insert(var_trans_pair(dl[i],
""));
603 for (
size_type i = 0; i < trees.size(); ++i) {
604 ga_workspace::tree_description &td = trees[i];
605 std::set<var_trans_pair> dllaux;
606 bool fv = ga_extract_variables(td.ptree->root, *
this, *(td.m),
609 if (td.order == order) {
610 for (std::set<var_trans_pair>::iterator it = dllaux.begin();
611 it!=dllaux.end(); ++it)
617 if (td.order == order) {
618 if (variable_group_exists(td.name_test1)) {
619 for (
const std::string &t : variable_group(td.name_test1))
620 vll.insert(var_trans_pair(t, td.interpolate_name_test1));
622 vll.insert(var_trans_pair(td.name_test1,
623 td.interpolate_name_test1));
626 for (
const std::string &t : vl_test1)
627 if (td.name_test1.compare(t) == 0)
630 vl_test1.push_back(td.name_test1);
634 if (td.order == order) {
635 if (variable_group_exists(td.name_test1)) {
636 for (
const std::string &t : variable_group(td.name_test1))
637 vll.insert(var_trans_pair(t, td.interpolate_name_test1));
639 vll.insert(var_trans_pair(td.name_test1,
640 td.interpolate_name_test1));
642 if (variable_group_exists(td.name_test2)) {
643 for (
const std::string &t : variable_group(td.name_test2))
644 vll.insert(var_trans_pair(t, td.interpolate_name_test2));
646 vll.insert(var_trans_pair(td.name_test2,
647 td.interpolate_name_test2));
650 for (
size_type j = 0; j < vl_test1.size(); ++j)
651 if ((td.name_test1.compare(vl_test1[j]) == 0) &&
652 (td.name_test2.compare(vl_test2[j]) == 0))
655 vl_test1.push_back(td.name_test1);
656 vl_test2.push_back(td.name_test2);
659 if (fv) islin =
false;
664 for (
const auto &var : vll)
665 if (vl.size() == 0 || var.varname.compare(vl.back()))
666 vl.push_back(var.varname);
668 for (
const auto &var : dll)
669 if (dl.size() == 0 || var.varname.compare(dl.back()))
670 dl.push_back(var.varname);
675 void ga_workspace::define_variable_group(
const std::string &group_name,
676 const std::vector<std::string> &nl) {
677 GMM_ASSERT1(!(variable_exists(group_name)),
"The name of a group of " 678 "variables cannot be the same as a variable name");
680 std::set<const mesh *> ms;
681 bool is_data_ =
false;
682 for (
size_type i = 0; i < nl.size(); ++i) {
684 is_data_ = is_constant(nl[i]);
686 GMM_ASSERT1(is_data_ == is_constant(nl[i]),
687 "It is not possible to mix variables and data in a group");
689 GMM_ASSERT1(variable_exists(nl[i]),
690 "All variables in a group have to exist in the model");
691 const mesh_fem *mf = associated_mf(nl[i]);
692 GMM_ASSERT1(mf,
"Variables in a group should be fem variables");
693 GMM_ASSERT1(ms.find(&(mf->linked_mesh())) == ms.end(),
694 "Two variables in a group cannot share the same mesh");
695 ms.insert(&(mf->linked_mesh()));
697 variable_groups[group_name] = nl;
701 const std::string &ga_workspace::variable_in_group
702 (
const std::string &group_name,
const mesh &m)
const {
703 if (variable_group_exists(group_name)) {
704 for (
const std::string &t : variable_group(group_name))
705 if (&(associated_mf(t)->linked_mesh()) == &m)
707 GMM_ASSERT1(
false,
"No variable in this group for the given mesh");
713 void ga_workspace::assembly(
size_type order) {
715 const ga_workspace *w =
this;
716 while (w->parent_workspace) w = w->parent_workspace;
717 if (w->md) ndof = w->md->nb_dof();
720 ga_instruction_set gis;
721 ga_compile(*
this, gis, order);
724 GA_TOCTIC(
"Compile time");
743 GA_TOCTIC(
"Init time");
746 GA_TOCTIC(
"Exec time");
749 MPI_SUM_VECTOR(assembled_vector());
750 MPI_SUM_VECTOR(unreduced_V);
751 }
else if (order == 0) {
752 MPI_SUM_VECTOR(assembled_tensor().as_vector());
757 std::set<std::string> vars_vec_done;
758 std::set<std::pair<std::string, std::string> > vars_mat_done;
759 for (ga_tree &tree : gis.trees) {
762 const std::string &name = tree.root->name_test1;
763 const std::vector<std::string> vnames_(1,name);
764 const std::vector<std::string> &vnames
765 = variable_group_exists(name) ? variable_group(name)
767 for (
const std::string &vname : vnames) {
768 const mesh_fem *mf = associated_mf(vname);
769 if (mf && mf->is_reduced() &&
770 vars_vec_done.find(vname) == vars_vec_done.end()) {
772 gmm::sub_vector(unreduced_V,
773 gis.var_intervals[vname]),
775 interval_of_variable(vname)));
776 vars_vec_done.insert(vname);
780 std::string &name1 = tree.root->name_test1;
781 std::string &name2 = tree.root->name_test2;
782 const std::vector<std::string> vnames1_(1,name1),
784 const std::vector<std::string> &vnames1
785 = variable_group_exists(name1) ? variable_group(name1)
787 const std::vector<std::string> &vnames2
788 = variable_group_exists(name2) ? variable_group(name2)
790 for (
const std::string &vname1 : vnames1) {
791 for (
const std::string &vname2 : vnames2) {
792 const mesh_fem *mf1 = associated_mf(vname1);
793 const mesh_fem *mf2 = associated_mf(vname2);
794 if (((mf1 && mf1->is_reduced())
795 || (mf2 && mf2->is_reduced()))) {
796 std::pair<std::string, std::string> p(vname1, vname2);
797 if (vars_mat_done.find(p) == vars_mat_done.end()) {
798 gmm::sub_interval uI1 = gis.var_intervals[vname1];
799 gmm::sub_interval uI2 = gis.var_intervals[vname2];
800 gmm::sub_interval I1 = interval_of_variable(vname1);
801 gmm::sub_interval I2 = interval_of_variable(vname2);
802 if ((mf1 && mf1->is_reduced()) &&
803 (mf2 && mf2->is_reduced())) {
804 model_real_sparse_matrix aux(I1.size(), uI2.size());
805 model_real_row_sparse_matrix M(I1.size(), I2.size());
806 gmm::mult(gmm::transposed(mf1->extension_matrix()),
807 gmm::sub_matrix(unreduced_K, uI1, uI2), aux);
808 gmm::mult(aux, mf2->extension_matrix(), M);
809 gmm::add(M, gmm::sub_matrix(*K, I1, I2));
810 }
else if (mf1 && mf1->is_reduced()) {
811 model_real_sparse_matrix M(I1.size(), I2.size());
812 gmm::mult(gmm::transposed(mf1->extension_matrix()),
813 gmm::sub_matrix(unreduced_K, uI1, uI2), M);
814 gmm::add(M, gmm::sub_matrix(*K, I1, I2));
816 model_real_row_sparse_matrix M(I1.size(), I2.size());
817 gmm::mult(gmm::sub_matrix(unreduced_K, uI1, uI2),
818 mf2->extension_matrix(), M);
819 gmm::add(M, gmm::sub_matrix(*K, I1, I2));
821 vars_mat_done.insert(p);
832 void ga_workspace::set_include_empty_int_points(
bool include) {
833 include_empty_int_pts = include;
836 bool ga_workspace::include_empty_int_points()
const {
837 return include_empty_int_pts;
840 void ga_workspace::clear_expressions() { trees.clear(); }
842 void ga_workspace::print(std::ostream &str) {
843 for (
size_type i = 0; i < trees.size(); ++i)
844 if (trees[i].ptree->root) {
845 cout <<
"Expression tree " << i <<
" of order " <<
846 trees[i].ptree->root->nb_test_functions() <<
" :" << endl;
847 ga_print_node(trees[i].ptree->root, str);
852 void ga_workspace::tree_description::copy(
const tree_description& td) {
855 varname_interpolation = td.varname_interpolation;
856 name_test1 = td.name_test1;
857 name_test2 = td.name_test2;
858 interpolate_name_test1 = td.interpolate_name_test1;
859 interpolate_name_test2 = td.interpolate_name_test2;
864 if (td.ptree) ptree =
new ga_tree(*(td.ptree));
867 ga_workspace::tree_description &ga_workspace::tree_description::operator =
868 (
const ga_workspace::tree_description& td)
869 {
if (ptree)
delete ptree; ptree = 0;
copy(td);
return *
this; }
870 ga_workspace::tree_description::~tree_description()
871 {
if (ptree)
delete ptree; ptree = 0; }
874 bool enable_all_variables)
875 : md(&md_), parent_workspace(0),
876 enable_all_md_variables(enable_all_variables),
877 macro_dict(md_.macro_dictionnary())
879 ga_workspace::ga_workspace(
bool,
const ga_workspace &gaw)
880 : md(0), parent_workspace(&gaw), enable_all_md_variables(false),
881 macro_dict(gaw.macro_dictionnary())
883 ga_workspace::ga_workspace()
884 : md(0), parent_workspace(0), enable_all_md_variables(false)
886 ga_workspace::~ga_workspace() { clear_expressions(); }
892 std::string ga_workspace::extract_constant_term(
const mesh &m) {
893 std::string constant_term;
894 for (
size_type i = 0; i < trees.size(); ++i) {
895 ga_workspace::tree_description &td = trees[i];
898 ga_tree local_tree = *(td.ptree);
900 ga_node_extract_constant_term(local_tree, local_tree.root, *
this, m);
902 ga_semantic_analysis(local_tree, *
this, m,
903 ref_elt_dim_of_mesh(m),
false,
false);
904 if (local_tree.root && local_tree.root->node_type != GA_NODE_ZERO) {
905 constant_term +=
"-("+ga_tree_to_string(local_tree)+
")";
909 return constant_term;
916 std::string ga_workspace::extract_order0_term() {
918 for (
size_type i = 0; i < trees.size(); ++i) {
919 ga_workspace::tree_description &td = trees[i];
921 ga_tree &local_tree = *(td.ptree);
923 term +=
"+("+ga_tree_to_string(local_tree)+
")";
925 term =
"("+ga_tree_to_string(local_tree)+
")";
936 std::string ga_workspace::extract_order1_term(
const std::string &varname) {
938 for (
size_type i = 0; i < trees.size(); ++i) {
939 ga_workspace::tree_description &td = trees[i];
940 if (td.order == 1 && td.name_test1.compare(varname) == 0) {
941 ga_tree &local_tree = *(td.ptree);
943 term +=
"+("+ga_tree_to_string(local_tree)+
")";
945 term =
"("+ga_tree_to_string(local_tree)+
")";
955 std::string ga_workspace::extract_Neumann_term(
const std::string &varname) {
957 for (
size_type i = 0; i < trees.size(); ++i) {
958 ga_workspace::tree_description &td = trees[i];
959 if (td.order == 1 && td.name_test1.compare(varname) == 0) {
960 ga_tree &local_tree = *(td.ptree);
962 ga_extract_Neumann_term(local_tree, varname, *
this,
963 local_tree.root, result);
const mesh_im & dummy_mesh_im()
Dummy mesh_im for default parameter of functions.
void interpolation(const mesh_fem &mf_source, const mesh_fem &mf_target, const VECTU &U, VECTV &V, int extrapolation=0, double EPS=1E-10, mesh_region rg_source=mesh_region::all_convexes(), mesh_region rg_target=mesh_region::all_convexes())
interpolation/extrapolation of (mf_source, U) on mf_target.
pinterpolate_transformation interpolate_transformation_neighbour_instance()
Create a new instance of a transformation corresponding to the interpolation on the neighbour element...
Semantic analysis of assembly trees and semantic manipulations.
``Model'' variables store the variables, the data and the description of a model. ...
size_t size_type
used as the common size type in the library
void copy(const L1 &l1, L2 &l2)
*/
GEneric Tool for Finite Element Methods.
void clear(L &l)
clear (fill with zeros) a vector or matrix.
void mult_add(const L1 &l1, const L2 &l2, L3 &l3)
*/
Compilation and execution operations.
void resize(M &v, size_type m, size_type n)
*/