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