getfem-commits
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Getfem-commits] (no subject)


From: Yves Renard
Subject: [Getfem-commits] (no subject)
Date: Wed, 2 May 2018 09:59:00 -0400 (EDT)

branch: devel-yves-generic-assembly-modifs
commit 3a284f7e07284b7a857845235e59e4d209adf913
Author: Yves Renard <address@hidden>
Date:   Tue May 1 14:02:02 2018 +0200

    Adding a Diff(expression, variable) operator in the assembly language
---
 doc/sphinx/source/userdoc/gasm_high.rst            |  27 +++-
 ...tfem_generic_assembly_functions_and_operators.h |   4 +
 src/getfem/getfem_generic_assembly_semantic.h      |   8 +-
 src/getfem_generic_assembly_compile_and_exec.cc    |   4 +-
 ...fem_generic_assembly_functions_and_operators.cc |  29 +++-
 src/getfem_generic_assembly_interpolation.cc       |   3 +-
 src/getfem_generic_assembly_semantic.cc            | 177 +++++++++++++--------
 src/getfem_generic_assembly_tree.cc                |  14 +-
 src/getfem_generic_assembly_workspace.cc           |  19 ++-
 9 files changed, 193 insertions(+), 92 deletions(-)

diff --git a/doc/sphinx/source/userdoc/gasm_high.rst 
b/doc/sphinx/source/userdoc/gasm_high.rst
index 6b1ecdb..97049ec 100644
--- a/doc/sphinx/source/userdoc/gasm_high.rst
+++ b/doc/sphinx/source/userdoc/gasm_high.rst
@@ -60,6 +60,8 @@ A specific language has been developed to describe the weak 
formulation of bound
 
   - A certain number of linear and nonlinear operators (``Trace``, ``Norm``, 
``Det``, ``Deviator``, ...). The nonlinear operators cannot be applied to test 
functions.
 
+  - ``Diff(expression, variable)``: The possibility to explicity differentiate 
an expression with respect to a variable
+
   - Possiblility of macro definition (in the model, the ga_workspace object or 
directly in the assembly string). The macros should be some valid expressions 
that are expanded inline at the lexical analysis phase (if they are used 
several times, the computation is automatically factorized at the compilation 
stage).
 
   - ``Interpolate(variable, transformation)``: Powerful operation which allows 
to interpolate the variables, or test functions either on the same mesh on 
other elements or on another mesh. ``transformation`` is an object stored by 
the workspace or model object which describes the map from the current point to 
the point where to perform the interpolation. This functionality can be used 
for instance to prescribe periodic conditions or to compute mortar matrices for 
two finite element space [...]
@@ -620,7 +622,7 @@ The following assembly string is then valid (if ``u`` is a 
valid variable)::
 
   "Def ps(a,b):=a.b; ps(Grad_u, Grad_Test_u)"
 
-Parameter are allowed to be post-fixed to ``Grad_``, ``Hess_``, ``Test_`` and 
``Test2_`` prefixes. So that the following assembly string is then valid::
+Parameter are allowed to be post-fixed to ``Grad_``, ``Hess_``, ``Test_`` and 
``Test2_`` prefixes, so that the following assembly string is valid::
 
   "Def psgrad(a,b):=Grad_a.Grad_b; psgrad(u, Test_u)"
 
@@ -633,8 +635,31 @@ A macro can be deleted from a ga_workspace or model object 
as follows::
   workspace.del_macro(name)
   model.del_macro(name)
 
+Note that a macro defined at the begining of an assembly string is only 
defined in the assembly string and cannot be used later without being added in 
a model or ga_workspace object.
+
 The macros are expanded inline at the lexical analysis phase. Note that a the 
compilation phase, the repeated expressions are automatically factorized and 
computed only once.
 
