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.