[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: |
Sun, 29 Apr 2018 13:11:23 -0400 (EDT) |
branch: devel-yves-generic-assembly-modifs
commit d9128beb76edff35fd19ba03ef8f44055d8ad1e3
Author: Yves Renard <address@hidden>
Date: Sun Apr 29 19:10:45 2018 +0200
adding the definition of macros with parameters, work in progress
---
src/getfem/getfem_generic_assembly.h | 66 ++++++++--
src/getfem/getfem_generic_assembly_tree.h | 8 +-
src/getfem/getfem_models.h | 4 +
src/getfem_generic_assembly_semantic.cc | 5 +-
src/getfem_generic_assembly_tree.cc | 205 ++++++++++++++++++++++++++++--
src/getfem_generic_assembly_workspace.cc | 27 +++-
6 files changed, 280 insertions(+), 35 deletions(-)
diff --git a/src/getfem/getfem_generic_assembly.h
b/src/getfem/getfem_generic_assembly.h
index f7d229a..c5531c2 100644
--- a/src/getfem/getfem_generic_assembly.h
+++ b/src/getfem/getfem_generic_assembly.h
@@ -132,9 +132,55 @@ namespace getfem {
pelementary_transformation;
//=========================================================================
+ // Structure dealing with macros.
+ //=========================================================================
+
+ class ga_macro {
+
+ protected:
+ ga_tree *ptree;
+ std::string macro_name_;
+ size_type nbp;
+
+ public:
+ ga_macro();
+ ga_macro(const std::string &name, const ga_tree &t, size_type nbp_);
+ ga_macro(const ga_macro &);
+ ~ga_macro();
+ ga_macro &operator =(const ga_macro &);
+
+ const std::string &name() const { return macro_name_; }
+ std::string &name() { return macro_name_; }
+ size_type nb_params() const { return nbp; }
+ size_type &nb_params() { return nbp; }
+ const ga_tree& tree() const { return *ptree; }
+ ga_tree& tree() { return *ptree; }
+ };
+
+
+ class ga_macro_dictionnary {
+
+ protected:
+ const ga_macro_dictionnary *parent;
+ std::map<std::string, ga_macro> macros;
+
+ public:
+ bool macro_exists(const std::string &name) const;
+ const ga_macro &get_macro(const std::string &name) const;
+
+ void add_macro(const ga_macro &gam);
+
+ ga_macro_dictionnary() : parent(0) {}
+ ga_macro_dictionnary(bool, const ga_macro_dictionnary& gamd)
+ : parent(&gamd) {}
+
+ };
+
+ //=========================================================================
// Structure dealing with predefined operators.
//=========================================================================
+
struct ga_nonlinear_operator {
typedef std::vector<const base_tensor *> arg_list;
@@ -274,7 +320,8 @@ namespace getfem {
std::vector<tree_description> trees;
std::map<std::string, std::vector<std::string> > variable_groups;
- std::map<std::string, std::string> macros;
+ std::map<std::string, std::string> macros; // A SUPPRIMER
+ ga_macro_dictionnary macro_dict;
struct m_tree {
ga_tree *ptree;
@@ -427,6 +474,8 @@ namespace getfem {
ga_tree& macro_tree(const std::string &name, size_type meshdim,
size_type ref_elt_dim, bool ignore_X) const;
+ const ga_macro_dictionnary ¯o_dictionnary() const { return macro_dict;
}
+
// interpolate and elementary transformations
void add_interpolate_transformation(const std::string &name,
@@ -457,17 +506,10 @@ namespace getfem {
void assembly(size_type order);
- ga_workspace(const getfem::model &md_, bool enable_all_variables = false)
- : md(&md_), parent_workspace(0),
- enable_all_md_variables(enable_all_variables)
- { init(); }
- ga_workspace(bool, const ga_workspace &gaw)
- : md(0), parent_workspace(&gaw), enable_all_md_variables(false)
- { init(); }
- ga_workspace()
- : md(0), parent_workspace(0), enable_all_md_variables(false)
- { init(); }
- ~ga_workspace() { clear_expressions(); }
+ ga_workspace(const getfem::model &md_, bool enable_all_variables = false);
+ ga_workspace(bool, const ga_workspace &gaw);
+ ga_workspace();
+ ~ga_workspace();
};
diff --git a/src/getfem/getfem_generic_assembly_tree.h
b/src/getfem/getfem_generic_assembly_tree.h
index 85b99dd..e9766b8 100644
--- a/src/getfem/getfem_generic_assembly_tree.h
+++ b/src/getfem/getfem_generic_assembly_tree.h
@@ -87,6 +87,8 @@ namespace getfem {
GA_DIV, // '/'
GA_COLON, // ':'
GA_QUOTE, // ''' transpose
+ GA_COLON_EQ, // ':=' macro def
+ GA_DEF, // 'Def' macro def
GA_SYM, // 'Sym' operator
GA_SKEW, // 'Skew' operator
GA_TRACE, // 'Trace' operator
@@ -126,6 +128,7 @@ namespace getfem {
GA_NODE_OPERATOR,
GA_NODE_CONSTANT,
GA_NODE_NAME,
+ GA_NODE_MACRO_PARAM,
GA_NODE_PARAMS,
GA_NODE_RESHAPE,
GA_NODE_ALLINDICES,
@@ -292,7 +295,7 @@ namespace getfem {
std::string interpolate_name_test1, interpolate_name_test2; // name
// of interpolation transformation if any
size_type qdim1, qdim2; // Qdims when test_function_type > 0.
- size_type nbc1, nbc2, nbc3; // For explicit matrices and x.
+ size_type nbc1, nbc2, nbc3; // For explicit matrices, X and macros.
size_type pos; // Position of the first character in string
std::string name; // variable/constant/function/operator name
std::string interpolate_name; // For Interpolate : name of transformation
@@ -463,7 +466,8 @@ namespace getfem {
// Syntax analysis of an assembly string. Conversion to a tree.
// No semantic analysis is done. The tree can be inconsistent.
- void ga_read_string(const std::string &expr, ga_tree &tree);
+ void ga_read_string(const std::string &expr, ga_tree &tree,
+ const ga_macro_dictionnary ¯o_dict);
} /* end of namespace */
diff --git a/src/getfem/getfem_models.h b/src/getfem/getfem_models.h
index a3f52a5..6bc7934 100644
--- a/src/getfem/getfem_models.h
+++ b/src/getfem/getfem_models.h
@@ -373,6 +373,8 @@ namespace getfem {
std::map<std::string, std::vector<std::string> > variable_groups;
std::map<std::string, std::string> macros;
+ ga_macro_dictionnary macro_dict;
+
virtual void actualize_sizes() const;
@@ -834,6 +836,8 @@ namespace getfem {
const std::string &primal_name, const mesh_im &mim,
size_type region, size_type niter = 1);
+ /** Dictonnary of user defined macros. */
+ const ga_macro_dictionnary ¯o_dictionnary() const { return macro_dict;
}
/** Add a macro definition for the high generic assembly langage.
This macro can be used for the definition of generic assembly bricks.
diff --git a/src/getfem_generic_assembly_semantic.cc
b/src/getfem_generic_assembly_semantic.cc
index 787337c..bd873fb 100644
--- a/src/getfem_generic_assembly_semantic.cc
+++ b/src/getfem_generic_assembly_semantic.cc
@@ -3126,6 +3126,8 @@ namespace getfem {
case GA_NODE_XFEM_MINUS_VAL: case GA_NODE_XFEM_MINUS_GRAD:
case GA_NODE_XFEM_MINUS_HESS: case GA_NODE_XFEM_MINUS_DIVERG:
return true;
+ case GA_NODE_INTERPOLATE_FILTER:
+ return ga_node_is_affine(child0);
case GA_NODE_OP:
switch(pnode->op_type) {
case GA_PLUS: case GA_MINUS:
@@ -3136,8 +3138,7 @@ namespace getfem {
return ga_node_is_affine(child1);
case GA_UNARY_MINUS: case GA_QUOTE: case GA_SYM: case GA_SKEW:
- case GA_TRACE: case GA_DEVIATOR:
- case GA_PRINT: case GA_NODE_INTERPOLATE_FILTER:
+ case GA_TRACE: case GA_DEVIATOR: case GA_PRINT:
return ga_node_is_affine(child0);
case GA_DOT: case GA_MULT: case GA_COLON: case GA_TMULT:
diff --git a/src/getfem_generic_assembly_tree.cc
b/src/getfem_generic_assembly_tree.cc
index 99e6307..2d84a2e 100644
--- a/src/getfem_generic_assembly_tree.cc
+++ b/src/getfem_generic_assembly_tree.cc
@@ -43,13 +43,12 @@ namespace getfem {
ga_char_type[','] = GA_COMMA; ga_char_type[';'] = GA_SEMICOLON;
ga_char_type['('] = GA_LPAR; ga_char_type[')'] = GA_RPAR;
ga_char_type['['] = GA_LBRACKET; ga_char_type[']'] = GA_RBRACKET;
- ga_char_type['_'] = GA_NAME;
+ ga_char_type['_'] = GA_NAME; ga_char_type['='] = GA_COLON_EQ;
for (unsigned i = 'a'; i <= 'z'; ++i) ga_char_type[i] = GA_NAME;
for (unsigned i = 'A'; i <= 'Z'; ++i) ga_char_type[i] = GA_NAME;
for (unsigned i = '0'; i <= '9'; ++i) ga_char_type[i] = GA_SCALAR;
- for (unsigned i = 0; i < GA_NB_TOKEN_TYPE; ++i)
- ga_operator_priorities[i] = 0;
+ for (unsigned i=0; i < GA_NB_TOKEN_TYPE; ++i) ga_operator_priorities[i] =
0;
ga_operator_priorities[GA_PLUS] = 1;
ga_operator_priorities[GA_MINUS] = 1;
ga_operator_priorities[GA_MULT] = 2;
@@ -133,6 +132,8 @@ namespace getfem {
}
if (expr.compare(token_pos, token_length, "Sym") == 0)
return GA_SYM;
+ if (expr.compare(token_pos, token_length, "Def") == 0)
+ return GA_DEF;
if (expr.compare(token_pos, token_length, "Skew") == 0)
return GA_SKEW;
if (expr.compare(token_pos, token_length, "Trace") == 0)
@@ -165,11 +166,18 @@ namespace getfem {
++pos; return GA_DSEMICOLON;
}
return type;
+ case GA_COLON:
+ if (pos < expr.size() &&
+ ga_char_type[unsigned(expr[pos])] == GA_COLON_EQ) {
+ ++pos; return GA_COLON_EQ;
+ }
+ return type;
+ case GA_COLON_EQ:
+ return GA_INVALID;
default: return type;
}
}
-
//=========================================================================
// Error handling
//=========================================================================
@@ -1020,6 +1028,16 @@ namespace getfem {
str << pnode->name;
GMM_ASSERT1(pnode->children.size() == 0, "Invalid tree");
break;
+
+ case GA_NODE_MACRO_PARAM:
+ if (pnode->nbc2 == 1) str << "Grad_";
+ if (pnode->nbc2 == 2) str << "Hess_";
+ if (pnode->nbc2 == 3) str << "Div_";
+ if (pnode->nbc3 == 1) str << "Test_";
+ if (pnode->nbc3 == 2) str << "Test2_";
+ str << "P" << pnode->nbc1;
+ GMM_ASSERT1(pnode->children.size() == 0, "Invalid tree");
+ break;
case GA_NODE_RESHAPE:
str << "Reshape";
@@ -1163,6 +1181,108 @@ namespace getfem {
return 0;
}
+
+ //=========================================================================
+ // Structure dealing with macros.
+ //=========================================================================
+
+ ga_macro::ga_macro() : ptree(new ga_tree), nbp(0) {}
+ ga_macro::~ga_macro() { delete ptree; }
+ ga_macro::ga_macro(const std::string &name, const ga_tree &t, size_type nbp_)
+ : ptree(new ga_tree(t)), macro_name_(name), nbp(nbp_) {}
+ ga_macro::ga_macro(const ga_macro &gam)
+ : ptree(new ga_tree(gam.tree())), macro_name_(gam.name()),
+ nbp(gam.nb_params()) {}
+ ga_macro &ga_macro::operator =(const ga_macro &gam) {
+ delete ptree; ptree = new ga_tree(gam.tree());
+ macro_name_ = gam.name();
+ nbp = gam.nb_params();
+ return *this;
+ }
+
+ void ga_expand_macro(const pga_tree_node pnode,
+ const ga_macro_dictionnary ¯o_dict,
+ const std::string &expr) {
+ if (!pnode) return;
+
+ if (pnode->node_type == GA_NODE_PARAMS) {
+
+ for (size_type i = 1; i < pnode->children.size(); ++i)
+ ga_expand_macro(pnode->children[i], macro_dict, expr);
+
+ if (macro_dict.macro_exists(pnode->children[0]->name)) { // Macro with
parameters
+
+
+
+ const ga_macro &gam = macro_dict.get_macro(pnode->children[0]->name);
+ if (gam.nb_params()+1 != pnode->children.size())
+ ga_throw_error(expr, pnode->pos,
+ "Bad number of parameters in the use of macro '"
+ << gam.name() << "'. Expected " << gam.nb_params()
+ << " found " << pnode->children.size()-1 << ".");
+ // performs expand
+ }
+
+ } else if (pnode->node_type == GA_NODE_NAME && // Macro without parameters
+ macro_dict.macro_exists(pnode->name)) {
+
+
+
+ } else {
+ for (size_type i = 0; i < pnode->children.size(); ++i)
+ ga_expand_macro(pnode->children[i], macro_dict, expr);
+ }
+ }
+
+
+ static void ga_mark_macro_params_rec(const pga_tree_node pnode,
+ const std::vector<std::string> ¶ms) {
+ if (!pnode) return;
+ for (size_type i = 0; i < pnode->children.size(); ++i)
+ ga_mark_macro_params_rec(pnode->children[i], params);
+
+ if (pnode->node_type == GA_NODE_NAME) {
+ size_type po = ga_parse_prefix_operator(pnode->name);
+ size_type pt = ga_parse_prefix_test(pnode->name);
+
+ for (size_type i = 0; i < params.size(); ++i)
+ if (pnode->name.compare(params[i]) == 0) {
+ pnode->node_type = GA_NODE_MACRO_PARAM;
+ pnode->nbc1 = i; pnode->nbc2 = po; pnode->nbc3 = pt;
+ }
+ }
+ }
+
+ static void ga_mark_macro_params(ga_macro &gam,
+ const std::vector<std::string> ¶ms,
+ const ga_macro_dictionnary ¯o_dict,
+ const std::string &expr) {
+ if (gam.tree().root) {
+ ga_mark_macro_params_rec(gam.tree().root, params);
+ ga_expand_macro(gam.tree().root, macro_dict, expr);
+ }
+ }
+
+ bool ga_macro_dictionnary::macro_exists(const std::string &name) const {
+ if (macros.find(name) != macros.end()) return true;
+ if (parent && parent->macro_exists(name)) return true;
+ return false;
+ }
+
+
+ const ga_macro &
+ ga_macro_dictionnary::get_macro(const std::string &name) const {
+ auto it = macros.find(name);
+ if (it != macros.end()) return it->second;
+ if (parent) return parent->get_macro(name);
+ GMM_ASSERT1(false, "Undefined macro");
+ }
+
+ void ga_macro_dictionnary::add_macro(const ga_macro &gam) {
+ macros[gam.name()] = gam;
+ }
+
+
//=========================================================================
// Syntax analysis for the generic assembly langage
@@ -1170,7 +1290,8 @@ namespace getfem {
// Read a term with an (implicit) pushdown automaton.
static GA_TOKEN_TYPE ga_read_term(const std::string &expr, size_type &pos,
- ga_tree &tree) {
+ ga_tree &tree,
+ ga_macro_dictionnary ¯o_dict) {
size_type token_pos, token_length;
GA_TOKEN_TYPE t_type;
int state = 1; // 1 = reading term, 2 = reading after term
@@ -1179,6 +1300,8 @@ 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:
@@ -1222,6 +1345,57 @@ namespace getfem {
tree.add_op(GA_DEVIATOR, token_pos);
state = 1; break;
+ case GA_DEF:
+ {
+ ga_macro gam;
+ t_type = ga_get_token(expr, pos, token_pos, token_length);
+ if (t_type != GA_NAME)
+ ga_throw_error(expr, pos,
+ "Macro definition should begin with macro name");
+ gam.name() = std::string(&(expr[token_pos]), token_length);
+ if (ga_check_name_validity(gam.name()))
+ ga_throw_error(expr, pos-1, "Invalid macro name.")
+ t_type = ga_get_token(expr, pos, token_pos, token_length);
+ std::vector<std::string> params;
+ if (t_type == GA_LPAR) {
+ t_type = ga_get_token(expr, pos, token_pos, token_length);
+ while (t_type == GA_NAME) {
+ params.push_back(std::string(&(expr[token_pos]), token_length));
+ if (ga_check_name_validity(params.back()))
+ ga_throw_error(expr, pos-1, "Invalid macro parameter name.");
+ for (size_type i = 0; i+1 < params.size(); ++i)
+ if (params.back().compare(params[i]) == 0)
+ ga_throw_error(expr, pos-1,
+ "Invalid repeated macro parameter name.");
+ t_type = ga_get_token(expr, pos, token_pos, token_length);
+ if (t_type == GA_COMMA)
+ t_type = ga_get_token(expr, pos, token_pos, token_length);
+ }
+ if (t_type != GA_RPAR)
+ ga_throw_error(expr, pos-1,
+ "Missing right parenthesis in macro
definition.");
+ t_type = ga_get_token(expr, pos, token_pos, token_length);
+ }
+ if (t_type != GA_COLON_EQ)
+ ga_throw_error(expr, pos-1, "Missing := for macro definition.");
+
+ 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);
+ macro_dict.add_macro(gam);
+
+ 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; // ??
+ }
+ break;
+
case GA_INTERPOLATE:
{
tree.add_scalar(scalar_type(0), token_pos);
@@ -1356,14 +1530,14 @@ namespace getfem {
ga_throw_error(expr,pos,
"Bad format for Interpolate_filter arguments.");
ga_tree sub_tree;
- t_type = ga_read_term(expr, pos, sub_tree);
+ t_type = ga_read_term(expr, pos, sub_tree, macro_dict);
if (t_type != GA_RPAR && t_type != GA_COMMA)
ga_throw_error(expr, pos-1,
"Bad format for Interpolate_filter arguments.");
tree.add_sub_tree(sub_tree);
if (t_type == GA_COMMA) {
ga_tree sub_tree2;
- t_type = ga_read_term(expr, pos, sub_tree2);
+ t_type = ga_read_term(expr, pos, sub_tree2, macro_dict);
tree.add_sub_tree(sub_tree2);
}
if (t_type != GA_RPAR)
@@ -1380,7 +1554,7 @@ namespace getfem {
{
ga_tree sub_tree;
GA_TOKEN_TYPE r_type;
- r_type = ga_read_term(expr, pos, sub_tree);
+ r_type = ga_read_term(expr, pos, sub_tree, macro_dict);
if (r_type != GA_RPAR)
ga_throw_error(expr, pos-1, "Unbalanced parenthesis.");
tree.add_sub_tree(sub_tree);
@@ -1398,7 +1572,7 @@ namespace getfem {
tree.add_matrix(token_pos);
do {
- r_type = ga_read_term(expr, pos, sub_tree);
+ r_type = ga_read_term(expr, pos, sub_tree, macro_dict);
if (sub_tree.root->node_type == GA_NODE_C_MATRIX) {
// nested format
@@ -1543,7 +1717,7 @@ namespace getfem {
GA_TOKEN_TYPE r_type;
tree.add_params(token_pos);
do {
- r_type = ga_read_term(expr, pos, sub_tree);
+ r_type = ga_read_term(expr, pos, sub_tree, macro_dict);
if (r_type != GA_RPAR && r_type != GA_COMMA)
ga_throw_error(expr, pos-((r_type != GA_END)?1:0),
"Parameters should be separated "
@@ -1565,13 +1739,20 @@ namespace getfem {
}
// Syntax analysis of a string. Conversion to a tree.
- void ga_read_string(const std::string &expr, ga_tree &tree) {
+ void ga_read_string(const std::string &expr, ga_tree &tree,
+ const 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;
- t = ga_read_term(expr, pos, tree);
+
+ 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.root, macro_dict_loc, expr);
+
switch (t) {
case GA_RPAR: ga_throw_error(expr, pos-1, "Unbalanced parenthesis.");
case GA_RBRACKET: ga_throw_error(expr, pos-1, "Unbalanced braket.");
diff --git a/src/getfem_generic_assembly_workspace.cc
b/src/getfem_generic_assembly_workspace.cc
index ccccb9d..6633814 100644
--- a/src/getfem_generic_assembly_workspace.cc
+++ b/src/getfem_generic_assembly_workspace.cc
@@ -337,7 +337,7 @@ namespace getfem {
}
if (to_be_analyzed) {
ga_tree tree;
- ga_read_string(get_macro(name), 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");
@@ -532,7 +532,7 @@ namespace getfem {
GA_TIC;
size_type max_order = 0;
std::vector<ga_tree> ltrees(1);
- ga_read_string(expr, ltrees[0]);
+ ga_read_string(expr, ltrees[0], macro_dictionnary());
// cout << "read : " << ga_tree_to_string(ltrees[0]) << endl;
ga_semantic_analysis(expr, ltrees[0], *this, mim.linked_mesh().dim(),
ref_elt_dim_of_mesh(mim.linked_mesh()),
@@ -576,7 +576,7 @@ namespace getfem {
void ga_workspace::add_function_expression(const std::string &expr) {
ga_tree tree;
- ga_read_string(expr, tree);
+ ga_read_string(expr, tree, macro_dictionnary());
ga_semantic_analysis(expr, tree, *this, 1, 1, false, true);
if (tree.root) {
// GMM_ASSERT1(tree.root->nb_test_functions() == 0,
@@ -591,7 +591,7 @@ namespace getfem {
const mesh_region &rg_) {
const mesh_region &rg = register_region(m, rg_);
ga_tree tree;
- ga_read_string(expr, tree);
+ ga_read_string(expr, tree, macro_dictionnary());
ga_semantic_analysis(expr, tree, *this, m.dim(), ref_elt_dim_of_mesh(m),
false, false);
if (tree.root) {
@@ -607,7 +607,7 @@ namespace getfem {
const mesh &m = mim.linked_mesh();
const mesh_region &rg = register_region(m, rg_);
ga_tree tree;
- ga_read_string(expr, tree);
+ ga_read_string(expr, tree, macro_dictionnary());
ga_semantic_analysis(expr, tree, *this, m.dim(), ref_elt_dim_of_mesh(m),
false, false);
if (tree.root) {
@@ -626,7 +626,7 @@ namespace getfem {
const mesh &m = mim.linked_mesh();
const mesh_region &rg = register_region(m, rg_);
ga_tree tree;
- ga_read_string(expr, tree);
+ ga_read_string(expr, tree, macro_dictionnary());
ga_semantic_analysis(expr, tree, *this, m.dim(), ref_elt_dim_of_mesh(m),
false, false);
if (tree.root) {
@@ -919,7 +919,20 @@ namespace getfem {
ga_workspace::tree_description::~tree_description()
{ if (ptree) delete ptree; ptree = 0; }
-
+ ga_workspace::ga_workspace(const getfem::model &md_,
+ bool enable_all_variables)
+ : md(&md_), parent_workspace(0),
+ enable_all_md_variables(enable_all_variables),
+ macro_dict(md_.macro_dictionnary())
+ { init(); }
+ ga_workspace::ga_workspace(bool, const ga_workspace &gaw)
+ : md(0), parent_workspace(&gaw), enable_all_md_variables(false),
+ macro_dict(gaw.macro_dictionnary())
+ { init(); }
+ ga_workspace::ga_workspace()
+ : md(0), parent_workspace(0), enable_all_md_variables(false)
+ { init(); }
+ ga_workspace::~ga_workspace() { clear_expressions(); }
//=========================================================================
// Extract the constant term of degree 1 expressions