33 static int num_petsc_objects = 0;
35 inline void vec_get_value(Vec x, PetscInt ni,
const PetscInt ix[], std::complex<double> y[])
37 VecGetValues(x, ni, ix, y);
40 void vec_get_value(Vec x, PetscInt ni,
const PetscInt ix[],
double y[])
42 PetscScalar *py =
new PetscScalar[ni];
43 VecGetValues(x, ni, ix, py);
44 for (
int i = 0;i<ni;i++)y[i] = py[i].real();
48 int remove_petsc_object()
50 PetscTruth petsc_initialized, petsc_finalized;
51 int ierr = PetscFinalized(&petsc_finalized); CHKERRQ(ierr);
52 ierr = PetscInitialized(&petsc_initialized); CHKERRQ(ierr);
53 if(petsc_finalized == PETSC_TRUE || petsc_initialized == PETSC_FALSE)
57 if(--num_petsc_objects == 0)
59 int ierr = PetscFinalize();
61 this->info(
"PETSc finalized. No more PETSc usage allowed until application restart.");
65 int add_petsc_object()
68 PetscTruth petsc_initialized, petsc_finalized;
69 ierr = PetscFinalized(&petsc_finalized); CHKERRQ(ierr);
71 if(petsc_finalized == PETSC_TRUE)
74 ierr = PetscInitialized(&petsc_initialized); CHKERRQ(ierr);
76 if(petsc_initialized != PETSC_TRUE)
78 ierr = PetscInitializeNoArguments();
85 template<
typename Scalar>
86 PetscMatrix<Scalar>::PetscMatrix()
92 template<
typename Scalar>
93 PetscMatrix<Scalar>::~PetscMatrix()
96 remove_petsc_object();
99 template<
typename Scalar>
100 void PetscMatrix<Scalar>::alloc()
102 assert(this->pages != NULL);
105 int *nnz_array =
new int[this->size];
108 int aisize = this->get_num_indices();
109 int *ai =
new int[aisize];
113 for (
unsigned int i = 0; i < this->size; i++)
115 nnz_array[i] = sort_and_store_indices(this->pages[i], ai + pos, ai + aisize);
120 delete [] this->pages; this->pages = NULL;
124 MatCreateSeqAIJ(PETSC_COMM_SELF, this->size, this->size, 0, nnz_array, &matrix);
133 template<
typename Scalar>
134 void PetscMatrix<Scalar>::free()
136 if(inited) MatDestroy(matrix);
140 template<
typename Scalar>
141 void PetscMatrix<Scalar>::finish()
143 MatAssemblyBegin(matrix, MAT_FINAL_ASSEMBLY);
144 MatAssemblyEnd(matrix, MAT_FINAL_ASSEMBLY);
148 double PetscMatrix<double>::get(
unsigned int m,
unsigned int n)
152 MatGetValues(matrix, 1, (PetscInt*) &m, 1, (PetscInt*) &n, &pv);
158 std::complex<double> PetscMatrix<std::complex<double> >::get(
unsigned int m,
unsigned int n)
160 std::complex<double> v = 0.0;
161 MatGetValues(matrix, 1, (PetscInt*) &m, 1, (PetscInt*) &n, &v);
165 template<
typename Scalar>
166 void PetscMatrix<Scalar>::zero()
168 MatZeroEntries(matrix);
171 inline PetscScalar to_petsc(
double x)
173 return std::complex<double>(x, 0);
176 inline PetscScalar to_petsc(std::complex<double> x)
181 template<
typename Scalar>
182 void PetscMatrix<Scalar>::add(
unsigned int m,
unsigned int n, Scalar v)
186 #pragma omp critical (PetscMatrix_add)
187 MatSetValue(matrix, (PetscInt) m, (PetscInt) n, to_petsc(v), ADD_VALUES);
193 template<
typename Scalar>
194 void PetscMatrix<Scalar>::add_to_diagonal(Scalar v)
196 for (
unsigned int i = 0; i<this->size; i++)
202 template<
typename Scalar>
203 void PetscMatrix<Scalar>::add(
unsigned int m,
unsigned int n, Scalar **mat,
int *rows,
int *cols)
207 for (
unsigned int i = 0; i < m; i++)
208 for (
unsigned int j = 0; j < n; j++)
209 if(rows[i] >= 0 && cols[j] >= 0)
210 add(rows[i], cols[j], mat[i][j]);
213 template<
typename Scalar>
214 bool PetscMatrix<Scalar>::dump(FILE *file,
const char *var_name,
EMatrixDumpFormat fmt,
char* number_format)
219 PetscViewer viewer = PETSC_VIEWER_STDOUT_SELF;
220 PetscViewerSetFormat(viewer, PETSC_VIEWER_ASCII_MATLAB);
221 MatView(matrix, viewer);
227 template<
typename Scalar>
228 unsigned int PetscMatrix<Scalar>::get_matrix_size()
const
233 template<
typename Scalar>
234 unsigned int PetscMatrix<Scalar>::get_nnz()
const
239 template<
typename Scalar>
240 double PetscMatrix<Scalar>::get_fill_in()
const
242 return (
double) nnz / ((double)this->size*this->size);
245 template<
typename Scalar>
246 void PetscMatrix<Scalar>::multiply_with_vector(Scalar* vector_in, Scalar* vector_out)
248 for (
unsigned int i = 0;i<this->size;i++)
251 for (
unsigned int j = 0; j<this->size; j++)
253 vector_out[i] +=vector_in[j]*
get(i, j);
258 template<
typename Scalar>
259 void PetscMatrix<Scalar>::add_matrix(PetscMatrix<Scalar>* mat)
261 MatAXPY(matrix, 1, mat->matrix, DIFFERENT_NONZERO_PATTERN);
264 template<
typename Scalar>
265 void PetscMatrix<Scalar>::add_to_diagonal_blocks(
int num_stages, PetscMatrix<Scalar>* mat)
267 int ndof = mat->get_size();
268 if(this->get_size() != (
unsigned int) num_stages * ndof)
271 for (
int i = 0; i < num_stages; i++)
273 this->add_as_block(ndof*i, ndof*i, mat);
277 template<
typename Scalar>
278 void PetscMatrix<Scalar>::add_sparse_to_diagonal_blocks(
int num_stages, SparseMatrix<Scalar>* mat)
280 add_to_diagonal_blocks(num_stages,
static_cast<PetscMatrix<Scalar>*
>(mat));
283 template<
typename Scalar>
284 void PetscMatrix<Scalar>::add_as_block(
unsigned int i,
unsigned int j, PetscMatrix<Scalar>* mat)
286 if((this->get_size() < i + mat->get_size() )||(this->get_size() < j + mat->get_size() ))
288 unsigned int block_size = mat->get_size();
289 for (
unsigned int r = 0;r<block_size;r++)
291 for (
unsigned int c = 0;c<block_size;c++)
293 this->add(i + r, j + c, mat->get(r, c));
300 template<
typename Scalar>
301 void PetscMatrix<Scalar>::multiply_with_Scalar(Scalar value)
303 MatScale(matrix, to_petsc(value));
307 template<
typename Scalar>
308 void PetscMatrix<Scalar>::create(
unsigned int size,
unsigned int nnz,
int* ap,
int* ai, Scalar* ax)
312 PetscScalar* pax =
new PetscScalar[nnz];
313 for (
unsigned i = 0;i<nnz;i++)
314 pax[i] = to_petsc(ax[i]);
315 MatCreateSeqAIJWithArrays(PETSC_COMM_SELF, size, size, ap, ai, pax, &matrix);
319 template<
typename Scalar>
320 PetscMatrix<Scalar>* PetscMatrix<Scalar>::duplicate()
322 PetscMatrix<Scalar>*ptscmatrix =
new PetscMatrix<Scalar>();
323 MatDuplicate(matrix, MAT_COPY_VALUES, &(ptscmatrix->matrix));
324 ptscmatrix->size = this->size;
325 ptscmatrix->nnz = nnz;
329 template<
typename Scalar>
330 PetscVector<Scalar>::PetscVector()
336 template<
typename Scalar>
337 PetscVector<Scalar>::~PetscVector()
340 remove_petsc_object();
343 template<
typename Scalar>
344 void PetscVector<Scalar>::alloc(
unsigned int n)
348 VecCreateSeq(PETSC_COMM_SELF, this->size, &vec);
352 template<
typename Scalar>
353 void PetscVector<Scalar>::free()
355 if(inited) VecDestroy(vec);
359 template<
typename Scalar>
360 void PetscVector<Scalar>::finish()
362 VecAssemblyBegin(vec);
367 double PetscVector<double>::get(
unsigned int idx)
371 VecGetValues(vec, 1, (PetscInt*) &idx, &py);
377 std::complex<double> PetscVector<std::complex<double> >::get(
unsigned int idx)
379 std::complex<double> y = 0;
380 VecGetValues(vec, 1, (PetscInt*) &idx, &y);
384 template<
typename Scalar>
385 void PetscVector<Scalar>::extract(Scalar *v)
const
387 int *idx =
new int[this->size];
388 for (
unsigned int i = 0; i < this->size; i++) idx[i] = i;
389 vec_get_value(vec, this->size, idx, v);
393 template<
typename Scalar>
394 void PetscVector<Scalar>::zero()
399 template<
typename Scalar>
400 void PetscVector<Scalar>::change_sign()
402 PetscScalar* y =
new PetscScalar[this->size];
403 int *idx =
new int[this->size];
404 for (
unsigned int i = 0; i < this->size; i++) idx[i] = i;
405 VecGetValues(vec, this->size, idx, y);
406 for (
unsigned int i = 0; i < this->size; i++) y[i] *= -1.;
407 VecSetValues(vec, this->size, idx, y, INSERT_VALUES);
412 template<
typename Scalar>
413 void PetscVector<Scalar>::set(
unsigned int idx, Scalar y)
415 VecSetValue(vec, idx, to_petsc(y), INSERT_VALUES);
418 template<
typename Scalar>
419 void PetscVector<Scalar>::add(
unsigned int idx, Scalar y)
421 #pragma omp critical (PetscVector_add)
422 VecSetValue(vec, idx, to_petsc(y), ADD_VALUES);
425 template<
typename Scalar>
426 void PetscVector<Scalar>::add(
unsigned int n,
unsigned int *idx, Scalar *y)
429 for (
unsigned int i = 0; i < n; i++)
431 VecSetValue(vec, idx[i], to_petsc(y[i]), ADD_VALUES);
435 template<
typename Scalar>
436 void PetscVector<Scalar>::add_vector(Vector<Scalar>* vec)
438 assert(this->length() == vec->length());
439 for (
unsigned int i = 0; i < this->length(); i++) this->add(i, vec->get(i));
442 template<
typename Scalar>
443 void PetscVector<Scalar>::add_vector(Scalar* vec)
445 for (
unsigned int i = 0; i < this->length(); i++) this->add(i, vec[i]);
448 template<
typename Scalar>
449 bool PetscVector<Scalar>::dump(FILE *file,
const char *var_name,
EMatrixDumpFormat fmt,
char* number_format)
454 PetscViewer viewer = PETSC_VIEWER_STDOUT_SELF;
455 PetscViewerSetFormat(viewer, PETSC_VIEWER_ASCII_MATLAB);
456 VecView(vec, viewer);
462 template class HERMES_API PetscMatrix<double>;
463 template class HERMES_API PetscMatrix<std::complex<double> >;
464 template class HERMES_API PetscVector<double>;
465 template class HERMES_API PetscVector<std::complex<double> >;
469 template<
typename Scalar>
470 PetscLinearMatrixSolver<Scalar>::PetscLinearMatrixSolver(PetscMatrix<Scalar> *mat, PetscVector<Scalar> *rhs)
471 : DirectSolver<Scalar>(), m(mat), rhs(rhs)
476 template<
typename Scalar>
477 PetscLinearMatrixSolver<Scalar>::~PetscLinearMatrixSolver()
479 remove_petsc_object();
482 template<
typename Scalar>
483 bool PetscLinearMatrixSolver<Scalar>::get_matrix_size()
488 template<
typename Scalar>
489 bool PetscLinearMatrixSolver<Scalar>::solve()
500 KSPCreate(PETSC_COMM_WORLD, &ksp);
502 KSPSetOperators(ksp, m->matrix, m->matrix, DIFFERENT_NONZERO_PATTERN);
503 KSPSetFromOptions(ksp);
504 VecDuplicate(rhs->vec, &x);
506 ec = KSPSolve(ksp, rhs->vec, x);
510 this->time = this->accumulated();
514 this->sln =
new Scalar[m->size];
515 memset(this->sln, 0, m->size *
sizeof(Scalar));
518 int *idx =
new int[m->size];
519 for (
unsigned int i = 0; i < m->size; i++) idx[i] = i;
522 vec_get_value(x, m->size, idx, this->sln);
531 template class HERMES_API PetscLinearMatrixSolver<double>;
532 template class HERMES_API PetscLinearMatrixSolver<std::complex<double> >;