6 #if defined(HAVE_PETSC)
12 #if((PETSC_VERSION_RELEASE == 0) || \
13 ((PETSC_VERSION_MAJOR == 3) && (PETSC_VERSION_MINOR >= 7)))
14 #define PetscOptionsGetInt(A, B, C, D) PetscOptionsGetInt(NULL, A, B, C, D)
15 #define PetscOptionsInsertString(A) PetscOptionsInsertString(NULL, A)
18 static void _check(
int ierr) { CHKERRABORT(PETSC_COMM_WORLD, ierr); }
20 template <
class scalar>
30 if(this->_parameters.count(
"petsc_solver_options"))
31 _check(PetscOptionsInsertString(
32 this->_parameters[
"petsc_solver_options"].c_str()));
33 _check(KSPCreate(_comm, &_ksp));
35 _check(KSPGetPC(_ksp, &pc));
42 KSPSetTolerances(_ksp, 1.e-8, PETSC_DEFAULT, PETSC_DEFAULT, PETSC_DEFAULT));
45 if(this->_parameters.count(
"petscPrefix"))
47 KSPAppendOptionsPrefix(_ksp, this->_parameters[
"petscPrefix"].c_str()));
48 _check(KSPSetFromOptions(_ksp));
49 _check(PCSetFromOptions(pc));
53 template <
class scalar>
57 _check(KSPGetIterationNumber(_ksp, &n));
61 template <
class scalar>
66 _kspAllocated =
false;
67 _matrixChangedSinceLastSolve =
true;
68 _valuesNotAssembled =
false;
69 _entriesPreAllocated =
false;
74 _comm = PETSC_COMM_WORLD;
76 _kspAllocated =
false;
77 _matrixChangedSinceLastSolve =
true;
78 _valuesNotAssembled =
false;
79 _entriesPreAllocated =
false;
85 if(_kspAllocated) _check(KSPDestroy(&_ksp));
88 template <
class scalar>
92 if(_comm == PETSC_COMM_WORLD) {
94 int value = _valuesNotAssembled ? 1 : 0;
96 MPI_Allreduce((
void *)&value, (
void *)&sumValue, 1, MPI_INT, MPI_SUM,
99 _valuesNotAssembled = 1;
104 if(_valuesNotAssembled) {
105 _check(MatAssemblyBegin(_a, MAT_FINAL_ASSEMBLY));
106 _check(MatAssemblyEnd(_a, MAT_FINAL_ASSEMBLY));
107 _matrixChangedSinceLastSolve =
true;
108 _valuesNotAssembled =
false;
112 template <
class scalar>
116 if(i < 0 || i >= _localSize)
return;
117 _sparsity.insertEntry(i, j);
122 if(_entriesPreAllocated)
return;
127 int blockSize = _getBlockSizeFromParameters();
128 std::vector<int> nByRowDiag(_localSize), nByRowOffDiag(_localSize);
129 if(_sparsity.getNbRows() == 0) {
130 PetscInt prealloc = 300;
132 PetscOptionsGetInt(PETSC_NULL,
"-petsc_prealloc", &prealloc, &set);
133 prealloc = std::min(prealloc, _localSize);
134 nByRowDiag.resize(0);
135 nByRowDiag.resize(_localSize, prealloc);
138 for(
int i = 0; i < _localSize; i++) {
140 const int *r = _sparsity.getRow(i, n);
141 for(
int j = 0; j < n; j++) {
142 if(r[j] >= _localRowStart && r[j] < _localRowEnd)
152 MPI_Comm_size(_comm, &commSize);
155 _check(MatSeqAIJSetPreallocation(_a, 0, &nByRowDiag[0]));
157 _check(MatSeqBAIJSetPreallocation(_a, blockSize, 0, &nByRowDiag[0]));
162 MatMPIAIJSetPreallocation(_a, 0, &nByRowDiag[0], 0, &nByRowOffDiag[0]));
164 _check(MatMPIBAIJSetPreallocation(_a, blockSize, 0, &nByRowDiag[0], 0,
167 if(blockSize > 1) _check(MatSetOption(_a, MAT_ROW_ORIENTED, PETSC_FALSE));
168 _entriesPreAllocated =
true;
170 #if ((PETSC_VERSION_MAJOR == 3) && (PETSC_VERSION_MINOR >= 3))
175 _check(MatSetOption(_a, MAT_NEW_NONZERO_ALLOCATION_ERR, PETSC_FALSE));
182 MPI_Comm_size(_comm, &commSize);
183 int blockSize = _getBlockSizeFromParameters();
185 _check(MatCreate(_comm, &_a));
186 _check(MatSetSizes(_a, blockSize * nbRows, blockSize * nbRows,
187 PETSC_DETERMINE, PETSC_DETERMINE));
190 _check(MatSetType(_a, MATMPIBAIJ));
193 _check(MatSetType(_a, MATSEQBAIJ));
198 if(this->_parameters.count(
"petscOptions"))
199 _check(PetscOptionsInsertString(this->_parameters[
"petscOptions"].c_str()));
200 if(this->_parameters.count(
"petscPrefix"))
202 MatAppendOptionsPrefix(_a, this->_parameters[
"petscPrefix"].c_str()));
203 _check(MatSetFromOptions(_a));
207 #if defined(HAVE_MPI)
213 MPI_COMM_WORLD, &status);
215 _localRowEnd = _localRowStart + nbRows;
220 MPI_Allreduce((
void *)&_localSize, (
void *)&_globalSize, 1, MPI_INT,
221 MPI_SUM, MPI_COMM_WORLD);
225 _localRowEnd = nbRows;
226 _globalSize = _localSize;
230 _localRowEnd = nbRows;
231 _globalSize = _localSize;
235 _check(VecCreate(_comm, &_x));
236 _check(VecSetSizes(_x, blockSize * nbRows, PETSC_DETERMINE));
239 if(this->_parameters.count(
"petscPrefix"))
241 VecAppendOptionsPrefix(_x, this->_parameters[
"petscPrefix"].c_str()));
242 _check(VecSetFromOptions(_x));
243 _check(VecDuplicate(_x, &_b));
245 _entriesPreAllocated =
false;
250 _assembleMatrixIfNeeded();
251 _check(VecAssemblyBegin(_b));
252 _check(VecAssemblyEnd(_b));
263 MatView(_a, PETSC_VIEWER_STDOUT_WORLD);
265 VecView(_b, PETSC_VIEWER_STDOUT_WORLD);
267 VecView(_x, PETSC_VIEWER_STDOUT_WORLD);
273 _check(MatDestroy(&_a));
274 _check(VecDestroy(&_x));
275 _check(VecDestroy(&_b));
277 _isAllocated =
false;
280 template <
class scalar>
284 Msg::Error(
"getFromMatrix not implemented for PETSc");
287 template <
class scalar>
293 _check(VecSetValues(_b, 1, &i, &s, ADD_VALUES));
295 #if defined(PETSC_USE_COMPLEX)
303 template <
class scalar>
306 _check(VecGetValues(_b, 1, &row, &val));
309 template <
class scalar>
313 VecAssemblyBegin(_b);
315 _check(VecNorm(_b, NORM_INFINITY, &nor));
319 template <
class scalar>
322 if(!_entriesPreAllocated) preAllocateEntries();
323 PetscInt i = row, j = col;
325 _check(MatSetValues(_a, 1, &i, 1, &j, &s, ADD_VALUES));
326 _valuesNotAssembled =
true;
329 template <
class scalar>
334 _check(VecSetValues(_x, 1, &i, &s, ADD_VALUES));
336 #if defined(PETSC_USE_COMPLEX)
343 template <
class scalar>
346 _check(VecGetValues(_x, 1, &row, &val));
351 #if defined(HAVE_MPI)
352 if(_comm == PETSC_COMM_WORLD) {
354 int value = _entriesPreAllocated ? 1 : 0;
356 MPI_Allreduce((
void *)&value, (
void *)&sumValue, 1, MPI_INT, MPI_SUM,
359 !_entriesPreAllocated) {
360 preAllocateEntries();
365 if(_isAllocated && _entriesPreAllocated) {
366 _assembleMatrixIfNeeded();
367 _check(MatZeroEntries(_a));
374 _check(VecAssemblyBegin(_b));
375 _check(VecAssemblyEnd(_b));
376 _check(VecZeroEntries(_b));
383 _check(VecAssemblyBegin(_x));
384 _check(VecAssemblyEnd(_x));
385 _check(VecZeroEntries(_x));
391 if(!_kspAllocated) _kspCreate();
392 _assembleMatrixIfNeeded();
393 if(!_matrixChangedSinceLastSolve ||
395 _check(KSPSetOperators(_ksp, _a, _a, SAME_PRECONDITIONER));
397 _check(KSPSetOperators(_ksp, _a, _a, SAME_NONZERO_PATTERN));
399 _check(KSPSetOperators(_ksp, _a, _a, DIFFERENT_NONZERO_PATTERN));
400 _matrixChangedSinceLastSolve =
false;
405 _check(VecAssemblyBegin(_b));
406 _check(VecAssemblyEnd(_b));
407 _check(KSPSolve(_ksp, _b, _x));
417 _check(MatAssemblyBegin(_a, MAT_FINAL_ASSEMBLY));
418 _check(MatAssemblyEnd(_a, MAT_FINAL_ASSEMBLY));
419 _check(VecAssemblyBegin(_b));
420 _check(VecAssemblyEnd(_b));
421 _check(MatMult(_a, _b, _x));
425 template <
class scalar>
428 _check(MatAssemblyBegin(_a, MAT_FINAL_ASSEMBLY));
429 _check(MatAssemblyEnd(_a, MAT_FINAL_ASSEMBLY));
430 _check(VecAssemblyBegin(_b));
431 _check(VecAssemblyEnd(_b));
434 PetscViewerASCIIOpen(PETSC_COMM_WORLD, filename, &viewer);
435 PetscViewerPushFormat(viewer, PETSC_VIEWER_ASCII_MATLAB);
437 PetscViewerDestroy(&viewer);