+Explixit Differentiation
+------------------------
+The workspace object automatically differentiate terms that are of lower 
deriation order. However, it is also allowed to explicitely differentiate an 
expression with respect to a variable. One interest is that the automatic 
differentiation performs a derivative with respect to all the declared 
variables of model/workspace but this is not necessarily the expected behavior 
when using a potential energy, for instance. The syntax is::
+
+  Diff(expression, variable)
+
+For instance, the following expression::
+
+  Diff(u.u, u)
+
+will result in::
+
+  2*(u.Test_u)
+
+So that::
+
+  Grad_u:Grad_test_u + Diff(u.u, u)
+
+is a valid expression.  
+
+  
 .. _ud-gasm-high-transf:
 
 Interpolate transformations
diff --git a/src/getfem/getfem_generic_assembly_functions_and_operators.h 
b/src/getfem/getfem_generic_assembly_functions_and_operators.h
index ca2f06a..7f5d831 100644
--- a/src/getfem/getfem_generic_assembly_functions_and_operators.h
+++ b/src/getfem/getfem_generic_assembly_functions_and_operators.h
@@ -106,6 +106,10 @@ namespace getfem {
     ga_spec_function_tab();
   };
 
+  struct ga_spec_op_tab : public std::set<std::string> {
+    ga_spec_op_tab();
+  };
+
 } /* end of namespace */
 
 
