35 static int num_petsc_objects = 0;
37 #ifdef PETSC_USE_COMPLEX
38 inline void vec_get_value(Vec x, PetscInt ni,
const PetscInt ix[], std::complex<double> y[])
40 VecGetValues(x, ni, ix, y);
43 void vec_get_value(Vec x, PetscInt ni,
const PetscInt ix[],
double y[])
45 PetscScalar *py = malloc_with_check<PetscScalar>(ni);
46 VecGetValues(x, ni, ix, py);
47 for (
int i = 0; i < ni; i++)y[i] = py[i].real();
51 inline void vec_get_value(Vec x, PetscInt ni,
const PetscInt ix[],
double y[])
53 VecGetValues(x, ni, ix, y);
55 inline void vec_get_value(Vec x, PetscInt ni,
const PetscInt ix[], std::complex<double> y[])
57 throw(Exceptions::Exception(
"PETSc with complex numbers support required."));
61 int remove_petsc_object()
63 PetscBool petsc_initialized, petsc_finalized;
64 int ierr = PetscFinalized(&petsc_finalized); CHKERRQ(ierr);
65 ierr = PetscInitialized(&petsc_initialized); CHKERRQ(ierr);
66 if (petsc_finalized == PETSC_TRUE || petsc_initialized == PETSC_FALSE)
70 if (--num_petsc_objects == 0)
72 int ierr = PetscFinalize();
78 int add_petsc_object()
81 PetscBool petsc_initialized, petsc_finalized;
82 ierr = PetscFinalized(&petsc_finalized); CHKERRQ(ierr);
84 if (petsc_finalized == PETSC_TRUE)
87 ierr = PetscInitialized(&petsc_initialized); CHKERRQ(ierr);
89 if (petsc_initialized != PETSC_TRUE)
91 ierr = PetscInitializeNoArguments();
98 template<
typename Scalar>
99 PetscMatrix<Scalar>::PetscMatrix()
105 template<
typename Scalar>
106 PetscMatrix<Scalar>::~PetscMatrix()
109 remove_petsc_object();
112 template<
typename Scalar>
113 void PetscMatrix<Scalar>::alloc()
115 assert(this->pages !=
nullptr);
118 int *nnz_array = malloc_with_check<int>(this->size);
121 int aisize = this->get_num_indices();
122 int *ai = malloc_with_check<int>(aisize);
126 for (
unsigned int i = 0; i < this->size; i++)
128 nnz_array[i] = this->sort_and_store_indices(this->pages[i], ai + pos, ai + aisize);
133 free_with_check(this->pages);
137 MatCreateSeqAIJ(PETSC_COMM_SELF, this->size, this->size, 0, nnz_array, &matrix);
140 free_with_check(nnz_array);
145 template<
typename Scalar>
146 void PetscMatrix<Scalar>::free()
148 if (inited) MatDestroy(&matrix);
152 template<
typename Scalar>
153 void PetscMatrix<Scalar>::finish()
155 MatAssemblyBegin(matrix, MAT_FINAL_ASSEMBLY);
156 MatAssemblyEnd(matrix, MAT_FINAL_ASSEMBLY);
160 double PetscMatrix<double>::get(
unsigned int m,
unsigned int n)
const
163 MatGetValues(matrix, 1, (PetscInt*)&m, 1, (PetscInt*)&n, &pv);
164 return PetscRealPart(pv);
167 #ifdef PETSC_USE_COMPLEX
169 std::complex<double> PetscMatrix<std::complex<double> >::get(
unsigned int m,
unsigned int n)
const
171 std::complex<double> v = 0.0;
172 MatGetValues(matrix, 1, (PetscInt*)&m, 1, (PetscInt*)&n, &v);
177 std::complex<double> PetscMatrix<std::complex<double> >::get(
unsigned int m,
unsigned int n)
const
179 throw(Exceptions::Exception(
"PETSc with complex numbers support required."));
183 template<
typename Scalar>
184 void PetscMatrix<Scalar>::zero()
186 MatZeroEntries(matrix);
189 #ifdef PETSC_USE_COMPLEX
190 inline PetscScalar to_petsc(
double x)
192 return std::complex<double>(x, 0);
195 inline PetscScalar to_petsc(std::complex<double> x)
200 inline PetscScalar to_petsc(
double x)
204 inline PetscScalar to_petsc(std::complex<double> x)
206 throw(Exceptions::Exception(
"PETSc with complex numbers support required."));
210 template<
typename Scalar>
211 void PetscMatrix<Scalar>::add(
unsigned int m,
unsigned int n, Scalar v)
215 #pragma omp critical (PetscMatrix_add)
216 MatSetValue(matrix, (PetscInt)m, (PetscInt)n, to_petsc(v), ADD_VALUES);
220 template<
typename Scalar>
221 void PetscMatrix<Scalar>::export_to_file(
const char *filename,
const char *var_name,
MatrixExportFormat fmt,
char* number_format)
223 throw Exceptions::MethodNotImplementedException(
"PetscVector<double>::export_to_file");
236 template<
typename Scalar>
237 unsigned int PetscMatrix<Scalar>::get_nnz()
const
242 template<
typename Scalar>
243 double PetscMatrix<Scalar>::get_fill_in()
const
245 return (
double)nnz / ((double)this->size*this->size);
248 template<
typename Scalar>
249 void PetscMatrix<Scalar>::add_petsc_matrix(PetscMatrix<Scalar>* mat)
252 MatAXPY(matrix, 1, mat->matrix, DIFFERENT_NONZERO_PATTERN);
255 template<
typename Scalar>
256 void PetscMatrix<Scalar>::add_sparse_matrix(SparseMatrix<Scalar>* mat)
258 PetscMatrix<Scalar>* mat_petsc = (PetscMatrix<Scalar>*)mat;
260 this->add_petsc_matrix(mat_petsc);
267 template<
typename Scalar>
268 void PetscMatrix<Scalar>::multiply_with_Scalar(Scalar value)
270 MatScale(matrix, to_petsc(value));
273 template<
typename Scalar>
274 void PetscMatrix<Scalar>::create(
unsigned int size,
unsigned int nnz,
int* ap,
int* ai, Scalar* ax)
278 PetscScalar* pax = malloc_with_check<PetscScalar>(nnz,
this);
279 for (
unsigned i = 0; i < nnz; i++)
280 pax[i] = to_petsc(ax[i]);
281 MatCreateSeqAIJWithArrays(PETSC_COMM_SELF, size, size, ap, ai, pax, &matrix);
285 template<
typename Scalar>
286 PetscMatrix<Scalar>* PetscMatrix<Scalar>::duplicate()
const
288 PetscMatrix<Scalar>*ptscmatrix =
new PetscMatrix<Scalar>();
289 MatDuplicate(matrix, MAT_COPY_VALUES, &(ptscmatrix->matrix));
290 ptscmatrix->size = this->size;
291 ptscmatrix->nnz = nnz;
295 template<
typename Scalar>
296 PetscVector<Scalar>::PetscVector()
302 template<
typename Scalar>
303 PetscVector<Scalar>::~PetscVector()
306 remove_petsc_object();
309 template<
typename Scalar>
310 void PetscVector<Scalar>::alloc(
unsigned int n)
314 VecCreateSeq(PETSC_COMM_SELF, this->size, &vec);
318 template<
typename Scalar>
319 void PetscVector<Scalar>::free()
321 if (inited) VecDestroy(&vec);
325 template<
typename Scalar>
326 void PetscVector<Scalar>::finish()
328 VecAssemblyBegin(vec);
333 double PetscVector<double>::get(
unsigned int idx)
const
336 VecGetValues(vec, 1, (PetscInt*)&idx, &py);
337 return PetscRealPart(py);
339 #ifdef PETSC_USE_COMPLEX
341 std::complex<double> PetscVector<std::complex<double> >::get(
unsigned int idx)
const
343 std::complex<double> y = 0;
344 VecGetValues(vec, 1, (PetscInt*)&idx, &y);
349 std::complex<double> PetscVector<std::complex<double> >::get(
unsigned int idx)
const
351 throw(Exceptions::Exception(
"PETSc with complex numbers support required."));
355 template<
typename Scalar>
356 void PetscVector<Scalar>::extract(Scalar *v)
const
358 int *idx = malloc_with_check<int>(this->size);
359 for (
unsigned int i = 0; i < this->size; i++) idx[i] = i;
360 vec_get_value(vec, this->size, idx, v);
361 free_with_check(idx);
364 template<
typename Scalar>
365 void PetscVector<Scalar>::zero()
370 template<
typename Scalar>
373 PetscScalar* y = malloc_with_check<PetscScalar>(this->size);
374 int *idx = malloc_with_check<int>(this->size);
375 for (
unsigned int i = 0; i < this->size; i++) idx[i] = i;
376 VecGetValues(vec, this->size, idx, y);
377 for (
unsigned int i = 0; i < this->size; i++) y[i] *= -1.;
378 VecSetValues(vec, this->size, idx, y, INSERT_VALUES);
380 free_with_check(idx);
384 template<
typename Scalar>
385 void PetscVector<Scalar>::set(
unsigned int idx, Scalar y)
387 VecSetValue(vec, idx, to_petsc(y), INSERT_VALUES);
390 template<
typename Scalar>
391 void PetscVector<Scalar>::add(
unsigned int idx, Scalar y)
393 #pragma omp critical (PetscVector_add)
394 VecSetValue(vec, idx, to_petsc(y), ADD_VALUES);
397 template<
typename Scalar>
398 void PetscVector<Scalar>::add(
unsigned int n,
unsigned int *idx, Scalar *y)
401 for (
unsigned int i = 0; i < n; i++)
403 VecSetValue(vec, idx[i], to_petsc(y[i]), ADD_VALUES);
407 template<
typename Scalar>
408 Vector<Scalar>* PetscVector<Scalar>::add_vector(Vector<Scalar>* vec)
410 assert(this->get_size() == vec->get_size());
411 for (
unsigned int i = 0; i < this->get_size(); i++)
412 this->add(i, vec->get(i));
416 template<
typename Scalar>
417 Vector<Scalar>* PetscVector<Scalar>::add_vector(Scalar* vec)
419 for (
unsigned int i = 0; i < this->get_size(); i++)
420 this->add(i, vec[i]);
424 template<
typename Scalar>
425 void PetscVector<Scalar>::export_to_file(
const char *filename,
const char *var_name,
MatrixExportFormat fmt,
char* number_format)
427 throw Exceptions::MethodNotImplementedException(
"PetscVector<double>::export_to_file");
440 template class HERMES_API PetscMatrix < double > ;
441 template class HERMES_API PetscMatrix < std::complex<double> > ;
442 template class HERMES_API PetscVector < double > ;
443 template class HERMES_API PetscVector < std::complex<double> > ;
447 template<
typename Scalar>
448 PetscLinearMatrixSolver<Scalar>::PetscLinearMatrixSolver(PetscMatrix<Scalar> *mat, PetscVector<Scalar> *rhs)
449 : DirectSolver<Scalar>(mat, rhs), m(mat), rhs(rhs)
454 template<
typename Scalar>
455 PetscLinearMatrixSolver<Scalar>::~PetscLinearMatrixSolver()
457 remove_petsc_object();
460 template<
typename Scalar>
461 int PetscLinearMatrixSolver<Scalar>::get_matrix_size()
463 return m->get_size();
466 template<
typename Scalar>
467 void PetscLinearMatrixSolver<Scalar>::solve()
469 assert(m !=
nullptr);
470 assert(rhs !=
nullptr);
478 KSPCreate(PETSC_COMM_WORLD, &ksp);
480 KSPSetOperators(ksp, m->matrix, m->matrix, DIFFERENT_NONZERO_PATTERN);
481 KSPSetFromOptions(ksp);
482 VecDuplicate(rhs->vec, &x);
484 ec = KSPSolve(ksp, rhs->vec, x);
488 this->time = this->accumulated();
491 free_with_check(this->sln);
492 this->sln = malloc_with_check<Scalar>(m->get_size());
493 memset(this->sln, 0, m->get_size() *
sizeof(Scalar));
496 int *idx = malloc_with_check<int>(m->get_size());
497 for (
unsigned int i = 0; i < m->get_size(); i++) idx[i] = i;
500 vec_get_value(x, m->get_size(), idx, this->sln);
501 free_with_check(idx);
507 template class HERMES_API PetscLinearMatrixSolver < double > ;
508 template class HERMES_API PetscLinearMatrixSolver < std::complex<double> > ;
General namespace for the Hermes library.
Exception interface Basically a std::exception, but with a constructor with string and with print_msg...
File containing common definitions, and basic global enums etc. for HermesCommon. ...
MatrixExportFormat
Format of file matrix and vector output.
virtual void add_sparse_matrix(SparseMatrix< Scalar > *mat)
File containing functionality for investigating call stack.
void change_sign(T **matrix, unsigned int m, unsigned int n)
Changes the sign of a matrix.
File containing common definitions, and basic global enums etc. for HermesCommon. ...