14 #if !defined (KRATOS_AMGCL_MPI_SCHUR_COMPLEMENT_SOLVER_H_INCLUDED)
15 #define KRATOS_AMGCL_MPI_SCHUR_COMPLEMENT_SOLVER_H_INCLUDED
18 #ifndef AMGCL_PARAM_UNKNOWN
20 # define AMGCL_PARAM_UNKNOWN(name) \
21 Kratos::Logger("AMGCL") << KRATOS_CODE_LOCATION << Kratos::Logger::Severity::WARNING << "Unknown parameter " << name << std::endl
33 #include <boost/range/iterator_range.hpp>
34 #include <boost/property_tree/json_parser.hpp>
36 #include <amgcl/amg.hpp>
37 #include <amgcl/adapter/epetra.hpp>
39 #include <amgcl/mpi/make_solver.hpp>
40 #include <amgcl/mpi/schur_pressure_correction.hpp>
41 #include <amgcl/mpi/solver/runtime.hpp>
42 #include <amgcl/mpi/block_preconditioner.hpp>
43 #include <amgcl/relaxation/as_preconditioner.hpp>
44 #include <amgcl/relaxation/runtime.hpp>
45 #include <amgcl/mpi/amg.hpp>
46 #include <amgcl/mpi/coarsening/runtime.hpp>
47 #include <amgcl/mpi/relaxation/runtime.hpp>
48 #include <amgcl/mpi/direct_solver/runtime.hpp>
49 #include <amgcl/mpi/partition/runtime.hpp>
54 template<
class TSparseSpaceType,
class TDenseSpaceType,
55 class TReordererType = Reorderer<TSparseSpaceType, TDenseSpaceType> >
57 TDenseSpaceType, TReordererType>
78 "solver_type" : "AmgclMPISchurComplementSolver",
79 "krylov_type" : "fgmres",
80 "velocity_block_preconditioner" :
82 "krylov_type" : "lgmres",
84 "preconditioner_type" : "ilu0",
87 "pressure_block_preconditioner" :
89 "krylov_type" : "fgmres",
91 "preconditioner_type" : "spai0",
95 "gmres_krylov_space_dimension": 50,
96 "coarsening_type": "aggregation",
100 "coarse_enough" : 5000
107 std::stringstream msg;
110 std::set<std::string> available_preconditioners = {
"spai0",
"ilu0",
"damped_jacobi",
"gauss_seidel",
"chebyshev"};
113 if(available_preconditioners.find(rParameters[
"velocity_block_preconditioner"][
"preconditioner_type"].
GetString()) == available_preconditioners.end())
115 msg <<
"currently prescribed velocity_block_preconditioner preconditioner_type : " << rParameters[
"velocity_block_preconditioner"][
"smoother_type"].
GetString() << std::endl;
116 msg <<
"admissible values are : spai0,ilu0,damped_jacobi,gauss_seidel,chebyshev"<< std::endl;
120 mCoarseEnough = rParameters[
"coarse_enough"].
GetInt();
151 mTolerance = rParameters[
"tolerance"].
GetDouble();
152 mMaxIterations = rParameters[
"max_iteration"].
GetInt();
153 mVerbosity=rParameters[
"verbosity"].
GetInt();
154 mprm.put(
"solver.type", rParameters[
"krylov_type"].GetString());
156 if(rParameters[
"krylov_type"].GetString() ==
"gmres" || rParameters[
"krylov_type"].GetString() ==
"lgmres" || rParameters[
"krylov_type"].GetString() ==
"fgmres")
157 mprm.put(
"solver.M", rParameters[
"gmres_krylov_space_dimension"].GetInt());
160 mprm.put(
"precond.usolver.solver.type", rParameters[
"velocity_block_preconditioner"][
"krylov_type"].GetString());
161 mprm.put(
"precond.usolver.solver.tol", rParameters[
"velocity_block_preconditioner"][
"tolerance"].GetDouble());
162 mprm.put(
"precond.usolver.solver.maxiter", rParameters[
"velocity_block_preconditioner"][
"max_iteration"].GetInt());
163 mprm.put(
"precond.usolver.precond.type", rParameters[
"velocity_block_preconditioner"][
"preconditioner_type"].GetString());
166 mprm.put(
"precond.psolver.solver.type", rParameters[
"pressure_block_preconditioner"][
"krylov_type"].GetString());
167 mprm.put(
"precond.psolver.solver.tol", rParameters[
"pressure_block_preconditioner"][
"tolerance"].GetDouble());
168 mprm.put(
"precond.psolver.solver.maxiter", rParameters[
"pressure_block_preconditioner"][
"max_iteration"].GetInt());
169 mprm.put(
"precond.psolver.precond.relax.type", rParameters[
"pressure_block_preconditioner"][
"preconditioner_type"].GetString());
170 mprm.put(
"precond.psolver.precond.coarse_enough", mCoarseEnough);
199 amgcl::mpi::communicator world ( the_comm );
200 if ( mVerbosity >=0 && world.rank == 0 ) {
201 std::cout <<
"World size: " << world.size << std::endl;
204 int chunk = rA.NumMyRows();
205 boost::iterator_range<double*> xrange ( rX.Values(), rX.Values() + chunk );
206 boost::iterator_range<double*> frange ( rB.Values(), rB.Values() + chunk );
208 if ( mVerbosity > 1 && world.rank == 0 ) {
209 write_json ( std::cout, mprm );
212 typedef amgcl::backend::builtin<double> Backend;
214 typedef amgcl::mpi::make_solver<
215 amgcl::mpi::schur_pressure_correction<
216 amgcl::mpi::make_solver<
217 amgcl::mpi::block_preconditioner<
218 amgcl::relaxation::as_preconditioner<Backend, amgcl::runtime::relaxation::wrapper>
220 amgcl::runtime::mpi::solver::wrapper<Backend>
222 amgcl::mpi::make_solver<
225 amgcl::runtime::mpi::coarsening::wrapper<Backend>,
226 amgcl::runtime::mpi::relaxation::wrapper<Backend>,
227 amgcl::runtime::mpi::direct::solver<double>,
228 amgcl::runtime::mpi::partition::wrapper<Backend>
230 amgcl::runtime::mpi::solver::wrapper<Backend>
233 amgcl::runtime::mpi::solver::wrapper<Backend>
236 mprm.put(
"precond.pmask",
static_cast<void*
>(&mPressureMask[0]));
237 mprm.put(
"precond.pmask_size", mPressureMask.size());
240 Solver
solve ( world, amgcl::adapter::map ( rA ), mprm );
246 std::tie ( iters, resid ) =
solve ( frange, xrange );
251 if ( rA.Comm().MyPID() == 0 ) {
252 if ( mVerbosity > 0 ) {
254 <<
"------- AMGCL -------\n" << std::endl
255 <<
"Iterations : " << iters << std::endl
256 <<
"Error : " << resid << std::endl;
322 int my_pid = rA.Comm().MyPID();
325 if(mPressureMask.size() !=
static_cast<unsigned int>(rA.NumMyRows()))
326 mPressureMask.resize( rA.NumMyRows(),
false );
334 if( it->GetSolutionStepValue ( PARTITION_INDEX ) == my_pid )
336 mPressureMask[
counter] = (it->GetVariable().Key() == PRESSURE);
340 if(it->GetVariable().Key() == PRESSURE)
346 std::cout <<
"MPI proc :" << my_pid <<
" npressures = " << npressures <<
" local rows = " << rA.NumMyRows();
349 KRATOS_ERROR <<
"pressure mask as a size " << mPressureMask.size() <<
" which does not correspond with the number of local rows:" << rA.NumMyRows() << std::endl;
354 void PrintInfo ( std::ostream& rOStream )
const override
356 rOStream <<
"AMGCL-MPI-Schur-Complement-Solver";
364 unsigned int mCoarseEnough = 5000;
366 std::vector< char > mPressureMask;
367 boost::property_tree::ptree mprm;
371 template<
class TSparseSpaceType,
class TDenseSpaceType,
class TReordererType>
374 TDenseSpaceType, TReordererType>& rThis )
376 rThis.PrintInfo ( rOStream );
377 rOStream << std::endl;
378 rThis.PrintData ( rOStream );
Definition: amgcl_mpi_schur_complement_solver.h:58
LinearSolver< TSparseSpaceType, TDenseSpaceType, TReordererType > BaseType
Definition: amgcl_mpi_schur_complement_solver.h:65
bool Solve(SparseMatrixType &rA, VectorType &rX, VectorType &rB) override
Definition: amgcl_mpi_schur_complement_solver.h:190
void ProvideAdditionalData(SparseMatrixType &rA, VectorType &rX, VectorType &rB, typename ModelPart::DofsArrayType &rDofSet, ModelPart &rModelPart) override
Definition: amgcl_mpi_schur_complement_solver.h:313
bool Solve(SparseMatrixType &rA, DenseMatrixType &rX, DenseMatrixType &rB) override
Definition: amgcl_mpi_schur_complement_solver.h:291
TSparseSpaceType::MatrixType SparseMatrixType
Definition: amgcl_mpi_schur_complement_solver.h:67
bool AdditionalPhysicalDataIsNeeded() override
Definition: amgcl_mpi_schur_complement_solver.h:302
virtual ~AmgclMPISchurComplementSolver()
Definition: amgcl_mpi_schur_complement_solver.h:180
TSparseSpaceType::VectorType VectorType
Definition: amgcl_mpi_schur_complement_solver.h:69
AmgclMPISchurComplementSolver(Parameters rParameters)
Definition: amgcl_mpi_schur_complement_solver.h:74
TDenseSpaceType::MatrixType DenseMatrixType
Definition: amgcl_mpi_schur_complement_solver.h:71
AmgclMPISchurComplementSolver & operator=(const AmgclMPISchurComplementSolver &Other)=delete
void PrintInfo(std::ostream &rOStream) const override
Print information about this object.
Definition: amgcl_mpi_schur_complement_solver.h:354
KRATOS_CLASS_POINTER_DEFINITION(AmgclMPISchurComplementSolver)
AmgclMPISchurComplementSolver(const AmgclMPISchurComplementSolver &Other)=delete
Base class for all the linear solvers in Kratos.
Definition: linear_solver.h:65
This class aims to manage meshes for multi-physics simulations.
Definition: model_part.h:77
This class provides to Kratos a data structure for I/O based on the standard of JSON.
Definition: kratos_parameters.h:59
double GetDouble() const
This method returns the double contained in the current Parameter.
Definition: kratos_parameters.cpp:657
int GetInt() const
This method returns the integer contained in the current Parameter.
Definition: kratos_parameters.cpp:666
void ValidateAndAssignDefaults(const Parameters &rDefaultParameters)
This function is designed to verify that the parameters under testing match the form prescribed by th...
Definition: kratos_parameters.cpp:1306
std::string GetString() const
This method returns the string contained in the current Parameter.
Definition: kratos_parameters.cpp:684
A sorted associative container similar to an STL set, but uses a vector to store pointers to its data...
Definition: pointer_vector_set.h:72
boost::indirect_iterator< typename TContainerType::iterator > iterator
Definition: pointer_vector_set.h:95
iterator begin()
Returns an iterator pointing to the beginning of the container.
Definition: pointer_vector_set.h:278
iterator end()
Returns an iterator pointing to the end of the container.
Definition: pointer_vector_set.h:314
#define KRATOS_THROW_ERROR(ExceptionType, ErrorMessage, MoreInfo)
Definition: define.h:77
#define KRATOS_CATCH(MoreInfo)
Definition: define.h:110
#define KRATOS_TRY
Definition: define.h:109
#define KRATOS_ERROR
Definition: exception.h:161
MPI_Comm GetMPICommFromEpetraComm(const Epetra_Comm &rEpetraComm)
Definition: trilinos_solver_utilities.cpp:32
REF: G. R. Cowper, GAUSSIAN QUADRATURE FORMULAS FOR TRIANGLES.
Definition: mesh_condition.cpp:21
std::ostream & operator<<(std::ostream &rOStream, const LinearMasterSlaveConstraint &rThis)
output stream function
Definition: linear_master_slave_constraint.h:432
def solve(A, rhs)
Definition: ode_solve.py:303
int counter
Definition: script_THERMAL_CORRECT.py:218