From cf404acd2931278556201f2b6bea865e3dac81aa Mon Sep 17 00:00:00 2001
From: acrovato <a.crovato@uliege.be>
Date: Thu, 24 Mar 2022 17:38:42 +0100
Subject: [PATCH] Use linear solvers from direct methods in Adjoint. Minor
 changes.

---
 dart/_src/dartw.i         |  2 +-
 dart/api/core.py          | 21 ++++++---------------
 dart/api/internal/trim.py |  4 ++--
 dart/api/mphys.py         |  2 +-
 dart/benchmark/onera.py   |  6 +-----
 dart/default.py           |  7 +++----
 dart/src/wAdjoint.cpp     | 32 +++++++++++++++++++++++---------
 dart/src/wAdjoint.h       |  9 +++++----
 dart/src/wSolver.cpp      |  4 ++--
 ext/amfe                  |  2 +-
 10 files changed, 45 insertions(+), 44 deletions(-)

diff --git a/dart/_src/dartw.i b/dart/_src/dartw.i
index e16e839..6847f36 100644
--- a/dart/_src/dartw.i
+++ b/dart/_src/dartw.i
@@ -70,8 +70,8 @@ threads="1"
 %immutable dart::Body::Cm;
 %immutable dart::Body::nLoads;
 %include "wBody.h"
-%include "wBlowing.h"
 %warnfilter(+509);
+%include "wBlowing.h"
 
 %immutable dart::Problem::msh; // read-only variable (no setter)
 %immutable dart::Problem::nDim;
diff --git a/dart/api/core.py b/dart/api/core.py
index e729b8d..69d1751 100644
--- a/dart/api/core.py
+++ b/dart/api/core.py
@@ -146,7 +146,7 @@ def initDart(params, scenario='aerodynamic', task='analysis'):
 
     # Mesh morpher creation
     if scenario == 'aerostructural' or task == 'optimization':
-        _mrf = tbox.MshDeform(_msh, _dim, nthrds=nthrd)
+        _mrf = tbox.MshDeform(_msh, tbox.Gmres(1, 1e-6, 30, 1e-8), _dim, nthrds=nthrd)
         _mrf.setField(params['Fluid'])
         _mrf.addFixed(params['Farfield'])
         if _dim == 2:
@@ -213,10 +213,10 @@ def initDart(params, scenario='aerodynamic', task='analysis'):
     elif params['LSolver'] == 'MUMPS':
         linsol = tbox.Mumps()
     elif params['LSolver'] == 'GMRES':
-        linsol = tbox.Gmres()
-        linsol.setFillFactor(params['G_fill']) if 'G_fill' in params else linsol.setFillFactor(2)
-        linsol.setRestart(params['G_restart']) if 'G_restart' in params else linsol.setRestart(50)
-        linsol.setTolerance(params['G_tol']) if 'G_tol' in params else linsol.setTolerance(1e-5)
+        gfil = params['G_fill'] if 'G_fill' in params else 2
+        grst = params['G_restart'] if 'G_restart' in params else 50
+        gtol = params['G_tol'] if 'G_tol' in params else 1e-5
+        linsol = tbox.Gmres(gfil, 1e-6, grst, gtol)
     else:
         raise RuntimeError('Available linear solvers: PARDISO, MUMPS or GMRES, but ' + params['LSolver'] + ' was given!\n')
     # initialize the nonlinear (outer) solver
@@ -224,16 +224,7 @@ def initDart(params, scenario='aerodynamic', task='analysis'):
 
     # Adjoint (reverse) solver creation
     if task == 'optimization':
-        if params['LSolver'] == 'PARDISO':
-            alinsol = tbox.Pardiso()
-        elif params['LSolver'] == 'MUMPS':
-            alinsol = tbox.Mumps()
-        else:
-            alinsol = tbox.Gmres()
-            alinsol.setFillFactor(params['G_fill']) if 'G_fill' in params else alinsol.setFillFactor(2)
-            alinsol.setRestart(params['G_restart']) if 'G_restart' in params else alinsol.setRestart(50)
-            alinsol.setTolerance(1e-12)
-        _adj = dart.Adjoint(_sol, _mrf, alinsol)
+        _adj = dart.Adjoint(_sol, _mrf)
     else:
         _adj = None
 
diff --git a/dart/api/internal/trim.py b/dart/api/internal/trim.py
index be1c330..74c0025 100644
--- a/dart/api/internal/trim.py
+++ b/dart/api/internal/trim.py
@@ -90,8 +90,8 @@ class Trim:
             self.pbl.update(self.alpha)
             # run the solver
             self.tms["solver"].start()
-            success = self.sol.run()
-            if not success:
+            status = self.sol.run()
+            if status >= 2:
                 raise RuntimeError('Flow solver diverged!\n')
             self.tms["solver"].stop()
             # update slope
