Commit efcb4578 authored by GILLES Sebastien's avatar GILLES Sebastien
Browse files

#729 ThirdParty/Snes: introduce Gmres solver.

parent cd3d8744
......@@ -343,6 +343,9 @@
BE4ED31C1A2CBAC400DE374E /* MatrixOperations.cpp in Sources */ = {isa = PBXBuildFile; fileRef = BE4ED3191A2CBAC400DE374E /* MatrixOperations.cpp */; };
BE4ED31D1A2CBAC400DE374E /* MatrixOperations.hpp in Headers */ = {isa = PBXBuildFile; fileRef = BE4ED31A1A2CBAC400DE374E /* MatrixOperations.hpp */; };
BE4ED31E1A2CBAC400DE374E /* MatrixOperations.hxx in Headers */ = {isa = PBXBuildFile; fileRef = BE4ED31B1A2CBAC400DE374E /* MatrixOperations.hxx */; };
BE4F2D9D1BE7FA5700FFF373 /* Gmres.cpp in Sources */ = {isa = PBXBuildFile; fileRef = BE4F2D9A1BE7FA5700FFF373 /* Gmres.cpp */; };
BE4F2D9E1BE7FA5700FFF373 /* Gmres.hpp in Headers */ = {isa = PBXBuildFile; fileRef = BE4F2D9B1BE7FA5700FFF373 /* Gmres.hpp */; };
BE4F2D9F1BE7FA5700FFF373 /* Gmres.hxx in Headers */ = {isa = PBXBuildFile; fileRef = BE4F2D9C1BE7FA5700FFF373 /* Gmres.hxx */; };
BE501D041A2DC03900B92486 /* MatrixOrVector.hpp in Headers */ = {isa = PBXBuildFile; fileRef = BE501D031A2DC03900B92486 /* MatrixOrVector.hpp */; };
BE51121D1BDFB56600CB5D1E /* main_aitken.cpp in Sources */ = {isa = PBXBuildFile; fileRef = BE51121C1BDFB56600CB5D1E /* main_aitken.cpp */; };
BE55781C1BE250670097FB58 /* Solver.cpp in Sources */ = {isa = PBXBuildFile; fileRef = BE5578191BE250670097FB58 /* Solver.cpp */; };
......@@ -3765,6 +3768,9 @@
BE4ED3191A2CBAC400DE374E /* MatrixOperations.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = MatrixOperations.cpp; sourceTree = "<group>"; };
BE4ED31A1A2CBAC400DE374E /* MatrixOperations.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = MatrixOperations.hpp; sourceTree = "<group>"; };
BE4ED31B1A2CBAC400DE374E /* MatrixOperations.hxx */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = MatrixOperations.hxx; sourceTree = "<group>"; };
BE4F2D9A1BE7FA5700FFF373 /* Gmres.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = Gmres.cpp; path = Solver/Instantiations/Gmres.cpp; sourceTree = "<group>"; };
BE4F2D9B1BE7FA5700FFF373 /* Gmres.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; name = Gmres.hpp; path = Solver/Instantiations/Gmres.hpp; sourceTree = "<group>"; };
BE4F2D9C1BE7FA5700FFF373 /* Gmres.hxx */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; name = Gmres.hxx; path = Solver/Instantiations/Gmres.hxx; sourceTree = "<group>"; };
BE4FC35A18F2AE87007B6DED /* QuadratureRuleList.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = QuadratureRuleList.cpp; sourceTree = "<group>"; };
BE4FC35B18F2AE87007B6DED /* QuadratureRuleList.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = QuadratureRuleList.hpp; sourceTree = "<group>"; };
BE501D031A2DC03900B92486 /* MatrixOrVector.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = MatrixOrVector.hpp; sourceTree = "<group>"; };
......@@ -5679,6 +5685,9 @@
BE4335D01BE7C47300802A82 /* Mumps.cpp */,
BE4335D11BE7C47300802A82 /* Mumps.hpp */,
BE4335D21BE7C47300802A82 /* Mumps.hxx */,
BE4F2D9A1BE7FA5700FFF373 /* Gmres.cpp */,
BE4F2D9B1BE7FA5700FFF373 /* Gmres.hpp */,
BE4F2D9C1BE7FA5700FFF373 /* Gmres.hxx */,
);
name = Instantiations;
sourceTree = "<group>";
......@@ -8737,6 +8746,7 @@
BE5697B11BE396E100B2EC67 /* ShellMatrix.hxx in Headers */,
BE90E1CA1A2492AA00CCAFDE /* Parmetis.hpp in Headers */,
BE6E4EE21B2ABE8B0049BB2D /* AccessGhostContent.hpp in Headers */,
BE4F2D9E1BE7FA5700FFF373 /* Gmres.hpp in Headers */,
BE4335CE1BE7C22F00802A82 /* Solver.hxx in Headers */,
BE1E87631B8DFB710002EE64 /* PrepareDefaultEntry.hpp in Headers */,
BE90E1621A24926E00CCAFDE /* Exception.hpp in Headers */,
......@@ -8777,6 +8787,7 @@
BE90E1D31A2492AA00CCAFDE /* Logs.hpp in Headers */,
BE90E1B81A24929A00CCAFDE /* Petsc.hpp in Headers */,
BE4335D41BE7C47300802A82 /* Mumps.hpp in Headers */,
BE4F2D9F1BE7FA5700FFF373 /* Gmres.hxx in Headers */,
BE90E1C61A2492AA00CCAFDE /* SubVector_Base.hxx in Headers */,
BE90E1691A24926E00CCAFDE /* PointerComparison.hxx in Headers */,
);
......@@ -10426,6 +10437,7 @@
BE90E16D1A24926E00CCAFDE /* BoolArray.cpp in Sources */,
BE41E96D1AC3F92A0072C8E6 /* EmptyString.cpp in Sources */,
BE90E1A91A24929A00CCAFDE /* Matrix.cpp in Sources */,
BE4F2D9D1BE7FA5700FFF373 /* Gmres.cpp in Sources */,
BE90E17E1A24929A00CCAFDE /* ExtendedOps.cpp in Sources */,
BE768E9D1B8331AE009B24CB /* Traits.cpp in Sources */,
BE5E406D1AAA088E007F8B1E /* EnvironmentVariable.cpp in Sources */,
......
......@@ -12,7 +12,7 @@
# include <utility>
# include "ThirdParty/Wrappers/Petsc/Print.hpp"
# include "ThirdParty/Wrappers/Petsc/Snes.hpp"
# include "ThirdParty/Wrappers/Petsc/Solver/Snes.hpp"
namespace HappyHeart
......
//
// Gmres.cpp
// HappyHeart
//
// Created by Sebastien Gilles on 02/11/15.
// Copyright © 2015 Inria. All rights reserved.
//
#include "ThirdParty/Wrappers/Petsc/Solver/Instantiations/Gmres.hpp"
#include "ThirdParty/Wrappers/Petsc/Solver/Snes.hpp"
namespace HappyHeart
{
namespace Wrappers
{
namespace Petsc
{
namespace Instantiations
{
Gmres::Gmres(unsigned int restart)
: parent(solver_type::direct),
restart_(static_cast<PetscInt>(restart))
{ }
void Gmres::SetSolveLinearOptions(Snes& snes,
const char* invoking_file, int invoking_line)
{
static_cast<void>(snes);
static_cast<void>(invoking_file);
static_cast<void>(invoking_line);
}
void Gmres::SupplInitOptions(Snes& snes,
const char* invoking_file, int invoking_line)
{
auto ksp = snes.GetKsp(invoking_file, invoking_line);
auto error_code = KSPGMRESSetRestart(ksp, GetRestart());
if (error_code)
throw ExceptionNS::Exception(error_code, "KSPGMRESSetRestart", invoking_file, invoking_line);
}
const std::string& Gmres::GetPetscName() const noexcept
{
static std::string ret(KSPGMRES);
return ret;
}
PetscInt Gmres::GetRestart() const noexcept
{
return restart_;
}
} //namespace Instantiations
} //namespace Petsc
} //namespace Wrappers
} // namespace HappyHeart
//
// Gmres.hpp
// HappyHeart
//
// Created by Sebastien Gilles on 02/11/15.
// Copyright © 2015 Inria. All rights reserved.
//
#ifndef HAPPY_HEART_x_THIRD_PARTY_x_WRAPPERS_x_PETSC_x_SOLVER_x_INSTANTIATIONS_x_GMRES_HPP_
# define HAPPY_HEART_x_THIRD_PARTY_x_WRAPPERS_x_PETSC_x_SOLVER_x_INSTANTIATIONS_x_GMRES_HPP_
# include <memory>
# include <vector>
# include "ThirdParty/IncludeWithoutWarning/Petsc/PetscSys.hpp"
# include "ThirdParty/Wrappers/Petsc/Solver/Private/Solver.hpp"
namespace HappyHeart
{
namespace Wrappers
{
namespace Petsc
{
namespace Instantiations
{
class Gmres final : public Private::Solver
{
public:
//! Alias to parent.
using parent = Private::Solver;
//! Alias to self.
using self = Gmres;
//! Alias to unique pointer.
using unique_ptr = std::unique_ptr<self>;
public:
/// \name Special members.
///@{
//! Constructor.
explicit Gmres(unsigned int restart);
//! Destructor.
~Gmres() = default;
//! Copy constructor.
Gmres(const Gmres&) = delete;
//! Move constructor.
Gmres(Gmres&&) = delete;
//! Copy affectation.
Gmres& operator=(const Gmres&) = delete;
//! Move affectation.
Gmres& operator=(Gmres&&) = delete;
///@}
private:
//! Set the options that are specific to the solver.
void SetSolveLinearOptions(Snes& snes,
const char* invoking_file, int invoking_line) override;
//! Set the options that are specific to the solver.
void SupplInitOptions(Snes& snes,
const char* invoking_file, int invoking_line) override;
/*!
* \brief Name of the solver used in Petsc.
*
* \internal The Petsc functions in which this name might be used depends on the type of the solver.
*/
const std::string& GetPetscName() const noexcept override;
private:
//! Restart.
PetscInt GetRestart() const noexcept;
private:
//! Restart.
const PetscInt restart_;
};
} //namespace Instantiations
} //namespace Petsc
} //namespace Wrappers
} // namespace HappyHeart
# include "ThirdParty/Wrappers/Petsc/Solver/Instantiations/Gmres.hxx"
#endif // HAPPY_HEART_x_THIRD_PARTY_x_WRAPPERS_x_PETSC_x_SOLVER_x_INSTANTIATIONS_x_GMRES_HPP_
//
// Gmres.hxx
// HappyHeart
//
// Created by Sebastien Gilles on 02/11/15.
// Copyright © 2015 Inria. All rights reserved.
//
#ifndef HAPPY_HEART_x_THIRD_PARTY_x_WRAPPERS_x_PETSC_x_SOLVER_x_INSTANTIATIONS_x_GMRES_HXX_
# define HAPPY_HEART_x_THIRD_PARTY_x_WRAPPERS_x_PETSC_x_SOLVER_x_INSTANTIATIONS_x_GMRES_HXX_
namespace HappyHeart
{
namespace Wrappers
{
namespace Petsc
{
namespace Instantiations
{
} //namespace Instantiations
} //namespace Petsc
} //namespace Wrappers
} // namespace HappyHeart
#endif // HAPPY_HEART_x_THIRD_PARTY_x_WRAPPERS_x_PETSC_x_SOLVER_x_INSTANTIATIONS_x_GMRES_HXX_
......@@ -33,7 +33,7 @@ namespace HappyHeart
void Mumps::SetOptions(Snes& snes,
void Mumps::SetSolveLinearOptions(Snes& snes,
const char* invoking_file, int invoking_line)
{
auto pc = snes.GetPreconditioner(invoking_file, invoking_line);
......@@ -81,6 +81,16 @@ namespace HappyHeart
TimeKeep::GetInstance().PrintTimeElapsed("AfterMUMPSSet");
}
void Mumps::SupplInitOptions(Snes& snes,
const char* invoking_file, int invoking_line)
{
static_cast<void>(snes);
static_cast<void>(invoking_file);
static_cast<void>(invoking_line);
}
const std::string& Mumps::GetPetscName() const noexcept
......
......@@ -74,8 +74,13 @@ namespace HappyHeart
private:
//! Set the options that are specific to the solver.
void SetOptions(Snes& snes,
const char* invoking_file, int invoking_line) override;
void SetSolveLinearOptions(Snes& snes,
const char* invoking_file, int invoking_line) override;
//! Set the options that are specific to the solver.
void SupplInitOptions(Snes& snes,
const char* invoking_file, int invoking_line) override;
/*!
......
......@@ -46,6 +46,7 @@ namespace HappyHeart
{
class Solver
{
......@@ -83,9 +84,14 @@ namespace HappyHeart
///@}
//! Set the options that are specific to the solver in SolveLinear().
virtual void SetSolveLinearOptions(Snes& snes,
const char* invoking_file, int invoking_line) = 0;
//! Set the options that are specific to the solver.
virtual void SetOptions(Snes& snes,
const char* invoking_file, int invoking_line) = 0;
virtual void SupplInitOptions(Snes& snes,
const char* invoking_file, int invoking_line) = 0;
/*!
......
......@@ -24,8 +24,8 @@ namespace HappyHeart
namespace Private
{
} //namespace Private
......
......@@ -43,8 +43,23 @@ namespace HappyHeart
snes_jacobian_(snes_jacobian),
snes_viewer_(snes_viewer)
{
// \todo #729 Replace this hardcoded line by factory!
solver_ = std::make_unique<Instantiations::Mumps>();
// \todo #729 Improve this ugly switch (by a factory).
// It is there as it is easier at the moment to deal this way with the different possible constructor
// arguments; factory could be introduced when InitSolver() that calls current constructor is more
// refined.
if (solver_name == "Mumps")
solver_ = std::make_unique<Instantiations::Mumps>();
else if (solver_name == "Gmres")
solver_ = std::make_unique<Instantiations::Gmres>(gmres_restart);
else if (solver_name == "Umfpack")
{
assert(false && "Not implemented yet");
}
else
{
assert(false && "All legit choices should be addressed here!");
}
const auto& solver = GetSolver();
......@@ -57,22 +72,7 @@ namespace HappyHeart
throw ExceptionNS::Exception(error_code, "SNESCreate", invoking_file, invoking_line);
auto ksp = GetKsp(invoking_file, invoking_line);
// std::string solver_id;
// if (solver == "Mumps")
// solver_id = MATSOLVERMUMPS;
// else if (solver == "Umfpack")
// solver_id = MATSOLVERUMFPACK;
// else if (solver == "Gmres")
// solver_id = KSPGMRES;
// else
// {
// assert(false && "Any other choice should have been trapped by InputParameterList!");
// }
//
// assert(!solver_id.empty());
// If the solver is a direct one, type must be 'preonly' and preconditioner 'lu'; actual solver
// used is determined by PCFactorSetMatSolverPackage().
......@@ -105,24 +105,16 @@ namespace HappyHeart
}
else
{
// error_code = KSPSetType(ksp, solver_id.c_str());
// if (error_code)
// throw ExceptionNS::Exception(error_code, "KSPSetType", invoking_file, invoking_line);
//
// if (solver == KSPGMRES)
// {
// error_code = KSPGMRESSetRestart(ksp, static_cast<PetscInt>(gmres_restart));
//
// if (error_code)
// throw ExceptionNS::Exception(error_code, "KSPGMRESSetRestart", invoking_file, invoking_line);
// }
//
//
// auto pc = GetPreconditioner(invoking_file, invoking_line);
//
// error_code = PCSetType(pc, preconditioner.c_str());
// if (error_code)
// throw ExceptionNS::Exception(error_code, "PCSetType", invoking_file, invoking_line);
error_code = KSPSetType(ksp, solver.GetPetscName().c_str());
if (error_code)
throw ExceptionNS::Exception(error_code, "KSPSetType", invoking_file, invoking_line);
auto pc = GetPreconditioner(invoking_file, invoking_line);
error_code = PCSetType(pc, preconditioner.c_str());
if (error_code)
throw ExceptionNS::Exception(error_code, "PCSetType", invoking_file, invoking_line);
}
......
......@@ -20,6 +20,7 @@
#include "ThirdParty/Wrappers/Petsc/Print.hpp"
#include "ThirdParty/Wrappers/Petsc/Exceptions/Petsc.hpp"
#include "ThirdParty/Wrappers/Petsc/Solver/Instantiations/Mumps.hpp"
#include "ThirdParty/Wrappers/Petsc/Solver/Instantiations/Gmres.hpp"
#include "Utilities/TimeKeep/TimeKeep.hpp"
......@@ -65,6 +66,8 @@ namespace HappyHeart
//! Friendship to helper class.
// \todo #729 I don't like having to put the list here; improve that!
friend Instantiations::Mumps;
friend Instantiations::Gmres;
public:
......
......@@ -82,7 +82,7 @@ namespace HappyHeart
TimeKeep::GetInstance().PrintTimeElapsed("AfterSetOperator");
GetNonCstSolver().SetOptions(*this, invoking_file, invoking_line);
GetNonCstSolver().SetSolveLinearOptions(*this, invoking_file, invoking_line);
// This optional line (would be called in KSPSolve) can lead to more explicit messages.
// Petsc documentation quote: 'The explicit call of this routine enables the separate monitoring of any
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment