Skip to content

110 add convection term#114

Open
HarryMclean wants to merge 31 commits intomainfrom
110-add-convection-term
Open

110 add convection term#114
HarryMclean wants to merge 31 commits intomainfrom
110-add-convection-term

Conversation

@HarryMclean
Copy link
Copy Markdown
Collaborator

This merge is because while we didn't fully implement the convection term, we did implement, PETsc library's for solving and output file compression.

HarryMclean and others added 27 commits September 2, 2025 13:05
…tFlow into 110-add-convection-term

Fixed merge
…ry output transiant output

Added a new input flag _CompressedOutput to param.in to enable binary 'stream' output in mod_output.f90. Also added a USER_MANUAL.md to docs/.
@HarryMclean HarryMclean requested a review from Copilot March 26, 2026 18:24
@HarryMclean HarryMclean self-assigned this Mar 26, 2026
@HarryMclean HarryMclean linked an issue Mar 26, 2026 that may be closed by this pull request
Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR modernizes HeatFlow’s solve and output pipeline in preparation for adding a convection term, by introducing a PETSc-based linear solver, switching the sparse H-matrix build to CSR, and adding optional compressed (binary) output plus per-material velocity input.

Changes:

  • Add a new PETSc KSP-based solver and wire it into the time evolution.
  • Build the H matrix directly into CSR arrays (acsr/ia/ja) rather than the previous sparse format path.
  • Add _CompressedOutput and binary stream output, and add vel to materials/grid cells.

Reviewed changes

Copilot reviewed 16 out of 16 changed files in this pull request and generated 16 comments.

Show a summary per file
File Description
src/heatflow/mod_setup.f90 Builds CSR H-matrix (acsr/ia/ja) and adds progress logging.
src/heatflow/mod_petsc_solver.f90 New PETSc wrapper to solve CSR systems with configurable preconditioning.
src/heatflow/mod_evolve.f90 Switches evolution solve step to PETSc CSR solver; adds diagnostics and CSR integer conversion.
src/heatflow/mod_output.f90 Adds optional compressed binary output (.bin) and uses global logname.
src/heatflow/mod_inputs.f90 Adds _CompressedOutput flag and parses material vel vector.
src/heatflow/mod_constructions.f90 Adds vel to heatblock and material types; removes some unused material fields.
src/heatflow/mod_material.f90 Extends material() to output vel; adjusts assignments for input-driven materials.
src/heatflow/mod_global.f90 Adds CSR arrays and global logname.
src/heatflow/mod_hmatrix.f90 Adds (currently commented-out) hooks and helpers for convection conductivity.
src/heatflow/mod_heating.f90 Updates heater logic and adds new heater cases; modifies tau usage and comments out radiative term.
src/heatflow.f90 Initializes/finalizes PETSc in the main program.
Makefile Reworks build to include PETSc headers/libs and separate compilation/link steps.
docs/USER_MANUAL.md Adds a new user manual covering inputs and run instructions.
src/.vscode/settings.json Adds nested VS Code settings under src/.
README.md Fixes install path capitalization (HeatFlow).
src/heatflow/mod_tempdep.f90 Comments out temperature-dependent property update hook.
src/heatflow/mod_boundary.f90 Adds (commented-out) boundary convection term scaffolding.
Comments suppressed due to low confidence (1)

src/heatflow/mod_setup.f90:129

  • sparse_Hmatrix allocates acsr/ja/ia every time it is called without first deallocating existing allocations. If this routine can be invoked more than once per run (e.g., for temperature-dependent properties or test harnesses), this will leak memory or error on re-allocation. Add if (allocated(...)) deallocate(...) before allocating, or reuse existing arrays when possible.
      if (Periodicx) addit = [addit, (nx-1)]
      if (ny .gt. 1) addit = [addit, nx] ! Add the values to add to the row to get the column
      if ((Periodicy).and.(ny .gt. 1)) addit = [addit, (ny-1)*nx]
      if (nz .gt. 1) addit = [addit, nx*ny]  ! Add the values to add to the row to get the column
      if ((Periodicz).and.(nz .gt. 1)) addit = [addit, (nz-1)*ny*nx]


💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines +49 to +68
#### Flags (Logical)
All flags default to `.False.`. Set to `.True.` (or `T`) to enable.
- `_Check_Sparse_Full`: Check if simulation is sparse or full.
- `_Check_Stability`: Perform stability check.
- `_Check_Steady_State`: Check for steady state convergence.
- `_WriteToTxt`: Enable writing output to text files.
- `_Percentage_Completion`: Show progress % in output.
- `_Test_Run`: Flag for test runs.
- `_InputTempDis`: Load initial temperature distribution from file.
- `_FullRestart`: Perform a full restart.

