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_NORMAL,
162 GA_NODE_INTERPOLATE_DERIVATIVE,
164 GA_NODE_ELEMENTARY_VAL,
165 GA_NODE_ELEMENTARY_GRAD,
166 GA_NODE_ELEMENTARY_HESS,
167 GA_NODE_ELEMENTARY_DIVERG,
168 GA_NODE_ELEMENTARY_VAL_TEST,
169 GA_NODE_ELEMENTARY_GRAD_TEST,
170 GA_NODE_ELEMENTARY_HESS_TEST,
171 GA_NODE_ELEMENTARY_DIVERG_TEST,
172 GA_NODE_SECONDARY_DOMAIN,
173 GA_NODE_SECONDARY_DOMAIN_VAL,
174 GA_NODE_SECONDARY_DOMAIN_GRAD,
175 GA_NODE_SECONDARY_DOMAIN_HESS,
176 GA_NODE_SECONDARY_DOMAIN_DIVERG,
177 GA_NODE_SECONDARY_DOMAIN_VAL_TEST,
178 GA_NODE_SECONDARY_DOMAIN_GRAD_TEST,
179 GA_NODE_SECONDARY_DOMAIN_HESS_TEST,
180 GA_NODE_SECONDARY_DOMAIN_DIVERG_TEST,
181 GA_NODE_SECONDARY_DOMAIN_X,
182 GA_NODE_SECONDARY_DOMAIN_NORMAL,
184 GA_NODE_XFEM_PLUS_VAL,
185 GA_NODE_XFEM_PLUS_GRAD,
186 GA_NODE_XFEM_PLUS_HESS,
187 GA_NODE_XFEM_PLUS_DIVERG,
188 GA_NODE_XFEM_PLUS_VAL_TEST,
189 GA_NODE_XFEM_PLUS_GRAD_TEST,
190 GA_NODE_XFEM_PLUS_HESS_TEST,
191 GA_NODE_XFEM_PLUS_DIVERG_TEST,
193 GA_NODE_XFEM_MINUS_VAL,
194 GA_NODE_XFEM_MINUS_GRAD,
195 GA_NODE_XFEM_MINUS_HESS,
196 GA_NODE_XFEM_MINUS_DIVERG,
197 GA_NODE_XFEM_MINUS_VAL_TEST,
198 GA_NODE_XFEM_MINUS_GRAD_TEST,
199 GA_NODE_XFEM_MINUS_HESS_TEST,
200 GA_NODE_XFEM_MINUS_DIVERG_TEST,
203 typedef std::shared_ptr<std::string> pstring;
205 void ga_throw_error_msg(pstring expr,
size_type pos,
206 const std::string &msg);
208 # define ga_throw_error(expr, pos, msg) \
209 { std::stringstream ss; ss << msg; \
210 ga_throw_error_msg(expr, pos, ss.str()); \
211 GMM_ASSERT1(false, "Error in assembly string" ); \
215 struct assembly_tensor {
220 assembly_tensor *tensor_copied;
222 const base_tensor &org_tensor()
const
223 {
return is_copied ? tensor_copied->org_tensor() : t; }
224 base_tensor &org_tensor()
225 {
return is_copied ? tensor_copied->org_tensor() : t; }
227 const base_tensor &tensor()
const
228 {
return (is_copied ? tensor_copied->tensor() : t); }
230 base_tensor &tensor()
231 {
return (is_copied ? tensor_copied->tensor() : t); }
234 { sparsity_ = sp; qdim_ = q; }
236 size_type qdim() {
return is_copied ? tensor_copied->qdim() : qdim_; }
239 {
return is_copied ? tensor_copied->sparsity() : sparsity_; }
241 inline void set_to_original() { is_copied =
false; }
242 inline void set_to_copy(assembly_tensor &t_) {
243 is_copied =
true; sparsity_ = t_.sparsity_; qdim_ = t_.qdim_;
244 t = t_.org_tensor(); tensor_copied = &(t_);
247 inline void adjust_sizes(
const bgeot::multi_index &ssizes)
248 { t.adjust_sizes(ssizes); }
250 inline void adjust_sizes()
251 {
if (t.sizes().size() || t.size() != 1) t.init(); }
254 {
if (t.sizes().size() != 1 || t.sizes()[0] != i) t.init(i); }
257 if (t.sizes().size() != 2 || t.sizes()[0] != i || t.sizes()[1] != j)
262 if (t.sizes().size() != 3 || t.sizes()[0] != i || t.sizes()[1] != j
263 || t.sizes()[2] != k)
268 if (t.sizes().size() != 3 || t.sizes()[0] != i || t.sizes()[1] != j
269 || t.sizes()[2] != k || t.sizes()[3] != l)
273 void init_scalar_tensor(scalar_type v)
274 { set_to_original(); t.adjust_sizes(); t[0] = v; }
277 { set_to_original(); t.adjust_sizes(d); }
280 { set_to_original(); t.adjust_sizes(n, m); }
282 void init_identity_matrix_tensor(
size_type n) {
283 init_matrix_tensor(n, n);
284 auto itw = t.begin();
287 *itw++ = (i == j) ? scalar_type(1) : scalar_type(0);
291 { set_to_original(); t.adjust_sizes(n, m, l); }
295 { set_to_original(); t.adjust_sizes(n, m, l, k); }
297 const bgeot::multi_index &sizes()
const {
return t.sizes(); }
300 : is_copied(false), sparsity_(0), qdim_(0), tensor_copied(0) {}
304 typedef ga_tree_node *pga_tree_node;
307 struct ga_tree_node {
308 GA_NODE_TYPE node_type;
309 GA_TOKEN_TYPE op_type;
315 std::string name_test1, name_test2;
317 std::string interpolate_name_test1, interpolate_name_test2;
326 std::string interpolate_name;
327 std::string interpolate_name_der;
329 std::string elementary_name;
331 std::string elementary_target;
336 pga_tree_node parent;
337 std::vector<pga_tree_node> children;
338 scalar_type hash_value;
341 inline const base_tensor &tensor()
const {
return t.tensor(); }
342 inline base_tensor &tensor() {
return t.tensor(); }
343 int sparsity()
const {
return t.sparsity(); }
345 inline size_type nb_test_functions()
const {
346 if (test_function_type ==
size_type(-1))
return 0;
347 return test_function_type - (test_function_type >= 2 ? 1 : 0);
351 {
return t.sizes().size() - nb_test_functions(); }
353 inline size_type tensor_test_size()
const {
355 return (st >= 1 ? t.sizes()[0] : 1) * (st == 2 ? t.sizes()[1] : 1);
358 inline size_type tensor_proper_size()
const
359 {
return t.org_tensor().size() / tensor_test_size(); }
362 {
return t.sizes()[nb_test_functions()+i]; }
365 void mult_test(
const pga_tree_node n0,
const pga_tree_node n1);
367 bool tensor_is_zero() {
368 if (node_type == GA_NODE_ZERO)
return true;
369 if (node_type != GA_NODE_CONSTANT)
return false;
370 for (
size_type i = 0; i < tensor().size(); ++i)
371 if (tensor()[i] != scalar_type(0))
return false;
375 inline bool is_constant() {
376 return (node_type == GA_NODE_CONSTANT ||
377 (node_type == GA_NODE_ZERO && test_function_type == 0));
380 inline void init_scalar_tensor(scalar_type v)
381 { t.init_scalar_tensor(v); test_function_type = 0; }
383 inline void init_vector_tensor(
size_type d)
384 { t.init_vector_tensor(d); test_function_type = 0; }
387 { t.init_matrix_tensor(n, m); test_function_type = 0; }
389 inline void init_identity_matrix_tensor(
size_type n)
390 { t.init_identity_matrix_tensor(n); test_function_type = 0; }
393 { t.init_third_order_tensor(n, m, l); test_function_type = 0; }
397 { t.init_fourth_order_tensor(n, m, l, k); test_function_type = 0; }
399 inline void adopt_child(pga_tree_node new_child)
400 { children.push_back(new_child); children.back()->parent =
this; }
402 inline void replace_child(pga_tree_node oldchild,
403 pga_tree_node newchild) {
405 for (pga_tree_node &child : children)
406 if (child == oldchild) { child = newchild; found =
true; }
407 GMM_ASSERT1(found,
"Internal error");
411 : node_type(GA_NODE_VOID), test_function_type(-1), qdim1(0), qdim2(0),
412 nbc1(0), nbc2(0), nbc3(0), pos(0), expr(0), der1(0), der2(0),
413 symmetric_op(false), hash_value(0) {}
414 ga_tree_node(GA_NODE_TYPE ty,
size_type p, pstring expr_)
415 : node_type(ty), test_function_type(-1),
416 qdim1(0), qdim2(0), nbc1(0), nbc2(0), nbc3(0),
417 pos(p), expr(expr_), der1(0), der2(0), symmetric_op(false),
419 ga_tree_node(scalar_type v,
size_type p, pstring expr_)
420 : node_type(GA_NODE_CONSTANT), test_function_type(-1),
421 qdim1(0), qdim2(0), nbc1(0), nbc2(0), nbc3(0),
422 pos(p), expr(expr_), der1(0), der2(0), symmetric_op(false),
424 { init_scalar_tensor(v); }
426 : node_type(GA_NODE_NAME), test_function_type(-1),
427 qdim1(0), qdim2(0), nbc1(0), nbc2(0), nbc3(0),
428 pos(p), expr(expr_), name(n, l), der1(0), der2(0), symmetric_op(false),
430 ga_tree_node(GA_TOKEN_TYPE op,
size_type p, pstring expr_)
431 : node_type(GA_NODE_OP), op_type(op), test_function_type(-1),
432 qdim1(0), qdim2(0), nbc1(0), nbc2(0), nbc3(0),
433 pos(p), expr(expr_), der1(0), der2(0), symmetric_op(false),
438 pga_tree_node root, current_node;
439 std::string secondary_domain;
441 void add_scalar(scalar_type val,
size_type pos, pstring expr);
442 void add_allindices(
size_type pos, pstring expr);
445 void add_sub_tree(ga_tree &sub_tree);
446 void add_params(
size_type pos, pstring expr);
447 void add_matrix(
size_type pos, pstring expr);
448 void add_op(GA_TOKEN_TYPE op_type,
size_type pos, pstring expr);
449 void clear_node_rec(pga_tree_node pnode);
450 void clear_node(pga_tree_node pnode);
451 void clear() { clear_node_rec(root); root = current_node =
nullptr; }
452 void clear_children(pga_tree_node pnode);
453 void replace_node_by_child(pga_tree_node pnode,
size_type i);
454 void copy_node(pga_tree_node pnode, pga_tree_node parent,
455 pga_tree_node &child);
456 void duplicate_with_operation(pga_tree_node pnode, GA_TOKEN_TYPE op_type);
457 void duplicate_with_addition(pga_tree_node pnode)
458 { duplicate_with_operation(pnode, GA_PLUS); }
459 void duplicate_with_substraction(pga_tree_node pnode)
460 { duplicate_with_operation(pnode, GA_MINUS); }
461 void insert_node(pga_tree_node pnode, GA_NODE_TYPE node_type);
462 void add_child(pga_tree_node pnode, GA_NODE_TYPE node_type = GA_NODE_VOID);
463 void swap(ga_tree &tree) {
464 std::swap(root, tree.root);
465 std::swap(current_node, tree.current_node);
466 std::swap(secondary_domain, tree.secondary_domain);
469 ga_tree() : root(nullptr), current_node(nullptr), secondary_domain() {}
471 ga_tree(
const ga_tree &tree) : root(nullptr), current_node(nullptr),
472 secondary_domain(tree.secondary_domain)
473 {
if (tree.root) copy_node(tree.root,
nullptr, root); }
475 ga_tree &operator =(
const ga_tree &tree) {
476 clear(); secondary_domain = tree.secondary_domain;
478 copy_node(tree.root,
nullptr,root);
482 ~ga_tree() {
clear(); }
489 bool sub_tree_are_equal
490 (
const pga_tree_node pnode1,
const pga_tree_node pnode2,
491 const ga_workspace &workspace,
int version);
495 void ga_print_node(
const pga_tree_node pnode,
498 std::string ga_tree_to_string(
const ga_tree &tree);
502 void ga_read_string(
const std::string &expr, ga_tree &tree,
503 const ga_macro_dictionary ¯o_dict);
504 void ga_read_string_reg(
const std::string &expr, ga_tree &tree,
505 ga_macro_dictionary ¯o_dict);