Skip to content

Commit 2e26177

Browse files
committed
Fixed petsc
1 parent ac8835c commit 2e26177

5 files changed

Lines changed: 120 additions & 11 deletions

File tree

src/heatflow/mod_evolve.f90

Lines changed: 32 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,9 @@ module evolution
3737

3838
private
3939
public :: simulate
40+
41+
! Module-level variables for PETSc (persist across time steps)
42+
integer, allocatable, save :: ia32(:), ja32(:) ! 32-bit copies for PETSc
4043

4144
contains
4245

@@ -52,7 +55,6 @@ subroutine simulate(itime)
5255
integer:: ncg, itol, itmax !, iss
5356
integer :: iter
5457
real(real12) :: e, err, tol
55-
integer, allocatable :: ia32(:), ja32(:) ! 32-bit copies for PETSc
5658
integer :: NA32
5759

5860
!----------------------
@@ -117,6 +119,16 @@ subroutine simulate(itime)
117119
!---------------------------------------------
118120
if ( iSteady .eq. 0 ) then
119121
S = - inverse_time * Temp_p * lin_rhoc - Qdens - B
122+
if (IVERB .gt. 3) then
123+
write(*,*) "S construction diagnostics:"
124+
write(*,*) " inverse_time =", inverse_time
125+
write(*,*) " Temp_p avg =", sum(Temp_p)/size(Temp_p)
126+
write(*,*) " lin_rhoc avg =", sum(lin_rhoc)/size(lin_rhoc)
127+
write(*,*) " Qdens avg =", sum(Qdens)/size(Qdens)
128+
write(*,*) " B avg =", sum(B)/size(B)
129+
write(*,*) " -inverse_time*Temp_p*lin_rhoc avg =", sum(-inverse_time*Temp_p*lin_rhoc)/size(Temp_p)
130+
write(*,*) " S before S_CAT avg =", sum(S)/size(S)
131+
end if
120132
if ( iCAttaneo .eq. 1) then
121133
S = S + S_CAT
122134
end if
@@ -159,6 +171,17 @@ subroutine simulate(itime)
159171
x = Temp_p + (Temp_p - Temp_pp)
160172
if (any(x - Temp_p .lt. TINY)) x = x + TINY ! avoid nan solver issue
161173

174+
! Debug: Print initial guess statistics
175+
if (IVERB .gt. 3) then
176+
write(*,*) "========== PETSc Solver Diagnostics =========="
177+
write(*,*) "Time step:", itime
178+
write(*,*) "Initial guess x: min=", minval(x), " max=", maxval(x), " avg=", sum(x)/size(x)
179+
write(*,*) "RHS S: min=", minval(S), " max=", maxval(S), " avg=", sum(S)/size(S)
180+
write(*,*) "Temp_p: min=", minval(Temp_p), " max=", maxval(Temp_p), " avg=", sum(Temp_p)/size(Temp_p)
181+
write(*,*) "Matrix acsr: min=", minval(acsr), " max=", maxval(acsr), " avg=", sum(acsr)/size(acsr)
182+
write(*,*) "Matrix size: n=", NA32, " nnz=", size(acsr)
183+
end if
184+
162185
! Convert to 32-bit integers for PETSc (only on first call)
163186
if (.not. allocated(ia32)) then
164187
allocate(ia32(size(ia)), ja32(size(ja)))
@@ -169,6 +192,14 @@ subroutine simulate(itime)
169192

170193
call solve_petsc_csr(NA32, ia32, ja32, acsr, S, x, tol, itmax)
171194

195+
! Debug: Print solution statistics and verify solution
196+
if (IVERB .gt. 3) then
197+
write(*,*) "Solution x after PETSc: min=", minval(x), " max=", maxval(x), " avg=", sum(x)/size(x)
198+
write(*,*) "Temperature change: avg(x-Temp_p)=", sum(x-Temp_p)/size(x)
199+
write(*,*) "Max temperature change: ", maxval(abs(x-Temp_p))
200+
write(*,*) "=============================================="
201+
end if
202+
172203
! Note: Don't deallocate ia32, ja32 - keep them for next time step
173204

174205

src/heatflow/mod_heating.f90

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -181,7 +181,7 @@ subroutine heater(itime, Q, Qdens)
181181

182182

183183
! Normalize all heat sources by the heated volume
184-
shared_power = .False.
184+
shared_power = .TRUE.
185185
if (shared_power) then
186186
if (heated_volume .gt. 0.0) then
187187
Qdens(:) = Q(:) / heated_volume

