Skip to content
GitLab
Menu
Projects
Groups
Snippets
Loading...
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
Menu
Open sidebar
Kirill Terekhov
INMOST
Commits
d55b1e90
Commit
d55b1e90
authored
Jun 26, 2015
by
Igor Konshin
Browse files
new linear solver k3biilu2 is added
parent
9a92cf91
Changes
8
Expand all
Hide whitespace changes
Inline
Side-by-side
examples/MatSolve/main.cpp
View file @
d55b1e90
...
...
@@ -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_
ML
ILUC,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_
DDPQ
ILUC,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
{
...
...
inmost_solver.h
View file @
d55b1e90
...
...
@@ -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
;}
...
...
k3d.cpp
0 → 100644
View file @
d55b1e90
This diff is collapsed.
Click to expand it.
k3d.h
0 → 100644
View file @
d55b1e90
This diff is collapsed.
Click to expand it.
solver.cpp
View file @
d55b1e90
...
...
@@ -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
;
}
...
...
solver_k3biilu2.cpp
0 → 100644
View file @
d55b1e90
#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
,