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 &tensor()
const
225 {
return (is_copied ? tensor_copied->tensor() : t); }
226 base_tensor &tensor()
227 {
return (is_copied ? tensor_copied->tensor() : t); }
230 { sparsity_ = sp; qdim_ = q; }
232 size_type qdim()
const {
return is_copied ? tensor_copied->qdim() : qdim_; }
235 {
return is_copied ? tensor_copied->sparsity() : sparsity_; }
237 inline void set_to_original() { is_copied =
false; }
239 inline void set_to_copy(assembly_tensor &t_) {
240 is_copied =
true; sparsity_ = t_.sparsity_; qdim_ = t_.qdim_;
241 t = t_.tensor(); tensor_copied = &(t_);
244 inline void adjust_sizes(
const bgeot::multi_index &ssizes)
245 { t.adjust_sizes(ssizes); }
247 inline void adjust_sizes()
248 {
if (t.sizes().size() || t.size() != 1) t.init(); }
251 {
if (t.sizes().size() != 1 || t.sizes()[0] != i) t.init(i); }
254 if (t.sizes().size() != 2 || t.sizes()[0] != i || t.sizes()[1] != j)
259 if (t.sizes().size() != 3 || t.sizes()[0] != i || t.sizes()[1] != j
260 || t.sizes()[2] != k)
265 if (t.sizes().size() != 3 || t.sizes()[0] != i || t.sizes()[1] != j
266 || t.sizes()[2] != k || t.sizes()[3] != l)
270 void init_scalar_tensor(scalar_type v)
271 { set_to_original(); t.adjust_sizes(); t[0] = v; }
274 { set_to_original(); t.adjust_sizes(d); }
277 { set_to_original(); t.adjust_sizes(n, m); }
279 void init_identity_matrix_tensor(
size_type n) {
280 init_matrix_tensor(n, n);
281 auto itw = t.begin();
284 *itw++ = (i == j) ? scalar_type(1) : scalar_type(0);
288 { set_to_original(); t.adjust_sizes(n, m, l); }
292 { set_to_original(); t.adjust_sizes(n, m, l, k); }
294 const bgeot::multi_index &sizes()
const {
return t.sizes(); }
297 : is_copied(false), sparsity_(0), qdim_(0), tensor_copied(0) {}
301 typedef ga_tree_node *pga_tree_node;
304 struct ga_tree_node {
305 GA_NODE_TYPE node_type;
306 GA_TOKEN_TYPE op_type;
312 std::string name_test1, name_test2;
314 std::string interpolate_name_test1, interpolate_name_test2;
323 std::string interpolate_name;
324 std::string interpolate_name_der;
326 std::string elementary_name;
328 std::string elementary_target;
333 pga_tree_node parent;
334 std::vector<pga_tree_node> children;
335 scalar_type hash_value;
338 inline const base_tensor &tensor()
const {
return t.tensor(); }
339 inline base_tensor &tensor() {
return t.tensor(); }
340 int sparsity()
const {
return t.sparsity(); }
342 inline size_type nb_test_functions()
const {
343 if (test_function_type ==
size_type(-1))
return 0;
344 return test_function_type - (test_function_type >= 2 ? 1 : 0);
348 {
return t.sizes().size() - nb_test_functions(); }
350 inline size_type tensor_test_size()
const {
352 return (st >= 1 ? t.sizes()[0] : 1) * (st == 2 ? t.sizes()[1] : 1);
355 inline size_type tensor_proper_size()
const
356 {
return t.tensor().size() / tensor_test_size(); }
359 {
return t.sizes()[nb_test_functions()+i]; }
362 void mult_test(
const pga_tree_node n0,
const pga_tree_node n1);
364 bool tensor_is_zero() {
365 if (node_type == GA_NODE_ZERO)
return true;
366 if (node_type != GA_NODE_CONSTANT)
return false;
367 for (
size_type i = 0; i < tensor().size(); ++i)
368 if (tensor()[i] != scalar_type(0))
return false;
372 inline bool is_constant() {
373 return (node_type == GA_NODE_CONSTANT ||
374 (node_type == GA_NODE_ZERO && test_function_type == 0));
377 inline void init_scalar_tensor(scalar_type v)
378 { t.init_scalar_tensor(v); test_function_type = 0; }
380 inline void init_vector_tensor(
size_type d)
381 { t.init_vector_tensor(d); test_function_type = 0; }
384 { t.init_matrix_tensor(n, m); test_function_type = 0; }
386 inline void init_identity_matrix_tensor(
size_type n)
387 { t.init_identity_matrix_tensor(n); test_function_type = 0; }
390 { t.init_third_order_tensor(n, m, l); test_function_type = 0; }
394 { t.init_fourth_order_tensor(n, m, l, k); test_function_type = 0; }
396 inline void adopt_child(pga_tree_node new_child)
397 { children.push_back(new_child); children.back()->parent =
this; }
400 GMM_ASSERT1(i < children.size(),
"Internal error");
401 children[i]->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 &pnode_new);
457 void duplicate_with_operation(pga_tree_node pnode, GA_TOKEN_TYPE op_type);
458 void duplicate_with_addition(pga_tree_node pnode)
459 { duplicate_with_operation(pnode, GA_PLUS); }
460 void duplicate_with_substraction(pga_tree_node pnode)
461 { duplicate_with_operation(pnode, GA_MINUS); }
462 void insert_node(pga_tree_node pnode, GA_NODE_TYPE node_type);
463 void add_child(pga_tree_node pnode, GA_NODE_TYPE node_type = GA_NODE_VOID);
464 void swap(ga_tree &tree) {
465 std::swap(root, tree.root);
466 std::swap(current_node, tree.current_node);
467 std::swap(secondary_domain, tree.secondary_domain);
470 ga_tree() : root(nullptr), current_node(nullptr), secondary_domain() {}
472 ga_tree(
const ga_tree &tree)
473 : root(nullptr), current_node(nullptr),
474 secondary_domain(tree.secondary_domain)
477 copy_node(tree.root, root);
480 ga_tree &operator =(
const ga_tree &tree) {
482 secondary_domain = tree.secondary_domain;
484 copy_node(tree.root, root);
488 ~ga_tree() {
clear(); }
495 bool sub_tree_are_equal
496 (
const pga_tree_node pnode1,
const pga_tree_node pnode2,
497 const ga_workspace &workspace,
int version);
501 void ga_print_node(
const pga_tree_node pnode, std::ostream &str);
503 std::string ga_tree_to_string(
const ga_tree &tree);
507 void ga_read_string(
const std::string &expr, ga_tree &tree,
508 const ga_macro_dictionary ¯o_dict);
509 void ga_read_string_reg(
const std::string &expr, ga_tree &tree,
510 ga_macro_dictionary ¯o_dict);
Inversion of geometric transformations.
region-tree for window/point search on a set of rectangles.
A simple singleton implementation.
A smart pointer that copies the value it points to on copy operations.
A language for generic assembly of pde boundary value problems.
Model representation in Getfem.
Tools for multithreaded, OpenMP and Boost based parallelization.
Basic linear algebra functions.
void clear(L &l)
clear (fill with zeros) a vector or matrix.
size_t size_type
used as the common size type in the library
GEneric Tool for Finite Element Methods.