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: Mon, 30 Apr 2018 05:25:31 -0400 (EDT)

branch: devel-yves-generic-assembly-modifs
commit a29bbf055e45f701f44c74385153a455f5a70792
Author: Yves Renard <address@hidden>
Date:   Mon Apr 30 11:25:11 2018 +0200

    macro interface
---
 interface/src/gf_model_set.cc             | 25 +++++++++++++
 src/getfem/getfem_generic_assembly.h      | 30 ++++++++--------
 src/getfem/getfem_generic_assembly_tree.h |  2 ++
 src/getfem/getfem_models.h                | 10 +++---
 src/getfem_generic_assembly_semantic.cc   | 16 ---------
 src/getfem_generic_assembly_tree.cc       | 50 ++++++++++++++++----------
 src/getfem_generic_assembly_workspace.cc  | 58 +------------------------------
 src/getfem_models.cc                      | 15 +++-----
 8 files changed, 84 insertions(+), 122 deletions(-)

diff --git a/interface/src/gf_model_set.cc b/interface/src/gf_model_set.cc
index 8254899..388e181 100644
--- a/interface/src/gf_model_set.cc
+++ b/interface/src/gf_model_set.cc
@@ -294,6 +294,31 @@ void gf_model_set(getfemint::mexargs_in& m_in,
        md->add_fixed_size_data(name, mi);
        );
 
+    /address@hidden ('add macro', @str name, @str expr)
+      Define a new macro for the high generic assembly language.
+      The name include the parameters. For instance name='sp(a,b)', expr='a.b'
+      is a valid definition. Macro without parameter can also be defined.
+      For instance name='x1', expr='X[1]' is valid. Teh form name='grad(u)',
+      expr='Grad_u' is also allowed but in that case, the parameter 'u' will
+      only be allowed to be a variable name when using the macro. Note that
+      macros can be directly defined inside the assembly strings with the
+      keyword 'Def'.
+      @*/
+    sub_command
+      ("add macro", 2, 2, 0, 0,
+       std::string name = in.pop().to_string();
+       std::string expr = in.pop().to_string();
+       md->add_macro(name, expr);
+       );
+
+    /address@hidden ('del macro', @str name)
+      Delete a previously defined macro for the high generic assembly language.
+      @*/
+    sub_command
+      ("del macro", 1, 1, 0, 0,
+       std::string name = in.pop().to_string();
+       md->del_macro(name);
+       );
 
     /address@hidden ('add initialized data', @str name, @vec V[, sizes])
       Add an initialized fixed size data to the model. `sizes` an