#### Output Control
Defines the region of the grid to write to output.
| Keyword | Type | Default | Description |
| :--- | :--- | :--- | :--- |
| `write_every` | Integer | `1` | Write output every N steps. |
| `start_ix`, `end_ix` | Integer | `1`..`Nx` | X-range for output. |
| `start_iy`, `end_iy` | Integer | `1`..`Ny` | Y-range for output. |
| `start_iz`, `end_iz` | Integer | `1`..`Nz` | Z-range for output. |

Copy link

Copilot AI Mar 26, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The user manual documents many param.in flags, but it doesn't mention the new _CompressedOutput flag or describe the binary stream output format (.bin) produced when it is enabled. Add documentation for _CompressedOutput (default, file naming, and how to read the binary layout: timestamp followed by the subregion temperature array).

Copilot uses AI. Check for mistakes.
Comment on lines +411 to +418
! if not an edge element
if ((x_in .ge. 1) .and. (x_in .le. nx) .and. (y_in .ge. 1) .and. &
(y_in .le. ny) .and. (z_in .ge. 1) .and. (z_in .le. nz)) then

rho = grid(x_out,y_out,z_out)%rho
CV = grid(x_out,y_out,z_out)%heat_capacity
vel_in = grid(x_in,y_in,z_in)%vel
vel_out = grid(x_out,y_out,z_out)%vel
Copy link

Copilot AI Mar 26, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

calculate_convective_conductivity only bounds-checks the in indices, but then unconditionally reads grid(x_out,y_out,z_out) for rho/CV/vel_out/Length. If this is called for boundary neighbors (e.g., x_out = 0 or nx+1 when convection terms are enabled), it will access out-of-bounds memory. Add bounds checks for the out indices (or route boundary cases through a dedicated boundary-term routine).

Copilot uses AI. Check for mistakes.
Comment on lines +120 to +125
if (CompressedOutput) then
write(*, *) 'Writing Temperature (Compressed) to file'
open(logunit,file=logname, status='unknown', access='stream', position='append')
write(logunit) real((itime-1)*(time_step), kind=real12)
write(logunit) (Temp_cur(start_ix:end_ix, start_iy:end_iy, start_iz:end_iz))
close(logunit)
Copy link

Copilot AI Mar 26, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same issue as the initial write: this OPEN uses access='stream' but doesn't specify form='unformatted' even though the code performs unformatted write(logunit) operations. This will fail at runtime on many compilers unless FORM is set appropriately.

Copilot uses AI. Check for mistakes.
Comment on lines +185 to +194
! Convert to 32-bit integers for PETSc (only on first call)
if (.not. allocated(ia32)) then
allocate(ia32(size(ia)), ja32(size(ja)))
ia32 = int(ia, kind=kind(ia32))
ja32 = int(ja, kind=kind(ja32))
end if
NA32 = int(NA, kind=kind(NA32))

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

Copy link

Copilot AI Mar 26, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

solve_petsc_csr requires PETSc to be initialized via PetscInitialize, but simulate calls it unconditionally and the module doesn't enforce initialization. This breaks non-main entry points (e.g., unit tests or any caller that invokes simulate without calling petsc_init). Consider initializing PETSc lazily (once) inside the PETSc wrapper, or adding/using an explicit init guard and updating callers/tests accordingly.

Copilot uses AI. Check for mistakes.
area = grid(ix,iy,iz)%Length(1)*grid(ix,iy,iz)%Length(2) !???
!tau divided by time_step squared in setup.f90
tau = grid(ix,iy,iz)%tau*(time_step**2.0_real12)
tau = grid(ix,iy,iz)%tau*(time_step)
Copy link

Copilot AI Mar 26, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

grid%tau is stored as tau/time_step^2 in setup (grid%tau = tau*inverse_time*inverse_time), and both hmatrix and the previous heater logic assume that scaling. Multiplying by only time_step here yields tau/time_step rather than the physical tau, which will change the Cattaneo/heater transient terms. This should likely be time_step**2 (or adjust the stored scaling consistently everywhere).

Suggested change
tau = grid(ix,iy,iz)%tau*(time_step)
tau = grid(ix,iy,iz)%tau*(time_step**2)

