Commit c7a00014 authored by Dmitry Bagaev's avatar Dmitry Bagaev

Doxygen comments, PETSc copy bug fix, and other fixes

parent 57624c3d
......@@ -7,7 +7,6 @@ add_subdirectory(NonlinearSolver)
add_subdirectory(Autodiff)
add_subdirectory(Partitioner)
add_subdirectory(Misc)
add_subdirectory(Utils)
add_subdirectory(Headers)
......
......@@ -225,6 +225,10 @@ namespace INMOST
SolverUnsupportedOperation,
SolverUnknownParameter,
SolverNonExistentParameters,
SolverCopyNullException,
SolverCopyException,
SolverAssignNullException,
SolverAssignException,
/// The list of errors may occur in the Partitioner.
ErrorInPartitioner = 500,
......
......@@ -8,12 +8,18 @@
namespace INMOST
{
#define GUARD_MPI(x) {ierr = x; if( ierr != MPI_SUCCESS ) {char str[4096]; int len; MPI_Error_string(ierr,str,&len); std::cout << #x << " not successfull: " << str << std::endl; MPI_Abort(comm,-1000);}}
#define HASH_TABLE_SIZE 2048
class SolverInterface;
class SolverParameters;
/// Main class to set and solve linear system.
/// Solver class is used to set the coefficient Matrix, the right-hand side Vector
/// and the initial guess Vector, construct the preconditioner and Solve
/// the linear system.
///
/// Formally, Solver class is independent of INMOST::Mesh class.
/// @see Sparse::Matrix
/// @see Sparse::Vector
/// @see Sparse::Solve
class Solver
{
private:
......@@ -147,7 +153,7 @@ namespace INMOST
//void ScalarProd(Vector const & left, Vector const & right, INMOST_DATA_ENUM_TYPE index_begin, INMOST_DATA_ENUM_TYPE index_end, INMOST_DATA_REAL_TYPE & sum) const;
};
// Main constructor of the solver.
/// Main constructor of the solver.
/// @param solverName The solver name to be used for solution.
/// @param prefix The user specified name of the current solver.
/// @param comm Communicator for parallel data exchanges, MPI_COMM_WORLD by default.
......@@ -172,11 +178,9 @@ namespace INMOST
/// Initialize the stage of parallel solution.
/// If MPI is not initialized yet, then it will be initialized.
///
/// database file is used to pass parameters to PETSc and Trilinos packages.
/// if database file for is provided any changes through SetParameterEnum,
/// SetParameterReal would not be effective for PETSc and Trilinos packages.
/// Currently this database file provides directions for package-specific
/// files. In future it is supposed to set up parameters for internal solvers.
/// database file is used to pass parameters to Inner solvers, PETSc and Trilinos packages.
/// if database file for is provided any changes through SetParameter
/// would not be effective for PETSc and Trilinos packages.
/// @param argc The number of arguments transmitted to the function main.
/// @param argv The pointer to arguments transmitted to the function main.
/// @param database Usually the name of the file with the Solver parameters.
......@@ -186,7 +190,7 @@ namespace INMOST
/// @see Solver::isInitialized
///
/// Example of contents of the database file:
///
/// Main: database.xml
/// PETSc: petsc_options.txt
/// Trilinos_Ifpack: trilinos_ifpack_options.xml
/// Trilinos_ML: trilinos_ml_options.xml
......@@ -201,8 +205,10 @@ namespace INMOST
/// @see Solver::isFinalized
static void Finalize();
/// Checks the stage of parallel solution is initialized
static bool isInitialized();
/// Checks the stage of parallel solution is finalized
static bool isFinalized();
/// Set the matrix and construct the preconditioner.
......@@ -236,7 +242,73 @@ namespace INMOST
/// Clear all internal data of the current solver including matrix, preconditioner etc.
bool Clear();
/// Get the solver output parameter
/// @param name The name of solver's output parameter
/// @see Solver::SetParameter
std::string GetParameter(std::string name) const;
/// @param name The name of parameter
/// @param value The value of parameter
/// Set the solver parameter of the integer type.
///
/// Parameters:
/// - "maximum_iterations" - total number of iterations
/// - "schwartz_overlap" - number of overlapping levels for additive schwartz method,
/// works for:
/// INNER_ILU2, INNER_MLILUC
/// Trilinos_Aztec, Trilinos_Belos, Trilinos_ML, Trilinos_Ifpack
/// PETSc
/// - "gmres_substeps" - number of gmres steps performed after each bicgstab step,
/// works for:
/// INNER_ILU2, INNER_MLILUC
/// - "reorder_nonzeros" - place sparser rows at the beggining of matrix during reordering,
/// works for:
/// INNER_MLILUC
/// - "rescale_iterations" - number of iterations for two-side matrix rescaling,
/// works for:
/// INNER_ILU2, INNER_MLILUC
/// - "condition_estimation" - exploit condition estimation of inversed factors to adapt
/// drop and reuse tolerances,
/// works for:
/// INNER_MLILUC
/// - "adapt_ddpq_tolerance" - adapt ddpq tolerance depending from the complexity
/// of calculation of Schur complement,
/// works for:
/// INNER_MLILUC
/// Set the solver parameter of the real type.
///
/// Parameters:
/// - "absolute_tolerance" - iterative method will stop on i-th iteration
/// if ||A x(i)-b|| < absolute_tolerance
/// - "relative_tolerance" - iterative method will stop on i-th iteration
/// if ||A x(i)-b||/||A x(0) - b||
/// - "divergence_tolerance" - iterative method will fail if
/// ||A x(i) - b|| > divergence_tolerance
/// - "drop_tolerance" - tolerance for dropping values during incomplete factorization,
/// works for:
/// INNER_ILU2, INNER_MLILUC
/// Trilinos_Aztec, Trilinos_Ifpack
/// PETSc
/// - "reuse_tolerance" - tolerance for reusing values during incomplete factorization,
/// these values are used only during calculation of L and U factors
/// and/or Schur complement and discarded once factorization is done,
/// value should be less then "drop_tolerance",
/// typical value is drop_tolerance^2,
/// works for:
/// INNER_ILU2, INNER_MLILUC
/// - "ddpq_tolerance" - by this tolerance most diagonnaly-dominant elements will be selected
/// to form the next level of factorization, the closer the tolerance
/// is to one the smaller will be the level. Actual rule is:
/// A(i,j)/(sum(A(i,:))+sum(A(:,j))-A(i,j)) > ddpq_tolerance *
/// A(imax,jmax)/(sum(A(imax,:))+sum(A(:,jmax))-A(imax,jmax))
/// where on imax, jmax maximum is reached.
/// works for:
/// INNER_MLILUC
/// - "fill_level" - level of fill for ILU-type preconditioners,
/// works for:
/// INNER_ILU2 (if LFILL is defined in solver_ilu2.hpp)
/// Trilinos, Trilinos_Ifpack
/// @see Solver::GetParameter
void SetParameter(std::string name, std::string value);
/// Return the number of iterations performed by the last solution.
......@@ -267,15 +339,18 @@ namespace INMOST
/// Checks if solver available
/// @param name Solver name
/// @see Solver::getAvailableSolvers
static bool isSolverAvailable(std::string name);
/// Return the list of all available solvers
/// @see Solver::isSolverAvailable
static std::vector<std::string> getAvailableSolvers();
~Solver();
private:
/// Reads the parameters from database file stored in xml format.
static void parseXMLDatabase(const char* xml_database);
};
......
set(SOURCE
${SOURCE}
${CMAKE_CURRENT_SOURCE_DIR}/timer.cpp
${CMAKE_CURRENT_SOURCE_DIR}/xml.cpp
${SOURCE}
${CMAKE_CURRENT_SOURCE_DIR}/timer.cpp
${CMAKE_CURRENT_SOURCE_DIR}/xml.cpp
${CMAKE_CURRENT_SOURCE_DIR}/utils.cpp
PARENT_SCOPE
)
set(HEADER
${HEADER}
PARENT_SCOPE
${HEADER}
${CMAKE_CURRENT_SOURCE_DIR}/utils.h
PARENT_SCOPE
)
\ No newline at end of file
#include "Utils.h"
#include "utils.h"
namespace INMOST {
......
#include <inmost.h>
#define GUARD_MPI(x) {ierr = x; if( ierr != MPI_SUCCESS ) {char str[4096]; int len; MPI_Error_string(ierr,str,&len); std::cout << #x << " not successfull: " << str << std::endl; MPI_Abort(comm,-1000);}}
#define HASH_TABLE_SIZE 2048
namespace INMOST {
int comparator(const void *pa, const void *pb) {
......
#include "SolverMaster.h"
#include "solver_inner/solver_ilu2/SolverILU2.h"
#include "solver_inner/solver_ddpqiluc2/SolverDDPQILUC2.h"
#include "solver_inner/solver_mptiluc/SolverMPTILUC.h"
#include "solver_inner/solver_mptilu2/SolverMPTILU2.h"
#if defined(USE_SOLVER_PETSC)
#include "solver_petsc/SolverPETSc.h"
#endif
#if defined(USE_SOLVER_TRILINOS) && defined(USE_MPI)
#include "solver_trilinos/SolverTrilinos.h"
#include "solver_trilinos/solver_aztec/SolverTrilinosAztec.h"
#include "solver_trilinos/solver_belos/SolverTrilinosBelos.h"
#include "solver_trilinos/solver_ml/SolverTrilinosML.h"
#include "solver_trilinos/solver_ifpack/SolverTrilinosIfpack.h"
#endif
#if defined(USE_SOLVER_ANI)
#include "solver_ani/SolverANI.h"
#endif
#if defined(USE_SOLVER_SUPERLU)
#include "solver_superlu/SolverSUPERLU.h"
#endif
#if defined(HAVE_SOLVER_K3BIILU2)
#include "solver_k3biilu2/SolverK3BIILU2.h"
#endif
#if defined(HAVE_SOLVER_FCBIILU2)
#include "solver_fcbiilu2/SolverFCBIILU2.h"
#endif
namespace INMOST {
SolverInterface *SolverMaster::getSolver(std::string name) {
......
#ifndef INMOST_SOLVER_MASTER
#define INMOST_SOLVER_MASTER
#include <inmost_solver.h>
#include <Source/Solver/SolverInterface.h>
#include "SolverMaster.h"
#include "solver_inner/solver_ilu2/SolverILU2.h"
#include "solver_inner/solver_ddpqiluc2/SolverDDPQILUC2.h"
#include "solver_inner/solver_mptiluc/SolverMPTILUC.h"
#include "solver_inner/solver_mptilu2/SolverMPTILU2.h"
#if defined(USE_SOLVER_PETSC)
#include "solver_petsc/SolverPETSc.h"
#endif
#if defined(USE_SOLVER_TRILINOS) && defined(USE_MPI)
#include "solver_trilinos/SolverTrilinos.h"
#include "solver_trilinos/solver_aztec/SolverTrilinosAztec.h"
#include "solver_trilinos/solver_belos/SolverTrilinosBelos.h"
#include "solver_trilinos/solver_ml/SolverTrilinosML.h"
#include "solver_trilinos/solver_ifpack/SolverTrilinosIfpack.h"
#endif
#if defined(USE_SOLVER_ANI)
#include "solver_ani/SolverANI.h"
#endif
#if defined(USE_SOLVER_SUPERLU)
#include "solver_superlu/SolverSUPERLU.h"
#endif
#if defined(HAVE_SOLVER_K3BIILU2)
#include "solver_k3biilu2/SolverK3BIILU2.h"
#endif
#if defined(HAVE_SOLVER_FCBIILU2)
#include "solver_fcbiilu2/SolverFCBIILU2.h"
#endif
namespace INMOST {
class SolverMaster {
private:
public:
static SolverInterface *getSolver(std::string name);
static std::vector<std::string> getAvailableSolvers();
static bool isSolverAvailable(std::string name);
friend Solver::Solver(std::string solverName, std::string prefix, INMOST_MPI_Comm _comm);
friend Solver::Solver(const Solver &other);
friend void Solver::Initialize(int *argc, char ***argv, const char *database);
friend bool Solver::isSolverAvailable(std::string name);
friend std::vector<std::string> Solver::getAvailableSolvers();
};
}
......
#include <inmost.h>
#include "SolverMaster.h"
#include "Source/Utils/Utils.h"
#include "Source/Misc/utils.h"
namespace INMOST {
......
......@@ -7,7 +7,15 @@ namespace INMOST {
}
SolverInterface *SolverFCBIILU2::Copy(const SolverInterface *other) {
const SolverFCBIILU2 *fcother = static_cast<const SolverFCBIILU2 *>(other);
if (other == NULL) {
throw INMOST::SolverCopyNullException;
}
const SolverFCBIILU2 *fcother;
try {
fcother = dynamic_cast<const SolverFCBIILU2 *>(other);
} catch (...) {
throw INMOST::SolverCopyException;
}
SolverCopyDataFcbiilu2(&solver_data, fcother->solver_data, communicator);
if (fcother->matrix_data != NULL) {
MatrixCopyDataFcbiilu2(&matrix_data, fcother->matrix_data);
......@@ -17,7 +25,15 @@ namespace INMOST {
}
void SolverFCBIILU2::Assign(const SolverInterface *other) {
const SolverFCBIILU2 *fcother = static_cast<const SolverFCBIILU2 *>(other);
if (other == NULL) {
throw INMOST::SolverAssignNullException;
}
const SolverFCBIILU2 *fcother;
try {
fcother = dynamic_cast<const SolverFCBIILU2 *>(other);
} catch (...) {
throw INMOST::SolverAssignException;
}
SolverAssignDataFcbiilu2(solver_data, fcother->solver_data);
if (fcother->matrix_data != NULL) {
if (matrix_data != NULL) {
......
......@@ -2,7 +2,7 @@
#define INMOST_SOLVERINNER_H
#include "Source/Solver/SolverInterface.h"
#include "Source/Utils/Utils.h"
#include "Source/Misc/utils.h"
#include "solver_prototypes.hpp"
#include "solver_bcgsl.hpp"
......
......@@ -7,7 +7,15 @@ namespace INMOST {
}
SolverInterface *SolverK3BIILU2::Copy(const SolverInterface *other) {
const SolverK3BIILU2 *k3other = static_cast<const SolverK3BIILU2 *>(other);
if (other == NULL) {
throw INMOST::SolverCopyNullException;
}
const SolverK3BIILU2 *k3other;
try {
k3other = dynamic_cast<const SolverK3BIILU2 *>(other);
} catch (...) {
throw INMOST::SolverCopyException;
}
SolverCopyDataK3biilu2(&solver_data, k3other->solver_data, k3other->communicator);
if (k3other->matrix_data != NULL) {
MatrixCopyDataK3biilu2(&matrix_data, k3other->matrix_data);
......@@ -17,7 +25,15 @@ namespace INMOST {
}
void SolverK3BIILU2::Assign(const SolverInterface *other) {
const SolverK3BIILU2 *k3other = static_cast<const SolverK3BIILU2 *>(other);
if (other == NULL) {
throw INMOST::SolverAssignNullException;
}
const SolverK3BIILU2 *k3other;
try {
k3other = dynamic_cast<const SolverK3BIILU2 *>(other);
} catch (...) {
throw INMOST::SolverAssignException;
}
SolverAssignDataK3biilu2(solver_data, k3other->solver_data);
if (k3other->matrix_data != NULL) {
if (matrix_data != NULL) {
......
......@@ -19,8 +19,15 @@ namespace INMOST {
}
SolverInterface *SolverPETSc::Copy(const SolverInterface *other) {
petscSolversCount++;
const SolverPETSc *solver = static_cast<const SolverPETSc *>(other);
if (other == NULL) {
throw INMOST::SolverCopyNullException;
}
const SolverPETSc *solver;
try {
solver = dynamic_cast<const SolverPETSc *>(other);
} catch (...) {
throw INMOST::SolverCopyException;
}
this->ksp = NULL;
this->matrix = NULL;
......@@ -33,7 +40,15 @@ namespace INMOST {
}
void SolverPETSc::Assign(const SolverInterface *other) {
const SolverPETSc *other_solver = static_cast<const SolverPETSc *>(other);
if (other == NULL) {
throw INMOST::SolverAssignNullException;
}
const SolverPETSc *other_solver;
try {
other_solver = dynamic_cast<const SolverPETSc *>(other);
} catch (...) {
throw INMOST::SolverAssignException;
}
this->parametersFile = other_solver->parametersFile;
SolverAssignDataPetsc(ksp, other_solver->ksp);
if (other_solver->matrix != NULL) {
......
......@@ -4,7 +4,7 @@
#include "petsc.h"
#include "solver_petsc.h"
#include "Source/Solver/SolverInterface.h"
#include "Source/Utils/Utils.h"
#include "Source/Misc/utils.h"
namespace INMOST {
......
......@@ -8,7 +8,7 @@
#include <inmost.h>
#include "Source/Solver/SolverInterface.h"
#include "Source/Utils/Utils.h"
#include "Source/Misc/utils.h"
#if defined(USE_MPI)
......
set(SOURCE
${SOURCE}
${CMAKE_CURRENT_SOURCE_DIR}/Utils.cpp
PARENT_SCOPE
)
set(HEADER
${HEADER}
${CMAKE_CURRENT_SOURCE_DIR}/Utils.h
PARENT_SCOPE
)
\ No newline at end of file
......@@ -56,6 +56,8 @@ endif()
if(USE_SOLVER_PETSC)
add_test(NAME solver_test000_serial_petsc COMMAND $<TARGET_FILE:solver_test000> 0 petsc)
add_test(NAME solver_test000_copy_serial_petsc COMMAND $<TARGET_FILE:solver_test000> 0 petsc 1)
add_test(NAME solver_test000_assign_serial_petsc COMMAND $<TARGET_FILE:solver_test000> 0 petsc 2)
endif()
if(USE_SOLVER_TRILINOS AND USE_MPI)
......@@ -93,6 +95,8 @@ endif()
if(USE_SOLVER_PETSC)
add_test(NAME solver_test000_parallel_normal_petsc COMMAND ${MPIEXEC} -np 4 $<TARGET_FILE:solver_test000> 0 petsc)
add_test(NAME solver_test000_copy_parallel_normal_petsc COMMAND ${MPIEXEC} -np 4 $<TARGET_FILE:solver_test000> 0 petsc 1)
add_test(NAME solver_test000_assign_parallel_normal_petsc COMMAND ${MPIEXEC} -np 4 $<TARGET_FILE:solver_test000> 0 petsc 2)
#add_test(NAME solver_test000_parallel_permute1_petsc COMMAND ${MPIEXEC} -np 4 $<TARGET_FILE:solver_test000> 1 2)
#add_test(NAME solver_test000_parallel_permute2_petsc COMMAND ${MPIEXEC} -np 4 $<TARGET_FILE:solver_test000> 2 2)
endif()
......
......@@ -7,10 +7,8 @@ using namespace INMOST;
int main(int argc,char ** argv)
{
int permut = 0;
int copy_test = 0;
std::string solver = "inner_ilu2";
// 0 - INNER_ILU2, 1 - INNER_MLILUC, 2 - PETSc
// 3 - Trilinos_Aztec, 4 - Trilinos_Ifpack,
// 5 - Trilinos_ML, 6 - Trilinos_Belos, 7 - ANI
int rank,procs,newrank;
Solver::Initialize(&argc,&argv,"database.txt"); // Initialize the solver and MPI activity
......@@ -24,6 +22,7 @@ int main(int argc,char ** argv)
if (argc > 1) permut = atoi(argv[1]);
if (argc > 2) solver = std::string(argv[2]);
if (argc > 3) copy_test = atoi(argv[3]);
if (permut < procs) newrank = (rank + permut) % procs;
else newrank = (permut - rank) % procs;
......@@ -32,7 +31,13 @@ int main(int argc,char ** argv)
{
Solver S(solver); // Specify the linear solver
Solver &actualSolver = S;
//Copy test
if (copy_test == 1) {
Solver copySolver(S);
actualSolver = copySolver;
}
Sparse::Matrix A; // Declare the matrix of the linear system to be solved
Sparse::Vector x,b; // Declare the solution and the right-hand side vectors
......@@ -52,13 +57,21 @@ int main(int argc,char ** argv)
b[i] = i;
x[i] = 0.1;
}
if (rank==0) std::cout << "next call S.SetMatrix(A);" << std::endl;
S.SetMatrix(A); // Compute the preconditioner for the original matrix
if (rank==0) std::cout << "next call S.Solve(b,x);" << std::endl;
if( !S.Solve(b,x) ) // Solve the linear system with the previously computted preconditioner
if (rank==0) std::cout << "next call SetMatrix(A);" << std::endl;
actualSolver.SetMatrix(A); // Compute the preconditioner for the original matrix
if (rank==0) std::cout << "next call Solve(b,x);" << std::endl;
//Assign test
if (copy_test == 2) {
Solver assignSolver(solver);
assignSolver = Solver(actualSolver);
actualSolver = assignSolver;
}
if( !actualSolver.Solve(b,x) ) // Solve the linear system with the previously computted preconditioner
{
if( rank == 0 )
std::cout << S.ReturnReason() << std::endl;
std::cout << actualSolver.ReturnReason() << std::endl;
#if defined(USE_MPI)
MPI_Abort(MPI_COMM_WORLD,-1);
#else
......@@ -98,6 +111,7 @@ int main(int argc,char ** argv)
//A.Save("A.mtx");
}
MPI_Barrier(MPI_COMM_WORLD);
Solver::Finalize(); // Finalize solver and close MPI activity
return 0;
}
Markdown is supported
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