Commit d55b1e90 authored by Igor Konshin's avatar Igor Konshin
Browse files

new linear solver k3biilu2 is added

parent 9a92cf91
......@@ -15,22 +15,24 @@ int main(int argc, char ** argv)
int rank,procs;
if( argc < 3 )
{
std::cout << "Usage: " << argv[0] << " method_number<0:INNER_ILU2,1:INNER_MLILUC,2:PETSc,3:Trilinos_Aztec,4:Trilinos_Belos,5:Trilinos_Ifpack,6:Trilinos_ML,7:ANI> matrix.mtx [right_hand_side.rhs] [solver_options.txt]" << std::endl;
std::cout << "Usage: " << argv[0] << " method_number<0:INNER_ILU2,1:INNER_DDPQILUC,2:INNER_MPTILUC,3:INNER_MPTILU2,4:Trilinos_Aztec,5:Trilinos_Belos,6:Trilinos_ML,7:Trilinos_Ifpack,8:PETSc,9:ANI,10:FCBIILU2,11:K3BIILU2> matrix.mtx [right_hand_side.rhs] [solver_options.txt]" << std::endl;
return -1;
}
Solver::Type type;
switch(atoi(argv[1]))
{
case 0: type = Solver::INNER_ILU2; break;
case 1: type = Solver::INNER_DDPQILUC; break;
case 2: type = Solver::PETSc; break;
case 3: type = Solver::Trilinos_Aztec; break;
case 4: type = Solver::Trilinos_Belos; break;
case 5: type = Solver::Trilinos_Ifpack; break;
case 6: type = Solver::Trilinos_ML; break;
case 7: type = Solver::ANI; break;
case 8: type = Solver::INNER_MPTILUC; break;
case 9: type = Solver::INNER_MPTILU2; break;
case 0: type = Solver::INNER_ILU2; break;
case 1: type = Solver::INNER_DDPQILUC; break;
case 2: type = Solver::INNER_MPTILUC; break;
case 3: type = Solver::INNER_MPTILU2; break;
case 4: type = Solver::Trilinos_Aztec; break;
case 5: type = Solver::Trilinos_Belos; break;
case 6: type = Solver::Trilinos_ML; break;
case 7: type = Solver::Trilinos_Ifpack; break;
case 8: type = Solver::PETSc; break;
case 9: type = Solver::ANI; break;
case 10: type = Solver::FCBIILU2; break;
case 11: type = Solver::K3BIILU2; break;
}
Solver::Initialize(&argc,&argv,argc > 4 ? argv[4] : NULL); // Initialize the linear solver in accordance with args
{
......
......@@ -51,8 +51,8 @@ namespace INMOST
Trilinos_Ifpack,///< external Solver AztecOO with Ifpack preconditioner.
PETSc, ///< external Solver PETSc, @see http://www.mcs.anl.gov/petsc/
ANI, ///< external Solver from ANI3D based on ILU2 (sequential Fortran version), @see http://ani3d.sourceforge.net/
FCBIILU2, // external FCBIILU2 Solver (BIILU2 parallel F2C version).
K3BIILU2 // inner K3BIILU2 Solver (BIILU2 parallel version).
FCBIILU2, ///< external FCBIILU2 Solver (BIILU2 parallel F2C version).
K3BIILU2 ///< inner K3BIILU2 Solver (BIILU2 parallel version).
};
static INMOST_MPI_Type & GetRowEntryType() {return RowEntryType;}
......
This diff is collapsed.
This diff is collapsed.
......@@ -1929,14 +1929,7 @@ namespace INMOST
void Solver::SetMatrix(Matrix & A, bool OldPreconditioner)
{
(void) OldPreconditioner;
std::cout<<"##### SetMatrix: bef.: the very-very beginning... _pack="<<_pack<<std::endl;//db!
bool ok = false;
#if defined(HAVE_SOLVER_FCBIILU2)
std::cout<<"##### SetMatrix: HAVE_SOLVER_FCBIILU2 is set, OK!!!!!!!!!!!!! _pack="<<_pack<<std::endl;//db!
#endif
#if defined(HAVE_SOLVER_K3BIILU2)
std::cout<<"##### SetMatrix: HAVE_SOLVER_K3BIILU2 is set, OK!!!!!!!!!!!!! _pack="<<_pack<<std::endl;//db!
#endif
#if defined(USE_SOLVER_PETSC)
if( _pack == PETSc )
{
......@@ -2094,7 +2087,6 @@ namespace INMOST
#if defined(HAVE_SOLVER_FCBIILU2)
if( _pack == FCBIILU2 )
{
std::cout<<"##### bef. FCBIILU2: bool modified_pattern = ... "<<std::endl;//db!
bool modified_pattern = false;
for(Matrix::iterator it = A.Begin(); it != A.End() && !modified_pattern; ++it)
modified_pattern |= it->modified_pattern;
......@@ -2104,7 +2096,6 @@ namespace INMOST
MatrixInitDataFcbiilu2(&matrix_data,A.GetCommunicator(),A.GetName().c_str());
modified_pattern = true;
}
std::cout<<"##### bef. if( modified_pattern )... "<<modified_pattern<<std::endl;//db!
if( modified_pattern )
{
global_size = local_size = A.Size();
......@@ -2133,7 +2124,6 @@ namespace INMOST
ibl[1] = n;
#endif
int * ia = (int *)malloc(sizeof(int)*(n+1));
std::cout<<"##### bef. for(...) myid="<<myid<<" A.Size()="<<A.Size()<<" n="<<n<<" nproc="<<nproc<<" ibl: "<<ibl[0]<<" "<<ibl[1]<<" ... "<<ibl[nproc]<<std::endl;//db!
for(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);
......@@ -2150,7 +2140,6 @@ namespace INMOST
shift += it->Size();
ia[q++] = shift;
}
std::cout<<"##### bef. MatrixFillFcbiilu2 myid="<<myid<<" n="<<n<<" nnz="<<nnz<<" shift="<<shift<<" ia: "<<ia[0]<<" "<<ia[1]<<" "<<ia[2]<<" ... "<<ia[n]<<" ja: "<<ja[0]<<" "<<ja[1]<<" "<<ja[2]<<" ... "<<ja[nnz-1]<<" a: "<<values[0]<<" "<<values[1]<<" "<<values[2]<<" ... "<<values[nnz-1]<<std::endl;//db!
MatrixFillFcbiilu2(matrix_data,n,nproc,ibl,ia,ja,values);
}
else
......@@ -2166,14 +2155,12 @@ namespace INMOST
}
MatrixFinalizeFcbiilu2(matrix_data);
SolverSetMatrixFcbiilu2(solver_data,matrix_data,modified_pattern,OldPreconditioner);
std::cout<<"##### bef. ok=true"<<std::endl;//db!
ok = true;
}
#endif
#if defined(HAVE_SOLVER_K3BIILU2)
if( _pack == K3BIILU2 )
{
std::cout<<"##### bef. K3BIILU2: bool modified_pattern = ... "<<std::endl;//db!
bool modified_pattern = false;
for(Matrix::iterator it = A.Begin(); it != A.End() && !modified_pattern; ++it)
modified_pattern |= it->modified_pattern;
......@@ -2183,14 +2170,13 @@ namespace INMOST
MatrixInitDataK3biilu2(&matrix_data,A.GetCommunicator(),A.GetName().c_str());
modified_pattern = true;
}
std::cout<<"##### bef. if( modified_pattern )... "<<modified_pattern<<std::endl;//db!
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 = 1;
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);
......@@ -2212,7 +2198,6 @@ namespace INMOST
ibl[1] = n;
#endif
int * ia = (int *)malloc(sizeof(int)*(n+1));
std::cout<<"##### bef. for(...) myid="<<myid<<" A.Size()="<<A.Size()<<" n="<<n<<" nproc="<<nproc<<" ibl: "<<ibl[0]<<" "<<ibl[1]<<" ... "<<ibl[nproc]<<std::endl;//db!
for(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);
......@@ -2221,7 +2206,7 @@ namespace INMOST
{
for(Row::iterator jt = it->Begin(); jt != it->End(); jt++)
{
ja[k] = jt->first + 1;
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++;
......@@ -2229,7 +2214,6 @@ namespace INMOST
shift += it->Size();
ia[q++] = shift;
}
std::cout<<"##### bef. MatrixFillK3biilu2 myid="<<myid<<" n="<<n<<" nnz="<<nnz<<" shift="<<shift<<" ia: "<<ia[0]<<" "<<ia[1]<<" "<<ia[2]<<" ... "<<ia[n]<<" ja: "<<ja[0]<<" "<<ja[1]<<" "<<ja[2]<<" ... "<<ja[nnz-1]<<" a: "<<values[0]<<" "<<values[1]<<" "<<values[2]<<" ... "<<values[nnz-1]<<std::endl;//db!
MatrixFillK3biilu2(matrix_data,n,nproc,ibl,ia,ja,values);
}
else
......@@ -2245,7 +2229,6 @@ namespace INMOST
}
MatrixFinalizeK3biilu2(matrix_data);
SolverSetMatrixK3biilu2(solver_data,matrix_data,modified_pattern,OldPreconditioner);
std::cout<<"##### bef. ok=true"<<std::endl;//db!
ok = true;
}
#endif
......@@ -2377,7 +2360,6 @@ namespace INMOST
}
for(Matrix::iterator it = A.Begin(); it != A.End(); it++) it->modified_pattern = false;
std::cout<<"##### SetMatrix: bef.: the very-very end... "<<std::endl;//db!
if(!ok) throw NotImplemented;
}
......
#include "solver_k3biilu2.h"
//#if defined(USE_SOLVER_K3BIILU2)
#include <stdio.h>
#include <stdlib.h>
#include <memory.h>
#include <math.h>
#include <string>
#include "k3d.h"
static int set_kovl = 0; // number of overlap layers: kovl=0,1,2,...
static double set_tau = 3e-3; // the ILU2 precision (for the submatrix factorization); tau=3e-3
static double set_eps = 1e-5; // the residual precision: ||r|| < eps * ||b||; eps=1e-6
static int set_nit = 999; // number of iterations permitted; nit=999
static int set_msglev = 2; // messages level; msglev=0 for silent; msglev=1 to output solution statistics
/* BiCGStab solver structure */
typedef struct
{
int n; // local number of unknowns at the local processor
int nproc; // number of processors
int * ibl; // block splitting: ibl[0]=0; ibl[nproc]=nglob
int * ia; // row pointers: ia[0]=0; ia[nloc]=nzloc
int * ja; // column numbers (NOTE: starting from 0 or 1); ja[nzloc]
double * a; // matrix A coefficients; a[nzloc]
int len_r8; // size of the working memory, set len_r8=nbl for the first call
double * W; // poiter to the working memory W[len_r8]
int kovl; // number of overlap layers: kovl=0,1,2,...
double tau; // the ILU2 precision (for the submatrix factorization); tau=3e-3
double eps; // the residual precision: ||r|| < eps * ||b||; eps=1e-6
int nit; // number of iterations permitted; nit=999
int msglev; // messages level; msglev=0 for silent; msglev=1 to output solution statistics
int ierr; // error flag on return; ierr=0 for success
int istat[16]; // integer statistics array on return
double dstat[16]; // double statistics array on return
double RESID; // residual norm
int ITER; // number of BiCGStab iterations performed
} bcg;
typedef struct
{
int n; // local number of unknowns at the local processor
int nproc; // number of processors
int * ibl; // block splitting: ibl[0]=0; ibl[nproc]=nglob
int * ia;
int * ja;
double * A;
} matrix;
typedef struct
{
int n; // local number of unknowns at the local processor
double * v;
} Vector;
/*****************************************************************************/
#include <stdlib.h> // for malloc()
#include <stdio.h> // for printf()
#if defined (USE_MPI)
#include <mpi.h> // for MPI_COMM_WORLD etc.
#endif
#if defined (USE_MPI)
#define MPI_BARRIER(comm) \
MPI_Barrier(comm)
#else
#define MPI_BARRIER(comm)
#endif
#if defined (USE_MPI)
#define MPI_ALLREDUCE(sendbuf, recvbuf, count, datatype, op, comm) \
MPI_Allreduce(sendbuf, recvbuf, count, datatype, op, comm)
#else
#define MPI_ALLREDUCE(sendbuf, recvbuf, count, datatype, op, comm)
#endif
// Solve the linear system A X = B by
// k3biilu2_bcg solver with working memory allocations and statistics output
int k3biilu2_bcg (
int *ibl, // block splitting: ibl[0]=0; ibl[nproc]=n
int *ia, // row pointers: ia[0]=0; ia[nloc]=nzloc
int *ja, // column numbers (NOTE: starting from 0 or 1); ja[nzloc]
double *a, // matrix A coefficients; a[nzloc]
double *b, // right-hand side B; b[nloc]
double *x, // initial guess to the solution X on entry; solution X on return; x[nloc]
int job, // job number: 0 - construct preconditioner; 1 - use the previously constructed one
int *len_r8,// size of the working memory, set len_r8=nbl for the first call
double **S, // poiter to the working memory S[len_r8]
int kovl, // number of overlap layers: kovl=0,1,2,...
double tau, // the ILU2 precision (for the submatrix factorization); tau=3e-3
double eps, // the residual precision: ||r|| < eps * ||b||; eps=1e-6
int nit, // number of iterations permitted; nit=999; if(nit==0) preconditioner construction only
int msglev, // messages level; msglev=0 for silent; msglev=1 to output solution statistics
int *ierr, // error flag on return; ierr=0 for success
int *istat, //[16], // integer statistics array on return
double *dstat) //[16]); // double statistics array on return
//
// Here, in notation:
// nproc - the number of processors (or blocks), nproc is equal to the MPI communicator size
// nzloc - the local number of nonzero elements, nzloc=ia[[myid+1]]-ia[ibl[myid]]
// nloc - the local number of unknowns at the current processor, nloc=ibl[myid+1]-ibl[myid]
// n - the total number of unknowns in matrix A, n=ibl[nproc]
//
// ON ENTRY:
// ibl, ia, ja, a, b, x, job, len_r8, S, kovl, tau, eps, nit, msglev
// ON RETURN:
// x, len_r8, S, ierr, istat, dstat
//
{
// Initialize MPI variables
int np=1, mp=0;
MPI_Comm comm = MPI_COMM_WORLD; //TODO: MSPP_COMM_WORLD
#if defined (USE_MPI)
MPI_Comm_size(MPI_COMM_WORLD, &np);
MPI_Comm_rank(MPI_COMM_WORLD, &mp);
#endif
k3d::SSolverParams params;
params.prec_float = 1;
params.ncycle = kovl;
params.fcttype = -1;
params.tau1 = tau;
params.tau2 = tau*tau;
params.theta = 0.1e0;
std::vector<long long> blks (np+1);
std::vector<int> blk2cpu (np+1);
long long *pblks = &blks[0];
int *pblk2cpu = &blk2cpu[0];
int i;
for (i=0;i<=np;i++) pblks[i] = ibl[i];
for (i=0;i<np;i++) pblk2cpu[i] = i;
k3d::CSolver<int,double,double> *pSolver = new k3d::CSolver<int,double,double>;
pSolver->PrepareSolver ((void *)&comm, &params, np, pblks, pblk2cpu,
true, ia, ja, a);
if (nit > 0) {
int ichk = 5;
msglev = 0;
ofstream *pfout = NULL;
if (mp == 0) msglev = 2;
double rhs_norm, res_ini, res_fin;
int niter;
pSolver->BiCGStab (nit, eps, ichk, msglev, pfout,
b, x,
rhs_norm, res_ini, niter, res_fin);
istat[2] = niter;
dstat[2] = (rhs_norm == 0e0) ? res_fin : res_fin/rhs_norm;
}
*ierr = 0;
return *ierr;
}
/*****************************************************************************/
/* Initialize bcg solver */
static int initbcg(bcg *s, matrix *A, double eps);
/* Reinitialize solver preconditioner with new matrix A */
static int renewbcg(bcg *s, double *A);
/* Solve linear system */
/*static*/ int solvebcg(bcg *s, Vector *b, Vector *x);
/* Free memory used by solver */
static void freebcg(bcg *s);
/*****************************************************************************/
/* Initialize solver with new matrix A */
static int newmatrixbcg(bcg *s, matrix *A, bool same_precond)
{
if( s->n != A->n && same_precond ) throw INMOST::CannotReusePreconditionerOfDifferentSize;
s->n = A->n;
s->nproc = A->nproc;
s->ibl = A->ibl;
s->ia = A->ia;
s->ja = A->ja;
if( !same_precond )
{
//do nothing...
//std::cout<<"##### inside newmatrixbcg bef. renewbcg \n";//db!
return renewbcg(s, A->A);
}
else return 0;
}
/* solver */
/* Initialize bcg solver */
int initbcg(bcg *s, matrix *A, double eps)
{
s->eps = eps;
//std::cout<<"##### inside initbcg bef. newmatrixbcg eps="<<eps<<" \n";//db!
return newmatrixbcg(s, A, false);
}
/* Reinitialize solver preconditioner with new matrix A */
int renewbcg(bcg *s, double *A)
{
//reinitialize matrix values
s->a = A;
//BIILU2 preconditioner construction...
s->kovl = set_kovl;
s->tau = set_tau;
s->msglev = set_msglev;
int job = 0;
int maxit = 0;
s->len_r8 = 0; //to be set by nbl inside k3biilu2_bcg
if(s->W) free(s->W); s->W=NULL;
int ierr = 0;
//std::cout<<"##### inside renewbcg bef. k3biilu2_bcg\n";//db!
//double *B = (double*) malloc(sizeof(double)*s->n); //db!!!!!!!!!!!!!!
//double *X = (double*) malloc(sizeof(double)*s->n); //db!!!!!!!!!!!!!!
k3biilu2_bcg (s->ibl, s->ia, s->ja, s->a,
NULL, NULL,
job, &s->len_r8, &s->W,
s->kovl, s->tau, s->eps, maxit, s->msglev,
&ierr, s->istat, s->dstat);
//std::cout<<"##### inside renewbcg aft. k3biilu2_bcg\n";//db!
//free(B);free(X);//db!!!!!!!!!!!!!!!
if (ierr) printf("initialization of biilu2 failed, ierr=%d\n", ierr);
return ierr;
}
/* Solve linear system */
int solvebcg(bcg *s, Vector *b, Vector *x)
{
s->kovl = set_kovl;
s->tau = set_tau;
// s->eps = set_eps;
s->nit = set_nit;
s->msglev = set_msglev;
int job = 1;
int maxit = s->nit;
int ierr = 0;
//std::cout<<"##### inside solvebcg bef. k3biilu2_bcg\n";//db!
k3biilu2_bcg (s->ibl, s->ia, s->ja, s->a, b->v, x->v,
job, &s->len_r8, &s->W,
s->kovl, s->tau, s->eps, maxit, s->msglev,
&ierr, s->istat, s->dstat);
//std::cout<<"##### inside solvebcg aft. k3biilu2_bcg\n";//db!
s->ITER = s->istat[2];
s->RESID = s->dstat[2];
return ierr;
}
/* Free memory used by solver */
void freebcg(bcg *s)
{
if(s->W) free(s->W); s->W=NULL; //-IK!!!!!!!!!!!!!!!!!!
}
/*****************************************************************************/
void MatrixCopyDataK3biilu2(void ** ppA, void * pB)
{
matrix * B = (matrix *)pB;
if( ppA == NULL || pB == NULL ) throw INMOST::DataCorruptedInSolver;
*ppA = malloc(sizeof(matrix));
matrix * A = (matrix *)ppA;
A->n = B->n;
if( B->n != 0 )
{
int nnz = B->ia[B->n] - B->ia[0];
A->nproc = B->nproc;
A->ibl = (int *) malloc(sizeof(int)*(A->nproc+1));
memcpy(A->ibl,B->ibl,sizeof(int)*(A->nproc+1));
A->ia = (int *) malloc(sizeof(int)*(A->n+1));
memcpy(A->ia,B->ia,sizeof(int)*(A->n+1));
A->ja = (int *) malloc(sizeof(int)*nnz);
memcpy(A->ja,B->ja,sizeof(int)*nnz);
A->A = (double *) malloc(sizeof(double)*nnz);
memcpy(A->A,B->A,sizeof(double)*nnz);
}
}
void MatrixAssignDataK3biilu2(void * pA, void * pB)
{
matrix * A = (matrix *)pA;
matrix * B = (matrix *)pB;
if( A == NULL || B == NULL ) throw INMOST::DataCorruptedInSolver;
if( A != B )
{
if( A->n != 0 )
{
free(A->ibl);
free(A->ia);
free(A->ja);
free(A->A);
}
if( B->n != 0 )
{
int nnz = B->ia[B->n] - B->ia[0];
A->n = B->n;
A->nproc = B->nproc;
A->ibl = (int *) malloc(sizeof(int)*(A->nproc+1));
memcpy(A->ibl,B->ibl,sizeof(int)*(A->nproc+1));
A->ia = (int *) malloc(sizeof(int)*(A->n+1));
memcpy(A->ia,B->ia,sizeof(int)*(A->n+1));
A->ja = (int *) malloc(sizeof(int)*nnz);
memcpy(A->ja,B->ja,sizeof(int)*nnz);
A->A = (double *) malloc(sizeof(double)*nnz);
memcpy(A->A,B->A,sizeof(double)*nnz);
}
}
}
void MatrixInitDataK3biilu2(void ** ppA, INMOST_MPI_Comm comm, const char * name)
{
//std::cout<<"##### ins. MatrixInitDataK3biilu2 \n";//db!
if( ppA == NULL ) throw INMOST::DataCorruptedInSolver;
if( *ppA == NULL )
{
*ppA = malloc(sizeof(matrix));
matrix * A = (matrix *)*ppA;
A->n = 0;
A->nproc = 0;
//std::cout<<"##### ins. MatrixInitDataK3biilu2 n=nproc=0 \n";//db!
}
(void) comm;
(void) name;
}
void MatrixDestroyDataK3biilu2(void ** pA)
{
matrix * A = (matrix *)(*pA);
if( A != NULL )
{
if( A->n != 0 )
{
free(A->ibl);
free(A->ia);
free(A->ja);
free(A->A);
//std::cout<<"##### ins. MatrixDestroyDataK3biilu2 ...free \n";//db!
}
free(*pA);
*pA = NULL;
}
}
void MatrixFillK3biilu2(void * pA, int size, int nproc, int * ibl, int * ia, int * ja, double * values)
{
//std::cout<<"##### ins. MatrixFillK3biilu2 n="<<size<<" nproc="<<nproc<<" \n";//db!
if( pA == NULL ) throw INMOST::DataCorruptedInSolver;
matrix * A = (matrix *) pA;
A->n = size;
A->nproc = nproc;
A->ibl = ibl;
A->ia = ia;
A->ja = ja;
A->A = values;
}
void MatrixFillValuesK3biilu2(void * pA, double * values)
{
//std::cout<<"##### ins. MatrixFillValuesK3biilu2 \n";//db!
if( pA == NULL ) throw INMOST::DataCorruptedInSolver;
matrix * A = (matrix *) pA;
free(A->A);
A->A = values;
}
void MatrixFinalizeK3biilu2(void * data)
{
//don't need to do anything
(void) data;
}
void VectorInitDataK3biilu2(void ** ppA, INMOST_MPI_Comm comm, const char * name)
{
if( ppA == NULL ) throw INMOST::DataCorruptedInSolver;
*ppA = malloc(sizeof(Vector));
Vector * A = (Vector *)*ppA;
A->n = 0;
(void) comm;
(void) name;
}
void VectorCopyDataK3biilu2(void ** ppA, void * pB)
{
//std::cout<<"##### ins. VectorCopyDataK3biilu2 \n";//db!
if( ppA == NULL || pB == NULL ) throw INMOST::DataCorruptedInSolver;
*ppA = malloc(sizeof(Vector));
Vector * A = (Vector *)*ppA;
Vector * B = (Vector *)pB;
A->n = B->n;
if( B->n != 0 )
{
A->v = (double *)malloc(sizeof(double)*A->n);
memcpy(A->v,B->v,sizeof(double)*A->n);
}
}
void VectorAssignDataK3biilu2(void * pA, void * pB)
{
//std::cout<<"##### ins. VectorAssignDataK3biilu2 \n";//db!
Vector * A = (Vector *)pA;
Vector * B = (Vector *)pB;
if( A == NULL || B == NULL ) throw INMOST::DataCorruptedInSolver;
if( A != B )
{
if( A->n != 0 ) free(A->v);
A->n = B->n;
if( B->n != 0 )
{
A->v = (double *) malloc(sizeof(double)*A->n);
memcpy(A->v,B->v,sizeof(double)*A->n);
}
}
}
void VectorPreallocateK3biilu2(void * pA, int size)
{
Vector * A = (Vector *)pA;
if( A == NULL ) throw INMOST::DataCorruptedInSolver;
A->n = size;
A->v = (double *)malloc(sizeof(double)*size);
}
void VectorFillK3biilu2(void * pA, double * values)
{