Skip to content

Zero Temperature eos#842

Merged
danieljprice merged 19 commits into
danieljprice:mainfrom
AliPourmand:zeroT_eos
Jun 18, 2026
Merged

Zero Temperature eos#842
danieljprice merged 19 commits into
danieljprice:mainfrom
AliPourmand:zeroT_eos

Conversation

@AliPourmand

@AliPourmand AliPourmand commented Jun 16, 2026

Copy link
Copy Markdown
Contributor

Description:
A new module has been added: the zero temperature equation of state (see Kippenhahn 15.2). This is only considering degenerate pressure and internal energy. It is implemented mainly comparison purposes; the more accurate form of this is the Helmholtz EOS.

Components modified:

  • Setup (src/setup)
  • [ x] Main code (src/main)
  • Moddump utilities (src/utils/moddump)
  • Analysis utilities (src/utils/analysis)
  • Test suite (src/tests)
  • Documentation (docs/)
  • [x ] Build/CI (build/ or github actions)

Type of change:

  • Bug fix
  • [ x] Physics improvements
  • Better initial conditions
  • Performance improvements
  • Documentation update
  • Better testing
  • Code cleanup / refactor
  • Other (please describe)

Testing:
Relaxed and tested two different WD masses. They matched expectations

Did you run the bots? no
Did you update relevant documentation in the docs directory?no

Did you add comments such that the purpose of the code is understandable? yes

Is there a unit test that could be added for this feature/bug? maybe

Summary by CodeRabbit

Release Notes

  • New Features

    • Added a new zero-temperature equation of state option (ieos=25), including configurable species mass fractions and EOS calculations with reporting.
  • Enhancements

    • Updated Phantom data directory mapping to recognize data/star_data_files and link it to the correct external dataset.
  • Tests

    • Added a white-dwarf relaxation test that exercises initialization under both ieos=15 and ieos=25, validating error metrics and skipping with a warning when the dataset is missing.

…ion from kippenhahn in it. I just need to derive sound speed and add it there along with internal energy and a reverse function to find density from pressure, along with options in eos.f90
…or density from pressure. also decided to add chandra eos function to make things easier
…y testing it if there is anything else he thinks is necessary

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

Copy link
Copy Markdown
Contributor

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 introduces a new zero-temperature equation of state (EOS type 25) for white dwarfs, implemented in eos_zerotemp.f90 and integrated into the main eos.f90 module and build configuration. The review feedback highlights several critical areas for improvement, primarily focusing on adding defensive guards against zero or negative density and pressure values to prevent division-by-zero and mathematically undefined operations. Additionally, the feedback suggests using Taylor series expansions to prevent catastrophic cancellation at low densities in f_chandra and get_zerotemp_u, analytically simplifying the sound speed calculation, and immediately aborting with a fatal error if the mass fractions do not sum to one.

Important

The consumer version of Gemini Code Assist on GitHub is being sunset. Starting June 18, 2026, new organization installations will be blocked, and all code review activity will officially cease on July 17, 2026.
For more details on the timeline and next steps, please review the Help Documentation.

Comment thread src/main/eos.f90
Comment thread src/main/eos_zerotemp.f90
Comment thread src/main/eos_zerotemp.f90
Comment thread src/main/eos_zerotemp.f90
Comment thread src/main/eos_zerotemp.f90
Comment thread src/main/eos_zerotemp.f90
Comment thread src/main/eos_zerotemp.f90
@danieljprice

Copy link
Copy Markdown
Owner

@AliPourmand this looks pretty good but would it be possible to add some unit tests of this Eos in test_eos.f90? For example, a simple one would be to check that calling eos_helmholtz with temperature of zero gives the same answer...

@AliPourmand

AliPourmand commented Jun 16, 2026

Copy link
Copy Markdown
Contributor Author

