From 5ba134b14938d6a8f4559936cdc55d45877d8112 Mon Sep 17 00:00:00 2001
From: acrovato <a.crovato@uliege.be>
Date: Fri, 22 Nov 2024 13:54:00 +0100
Subject: [PATCH] Add tbb loop in Adjoint. Add doc. Refactoring.

---
 dart/api/core.py              |  6 +++---
 dart/src/wAdjoint.cpp         | 27 +++++++++++++--------------
 dart/src/wAdjoint.h           |  3 ++-
 dart/src/wBlowing.cpp         | 19 -------------------
 dart/src/wBlowing.h           |  4 ++--
 dart/src/wBlowingResidual.cpp | 21 +++++++++++++++------
 dart/src/wSolver.h            |  2 +-
 7 files changed, 36 insertions(+), 46 deletions(-)

diff --git a/dart/api/core.py b/dart/api/core.py
index 6476b4a..7cb61f7 100644
--- a/dart/api/core.py
+++ b/dart/api/core.py
@@ -219,12 +219,12 @@ def init_dart(cfg, scenario='aerodynamic', task='analysis', viscous=False):
         linsol = tbox.Pardiso()
     elif cfg['LSolver'] == 'MUMPS':
         linsol = tbox.Mumps()
+    elif cfg['LSolver'] == 'SparseLU':
+        linsol = tbox.SparseLu()
     elif cfg['LSolver'] == 'GMRES':
         linsol = tbox.Gmres(cfg.get('G_fill', 2), 1e-6, cfg.get('G_restart', 50), cfg.get('G_tol', 1e-5), 200)
-    elif cfg['LSolver'] == 'SparseLu':
-        linsol = tbox.SparseLu()
     else:
-        raise RuntimeError('Available linear solvers: PARDISO, MUMPS or GMRES, but ' + cfg['LSolver'] + ' was given!\n')
+        raise RuntimeError('Available linear solvers: PARDISO, MUMPS, SparseLU or GMRES, but ' + cfg['LSolver'] + ' was given!\n')
     # initialize the nonlinear (outer) solver
     _sol = dart.Newton(_pbl, linsol, rTol=cfg['Rel_tol'], aTol=cfg['Abs_tol'], mIt=cfg['Max_it'], nthrds=nthrd, vrb=verb)
 
diff --git a/dart/src/wAdjoint.cpp b/dart/src/wAdjoint.cpp
index 367921e..030bbbb 100644
--- a/dart/src/wAdjoint.cpp
+++ b/dart/src/wAdjoint.cpp
@@ -564,25 +564,24 @@ void Adjoint::buildGradientResidualMesh(Eigen::SparseMatrix<double, Eigen::RowMa
     // Farfield B.C. are not taken into account because they have no influence on the solution
 
     // Blowing boundary
-    if (sol->pbl->bBCs.size() > 0)
+    for (auto blow : sol->pbl->bBCs)
     {
-        for (auto b : sol->pbl->bBCs)
-        {
-            for (auto p : b->uE)
+        tbb::parallel_for_each(blow->uE.begin(), blow->uE.end(), [&](std::pair<Element *, F0ElC *> p) {
+            // Build elementary matrices
+            Eigen::MatrixXd A = BlowingResidual::buildGradientMesh(*p.first, sol->phi, *p.second, sol->pbl->nDim);
+            // Assembly
+            tbb::spin_mutex::scoped_lock lock(mutex);
+            for (size_t i = 0; i < p.first->nodes.size(); ++i)
             {
-                Eigen::MatrixXd A = BlowingResidual::buildGradientMesh(*p.first, sol->phi, *p.second, sol->pbl->nDim);
-                for (size_t i = 0; i < p.first->nodes.size(); ++i)
+                size_t rowi = p.first->nodes[i]->row;
+                for (size_t j = 0; j < p.first->nodes.size(); ++j)
                 {
-                    size_t rowi = p.first->nodes[i]->row;
-                    for (size_t j = 0; j < p.first->nodes.size(); ++j)
-                    {
-                        int rowj = p.first->nodes[j]->row;
-                        for (int n = 0; n < sol->pbl->nDim; ++n)
-                            T.push_back(Eigen::Triplet<double>(sol->rows[rowi], sol->pbl->nDim * rowj + n, A(i, sol->pbl->nDim * j + n)));
-                    }
+                    int rowj = p.first->nodes[j]->row;
+                    for (int n = 0; n < sol->pbl->nDim; ++n)
+                        T.push_back(Eigen::Triplet<double>(sol->rows[rowi], sol->pbl->nDim * rowj + n, A(i, sol->pbl->nDim * j + n)));
                 }
             }
-        }
+        });
     }
 
     // Wake
diff --git a/dart/src/wAdjoint.h b/dart/src/wAdjoint.h
index 79f4eee..5c1e1cd 100644
--- a/dart/src/wAdjoint.h
+++ b/dart/src/wAdjoint.h
@@ -87,12 +87,13 @@ public:
     std::vector<double> computeGradientCoefficientsAoa();
     std::vector<std::vector<double>> computeGradientCoefficientsMesh();
 
+#ifndef SWIG
+    // Getters for partials (required by VII-BLASTER)
     Eigen::SparseMatrix<double, Eigen::RowMajor> getRu_U() const { return dRu_U; }
     Eigen::VectorXd getRu_A() const { return dRu_A; }
     Eigen::SparseMatrix<double, Eigen::RowMajor> getRu_X() const { return dRu_X; }
     Eigen::SparseMatrix<double, Eigen::RowMajor> getRx_X() const { return dRx_X; }
 
-#ifndef SWIG
     virtual void write(std::ostream &out) const override;
 #endif
 
diff --git a/dart/src/wBlowing.cpp b/dart/src/wBlowing.cpp
index ef2c86a..c4163f3 100644
--- a/dart/src/wBlowing.cpp
+++ b/dart/src/wBlowing.cpp
@@ -59,25 +59,6 @@ void Blowing::create()
     }
 }
 
