Commit 9915f5f8 authored by Dmitry Bagaev's avatar Dmitry Bagaev
Browse files

Improvements in Solver

1) Parameters parsing in inner solvers
2) Parameters parsing in trillions solvers
3) Added xml parsing test
4) Trilinos without mpi support will not compile, disable trillions
solvers if compiling without mpi
parent 57c8d057
......@@ -2,10 +2,12 @@
#define INMOST_SOLVERINNER_H
#include "inmost_solver_interface.h"
#include "inmost_utils.h"
#include "solver_prototypes.hpp"
#include "solver_bcgsl.hpp"
namespace INMOST {
class SolverInner : public SolverInterface {
......@@ -13,8 +15,11 @@ namespace INMOST {
Sparse::Matrix *matrix;
KSOLVER *solver;
Solver::OrderInfo info;
INMOST_DATA_ENUM_TYPE iters, scale_iters, condest, ddpqatol, overlap, ell, reorder_nnz, fill;
INMOST_DATA_REAL_TYPE atol, rtol, dtol, ddpqtol, tau, tau2;
public:
SolverInner(SolverParameters &parameters);
SolverInner();
SolverInner(const SolverInterface *other);
......@@ -30,6 +35,10 @@ namespace INMOST {
virtual bool isMatrixSet();
virtual std::string GetParameter(std::string name) const;
virtual void SetParameter(std::string name, std::string value);
virtual const INMOST_DATA_ENUM_TYPE Iterations() const;
virtual const INMOST_DATA_REAL_TYPE Residual() const;
......
......@@ -2,13 +2,13 @@
namespace INMOST {
SolverDDPQILUC2::SolverDDPQILUC2(SolverParameters &parameters): SolverInner(parameters) {
SolverDDPQILUC2::SolverDDPQILUC2() {
Method *preconditioner = new ILUC_preconditioner(info);
solver = new KSOLVER(preconditioner, info);
matrix = NULL;
}
SolverDDPQILUC2::SolverDDPQILUC2(const SolverInterface *other): SolverInner(other) {
SolverDDPQILUC2::SolverDDPQILUC2(const SolverInterface *other) {
//You should not really want to copy solver's information
throw INMOST::SolverUnsupportedOperation;
}
......@@ -18,19 +18,19 @@ namespace INMOST {
delete matrix;
}
matrix = new Sparse::Matrix(A);
info.PrepareMatrix(*matrix, parameters.get<INMOST_DATA_ENUM_TYPE>("additive_schwartz_overlap"));
info.PrepareMatrix(*matrix, overlap);
solver->ReplaceMAT(*matrix);
solver->RealParameter(":tau") = parameters.get<INMOST_DATA_REAL_TYPE>("drop_tolerance");
solver->RealParameter(":tau2") = parameters.get<INMOST_DATA_REAL_TYPE>("reuse_tolerance");
solver->EnumParameter(":scale_iters") = parameters.get<INMOST_DATA_ENUM_TYPE>("rescale_iterations");
solver->RealParameter(":ddpq_tau") = parameters.get<INMOST_DATA_REAL_TYPE>("ddpq_tolerance");
solver->EnumParameter(":reorder_nnz") = parameters.get<INMOST_DATA_ENUM_TYPE>("reorder_nonzero");
solver->EnumParameter(":estimator") = parameters.get<INMOST_DATA_ENUM_TYPE>("condition_estimation");
solver->EnumParameter(":ddpq_tau_adapt") = parameters.get<INMOST_DATA_ENUM_TYPE>("adapt_ddpq_tolerance");
solver->RealParameter(":tau") = tau;
solver->RealParameter(":tau2") = tau2;
solver->EnumParameter(":scale_iters") = scale_iters;
solver->RealParameter(":ddpq_tau") = ddpqtol;
solver->EnumParameter(":reorder_nnz") = reorder_nnz;
solver->EnumParameter(":estimator") = condest;
solver->EnumParameter(":ddpq_tau_adapt") = ddpqatol;
if (sizeof(KSOLVER) == sizeof(BCGSL_solver)) {
solver->EnumParameter("levels") = parameters.get<INMOST_DATA_ENUM_TYPE>("gmres_substeps");
solver->EnumParameter("levels") = ell;
}
if (!solver->isInitialized()) {
......
......@@ -10,7 +10,7 @@ namespace INMOST {
class SolverDDPQILUC2 : public SolverInner {
public:
SolverDDPQILUC2(SolverParameters &parameters);
SolverDDPQILUC2();
SolverDDPQILUC2(const SolverInterface *other);
......
......@@ -2,13 +2,13 @@
namespace INMOST {
SolverILU2::SolverILU2(SolverParameters &parameters): SolverInner(parameters) {
SolverILU2::SolverILU2() {
Method *preconditioner = new ILU2_preconditioner(info);
solver = new KSOLVER(preconditioner, info);
matrix = NULL;
}
SolverILU2::SolverILU2(const SolverInterface *other): SolverInner(other) {
SolverILU2::SolverILU2(const SolverInterface *other) {
//You should not really want to copy solver's information
throw INMOST::SolverUnsupportedOperation;
}
......@@ -18,16 +18,16 @@ namespace INMOST {
delete matrix;
}
matrix = new Sparse::Matrix(A);
info.PrepareMatrix(*matrix, parameters.get<INMOST_DATA_ENUM_TYPE>("additive_schwartz_overlap"));
info.PrepareMatrix(*matrix, overlap);
solver->ReplaceMAT(*matrix);
solver->RealParameter(":tau") = parameters.get<INMOST_DATA_REAL_TYPE>("drop_tolerance");
solver->RealParameter(":tau2") = parameters.get<INMOST_DATA_REAL_TYPE>("reuse_tolerance");
solver->EnumParameter(":scale_iters") = parameters.get<INMOST_DATA_ENUM_TYPE>("rescale_iterations");
solver->EnumParameter(":fill") = parameters.get<INMOST_DATA_ENUM_TYPE>("fill_level");
solver->RealParameter(":tau") = tau;
solver->RealParameter(":tau2") = tau2;
solver->EnumParameter(":scale_iters") = scale_iters;
solver->EnumParameter(":fill") = fill;
if (sizeof(KSOLVER) == sizeof(BCGSL_solver)) {
solver->EnumParameter("levels") = parameters.get<INMOST_DATA_ENUM_TYPE>("gmres_substeps");
solver->EnumParameter("levels") = ell;
}
if (!solver->isInitialized()) {
......
......@@ -9,7 +9,7 @@ namespace INMOST {
class SolverILU2 : public SolverInner {
public:
SolverILU2(SolverParameters &parameters);
SolverILU2();
SolverILU2(const SolverInterface *other);
......
......@@ -2,13 +2,13 @@
namespace INMOST {
SolverMPTILU2::SolverMPTILU2(SolverParameters &parameters): SolverInner(parameters) {
SolverMPTILU2::SolverMPTILU2() {
Method *preconditioner = new MTILU2_preconditioner(info);
solver = new KSOLVER(preconditioner, info);
matrix = NULL;
}
SolverMPTILU2::SolverMPTILU2(const SolverInterface *other): SolverInner(other) {
SolverMPTILU2::SolverMPTILU2(const SolverInterface *other) {
//You should not really want to copy solver's information
throw INMOST::SolverUnsupportedOperation;
}
......@@ -18,15 +18,15 @@ namespace INMOST {
delete matrix;
}
matrix = new Sparse::Matrix(A);
info.PrepareMatrix(*matrix, parameters.get<INMOST_DATA_ENUM_TYPE>("additive_schwartz_overlap"));
info.PrepareMatrix(*matrix, overlap);
solver->ReplaceMAT(*matrix);
solver->RealParameter(":tau") = parameters.get<INMOST_DATA_REAL_TYPE>("drop_tolerance");
solver->RealParameter(":tau2") = parameters.get<INMOST_DATA_REAL_TYPE>("reuse_tolerance");
solver->EnumParameter(":scale_iters") = parameters.get<INMOST_DATA_ENUM_TYPE>("rescale_iterations");
solver->RealParameter(":tau") = tau;
solver->RealParameter(":tau2") = tau2;
solver->EnumParameter(":scale_iters") = scale_iters;
if (sizeof(KSOLVER) == sizeof(BCGSL_solver)) {
solver->EnumParameter("levels") = parameters.get<INMOST_DATA_ENUM_TYPE>("gmres_substeps");
solver->EnumParameter("levels") = ell;
}
if (!solver->isInitialized()) {
......
......@@ -10,7 +10,7 @@ namespace INMOST {
class SolverMPTILU2 : public SolverInner {
public:
SolverMPTILU2(SolverParameters &parameters);
SolverMPTILU2();
SolverMPTILU2(const SolverInterface *other);
......
......@@ -2,13 +2,13 @@
namespace INMOST {
SolverMPTILUC::SolverMPTILUC(SolverParameters &parameters): SolverInner(parameters) {
SolverMPTILUC::SolverMPTILUC() {
Method *preconditioner = new MTILUC_preconditioner(info);
solver = new KSOLVER(preconditioner, info);
matrix = NULL;
}
SolverMPTILUC::SolverMPTILUC(const SolverInterface *other): SolverInner(other) {
SolverMPTILUC::SolverMPTILUC(const SolverInterface *other) {
//You should not really want to copy solver's information
throw INMOST::SolverUnsupportedOperation;
}
......@@ -18,16 +18,16 @@ namespace INMOST {
delete matrix;
}
matrix = new Sparse::Matrix(A);
info.PrepareMatrix(*matrix, parameters.get<INMOST_DATA_ENUM_TYPE>("additive_schwartz_overlap"));
info.PrepareMatrix(*matrix, overlap);
solver->ReplaceMAT(*matrix);
solver->RealParameter(":tau") = parameters.get<INMOST_DATA_REAL_TYPE>("drop_tolerance");
solver->RealParameter(":tau2") = parameters.get<INMOST_DATA_REAL_TYPE>("reuse_tolerance");
solver->EnumParameter(":scale_iters") = parameters.get<INMOST_DATA_ENUM_TYPE>("rescale_iterations");
solver->EnumParameter(":estimator") = parameters.get<INMOST_DATA_ENUM_TYPE>("condition_estimation");
solver->RealParameter(":tau") = tau;
solver->RealParameter(":tau2") = tau2;
solver->EnumParameter(":scale_iters") = scale_iters;
solver->EnumParameter(":estimator") = condest;
if (sizeof(KSOLVER) == sizeof(BCGSL_solver)) {
solver->EnumParameter("levels") = parameters.get<INMOST_DATA_ENUM_TYPE>("gmres_substeps");
solver->EnumParameter("levels") = ell;
}
if (!solver->isInitialized()) {
......@@ -36,14 +36,12 @@ namespace INMOST {
}
bool SolverMPTILUC::Solve(Sparse::Vector &RHS, Sparse::Vector &SOL) {
solver->EnumParameter("maxits") = parameters.get<INMOST_DATA_ENUM_TYPE>("maximum_iterations");
solver->RealParameter("rtol") = parameters.get<INMOST_DATA_REAL_TYPE>("relative_tolerance");
solver->RealParameter("atol") = parameters.get<INMOST_DATA_REAL_TYPE>("absolute_tolerance");
solver->RealParameter("divtol") = parameters.get<INMOST_DATA_REAL_TYPE>("divergence_tolerance");
solver->EnumParameter("maxits") = iters;
solver->RealParameter("rtol") = rtol;
solver->RealParameter("atol") = atol;
solver->RealParameter("divtol") = dtol;
bool solve = solver->Solve(RHS, SOL);
parameters.set("condition_number_L", std::to_string(solver->RealParameter(":condition_number_L")));
parameters.set("condition_number_U", std::to_string(solver->RealParameter(":condition_number_U")));
return solve;
}
......
......@@ -9,7 +9,7 @@ namespace INMOST {
class SolverMPTILUC : public SolverInner {
public:
SolverMPTILUC(SolverParameters &parameters);
SolverMPTILUC();
SolverMPTILUC(const SolverInterface *other);
......
......@@ -2,7 +2,7 @@ if (USE_MPI)
if (EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/solver_k3biilu2.h" AND EXISTS
"${CMAKE_CURRENT_SOURCE_DIR}/solver_k3biilu2.cpp" AND EXISTS
"${CMAKE_CURRENT_SOURCE_DIR}/k3d.h" AND EXISTS
"${CMAKE_CURRENT_SOURCE_DIR}/k3d.cpp")
"${CMAKE_CURRENT_SOURCE_DIR}/k3d.cpp" AND USE_SOLVER_METIS)
set(SOLVER_DEFINITIONS ${SOLVER_DEFINITIONS} -DHAVE_SOLVER_K3BIILU2 PARENT_SCOPE)
set(HAVE_SOLVER_K3BIILU2 TRUE PARENT_SCOPE)
set(HEADER ${HEADER}
......
......@@ -2,163 +2,174 @@
namespace INMOST {
SolverK3BIILU2::SolverK3BIILU2(SolverParameters &parameters): SolverInterface(parameters) {
}
SolverK3BIILU2::SolverK3BIILU2(const SolverInterface *other): SolverInterface(other) {
const SolverK3BIILU2 *k3other = static_cast<const SolverK3BIILU2 *>(other);
SolverCopyDataK3biilu2(&solver_data, k3other->solver_data, k3other->communicator);
if (k3other->matrix_data != NULL) {
MatrixCopyDataK3biilu2(&matrix_data, k3other->matrix_data);
SolverSetMatrixK3biilu2(solver_data, matrix_data, false, false);
}
}
void SolverK3BIILU2::Assign(const SolverInterface *other) {
const SolverK3BIILU2 *k3other = static_cast<const SolverK3BIILU2 *>(other);
SolverAssignDataK3biilu2(solver_data, k3other->solver_data);
if (k3other->matrix_data != NULL) {
if (matrix_data != NULL ) {
MatrixAssignDataK3biilu2(matrix_data, k3other->matrix_data);
} else {
MatrixCopyDataK3biilu2(&matrix_data, k3other->matrix_data);
}
SolverSetMatrixK3biilu2(solver_data, matrix_data, false, false);
}
}
void SolverK3BIILU2::Initialize(int *argc, char ***argv, const char *parameters_file, std::string prefix) {
SolverInitDataK3biilu2(&solver_data, communicator, prefix.c_str());
SolverInitializeK3biilu2(argc, argv, parameters_file);
}
void SolverK3BIILU2::SetMatrix(Sparse::Matrix &A, bool ModifiedPattern, bool OldPreconditioner) {
bool modified_pattern = ModifiedPattern;
//~ if( A.comm != comm ) throw DifferentCommunicatorInSolver;
if (matrix_data == NULL) {
MatrixInitDataK3biilu2(&matrix_data, A.GetCommunicator(), A.GetName().c_str());
modified_pattern = true;
}
if (modified_pattern) {
global_size = local_size = A.Size();
MatrixDestroyDataK3biilu2(&matrix_data);
MatrixInitDataK3biilu2(&matrix_data, A.GetCommunicator(), A.GetName().c_str());
INMOST_DATA_ENUM_TYPE nnz = 0, k = 0, q = 1, shift = 0;
int nproc, myid;
SolverK3BIILU2::SolverK3BIILU2() {
}
SolverK3BIILU2::SolverK3BIILU2(const SolverInterface *other) {
const SolverK3BIILU2 *k3other = static_cast<const SolverK3BIILU2 *>(other);
SolverCopyDataK3biilu2(&solver_data, k3other->solver_data, k3other->communicator);
if (k3other->matrix_data != NULL) {
MatrixCopyDataK3biilu2(&matrix_data, k3other->matrix_data);
SolverSetMatrixK3biilu2(solver_data, matrix_data, false, false);
}
}
void SolverK3BIILU2::Assign(const SolverInterface *other) {
const SolverK3BIILU2 *k3other = static_cast<const SolverK3BIILU2 *>(other);
SolverAssignDataK3biilu2(solver_data, k3other->solver_data);
if (k3other->matrix_data != NULL) {
if (matrix_data != NULL) {
MatrixAssignDataK3biilu2(matrix_data, k3other->matrix_data);
} else {
MatrixCopyDataK3biilu2(&matrix_data, k3other->matrix_data);
}
SolverSetMatrixK3biilu2(solver_data, matrix_data, false, false);
}
}
void SolverK3BIILU2::Initialize(int *argc, char ***argv, const char *parameters_file, std::string prefix) {
SolverInitDataK3biilu2(&solver_data, communicator, prefix.c_str());
SolverInitializeK3biilu2(argc, argv, parameters_file);
}
void SolverK3BIILU2::SetMatrix(Sparse::Matrix &A, bool ModifiedPattern, bool OldPreconditioner) {
bool modified_pattern = ModifiedPattern;
//~ if( A.comm != comm ) throw DifferentCommunicatorInSolver;
if (matrix_data == NULL) {
MatrixInitDataK3biilu2(&matrix_data, A.GetCommunicator(), A.GetName().c_str());
modified_pattern = true;
}
if (modified_pattern) {
global_size = local_size = A.Size();
MatrixDestroyDataK3biilu2(&matrix_data);
MatrixInitDataK3biilu2(&matrix_data, A.GetCommunicator(), A.GetName().c_str());
INMOST_DATA_ENUM_TYPE nnz = 0, k = 0, q = 1, shift = 0;
int nproc, myid;
#if defined(USE_MPI)
MPI_Comm_size(A.GetCommunicator(), &nproc);
MPI_Comm_rank(A.GetCommunicator(), &myid);
MPI_Comm_size(A.GetCommunicator(), &nproc);
MPI_Comm_rank(A.GetCommunicator(), &myid);
#else
nproc = 1;
myid = 0;
nproc = 1;
myid = 0;
#endif
int * ibl = (int *) malloc(sizeof(int) * (nproc + 1));
ibl[0] = 0;
int n = A.Size();
int *ibl = (int *) malloc(sizeof(int) * (nproc + 1));
ibl[0] = 0;
int n = A.Size();
#if defined(USE_MPI)
INMOST_DATA_ENUM_TYPE mbeg,mend;
A.GetInterval(mbeg, mend);
n = mend - mbeg;
int block_end = mend;
MPI_Allgather(&block_end, 1, MPI_INT, &ibl[1], 1, MPI_INT, A.GetCommunicator());
INMOST_DATA_ENUM_TYPE mbeg,mend;
A.GetInterval(mbeg, mend);
n = mend - mbeg;
int block_end = mend;
MPI_Allgather(&block_end, 1, MPI_INT, &ibl[1], 1, MPI_INT, A.GetCommunicator());
#else
ibl[1] = n;
ibl[1] = n;
#endif
int * ia = (int *) malloc(sizeof(int) * (n + 1));
for(Sparse::Matrix::iterator it = A.Begin(); it != A.End(); it++) {
nnz += it->Size();
}
int * ja = (int *) malloc(sizeof(int) * nnz);
double * values = (double *) malloc(sizeof(double) * nnz);
ia[0] = shift;
for(Sparse::Matrix::iterator it = A.Begin(); it != A.End(); it++) {
for(Sparse::Row::iterator jt = it->Begin(); jt != it->End(); jt++) {
ja[k] = jt->first + 0;
values[k] = jt->second;
//std::cout<<"# q="<<q<<" k="<<k<<" ja="<<ja[k]<<" a="<<values[k]<<std::endl;//db!
k++;
}
shift += it->Size();
ia[q++] = shift;
}
MatrixFillK3biilu2(matrix_data,n,nproc,ibl,ia,ja,values);
} else {
INMOST_DATA_ENUM_TYPE nnz = 0, k = 0;
for(Sparse::Matrix::iterator it = A.Begin(); it != A.End(); it++) {
nnz += it->Size();
}
double * values = (double *) malloc(sizeof(double) * nnz);
k = 0;
for(Sparse::Matrix::iterator it = A.Begin(); it != A.End(); it++) {
for(Sparse::Row::iterator jt = it->Begin(); jt != it->End(); jt++) {
values[k++] = jt->second;
}
}
MatrixFillValuesK3biilu2(matrix_data,values);
}
MatrixFinalizeK3biilu2(matrix_data);
SolverSetMatrixK3biilu2(solver_data, matrix_data, modified_pattern, OldPreconditioner);
}
bool SolverK3BIILU2::Solve(INMOST::Sparse::Vector &RHS, INMOST::Sparse::Vector &SOL) {
INMOST_DATA_ENUM_TYPE vbeg, vend;
int *ia = (int *) malloc(sizeof(int) * (n + 1));
for (Sparse::Matrix::iterator it = A.Begin(); it != A.End(); it++) {
nnz += it->Size();
}
int *ja = (int *) malloc(sizeof(int) * nnz);
double *values = (double *) malloc(sizeof(double) * nnz);
ia[0] = shift;
for (Sparse::Matrix::iterator it = A.Begin(); it != A.End(); it++) {
for (Sparse::Row::iterator jt = it->Begin(); jt != it->End(); jt++) {
ja[k] = jt->first + 0;
values[k] = jt->second;
//std::cout<<"# q="<<q<<" k="<<k<<" ja="<<ja[k]<<" a="<<values[k]<<std::endl;//db!
k++;
}
shift += it->Size();
ia[q++] = shift;
}
MatrixFillK3biilu2(matrix_data, n, nproc, ibl, ia, ja, values);
} else {
INMOST_DATA_ENUM_TYPE nnz = 0, k = 0;
for (Sparse::Matrix::iterator it = A.Begin(); it != A.End(); it++) {
nnz += it->Size();
}
double *values = (double *) malloc(sizeof(double) * nnz);
k = 0;
for (Sparse::Matrix::iterator it = A.Begin(); it != A.End(); it++) {
for (Sparse::Row::iterator jt = it->Begin(); jt != it->End(); jt++) {
values[k++] = jt->second;
}
}
MatrixFillValuesK3biilu2(matrix_data, values);
}
MatrixFinalizeK3biilu2(matrix_data);
SolverSetMatrixK3biilu2(solver_data, matrix_data, modified_pattern, OldPreconditioner);
}
bool SolverK3BIILU2::Solve(INMOST::Sparse::Vector &RHS, INMOST::Sparse::Vector &SOL) {
INMOST_DATA_ENUM_TYPE vbeg, vend;
RHS.GetInterval(vbeg, vend);
void *rhs_data = NULL;
void *solution_data = NULL;
VectorInitDataK3biilu2(&rhs_data, RHS.GetCommunicator(), RHS.GetName().c_str());
VectorPreallocateK3biilu2(rhs_data, local_size);
VectorInitDataK3biilu2(&solution_data, SOL.GetCommunicator(), SOL.GetName().c_str());
VectorPreallocateK3biilu2(solution_data,local_size);
VectorFillK3biilu2(rhs_data, &RHS[vbeg]);
VectorFinalizeK3biilu2(rhs_data);
VectorFillK3biilu2(solution_data, &SOL[vbeg]);
VectorFinalizeK3biilu2(solution_data);
bool result = SolverSolveK3biilu2(solver_data, rhs_data, solution_data);
if (result) VectorLoadK3biilu2(solution_data, &SOL[vbeg]);
return result;
}
bool SolverK3BIILU2::Clear() {
if (matrix_data != NULL) {
MatrixDestroyDataK3biilu2(&matrix_data);
}
SolverDestroyDataK3biilu2(&solver_data);
return true;
}
bool SolverK3BIILU2::isMatrixSet() {
return matrix_data != NULL;
}
const INMOST_DATA_ENUM_TYPE SolverK3BIILU2::Iterations() const {
return static_cast<INMOST_DATA_ENUM_TYPE>(SolverIterationNumberK3biilu2(solver_data));
}
const INMOST_DATA_REAL_TYPE SolverK3BIILU2::Residual() const {
return SolverResidualNormK3biilu2(solver_data);
}
const std::string SolverK3BIILU2::ReturnReason() const {
return "Unspecified for K3BIILU2";
}
const std::string SolverK3BIILU2::SolverName() const {
return "k3biilu2";
}
void SolverK3BIILU2::Finalize() {
SolverFinalizeK3biilu2();
}
SolverK3BIILU2::~SolverK3BIILU2() {
this->Clear();
}
void *rhs_data = NULL;
void *solution_data = NULL;
VectorInitDataK3biilu2(&rhs_data, RHS.GetCommunicator(), RHS.GetName().c_str());
VectorPreallocateK3biilu2(rhs_data, local_size);
VectorInitDataK3biilu2(&solution_data, SOL.GetCommunicator(), SOL.GetName().c_str());
VectorPreallocateK3biilu2(solution_data, local_size);
VectorFillK3biilu2(rhs_data, &RHS[vbeg]);
VectorFinalizeK3biilu2(rhs_data);
VectorFillK3biilu2(solution_data, &SOL[vbeg]);
VectorFinalizeK3biilu2(solution_data);
bool result = SolverSolveK3biilu2(solver_data, rhs_data, solution_data);
if (result) VectorLoadK3biilu2(solution_data, &SOL[vbeg]);
return result;
}
bool SolverK3BIILU2::Clear() {
if (matrix_data != NULL) {
MatrixDestroyDataK3biilu2(&matrix_data);
}
SolverDestroyDataK3biilu2(&solver_data);
return true;
}
bool SolverK3BIILU2::isMatrixSet() {
return matrix_data != NULL;
}
std::string SolverK3BIILU2::GetParameter(std::string name) const {
std::cout << "SolverK3BIILU2::GetParameter unsupported operation" << std::endl;
//throw INMOST::SolverUnsupportedOperation;
return "";