39 #ifndef GETFEM_GENERIC_ASSEMBLY_TREE_H__
40 #define GETFEM_GENERIC_ASSEMBLY_TREE_H__
57 #define GA_DEBUG_ASSERT(a, b) GMM_ASSERT1(a, b)
65 # define GA_TIC scalar_type _ga_time_ = gmm::uclock_sec();
66 # define GA_TOC(a) { cout <<(a)<<" : "<<gmm::uclock_sec()-_ga_time_<< endl; }
67 # define GA_TOCTIC(a) { GA_TOC(a); _ga_time_ = gmm::uclock_sec(); }
92 GA_INTERPOLATE_FILTER,
93 GA_INTERPOLATE_DERIVATIVE,
115 size_type ga_parse_prefix_operator(std::string &name);
117 size_type ga_parse_prefix_test(std::string &name);
131 GA_NODE_CROSS_PRODUCT,
133 GA_NODE_IND_MOVE_LAST,
151 GA_NODE_INTERPOLATE_FILTER,
152 GA_NODE_INTERPOLATE_VAL,
153 GA_NODE_INTERPOLATE_GRAD,
154 GA_NODE_INTERPOLATE_HESS,
155 GA_NODE_INTERPOLATE_DIVERG,
156 GA_NODE_INTERPOLATE_VAL_TEST,
157 GA_NODE_INTERPOLATE_GRAD_TEST,
158 GA_NODE_INTERPOLATE_HESS_TEST,
159 GA_NODE_INTERPOLATE_DIVERG_TEST,
160 GA_NODE_INTERPOLATE_X,
161 GA_NODE_INTERPOLATE_ELT_K,
162 GA_NODE_INTERPOLATE_ELT_B,
163 GA_NODE_INTERPOLATE_NORMAL,
164 GA_NODE_INTERPOLATE_DERIVATIVE,
166 GA_NODE_ELEMENTARY_VAL,
167 GA_NODE_ELEMENTARY_GRAD,
168 GA_NODE_ELEMENTARY_HESS,
169 GA_NODE_ELEMENTARY_DIVERG,
170 GA_NODE_ELEMENTARY_VAL_TEST,
171 GA_NODE_ELEMENTARY_GRAD_TEST,
172 GA_NODE_ELEMENTARY_HESS_TEST,
173 GA_NODE_ELEMENTARY_DIVERG_TEST,
174 GA_NODE_SECONDARY_DOMAIN,
175 GA_NODE_SECONDARY_DOMAIN_VAL,
176 GA_NODE_SECONDARY_DOMAIN_GRAD,
177 GA_NODE_SECONDARY_DOMAIN_HESS,
178 GA_NODE_SECONDARY_DOMAIN_DIVERG,
179 GA_NODE_SECONDARY_DOMAIN_VAL_TEST,
180 GA_NODE_SECONDARY_DOMAIN_GRAD_TEST,
181 GA_NODE_SECONDARY_DOMAIN_HESS_TEST,
182 GA_NODE_SECONDARY_DOMAIN_DIVERG_TEST,
183 GA_NODE_SECONDARY_DOMAIN_X,
184 GA_NODE_SECONDARY_DOMAIN_NORMAL,
186 GA_NODE_XFEM_PLUS_VAL,
187 GA_NODE_XFEM_PLUS_GRAD,
188 GA_NODE_XFEM_PLUS_HESS,
189 GA_NODE_XFEM_PLUS_DIVERG,
190 GA_NODE_XFEM_PLUS_VAL_TEST,
191 GA_NODE_XFEM_PLUS_GRAD_TEST,
192 GA_NODE_XFEM_PLUS_HESS_TEST,
193 GA_NODE_XFEM_PLUS_DIVERG_TEST,
195 GA_NODE_XFEM_MINUS_VAL,
196 GA_NODE_XFEM_MINUS_GRAD,
197 GA_NODE_XFEM_MINUS_HESS,
198 GA_NODE_XFEM_MINUS_DIVERG,
199 GA_NODE_XFEM_MINUS_VAL_TEST,
200 GA_NODE_XFEM_MINUS_GRAD_TEST,
201 GA_NODE_XFEM_MINUS_HESS_TEST,
202 GA_NODE_XFEM_MINUS_DIVERG_TEST,
205 typedef std::shared_ptr<std::string> pstring;
207 void ga_throw_error_msg(pstring expr,
size_type pos,
208 const std::string &msg);
210 # define ga_throw_error(expr, pos, msg) \
211 { std::stringstream ss; ss << msg; \
212 ga_throw_error_msg(expr, pos, ss.str()); \
213 GMM_ASSERT1(false, "Error in assembly string" ); \
217 struct assembly_tensor {
222 assembly_tensor *tensor_copied;
224 const base_tensor &org_tensor()
const
225 {
return is_copied ? tensor_copied->org_tensor() : t; }
226 base_tensor &org_tensor()
227 {
return is_copied ? tensor_copied->org_tensor() : t; }
229 const base_tensor &tensor()
const
230 {
return (is_copied ? tensor_copied->tensor() : t); }
232 base_tensor &tensor()
233 {
return (is_copied ? tensor_copied->tensor() : t); }
236 { sparsity_ = sp; qdim_ = q; }
238 size_type qdim() {
return is_copied ? tensor_copied->qdim() : qdim_; }
241 {
return is_copied ? tensor_copied->sparsity() : sparsity_; }
243 inline void set_to_original() { is_copied =
false; }
244 inline void set_to_copy(assembly_tensor &t_) {
245 is_copied =
true; sparsity_ = t_.sparsity_; qdim_ = t_.qdim_;
246 t = t_.org_tensor(); tensor_copied = &(t_);
249 inline void adjust_sizes(
const bgeot::multi_index &ssizes)
250 { t.adjust_sizes(ssizes); }
252 inline void adjust_sizes()
253 {
if (t.sizes().size() || t.size() != 1) t.init(); }
256 {
if (t.sizes().size() != 1 || t.sizes()[0] != i) t.init(i); }
259 if (t.sizes().size() != 2 || t.sizes()[0] != i || t.sizes()[1] != j)
264 if (t.sizes().size() != 3 || t.sizes()[0] != i || t.sizes()[1] != j
265 || t.sizes()[2] != k)
270 if (t.sizes().size() != 3 || t.sizes()[0] != i || t.sizes()[1] != j
271 || t.sizes()[2] != k || t.sizes()[3] != l)
275 void init_scalar_tensor(scalar_type v)
276 { set_to_original(); t.adjust_sizes(); t[0] = v; }
279 { set_to_original(); t.adjust_sizes(d); }
282 { set_to_original(); t.adjust_sizes(n, m); }
284 void init_identity_matrix_tensor(
size_type n) {
285 init_matrix_tensor(n, n);
286 auto itw = t.begin();
289 *itw++ = (i == j) ? scalar_type(1) : scalar_type(0);
293 { set_to_original(); t.adjust_sizes(n, m, l); }
297 { set_to_original(); t.adjust_sizes(n, m, l, k); }
299 const bgeot::multi_index &sizes()
const {
return t.sizes(); }
302 : is_copied(false), sparsity_(0), qdim_(0), tensor_copied(0) {}
306 typedef ga_tree_node *pga_tree_node;
309 struct ga_tree_node {
310 GA_NODE_TYPE node_type;
311 GA_TOKEN_TYPE op_type;
317 std::string name_test1, name_test2;
319 std::string interpolate_name_test1, interpolate_name_test2;
328 std::string interpolate_name;
329 std::string interpolate_name_der;
331 std::string elementary_name;
333 std::string elementary_target;
338 pga_tree_node parent;
339 std::vector<pga_tree_node> children;
340 scalar_type hash_value;
343 inline const base_tensor &tensor()
const {
return t.tensor(); }
344 inline base_tensor &tensor() {
return t.tensor(); }
345 int sparsity()
const {
return t.sparsity(); }
347 inline size_type nb_test_functions()
const {
348 if (test_function_type ==
size_type(-1))
return 0;
349 return test_function_type - (test_function_type >= 2 ? 1 : 0);
353 {
return t.sizes().size() - nb_test_functions(); }
355 inline size_type tensor_test_size()
const {
357 return (st >= 1 ? t.sizes()[0] : 1) * (st == 2 ? t.sizes()[1] : 1);
360 inline size_type tensor_proper_size()
const
361 {
return t.org_tensor().size() / tensor_test_size(); }
364 {
return t.sizes()[nb_test_functions()+i]; }
367 void mult_test(
const pga_tree_node n0,
const pga_tree_node n1);
369 bool tensor_is_zero() {
370 if (node_type == GA_NODE_ZERO)
return true;
371 if (node_type != GA_NODE_CONSTANT)
return false;
372 for (
size_type i = 0; i < tensor().size(); ++i)
373 if (tensor()[i] != scalar_type(0))
return false;
377 inline bool is_constant() {
378 return (node_type == GA_NODE_CONSTANT ||
379 (node_type == GA_NODE_ZERO && test_function_type == 0));
382 inline void init_scalar_tensor(scalar_type v)
383 { t.init_scalar_tensor(v); test_function_type = 0; }
385 inline void init_vector_tensor(
size_type d)
386 { t.init_vector_tensor(d); test_function_type = 0; }
389 { t.init_matrix_tensor(n, m); test_function_type = 0; }
391 inline void init_identity_matrix_tensor(
size_type n)
392 { t.init_identity_matrix_tensor(n); test_function_type = 0; }
395 { t.init_third_order_tensor(n, m, l); test_function_type = 0; }
399 { t.init_fourth_order_tensor(n, m, l, k); test_function_type = 0; }
401 inline void adopt_child(pga_tree_node new_child)
402 { children.push_back(new_child); children.back()->parent =
this; }
404 inline void replace_child(pga_tree_node oldchild,
405 pga_tree_node newchild) {
407 for (pga_tree_node &child : children)
408 if (child == oldchild) { child = newchild; found =
true; }
409 GMM_ASSERT1(found,
"Internal error");
413 : node_type(GA_NODE_VOID), test_function_type(-1), qdim1(0), qdim2(0),
414 nbc1(0), nbc2(0), nbc3(0), pos(0), expr(0), der1(0), der2(0),
415 symmetric_op(false), hash_value(0) {}
416 ga_tree_node(GA_NODE_TYPE ty,
size_type p, pstring expr_)
417 : node_type(ty), test_function_type(-1),
418 qdim1(0), qdim2(0), nbc1(0), nbc2(0), nbc3(0),
419 pos(p), expr(expr_), der1(0), der2(0), symmetric_op(false),
421 ga_tree_node(scalar_type v,
size_type p, pstring expr_)
422 : node_type(GA_NODE_CONSTANT), test_function_type(-1),
423 qdim1(0), qdim2(0), nbc1(0), nbc2(0), nbc3(0),
424 pos(p), expr(expr_), der1(0), der2(0), symmetric_op(false),
426 { init_scalar_tensor(v); }
428 : node_type(GA_NODE_NAME), test_function_type(-1),
429 qdim1(0), qdim2(0), nbc1(0), nbc2(0), nbc3(0),
430 pos(p), expr(expr_), name(n, l), der1(0), der2(0), symmetric_op(false),
432 ga_tree_node(GA_TOKEN_TYPE op,
size_type p, pstring expr_)
433 : node_type(GA_NODE_OP), op_type(op), test_function_type(-1),
434 qdim1(0), qdim2(0), nbc1(0), nbc2(0), nbc3(0),
435 pos(p), expr(expr_), der1(0), der2(0), symmetric_op(false),
440 pga_tree_node root, current_node;
441 std::string secondary_domain;
443 void add_scalar(scalar_type val,
size_type pos, pstring expr);
444 void add_allindices(
size_type pos, pstring expr);
447 void add_sub_tree(ga_tree &sub_tree);
448 void add_params(
size_type pos, pstring expr);
449 void add_matrix(
size_type pos, pstring expr);
450 void add_op(GA_TOKEN_TYPE op_type,
size_type pos, pstring expr);
451 void clear_node_rec(pga_tree_node pnode);
452 void clear_node(pga_tree_node pnode);
453 void clear() { clear_node_rec(root); root = current_node =
nullptr; }
454 void clear_children(pga_tree_node pnode);
455 void replace_node_by_child(pga_tree_node pnode,
size_type i);
456 void copy_node(pga_tree_node pnode, pga_tree_node parent,
457 pga_tree_node &child);
458 void duplicate_with_operation(pga_tree_node pnode, GA_TOKEN_TYPE op_type);
459 void duplicate_with_addition(pga_tree_node pnode)
460 { duplicate_with_operation(pnode, GA_PLUS); }
461 void duplicate_with_substraction(pga_tree_node pnode)
462 { duplicate_with_operation(pnode, GA_MINUS); }
463 void insert_node(pga_tree_node pnode, GA_NODE_TYPE node_type);
464 void add_child(pga_tree_node pnode, GA_NODE_TYPE node_type = GA_NODE_VOID);
465 void swap(ga_tree &tree) {
466 std::swap(root, tree.root);
467 std::swap(current_node, tree.current_node);
468 std::swap(secondary_domain, tree.secondary_domain);
471 ga_tree() : root(nullptr), current_node(nullptr), secondary_domain() {}
473 ga_tree(
const ga_tree &tree) : root(nullptr), current_node(nullptr),
474 secondary_domain(tree.secondary_domain)
475 {
if (tree.root) copy_node(tree.root,
nullptr, root); }
477 ga_tree &operator =(
const ga_tree &tree) {
478 clear(); secondary_domain = tree.secondary_domain;
480 copy_node(tree.root,
nullptr,root);
484 ~ga_tree() {
clear(); }
491 bool sub_tree_are_equal
492 (
const pga_tree_node pnode1,
const pga_tree_node pnode2,
493 const ga_workspace &workspace,
int version);
497 void ga_print_node(
const pga_tree_node pnode,
500 std::string ga_tree_to_string(
const ga_tree &tree);
504 void ga_read_string(
const std::string &expr, ga_tree &tree,
505 const ga_macro_dictionary ¯o_dict);
506 void ga_read_string_reg(
const std::string &expr, ga_tree &tree,
507 ga_macro_dictionary ¯o_dict);