[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 ced932d32a5db7a54604e7438884354a199d6bd4
Author: Yves Renard <address@hidden>
Date: Mon Apr 30 16:13:56 2018 +0200
better error messages
---
src/getfem/getfem_generic_assembly_semantic.h | 2 +-
src/getfem/getfem_generic_assembly_tree.h | 52 ++--
src/getfem_generic_assembly_compile_and_exec.cc | 4 +-
...fem_generic_assembly_functions_and_operators.cc | 5 +-
src/getfem_generic_assembly_interpolation.cc | 3 +-
src/getfem_generic_assembly_semantic.cc | 279 +++++++++++----------
src/getfem_generic_assembly_tree.cc | 247 +++++++++---------
src/getfem_generic_assembly_workspace.cc | 18 +-
src/getfem_models.cc | 6 +-
9 files changed, 326 insertions(+), 290 deletions(-)
diff --git a/src/getfem/getfem_generic_assembly_semantic.h
b/src/getfem/getfem_generic_assembly_semantic.h
index 78abcfe..a4426bb 100644
--- a/src/getfem/getfem_generic_assembly_semantic.h
+++ b/src/getfem/getfem_generic_assembly_semantic.h
@@ -55,7 +55,7 @@ namespace getfem {
3 : do not complain about incompatible test functions neither
store them.
*/
- void ga_semantic_analysis(const std::string &expr, ga_tree &tree,
+ void ga_semantic_analysis(ga_tree &tree,
const ga_workspace &workspace,
size_type meshdim,
size_type ref_elt_dim,
diff --git a/src/getfem/getfem_generic_assembly_tree.h
b/src/getfem/getfem_generic_assembly_tree.h
index 36b6b88..2d05fdc 100644
--- a/src/getfem/getfem_generic_assembly_tree.h
+++ b/src/getfem/getfem_generic_assembly_tree.h
@@ -188,8 +188,9 @@ namespace getfem {
GA_NODE_XFEM_MINUS_DIVERG_TEST,
GA_NODE_ZERO};
+ typedef std::shared_ptr<std::string> pstring;
// Print error message indicating the position in the assembly string
- void ga_throw_error_msg(const std::string &expr, size_type pos,
+ void ga_throw_error_msg(pstring expr, size_type pos,
const std::string &msg);
# define ga_throw_error(expr, pos, msg) \
@@ -282,6 +283,7 @@ namespace getfem {
struct ga_tree_node;
typedef ga_tree_node *pga_tree_node;
+
struct ga_tree_node {
GA_NODE_TYPE node_type;
GA_TOKEN_TYPE op_type;
@@ -297,6 +299,7 @@ namespace getfem {
size_type qdim1, qdim2; // Qdims when test_function_type > 0.
size_type nbc1, nbc2, nbc3; // For explicit matrices, X and macros.
size_type pos; // Position of the first character in string
+ pstring expr; // Original string, for error messages.
std::string name; // variable/constant/function/operator name
std::string interpolate_name; // For Interpolate : name of transformation
std::string interpolate_name_der; // For Interpolate derivative:
@@ -335,8 +338,7 @@ namespace getfem {
{ return t.sizes()[nb_test_functions()+i]; }
- void mult_test(const pga_tree_node n0, const pga_tree_node n1,
- const std::string &expr);
+ void mult_test(const pga_tree_node n0, const pga_tree_node n1);
bool tensor_is_zero() {
if (node_type == GA_NODE_ZERO) return true;
@@ -375,51 +377,43 @@ namespace getfem {
ga_tree_node()
: node_type(GA_NODE_VOID), test_function_type(-1), qdim1(0), qdim2(0),
- nbc1(0), nbc2(0), nbc3(0), pos(0), der1(0), der2(0),
+ nbc1(0), nbc2(0), nbc3(0), pos(0), expr(0), der1(0), der2(0),
symmetric_op(false), hash_value(0) {}
- ga_tree_node(GA_NODE_TYPE ty, size_type p)
+ ga_tree_node(GA_NODE_TYPE ty, size_type p, pstring expr_)
: node_type(ty), test_function_type(-1),
qdim1(0), qdim2(0), nbc1(0), nbc2(0), nbc3(0),
- pos(p), der1(0), der2(0), symmetric_op(false), hash_value(0) {}
- ga_tree_node(scalar_type v, size_type p)
+ pos(p), expr(expr_), der1(0), der2(0), symmetric_op(false),
+ hash_value(0) {}
+ ga_tree_node(scalar_type v, size_type p, pstring expr_)
: node_type(GA_NODE_CONSTANT), test_function_type(-1),
qdim1(0), qdim2(0), nbc1(0), nbc2(0), nbc3(0),
- pos(p), der1(0), der2(0), symmetric_op(false),
+ pos(p), expr(expr_), der1(0), der2(0), symmetric_op(false),
hash_value(0)
{ init_scalar_tensor(v); }
- ga_tree_node(const char *n, size_type l, size_type p)
+ ga_tree_node(const char *n, size_type l, size_type p, pstring expr_)
: node_type(GA_NODE_NAME), test_function_type(-1),
qdim1(0), qdim2(0), nbc1(0), nbc2(0), nbc3(0),
- pos(p), name(n, l), der1(0), der2(0), symmetric_op(false),
+ pos(p), expr(expr_), name(n, l), der1(0), der2(0), symmetric_op(false),
hash_value(0) {}
- ga_tree_node(GA_TOKEN_TYPE op, size_type p)
+ ga_tree_node(GA_TOKEN_TYPE op, size_type p, pstring expr_)
: node_type(GA_NODE_OP), op_type(op), test_function_type(-1),
qdim1(0), qdim2(0), nbc1(0), nbc2(0), nbc3(0),
- pos(p), der1(0), der2(0), symmetric_op(false),
+ pos(p), expr(expr_), der1(0), der2(0), symmetric_op(false),
hash_value(0) {}
};
-# define ga_valid_operand(expr, pnode) \
- { \
- if (pnode && (pnode->node_type == GA_NODE_PREDEF_FUNC || \
- pnode->node_type == GA_NODE_SPEC_FUNC || \
- pnode->node_type == GA_NODE_NAME || \
- pnode->node_type == GA_NODE_OPERATOR || \
- pnode->node_type == GA_NODE_ALLINDICES)) \
- ga_throw_error(expr, pnode->pos, "Invalid term"); \
- }
-
struct ga_tree {
pga_tree_node root, current_node;
- void add_scalar(scalar_type val, size_type pos);
- void add_allindices(size_type pos);
- void add_name(const char *name, size_type length, size_type pos);
+ void add_scalar(scalar_type val, size_type pos, pstring expr);
+ void add_allindices(size_type pos, pstring expr);
+ void add_name(const char *name, size_type length, size_type pos,
+ pstring expr);
void add_sub_tree(ga_tree &sub_tree);
- void add_params(size_type pos);
- void add_matrix(size_type pos);
+ void add_params(size_type pos, pstring expr);
+ void add_matrix(size_type pos, pstring expr);
void zip_matrix(const pga_tree_node source_node);
- void add_op(GA_TOKEN_TYPE op_type, size_type pos);
+ void add_op(GA_TOKEN_TYPE op_type, size_type pos, pstring expr);
void clear_node_rec(pga_tree_node pnode);
void clear_node(pga_tree_node pnode);
void clear() { clear_node_rec(root); root = current_node = nullptr; }
@@ -440,7 +434,7 @@ namespace getfem {
ga_tree() : root(nullptr), current_node(nullptr) {}
- ga_tree(const ga_tree &tree) : root(nullptr), current_node(nullptr)
+ ga_tree(const ga_tree &tree) : root(nullptr), current_node(nullptr)
{ if (tree.root) copy_node(tree.root, nullptr, root); }
ga_tree &operator = (const ga_tree &tree)
diff --git a/src/getfem_generic_assembly_compile_and_exec.cc
b/src/getfem_generic_assembly_compile_and_exec.cc
index 507db9e..a8b0900 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->dim(),
ref_elt_dim_of_mesh(*m), true, false);
pga_tree_node root = gis.trees.back().root;
if (root) {
@@ -5992,7 +5992,7 @@ namespace getfem {
}
// Semantic analysis mainly to evaluate fixed size variables and data
- ga_semantic_analysis("", *added_tree, workspace,
+ ga_semantic_analysis(*added_tree, workspace,
td.mim->linked_mesh().dim(),
ref_elt_dim_of_mesh(td.mim->linked_mesh()),
true, false);
diff --git a/src/getfem_generic_assembly_functions_and_operators.cc
b/src/getfem_generic_assembly_functions_and_operators.cc
index 36abf9b..2a65913 100644
--- a/src/getfem_generic_assembly_functions_and_operators.cc
+++ b/src/getfem_generic_assembly_functions_and_operators.cc
@@ -702,13 +702,12 @@ 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(expr, tree, local_workspace, 1, 1, false, true);
+ ga_semantic_analysis(tree, local_workspace, 1, 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(expr, tree, local_workspace, 1, 1,
- // false, true);
+ // ga_semantic_analysis(tree, local_workspace, 1, 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 b6bde52..c0476be 100644
--- a/src/getfem_generic_assembly_interpolation.cc
+++ b/src/getfem_generic_assembly_interpolation.cc
@@ -568,8 +568,7 @@ namespace getfem {
ga_derivative(tree, pwi.workspace(), source_mesh,
var.varname, var.transname, 1);
if (tree.root)
- ga_semantic_analysis(expr, tree, local_workspace, 1, 1,
- false, true);
+ ga_semantic_analysis(tree, local_workspace, 1, 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 0a589d0..740cc88 100644
--- a/src/getfem_generic_assembly_semantic.cc
+++ b/src/getfem_generic_assembly_semantic.cc
@@ -176,7 +176,17 @@ namespace getfem {
return c;
}
- static void ga_node_analysis(const std::string &expr, ga_tree &tree,
+# define ga_valid_operand(pnode) \
+ { \
+ if (pnode && (pnode->node_type == GA_NODE_PREDEF_FUNC || \
+ pnode->node_type == GA_NODE_SPEC_FUNC || \
+ pnode->node_type == GA_NODE_NAME || \
+ pnode->node_type == GA_NODE_OPERATOR || \
+ pnode->node_type == GA_NODE_ALLINDICES)) \
+ ga_throw_error(pnode->expr, pnode->pos, "Invalid term"); \
+ }
+
+ static void ga_node_analysis(ga_tree &tree,
const ga_workspace &workspace,
pga_tree_node pnode, size_type meshdim,
size_type ref_elt_dim, bool eval_fixed_size,
@@ -185,14 +195,14 @@ namespace getfem {
pnode->symmetric_op = false;
for (size_type i = 0; i < pnode->children.size(); ++i) {
- ga_node_analysis(expr, tree, workspace, pnode->children[i], meshdim,
+ ga_node_analysis(tree, workspace, pnode->children[i], meshdim,
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);
GMM_ASSERT1(pnode->children[i]->test_function_type != size_type(-1),
"internal error on child " << i);
if (pnode->node_type != GA_NODE_PARAMS)
- ga_valid_operand(expr, pnode->children[i]);
+ ga_valid_operand(pnode->children[i]);
}
size_type nbch = pnode->children.size();
@@ -270,7 +280,8 @@ namespace getfem {
(var_trans_pair(pnode->name_test1,
pnode->interpolate_name_test1));
if (!(pnode->qdim1))
- ga_throw_error(expr, pnode->pos, "Invalid null size of variable");
+ ga_throw_error(pnode->expr, pnode->pos,
+ "Invalid null size of variable");
} else {
pnode->interpolate_name_test1 = pnode->name_test1 = "";
pnode->name_test2 = pnode->name;
@@ -282,12 +293,14 @@ namespace getfem {
(var_trans_pair(pnode->name_test2,
pnode->interpolate_name_test2));
if (!(pnode->qdim2))
- ga_throw_error(expr, pnode->pos, "Invalid null size of variable");
+ ga_throw_error(pnode->expr, pnode->pos,
+ "Invalid null size of variable");
}
if (!mf) {
size_type n = workspace.qdim(pnode->name);
if (!n)
- ga_throw_error(expr, pnode->pos, "Invalid null size of variable");
+ ga_throw_error(pnode->expr, pnode->pos,
+ "Invalid null size of variable");
if (n == 1) {
pnode->init_vector_tensor(1);
pnode->tensor()[0] = scalar_type(1);
@@ -337,21 +350,21 @@ namespace getfem {
// Group must be tested and it should be a fem variable
if (!(workspace.variable_or_group_exists(name)))
- ga_throw_error(expr, pnode->pos,
+ ga_throw_error(pnode->expr, pnode->pos,
"Unknown variable or group of variables");
const mesh_fem *mf = workspace.associated_mf(name);
if (!mf)
- ga_throw_error(expr, pnode->pos, op__name
+ ga_throw_error(pnode->expr, pnode->pos, op__name
<< " can only apply to finite element
variables/data");
size_type q = workspace.qdim(name), n = mf->linked_mesh().dim();
- if (!q) ga_throw_error(expr, pnode->pos,
+ if (!q) ga_throw_error(pnode->expr, pnode->pos,
"Invalid null size of variable");
bgeot::multi_index mii = workspace.qdims(name);
if (mii.size() > 6)
- ga_throw_error(expr, pnode->pos,
+ ga_throw_error(pnode->expr, pnode->pos,
"Tensor with too many dimensions. Limited to 6");
if (test == 1) {
@@ -363,7 +376,7 @@ namespace getfem {
pnode->interpolate_name_test1));
pnode->qdim1 = workspace.qdim(name);
if (!(pnode->qdim1))
- ga_throw_error(expr, pnode->pos,
+ ga_throw_error(pnode->expr, pnode->pos,
"Invalid null size of variable");
} else if (test == 2) {
pnode->name_test2 = name;
@@ -374,7 +387,7 @@ namespace getfem {
pnode->interpolate_name_test2));
pnode->qdim2 = workspace.qdim(name);
if (!(pnode->qdim2))
- ga_throw_error(expr, pnode->pos,
+ ga_throw_error(pnode->expr, pnode->pos,
"Invalid null size of variable");
}
@@ -463,7 +476,7 @@ namespace getfem {
break;
case 3: // divergence
if (q != n)
- ga_throw_error(expr, pnode->pos,
+ ga_throw_error(pnode->expr, pnode->pos,
"Divergence operator requires fem qdim ("
<< q << ") to be equal to dim (" << n << ")");
if (!test) {
@@ -495,13 +508,13 @@ namespace getfem {
if (ndt == 1) {
if (!(workspace.interpolate_transformation_exists
(pnode->interpolate_name))) {
- ga_throw_error(expr, pnode->pos,
+ ga_throw_error(pnode->expr, pnode->pos,
"Unknown interpolate transformation");
}
} else if (ndt == 2) {
if (!(workspace.elementary_transformation_exists
(pnode->elementary_name))) {
- ga_throw_error(expr, pnode->pos,
+ ga_throw_error(pnode->expr, pnode->pos,
"Unknown elementary transformation");
}
}
@@ -514,7 +527,7 @@ namespace getfem {
bool valid = (child1->node_type == GA_NODE_CONSTANT);
int n = valid ? int(round(child1->tensor()[0])) : -1;
if (n < 0 || n > 100 || child1->tensor_order() > 0)
- ga_throw_error(expr, pnode->pos, "The third argument of "
+ ga_throw_error(pnode->expr, pnode->pos, "The third argument of "
"Interpolate_filter should be a (small) "
"non-negative integer.");
pnode->nbc1 = size_type(n);
@@ -522,7 +535,7 @@ namespace getfem {
}
if (!(workspace.interpolate_transformation_exists
(pnode->interpolate_name)))
- ga_throw_error(expr, pnode->pos,
+ ga_throw_error(pnode->expr, pnode->pos,
"Unknown interpolate transformation");
pnode->t = child0->t;
pnode->test_function_type = child0->test_function_type;
@@ -558,9 +571,9 @@ namespace getfem {
if (size1[i] != 1) compatible = false;
if (!compatible)
- ga_throw_error(expr, pnode->pos, "Addition or subtraction of "
- "expressions of different sizes: "
- << size0 << " != " << size1);
+ ga_throw_error(pnode->expr, pnode->pos,
+ "Addition or subtraction of expressions of "
+ "different sizes: " << size0 << " != " << size1);
if (child0->test_function_type || child1->test_function_type) {
switch (option) {
case 0: case 2:
@@ -579,8 +592,8 @@ namespace getfem {
if (child0->test_function_type != child1->test_function_type ||
(!compatible && option != 2))
- ga_throw_error(expr, pnode->pos, "Addition or subtraction of "
- "incompatible test functions");
+ ga_throw_error(pnode->expr, pnode->pos, "Addition or subtraction "
+ "of incompatible test functions");
if (all_cte) {
pnode->node_type = GA_NODE_CONSTANT;
pnode->test_function_type = 0;
@@ -676,14 +689,14 @@ namespace getfem {
}
if (!compatible)
- ga_throw_error(expr, pnode->pos,
+ ga_throw_error(pnode->expr, pnode->pos,
"Arguments of different sizes for .* or ./");
if (pnode->op_type == GA_DOTDIV && child1->test_function_type)
- ga_throw_error(expr, pnode->pos,
+ ga_throw_error(pnode->expr, pnode->pos,
"Division by test functions is not allowed");
- pnode->mult_test(child0, child1, expr);
+ pnode->mult_test(child0, child1);
mi = pnode->t.sizes();
for (size_type i = 0; i < child0->tensor_order(); ++i)
mi.push_back(child0->tensor_proper_size(i));
@@ -698,7 +711,7 @@ namespace getfem {
} else {
for (size_type i = 0; i < child0->tensor().size(); ++i) {
if (child1->tensor()[i] == scalar_type(0))
- ga_throw_error(expr, pnode->pos, "Division by zero.");
+ ga_throw_error(pnode->expr, pnode->pos, "Division by zero.");
pnode->tensor()[i] = child0->tensor()[i] / child1->tensor()[i];
}
}
@@ -710,7 +723,7 @@ namespace getfem {
tree.clear_children(pnode);
}
if (child1->tensor_is_zero() && pnode->op_type == GA_DOTDIV)
- ga_throw_error(expr, pnode->pos, "Division by zero.");
+ ga_throw_error(pnode->expr, pnode->pos, "Division by zero.");
}
}
break;
@@ -737,7 +750,7 @@ namespace getfem {
case GA_QUOTE:
if (dim0 > 2)
- ga_throw_error(expr, pnode->pos, "Transpose operator is for "
+ ga_throw_error(pnode->expr, pnode->pos, "Transpose operator is for "
"vectors or matrices only.");
mi = size0;
if (child0->tensor_proper_size() == 1)
@@ -775,8 +788,8 @@ namespace getfem {
case GA_SYM: case GA_SKEW:
if (child0->tensor_proper_size() != 1 &&
(dim0 != 2 || size0.back() != size0[size0.size()-2]))
- ga_throw_error(expr, pnode->pos, "Sym and Skew operators are for "
- "square matrices only.");
+ ga_throw_error(pnode->expr, pnode->pos, "Sym and Skew operators are "
+ "for square matrices only.");
mi = size0;
if (child0->tensor_proper_size() == 1) {
if (pnode->op_type == GA_SYM)
@@ -826,7 +839,7 @@ namespace getfem {
if ((dim0 != 2 && child0->tensor_proper_size() != 1) ||
(dim0 == 2 && mi[mi.size()-2] != N))
- ga_throw_error(expr, pnode->pos,
+ ga_throw_error(pnode->expr, pnode->pos,
"Trace operator is for square matrices only.");
if (dim0 == 2) { mi.pop_back(); mi.pop_back(); }
@@ -864,7 +877,7 @@ namespace getfem {
if ((dim0 != 2 && child0->tensor_proper_size() != 1) ||
(dim0 == 2 && mi[mi.size()-2] != N))
- ga_throw_error(expr, pnode->pos,
+ ga_throw_error(pnode->expr, pnode->pos,
"Deviator operator is for square matrices only.");
if (child0->tensor_proper_size() == 1) {
@@ -932,16 +945,16 @@ namespace getfem {
case GA_DOT:
if (dim1 > 1)
- ga_throw_error(expr, pnode->pos, "The second argument of the dot "
- "product has to be a vector.")
+ ga_throw_error(pnode->expr, pnode->pos, "The second argument of the "
+ "dot product has to be a vector.")
else {
size_type s0 = dim0 == 0 ? 1 : size0.back();
size_type s1 = dim1 == 0 ? 1 : size1.back();
- if (s0 != s1) ga_throw_error(expr, pnode->pos, "Dot product "
+ if (s0 != s1) ga_throw_error(pnode->expr, pnode->pos, "Dot product "
"of expressions of different sizes ("
<< s0 << " != " << s1 << ").");
if (child0->tensor_order() <= 1) pnode->symmetric_op = true;
- pnode->mult_test(child0, child1, expr);
+ pnode->mult_test(child0, child1);
if (dim0 > 1) {
mi = pnode->t.sizes();
for (size_type i = 1; i < dim0; ++i)
@@ -971,7 +984,7 @@ namespace getfem {
case GA_COLON:
if (dim1 > 2)
- ga_throw_error(expr, pnode->pos,
+ ga_throw_error(pnode->expr, pnode->pos,
"Frobenius product acts only on matrices.")
else {
size_type s00 = (dim0 == 0) ? 1
@@ -981,12 +994,12 @@ namespace getfem {
: (dim1 == 1 ? size1.back() : size1[size1.size()-2]);
size_type s11 = (dim1 >= 2) ? size1.back() : 1;
if (s00 != s10 || s01 != s11)
- ga_throw_error(expr, pnode->pos, "Frobenius product "
+ ga_throw_error(pnode->expr, pnode->pos, "Frobenius product "
"of expressions of different sizes ("
<< s00 << "," << s01 << " != " << s10 << ","
<< s11 << ").");
if (child0->tensor_order() <= 2) pnode->symmetric_op = true;
- pnode->mult_test(child0, child1, expr);
+ pnode->mult_test(child0, child1);
if (dim0 > 2) {
mi = pnode->t.sizes();
for (size_type i = 2; i < dim0; ++i)
@@ -1030,7 +1043,7 @@ namespace getfem {
scalar_type(child1->tensor()[0]));
} else {
if (dim0+dim1 > 6)
- ga_throw_error(expr, pnode->pos, "Unauthorized "
+ ga_throw_error(pnode->expr, pnode->pos, "Unauthorized "
"tensor multiplication.");
for (size_type i = 0; i < dim0; ++i)
mi.push_back(child0->tensor().size(i));
@@ -1045,7 +1058,7 @@ namespace getfem {
}
tree.clear_children(pnode);
} else {
- pnode->mult_test(child0, child1, expr);
+ pnode->mult_test(child0, child1);
mi = pnode->t.sizes();
if (child0->tensor_proper_size() != 1
|| child1->tensor_proper_size() != 1) {
@@ -1057,7 +1070,7 @@ namespace getfem {
mi.push_back(child0->tensor_proper_size(i));
} else {
if (dim0+dim1 > 6)
- ga_throw_error(expr, pnode->pos, "Unauthorized "
+ ga_throw_error(pnode->expr, pnode->pos, "Unauthorized "
"tensor multiplication.");
for (size_type i = 0; i < dim0; ++i)
mi.push_back(child0->tensor_proper_size(i));
@@ -1090,7 +1103,7 @@ namespace getfem {
} else if (dim0 == 2 && dim1 == 1) {
size_type m=child0->tensor().size(0), n=child0->tensor().size(1);
if (n != child1->tensor().size(0))
- ga_throw_error(expr, pnode->pos,
+ ga_throw_error(pnode->expr, pnode->pos,
"Incompatible sizes in matrix-vector "
"multiplication (" << n << " != "
<< child1->tensor().size(0) << ").");
@@ -1104,7 +1117,7 @@ namespace getfem {
size_type n = child0->tensor().size(1);
size_type p = child1->tensor().size(1);
if (n != child1->tensor().size(0))
- ga_throw_error(expr, pnode->pos,
+ ga_throw_error(pnode->expr, pnode->pos,
"Incompatible sizes in matrix-matrix "
"multiplication (" << n << " != "
<< child1->tensor().size(0) << ").");
@@ -1120,7 +1133,7 @@ namespace getfem {
size_type m=child0->tensor().size(0), n=child0->tensor().size(1);
size_type o=child0->tensor().size(2), p=child0->tensor().size(3);
if (o != child1->tensor().size(0) || p != child1->tensor().size(1))
- ga_throw_error(expr, pnode->pos,
+ ga_throw_error(pnode->expr, pnode->pos,
"Incompatible sizes in tensor-matrix "
"multiplication (" << o << "," << p << " != "
<< child1->tensor().size(0) << ","
@@ -1133,11 +1146,11 @@ namespace getfem {
for (size_type l = 0; l < p; ++l)
pnode->tensor()(i,j) += child0->tensor()(i,j,k,l)
* child1->tensor()(k,l);
- } else ga_throw_error(expr, pnode->pos,
+ } else ga_throw_error(pnode->expr, pnode->pos,
"Unauthorized multiplication.");
tree.clear_children(pnode);
} else {
- pnode->mult_test(child0, child1, expr);
+ pnode->mult_test(child0, child1);
mi = pnode->t.sizes();
if (child0->tensor_proper_size() == 1 &&
@@ -1157,7 +1170,7 @@ namespace getfem {
size_type n = child0->tensor_proper_size(1);
mi.push_back(m);
if (n != child1->tensor_proper_size(0))
- ga_throw_error(expr, pnode->pos,
+ ga_throw_error(pnode->expr, pnode->pos,
"Incompatible sizes in matrix-vector "
"multiplication (" << n << " != "
<< child1->tensor_proper_size(0) << ").");
@@ -1168,7 +1181,7 @@ namespace getfem {
size_type p = child1->tensor_proper_size(1);
mi.push_back(m); mi.push_back(p);
if (n != child1->tensor_proper_size(0))
- ga_throw_error(expr, pnode->pos,
+ ga_throw_error(pnode->expr, pnode->pos,
"Incompatible sizes in matrix-matrix "
"multiplication (" << n << " != "
<< child1->tensor_proper_size(0) << ").");
@@ -1182,12 +1195,12 @@ namespace getfem {
mi.push_back(m); mi.push_back(n);
if (o != child1->tensor_proper_size(0) ||
p != child1->tensor_proper_size(1))
- ga_throw_error(expr, pnode->pos,
+ ga_throw_error(pnode->expr, pnode->pos,
"Incompatible sizes in tensor-matrix "
"multiplication (" << o << "," << p << " != "
<< child1->tensor_proper_size(0) << ","
<< child1->tensor_proper_size(1) << ").");
- } else ga_throw_error(expr, pnode->pos,
+ } else ga_throw_error(pnode->expr, pnode->pos,
"Unauthorized multiplication.");
pnode->t.adjust_sizes(mi);
// Simplifications
@@ -1211,15 +1224,16 @@ namespace getfem {
case GA_DIV:
if (child1->tensor_proper_size() > 1)
- ga_throw_error(expr, pnode->pos,
+ ga_throw_error(pnode->expr, pnode->pos,
"Only the division by a scalar is allowed. "
"Got a size of " << child1->tensor_proper_size());
if (child1->test_function_type)
- ga_throw_error(expr, pnode->pos,
+ ga_throw_error(pnode->expr, pnode->pos,
"Division by test functions is not allowed.");
if (child1->node_type == GA_NODE_CONSTANT &&
child1->tensor()[0] == scalar_type(0))
- ga_throw_error(expr, pnode->children[1]->pos, "Division by zero");
+ ga_throw_error(pnode->expr, pnode->children[1]->pos,
+ "Division by zero");
pnode->t = child0->t;
pnode->test_function_type = child0->test_function_type;
@@ -1256,7 +1270,8 @@ namespace getfem {
case GA_NODE_C_MATRIX:
{
if (!all_sc) {
- ga_throw_error(expr, pnode->pos, "Constant vector/matrix/tensor "
+ ga_throw_error(pnode->expr, pnode->pos,
+ "Constant vector/matrix/tensor "
"components should be scalar valued.");
}
@@ -1285,8 +1300,8 @@ namespace getfem {
(pnode->children[i]->interpolate_name_test1) ||
pnode->interpolate_name_test2.compare
(pnode->children[i]->interpolate_name_test2))
- ga_throw_error(expr, pnode->pos, "Inconsistent use of test "
- "function in constant matrix.");
+ ga_throw_error(pnode->expr, pnode->pos, "Inconsistent use of "
+ "test function in constant matrix.");
}
}
}
@@ -1389,7 +1404,7 @@ namespace getfem {
name = name.substr(s+1);
}
if (!valid || pnode->der1 == 0)
- ga_throw_error(expr, pnode->pos, "Invalid derivative format");
+ ga_throw_error(pnode->expr, pnode->pos,"Invalid derivative
format");
}
ga_predef_function_tab::const_iterator it=PREDEF_FUNCTIONS.find(name);
@@ -1401,7 +1416,7 @@ namespace getfem {
if (pnode->der1) {
if (pnode->der1 > it->second.nbargs()
|| pnode->der2 > it->second.nbargs())
- ga_throw_error(expr, pnode->pos, "Invalid derivative.");
+ ga_throw_error(pnode->expr, pnode->pos, "Invalid derivative.");
const ga_predef_function &F = it->second;
if ((F.ftype() == 0 || F.dtype() == 2) && !(pnode->der2)) {
pnode->name = ((pnode->der1 == 1) ?
@@ -1412,7 +1427,7 @@ namespace getfem {
} else if (SPEC_FUNCTIONS.find(name) != SPEC_FUNCTIONS.end()) {
// Special function found
if (pnode->der1)
- ga_throw_error(expr, pnode->pos, "Special functions do not "
+ ga_throw_error(pnode->expr, pnode->pos, "Special functions do not "
"support derivatives.");
pnode->node_type = GA_NODE_SPEC_FUNC;
pnode->name = name;
@@ -1441,12 +1456,13 @@ namespace getfem {
size_type test = ga_parse_prefix_test(name);
if (!(workspace.variable_exists(name)))
- ga_throw_error(expr, pnode->pos, "Unknown variable, function, "
- "operator or data " + name);
+ ga_throw_error(pnode->expr, pnode->pos, "Unknown variable, "
+ "function, operator or data " + name);
if (pnode->der1)
- ga_throw_error(expr, pnode->pos, "Derivative is for functions or "
- "operators, not for variables. Use Grad instead.");
+ ga_throw_error(pnode->expr, pnode->pos, "Derivative is for "
+ "functions or operators, not for variables. "
+ "Use Grad instead.");
pnode->name = name;
const mesh_fem *mf = workspace.associated_mf(name);
@@ -1454,8 +1470,8 @@ namespace getfem {
if (test && workspace.is_constant(name) &&
!(workspace.is_disabled_variable(name)))
- ga_throw_error(expr, pnode->pos, "Test functions of constants "
- "are not allowed.");
+ ga_throw_error(pnode->expr, pnode->pos, "Test functions of "
+ "constants are not allowed.");
if (test == 1) {
pnode->name_test1 = name;
pnode->interpolate_name_test1 = "";
@@ -1466,7 +1482,7 @@ namespace getfem {
pnode->qdim1 = mf ? workspace.qdim(name)
: gmm::vect_size(workspace.value(name));
if (!(pnode->qdim1))
- ga_throw_error(expr, pnode->pos,
+ ga_throw_error(pnode->expr, pnode->pos,
"Invalid null size of variable");
} else if (test == 2) {
pnode->name_test2 = name;
@@ -1478,14 +1494,14 @@ namespace getfem {
pnode->qdim2 = mf ? workspace.qdim(name)
: gmm::vect_size(workspace.value(name));
if (!(pnode->qdim2))
- ga_throw_error(expr, pnode->pos,
+ ga_throw_error(pnode->expr, pnode->pos,
"Invalid null size of variable");
}
if (!mf && (test || !imd)) {
if (prefix_id)
- ga_throw_error(expr, pnode->pos, "Gradient, Hessian or
Divergence"
- " cannot be evaluated for fixed size data.");
+ ga_throw_error(pnode->expr, pnode->pos, "Gradient, Hessian or "
+ "Divergence cannot be evaluated for fixed size data.");
if (test)
pnode->node_type = GA_NODE_VAL_TEST;
else if (eval_fixed_size)
@@ -1514,8 +1530,8 @@ namespace getfem {
}
} else if (!test && imd) {
if (prefix_id)
- ga_throw_error(expr, pnode->pos, "Gradient, Hessian or
Divergence"
- " cannot be evaluated for im data.");
+ ga_throw_error(pnode->expr, pnode->pos, "Gradient, Hessian or "
+ "Divergence cannot be evaluated for im data.");
pnode->node_type = GA_NODE_VAL;
pnode->t.adjust_sizes(workspace.qdims(name));
} else {
@@ -1523,10 +1539,10 @@ namespace getfem {
size_type n = mf->linked_mesh().dim();
bgeot::multi_index mii = workspace.qdims(name);
- if (!q) ga_throw_error(expr, pnode->pos,
+ if (!q) ga_throw_error(pnode->expr, pnode->pos,
"Invalid null size of variable " << name);
if (mii.size() > 6)
- ga_throw_error(expr, pnode->pos,
+ ga_throw_error(pnode->expr, pnode->pos,
"Tensor with too much dimensions. Limited to 6");
switch (prefix_id) {
@@ -1574,7 +1590,7 @@ namespace getfem {
case 3: // divergence
pnode->node_type = test ? GA_NODE_DIVERG_TEST : GA_NODE_DIVERG;
if (q != n)
- ga_throw_error(expr, pnode->pos,
+ ga_throw_error(pnode->expr, pnode->pos,
"Divergence operator can only be applied to"
"Fields with qdim (" << q << ") equal to dim ("
<< n << ")");
@@ -1593,15 +1609,16 @@ namespace getfem {
if (child0->node_type == GA_NODE_X) {
child0->init_scalar_tensor(0);
if (pnode->children.size() != 2)
- ga_throw_error(expr, child1->pos, "X stands for the coordinates on "
+ ga_throw_error(pnode->expr, child1->pos,
+ "X stands for the coordinates on "
"the real elements. It accepts only one index.");
if (!(child1->node_type == GA_NODE_CONSTANT) ||
child1->tensor().size() != 1)
- ga_throw_error(expr, child1->pos, "Index for X has to be constant "
- "and of size 1.");
+ ga_throw_error(pnode->expr, child1->pos,
+ "Index for X has to be constant and of size 1.");
child0->nbc1 = size_type(round(child1->tensor()[0]));
if (child0->nbc1 == 0 || child0->nbc1 > meshdim)
- ga_throw_error(expr, child1->pos, "Index for X not convenient. "
+ ga_throw_error(pnode->expr, child1->pos,"Index for X not convenient.
"
"Found " << child0->nbc1 << " with meshdim = "
<< meshdim);
tree.replace_node_by_child(pnode, 0);
@@ -1609,10 +1626,10 @@ namespace getfem {
} else if (child0->node_type == GA_NODE_RESHAPE) {
if (pnode->children.size() < 3)
- ga_throw_error(expr, child1->pos,
+ ga_throw_error(pnode->expr, child1->pos,
"Not enough parameters for Reshape");
if (pnode->children.size() > 8)
- ga_throw_error(expr, child1->pos,
+ ga_throw_error(pnode->expr, child1->pos,
"Too many parameters for Reshape");
pnode->t = child1->t;
pnode->test_function_type = child1->test_function_type;
@@ -1628,18 +1645,18 @@ namespace getfem {
for (size_type i = 2; i < pnode->children.size(); ++i) {
if (pnode->children[i]->node_type != GA_NODE_CONSTANT)
- ga_throw_error(expr, pnode->children[i]->pos, "Reshape sizes "
+ ga_throw_error(pnode->expr, pnode->children[i]->pos,"Reshape sizes
"
"should be constant positive integers.");
mi.push_back(size_type(round(pnode->children[i]->tensor()[0])));
if (mi.back() == 0)
- ga_throw_error(expr, pnode->children[i]->pos, "Wrong zero size "
- "for Reshape.");
+ ga_throw_error(pnode->expr, pnode->children[i]->pos,
+ "Wrong zero size for Reshape.");
}
size_type total_size(1);
for (size_type i = 0; i < mi.size(); ++i)
total_size *= mi[i];
if (total_size != pnode->tensor().size())
- ga_throw_error(expr, pnode->pos, "Invalid sizes for reshape.");
+ ga_throw_error(pnode->expr, pnode->pos,"Invalid sizes for
reshape.");
pnode->t.adjust_sizes(mi);
if (child1->node_type == GA_NODE_CONSTANT) {
@@ -1654,14 +1671,14 @@ namespace getfem {
// Evaluation of a predefined function
for (size_type i = 1; i < pnode->children.size(); ++i)
- ga_valid_operand(expr, pnode->children[i]);
+ ga_valid_operand(pnode->children[i]);
std::string name = child0->name;
ga_predef_function_tab::const_iterator it =
PREDEF_FUNCTIONS.find(name);
const ga_predef_function &F = it->second;
size_type nbargs = F.nbargs();
if (nbargs+1 != pnode->children.size()) {
- ga_throw_error(expr, pnode->pos, "Bad number of arguments for "
- "predefined function " << name << ". Found "
+ ga_throw_error(pnode->expr, pnode->pos, "Bad number of arguments "
+ "for predefined function " << name << ". Found "
<< pnode->children.size()-1 << ", should be "<<nbargs << ".");
}
pnode->test_function_type = 0;
@@ -1670,15 +1687,15 @@ namespace getfem {
if (nbargs == 2)
all_cte = all_cte && (child2->node_type == GA_NODE_CONSTANT);
if (child1->test_function_type || child2->test_function_type)
- ga_throw_error(expr, pnode->pos, "Test functions cannot be passed "
- "as argument of a predefined function.");
+ ga_throw_error(pnode->expr, pnode->pos, "Test functions cannot be "
+ "passed as argument of a predefined function.");
if (child1->tensor_order() > 2 || child2->tensor_order() > 2)
- ga_throw_error(expr, pnode->pos, "Sorry, function can be applied "
- "to scalar, vector and matrices only.");
+ ga_throw_error(pnode->expr, pnode->pos, "Sorry, function can be "
+ "applied to scalar, vector and matrices only.");
size_type s1 = child1->tensor().size();
size_type s2 = (nbargs == 2) ? child2->tensor().size() : s1;
if (s1 != s2 && (s1 != 1 || s2 != 1))
- ga_throw_error(expr, pnode->pos,
+ ga_throw_error(pnode->expr, pnode->pos,
"Invalid argument size for a scalar function. "
"Size of first argument: " << s1 <<
". Size of second argument: " << s2 << ".");
@@ -1724,32 +1741,32 @@ namespace getfem {
// Special constant functions: meshdim, qdim(u) ...
for (size_type i = 1; i < pnode->children.size(); ++i)
- ga_valid_operand(expr, pnode->children[i]);
+ ga_valid_operand(pnode->children[i]);
if (pnode->children.size() != 2)
- ga_throw_error(expr, pnode->pos,
+ ga_throw_error(pnode->expr, pnode->pos,
"One and only one argument is allowed for function "
+child0->name+".");
if (!(child0->name.compare("qdim"))) {
if (child1->node_type != GA_NODE_VAL)
- ga_throw_error(expr, pnode->pos, "The argument of qdim "
+ ga_throw_error(pnode->expr, pnode->pos, "The argument of qdim "
"function can only be a variable name.");
pnode->node_type = GA_NODE_CONSTANT;
pnode->init_scalar_tensor(scalar_type(workspace.qdim(child1->name)));
if (pnode->tensor()[0] <= 0)
- ga_throw_error(expr, pnode->pos,
+ ga_throw_error(pnode->expr, pnode->pos,
"Invalid null size of variable");
} else if (!(child0->name.compare("qdims"))) {
if (child1->node_type != GA_NODE_VAL)
- ga_throw_error(expr, pnode->pos, "The argument of qdim "
+ ga_throw_error(pnode->expr, pnode->pos, "The argument of qdim "
"function can only be a variable name.");
pnode->node_type = GA_NODE_CONSTANT;
bgeot::multi_index mii = workspace.qdims(child1->name);
if (mii.size() > 6)
- ga_throw_error(expr, pnode->pos,
+ ga_throw_error(pnode->expr, pnode->pos,
"Tensor with too much dimensions. Limited to 6");
if (mii.size() == 0 || scalar_type(mii[0]) <= 0)
- ga_throw_error(expr, pnode->pos,
+ ga_throw_error(pnode->expr, pnode->pos,
"Invalid null size of variable");
if (mii.size() == 1)
pnode->init_scalar_tensor(scalar_type(mii[0]));
@@ -1762,7 +1779,7 @@ namespace getfem {
bool valid = (child1->node_type == GA_NODE_CONSTANT);
int n = valid ? int(round(child1->tensor()[0])) : -1;
if (n <= 0 || n > 100 || child1->tensor_order() > 0)
- ga_throw_error(expr, pnode->pos, "The argument of Id "
+ ga_throw_error(pnode->expr, pnode->pos, "The argument of Id "
"should be a (small) positive integer.");
pnode->node_type = GA_NODE_CONSTANT;
if (n == 1)
@@ -1771,7 +1788,7 @@ namespace getfem {
pnode->init_matrix_tensor(n,n);
for (int i = 0; i < n; ++i) pnode->tensor()(i,i) = scalar_type(1);
}
- } else ga_throw_error(expr, pnode->children[0]->pos,
+ } else ga_throw_error(pnode->expr, pnode->children[0]->pos,
"Unknown special function.");
tree.clear_children(pnode);
} else if (child0->node_type == GA_NODE_OPERATOR) {
@@ -1779,7 +1796,7 @@ namespace getfem {
// Call to a nonlinear operator
for (size_type i = 1; i < pnode->children.size(); ++i)
- ga_valid_operand(expr, pnode->children[i]);
+ ga_valid_operand(pnode->children[i]);
all_cte = true;
ga_nonlinear_operator::arg_list args;
for (size_type i = 1; i < pnode->children.size(); ++i) {
@@ -1787,29 +1804,30 @@ namespace getfem {
&& (pnode->children[i]->node_type == GA_NODE_CONSTANT);
args.push_back(&(pnode->children[i]->tensor()));
if (pnode->children[i]->node_type == GA_NODE_ALLINDICES)
- ga_throw_error(expr, pnode->children[i]->pos,
+ ga_throw_error(pnode->expr, pnode->children[i]->pos,
"Colon operator is not allowed in nonlinear "
"operator call.");
if (pnode->children[i]->test_function_type)
- ga_throw_error(expr, pnode->pos, "Test functions cannot be passed "
- "as argument of a nonlinear operator.");
+ ga_throw_error(pnode->expr, pnode->pos, "Test functions cannot be "
+ "passed as argument of a nonlinear operator.");
if (pnode->children[i]->tensor_order() > 2)
- ga_throw_error(expr, pnode->pos, "Sorry, arguments to nonlinear "
- "operators should only be scalar, vector or matrices");
+ ga_throw_error(pnode->expr, pnode->pos,
+ "Sorry, arguments to nonlinear operators should "
+ "only be scalar, vector or matrices");
}
ga_predef_operator_tab::T::const_iterator it
= PREDEF_OPERATORS.tab.find(child0->name);
const ga_nonlinear_operator &OP = *(it->second);
mi.resize(0);
if (!(OP.result_size(args, mi)))
- ga_throw_error(expr, pnode->pos,
+ ga_throw_error(pnode->expr, pnode->pos,
"Wrong number or wrong size of arguments for the "
"call of nonlinear operator " + child0->name);
pnode->test_function_type = 0;
if (child0->der1 > args.size() || child0->der2 > args.size())
- ga_throw_error(expr, child0->pos,
+ ga_throw_error(pnode->expr, child0->pos,
"Invalid derivative number for nonlinear operator "
+ child0->name);
@@ -1850,12 +1868,12 @@ namespace getfem {
// cout << endl << "child0->t.sizes() = "
// << child0->t.sizes() << endl;
if (pnode->children.size() != child0->tensor_order() + 1)
- ga_throw_error(expr, pnode->pos, "Bad number of indices.");
+ ga_throw_error(pnode->expr, pnode->pos, "Bad number of indices.");
for (size_type i = 1; i < pnode->children.size(); ++i)
if (pnode->children[i]->node_type != GA_NODE_ALLINDICES &&
(pnode->children[i]->node_type != GA_NODE_CONSTANT ||
pnode->children[i]->tensor().size() != 1))
- ga_throw_error(expr, pnode->children[i]->pos,
+ ga_throw_error(pnode->expr, pnode->children[i]->pos,
"Indices should be constant integers or colon.");
bgeot::multi_index mi1(size0.size()), mi2, indices;
@@ -1867,7 +1885,7 @@ namespace getfem {
} else {
mi1[i] = size_type(round(pnode->children[i+1]->tensor()[0])-1);
if (mi1[i] >= child0->tensor_proper_size(i))
- ga_throw_error(expr, pnode->children[i+1]->pos,
+ ga_throw_error(pnode->expr, pnode->children[i+1]->pos,
"Index out of range, " << mi1[i]+1
<< ". Should be between 1 and "
<< child0->tensor_proper_size(i) << ".");
@@ -1921,19 +1939,19 @@ namespace getfem {
}
- void ga_semantic_analysis(const std::string &expr, ga_tree &tree,
- const ga_workspace &workspace,
- size_type meshdim,
- size_type ref_elt_dim,
- bool eval_fixed_size,
- bool ignore_X, int option) {
+ void ga_semantic_analysis(ga_tree &tree,
+ const ga_workspace &workspace,
+ size_type meshdim,
+ size_type ref_elt_dim,
+ bool eval_fixed_size,
+ bool ignore_X, int option) {
GMM_ASSERT1(predef_operators_nonlinear_elasticity_initialized &&
predef_operators_plasticity_initialized &&
predef_operators_contact_initialized, "Internal error");
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(expr, tree, workspace, tree.root, meshdim, ref_elt_dim,
+ ga_node_analysis(tree, workspace, tree.root, meshdim, ref_elt_dim,
eval_fixed_size, ignore_X, option);
if (tree.root && option == 2) {
if (((tree.root->test_function_type & 1) &&
@@ -1948,7 +1966,7 @@ namespace getfem {
tree.clear();
}
// cout << "semantic analysis done " << endl;
- ga_valid_operand(expr, tree.root);
+ ga_valid_operand(tree.root);
}
@@ -2037,7 +2055,8 @@ namespace getfem {
for (size_type i = 0; i < pnode->children.size(); ++i) {
if (pnode_child == pnode->children[i]) {
- pnode->children[i] = new ga_tree_node(GA_NODE_ZERO, pnode->pos);
+ pnode->children[i] = new ga_tree_node(GA_NODE_ZERO, pnode->pos,
+ pnode->expr);
pnode->children[i]->init_scalar_tensor(scalar_type(0));
pnode->children[i]->parent = pnode;
}
@@ -2325,20 +2344,20 @@ namespace getfem {
for (size_type k = 0; k < meshdim; ++k) {
if (j == i) {
pga_tree_node param_node = new_pnode->children[k*N+j]
- = new ga_tree_node(GA_NODE_PARAMS, pnode->pos);
+ = new ga_tree_node(GA_NODE_PARAMS, pnode->pos, pnode->expr);
new_pnode->children[k*N+j]->parent = new_pnode;
param_node->children.resize(2);
- param_node->children[0] = new ga_tree_node(GA_NODE_NORMAL,
- pnode->pos);
+ param_node->children[0]
+ = new ga_tree_node(GA_NODE_NORMAL, pnode->pos, pnode->expr);
param_node->children[0]->parent = param_node;
- param_node->children[1] = new ga_tree_node(GA_NODE_CONSTANT,
- pnode->pos);
+ param_node->children[1]
+ = new ga_tree_node(GA_NODE_CONSTANT, pnode->pos, pnode->expr);
param_node->children[1]->parent = param_node;
param_node->children[1]->init_scalar_tensor(scalar_type(k));
} else {
- new_pnode->children[k*N+j] = new ga_tree_node(GA_NODE_ZERO,
- pnode->pos);
+ new_pnode->children[k*N+j]
+ = new ga_tree_node(GA_NODE_ZERO, pnode->pos, pnode->expr);
new_pnode->children[k*N+j]->init_scalar_tensor(scalar_type(0));
new_pnode->children[k*N+j]->parent = new_pnode;
}
@@ -3083,7 +3102,7 @@ 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(expr, tree, workspace, 1, 1, false, true);
+ ga_semantic_analysis(tree, workspace, 1, 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 e5d23f0..db3a363 100644
--- a/src/getfem_generic_assembly_tree.cc
+++ b/src/getfem_generic_assembly_tree.cc
@@ -182,22 +182,22 @@ namespace getfem {
// Error handling
//=========================================================================
- void ga_throw_error_msg(const std::string &expr, size_type pos,
- const std::string &msg) {
+ void ga_throw_error_msg(pstring expr, size_type pos,
+ const std::string &msg) {
int length_before = 70, length_after = 70;
- if (expr.size()) {
+ if (expr && expr->size()) {
int first = std::max(0, int(pos)-length_before);
- int last = std::min(int(pos)+length_after, int(expr.size()));
+ int last = std::min(int(pos)+length_after, int(expr->size()));
if (last - first < length_before+length_after)
first = std::max(0, int(pos)-length_before
-(length_before+length_after-last+first));
if (last - first < length_before+length_after)
last = std::min(int(pos)+length_after
+(length_before+length_after-last+first),
- int(expr.size()));
+ int(expr->size()));
if (first > 0) cerr << "...";
- cerr << expr.substr(first, last-first);
- if (last < int(expr.size())) cerr << "...";
+ cerr << expr->substr(first, last-first);
+ if (last < int(expr->size())) cerr << "...";
cerr << endl;
if (first > 0) cerr << " ";
if (int(pos) > first)
@@ -212,8 +212,7 @@ namespace getfem {
// Tree structure
//=========================================================================
- void ga_tree_node::mult_test(const pga_tree_node n0, const pga_tree_node n1,
- const std::string &expr) {
+ void ga_tree_node::mult_test(const pga_tree_node n0, const pga_tree_node n1)
{
size_type test0 = n0->test_function_type, test1 = n1->test_function_type;
if (test0 && test1 && (test0 == test1 ||
@@ -257,44 +256,45 @@ namespace getfem {
t.adjust_sizes(mi);
}
- void ga_tree::add_scalar(scalar_type val, size_type pos) {
+ void ga_tree::add_scalar(scalar_type val, size_type pos, pstring expr) {
while (current_node && current_node->node_type != GA_NODE_OP)
current_node = current_node->parent;
if (current_node) {
- current_node->adopt_child(new ga_tree_node(val, pos));
+ current_node->adopt_child(new ga_tree_node(val, pos, expr));
current_node = current_node->children.back();
}
else {
GMM_ASSERT1(root == nullptr, "Invalid tree operation");
- current_node = root = new ga_tree_node(val, pos);
+ current_node = root = new ga_tree_node(val, pos, expr);
root->parent = nullptr;
}
}
- void ga_tree::add_allindices(size_type pos) {
+ void ga_tree::add_allindices(size_type pos, pstring expr) {
while (current_node && current_node->node_type != GA_NODE_OP)
current_node = current_node->parent;
if (current_node) {
- current_node->adopt_child(new ga_tree_node(GA_NODE_ALLINDICES, pos));
+ current_node->adopt_child(new ga_tree_node(GA_NODE_ALLINDICES,
pos,expr));
current_node = current_node->children.back();
}
else {
GMM_ASSERT1(root == nullptr, "Invalid tree operation");
- current_node = root = new ga_tree_node(GA_NODE_ALLINDICES, pos);
+ current_node = root = new ga_tree_node(GA_NODE_ALLINDICES, pos, expr);
root->parent = nullptr;
}
}
- void ga_tree::add_name(const char *name, size_type length, size_type pos) {
+ void ga_tree::add_name(const char *name, size_type length, size_type pos,
+ pstring expr) {
while (current_node && current_node->node_type != GA_NODE_OP)
current_node = current_node->parent;
if (current_node) {
- current_node->adopt_child(new ga_tree_node(name, length, pos));
+ current_node->adopt_child(new ga_tree_node(name, length, pos, expr));
current_node = current_node->children.back();
}
else {
GMM_ASSERT1(root == nullptr, "Invalid tree operation");
- current_node = root = new ga_tree_node(name, length, pos);
+ current_node = root = new ga_tree_node(name, length, pos, expr);
root->parent = nullptr;
}
}
@@ -323,13 +323,13 @@ namespace getfem {
sub_tree.root = sub_tree.current_node = nullptr;
}
- void ga_tree::add_params(size_type pos) {
+ void ga_tree::add_params(size_type pos, pstring expr) {
GMM_ASSERT1(current_node, "internal error");
while (current_node && current_node->parent &&
current_node->parent->node_type == GA_NODE_OP &&
ga_operator_priorities[current_node->parent->op_type] >= 4)
current_node = current_node->parent;
- pga_tree_node new_node = new ga_tree_node(GA_NODE_PARAMS, pos);
+ pga_tree_node new_node = new ga_tree_node(GA_NODE_PARAMS, pos, expr);
new_node->parent = current_node->parent;
if (current_node->parent)
current_node->parent->replace_child(current_node, new_node);
@@ -339,16 +339,16 @@ namespace getfem {
current_node = new_node;
}
- void ga_tree::add_matrix(size_type pos) {
+ void ga_tree::add_matrix(size_type pos, pstring expr) {
while (current_node && current_node->node_type != GA_NODE_OP)
current_node = current_node->parent;
if (current_node) {
- current_node->adopt_child(new ga_tree_node(GA_NODE_C_MATRIX, pos));
+ current_node->adopt_child(new ga_tree_node(GA_NODE_C_MATRIX, pos, expr));
current_node = current_node->children.back();
}
else {
GMM_ASSERT1(root == nullptr, "Invalid tree operation");
- current_node = root = new ga_tree_node(GA_NODE_C_MATRIX, pos);
+ current_node = root = new ga_tree_node(GA_NODE_C_MATRIX, pos, expr);
root->parent = nullptr;
}
current_node->nbc1 = current_node->nbc2 = current_node->nbc3 = 0;
@@ -376,13 +376,14 @@ namespace getfem {
current_node->children = new_children;
}
- void ga_tree::add_op(GA_TOKEN_TYPE op_type, size_type pos) {
+ void ga_tree::add_op(GA_TOKEN_TYPE op_type, size_type pos,
+ pstring expr) {
while (current_node && current_node->parent &&
current_node->parent->node_type == GA_NODE_OP &&
ga_operator_priorities[current_node->parent->op_type]
>= ga_operator_priorities[op_type])
current_node = current_node->parent;
- pga_tree_node new_node = new ga_tree_node(op_type, pos);
+ pga_tree_node new_node = new ga_tree_node(op_type, pos, expr);
if (current_node) {
if (op_type == GA_UNARY_MINUS
|| op_type == GA_SYM || op_type == GA_SKEW
@@ -463,7 +464,7 @@ namespace getfem {
void ga_tree::duplicate_with_operation(pga_tree_node pnode,
GA_TOKEN_TYPE op_type) {
- pga_tree_node newop = new ga_tree_node(op_type, pnode->pos);
+ pga_tree_node newop = new ga_tree_node(op_type, pnode->pos, pnode->expr);
newop->children.resize(2, nullptr);
newop->children[0] = pnode;
newop->parent = pnode->parent;
@@ -1100,7 +1101,6 @@ namespace getfem {
return str.str();
}
-
size_type ga_parse_prefix_operator(std::string &name) {
if (name.size() >= 5 && name.compare(0, 5, "Grad_") == 0)
{ name = name.substr(5); return 1; }
@@ -1200,12 +1200,12 @@ namespace getfem {
return *this;
}
- void ga_replace_macro_params(const std::string expr, ga_tree &tree,
- pga_tree_node pnode,
- const std::vector<pga_tree_node> &children) {
+ static void ga_replace_macro_params
+ (ga_tree &tree, pga_tree_node pnode,
+ const std::vector<pga_tree_node> &children) {
if (!pnode) return;
for (size_type i = 0; i < pnode->children.size(); ++i)
- ga_replace_macro_params(expr, tree, pnode->children[i], children);
+ ga_replace_macro_params(tree, pnode->children[i], children);
if (pnode->node_type == GA_NODE_MACRO_PARAM) {
size_type po = pnode->nbc2;
@@ -1215,10 +1215,18 @@ namespace getfem {
if (po || pt) {
if (!(pchild->children.empty()) || pchild->node_type != GA_NODE_NAME)
- ga_throw_error(expr, pchild->pos, "Error in macro expansion. "
- "Only variable name are allowed for macro parameter "
- "preceded by Grad_ Hess_ Test_ or Test2_ prefixes.");
- pnode->node_type = GA_NODE_NAME;
+ ga_throw_error(pchild->expr, pchild->pos, "Error in macro "
+ "expansion. Only variable name are allowed for macro "
+ "parameter preceded by Grad_ Hess_ Test_ or Test2_ "
+ "prefixes.");
+ switch(pnode->op_type) {
+ case GA_NAME : pnode->node_type = GA_NODE_NAME; break;
+ case GA_INTERPOLATE : pnode->node_type = GA_NODE_INTERPOLATE; break;
+ case GA_ELEMENTARY : pnode->node_type = GA_NODE_ELEMENTARY; break;
+ case GA_XFEM_PLUS : pnode->node_type = GA_NODE_XFEM_PLUS; break;
+ case GA_XFEM_MINUS: pnode->node_type = GA_NODE_XFEM_MINUS; break;
+ default:break;
+ }
pnode->name = pchild->name;
if (pt == 1) pnode->name = "Test_" + pnode->name;
if (pt == 2) pnode->name = "Test2_" + pnode->name;
@@ -1239,21 +1247,20 @@ namespace getfem {
}
}
- void ga_expand_macro(ga_tree &tree, pga_tree_node pnode,
- const ga_macro_dictionnary ¯o_dict,
- const std::string &expr) {
+ static void ga_expand_macro(ga_tree &tree, pga_tree_node pnode,
+ const ga_macro_dictionnary ¯o_dict) {
if (!pnode) return;
if (pnode->node_type == GA_NODE_PARAMS) {
for (size_type i = 1; i < pnode->children.size(); ++i)
- ga_expand_macro(tree, pnode->children[i], macro_dict, expr);
+ ga_expand_macro(tree, pnode->children[i], macro_dict);
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,
+ ga_throw_error(pnode->expr, pnode->pos,
"Bad number of parameters in the use of macro '"
<< gam.name() << "'. Expected " << gam.nb_params()
<< " found " << pnode->children.size()-1 << ".");
@@ -1265,7 +1272,7 @@ namespace getfem {
pnode_old->parent->replace_child(pnode_old, pnode);
else
tree.root = pnode;
- ga_replace_macro_params(expr, tree, pnode, pnode_old->children);
+ ga_replace_macro_params(tree, pnode, pnode_old->children);
}
} else if (pnode->node_type == GA_NODE_NAME &&
@@ -1273,7 +1280,7 @@ namespace getfem {
// Macro without parameters
const ga_macro &gam = macro_dict.get_macro(pnode->name);
if (gam.nb_params() != 0)
- ga_throw_error(expr, pnode->pos,
+ ga_throw_error(pnode->expr, pnode->pos,
"Bad number of parameters in the use of macro '"
<< gam.name() << "'. Expected " << gam.nb_params()
<< " none found.");
@@ -1289,7 +1296,7 @@ namespace getfem {
delete pnode_old;
} else {
for (size_type i = 0; i < pnode->children.size(); ++i)
- ga_expand_macro(tree, pnode->children[i], macro_dict, expr);
+ ga_expand_macro(tree, pnode->children[i], macro_dict);
}
}
@@ -1299,12 +1306,24 @@ namespace getfem {
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) {
+ if (pnode->node_type == GA_NODE_NAME ||
+ pnode->node_type == GA_NODE_INTERPOLATE ||
+ pnode->node_type == GA_NODE_ELEMENTARY ||
+ pnode->node_type == GA_NODE_XFEM_PLUS ||
+ pnode->node_type == GA_NODE_XFEM_MINUS) {
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) {
+ switch(pnode->node_type) {
+ case GA_NODE_NAME : pnode->op_type = GA_NAME; break;
+ case GA_NODE_INTERPOLATE : pnode->op_type = GA_INTERPOLATE; break;
+ case GA_NODE_ELEMENTARY : pnode->op_type = GA_ELEMENTARY; break;
+ case GA_NODE_XFEM_PLUS : pnode->op_type = GA_XFEM_PLUS; break;
+ case GA_NODE_XFEM_MINUS: pnode->op_type = GA_XFEM_MINUS; break;
+ default:break;
+ }
pnode->node_type = GA_NODE_MACRO_PARAM;
pnode->nbc1 = i; pnode->nbc2 = po; pnode->nbc3 = pt;
}
@@ -1313,11 +1332,10 @@ namespace getfem {
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) {
+ const ga_macro_dictionnary ¯o_dict) {
if (gam.tree().root) {
ga_mark_macro_params_rec(gam.tree().root, params);
- ga_expand_macro(gam.tree(), gam.tree().root, macro_dict, expr);
+ ga_expand_macro(gam.tree(), gam.tree().root, macro_dict);
}
}
@@ -1355,7 +1373,7 @@ namespace getfem {
//=========================================================================
// Read a term with an (implicit) pushdown automaton.
- static GA_TOKEN_TYPE ga_read_term(const std::string &expr, size_type &pos,
+ static GA_TOKEN_TYPE ga_read_term(pstring expr, size_type &pos,
ga_tree &tree,
ga_macro_dictionnary ¯o_dict) {
size_type token_pos, token_length;
@@ -1364,7 +1382,7 @@ namespace getfem {
for (;;) {
- t_type = ga_get_token(expr, pos, token_pos, token_length);
+ t_type = ga_get_token(*expr, pos, token_pos, token_length);
switch (state) {
@@ -1372,82 +1390,83 @@ namespace getfem {
switch (t_type) {
case GA_SCALAR:
{
- char *endptr; const char *nptr = &(expr[token_pos]);
+ char *endptr; const char *nptr = &((*expr)[token_pos]);
scalar_type s_read = ::strtod(nptr, &endptr);
if (endptr == nptr)
ga_throw_error(expr, token_pos, "Bad numeric format.");
- tree.add_scalar(s_read, token_pos);
+ tree.add_scalar(s_read, token_pos, expr);
}
state = 2; break;
case GA_COLON:
- tree.add_allindices(token_pos);
+ tree.add_allindices(token_pos, expr);
state = 2; break;
case GA_NAME:
- tree.add_name(&(expr[token_pos]), token_length, token_pos);
+ tree.add_name(&((*expr)[token_pos]), token_length, token_pos, expr);
state = 2; break;
case GA_MINUS: // unary -
- tree.add_op(GA_UNARY_MINUS, token_pos);
+ tree.add_op(GA_UNARY_MINUS, token_pos, expr);
case GA_PLUS: // unary +
state = 1; break;
case GA_SYM:
- tree.add_op(GA_SYM, token_pos);
+ tree.add_op(GA_SYM, token_pos, expr);
state = 1; break;
case GA_SKEW:
- tree.add_op(GA_SKEW, token_pos);
+ tree.add_op(GA_SKEW, token_pos, expr);
state = 1; break;
case GA_TRACE:
- tree.add_op(GA_TRACE, token_pos);
+ tree.add_op(GA_TRACE, token_pos, expr);
state = 1; break;
case GA_DEVIATOR:
- tree.add_op(GA_DEVIATOR, token_pos);
+ tree.add_op(GA_DEVIATOR, token_pos, expr);
state = 1; break;
case GA_DEF:
{
ga_macro gam;
- t_type = ga_get_token(expr, pos, token_pos, token_length);
+ 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);
+ 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);
+ 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);
+ 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));
+ 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);
+ 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);
+ 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);
+ 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);
if (gam.tree().root)
- ga_expand_macro(gam.tree(), gam.tree().root, macro_dict, expr);
+ ga_expand_macro(gam.tree(), gam.tree().root, macro_dict);
+ gam.nb_params() = params.size();
+ ga_mark_macro_params(gam, params, macro_dict);
macro_dict.add_macro(gam);
// cout << "macro \"" << gam.name() << "\" registered with "
@@ -1464,31 +1483,31 @@ namespace getfem {
case GA_INTERPOLATE:
{
- tree.add_scalar(scalar_type(0), token_pos);
+ tree.add_scalar(scalar_type(0), token_pos, expr);
tree.current_node->node_type = GA_NODE_INTERPOLATE;
- t_type = ga_get_token(expr, pos, token_pos, token_length);
+ t_type = ga_get_token(*expr, pos, token_pos, token_length);
if (t_type != GA_LPAR)
ga_throw_error(expr, pos-1, "Missing interpolate arguments.");
- t_type = ga_get_token(expr, pos, token_pos, token_length);
+ t_type = ga_get_token(*expr, pos, token_pos, token_length);
if (t_type != GA_NAME)
ga_throw_error(expr, pos,
"First argument of Interpolate should be a "
"variable, test function, X or Normal.");
- tree.current_node->name = std::string(&(expr[token_pos]),
+ tree.current_node->name = std::string(&((*expr)[token_pos]),
token_length);
- t_type = ga_get_token(expr, pos, token_pos, token_length);
+ t_type = ga_get_token(*expr, pos, token_pos, token_length);
if (t_type != GA_COMMA)
ga_throw_error(expr, pos, "Bad format for Interpolate "
"arguments.");
- t_type = ga_get_token(expr, pos, token_pos, token_length);
+ t_type = ga_get_token(*expr, pos, token_pos, token_length);
if (t_type != GA_NAME)
ga_throw_error(expr, pos,
"Second argument of Interpolate should be a "
"transformation name.");
tree.current_node->interpolate_name
- = std::string(&(expr[token_pos]), token_length);
- t_type = ga_get_token(expr, pos, token_pos, token_length);
+ = std::string(&((*expr)[token_pos]), token_length);
+ t_type = ga_get_token(*expr, pos, token_pos, token_length);
if (t_type != GA_RPAR)
ga_throw_error(expr, pos-1, "Missing a parenthesis after "
"interpolate arguments.");
@@ -1498,32 +1517,32 @@ namespace getfem {
case GA_ELEMENTARY:
{
- tree.add_scalar(scalar_type(0), token_pos);
+ tree.add_scalar(scalar_type(0), token_pos, expr);
tree.current_node->node_type = GA_NODE_ELEMENTARY;
- t_type = ga_get_token(expr, pos, token_pos, token_length);
+ t_type = ga_get_token(*expr, pos, token_pos, token_length);
if (t_type != GA_LPAR)
ga_throw_error(expr, pos-1,
"Missing Elementary_transformation arguments.");
- t_type = ga_get_token(expr, pos, token_pos, token_length);
+ t_type = ga_get_token(*expr, pos, token_pos, token_length);
if (t_type != GA_NAME)
ga_throw_error(expr, pos,
"First argument of Elementary_transformation "
"should be a variable or a test function.");
- tree.current_node->name = std::string(&(expr[token_pos]),
+ tree.current_node->name = std::string(&((*expr)[token_pos]),
token_length);
- t_type = ga_get_token(expr, pos, token_pos, token_length);
+ t_type = ga_get_token(*expr, pos, token_pos, token_length);
if (t_type != GA_COMMA)
ga_throw_error(expr, pos, "Bad format for "
"Elementary_transformation arguments.");
- t_type = ga_get_token(expr, pos, token_pos, token_length);
+ t_type = ga_get_token(*expr, pos, token_pos, token_length);
if (t_type != GA_NAME)
ga_throw_error(expr, pos,
"Second argument of Elementary_transformation "
"should be a transformation name.");
tree.current_node->elementary_name
- = std::string(&(expr[token_pos]), token_length);
- t_type = ga_get_token(expr, pos, token_pos, token_length);
+ = std::string(&((*expr)[token_pos]), token_length);
+ t_type = ga_get_token(*expr, pos, token_pos, token_length);
if (t_type != GA_RPAR)
ga_throw_error(expr, pos-1, "Missing a parenthesis after "
"Elementary_transformation arguments.");
@@ -1533,20 +1552,20 @@ namespace getfem {
case GA_XFEM_PLUS:
{
- tree.add_scalar(scalar_type(0), token_pos);
+ tree.add_scalar(scalar_type(0), token_pos, expr);
tree.current_node->node_type = GA_NODE_XFEM_PLUS;
- t_type = ga_get_token(expr, pos, token_pos, token_length);
+ t_type = ga_get_token(*expr, pos, token_pos, token_length);
if (t_type != GA_LPAR)
ga_throw_error(expr, pos-1,
"Missing Xfem_plus arguments.");
- t_type = ga_get_token(expr, pos, token_pos, token_length);
+ t_type = ga_get_token(*expr, pos, token_pos, token_length);
if (t_type != GA_NAME)
ga_throw_error(expr, pos,
"The argument of Xfem_plus should be a "
"variable or a test function.");
- tree.current_node->name = std::string(&(expr[token_pos]),
+ tree.current_node->name = std::string(&((*expr)[token_pos]),
token_length);
- t_type = ga_get_token(expr, pos, token_pos, token_length);
+ t_type = ga_get_token(*expr, pos, token_pos, token_length);
if (t_type != GA_RPAR)
ga_throw_error(expr, pos-1, "Missing a parenthesis after "
"Xfem_plus argument.");
@@ -1556,20 +1575,20 @@ namespace getfem {
case GA_XFEM_MINUS:
{
- tree.add_scalar(scalar_type(0), token_pos);
+ tree.add_scalar(scalar_type(0), token_pos, expr);
tree.current_node->node_type = GA_NODE_XFEM_MINUS;
- t_type = ga_get_token(expr, pos, token_pos, token_length);
+ t_type = ga_get_token(*expr, pos, token_pos, token_length);
if (t_type != GA_LPAR)
ga_throw_error(expr, pos-1,
"Missing Xfem_minus arguments.");
- t_type = ga_get_token(expr, pos, token_pos, token_length);
+ t_type = ga_get_token(*expr, pos, token_pos, token_length);
if (t_type != GA_NAME)
ga_throw_error(expr, pos,
"The argument of Xfem_minus should be a "
"variable or a test function.");
- tree.current_node->name = std::string(&(expr[token_pos]),
+ tree.current_node->name = std::string(&((*expr)[token_pos]),
token_length);
- t_type = ga_get_token(expr, pos, token_pos, token_length);
+ t_type = ga_get_token(*expr, pos, token_pos, token_length);
if (t_type != GA_RPAR)
ga_throw_error(expr, pos-1, "Missing a parenthesis after "
"Xfem_minus argument.");
@@ -1579,21 +1598,21 @@ namespace getfem {
case GA_INTERPOLATE_FILTER:
{
- tree.add_scalar(scalar_type(0), token_pos);
+ tree.add_scalar(scalar_type(0), token_pos, expr);
tree.current_node->node_type = GA_NODE_INTERPOLATE_FILTER;
tree.current_node->nbc1 = size_type(-1);
- t_type = ga_get_token(expr, pos, token_pos, token_length);
+ t_type = ga_get_token(*expr, pos, token_pos, token_length);
if (t_type != GA_LPAR)
ga_throw_error(expr, pos-1, "Missing interpolate arguments.");
- t_type = ga_get_token(expr, pos, token_pos, token_length);
+ t_type = ga_get_token(*expr, pos, token_pos, token_length);
if (t_type != GA_NAME)
ga_throw_error(expr, pos, "First argument of Interpolate_filter "
"should be a transformation name.");
tree.current_node->interpolate_name
- = std::string(&(expr[token_pos]), token_length);
- t_type = ga_get_token(expr, pos, token_pos, token_length);
+ = std::string(&((*expr)[token_pos]), token_length);
+ t_type = ga_get_token(*expr, pos, token_pos, token_length);
if (t_type != GA_COMMA)
- ga_throw_error(expr,pos,
+ ga_throw_error(expr, pos,
"Bad format for Interpolate_filter arguments.");
ga_tree sub_tree;
t_type = ga_read_term(expr, pos, sub_tree, macro_dict);
@@ -1613,7 +1632,7 @@ namespace getfem {
break;
case GA_PRINT:
- tree.add_op(GA_PRINT, token_pos);
+ tree.add_op(GA_PRINT, token_pos, expr);
state = 1; break;
case GA_LPAR: // Parenthesed expression
@@ -1636,7 +1655,7 @@ namespace getfem {
size_type tensor_order(1);
bool foundcomma(false), foundsemi(false), nested_format(false);
- tree.add_matrix(token_pos);
+ tree.add_matrix(token_pos, expr);
do {
r_type = ga_read_term(expr, pos, sub_tree, macro_dict);
@@ -1769,10 +1788,10 @@ namespace getfem {
case GA_PLUS: case GA_MINUS: case GA_MULT: case GA_DIV:
case GA_COLON: case GA_DOT: case GA_DOTMULT: case GA_DOTDIV:
case GA_TMULT:
- tree.add_op(t_type, token_pos);
+ tree.add_op(t_type, token_pos, expr);
state = 1; break;
case GA_QUOTE:
- tree.add_op(t_type, token_pos);
+ tree.add_op(t_type, token_pos, expr);
state = 2; break;
case GA_END: case GA_RPAR: case GA_COMMA: case GA_DCOMMA:
case GA_RBRACKET: case GA_SEMICOLON: case GA_DSEMICOLON:
@@ -1781,7 +1800,7 @@ namespace getfem {
{
ga_tree sub_tree;
GA_TOKEN_TYPE r_type;
- tree.add_params(token_pos);
+ tree.add_params(token_pos, expr);
do {
r_type = ga_read_term(expr, pos, sub_tree, macro_dict);
if (r_type != GA_RPAR && r_type != GA_COMMA)
@@ -1812,15 +1831,19 @@ namespace getfem {
GA_TOKEN_TYPE t = ga_get_token(expr, pos, token_pos, token_length);
if (t == GA_END) return;
pos = 0;
+ pstring nexpr(new std::string(expr));
- t = ga_read_term(expr, pos, tree, macro_dict);
- if (tree.root) ga_expand_macro(tree, tree.root, macro_dict, 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(expr, pos-1, "Unbalanced parenthesis.");
- case GA_RBRACKET: ga_throw_error(expr, pos-1, "Unbalanced braket.");
+ case GA_RPAR: ga_throw_error(nexpr, pos-1, "Unbalanced parenthesis.");
+ case GA_RBRACKET: ga_throw_error(nexpr, pos-1, "Unbalanced braket.");
case GA_END: break;
- default: ga_throw_error(expr, pos-1, "Unexpected token.");
+ default: ga_throw_error(nexpr, pos-1, "Unexpected token.");
}
}
@@ -1831,9 +1854,9 @@ namespace getfem {
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
+ // Should be replaced by macros now.
std::string ga_substitute(const std::string &expr,
const std::map<std::string, std::string> &dict) {
if (dict.size()) {
diff --git a/src/getfem_generic_assembly_workspace.cc
b/src/getfem_generic_assembly_workspace.cc
index 018730b..15da368 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.dim(),
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(expr, dtree, *this, m.dim(),
+ ga_semantic_analysis(dtree, *this, m.dim(),
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(expr, ltrees[0], *this, mim.linked_mesh().dim(),
+ ga_semantic_analysis(ltrees[0], *this, mim.linked_mesh().dim(),
ref_elt_dim_of_mesh(mim.linked_mesh()),
false, false, 1);
// cout << "analysed : " << ga_tree_to_string(ltrees[0]) << endl;
@@ -499,7 +499,7 @@ namespace getfem {
selected_test1 = *it1;
if (test2.size()) selected_test2 = *it2++;
// cout << "analysis with " << selected_test1.first << endl;
- ga_semantic_analysis(expr, ltrees[i*ntest2+j], *this,
+ ga_semantic_analysis(ltrees[i*ntest2+j], *this,
mim.linked_mesh().dim(),
ref_elt_dim_of_mesh(mim.linked_mesh()),
false, false, 2);
@@ -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(expr, tree, *this, 1, 1, false, true);
+ ga_semantic_analysis(tree, *this, 1, 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(expr, tree, *this, m.dim(), ref_elt_dim_of_mesh(m),
+ ga_semantic_analysis(tree, *this, m.dim(), 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(expr, tree, *this, m.dim(), ref_elt_dim_of_mesh(m),
+ ga_semantic_analysis(tree, *this, m.dim(), ref_elt_dim_of_mesh(m),
false, false);
if (tree.root) {
GMM_ASSERT1(tree.root->nb_test_functions() == 0,
@@ -574,7 +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(expr, tree, *this, m.dim(), ref_elt_dim_of_mesh(m),
+ ga_semantic_analysis(tree, *this, m.dim(), ref_elt_dim_of_mesh(m),
false, false);
if (tree.root) {
GMM_ASSERT1(tree.root->nb_test_functions() == 0,
@@ -892,7 +892,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.dim(),
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)+")";
diff --git a/src/getfem_models.cc b/src/getfem_models.cc
index fd7839b..7e16876 100644
--- a/src/getfem_models.cc
+++ b/src/getfem_models.cc
@@ -984,8 +984,10 @@ namespace getfem {
return variables.count(no_old_prefix_name(name)) > 0;
}
- void model::add_macro(const std::string &name, const std::string &expr)
- { check_name_validity(name); macro_dict.add_macro(name, expr); }
+ void model::add_macro(const std::string &name, const std::string &expr) {
+ check_name_validity(name.substr(0, name.find("(")));
+ macro_dict.add_macro(name, expr);
+ }
void model::del_macro(const std::string &name)
{ macro_dict.del_macro(name); }