diff --git a/src/getfem/getfem_generic_assembly_semantic.h 
b/src/getfem/getfem_generic_assembly_semantic.h
index a4426bb..98ae7b4 100644
--- a/src/getfem/getfem_generic_assembly_semantic.h
+++ b/src/getfem/getfem_generic_assembly_semantic.h
@@ -57,7 +57,7 @@ namespace getfem {
   */
   void ga_semantic_analysis(ga_tree &tree,
                            const ga_workspace &workspace,
-                           size_type meshdim,
+                           const mesh &m,
                            size_type ref_elt_dim,
                            bool eval_fixed_size,
                            bool ignore_X, int option = 0);
@@ -93,9 +93,9 @@ namespace getfem {
      The tree is modified and should be copied first and passed to
      ga_semantic_analysis after for enrichment. */
   void ga_derivative(ga_tree &tree, const ga_workspace &workspace,
-                            const mesh &m, const std::string &varname,
-                            const std::string &interpolatename,
-                            size_type order);
+                    const mesh &m, const std::string &varname,
+                    const std::string &interpolatename,
+                    size_type order);
 
   std::string ga_derivative_scalar_function(const std::string &expr,
                                            const std::string &var);
diff --git a/src/getfem_generic_assembly_compile_and_exec.cc 
b/src/getfem_generic_assembly_compile_and_exec.cc
index a8b0900..d7b14dc 100644
--- a/src/getfem_generic_assembly_compile_and_exec.cc
+++ b/src/getfem_generic_assembly_compile_and_exec.cc
@@ -5946,7 +5946,7 @@ namespace getfem {
         // Semantic analysis mainly to evaluate fixed size variables and data
         const mesh *m = td.m;
         GMM_ASSERT1(m, "Internal error");
-        ga_semantic_analysis(gis.trees.back(), workspace, m->dim(),
+        ga_semantic_analysis(gis.trees.back(), workspace, *m,
                              ref_elt_dim_of_mesh(*m), true, false);
         pga_tree_node root = gis.trees.back().root;
         if (root) {
@@ -5993,7 +5993,7 @@ namespace getfem {
 
           // Semantic analysis mainly to evaluate fixed size variables and data
           ga_semantic_analysis(*added_tree, workspace,
-                               td.mim->linked_mesh().dim(),
+                               td.mim->linked_mesh(),
                                ref_elt_dim_of_mesh(td.mim->linked_mesh()),
                                true, false);
           pga_tree_node root = added_tree->root;
diff --git a/src/getfem_generic_assembly_functions_and_operators.cc 
b/src/getfem_generic_assembly_functions_and_operators.cc
index 2a65913..cb2c7e2 100644
--- a/src/getfem_generic_assembly_functions_and_operators.cc
+++ b/src/getfem_generic_assembly_functions_and_operators.cc
@@ -553,6 +553,29 @@ namespace getfem {
     SPEC_FUNCTIONS.insert("Id");
   }
 
+  ga_spec_op_tab::ga_spec_op_tab() {
+    // Predefined special operators
+    ga_spec_op_tab &SPEC_OP = *this;
+    SPEC_OP.insert("X");
+    SPEC_OP.insert("element_size");
+    SPEC_OP.insert("element_K");
+    SPEC_OP.insert("element_B");
+    SPEC_OP.insert("Normal");
+    SPEC_OP.insert("Reshape");
+    SPEC_OP.insert("Sym");
+    SPEC_OP.insert("Skew");
+    SPEC_OP.insert("Def");
+    SPEC_OP.insert("Trace");
+    SPEC_OP.insert("Deviator");
+    SPEC_OP.insert("Interpolate");
+    SPEC_OP.insert("Interpolate_filter");
+    SPEC_OP.insert("Elementary_transformation");
+    SPEC_OP.insert("Xfem_plus");
+    SPEC_OP.insert("Xfem_minus");
+    SPEC_OP.insert("Print");
+    SPEC_OP.insert("Diff");
+  }
+
 
   ga_predef_operator_tab::ga_predef_operator_tab(void) {
     // Predefined operators
@@ -702,12 +725,14 @@ namespace getfem {
       ga_tree tree = *(local_workspace.tree_info(0).ptree);
       ga_derivative(tree, local_workspace, *((const mesh *)(0)), var, "", 1);
       if (tree.root) {
-        ga_semantic_analysis(tree, local_workspace, 1, 1, false, true);
+        ga_semantic_analysis(tree, local_workspace, *((const mesh *)(0)),
+                            1, false, true);
         // To be improved to suppress test functions in the expression ...
         // ga_replace_test_by_cte do not work in all operations like
         // vector components x(1)
         // ga_replace_test_by_cte(tree.root, false);
-        // ga_semantic_analysis(tree, local_workspace, 1, 1, false, true);
+        // ga_semantic_analysis(tree, local_workspace, *((const mesh *)(0)), 1,
+       //                      false, true);
       }
       expr = ga_tree_to_string(tree);
     }
diff --git a/src/getfem_generic_assembly_interpolation.cc 
b/src/getfem_generic_assembly_interpolation.cc
index c0476be..44718e3 100644
--- a/src/getfem_generic_assembly_interpolation.cc
+++ b/src/getfem_generic_assembly_interpolation.cc
@@ -568,7 +568,8 @@ namespace getfem {
           ga_derivative(tree, pwi.workspace(), source_mesh,
                         var.varname, var.transname, 1);
           if (tree.root)
-            ga_semantic_analysis(tree, local_workspace, 1, 1, false, true);
+            ga_semantic_analysis(tree, local_workspace, *((const mesh *)(0)),
+                                1, false, true);
           ga_compile_interpolation(pwi.workspace(), pwi.gis());
         }
       }
diff --git a/src/getfem_generic_assembly_semantic.cc 
b/src/getfem_generic_assembly_semantic.cc
index 740cc88..e8cc9ea 100644
--- a/src/getfem_generic_assembly_semantic.cc
+++ b/src/getfem_generic_assembly_semantic.cc
@@ -91,6 +91,70 @@ namespace getfem {
     return found_var;
   }
 
+
+  static bool ga_node_mark_tree_for_variable
+  (pga_tree_node pnode, const ga_workspace &workspace, const mesh &m,
+   const std::string &varname,
+   const std::string &interpolatename) {
+    bool marked = false;
+    for (size_type i = 0; i < pnode->children.size(); ++i)
+      if (ga_node_mark_tree_for_variable(pnode->children[i], workspace, m,
+                                         varname, interpolatename))
+        marked = true;
+
+    bool plain_node(pnode->node_type == GA_NODE_VAL ||
+                    pnode->node_type == GA_NODE_GRAD ||
+                    pnode->node_type == GA_NODE_HESS ||
+                    pnode->node_type == GA_NODE_DIVERG);
+    bool interpolate_node(pnode->node_type == GA_NODE_INTERPOLATE_VAL ||
+                          pnode->node_type == GA_NODE_INTERPOLATE_GRAD ||
+                          pnode->node_type == GA_NODE_INTERPOLATE_HESS ||
+                          pnode->node_type == GA_NODE_INTERPOLATE_DIVERG);
+    bool elementary_node(pnode->node_type == GA_NODE_ELEMENTARY_VAL ||
+                         pnode->node_type == GA_NODE_ELEMENTARY_GRAD ||
+                         pnode->node_type == GA_NODE_ELEMENTARY_HESS ||
+                         pnode->node_type == GA_NODE_ELEMENTARY_DIVERG);
+    bool xfem_node(pnode->node_type == GA_NODE_XFEM_PLUS_VAL ||
+                   pnode->node_type == GA_NODE_XFEM_PLUS_GRAD ||
+                   pnode->node_type == GA_NODE_XFEM_PLUS_HESS ||
+                   pnode->node_type == GA_NODE_XFEM_PLUS_DIVERG ||
+                   pnode->node_type == GA_NODE_XFEM_MINUS_VAL ||
+                   pnode->node_type == GA_NODE_XFEM_MINUS_GRAD ||
+                   pnode->node_type == GA_NODE_XFEM_MINUS_HESS ||
+                   pnode->node_type == GA_NODE_XFEM_MINUS_DIVERG);
+    bool interpolate_test_node
+      (pnode->node_type == GA_NODE_INTERPOLATE_VAL_TEST ||
+       pnode->node_type == GA_NODE_INTERPOLATE_GRAD_TEST ||
+       pnode->node_type == GA_NODE_INTERPOLATE_HESS_TEST ||
+       pnode->node_type == GA_NODE_INTERPOLATE_DIVERG_TEST);
+
+    if ((plain_node || interpolate_node || elementary_node || xfem_node) &&
+        (pnode->name.compare(varname) == 0 &&
+         pnode->interpolate_name.compare(interpolatename) == 0)) marked = true;
+
+    if (interpolate_node || interpolate_test_node ||
+        pnode->node_type == GA_NODE_INTERPOLATE_X ||
+        pnode->node_type == GA_NODE_INTERPOLATE_NORMAL) {
+      std::set<var_trans_pair> vars;
+      workspace.interpolate_transformation(pnode->interpolate_name)
+        ->extract_variables(workspace, vars, true,
+                            m, pnode->interpolate_name);
+      for (std::set<var_trans_pair>::iterator it=vars.begin();
+           it != vars.end(); ++it) {
+        if (it->varname.compare(varname) == 0 &&
+            it->transname.compare(interpolatename) == 0) marked = true;
+      }
+    }
+    pnode->marked = marked;
+    return marked;
+  }
+
+  static void ga_node_derivation(ga_tree &tree, const ga_workspace &workspace,
+                                 const mesh &m,
+                                 pga_tree_node pnode,
+                                 const std::string &varname,
+                                 const std::string &interpolatename,
+                                 size_type order); 
   //=========================================================================
   // Some hash code functions for node identification
   //=========================================================================
@@ -188,14 +252,15 @@ namespace getfem {
 
   static void ga_node_analysis(ga_tree &tree,
                                const ga_workspace &workspace,
-                               pga_tree_node pnode, size_type meshdim,
+                               pga_tree_node pnode, const mesh &me,
                                size_type ref_elt_dim, bool eval_fixed_size,
                                bool ignore_X, int option) {
     bool all_cte = true, all_sc = true;
+    size_type meshdim = &me ? me.dim() : 1;
     pnode->symmetric_op = false;
 
     for (size_type i = 0; i < pnode->children.size(); ++i) {
-      ga_node_analysis(tree, workspace, pnode->children[i], meshdim,
+      ga_node_analysis(tree, workspace, pnode->children[i], me,
                        ref_elt_dim, eval_fixed_size, ignore_X, option);
       all_cte = all_cte && (pnode->children[i]->node_type == GA_NODE_CONSTANT);
       all_sc = all_sc && (pnode->children[i]->tensor_proper_size() == 1);
@@ -1355,6 +1420,10 @@ namespace getfem {
           pnode->init_vector_tensor(meshdim);
           break;
         }
+       if (!(name.compare("Diff"))) {
+         pnode->test_function_type = 0;
+          break;
+        }
         if (!(name.compare("element_size"))) {
           pnode->node_type = GA_NODE_ELT_SIZE;
           pnode->init_scalar_tensor(0);
@@ -1606,7 +1675,41 @@ namespace getfem {
       break;
 
     case GA_NODE_PARAMS:
-      if (child0->node_type == GA_NODE_X) {
+      if (child0->node_type == GA_NODE_NAME) {
+       if (child0->name.compare("Diff") == 0) { // Diff operator
+         
+         if (pnode->children.size() != 3)
+           ga_throw_error(pnode->expr, child0->pos,
+                          "Bad number of parameters for Diff operator");
+         pga_tree_node child2 = pnode->children[2];
+         if (child2->node_type != GA_NODE_VAL)
+           ga_throw_error(pnode->expr, child2->pos, "Second parameter of "
+                          "Diff operator has to be a variable name");
+         std::string vardiff = child2->name;
+         size_type order = child1->test_function_type;
+         if (order > 1)
+           ga_throw_error(pnode->expr, child2->pos, "Cannot derive further "
+                          "this order two expression");
+         
+         if (ga_node_mark_tree_for_variable(child1,workspace,me,vardiff,"")) {
+           ga_node_derivation(tree, workspace, me, child1, vardiff,"",order+1);
+           child1 = pnode->children[1];
+           ga_node_analysis(tree, workspace, child1, me, ref_elt_dim,
+                            eval_fixed_size, ignore_X, option);
+           child1 = pnode->children[1];
+         } else {
+           mi = child1->t.sizes(); mi.insert(mi.begin(), 2);
+           child1->t.adjust_sizes(mi);
+           child1->node_type = GA_NODE_ZERO;
+           child1->test_function_type = order ? 3 : 1;
+           gmm::clear(child1->tensor().as_vector());
+           tree.clear_children(child1);
+         }
+         tree.replace_node_by_child(pnode, 1);
+         pnode = child1;
+       } else
+         ga_throw_error(pnode->expr, child0->pos, "Unknown special operator");
+      } else if (child0->node_type == GA_NODE_X) {
         child0->init_scalar_tensor(0);
         if (pnode->children.size() != 2)
           ga_throw_error(pnode->expr, child1->pos,
@@ -1941,7 +2044,7 @@ namespace getfem {
 
   void ga_semantic_analysis(ga_tree &tree,
                            const ga_workspace &workspace,
-                           size_type meshdim,
+                           const mesh &m,
                            size_type ref_elt_dim,
                            bool eval_fixed_size,
                            bool ignore_X, int option) {
@@ -1951,7 +2054,7 @@ namespace getfem {
     if (!(tree.root)) return;
     if (option == 1) { workspace.test1.clear(); workspace.test2.clear(); }
     // cout << "semantic analysis of " << ga_tree_to_string(tree) << endl;
-    ga_node_analysis(tree, workspace, tree.root, meshdim, ref_elt_dim,
+    ga_node_analysis(tree, workspace, tree.root, m, ref_elt_dim,
                      eval_fixed_size, ignore_X, option);
     if (tree.root && option == 2) {
       if (((tree.root->test_function_type & 1) &&
@@ -2407,62 +2510,6 @@ namespace getfem {
   //   ga_semantic_analysis for enrichment.
   //=========================================================================
 
-  static bool ga_node_mark_tree_for_variable
-  (pga_tree_node pnode, const ga_workspace &workspace, const mesh &m,
-   const std::string &varname,
-   const std::string &interpolatename) {
-    bool marked = false;
-    for (size_type i = 0; i < pnode->children.size(); ++i)
-      if (ga_node_mark_tree_for_variable(pnode->children[i], workspace, m,
-                                         varname, interpolatename))
-        marked = true;
-
-    bool plain_node(pnode->node_type == GA_NODE_VAL ||
-                    pnode->node_type == GA_NODE_GRAD ||
-                    pnode->node_type == GA_NODE_HESS ||
-                    pnode->node_type == GA_NODE_DIVERG);
-    bool interpolate_node(pnode->node_type == GA_NODE_INTERPOLATE_VAL ||
-                          pnode->node_type == GA_NODE_INTERPOLATE_GRAD ||
-                          pnode->node_type == GA_NODE_INTERPOLATE_HESS ||
-                          pnode->node_type == GA_NODE_INTERPOLATE_DIVERG);
-    bool elementary_node(pnode->node_type == GA_NODE_ELEMENTARY_VAL ||
-                         pnode->node_type == GA_NODE_ELEMENTARY_GRAD ||
-                         pnode->node_type == GA_NODE_ELEMENTARY_HESS ||
-                         pnode->node_type == GA_NODE_ELEMENTARY_DIVERG);
-    bool xfem_node(pnode->node_type == GA_NODE_XFEM_PLUS_VAL ||
-                   pnode->node_type == GA_NODE_XFEM_PLUS_GRAD ||
-                   pnode->node_type == GA_NODE_XFEM_PLUS_HESS ||
-                   pnode->node_type == GA_NODE_XFEM_PLUS_DIVERG ||
-                   pnode->node_type == GA_NODE_XFEM_MINUS_VAL ||
-                   pnode->node_type == GA_NODE_XFEM_MINUS_GRAD ||
-                   pnode->node_type == GA_NODE_XFEM_MINUS_HESS ||
-                   pnode->node_type == GA_NODE_XFEM_MINUS_DIVERG);
-    bool interpolate_test_node
-      (pnode->node_type == GA_NODE_INTERPOLATE_VAL_TEST ||
-       pnode->node_type == GA_NODE_INTERPOLATE_GRAD_TEST ||
-       pnode->node_type == GA_NODE_INTERPOLATE_HESS_TEST ||
-       pnode->node_type == GA_NODE_INTERPOLATE_DIVERG_TEST);
-
-    if ((plain_node || interpolate_node || elementary_node || xfem_node) &&
-        (pnode->name.compare(varname) == 0 &&
-         pnode->interpolate_name.compare(interpolatename) == 0)) marked = true;
-
-    if (interpolate_node || interpolate_test_node ||
-        pnode->node_type == GA_NODE_INTERPOLATE_X ||
-        pnode->node_type == GA_NODE_INTERPOLATE_NORMAL) {
-      std::set<var_trans_pair> vars;
-      workspace.interpolate_transformation(pnode->interpolate_name)
-        ->extract_variables(workspace, vars, true,
-                            m, pnode->interpolate_name);
-      for (std::set<var_trans_pair>::iterator it=vars.begin();
-           it != vars.end(); ++it) {
-        if (it->varname.compare(varname) == 0 &&
-            it->transname.compare(interpolatename) == 0) marked = true;
-      }
-    }
-    pnode->marked = marked;
-    return marked;
-  }
 
   static void ga_node_derivation(ga_tree &tree, const ga_workspace &workspace,
                                  const mesh &m,
@@ -3062,9 +3109,8 @@ namespace getfem {
   // The tree is modified. Should be copied first and passed to
   // ga_semantic_analysis after for enrichment
   void ga_derivative(ga_tree &tree, const ga_workspace &workspace,
-                            const mesh &m, const std::string &varname,
-                            const std::string &interpolatename,
-                            size_type order) {
+                    const mesh &m, const std::string &varname,
+                    const std::string &interpolatename, size_type order) {
     // cout << "compute derivative of " << ga_tree_to_string(tree)
     //  << " with respect to " << varname << " : " << interpolatename << endl;
     if (!(tree.root)) return;
@@ -3102,7 +3148,8 @@ namespace getfem {
       ga_derivative(tree, workspace, *((const mesh *)(0)), var, "", 1);
       if (tree.root) {
         ga_replace_test_by_cte(tree.root, true);
-        ga_semantic_analysis(tree, workspace, 1, 1, false, true);
+        ga_semantic_analysis(tree, workspace, *((const mesh *)(0)), 1,
+                            false, true);
       }
       return ga_tree_to_string(tree);
     } else return "0";
diff --git a/src/getfem_generic_assembly_tree.cc 
b/src/getfem_generic_assembly_tree.cc
index db3a363..d0bb3e5 100644
--- a/src/getfem_generic_assembly_tree.cc
+++ b/src/getfem_generic_assembly_tree.cc
@@ -866,7 +866,6 @@ namespace getfem {
           GMM_ASSERT1(pnode->children.size() == 1, "Invalid tree");
           str << "Print("; ga_print_node(pnode->children[0], str); str << ")";
         } else {
-          // GMM_ASSERT1(pnode->children.size() == 2, "Invalid tree");
           if (!par && pnode->op_type == GA_MULT &&
               (pnode->children.size() == 1 ||
                pnode->test_function_type == size_type(-1) ||
@@ -1121,7 +1120,7 @@ namespace getfem {
 
   // 0 : ok
   // 1 : function or operator name or "X"
-  // 2 : reserved prefix Grad, Hess, Div, Test and Test2
+  // 2 : reserved prefix Grad, Hess, Div, Derivative_ Test and Test2
   // 3 : reserved prefix Dot and Previous
   int ga_check_name_validity(const std::string &name) {
 
@@ -1140,9 +1139,13 @@ namespace getfem {
       = dal::singleton<ga_predef_operator_tab>::instance(0);
     const ga_spec_function_tab &SPEC_FUNCTIONS
       = dal::singleton<ga_spec_function_tab>::instance(0);
+    const ga_spec_op_tab &SPEC_OP
+      = dal::singleton<ga_spec_op_tab>::instance(0);
     
-    ga_predef_function_tab::const_iterator it=PREDEF_FUNCTIONS.find(name);
-    if (it != PREDEF_FUNCTIONS.end())
+    if (SPEC_OP.find(name) != SPEC_OP.end())
+      return 1;
+
+    if (PREDEF_FUNCTIONS.find(name) != PREDEF_FUNCTIONS.end())
       return 1;
     
     if (SPEC_FUNCTIONS.find(name) != SPEC_FUNCTIONS.end())
@@ -1833,11 +1836,8 @@ namespace getfem {
     pos = 0;
     pstring nexpr(new std::string(expr));
     
-    cout << "Original " << expr << endl;
     t = ga_read_term(nexpr, pos, tree, macro_dict);
-    cout << "Before expand " << ga_tree_to_string(tree) << endl;
     if (tree.root) ga_expand_macro(tree, tree.root, macro_dict);
-    cout << "After expand " << ga_tree_to_string(tree) << endl;
     
     switch (t) {
     case GA_RPAR: ga_throw_error(nexpr, pos-1, "Unbalanced parenthesis.");
diff --git a/src/getfem_generic_assembly_workspace.cc 
b/src/getfem_generic_assembly_workspace.cc
index 15da368..0429b2e 100644
--- a/src/getfem_generic_assembly_workspace.cc
+++ b/src/getfem_generic_assembly_workspace.cc
@@ -410,7 +410,7 @@ namespace getfem {
           ftree.root->op_type = GA_PLUS;
           ftree.root->children.resize(2, nullptr);
           ftree.copy_node(tree.root, ftree.root, ftree.root->children[1]);
-          ga_semantic_analysis(ftree, *this, m.dim(),
+          ga_semantic_analysis(ftree, *this, m,
                                ref_elt_dim_of_mesh(m), false, function_expr);
           found = true;
           break;
@@ -447,7 +447,7 @@ namespace getfem {
             ga_derivative(dtree, *this, m, var.varname, var.transname, 
1+order);
             // cout << "Result : " << ga_tree_to_string(dtree) << endl;
             GA_TOCTIC("Derivative time");
-            ga_semantic_analysis(dtree, *this, m.dim(),
+            ga_semantic_analysis(dtree, *this, m,
                                  ref_elt_dim_of_mesh(m), false, function_expr);
             GA_TOCTIC("Analysis after Derivative time");
             // cout << "after analysis "  << ga_tree_to_string(dtree) << endl;
@@ -481,7 +481,7 @@ namespace getfem {
     std::vector<ga_tree> ltrees(1);
     ga_read_string(expr, ltrees[0], macro_dictionnary());
     // cout << "read : " << ga_tree_to_string(ltrees[0])  << endl;
-    ga_semantic_analysis(ltrees[0], *this, mim.linked_mesh().dim(),
+    ga_semantic_analysis(ltrees[0], *this, mim.linked_mesh(),
                          ref_elt_dim_of_mesh(mim.linked_mesh()),
                          false, false, 1);
     // cout << "analysed : " << ga_tree_to_string(ltrees[0]) << endl;
@@ -500,7 +500,7 @@ namespace getfem {
             if (test2.size()) selected_test2 = *it2++;
             // cout << "analysis with " << selected_test1.first << endl;
             ga_semantic_analysis(ltrees[i*ntest2+j], *this,
-                                 mim.linked_mesh().dim(),
+                                 mim.linked_mesh(),
                                  ref_elt_dim_of_mesh(mim.linked_mesh()),
                                  false, false, 2);
             // cout <<"split: "<< ga_tree_to_string(ltrees[i*ntest2+j]) << 
endl;
@@ -524,7 +524,7 @@ namespace getfem {
   void ga_workspace::add_function_expression(const std::string &expr) {
     ga_tree tree;
     ga_read_string(expr, tree, macro_dictionnary());
-    ga_semantic_analysis(tree, *this, 1, 1, false, true);
+    ga_semantic_analysis(tree, *this, *((const mesh *)(0)), 1, false, true);
     if (tree.root) {
       // GMM_ASSERT1(tree.root->nb_test_functions() == 0,
       //            "Invalid function expression");
@@ -539,7 +539,7 @@ namespace getfem {
     const mesh_region &rg = register_region(m, rg_);
     ga_tree tree;
     ga_read_string(expr, tree, macro_dictionnary());
-    ga_semantic_analysis(tree, *this, m.dim(), ref_elt_dim_of_mesh(m),
+    ga_semantic_analysis(tree, *this, m, ref_elt_dim_of_mesh(m),
                          false, false);
     if (tree.root) {
       // GMM_ASSERT1(tree.root->nb_test_functions() == 0,
@@ -555,7 +555,7 @@ namespace getfem {
     const mesh_region &rg = register_region(m, rg_);
     ga_tree tree;
     ga_read_string(expr, tree, macro_dictionnary());
-    ga_semantic_analysis(tree, *this, m.dim(), ref_elt_dim_of_mesh(m),
+    ga_semantic_analysis(tree, *this, m, ref_elt_dim_of_mesh(m),
                          false, false);
     if (tree.root) {
       GMM_ASSERT1(tree.root->nb_test_functions() == 0,
@@ -574,8 +574,7 @@ namespace getfem {
     const mesh_region &rg = register_region(m, rg_);
     ga_tree tree;
     ga_read_string(expr, tree, macro_dictionnary());
-    ga_semantic_analysis(tree, *this, m.dim(), ref_elt_dim_of_mesh(m),
-                         false, false);
+    ga_semantic_analysis(tree, *this, m, ref_elt_dim_of_mesh(m), false, false);
     if (tree.root) {
       GMM_ASSERT1(tree.root->nb_test_functions() == 0,
                   "Invalid expression containing test functions");
@@ -892,7 +891,7 @@ namespace getfem {
         if (local_tree.root)
           ga_node_extract_constant_term(local_tree, local_tree.root, *this, m);
         if (local_tree.root)
-          ga_semantic_analysis(local_tree, *this, m.dim(),
+          ga_semantic_analysis(local_tree, *this, m,
                                ref_elt_dim_of_mesh(m), false, false);
         if (local_tree.root && local_tree.root->node_type != GA_NODE_ZERO) {
           constant_term += "-("+ga_tree_to_string(local_tree)+")";



reply via email to

[Prev in Thread] Current Thread [Next in Thread]