13#if defined(PETSC_D) || defined(PETSC_Z)
20 template <
typename _Type>
26 if (m_version !=
"petsc") {
28 problem =
"The SparseLinearSystem has been instantiated with an unrecognised\n";
29 problem +=
"request for a solver type. Options: 'petsc'. \n";
33 if(m_version ==
"petsc") {
34#if !defined(PETSC_D) && !defined(PETSC_Z)
36 problem =
"The SparseLinearSystem has been instantiated for a petsc solver.\n";
37 problem +=
"HOWEVER, CppNoddy was not compiled with PETSC_D or PETSC_Z defined.\n";
42#if defined(PETSC_D) || defined(PETSC_Z)
43 if(m_version ==
"petsc") {
45 MPI_Initialized(&flag);
48 problem =
"The SparseLinearSystem has been instantiated for a petsc solver.\n";
49 problem +=
"You must call PetscInitialize before calling the petsc solver.\n";
56 template<
typename _Type>
61 template<
typename _Type>
63#if defined(PETSC_D) || defined(PETSC_Z)
66 VecDestroy(&m_petsc_x);
67 VecDestroy(&m_petsc_B);
68 KSPDestroy(&m_petsc_ksp);
74 template <
typename _Type>
76 if(
"petsc" == m_version) {
78 solve_using_factorisation();
81 problem =
"CppNoddy needs to be linked to PETSc to solve sparse\n";
82 problem +=
"linear systems.";
96 problem =
"CppNoddy is linked against the COMPLEX version of PETSc\n";
97 problem +=
"but you are trying to factorise a DOUBLE matrix. Either\n";
98 problem +=
"redefine your matrix as complex, or recompile with $PETSC_ARCH\n";
99 problem +=
"pointing to a DOUBLE version of the PETSc code.";
111 PetscInt Istart,Iend,n;
119 VecCreate(PETSC_COMM_WORLD,&m_petsc_B);
120 VecSetSizes(m_petsc_B,PETSC_DECIDE,m_pA->nrows());
122 VecSetFromOptions(m_petsc_B);
124 VecDuplicate(m_petsc_B,&m_petsc_x);
128 MatCreate(PETSC_COMM_WORLD,&petsc_A);
130 MatSetSizes(petsc_A,PETSC_DECIDE,PETSC_DECIDE,n,n);
132 MatSetFromOptions(petsc_A);
135 PetscInt* all_rows_nnz =
new PetscInt[ n ];
136 m_pA -> nelts_all_rows(all_rows_nnz);
140 MatSeqAIJSetPreallocation(petsc_A, 0, all_rows_nnz);
143 MatSetFromOptions(petsc_A);
150 MatGetOwnershipRange(petsc_A,&Istart,&Iend);
152 for(PetscInt i = Istart; i<Iend; ++i) {
154 std::size_t nelts_in_row = all_rows_nnz[i];
156 PetscInt* cols =
new PetscInt[all_rows_nnz[i]];
158 PetscScalar* storage =
new PetscScalar[all_rows_nnz[i]];
160 m_pA -> get_row_petsc(i, storage, cols);
161 MatSetValues(petsc_A,1,&i,nelts_in_row,cols,storage,INSERT_VALUES);
169 MatAssemblyBegin(petsc_A,MAT_FINAL_ASSEMBLY);
170 MatAssemblyEnd(petsc_A,MAT_FINAL_ASSEMBLY);
176 KSPCreate(PETSC_COMM_WORLD,&m_petsc_ksp);
177 KSPSetOperators(m_petsc_ksp,petsc_A,petsc_A);
183 KSPGetPC(m_petsc_ksp,&m_petsc_pc);
189 KSPSetFromOptions(m_petsc_ksp);
190 KSPSetUp(m_petsc_ksp);
193 PCFactorGetMatrix(m_petsc_pc,&m_petsc_F);
232 MatDestroy(&petsc_A);
233 delete[] all_rows_nnz;
245 problem =
"CppNoddy is linked against the COMPLEX version of PETSc\n";
246 problem +=
"but you are trying to solve a DOUBLE matrix. Either\n";
247 problem +=
"redefine your matrix as complex, or recompile with $PETSC_ARCH\n";
248 problem +=
"pointing to a DOUBLE version of the PETSc code.";
253 PetscInt n = m_pA -> nrows();
256 for(PetscInt i = 0; i < n; ++i) {
257 VecSetValue(m_petsc_B,i,m_pB->operator[](i),INSERT_VALUES);
263 KSPSolve(m_petsc_ksp,m_petsc_B,m_petsc_x);
272 VecScatterCreateToAll(m_petsc_x,&ctx,&y);
274 VecScatterBegin(ctx,m_petsc_x,y,INSERT_VALUES,SCATTER_FORWARD);
275 VecScatterEnd(ctx,m_petsc_x,y,INSERT_VALUES,SCATTER_FORWARD);
277 VecScatterDestroy(&ctx);
280 VecGetArray(y,&array);
282 for(PetscInt i=0; i<n; i++) {
283 m_pB -> operator[](i) = array[i];
286 VecRestoreArray(m_petsc_x,&array);
304 problem =
"CppNoddy is linked against the DOUBLE version of PETSc\n";
305 problem +=
"but you are trying to factorise a COMPLEX matrix.\n";
306 problem +=
"Recompile with $PETSC_ARCH\n";
307 problem +=
"pointing to a COMPLEX version of the PETSc code.";
319 PetscInt Istart,Iend,n;
327 VecCreate(PETSC_COMM_WORLD,&m_petsc_B);
328 VecSetSizes(m_petsc_B,PETSC_DECIDE,m_pA->nrows());
329 VecSetFromOptions(m_petsc_B);
330 VecDuplicate(m_petsc_B,&m_petsc_x);
333 MatCreate(PETSC_COMM_WORLD,&A);
335 MatSetSizes(A,PETSC_DECIDE,PETSC_DECIDE,n,n);
336 MatSetFromOptions(A);
339 PetscInt* all_rows_nnz =
new PetscInt[ n ];
340 m_pA -> nelts_all_rows(all_rows_nnz);
344 MatSeqAIJSetPreallocation(A, 0, all_rows_nnz);
352 MatGetOwnershipRange(A,&Istart,&Iend);
354 for(PetscInt i = Istart; i<Iend; ++i) {
356 std::size_t nelts_in_row = all_rows_nnz[i];
358 PetscInt* cols =
new PetscInt[nelts_in_row];
360 PetscScalar* storage =
new PetscScalar[nelts_in_row];
362 m_pA -> get_row_petsc(i, storage, cols);
363 MatSetValues(A,1,&i,nelts_in_row,cols,storage,INSERT_VALUES);
375 MatAssemblyBegin(A,MAT_FINAL_ASSEMBLY);
376 MatAssemblyEnd(A,MAT_FINAL_ASSEMBLY);
382 KSPCreate(PETSC_COMM_WORLD,&m_petsc_ksp);
383 KSPSetOperators(m_petsc_ksp,A,A);
386 KSPGetPC(m_petsc_ksp,&m_petsc_pc);
394 KSPSetFromOptions(m_petsc_ksp);
396 KSPSetUp(m_petsc_ksp);
398 PCFactorGetMatrix(m_petsc_pc,&m_petsc_F);
423 delete[] all_rows_nnz;
435 problem =
"CppNoddy is linked against the DOUBLE version of PETSc\n";
436 problem +=
"but you are trying to solve e a COMPLEX matrix.\n";
437 problem +=
"Recompile with $PETSC_ARCH\n";
438 problem +=
"pointing to a COMPLEX version of the PETSc code.";
443 PetscInt n = m_pA -> nrows();
446 for(PetscInt i = 0; i < n; ++i) {
447 VecSetValue(m_petsc_B,i,m_pB->operator[](i),INSERT_VALUES);
453 KSPSolve(m_petsc_ksp,m_petsc_B,m_petsc_x);
462 VecScatterCreateToAll(m_petsc_x,&ctx,&y);
464 VecScatterBegin(ctx,m_petsc_x,y,INSERT_VALUES,SCATTER_FORWARD);
465 VecScatterEnd(ctx,m_petsc_x,y,INSERT_VALUES,SCATTER_FORWARD);
467 VecScatterDestroy(&ctx);
470 VecGetArray(y,&array);
472 for(PetscInt i=0; i<n; i++) {
473 m_pB -> operator[](i) = array[i];
476 VecRestoreArray(m_petsc_x,&array);
The collection of CppNoddy exceptions.
Specification of a sparse-storage linear system class.
A spec for the CppNoddy Timer object.
An DenseVector class – a dense vector object.
An exception to indicate that an error has been detected in an external (LAPACK) routine.
A generic runtime exception.
A linear system class for vector right-hand sides.
void factorise()
Factorise the Ax=B system.
void solve()
Solve the sparse system.
SparseLinearSystem(SparseMatrix< _Type > *Aptr, DenseVector< _Type > *Bptr, std::string which="native")
Constructor for a sparse linear system object.
void solve_using_factorisation()
Resolve the same system using the same factorisation.
void cleanup()
deallocates some objects
~SparseLinearSystem()
Destructor for a linear system object.
A matrix class that constructs a SPARSE matrix as a row major std::vector of SparseVectors.
A collection of OO numerical routines aimed at simple (typical) applied problems in continuum mechani...