I don't know if Coulomb interactions would still play a role with Helmholtz EOS at T=0 though, so my guess is that isn't a good test. ( actually when i relax the same MESA star with both helmholtz and zerotemp, helmholtz recreates the MESA star accurately at the core where it is T~0 but zero temp doesn't and part of the reason is probably what I said)

… test in test_setstar. the subroutine there called test_whitedwarf will relax the star with eos helmholtz and eos zerotemp. not done testing it yet though
…ste stuff into the root directory to test, but this issue I had before too so its fine
@coderabbitai

coderabbitai Bot commented Jun 18, 2026

Copy link
Copy Markdown

Review Change Stack

Note

Reviews paused

It looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review
📝 Walkthrough

Walkthrough

A new Fortran module eos_zerotemp is added implementing a zero-temperature electron-degenerate EOS (Chandrasekhar degeneracy pressure, bisection density inversion, composition-based mu_e). It is registered in eos.f90 as ieos=25 across all dispatcher hooks. A white dwarf set_star test and a Zenodo data URL are also added.

Changes

Zero-temperature EOS (ieos=25)

Layer / File(s) Summary
New eos_zerotemp module: state, physics, I/O
src/main/eos_zerotemp.f90
Defines private species composition state (H, He, C, O, Ne, Mg mass fractions, mu_e), Chandrasekhar auxiliary function f_chandra, routines for pressure, internal energy, sound speed, bisection pressure-to-density inversion, and read/write/info I/O entry points.
EOS dispatcher wiring for ieos=25
src/main/eos.f90
Increases maxeos to 25 and adds case (25) branches in equationofstate, init_eos, calc_temp_and_ene, calc_rho_from_PT, eos_is_non_ideal, eos_allows_shock_and_work, eos_has_pressure_without_u, eosinfo, write_options_eos, and read_options_eos.
White dwarf test, data URL, build list
src/tests/test_setstar.f90, src/main/datafiles.f90, build/Makefile
Adds test_whitedwarf to run set_star with Helmholtz and ieos=25 against a MESA profile and compare density rms; registers data/star_data_files → Zenodo URL in map_dir_to_web; reformats the SRCEOS continuation line.

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~50 minutes

Poem

🐇 A white dwarf glimmers, cold and bright,
No temperature, just pressure's might!
Chandrasekhar shows the way,
Bisection finds the density each day.
mu_e computed, species in line —
ieos=25, the stars align! ✨

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Title check ✅ Passed The title 'Zero Temperature eos' directly and clearly summarizes the main change—the addition of a zero temperature equation of state module.
Description check ✅ Passed The PR description covers most required sections: a clear problem statement, components modified (Main code and Build/CI), type of change (Physics improvements), testing approach, and answers to documentation/comments/testing questions.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Comment @coderabbitai help to get the list of available commands and usage tips.

@coderabbitai coderabbitai 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.

Actionable comments posted: 4

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@src/main/eos_zerotemp.f90`:
- Around line 105-110: The species mass fraction variables (xh, xhe, xc, xo,
xne, xmg) are read using read_inopt without any validation of their bounds,
allowing invalid inputs like negative values to pass through. After each
read_inopt call for these variables, add validation checks to ensure each mass
fraction is within a valid physical range (typically 0.0 to 1.0). If a value is
out of range, increment nerr and log an appropriate error message to alert the
user to the invalid input before further calculations that depend on these
fractions are performed.
- Around line 267-295: When presi is zero or negative, the density inversion
should return zero density without attempting the bisection loop, as this
boundary case causes xmid to approach zero and the convergence criterion at line
290 fails due to division by near-zero. Add an explicit check for presi <= 0
before the bisection loop (before setting up xlo and xhi), and if presi is
non-positive, set the result to zero density (xmid = 0.0) and skip the iterative
algorithm entirely, avoiding the problematic division in the convergence check.

In `@src/tests/test_setstar.f90`:
- Line 478: The call to update_test_scores function at line 478 is a duplicate
that appears without any new assertion between it and a previous invocation,
causing test results to be double-counted. Remove this redundant call to
update_test_scores to ensure each test result is counted only once.
- Around line 441-458: The variable expected_error is used uninitialized in the
checkval call within the set_star test block, making the assertion
nondeterministic. Initialize expected_error to 0 before calling init_eos.
Additionally, add a radiation-conflict check after init_eos similar to the
pattern in test_redsupergiant that short-circuits and exits the current
iteration when radiation is enabled with an unsupported EOS, preventing the
set_star call and subsequent assertions from executing in those cases.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: 2f62b624-a827-4263-86f9-6e4ef7d0b0e5

📥 Commits

Reviewing files that changed from the base of the PR and between ceb4b3a and 3cabfed.

📒 Files selected for processing (5)
  • build/Makefile
  • src/main/datafiles.f90
  • src/main/eos.f90
  • src/main/eos_zerotemp.f90
  • src/tests/test_setstar.f90

Comment thread src/main/eos_zerotemp.f90
Comment thread src/main/eos_zerotemp.f90
Comment on lines +441 to +458
if (id==master) write(*,"(/,a,i2/)") '--> Testing ieos = ',ieos
call init_eos(ieos,ierr)

rmserr = 0.
call set_star(id,master,star,xyzh,vxyzu,eos_vars,rad,&
npart,npartoftype,massoftype,hfact,&
xyzmh_ptmass,vxyz_ptmass,nptmass,ieos,gamma,X_in,Z_in,&
relax=relax_star,use_var_comp=var_comp,write_rho_to_file=.false.,&
rhozero=rhozero,npart_total=ntot,mask=i_belong,ierr=ierr,&
write_files=.false.,density_error=rmserr,energy_error=ekin)


call checkval(ierr,expected_error,0,nfail(1),'set_star runs with expected ierr')
call update_test_scores(ntests,nfail,npass)

call check_setup(nerror,nwarn,restart=.false.)
call checkval(nerror+nwarn,0,0,nfail(1),'no errors or warnings')
call update_test_scores(ntests,nfail,npass)

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major | ⚡ Quick win

Initialize expected_error before assertion and mirror radiation-conflict handling.

At Line 453, expected_error is used uninitialized, so this check is nondeterministic. Also, when radiation is enabled with unsupported EOS, this test should short-circuit like test_redsupergiant.

Suggested fix
     if (id==master) write(*,"(/,a,i2/)") '--> Testing ieos = ',ieos
     call init_eos(ieos,ierr)
@@
-    call checkval(ierr,expected_error,0,nfail(1),'set_star runs with expected ierr')
+    if (do_radiation .and. (.not. eos_works_with_radiation(ieos))) then
+       expected_error = ierr_radiation_conflict
+    else
+       expected_error = 0
+    endif
+    call checkval(ierr,expected_error,0,nfail(1),'set_star runs with expected ierr')
     call update_test_scores(ntests,nfail,npass)
+    if (ierr == ierr_radiation_conflict) cycle
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
if (id==master) write(*,"(/,a,i2/)") '--> Testing ieos = ',ieos
call init_eos(ieos,ierr)
rmserr = 0.
call set_star(id,master,star,xyzh,vxyzu,eos_vars,rad,&
npart,npartoftype,massoftype,hfact,&
xyzmh_ptmass,vxyz_ptmass,nptmass,ieos,gamma,X_in,Z_in,&
relax=relax_star,use_var_comp=var_comp,write_rho_to_file=.false.,&
rhozero=rhozero,npart_total=ntot,mask=i_belong,ierr=ierr,&
write_files=.false.,density_error=rmserr,energy_error=ekin)
call checkval(ierr,expected_error,0,nfail(1),'set_star runs with expected ierr')
call update_test_scores(ntests,nfail,npass)
call check_setup(nerror,nwarn,restart=.false.)
call checkval(nerror+nwarn,0,0,nfail(1),'no errors or warnings')
call update_test_scores(ntests,nfail,npass)
if (id==master) write(*,"(/,a,i2/)") '--> Testing ieos = ',ieos
call init_eos(ieos,ierr)
rmserr = 0.
call set_star(id,master,star,xyzh,vxyzu,eos_vars,rad,&
npart,npartoftype,massoftype,hfact,&
xyzmh_ptmass,vxyz_ptmass,nptmass,ieos,gamma,X_in,Z_in,&
relax=relax_star,use_var_comp=var_comp,write_rho_to_file=.false.,&
rhozero=rhozero,npart_total=ntot,mask=i_belong,ierr=ierr,&
write_files=.false.,density_error=rmserr,energy_error=ekin)
if (do_radiation .and. (.not. eos_works_with_radiation(ieos))) then
expected_error = ierr_radiation_conflict
else
expected_error = 0
endif
call checkval(ierr,expected_error,0,nfail(1),'set_star runs with expected ierr')
call update_test_scores(ntests,nfail,npass)
if (ierr == ierr_radiation_conflict) cycle
call check_setup(nerror,nwarn,restart=.false.)
call checkval(nerror+nwarn,0,0,nfail(1),'no errors or warnings')
call update_test_scores(ntests,nfail,npass)
🧰 Tools
🪛 Fortitude (0.9.0)

[error] 441-441: String uses single quotes but double quotes preferred

(S241)


[error] 452-452: trailing whitespace

(S101)


[error] 453-453: String uses single quotes but double quotes preferred

(S241)


[error] 457-457: String uses single quotes but double quotes preferred

(S241)

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/tests/test_setstar.f90` around lines 441 - 458, The variable
expected_error is used uninitialized in the checkval call within the set_star
test block, making the assertion nondeterministic. Initialize expected_error to
0 before calling init_eos. Additionally, add a radiation-conflict check after
init_eos similar to the pattern in test_redsupergiant that short-circuits and
exits the current iteration when radiation is enabled with an unsupported EOS,
preventing the set_star call and subsequent assertions from executing in those
cases.

Comment thread src/tests/test_setstar.f90 Outdated

@coderabbitai coderabbitai 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.

♻️ Duplicate comments (1)
src/tests/test_setstar.f90 (1)

441-454: ⚠️ Potential issue | 🔴 Critical | ⚡ Quick win

expected_error is used uninitialized, making this assertion nondeterministic.

The variable expected_error declared at line 400 is never assigned before use at line 453. In Fortran, local variables have undefined values unless explicitly initialized. This test should mirror the pattern in test_redsupergiant (lines 304-308).

🐛 Proposed fix
     if (id==master) write(*,"(/,a,i2/)") '--> Testing ieos = ',ieos
     call init_eos(ieos,ierr)

     rmserr = 0.
     call set_star(id,master,star,xyzh,vxyzu,eos_vars,rad,&
                npart,npartoftype,massoftype,hfact,&
                xyzmh_ptmass,vxyz_ptmass,nptmass,ieos,gamma,X_in,Z_in,&
                relax=relax_star,use_var_comp=var_comp,write_rho_to_file=.false.,&
                rhozero=rhozero,npart_total=ntot,mask=i_belong,ierr=ierr,&
                write_files=.false.,density_error=rmserr,energy_error=ekin)

-  
+    if (do_radiation .and. (.not. eos_works_with_radiation(ieos))) then
+       expected_error = ierr_radiation_conflict
+    else
+       expected_error = 0
+    endif
     call checkval(ierr,expected_error,0,nfail(1),'set_star runs with expected ierr')
     call update_test_scores(ntests,nfail,npass)
+    if (ierr == ierr_radiation_conflict) cycle
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/tests/test_setstar.f90` around lines 441 - 454, The variable
`expected_error` is used uninitialized in the checkval function call after the
set_star invocation, which causes nondeterministic test behavior. Initialize
`expected_error` to an appropriate value before calling checkval at line 453,
following the same pattern used in the test_redsupergiant subroutine around
lines 304-308. This ensures the test has a deterministic expected error value to
compare against the actual ierr returned from set_star.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Duplicate comments:
In `@src/tests/test_setstar.f90`:
- Around line 441-454: The variable `expected_error` is used uninitialized in
the checkval function call after the set_star invocation, which causes
nondeterministic test behavior. Initialize `expected_error` to an appropriate
value before calling checkval at line 453, following the same pattern used in
the test_redsupergiant subroutine around lines 304-308. This ensures the test
has a deterministic expected error value to compare against the actual ierr
returned from set_star.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: 740a299d-bca0-468e-ba64-a0c1b0c7bbd8

📥 Commits

Reviewing files that changed from the base of the PR and between 83b4261 and 1396926.

📒 Files selected for processing (1)
  • src/tests/test_setstar.f90

@coderabbitai coderabbitai 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.

♻️ Duplicate comments (1)
src/tests/test_setstar.f90 (1)

400-454: ⚠️ Potential issue | 🔴 Critical | ⚡ Quick win

expected_error is used uninitialized, causing nondeterministic test results.

The variable expected_error is declared on line 400 but never assigned before use on line 453. The test_redsupergiant routine (lines 304-311) demonstrates the correct pattern with radiation-conflict handling.

Proposed fix

Update the use eos statement and add the conditional assignment:

-use eos,       only:init_eos,gamma,X_in,Z_in
+use eos,       only:init_eos,gamma,X_in,Z_in,eos_works_with_radiation
-use setstar,   only:star_t,set_star,set_defaults_star,imesa
+use setstar,   only:star_t,set_star,set_defaults_star,imesa,ierr_radiation_conflict

Then before the checkval call at line 453:

               write_files=.false.,density_error=rmserr,energy_error=ekin)

-  
-    call checkval(ierr,expected_error,0,nfail(1),'set_star runs with expected ierr')
+    if (do_radiation .and. (.not. eos_works_with_radiation(ieos))) then
+       expected_error = ierr_radiation_conflict
+    else
+       expected_error = 0
+    endif
+    call checkval(ierr,expected_error,0,nfail(1),'set_star runs with expected ierr')
     call update_test_scores(ntests,nfail,npass)
+    if (ierr == ierr_radiation_conflict) cycle
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/tests/test_setstar.f90` around lines 400 - 454, The variable
expected_error is declared on line 400 but never initialized before being used
in the checkval call around line 453, causing nondeterministic test results.
Following the pattern demonstrated in the test_redsupergiant routine (lines
304-311), add a conditional check before the checkval call to set expected_error
appropriately based on radiation conflict detection, ensuring the variable is
properly initialized with either 1 or 0 depending on whether radiation conflicts
occur during the set_star call for each EOS type tested in the loop.
🧹 Nitpick comments (1)
src/tests/test_setstar.f90 (1)

425-431: 💤 Low value

Remove unused variables.

Several variables are declared/initialized but never used, likely copy-paste artifacts from test_redsupergiant:

  • x0 (line 425)
  • ncheck, errmax (line 427)
  • Zfrac (line 431)
Proposed cleanup
-real :: rhozero,rmserr,ekin,x0(3),errmax(2)
+real :: rhozero,rmserr,ekin
 real :: Mstar,tolprof,rhoj,rhoj_mesa,rj
 integer(kind=8) :: ntot
-integer :: ierr,nfail(2),ncheck(2),i,j,nerror,nwarn,iunit,expected_error
+integer :: ierr,nfail(1),i,j,nerror,nwarn,iunit,expected_error
 logical :: relax_star,var_comp
-real, allocatable :: r(:),den(:),pres(:),temp(:),en(:),mtab(:),Xfrac(:),Yfrac(:),Zfrac(:),mu(:)
+real, allocatable :: r(:),den(:),pres(:),temp(:),en(:),mtab(:),Xfrac(:),Yfrac(:),mu(:)

And remove:

-x0 = 0.
-
-nfail = 0; ncheck = 0; errmax = 0.
+nfail = 0
 call read_mesa(filepath,den,r,pres,mtab,en,temp,X_in,Z_in,Xfrac,Yfrac,mu,Mstar,ierr)
-Zfrac = 1.-Xfrac-Yfrac
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/tests/test_setstar.f90` around lines 425 - 431, Remove the unused
variables that appear to be copy-paste artifacts from another test function.
Delete the initialization of x0 on line 425, remove ncheck and errmax from the
initialization statement on line 427 (keeping only nfail and tolprof), and
delete the Zfrac assignment on line 431 since these variables are never
referenced elsewhere in the test_setstar test function.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Duplicate comments:
In `@src/tests/test_setstar.f90`:
- Around line 400-454: The variable expected_error is declared on line 400 but
never initialized before being used in the checkval call around line 453,
causing nondeterministic test results. Following the pattern demonstrated in the
test_redsupergiant routine (lines 304-311), add a conditional check before the
checkval call to set expected_error appropriately based on radiation conflict
detection, ensuring the variable is properly initialized with either 1 or 0
depending on whether radiation conflicts occur during the set_star call for each
EOS type tested in the loop.

---

Nitpick comments:
In `@src/tests/test_setstar.f90`:
- Around line 425-431: Remove the unused variables that appear to be copy-paste
artifacts from another test function. Delete the initialization of x0 on line
425, remove ncheck and errmax from the initialization statement on line 427
(keeping only nfail and tolprof), and delete the Zfrac assignment on line 431
since these variables are never referenced elsewhere in the test_setstar test
function.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: c6b9257e-c4a6-472b-aa35-7fcfa0794782

📥 Commits

Reviewing files that changed from the base of the PR and between 1396926 and 6ae3714.

📒 Files selected for processing (1)
  • src/tests/test_setstar.f90

@danieljprice danieljprice merged commit fbf2c68 into danieljprice:main Jun 18, 2026
270 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.

2 participants