diff --git a/src/getfem/getfem_generic_assembly.h 
b/src/getfem/getfem_generic_assembly.h
index c5531c2..991bd58 100644
--- a/src/getfem/getfem_generic_assembly.h
+++ b/src/getfem/getfem_generic_assembly.h
@@ -169,6 +169,8 @@ namespace getfem {
     const ga_macro &get_macro(const std::string &name) const;
     
     void add_macro(const ga_macro &gam);
+    void add_macro(const std::string &name, const std::string &expr);
+    void del_macro(const std::string &name);
     
     ga_macro_dictionnary() : parent(0) {}
     ga_macro_dictionnary(bool, const ga_macro_dictionnary& gamd)
@@ -320,7 +322,7 @@ namespace getfem {
     std::vector<tree_description> trees;
 
     std::map<std::string, std::vector<std::string> > variable_groups;
-    std::map<std::string, std::string> macros; // A SUPPRIMER
+
     ga_macro_dictionnary macro_dict;
 
     struct m_tree {
@@ -333,8 +335,6 @@ namespace getfem {
       ~m_tree();
     };
 
-    mutable std::map<std::string, m_tree> macro_trees;
-
     void add_tree(ga_tree &tree, const mesh &m, const mesh_im &mim,
                   const mesh_region &rg,
                   const std::string &expr, size_type add_derivative_order,
@@ -464,15 +464,15 @@ namespace getfem {
     scalar_type get_time_step() const;
 
     // macros
-    bool macro_exists(const std::string &name) const;
+    bool macro_exists(const std::string &name) const
+    { return macro_dict.macro_exists(name); }
 
     void add_macro(const std::string &name, const std::string &expr)
-    { macros[name] = expr; }
+    { macro_dict.add_macro(name, expr); }
 
-    const std::string& get_macro(const std::string &name) const;
+    void del_macro(const std::string &name) { macro_dict.del_macro(name); }
 
-    ga_tree& macro_tree(const std::string &name, size_type meshdim,
-                        size_type ref_elt_dim, bool ignore_X) const;
+    const std::string& get_macro(const std::string &name) const;
 
     const ga_macro_dictionnary &macro_dictionnary() const { return macro_dict; 
}
 
@@ -669,12 +669,12 @@ namespace getfem {
   (ga_workspace &workspace, const std::string &transname,
    const mesh &source_mesh, const mesh &target_mesh, const std::string &expr);
 
-  /** Add a transformation to the workspace that creates an identity mapping 
between
-      two meshes in deformed state. Conceptually, it can be viewed as a 
transformation
-      from expression Xsource + Usource - Utarget, except such an expression
-      cannot be used directly in the transformation from expression (function 
above),
-      as Utarget needs to be interpolated though an inversion of the 
transformation of
-      the target domain.
+  /** Add a transformation to the workspace that creates an identity mapping
+      between two meshes in deformed state. Conceptually, it can be viewed
+      as a transformation from expression Xsource + Usource - Utarget,
+      except such an expression cannot be used directly in the transformation
+      from expression (function above), as Utarget needs to be interpolated
+      though an inversion of the transformation of the target domain.
       Thread safe if added to thread local workspace.
   */
   void add_interpolate_transformation_on_deformed_domains
@@ -683,7 +683,7 @@ namespace getfem {
    const mesh_region &source_region, const mesh &target_mesh,
    const std::string &target_displacements, const mesh_region &target_region);
 
-  /**.. the same as above, but adding transformation to the model.
+  /** The same as above, but adding transformation to the model.
   Note, this version is not thread safe.*/
   void add_interpolate_transformation_on_deformed_domains
   (model &md, const std::string &transname,
diff --git a/src/getfem/getfem_generic_assembly_tree.h 
b/src/getfem/getfem_generic_assembly_tree.h
index e9766b8..36b6b88 100644
--- a/src/getfem/getfem_generic_assembly_tree.h
+++ b/src/getfem/getfem_generic_assembly_tree.h
@@ -468,6 +468,8 @@ namespace getfem {
   // No semantic analysis is done. The tree can be inconsistent.
   void ga_read_string(const std::string &expr, ga_tree &tree,
                      const ga_macro_dictionnary &macro_dict);
+  void ga_read_string_reg(const std::string &expr, ga_tree &tree,
+                         ga_macro_dictionnary &macro_dict);
 
 
 } /* end of namespace */
diff --git a/src/getfem/getfem_models.h b/src/getfem/getfem_models.h
index 6bc7934..7da65d1 100644
--- a/src/getfem/getfem_models.h
+++ b/src/getfem/getfem_models.h
@@ -372,7 +372,6 @@ namespace getfem {
     // generic assembly
     std::map<std::string, std::vector<std::string> > variable_groups;
 
-    std::map<std::string, std::string> macros;
     ga_macro_dictionnary macro_dict;
     
 
@@ -844,11 +843,12 @@ namespace getfem {
         The name of a macro cannot coincide with a variable name. */
     void add_macro(const std::string &name, const std::string &expr);
 
-    /** Says if a macro of that name has been defined. */
-    bool macro_exists(const std::string &name) const;
+    /** Delete a previously defined macro definition. */
+    void del_macro(const std::string &name);
 
-    /** Gives the exression string of a macro. */
-    const std::string& get_macro(const std::string &name) const;
+    /** Says if a macro of that name has been defined. */
+    bool macro_exists(const std::string &name) const
+    { return macro_dict.macro_exists(name); }
 
     /** Delete a variable or data of the model. */
     void delete_variable(const std::string &varname);
diff --git a/src/getfem_generic_assembly_semantic.cc 
b/src/getfem_generic_assembly_semantic.cc
index bd873fb..0a589d0 100644
--- a/src/getfem_generic_assembly_semantic.cc
+++ b/src/getfem_generic_assembly_semantic.cc
@@ -1433,22 +1433,6 @@ namespace getfem {
           pnode->node_type = GA_NODE_OPERATOR;
           pnode->name = name;
           pnode->test_function_type = 0;
-        } else if (workspace.macro_exists(name)) {
-          GMM_ASSERT1(pnode->der1 == 0 && pnode->der2 == 0,
-                      "Derivativation of a macro is not allowed");
-          ga_tree &ma_tree
-            = workspace.macro_tree(name, meshdim, ref_elt_dim, ignore_X);
-          pga_tree_node pnode_old = pnode;
-          pnode = nullptr;
-          tree.copy_node(ma_tree.root, pnode_old->parent, pnode);
-          if (pnode_old->parent)
-            pnode_old->parent->replace_child(pnode_old, pnode);
-          else
-            tree.root = pnode;
-          GMM_ASSERT1(pnode_old->children.empty(), "Internal error");
-          delete pnode_old;
-          ga_node_analysis(expr, tree, workspace, pnode, meshdim,
-                           ref_elt_dim, eval_fixed_size, ignore_X, option);
         } else {
           // Search for a variable name with optional gradient, Hessian,
           // divergence or test functions
diff --git a/src/getfem_generic_assembly_tree.cc 
b/src/getfem_generic_assembly_tree.cc
index 57d693a..e5d23f0 100644
--- a/src/getfem_generic_assembly_tree.cc
+++ b/src/getfem_generic_assembly_tree.cc
@@ -1336,10 +1336,18 @@ namespace getfem {
     GMM_ASSERT1(false, "Undefined macro");
   }
 
-  void ga_macro_dictionnary::add_macro(const ga_macro &gam) {
-    macros[gam.name()] = gam;
-  }
+  void ga_macro_dictionnary::add_macro(const ga_macro &gam)
+  { macros[gam.name()] = gam; }
 
+  void ga_macro_dictionnary::add_macro(const std::string &name,
+                                      const std::string &expr)
+  { ga_tree tree; ga_read_string_reg("Def "+name+":="+expr, tree, *this); }
+
+  void ga_macro_dictionnary::del_macro(const std::string &name) {
+    auto it = macros.find(name);
+    GMM_ASSERT1(it != macros.end(), "Undefined macro (at this level)");
+    macros.erase(it);
+  }
 
   
   //=========================================================================
@@ -1358,8 +1366,6 @@ namespace getfem {
 
       t_type = ga_get_token(expr, pos, token_pos, token_length);
 
-      // cout << "t_type = " << int(t_type) << " state = " << state << endl;
-
       switch (state) {
 
       case 1:
@@ -1431,7 +1437,7 @@ namespace getfem {
              }
              if (t_type != GA_RPAR)
                ga_throw_error(expr, pos-1,
-                              "Missing right parenthesis in macro 
definition.");
+                             "Missing right parenthesis in macro definition.");
              t_type = ga_get_token(expr, pos, token_pos, token_length);
            }
            if (t_type != GA_COLON_EQ)
@@ -1440,17 +1446,19 @@ namespace getfem {
            t_type = ga_read_term(expr, pos, gam.tree(), macro_dict);
            gam.nb_params() = params.size();
            ga_mark_macro_params(gam, params, macro_dict, expr);
+           if (gam.tree().root)
+             ga_expand_macro(gam.tree(), gam.tree().root, macro_dict, expr);
            macro_dict.add_macro(gam);
 
-           cout << "macro \"" << gam.name() << "\" registered with "
-                << gam.nb_params() << " params  := "
-                << ga_tree_to_string(gam.tree()) << endl;
+           // cout << "macro \"" << gam.name() << "\" registered with "
+           //   << gam.nb_params() << " params  := "
+           //   << ga_tree_to_string(gam.tree()) << endl;
            
            if (t_type == GA_END) return t_type;
             else if (t_type != GA_SEMICOLON)
               ga_throw_error(expr, pos-1,
                             "Syntax error at the end of macro definition.");
-           state = 1; // ?? 
+           state = 1;
          }
          break;
 
@@ -1796,20 +1804,17 @@ namespace getfem {
     return GA_INVALID;
   }
 
-  // Syntax analysis of a string. Conversion to a tree.
-  void ga_read_string(const std::string &expr, ga_tree &tree,
-                     const ga_macro_dictionnary &macro_dict) {
+  // Syntax analysis of a string. Conversion to a tree. register the macros.
+  void ga_read_string_reg(const std::string &expr, ga_tree &tree,
+                         ga_macro_dictionnary &macro_dict) {
     size_type pos = 0, token_pos, token_length;
     tree.clear();
     GA_TOKEN_TYPE t = ga_get_token(expr, pos, token_pos, token_length);
     if (t == GA_END) return;
     pos = 0;
-
-    ga_macro_dictionnary macro_dict_loc(true, macro_dict);
     
-    t = ga_read_term(expr, pos, tree, macro_dict_loc);
-
-    if (tree.root) ga_expand_macro(tree, tree.root, macro_dict_loc, expr);
+    t = ga_read_term(expr, pos, tree, macro_dict);
+    if (tree.root) ga_expand_macro(tree, tree.root, macro_dict, expr);
     
     switch (t) {
     case GA_RPAR: ga_throw_error(expr, pos-1, "Unbalanced parenthesis.");
@@ -1818,6 +1823,15 @@ namespace getfem {
     default: ga_throw_error(expr, pos-1, "Unexpected token.");
     }
   }
+  
+  // Syntax analysis of a string. Conversion to a tree.
+  // Do not register the macros (but expand them).
+  void ga_read_string(const std::string &expr, ga_tree &tree,
+                     const ga_macro_dictionnary &macro_dict) {
+    ga_macro_dictionnary macro_dict_loc(true, macro_dict);
+    ga_read_string_reg(expr, tree, macro_dict_loc);
+  }
+  
 
   // Small tool to make basic substitutions into an assembly string
   std::string ga_substitute(const std::string &expr,
diff --git a/src/getfem_generic_assembly_workspace.cc 
b/src/getfem_generic_assembly_workspace.cc
index 6633814..018730b 100644
--- a/src/getfem_generic_assembly_workspace.cc
+++ b/src/getfem_generic_assembly_workspace.cc
@@ -295,59 +295,6 @@ namespace getfem {
     GMM_ASSERT1(false, "No time step defined here");
   }
 
-
-  // Macros
-  bool ga_workspace::macro_exists(const std::string &name) const {
-    if (macros.find(name) != macros.end()) return true;
-    if (md && md->macro_exists(name)) return true;
-    if (parent_workspace &&
-        parent_workspace->macro_exists(name)) return true;
-    return false;
-  }
-
-  const std::string&
-  ga_workspace::get_macro(const std::string &name) const {
-    std::map<std::string, std::string>::const_iterator it=macros.find(name);
-    if (it != macros.end()) return it->second;
-    if (md && md->macro_exists(name)) return md->get_macro(name);
-    if (parent_workspace &&
-        parent_workspace->macro_exists(name))
-      return parent_workspace->get_macro(name);
-    GMM_ASSERT1(false, "Undefined macro");
-  }
-
-  ga_tree &
-  ga_workspace::macro_tree(const std::string &name, size_type meshdim,
-                           size_type ref_elt_dim, bool ignore_X) const {
-    GMM_ASSERT1(macro_exists(name), "Undefined macro");
-    auto it = macro_trees.find(name);
-    bool to_be_analyzed = false;
-    m_tree *mt = 0;
-
-    if (it == macro_trees.end()) {
-      mt = &(macro_trees[name]);
-      to_be_analyzed = true;
-    } else {
-      mt = &(it->second);
-      GMM_ASSERT1(mt->ptree, "Recursive definition of macro " << name);
-      if (mt->meshdim != meshdim || mt->ignore_X != ignore_X) {
-        to_be_analyzed = true;
-        delete mt->ptree; mt->ptree = 0;
-      }
-    }
-    if (to_be_analyzed) {
-      ga_tree tree;
-      ga_read_string(get_macro(name), tree, macro_dictionnary());
-      ga_semantic_analysis(get_macro(name), tree, *this, meshdim, ref_elt_dim,
-                           false, ignore_X, 3);
-      GMM_ASSERT1(tree.root, "Invalid macro");
-      mt->ptree = new ga_tree(tree);
-      mt->meshdim = meshdim;
-      mt->ignore_X = ignore_X;
-    }
-    return *(mt->ptree);
-  }
-
   void ga_workspace::add_interpolate_transformation
   (const std::string &name, pinterpolate_transformation ptrans) {
     if (transformations.find(name) != transformations.end())
@@ -883,10 +830,7 @@ namespace getfem {
     }
   }
 
-  void ga_workspace::clear_expressions() {
-    trees.clear();
-    macro_trees.clear();
-  }
+  void ga_workspace::clear_expressions() { trees.clear(); }
 
   void ga_workspace::print(std::ostream &str) {
     for (size_type i = 0; i < trees.size(); ++i)
diff --git a/src/getfem_models.cc b/src/getfem_models.cc
index ded2a43..fd7839b 100644
--- a/src/getfem_models.cc
+++ b/src/getfem_models.cc
@@ -168,7 +168,7 @@ namespace getfem {
       return false;
     }
 
-    if (macros.find(name) != macros.end()) {
+    if (macro_exists(name)) {
       GMM_ASSERT1(!assert,
                   name << " corresponds to an already existing macro");
       return false;
@@ -985,17 +985,10 @@ namespace getfem {
   }
 
   void model::add_macro(const std::string &name, const std::string &expr)
-  { check_name_validity(name); macros[name] = expr; }
-
-  bool model::macro_exists(const std::string &name) const
-  { return (macros.find(name) != macros.end()); }
-
-  const std::string &model::get_macro(const std::string &name) const {
-    std::map<std::string, std::string>::const_iterator it = macros.find(name);
-    GMM_ASSERT1(it != macros.end(), "Undefined macro");
-    return it->second;
-  }
+  { check_name_validity(name); macro_dict.add_macro(name, expr); }
 
+  void model::del_macro(const std::string &name)
+  { macro_dict.del_macro(name); }
 
   void model::delete_brick(size_type ib) {
      GMM_ASSERT1(valid_bricks[ib], "Inexistent brick");



reply via email to

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