diff --git a/dart/api/mphys.py b/dart/api/mphys.py
index 58200c0..56fcf9a 100644
--- a/dart/api/mphys.py
+++ b/dart/api/mphys.py
@@ -372,7 +372,7 @@ class DartCoefficients(om.ExplicitComponent):
         """
         # NB: inputs already up-to-date because DartSolver has already been run
         # Write to disk
-        if self.options['morph'] and str(type(self.options['wrtr'])) == '<class \'tboxw.GmshExport\'>':
+        if self.options['morph'] and self.options['wrtr'].type() == 1:
             if self.iscn == 0:
                 self.options['wrtr'].save(self.sol.pbl.msh.name)
             else:
diff --git a/dart/benchmark/onera.py b/dart/benchmark/onera.py
index 75209e2..b0f9c21 100644
--- a/dart/benchmark/onera.py
+++ b/dart/benchmark/onera.py
@@ -36,11 +36,7 @@ def newton(pbl):
     try:
         newton = dart.Newton(pbl, tbox.Pardiso(), nthrds=k, vrb=2)
     except:
-        gmres = tbox.Gmres()
-        gmres.setFillFactor(2)
-        gmres.setDropTol(1e-6)
-        gmres.setRestart(50)
-        gmres.setTolerance(1e-5)
+        gmres = tbox.Gmres(2, 1e-6, 50, 1e-5)
         newton = dart.Newton(pbl, gmres, nthrds=k, vrb=2)
     return newton
 
diff --git a/dart/default.py b/dart/default.py
index 93cb86c..caf91dc 100644
--- a/dart/default.py
+++ b/dart/default.py
@@ -150,7 +150,7 @@ def picard(pbl):
         problem formulation
     """
     args = parseargs()
-    solver = dart.Picard(pbl, tbox.Gmres(), nthrds=args.k, vrb=args.verb+1)
+    solver = dart.Picard(pbl, tbox.Gmres(1, 1e-6, 30, 1e-8), nthrds=args.k, vrb=args.verb+1)
     return solver
 
 def newton(pbl):
