Skip to content

Renaming dust_density array to dust_density_o_n_grains for clarity#173

Merged
cpinte merged 5 commits into
mainfrom
dust_density_fix
May 13, 2026
Merged

Renaming dust_density array to dust_density_o_n_grains for clarity#173
cpinte merged 5 commits into
mainfrom
dust_density_fix

Conversation

@cpinte

@cpinte cpinte commented May 1, 2026

Copy link
Copy Markdown
Owner

Type of PR:
Bug fix / new physics / modification to existing code / other

Description:
Give a short description of the change.

Testing:
Describe how you have tested the change

Did you run the botscheck that the code and comments follow the code of conduct? yes/no

Did you update relevant documentation in the docs directory? yes/no

@gemini-code-assist gemini-code-assist Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Code Review

This pull request renames the dust_density variable to dust_density_o_n_grains across the codebase to clarify its definition as density divided by the number of grains. It also updates the Makefile to support HDF5 on Apple Silicon (Darwin arm64) and removes several debug print statements. The review feedback identifies multiple instances in density.f90 and SPH2mcfost.f90 where the new division by n_grains(k) could cause a division-by-zero error if a grain size bin is empty, suggesting the addition of safety checks to ensure numerical stability.

Comment thread src/density.f90 Outdated
endif
do i=1, n_rad
dust_density(k,cell_map(i,j,phik)) = sph_dens(i,jj,phik,1)
dust_density_o_n_grains(k,cell_map(i,j,phik)) = sph_dens(i,jj,phik,1) / n_grains(k)

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

high

Potential division by zero if n_grains(k) is zero. While n_grains is typically positive in MCFOST, it's safer to check for zero values to avoid runtime crashes or NaNs, especially since this division is a new addition in this PR.

                    if (n_grains(k) > 0.0_dp) then
                       dust_density_o_n_grains(k,cell_map(i,j,phik)) = sph_dens(i,jj,phik,1) / n_grains(k)
                    else
                       dust_density_o_n_grains(k,cell_map(i,j,phik)) = 0.0_dp
                    endif

Comment thread src/density.f90 Outdated
if (j==0) cycle
do i=1, n_rad
dust_density(k,cell_map(i,j,phik)) = sph_dens(i,jj,phik,n_a)
dust_density_o_n_grains(k,cell_map(i,j,phik)) = sph_dens(i,jj,phik,n_a) / n_grains(k)

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

high

Potential division by zero if n_grains(k) is zero. A safety check is recommended here as well to handle potentially empty grain size bins.

                    if (n_grains(k) > 0.0_dp) then
                       dust_density_o_n_grains(k,cell_map(i,j,phik)) = sph_dens(i,jj,phik,n_a) / n_grains(k)
                    else
                       dust_density_o_n_grains(k,cell_map(i,j,phik)) = 0.0_dp
                    endif

Comment thread src/density.f90 Outdated
Comment on lines +1728 to +1729
dust_density_o_n_grains(k,cell_map(i,j,phik)) = &
( sph_dens(i,jj,phik,l) + f * ( sph_dens(i,jj,phik,l+1) - sph_dens(i,jj,phik,l) ) ) / n_grains(k)

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

high

Potential division by zero if n_grains(k) is zero. A safety check should be added to handle cases where a grain size bin might be empty in the distribution.

                    if (n_grains(k) > 0.0_dp) then
                       dust_density_o_n_grains(k,cell_map(i,j,phik)) = &
                            ( sph_dens(i,jj,phik,l) + f * ( sph_dens(i,jj,phik,l+1) -  sph_dens(i,jj,phik,l) ) ) / n_grains(k)
                    else
                       dust_density_o_n_grains(k,cell_map(i,j,phik)) = 0.0_dp
                    endif

Comment thread src/SPH2mcfost.f90 Outdated
do k=1,n_grains_tot
if (r_grain(k) < a_SPH(1)) then ! small grains
dust_density(k,icell) = rho_dust(1) / n_grains(k)
dust_density_o_n_grains(k,icell) = rho_dust(1) / n_grains(k)

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

high

Potential division by zero if n_grains(k) is zero. This new division should be protected with a check to ensure numerical stability.

                   if (n_grains(k) > 0.0_dp) then
                      dust_density_o_n_grains(k,icell) = rho_dust(1) / n_grains(k)
                   else
                      dust_density_o_n_grains(k,icell) = 0.0_dp
                   endif

