[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Getfem-commits] [getfem-commits] branch master updated: Replace some sw
From: |
Konstantinos Poulios |
Subject: |
[Getfem-commits] [getfem-commits] branch master updated: Replace some switches with lookup tables to reduce code duplication |
Date: |
Tue, 17 Oct 2023 08:27:19 -0400 |
This is an automated email from the git hooks/post-receive script.
logari81 pushed a commit to branch master
in repository getfem.
The following commit(s) were added to refs/heads/master by this push:
new 9a57bfb9 Replace some switches with lookup tables to reduce code
duplication
9a57bfb9 is described below
commit 9a57bfb909e03f74c766301f1ed2bc4eb6a8e517
Author: Konstantinos Poulios <logari81@gmail.com>
AuthorDate: Tue Oct 17 14:27:09 2023 +0200
Replace some switches with lookup tables to reduce code duplication
- hopefully no performance penalty
---
src/getfem_generic_assembly_semantic.cc | 306 +++++++++++++-------------------
1 file changed, 120 insertions(+), 186 deletions(-)
diff --git a/src/getfem_generic_assembly_semantic.cc
b/src/getfem_generic_assembly_semantic.cc
index 58289d3c..9718838f 100644
--- a/src/getfem_generic_assembly_semantic.cc
+++ b/src/getfem_generic_assembly_semantic.cc
@@ -609,14 +609,14 @@ namespace getfem {
+ ((pnode->node_type == GA_NODE_SECONDARY_DOMAIN) ? 3 : 0)
+ ((pnode->node_type == GA_NODE_XFEM_PLUS) ? 4 : 0)
+ ((pnode->node_type == GA_NODE_XFEM_MINUS) ? 5 : 0);
- std::string op__name =
- (pnode->node_type == GA_NODE_INTERPOLATE) ? "Interpolation" : ""
- + (pnode->node_type == GA_NODE_ELEMENTARY) ?
- "Elementary_transformation" : ""
- + (pnode->node_type == GA_NODE_SECONDARY_DOMAIN) ?
- "Secondary_domain" : ""
- + (pnode->node_type == GA_NODE_XFEM_PLUS) ? "Xfem_plus" : ""
- + (pnode->node_type == GA_NODE_XFEM_MINUS) ? "Xfem_minus" : "";
+ GMM_ASSERT1(ndt > 0 && ndt < 6, "internal error");
+ constexpr std::array<const char*,5>
+ op_name_selector{"Interpolation",
+ "Elementary_transformation",
+ "Secondary_domain",
+ "Xfem_plus",
+ "Xfem_minus"};
+ std::string op__name = op_name_selector.at(ndt-1);
std::string name = pnode->name;
size_type prefix_id = ga_parse_prefix_operator(name);
@@ -674,26 +674,53 @@ namespace getfem {
"Invalid null size of variable");
}
+ constexpr std::array<GA_NODE_TYPE,5>
+ node_type_selector_val{GA_NODE_INTERPOLATE_VAL,
+ GA_NODE_ELEMENTARY_VAL,
+ GA_NODE_SECONDARY_DOMAIN_VAL,
+ GA_NODE_XFEM_PLUS_VAL,
+ GA_NODE_XFEM_MINUS_VAL},
+ node_type_selector_val_test{GA_NODE_INTERPOLATE_VAL_TEST,
+ GA_NODE_ELEMENTARY_VAL_TEST,
+ GA_NODE_SECONDARY_DOMAIN_VAL_TEST,
+ GA_NODE_XFEM_PLUS_VAL_TEST,
+ GA_NODE_XFEM_MINUS_VAL_TEST},
+ node_type_selector_grad{GA_NODE_INTERPOLATE_GRAD,
+ GA_NODE_ELEMENTARY_GRAD,
+ GA_NODE_SECONDARY_DOMAIN_GRAD,
+ GA_NODE_XFEM_PLUS_GRAD,
+ GA_NODE_XFEM_MINUS_GRAD},
+ node_type_selector_grad_test{GA_NODE_INTERPOLATE_GRAD_TEST,
+ GA_NODE_ELEMENTARY_GRAD_TEST,
+ GA_NODE_SECONDARY_DOMAIN_GRAD_TEST,
+ GA_NODE_XFEM_PLUS_GRAD_TEST,
+ GA_NODE_XFEM_MINUS_GRAD_TEST},
+ node_type_selector_hess{GA_NODE_INTERPOLATE_HESS,
+ GA_NODE_ELEMENTARY_HESS,
+ GA_NODE_SECONDARY_DOMAIN_HESS,
+ GA_NODE_XFEM_PLUS_HESS,
+ GA_NODE_XFEM_MINUS_HESS},
+ node_type_selector_hess_test{GA_NODE_INTERPOLATE_HESS_TEST,
+ GA_NODE_ELEMENTARY_HESS_TEST,
+ GA_NODE_SECONDARY_DOMAIN_HESS_TEST,
+ GA_NODE_XFEM_PLUS_HESS_TEST,
+ GA_NODE_XFEM_MINUS_HESS_TEST},
+ node_type_selector_div{GA_NODE_INTERPOLATE_DIVERG,
+ GA_NODE_ELEMENTARY_DIVERG,
+ GA_NODE_SECONDARY_DOMAIN_DIVERG,
+ GA_NODE_XFEM_PLUS_DIVERG,
+ GA_NODE_XFEM_MINUS_DIVERG},
+ node_type_selector_div_test{GA_NODE_INTERPOLATE_DIVERG_TEST,
+ GA_NODE_ELEMENTARY_DIVERG_TEST,
+ GA_NODE_SECONDARY_DOMAIN_DIVERG_TEST,
+ GA_NODE_XFEM_PLUS_DIVERG_TEST,
+ GA_NODE_XFEM_MINUS_DIVERG_TEST};
+
switch (prefix_id) {
case 0: // value
- if (!test) {
- switch (ndt) {
- case 1: pnode->node_type = GA_NODE_INTERPOLATE_VAL; break;
- case 2: pnode->node_type = GA_NODE_ELEMENTARY_VAL; break;
- case 3: pnode->node_type = GA_NODE_SECONDARY_DOMAIN_VAL; break;
- case 4: pnode->node_type = GA_NODE_XFEM_PLUS_VAL; break;
- case 5: pnode->node_type = GA_NODE_XFEM_MINUS_VAL; break;
- default: GMM_ASSERT1(false, "internal error");
- }
- } else {
- switch (ndt) {
- case 1: pnode->node_type = GA_NODE_INTERPOLATE_VAL_TEST; break;
- case 2: pnode->node_type = GA_NODE_ELEMENTARY_VAL_TEST; break;
- case 3: pnode->node_type = GA_NODE_SECONDARY_DOMAIN_VAL_TEST;
break;
- case 4: pnode->node_type = GA_NODE_XFEM_PLUS_VAL_TEST; break;
- case 5: pnode->node_type = GA_NODE_XFEM_MINUS_VAL_TEST; break;
- default: GMM_ASSERT1(false, "internal error");
- }
+ pnode->node_type = test ? node_type_selector_val_test[ndt-1]
+ : node_type_selector_val[ndt-1];
+ if (test) {
if (q == 1 && mii.size() <= 1) {
mii.resize(1);
mii[0] = 2;
@@ -702,65 +729,41 @@ namespace getfem {
}
break;
case 1: // grad
- if (!test) {
- switch (ndt) {
- case 1: pnode->node_type = GA_NODE_INTERPOLATE_GRAD; break;
- case 2: pnode->node_type = GA_NODE_ELEMENTARY_GRAD; break;
- case 3: pnode->node_type = GA_NODE_SECONDARY_DOMAIN_GRAD; break;
- case 4: pnode->node_type = GA_NODE_XFEM_PLUS_GRAD; break;
- case 5: pnode->node_type = GA_NODE_XFEM_MINUS_GRAD; break;
- default: GMM_ASSERT1(false, "internal error");
- }
- if (n > 1) {
- if (q == 1 && mii.size() == 1) mii[0] = n;
- else mii.push_back(n);
- }
- } else {
- switch (ndt) {
- case 1: pnode->node_type = GA_NODE_INTERPOLATE_GRAD_TEST; break;
- case 2: pnode->node_type = GA_NODE_ELEMENTARY_GRAD_TEST; break;
- case 3: pnode->node_type =
GA_NODE_SECONDARY_DOMAIN_GRAD_TEST;break;
- case 4: pnode->node_type = GA_NODE_XFEM_PLUS_GRAD_TEST; break;
- case 5: pnode->node_type = GA_NODE_XFEM_MINUS_GRAD_TEST; break;
- default: GMM_ASSERT1(false, "internal error");
- }
+ pnode->node_type = test ? node_type_selector_grad_test[ndt-1]
+ : node_type_selector_grad[ndt-1];
+ if (test) {
if (q == 1 && mii.size() <= 1) {
mii.resize(1);
mii[0] = 2;
} else
mii.insert(mii.begin(), 2);
if (n > 1) mii.push_back(n);
+ } else if (n > 1) {
+ if (q == 1 && mii.size() == 1)
+ mii[0] = n;
+ else
+ mii.push_back(n);
}
break;
case 2: // Hessian
- if (!test) {
- switch (ndt) {
- case 1: pnode->node_type = GA_NODE_INTERPOLATE_HESS; break;
- case 2: pnode->node_type = GA_NODE_ELEMENTARY_HESS; break;
- case 3: pnode->node_type = GA_NODE_SECONDARY_DOMAIN_HESS; break;
- case 4: pnode->node_type = GA_NODE_XFEM_PLUS_HESS; break;
- case 5: pnode->node_type = GA_NODE_XFEM_MINUS_HESS; break;
- default: GMM_ASSERT1(false, "internal error");
- }
- if (n > 1) {
- if (q == 1 && mii.size() == 1) { mii[0] = n; mii.push_back(n); }
- else { mii.push_back(n); mii.push_back(n); }
- }
- } else {
- switch (ndt) {
- case 1: pnode->node_type = GA_NODE_INTERPOLATE_HESS_TEST; break;
- case 2: pnode->node_type = GA_NODE_ELEMENTARY_HESS_TEST; break;
- case 3: pnode->node_type =
GA_NODE_SECONDARY_DOMAIN_HESS_TEST;break;
- case 4: pnode->node_type = GA_NODE_XFEM_PLUS_HESS_TEST; break;
- case 5: pnode->node_type = GA_NODE_XFEM_MINUS_HESS_TEST; break;
- default: GMM_ASSERT1(false, "internal error");
- }
+ pnode->node_type = test ? node_type_selector_hess_test[ndt-1]
+ : node_type_selector_hess[ndt-1];
+ if (test) {
if (q == 1 && mii.size() <= 1) {
mii.resize(1);
mii[0] = 2;
} else
mii.insert(mii.begin(), 2);
- if (n > 1) { mii.push_back(n); mii.push_back(n); }
+ if (n > 1) {
+ mii.push_back(n);
+ mii.push_back(n);
+ }
+ } else if (n > 1) {
+ if (q == 1 && mii.size() == 1)
+ mii[0] = n;
+ else
+ mii.push_back(n);
+ mii.push_back(n);
}
break;
case 3: // divergence
@@ -768,29 +771,10 @@ namespace getfem {
ga_throw_error(pnode->expr, pnode->pos,
"Divergence operator requires fem qdim ("
<< q << ") to be equal to dim (" << n << ")");
- if (!test) {
- switch (ndt) {
- case 1: pnode->node_type = GA_NODE_INTERPOLATE_DIVERG; break;
- case 2: pnode->node_type = GA_NODE_ELEMENTARY_DIVERG; break;
- case 3: pnode->node_type = GA_NODE_SECONDARY_DOMAIN_DIVERG;break;
- case 4: pnode->node_type = GA_NODE_XFEM_PLUS_DIVERG; break;
- case 5: pnode->node_type = GA_NODE_XFEM_MINUS_DIVERG; break;
- default: GMM_ASSERT1(false, "internal error");
- }
- mii.resize(1);
- mii[0] = 1;
- } else {
- switch (ndt) {
- case 1: pnode->node_type = GA_NODE_INTERPOLATE_DIVERG_TEST; break;
- case 2: pnode->node_type = GA_NODE_ELEMENTARY_DIVERG_TEST; break;
- case 3:
pnode->node_type=GA_NODE_SECONDARY_DOMAIN_DIVERG_TEST;break;
- case 4: pnode->node_type = GA_NODE_XFEM_PLUS_DIVERG_TEST; break;
- case 5: pnode->node_type = GA_NODE_XFEM_MINUS_DIVERG_TEST; break;
- default: GMM_ASSERT1(false, "internal error");
- }
- mii.resize(1);
- mii[0] = 2;
- }
+ pnode->node_type = test ? node_type_selector_div_test[ndt-1]
+ : node_type_selector_div[ndt-1];
+ mii.resize(1);
+ mii[0] = test ? 2 : 1;
break;
}
pnode->t.adjust_sizes(mii);
@@ -4232,107 +4216,57 @@ namespace getfem {
ga_node_grad(tree, workspace, m, child0);
break;
- case GA_NODE_ELEMENTARY_VAL: case GA_NODE_ELEMENTARY_VAL_TEST:
- if (pnode->node_type == GA_NODE_ELEMENTARY_VAL)
- pnode->node_type = GA_NODE_ELEMENTARY_GRAD;
- else
- pnode->node_type = GA_NODE_ELEMENTARY_GRAD_TEST;
- mi = pnode->tensor().sizes();
- if (mi.back() != 1) mi.push_back(m.dim()); else mi.back() = m.dim();
- pnode->t.adjust_sizes(mi);
- break;
+ case GA_NODE_ELEMENTARY_VAL: case GA_NODE_ELEMENTARY_VAL_TEST:
+ case GA_NODE_XFEM_PLUS_VAL: case GA_NODE_XFEM_PLUS_VAL_TEST:
+ case GA_NODE_XFEM_MINUS_VAL: case GA_NODE_XFEM_MINUS_VAL_TEST:
case GA_NODE_ELEMENTARY_GRAD: case GA_NODE_ELEMENTARY_GRAD_TEST:
- if (pnode->node_type == GA_NODE_ELEMENTARY_GRAD)
- pnode->node_type = GA_NODE_ELEMENTARY_HESS;
- else
- pnode->node_type = GA_NODE_ELEMENTARY_HESS_TEST;
- mi = pnode->tensor().sizes();
- if (mi.back() != 1) mi.push_back(m.dim()); else mi.back() = m.dim();
- pnode->t.adjust_sizes(mi);
- break;
- case GA_NODE_ELEMENTARY_HESS: case GA_NODE_ELEMENTARY_HESS_TEST:
- GMM_ASSERT1(false, "Sorry, cannot derive an Hessian once more");
- case GA_NODE_ELEMENTARY_DIVERG: case GA_NODE_ELEMENTARY_DIVERG_TEST:
- if (pnode->node_type == GA_NODE_ELEMENTARY_DIVERG)
- pnode->node_type = GA_NODE_ELEMENTARY_HESS;
- else
- pnode->node_type = GA_NODE_ELEMENTARY_HESS_TEST;
- mi = pnode->tensor().sizes();
- mi.pop_back(), mi.push_back(m.dim());
- if (m.dim() > 1) mi.push_back(m.dim());
- pnode->t.adjust_sizes(mi);
- tree.duplicate_with_operation(pnode, GA_COLON);
- child0 = pnode; pnode = pnode->parent; child1 = pnode->children[1];
- child1->init_matrix_tensor(meshdim, meshdim);
- gmm::clear(pnode->tensor().as_vector());
- for (size_type i = 0; i < meshdim; ++i)
- child1->tensor()(i,i) = scalar_type(1);
- child1->node_type = GA_NODE_CONSTANT;
- break;
-
- case GA_NODE_XFEM_PLUS_VAL: case GA_NODE_XFEM_PLUS_VAL_TEST:
- if (pnode->node_type == GA_NODE_XFEM_PLUS_VAL)
- pnode->node_type = GA_NODE_XFEM_PLUS_GRAD;
- else
- pnode->node_type = GA_NODE_XFEM_PLUS_GRAD_TEST;
+ case GA_NODE_XFEM_PLUS_GRAD: case GA_NODE_XFEM_PLUS_GRAD_TEST:
+ case GA_NODE_XFEM_MINUS_GRAD: case GA_NODE_XFEM_MINUS_GRAD_TEST:
+ {
+ static const std::map<GA_NODE_TYPE, GA_NODE_TYPE>
+ replacement_table =
+ { {GA_NODE_ELEMENTARY_VAL, GA_NODE_ELEMENTARY_GRAD},
+ {GA_NODE_ELEMENTARY_VAL_TEST, GA_NODE_ELEMENTARY_GRAD_TEST},
+ {GA_NODE_ELEMENTARY_GRAD, GA_NODE_ELEMENTARY_HESS},
+ {GA_NODE_ELEMENTARY_GRAD_TEST, GA_NODE_ELEMENTARY_HESS_TEST},
+ {GA_NODE_XFEM_PLUS_VAL, GA_NODE_XFEM_PLUS_GRAD},
+ {GA_NODE_XFEM_PLUS_VAL_TEST, GA_NODE_XFEM_PLUS_GRAD_TEST},
+ {GA_NODE_XFEM_PLUS_GRAD, GA_NODE_XFEM_PLUS_HESS},
+ {GA_NODE_XFEM_PLUS_GRAD_TEST, GA_NODE_XFEM_PLUS_HESS_TEST},
+ {GA_NODE_XFEM_MINUS_VAL, GA_NODE_XFEM_MINUS_GRAD},
+ {GA_NODE_XFEM_MINUS_VAL_TEST, GA_NODE_XFEM_MINUS_GRAD_TEST},
+ {GA_NODE_XFEM_MINUS_GRAD, GA_NODE_XFEM_MINUS_HESS},
+ {GA_NODE_XFEM_MINUS_GRAD_TEST, GA_NODE_XFEM_MINUS_HESS_TEST}
+ };
+ pnode->node_type = replacement_table.at(pnode->node_type);
+ }
mi = pnode->tensor().sizes();
- if (mi.back() != 1) mi.push_back(m.dim()); else mi.back() = m.dim();
- pnode->t.adjust_sizes(mi);
- break;
- case GA_NODE_XFEM_PLUS_GRAD: case GA_NODE_XFEM_PLUS_GRAD_TEST:
- if (pnode->node_type == GA_NODE_XFEM_PLUS_GRAD)
- pnode->node_type = GA_NODE_XFEM_PLUS_HESS;
+ if (mi.back() == 1)
+ mi.back() = m.dim();
else
- pnode->node_type = GA_NODE_XFEM_PLUS_HESS_TEST;
- mi = pnode->tensor().sizes();
- if (mi.back() != 1) mi.push_back(m.dim()); else mi.back() = m.dim();
+ mi.push_back(m.dim());
pnode->t.adjust_sizes(mi);
break;
+ case GA_NODE_ELEMENTARY_HESS: case GA_NODE_ELEMENTARY_HESS_TEST:
case GA_NODE_XFEM_PLUS_HESS: case GA_NODE_XFEM_PLUS_HESS_TEST:
- GMM_ASSERT1(false, "Sorry, cannot derive an Hessian once more");
- case GA_NODE_XFEM_PLUS_DIVERG: case GA_NODE_XFEM_PLUS_DIVERG_TEST:
- if (pnode->node_type == GA_NODE_XFEM_PLUS_DIVERG)
- pnode->node_type = GA_NODE_XFEM_PLUS_HESS;
- else
- pnode->node_type = GA_NODE_XFEM_PLUS_HESS_TEST;
- mi = pnode->tensor().sizes();
- mi.pop_back(), mi.push_back(m.dim());
- if (m.dim() > 1) mi.push_back(m.dim());
- pnode->t.adjust_sizes(mi);
- tree.duplicate_with_operation(pnode, GA_COLON);
- child0 = pnode; pnode = pnode->parent; child1 = pnode->children[1];
- child1->init_matrix_tensor(meshdim, meshdim);
- gmm::clear(pnode->tensor().as_vector());
- for (size_type i = 0; i < meshdim; ++i)
- child1->tensor()(i,i) = scalar_type(1);
- child1->node_type = GA_NODE_CONSTANT;
- break;
-
- case GA_NODE_XFEM_MINUS_VAL: case GA_NODE_XFEM_MINUS_VAL_TEST:
- if (pnode->node_type == GA_NODE_XFEM_MINUS_VAL)
- pnode->node_type = GA_NODE_XFEM_MINUS_GRAD;
- else
- pnode->node_type = GA_NODE_XFEM_MINUS_GRAD_TEST;
- mi = pnode->tensor().sizes();
- if (mi.back() != 1) mi.push_back(m.dim()); else mi.back() = m.dim();
- pnode->t.adjust_sizes(mi);
- break;
- case GA_NODE_XFEM_MINUS_GRAD: case GA_NODE_XFEM_MINUS_GRAD_TEST:
- if (pnode->node_type == GA_NODE_XFEM_MINUS_GRAD)
- pnode->node_type = GA_NODE_XFEM_MINUS_HESS;
- else
- pnode->node_type = GA_NODE_XFEM_MINUS_HESS_TEST;
- mi = pnode->tensor().sizes();
- if (mi.back() != 1) mi.push_back(m.dim()); else mi.back() = m.dim();
- pnode->t.adjust_sizes(mi);
- break;
case GA_NODE_XFEM_MINUS_HESS: case GA_NODE_XFEM_MINUS_HESS_TEST:
GMM_ASSERT1(false, "Sorry, cannot derive an Hessian once more");
+ break;
+ case GA_NODE_ELEMENTARY_DIVERG: case GA_NODE_ELEMENTARY_DIVERG_TEST:
+ case GA_NODE_XFEM_PLUS_DIVERG: case GA_NODE_XFEM_PLUS_DIVERG_TEST:
case GA_NODE_XFEM_MINUS_DIVERG: case GA_NODE_XFEM_MINUS_DIVERG_TEST:
- if (pnode->node_type == GA_NODE_XFEM_MINUS_DIVERG)
- pnode->node_type = GA_NODE_XFEM_MINUS_HESS;
- else
- pnode->node_type = GA_NODE_XFEM_MINUS_HESS_TEST;
+ {
+ static const std::map<GA_NODE_TYPE, GA_NODE_TYPE>
+ replacement_table =
+ { {GA_NODE_ELEMENTARY_DIVERG, GA_NODE_ELEMENTARY_HESS},
+ {GA_NODE_ELEMENTARY_DIVERG_TEST, GA_NODE_ELEMENTARY_HESS_TEST},
+ {GA_NODE_XFEM_PLUS_DIVERG, GA_NODE_XFEM_PLUS_HESS},
+ {GA_NODE_XFEM_PLUS_DIVERG_TEST, GA_NODE_XFEM_PLUS_HESS_TEST},
+ {GA_NODE_XFEM_MINUS_DIVERG, GA_NODE_XFEM_MINUS_HESS},
+ {GA_NODE_XFEM_MINUS_DIVERG_TEST, GA_NODE_XFEM_MINUS_HESS_TEST}
+ };
+ pnode->node_type = replacement_table.at(pnode->node_type);
+ }
mi = pnode->tensor().sizes();
mi.pop_back();
mi.push_back(m.dim());
[Prev in Thread] |
Current Thread |
[Next in Thread] |
- [Getfem-commits] [getfem-commits] branch master updated: Replace some switches with lookup tables to reduce code duplication,
Konstantinos Poulios <=