src/heatflow/mod_petsc_solver.f90

Lines changed: 51 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -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)

src/heatflow/mod_setup.f90

100644100755
Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@ subroutine set_global_variables()
3737
integer(int12) :: ix,iy,iz,index
3838
real(real12) :: kappa,kappa3D,h_conv,heat_capacity,rho,sound_speed,tau, em
3939
real(real12), dimension(3) :: vel
40+
4041
allocate(Temp_cur(nx, ny, nz))
4142
allocate(Temp_p(NA))
4243
allocate(Temp_pp(NA))
@@ -82,7 +83,6 @@ subroutine set_global_variables()
8283
! Allocate the arrays to hold the H matrix in CSR format
8384
allocate(acsr(ra%len), ja(ra%len), ia(ra%n+1))
8485
CALL coo2csr(ra%n, ra%len, ra%val, ra%irow, ra%jcol, acsr, ja, ia)
85-
! print*, ra%val
8686
end if
8787
!^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
8888

@@ -106,7 +106,7 @@ subroutine sparse_Hmatrix()
106106
if (Periodicz) len = len + 2*nx*ny
107107
ra%n = NA ! The number of rows in the H matrix
108108
ra%len = len ! The number of non-zero elements in the H matrix
109-
! Allocate the arrays to hold the H matrix in sparse row storage
109+
! Allocate the arrays to hold the H matrix in sparse storage
110110
allocate(ra%val(len), ra%irow(len), ra%jcol(len))
111111
ra%val(:)=0
112112
ra%irow(:)=-2
@@ -147,7 +147,6 @@ subroutine sparse_Hmatrix()
147147
ra%irow(count) = i ! The row of the H matrix
148148
ra%jcol(count) = j ! The column of the H matrix
149149
count = count + 1 ! The number of non-zero elements in the H matrix
150-
H0=hmatrixfunc(j,i) ! The value of the H matrix
151150
ra%val(count) = H0 ! The value of the H matrix
152151
ra%irow(count) = j ! The row of the H matrix
153152
ra%jcol(count) = i ! The column of the H matrix

src/heatflow/mod_sparse_solver.f90

Lines changed: 34 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -60,10 +60,14 @@ subroutine coo2csr( nrow, &
6060
integer(kind=8), dimension(nrow+1), intent(out) :: ia
6161

6262
! Local variables.
63-
integer (kind=8) :: i, iad, j, k, k0
63+
integer (kind=8) :: i, iad, j, k, k0, row_start
64+
integer (kind=8) :: dup_count
6465
real(kind=8) :: x
66+
logical :: found_dup
67+
integer(kind=8), dimension(nrow+1) :: ia_save ! Save original row starts
6568

6669
ia(1:nrow+1) = 0
70+
dup_count = 0
6771

6872
! determine the row lengths.
6973

@@ -83,20 +87,45 @@ subroutine coo2csr( nrow, &
8387

8488
end do
8589

90+
! Save the original row pointers
91+
ia_save = ia
92+
8693
! go through the structure once more. fill in output matrix.
94+
! This version handles duplicate (i,j) entries by summing them.
8795

8896
do k = 1, nnz
8997

9098
i = ir(k)
9199
j = jc(k)
92100
x = a(k)
93-
iad = ia(i)
94-
acsr(iad) = x
95-
ja(iad) = j
96-
ia(i) = iad + 1
101+
102+
! Search for existing entry in this row with same column
103+
found_dup = .false.
104+
row_start = ia_save(i)
105+
do iad = row_start, ia(i)-1
106+
if (ja(iad) == j) then
107+
! Found duplicate - sum the values
108+
acsr(iad) = acsr(iad) + x
109+
found_dup = .true.
110+
dup_count = dup_count + 1
111+
exit
112+
end if
113+
end do
114+
115+
if (.not. found_dup) then
116+
! New entry - insert it
117+
iad = ia(i)
118+
acsr(iad) = x
119+
ja(iad) = j
120+
ia(i) = iad + 1
121+
end if
97122

98123
end do
99124

125+
if (dup_count > 0) then
126+
write(*,'(A,I0,A)') 'WARNING: COO->CSR found and summed ', dup_count, ' duplicate entries'
127+
end if
128+
100129
! shift back ia.
101130

102131
do j = nrow, 1, -1

0 commit comments

Comments
 (0)