getfem-commits
[Top][All Lists]
Advanced

[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());



reply via email to

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