[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 ¯o_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 ¯o_dict);
+ void ga_read_string_reg(const std::string &expr, ga_tree &tree,
+ ga_macro_dictionnary ¯o_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 ¯o_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 ¯o_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 ¯o_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");