Comment thread src/SPH2mcfost.f90 Outdated
dust_density_o_n_grains(k,icell) = rho_dust(1) / n_grains(k)
else if (r_grain(k) > a_SPH(ndusttypes+1)) then ! large grains
dust_density(k,icell) = rho_dust(ndusttypes+1) / n_grains(k)
dust_density_o_n_grains(k,icell) = rho_dust(ndusttypes+1) / n_grains(k)

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

high

Potential division by zero if n_grains(k) is zero.

                   if (n_grains(k) > 0.0_dp) then
                      dust_density_o_n_grains(k,icell) = rho_dust(ndusttypes+1) / n_grains(k)
                   else
                      dust_density_o_n_grains(k,icell) = 0.0_dp
                   endif

Comment thread src/SPH2mcfost.f90 Outdated
if (r_grain(k) > a_sph(l+1)) l = l+1
f = (log(r_grain(k))-log_a_sph(l))/(log_a_sph(l+1)-log_a_sph(l))
dust_density(k,icell) = (rho_dust(l) + f * (rho_dust(l+1) - rho_dust(l))) / n_grains(k)
dust_density_o_n_grains(k,icell) = (rho_dust(l) + f * (rho_dust(l+1) - rho_dust(l))) / n_grains(k)

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

high

Potential division by zero if n_grains(k) is zero.

                   if (n_grains(k) > 0.0_dp) then
                      dust_density_o_n_grains(k,icell) = (rho_dust(l) + f * (rho_dust(l+1)  - rho_dust(l))) / n_grains(k)
                   else
                      dust_density_o_n_grains(k,icell) = 0.0_dp
                   endif

@cpinte

cpinte commented May 13, 2026

Copy link
Copy Markdown
Owner Author

/gemini review

@gemini-code-assist gemini-code-assist Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Code Review

This pull request refactors the codebase by renaming the dust_density variable to dust_density_o_n_grains to clarify its physical definition. It also introduces logic to automatically detect variable dust sizes in FITS and Phantom input files, and updates the Makefile for Apple Silicon HDF5 support. Review feedback identified a bug in src/density.f90 where uninitialized loop indices are used in an else branch, potentially leading to incorrect memory access. Additionally, the logic for reading dust types from Phantom HDF5 headers was found to be fragile and requires more robust handling of optional fields.

Comment thread src/density.f90
Comment on lines +1748 to 1750
else
dust_density_o_n_grains(k,cell_map(i,j,phik)) = 0.0_dp
endif

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

high

The variables i, j, and phik are loop indices defined only within the if (n_grains(k) > 0.0_dp) block. In this else branch, they are either uninitialized or contain stale values from a previous iteration. Furthermore, using cell_map here only zeroes out a single cell, whereas the intention is likely to zero out the density for grain size k across all cells to avoid using uninitialized or invalid data.

        else
           dust_density_o_n_grains(k,:) = 0.0_dp
        endif

Comment thread src/read_phantom.f90
Comment on lines +54 to +61
call read_from_hdf5(ndustsmall,'ndustsmall',hdf5_group_id,got,ierr)
call read_from_hdf5(ndustlarge,'ndustlarge',hdf5_group_id,got,ierr)
if (got) then
ndusttypes = ndustsmall + ndustlarge
else
ndusttypes = 0
endif
endif

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

medium

The logic for determining ndusttypes from ndustsmall and ndustlarge is fragile. The got variable is overwritten by the second call, and if ndustsmall is present but ndustlarge is not, ndusttypes will be incorrectly set to 0. Additionally, ndustsmall and ndustlarge should be initialized to 0 to avoid using junk values if they are not found in the HDF5 file.

         ndustsmall = 0
         ndustlarge = 0
         call read_from_hdf5(ndustsmall,'ndustsmall',hdf5_group_id,got,ierr)
         call read_from_hdf5(ndustlarge,'ndustlarge',hdf5_group_id,got,ierr)
         ndusttypes = ndustsmall + ndustlarge

@cpinte cpinte merged commit 0a04431 into main May 13, 2026
21 checks passed
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.

1 participant