1 /*!
2  * \file  mfront/src/NonLinearSystemSolverFactory.cxx
3  * \brief
4  * \author Thomas Helfer
5  * \brief 10 juin 2014
6  * \copyright Copyright (C) 2006-2018 CEA/DEN, EDF R&D. All rights
7  * reserved.
8  * This project is publicly released under either the GNU GPL Licence
9  * or the CECILL-A licence. A copy of thoses licences are delivered
10  * with the sources of TFEL. CEA or EDF may also distribute this
11  * project under specific licensing conditions.
12  */
13 
14 #include<stdexcept>
15 #include"TFEL/Raise.hxx"
16 #include"MFront/NonLinearSystemSolver.hxx"
17 #include"MFront/NewtonRaphsonSolvers.hxx"
18 #include"MFront/BroydenSolvers.hxx"
19 #include"MFront/SecondBroydenSolver.hxx"
20 #include"MFront/LevenbergMarquardtSolvers.hxx"
21 #include"MFront/NonLinearSystemSolverFactory.hxx"
22 
23 namespace mfront
24 {
25 
26   template <typename T>
buildSolverConstructor()27   static std::shared_ptr<NonLinearSystemSolver> buildSolverConstructor() {
28     return std::shared_ptr<NonLinearSystemSolver>(new T());
29   } // end of buildAlgoritmConstructor
30 
31   NonLinearSystemSolverFactory&
getNonLinearSystemSolverFactory()32   NonLinearSystemSolverFactory::getNonLinearSystemSolverFactory() {
33     static NonLinearSystemSolverFactory factory;
34     return factory;
35   }
36 
37   std::shared_ptr<NonLinearSystemSolver>
getSolver(const std::string & a) const38   NonLinearSystemSolverFactory::getSolver(const std::string& a) const {
39     const auto p = this->constructors.find(a);
40     tfel::raise_if(p == this->constructors.end(),
41                    "NonLinearSystemSolverFactory::getSolver : "
42                    "no solver '" +
43                        a + "' registred");
44     return (*(p->second))();
45   }
46 
NonLinearSystemSolverFactory()47   NonLinearSystemSolverFactory::NonLinearSystemSolverFactory() {
48     this->registerSolver("NewtonRaphson",
49 			 buildSolverConstructor<MFrontNewtonRaphsonSolver>);
50     this->registerSolver("NewtonRaphson_NumericalJacobian",
51 			 buildSolverConstructor<MFrontNewtonRaphsonNumericalJacobianSolver>);
52     this->registerSolver("PowellDogLeg_NewtonRaphson",
53 			 buildSolverConstructor<MFrontPowellDogLegNewtonRaphsonSolver>);
54     this->registerSolver("PowellDogLeg_NewtonRaphson_NumericalJacobian",
55 			 buildSolverConstructor<MFrontPowellDogLegNewtonRaphsonNumericalJacobianSolver>);
56     this->registerSolver("Broyden",
57 			 buildSolverConstructor<MFrontBroydenSolver>);
58     this->registerSolver("PowellDogLeg_Broyden",
59 			 buildSolverConstructor<MFrontPowellDogLegBroydenSolver>);
60     this->registerSolver("Broyden2",
61 			 buildSolverConstructor<SecondBroydenSolver>);
62     this->registerSolver("LevenbergMarquardt",
63 			 buildSolverConstructor<LevenbergMarquardtSolver>);
64     this->registerSolver("LevenbergMarquardt_NumericalJacobian",
65 			 buildSolverConstructor<LevenbergMarquardtNumericalJacobianSolver>);
66   } // end of NonLinearSystemSolverFactory::NonLinearSystemSolverFactory
67 
registerSolver(const std::string & a,const constructor c)68   void NonLinearSystemSolverFactory::registerSolver(const std::string& a,
69                                                     const constructor c) {
70     tfel::raise_if(!this->constructors.insert({a,c}).second,
71 		   "NonLinearSystemSolverFactory::registerSolver : "
72 		   "solver '"+a+"' already declared");
73   } // end of NonLinearSystemSolverFactory::registerSolver
74 
getRegistredSolvers() const75   std::vector<std::string> NonLinearSystemSolverFactory::getRegistredSolvers()
76       const {
77     std::vector<std::string> solvers;
78     for (const auto& s : this->constructors) {
79       solvers.push_back(s.first);
80     }
81     return solvers;
82   }  // end of NonLinearSystemSolverFactory::getRegistredSolvers
83 
84 } // end of namespace mfront
85