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,
113 size_type ga_parse_prefix_operator(std::string &name);
115 size_type ga_parse_prefix_test(std::string &name);
130 GA_NODE_IND_MOVE_LAST,
148 GA_NODE_INTERPOLATE_FILTER,
149 GA_NODE_INTERPOLATE_VAL,
150 GA_NODE_INTERPOLATE_GRAD,
151 GA_NODE_INTERPOLATE_HESS,
152 GA_NODE_INTERPOLATE_DIVERG,
153 GA_NODE_INTERPOLATE_VAL_TEST,
154 GA_NODE_INTERPOLATE_GRAD_TEST,
155 GA_NODE_INTERPOLATE_HESS_TEST,
156 GA_NODE_INTERPOLATE_DIVERG_TEST,
157 GA_NODE_INTERPOLATE_X,
158 GA_NODE_INTERPOLATE_NORMAL,
159 GA_NODE_INTERPOLATE_DERIVATIVE,
161 GA_NODE_ELEMENTARY_VAL,
162 GA_NODE_ELEMENTARY_GRAD,
163 GA_NODE_ELEMENTARY_HESS,
164 GA_NODE_ELEMENTARY_DIVERG,
165 GA_NODE_ELEMENTARY_VAL_TEST,
166 GA_NODE_ELEMENTARY_GRAD_TEST,
167 GA_NODE_ELEMENTARY_HESS_TEST,
168 GA_NODE_ELEMENTARY_DIVERG_TEST,
170 GA_NODE_XFEM_PLUS_VAL,
171 GA_NODE_XFEM_PLUS_GRAD,
172 GA_NODE_XFEM_PLUS_HESS,
173 GA_NODE_XFEM_PLUS_DIVERG,
174 GA_NODE_XFEM_PLUS_VAL_TEST,
175 GA_NODE_XFEM_PLUS_GRAD_TEST,
176 GA_NODE_XFEM_PLUS_HESS_TEST,
177 GA_NODE_XFEM_PLUS_DIVERG_TEST,
179 GA_NODE_XFEM_MINUS_VAL,
180 GA_NODE_XFEM_MINUS_GRAD,
181 GA_NODE_XFEM_MINUS_HESS,
182 GA_NODE_XFEM_MINUS_DIVERG,
183 GA_NODE_XFEM_MINUS_VAL_TEST,
184 GA_NODE_XFEM_MINUS_GRAD_TEST,
185 GA_NODE_XFEM_MINUS_HESS_TEST,
186 GA_NODE_XFEM_MINUS_DIVERG_TEST,
189 typedef std::shared_ptr<std::string> pstring;
191 void ga_throw_error_msg(pstring expr,
size_type pos,
192 const std::string &msg);
194 # define ga_throw_error(expr, pos, msg) \ 195 { std::stringstream ss; ss << msg; \ 196 ga_throw_error_msg(expr, pos, ss.str()); \ 197 GMM_ASSERT1(false, "Error in assembly string" ); \ 201 struct assembly_tensor {
206 assembly_tensor *tensor_copied;
208 const base_tensor &org_tensor()
const 209 {
return is_copied ? tensor_copied->org_tensor() : t; }
210 base_tensor &org_tensor()
211 {
return is_copied ? tensor_copied->org_tensor() : t; }
213 const base_tensor &tensor()
const 214 {
return (is_copied ? tensor_copied->tensor() : t); }
216 base_tensor &tensor()
217 {
return (is_copied ? tensor_copied->tensor() : t); }
220 { sparsity_ = sp; qdim_ = q; }
222 size_type qdim() {
return is_copied ? tensor_copied->qdim() : qdim_; }
225 {
return is_copied ? tensor_copied->sparsity() : sparsity_; }
227 inline void set_to_original() { is_copied =
false; }
228 inline void set_to_copy(assembly_tensor &t_) {
229 is_copied =
true; sparsity_ = t_.sparsity_; qdim_ = t_.qdim_;
230 t = t_.org_tensor(); tensor_copied = &(t_);
233 inline void adjust_sizes(
const bgeot::multi_index &ssizes)
234 { t.adjust_sizes(ssizes); }
236 inline void adjust_sizes()
237 {
if (t.sizes().size() || t.size() != 1) t.init(); }
240 {
if (t.sizes().size() != 1 || t.sizes()[0] != i) t.init(i); }
243 if (t.sizes().size() != 2 || t.sizes()[0] != i || t.sizes()[1] != j)
248 if (t.sizes().size() != 3 || t.sizes()[0] != i || t.sizes()[1] != j
249 || t.sizes()[2] != k)
254 if (t.sizes().size() != 3 || t.sizes()[0] != i || t.sizes()[1] != j
255 || t.sizes()[2] != k || t.sizes()[3] != l)
259 void init_scalar_tensor(scalar_type v)
260 { set_to_original(); t.adjust_sizes(); t[0] = v; }
263 { set_to_original(); t.adjust_sizes(d); }
266 { set_to_original(); t.adjust_sizes(n, m); }
269 { set_to_original(); t.adjust_sizes(n, m, l); }
273 { set_to_original(); t.adjust_sizes(n, m, l, k); }
275 const bgeot::multi_index &sizes()
const {
return t.sizes(); }
278 : is_copied(false), sparsity_(0), qdim_(0), tensor_copied(0) {}
282 typedef ga_tree_node *pga_tree_node;
285 struct ga_tree_node {
286 GA_NODE_TYPE node_type;
287 GA_TOKEN_TYPE op_type;
293 std::string name_test1, name_test2;
295 std::string interpolate_name_test1, interpolate_name_test2;
304 std::string interpolate_name;
305 std::string interpolate_name_der;
307 std::string elementary_name;
312 pga_tree_node parent;
313 std::vector<pga_tree_node> children;
314 scalar_type hash_value;
317 inline const base_tensor &tensor()
const {
return t.tensor(); }
318 inline base_tensor &tensor() {
return t.tensor(); }
319 int sparsity()
const {
return t.sparsity(); }
321 inline size_type nb_test_functions()
const {
322 if (test_function_type ==
size_type(-1))
return 0;
323 return test_function_type - (test_function_type >= 2 ? 1 : 0);
327 {
return t.sizes().size() - nb_test_functions(); }
329 inline size_type tensor_test_size()
const {
331 return (st >= 1 ? t.sizes()[0] : 1) * (st == 2 ? t.sizes()[1] : 1);
334 inline size_type tensor_proper_size()
const 335 {
return t.org_tensor().size() / tensor_test_size(); }
338 {
return t.sizes()[nb_test_functions()+i]; }
341 void mult_test(
const pga_tree_node n0,
const pga_tree_node n1);
343 bool tensor_is_zero() {
344 if (node_type == GA_NODE_ZERO)
return true;
345 if (node_type != GA_NODE_CONSTANT)
return false;
346 for (
size_type i = 0; i < tensor().size(); ++i)
347 if (tensor()[i] != scalar_type(0))
return false;
351 inline void init_scalar_tensor(scalar_type v)
352 { t.init_scalar_tensor(v); test_function_type = 0; }
354 inline void init_vector_tensor(
size_type d)
355 { t.init_vector_tensor(d); test_function_type = 0; }
358 { t.init_matrix_tensor(n, m); test_function_type = 0; }
361 { t.init_third_order_tensor(n, m, l); test_function_type = 0; }
365 { t.init_fourth_order_tensor(n, m, l, k); test_function_type = 0; }
367 inline void adopt_child(pga_tree_node new_child)
368 { children.push_back(new_child); children.back()->parent =
this; }
370 inline void replace_child(pga_tree_node oldchild,
371 pga_tree_node newchild) {
373 for (pga_tree_node &child : children)
374 if (child == oldchild) { child = newchild; found =
true; }
375 GMM_ASSERT1(found,
"Internal error");
379 : node_type(GA_NODE_VOID), test_function_type(-1), qdim1(0), qdim2(0),
380 nbc1(0), nbc2(0), nbc3(0), pos(0), expr(0), der1(0), der2(0),
381 symmetric_op(false), hash_value(0) {}
382 ga_tree_node(GA_NODE_TYPE ty,
size_type p, pstring expr_)
383 : node_type(ty), test_function_type(-1),
384 qdim1(0), qdim2(0), nbc1(0), nbc2(0), nbc3(0),
385 pos(p), expr(expr_), der1(0), der2(0), symmetric_op(false),
387 ga_tree_node(scalar_type v,
size_type p, pstring expr_)
388 : node_type(GA_NODE_CONSTANT), test_function_type(-1),
389 qdim1(0), qdim2(0), nbc1(0), nbc2(0), nbc3(0),
390 pos(p), expr(expr_), der1(0), der2(0), symmetric_op(false),
392 { init_scalar_tensor(v); }
394 : node_type(GA_NODE_NAME), test_function_type(-1),
395 qdim1(0), qdim2(0), nbc1(0), nbc2(0), nbc3(0),
396 pos(p), expr(expr_), name(n, l), der1(0), der2(0), symmetric_op(false),
398 ga_tree_node(GA_TOKEN_TYPE op,
size_type p, pstring expr_)
399 : node_type(GA_NODE_OP), op_type(op), test_function_type(-1),
400 qdim1(0), qdim2(0), nbc1(0), nbc2(0), nbc3(0),
401 pos(p), expr(expr_), der1(0), der2(0), symmetric_op(false),
406 pga_tree_node root, current_node;
408 void add_scalar(scalar_type val,
size_type pos, pstring expr);
409 void add_allindices(
size_type pos, pstring expr);
412 void add_sub_tree(ga_tree &sub_tree);
413 void add_params(
size_type pos, pstring expr);
414 void add_matrix(
size_type pos, pstring expr);
415 void add_op(GA_TOKEN_TYPE op_type,
size_type pos, pstring expr);
416 void clear_node_rec(pga_tree_node pnode);
417 void clear_node(pga_tree_node pnode);
418 void clear() { clear_node_rec(root); root = current_node =
nullptr; }
419 void clear_children(pga_tree_node pnode);
420 void replace_node_by_child(pga_tree_node pnode,
size_type i);
421 void copy_node(pga_tree_node pnode, pga_tree_node parent,
422 pga_tree_node &child);
423 void duplicate_with_operation(pga_tree_node pnode, GA_TOKEN_TYPE op_type);
424 void duplicate_with_addition(pga_tree_node pnode)
425 { duplicate_with_operation(pnode, GA_PLUS); }
426 void duplicate_with_substraction(pga_tree_node pnode)
427 { duplicate_with_operation(pnode, GA_MINUS); }
428 void insert_node(pga_tree_node pnode, GA_NODE_TYPE node_type);
429 void add_child(pga_tree_node pnode, GA_NODE_TYPE node_type = GA_NODE_VOID);
430 void swap(ga_tree &tree)
431 { std::swap(root, tree.root); std::swap(current_node, tree.current_node); }
433 ga_tree() : root(nullptr), current_node(nullptr) {}
435 ga_tree(
const ga_tree &tree) : root(nullptr), current_node(nullptr)
436 {
if (tree.root) copy_node(tree.root,
nullptr, root); }
438 ga_tree &operator = (
const ga_tree &tree)
439 {
clear();
if (tree.root) copy_node(tree.root,
nullptr,root);
return *
this; }
441 ~ga_tree() {
clear(); }
448 bool sub_tree_are_equal
449 (
const pga_tree_node pnode1,
const pga_tree_node pnode2,
450 const ga_workspace &workspace,
int version);
454 void ga_print_node(
const pga_tree_node pnode,
457 std::string ga_tree_to_string(
const ga_tree &tree);
461 void ga_read_string(
const std::string &expr, ga_tree &tree,
462 const ga_macro_dictionnary ¯o_dict);
463 void ga_read_string_reg(
const std::string &expr, ga_tree &tree,
464 ga_macro_dictionnary ¯o_dict);
A smart pointer that copies the value it points to on copy operations.
Tools for multithreaded, OpenMP and Boost based parallelization.
size_t size_type
used as the common size type in the library
Inversion of geometric transformations.
Model representation in Getfem.
A simple singleton implementation.
A langage for generic assembly of pde boundary value problems.
GEneric Tool for Finite Element Methods.
void clear(L &l)
clear (fill with zeros) a vector or matrix.
Basic linear algebra functions.
region-tree for window/point search on a set of rectangles.