@@ -42,19 +42,34 @@ subroutine solve_petsc_csr(n, ia, ja, aval, b, x, rtol, maxit)
4242 ! Create matrix with an estimated 7 nonzeros/row (adjust if needed)
4343 call MatCreateSeqAIJ(PETSC_COMM_SELF, n, n, 7 , PETSC_NULL_INTEGER, A, ierr)
4444
45+ ! Fill matrix from CSR format (ia, ja are 1-based Fortran indexing)
4546 do i = 1 , n
4647 row_nz = ia(i+1 ) - ia(i)
4748 if (row_nz > 0 ) then
4849 start_k = ia(i)
4950 allocate (cols0(row_nz), vals(row_nz))
50- cols0 = ja(start_k:start_k+ row_nz-1 ) - 1 ! zero-based
51+ ! Convert column indices from 1-based to 0-based for PETSc
52+ cols0 = ja(start_k:start_k+ row_nz-1 ) - 1
5153 vals = aval(start_k:start_k+ row_nz-1 )
54+
55+ ! Debug: print first row details
56+ if (i == 1 ) then
57+ write (* ,' (A,I0,A,I0)' ) ' Row 1: nnz=' , row_nz, ' , start_k=' , start_k
58+ write (* ,' (A,10I6)' ) ' 1-based cols:' , ja(start_k:min (start_k+9 ,start_k+ row_nz-1 ))
59+ write (* ,' (A,10I6)' ) ' 0-based cols:' , cols0(1 :min (10 ,row_nz))
60+ write (* ,' (A,10ES12.4)' ) ' vals:' , vals(1 :min (10 ,row_nz))
61+ end if
62+
63+ ! Set row i-1 (0-based) with column indices cols0 (0-based)
5264 call MatSetValues(A, 1 , (/ i-1 / ), row_nz, cols0, vals, INSERT_VALUES, ierr)
5365 deallocate (cols0, vals)
5466 end if
5567 end do
5668 call MatAssemblyBegin(A, MAT_FINAL_ASSEMBLY, ierr)
5769 call MatAssemblyEnd(A, MAT_FINAL_ASSEMBLY, ierr)
70+
71+ ! Optional: Verify matrix assembly (uncomment for debugging)
72+ ! call MatView(A, PETSC_VIEWER_STDOUT_SELF, ierr)
5873
5974 ! Create vectors
6075 call VecCreateSeq(PETSC_COMM_SELF, n, bb, ierr)
@@ -93,6 +108,10 @@ subroutine solve_petsc_csr(n, ia, ja, aval, b, x, rtol, maxit)
93108 call KSPGetIterationNumber(ksp, its, ierr)
94109 call KSPGetResidualNorm(ksp, rnorm, ierr)
95110
111+ ! Report convergence status (commented out by default for performance)
112+ ! Uncomment the next line to see convergence info every solve:
113+ ! write(*,'(A,I0,A,ES12.5,A,I0)') ' PETSc: iterations=', its, ', residual=', rnorm, ', reason=', reason
114+
96115 if (reason < 0 ) then
97116 write (0 ,* ) " WARNING: PETSc solver diverged or failed!"
98117 write (0 ,* ) " Reason code:" , reason
@@ -105,6 +124,37 @@ subroutine solve_petsc_csr(n, ia, ja, aval, b, x, rtol, maxit)
105124 call VecGetArrayF90(xx, xptr, ierr)
106125 x = xptr
107126 call VecRestoreArrayF90(xx, xptr, ierr)
127+
128+ ! Manual residual check: compute ||A*x - b||
129+ block
130+ real (8 ), allocatable :: Ax(:), residual(:)
131+ real (8 ) :: manual_rnorm, bnorm
132+ integer (8 ) :: i, k, start_k, row_nz
133+
134+ allocate (Ax(n), residual(n))
135+ Ax = 0.0_8
136+
137+ ! Compute A*x manually using CSR format
138+ do i = 1 , n
139+ row_nz = ia(i+1 ) - ia(i)
140+ if (row_nz > 0 ) then
141+ start_k = ia(i)
142+ do k = start_k, start_k + row_nz - 1
143+ Ax(i) = Ax(i) + aval(k) * x(ja(k))
144+ end do
145+ end if
146+ end do
147+
148+ residual = Ax - b
149+ manual_rnorm = sqrt (sum (residual** 2 ))
150+ bnorm = sqrt (sum (b** 2 ))
151+
152+ write (* ,' (A,ES15.7)' ) ' Manual residual check: ||A*x-b|| = ' , manual_rnorm
153+ write (* ,' (A,ES15.7)' ) ' ||b|| = ' , bnorm
154+ write (* ,' (A,ES15.7)' ) ' ||A*x-b||/||b|| = ' , manual_rnorm/ bnorm
155+
156+ deallocate (Ax, residual)
157+ end block
108158
109159 ! Cleanup
110160 deallocate (idx)
0 commit comments