Copilot uses AI. Check for mistakes.
Comment on lines 706 to 712
CALL assignD(buffer,"heat_capacity",dum_mat(i)%heat_capacity,readvarmat(1))! assign heatCapacity
CALL assignD(buffer,"h_conv" ,dum_mat(i)%h_conv ,readvarmat(2))! assign h_conv
CALL assignD(buffer,"kappa" ,dum_mat(i)%kappa ,readvarmat(3))! assign kappa
CALL assignD(buffer,"kappa3D" ,dum_mat(i)%kappa3D ,readvarmat(4))! assign kappa3D
CALL assignD(buffer,"rho" ,dum_mat(i)%rho ,readvarmat(5))! assign rho
CALL assignD(buffer,"sound_speed" ,dum_mat(i)%sound_speed ,readvarmat(6))! assign sound_speed
CALL assignD(buffer,"tau" ,dum_mat(i)%tau ,readvarmat(7))! assign tau
CALL assignD(buffer,"em" ,dum_mat(i)%em ,readvarmat(8))! assign e
CALL assignD(buffer,"kappa" ,dum_mat(i)%kappa ,readvarmat(2))! assign kappa
CALL assignD(buffer,"rho" ,dum_mat(i)%rho ,readvarmat(3))! assign rho
CALL assignD(buffer,"tau" ,dum_mat(i)%tau ,readvarmat(4))! assign tau
CALL assignD(buffer,"em" ,dum_mat(i)%em ,readvarmat(5))! assign e
CALL assignV(buffer,"vel" ,dum_mat(i)%vel ,readvarmat(6)) ! assign velocity
end do read
Copy link

Copilot AI Mar 26, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

With readvarmat now tracking only 6 fields and vel included, every material block in mat.in must specify vel or the parser will stop with an error (any(readvarmat .ne. 1)). This is a breaking input-format change; consider defaulting vel to (0,0,0) and not requiring it in the completeness check, or document that vel is mandatory for all materials.

Copilot uses AI. Check for mistakes.
Comment on lines +206 to 211

deallocate(row_vals, row_cols)
write(*,'(A,I12,A)') " CSR matrix built successfully. Actual nonzeros: ", count, ""
end subroutine sparse_Hmatrix
!!!#################################################################################################

Copy link

Copilot AI Mar 26, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The comment says the CSR arrays "will grow if needed", but the code writes into acsr/ja with no bounds check and no growth logic. If nnz_estimate is ever underestimated (e.g., due to stencil/periodic logic changes), this will write past the end of the arrays. Add a count+row_count > size(acsr) check and reallocate/grow safely (or compute nnz exactly up-front).

Copilot uses AI. Check for mistakes.
write(logunit,*) real((itime-1)*(time_step)), &
(Temp_cur(start_ix:end_ix, start_iy:end_iy, start_iz:end_iz))
if (CompressedOutput) then
open(logunit,file=logname, status='unknown', access='stream', position='append')
Copy link

Copilot AI Mar 26, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

When CompressedOutput is enabled the file is opened as access='stream' but the subsequent write(logunit) statements are unformatted. Without form='unformatted' on the OPEN, this will be a runtime I/O error (default FORM is formatted). Update the OPEN to explicitly use unformatted stream (and keep it consistent in both compressed write sites).

Suggested change
open(logunit,file=logname, status='unknown', access='stream', position='append')
open(logunit,file=logname, status='unknown', access='stream', form='unformatted', position='append')

Copilot uses AI. Check for mistakes.
write(*,*) "RHS S: min=", minval(S), " max=", maxval(S), " avg=", sum(S)/size(S)
write(*,*) "Temp_p: min=", minval(Temp_p), " max=", maxval(Temp_p), " avg=", sum(Temp_p)/size(Temp_p)
write(*,*) "Matrix acsr: min=", minval(acsr), " max=", maxval(acsr), " avg=", sum(acsr)/size(acsr)
write(*,*) "Matrix size: n=", NA32, " nnz=", size(acsr)
Copy link

Copilot AI Mar 26, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

NA32 is printed in the PETSc diagnostics before it is assigned (it is only set a few lines later). This can print a garbage matrix size and makes debugging misleading; assign NA32 before this block or print NA directly.

Suggested change
write(*,*) "Matrix size: n=", NA32, " nnz=", size(acsr)
write(*,*) "Matrix size: n=", NA, " nnz=", size(acsr)

Copilot uses AI. Check for mistakes.
Comment on lines +1 to +5
{
"python-envs.defaultEnvManager": "ms-python.python:conda",
"python-envs.defaultPackageManager": "ms-python.python:conda",
"python-envs.pythonProjects": []
} No newline at end of file
Copy link

Copilot AI Mar 26, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This adds editor-specific VS Code Python environment settings under src/.vscode/. The repo already has a top-level .vscode/settings.json, so this nested settings file is likely accidental and can cause inconsistent workspace behavior. Consider removing src/.vscode/settings.json and keeping editor config only at the repo root (or add it to .gitignore).

Suggested change
{
"python-envs.defaultEnvManager": "ms-python.python:conda",
"python-envs.defaultPackageManager": "ms-python.python:conda",
"python-envs.pythonProjects": []
}
{}

Copilot uses AI. Check for mistakes.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Add convection term

4 participants