@@ -187,7 +187,7 @@ def morpher(msh, dim, mov, fxd = ['upstream', 'farfield', 'downstream'], fld = '
         name of physical tag contaning the symmetry plane (y)
     """
     args = parseargs()
-    mshDef = tbox.MshDeform(msh, dim, nthrds=args.k)
+    mshDef = tbox.MshDeform(msh, tbox.Gmres(1, 1e-6, 30, 1e-8), dim, nthrds=args.k)
     mshDef.setField(fld)
     mshDef.addFixed(fxd)
     mshDef.addMoving(mov)
@@ -207,8 +207,7 @@ def adjoint(solver, morpher):
     solver : tbox.MshDeform object
         mesh morpher
     """
-    from tbox.solvers import LinearSolver
-    adjoint = dart.Adjoint(solver, morpher, LinearSolver().pardiso())
+    adjoint = dart.Adjoint(solver, morpher)
     return adjoint
 
 def initViewer(problem):
diff --git a/dart/src/wAdjoint.cpp b/dart/src/wAdjoint.cpp
index 3e58eae..8b22008 100644
--- a/dart/src/wAdjoint.cpp
+++ b/dart/src/wAdjoint.cpp
@@ -32,6 +32,7 @@
 #include "wNode.h"
 #include "wElement.h"
 #include "wLinearSolver.h"
+#include "wGmres.h"
 #include "wMshDeform.h"
 #include "wResults.h"
 #include "wMshExport.h"
@@ -51,12 +52,24 @@ using namespace dart;
 /**
  * @brief Initialize the adjoint solver
  */
-Adjoint::Adjoint(std::shared_ptr<Newton> _sol, std::shared_ptr<tbox::MshDeform> _morph, std::shared_ptr<tbox::LinearSolver> _linsol) : sol(_sol), morph(_morph), linsol(_linsol)
+Adjoint::Adjoint(std::shared_ptr<Newton> _sol, std::shared_ptr<tbox::MshDeform> _morph) : sol(_sol), morph(_morph)
 {
     // Default parameters
     nthreads = sol->nthreads;
     verbose = sol->verbose;
 
+    // Linear solvers
+    if (sol->linsol->type() == LSOLTYPE::GMRES_ILUT)
+    {
+        // Use the same GMRES, but with a thighter tolerance
+        std::shared_ptr<Gmres> gmres = std::make_shared<Gmres>(*dynamic_cast<Gmres*>(sol->linsol.get()));
+        gmres->setTolerance(1e-8);
+        alinsol = gmres;
+    }
+    else
+        alinsol = sol->linsol;
+    mlinsol = morph->linsol;
+
     // Update element gradients
     sol->pbl->initGradElems();
 
@@ -67,6 +80,13 @@ Adjoint::Adjoint(std::shared_ptr<Newton> _sol, std::shared_ptr<tbox::MshDeform>
     dCdMsh.resize(sol->pbl->msh->nodes.size(), Eigen::Vector3d::Zero());
     dClAoa = 0;
     dCdAoa = 0;
+
+    // Display solver parameters
+    std::cout << "--- Adjoint solver ---\n"
+              << "Aero inner solver: " << *alinsol
+              << "Mesh inner solver: " << *mlinsol
+              << "Number of threads: " << nthreads << "\n"
+              << std::endl;
 }
 
 /**
@@ -81,12 +101,6 @@ void Adjoint::run()
     // Init
     tbb::global_control control(tbb::global_control::max_allowed_parallelism, nthreads);
 
-    // Display solver parameters
-    std::cout << "--- Adjoint solver ---\n"
-              << "Inner solver: " << *linsol
-              << "Number of threads: " << nthreads << "\n"
-              << std::endl;
-
     // Compute partial gradients of flow residuals and solve flow adjoint
     tms["0-AdjFlo"].start();
     this->linearizeFlow();                                                            // dRu/dU, dRu/dA, dRu/dX
@@ -195,7 +209,7 @@ std::vector<double> Adjoint::solveMesh(std::vector<double> const &dX)
     Eigen::Map<Eigen::VectorXd> dR_(dR.data(), dR.size());
     Eigen::VectorXd dX_ = Eigen::Map<const Eigen::VectorXd>(dX.data(), dX.size());
     // Solve
-    linsol->compute(dRx_X.transpose(), Eigen::Map<Eigen::VectorXd>(dX_.data(), dX_.size()), dR_);
+    mlinsol->compute(dRx_X.transpose(), Eigen::Map<Eigen::VectorXd>(dX_.data(), dX_.size()), dR_);
     return std::vector<double>(dR.data(), dR.data() + dR.size());
 }
 
@@ -243,7 +257,7 @@ std::vector<double> Adjoint::solveFlow(std::vector<double> const &dU)
     Eigen::Map<Eigen::VectorXd> dR_(dR.data(), dR.size());
     Eigen::VectorXd dU_ = Eigen::Map<const Eigen::VectorXd>(dU.data(), dU.size());
     // Solve
-    linsol->compute(dRu_U.transpose(), Eigen::Map<Eigen::VectorXd>(dU_.data(), dU_.size()), dR_);
+    alinsol->compute(dRu_U.transpose(), Eigen::Map<Eigen::VectorXd>(dU_.data(), dU_.size()), dR_);
     return std::vector<double>(dR.data(), dR.data() + dR.size());
 }
 
diff --git a/dart/src/wAdjoint.h b/dart/src/wAdjoint.h
index 308a438..a33efb1 100644
--- a/dart/src/wAdjoint.h
+++ b/dart/src/wAdjoint.h
@@ -37,9 +37,10 @@ namespace dart
 class DART_API Adjoint : public fwk::wSharedObject
 {
 public:
-    std::shared_ptr<Newton> sol;                ///< Newton solver
-    std::shared_ptr<tbox::MshDeform> morph;     ///< mesh morpher
-    std::shared_ptr<tbox::LinearSolver> linsol; ///< linear solver
+    std::shared_ptr<Newton> sol;                 ///< Newton solver
+    std::shared_ptr<tbox::MshDeform> morph;      ///< mesh morpher
+    std::shared_ptr<tbox::LinearSolver> alinsol; ///< linear solver (adjoint aero)
+    std::shared_ptr<tbox::LinearSolver> mlinsol; ///< linear solver (adjoint mesh)
 
     int nthreads; ///< number of threads for the assembly
     int verbose;  ///< display more info
@@ -61,7 +62,7 @@ private:
     fwk::Timers tms;                                    ///< internal timers
 
 public:
-    Adjoint(std::shared_ptr<Newton> _sol, std::shared_ptr<tbox::MshDeform> _morph, std::shared_ptr<tbox::LinearSolver> _linsol);
+    Adjoint(std::shared_ptr<Newton> _sol, std::shared_ptr<tbox::MshDeform> _morph);
     virtual ~Adjoint() { std::cout << "~Adjoint()\n"; }
 
     void run();
diff --git a/dart/src/wSolver.cpp b/dart/src/wSolver.cpp
index 8cf95c7..68d2b61 100644
--- a/dart/src/wSolver.cpp
+++ b/dart/src/wSolver.cpp
@@ -64,9 +64,9 @@ Solver::Solver(std::shared_ptr<Problem> _pbl,
               << "**                      _  /_/ /_  ___ |  __ _/_  /                          **\n"
               << "**                      /_____/ /_/  |_/_/ |_| /_/                           **\n"
               << "*******************************************************************************\n"
-              << "** Hi! My name is DART v1.1.0-21.09                                          **\n"
+              << "** Hi! My name is DART v1.2.0-22.04                                          **\n"
               << "** Adrien Crovato                                                            **\n"
-              << "** ULiege 2018-2021                                                          **\n"
+              << "** ULiege 2018-2022                                                          **\n"
               << "*******************************************************************************\n"
               << std::endl;
 
diff --git a/ext/amfe b/ext/amfe
index 054ba00..46eb2e5 160000
--- a/ext/amfe
+++ b/ext/amfe
@@ -1 +1 @@
-Subproject commit 054ba00c327e4f2745ff9c559832247f90c3cec9
+Subproject commit 46eb2e5f08e56260e21fe610bf572a708c1b1179
-- 
GitLab