-/**
- * @brief Set blowing velocity
- */
-void Blowing::setU(size_t i, double ue)
-{
-    uE[i].second->update(ue);
-}
-
-/**
- * @brief Get blowing velocity
- */
-double Blowing::getU(size_t i) const
-{
-    // Return a constant value
-    tbox::Element *e = uE[i].first;
-    std::vector<double> phi(0, 0.);
-    return uE[i].second->eval(*e, phi, 0);
-}
-
 void Blowing::write(std::ostream &out) const
 {
     out << " Blowing boundary condition on " << *tag << std::endl;
diff --git a/dart/src/wBlowing.h b/dart/src/wBlowing.h
index 2a0cd7d..93b27c7 100644
--- a/dart/src/wBlowing.h
+++ b/dart/src/wBlowing.h
@@ -41,8 +41,8 @@ public:
     Blowing(std::shared_ptr<tbox::MshData> _msh, std::string const &names);
     virtual ~Blowing();
 
-    void setU(size_t i, double ue);
-    double getU(size_t i) const;
+    void setU(size_t i, double ue) { uE[i].second->update(ue); }
+    double getU(size_t i) const { return uE[i].second->eval(*uE[i].first, std::vector<double>(), 0); }
 
 #ifndef SWIG
     virtual void write(std::ostream &out) const override;
diff --git a/dart/src/wBlowingResidual.cpp b/dart/src/wBlowingResidual.cpp
index b8b4ea3..0c07b67 100644
--- a/dart/src/wBlowingResidual.cpp
+++ b/dart/src/wBlowingResidual.cpp
@@ -27,7 +27,7 @@ using namespace dart;
 /**
  * @brief Build the residual vector, on one boundary element
  *
- * b = \int psi * vn dV
+ * b = \int psi * vn dS
  */
 Eigen::VectorXd BlowingResidual::build(Element const &e, std::vector<double> const &phi, F0El const &f)
 {
@@ -47,11 +47,16 @@ Eigen::VectorXd BlowingResidual::build(Element const &e, std::vector<double> con
 
 /**
  * @brief Build the gradient of the residual vector with respect to the blowing velocity, on one blowing boundary element
+ *
+ * b = \int psi dS
  */
 Eigen::VectorXd BlowingResidual::buildGradientBlowing(tbox::Element const &e)
 {
+    // Get pre-computed values
     Cache &cache = e.getVCache();
     Gauss &gauss = cache.getVGauss();
+
+    // Build velocity gradient
     Eigen::VectorXd b = Eigen::VectorXd::Zero(e.nodes.size());
     for (size_t k = 0; k < gauss.getN(); ++k)
         b += cache.getSf(k) * gauss.getW(k) * e.getDetJ(k);
@@ -60,19 +65,23 @@ Eigen::VectorXd BlowingResidual::buildGradientBlowing(tbox::Element const &e)
 
 /**
  * @brief Build the gradient of the residual vector with respect to the mesh, on one blowing boundary element
+ *
+ * A = \int psi * vn ddS
  */
 Eigen::MatrixXd BlowingResidual::buildGradientMesh(tbox::Element const &e, std::vector<double> const &phi, F0El const &f, int const nDim)
 {
-    Eigen::MatrixXd A = Eigen::MatrixXd::Zero(e.nodes.size(), nDim * e.nodes.size());
+    // Get pre-computed values
     Cache &cache = e.getVCache();
     Gauss &gauss = cache.getVGauss();
-    // Blowing velocity
+
+    // Build velocity gradient
     double vn = f.eval(e, phi, 0);
+    Eigen::MatrixXd A = Eigen::MatrixXd::Zero(e.nodes.size(), nDim * e.nodes.size());
     for (size_t k = 0; k < gauss.getN(); ++k)
     {
-        std::vector<double> gradJ = e.getGradDetJ(k);
-        for (size_t i = 0; i < gradJ.size(); i++)
-            A.col(i) += cache.getSf(k) * vn * gauss.getW(k) * gradJ[i];
+        std::vector<double> dDetJ = e.getGradDetJ(k);
+        for (size_t i = 0; i < dDetJ.size(); i++)
+            A.col(i) += cache.getSf(k) * vn * gauss.getW(k) * dDetJ[i];
     }
     return A;
 }
diff --git a/dart/src/wSolver.h b/dart/src/wSolver.h
index 62a2968..a988bca 100644
--- a/dart/src/wSolver.h
+++ b/dart/src/wSolver.h
@@ -80,7 +80,7 @@ public:
     virtual Status run();
     void save(tbox::MshExport *mshWriter, std::string const &suffix = "");
 
-    int getRow(int i) const { return rows[i]; };
+    int getRow(size_t i) const { return rows[i]; };
 
 protected:
     void computeFlow();
-- 
GitLab