Skip to content

Three component phase separation for ultramassive white dwarfs, part 2#863

Draft
evbauer wants to merge 23 commits into
mainfrom
three_component_PS
Draft

Three component phase separation for ultramassive white dwarfs, part 2#863
evbauer wants to merge 23 commits into
mainfrom
three_component_PS

Conversation

@evbauer

@evbauer evbauer commented Sep 30, 2025

Copy link
Copy Markdown
Member

Updated code in phase_separation.f90 and a new wd_o_ne_3_phase test suite.

Updated code in phase_separation.f90 and a new wd_o_ne_3_phase test suite.
@evbauer evbauer self-assigned this Sep 30, 2025
@evbauer

evbauer commented Sep 30, 2025

Copy link
Copy Markdown
Member Author

@mcastrotapia I've pushed a few "housekeeping" fixes to get the static analysis script to pass, so you might want to merge this branch into your fork to stay up to date.

Anyway, this PR will eventually be the one that merges the code into main once I get a chance to review the substance of the code. So I'll either leave comments/questions here for you or push changes directly on this branch. If you end up needing to push substantial code updates, you can open a new PR onto this three_component_PS branch, and then if we merge them those changes will eventually make their way into MESA main via this PR.

Thanks for submitting this code!

@mcastrotapia

Copy link
Copy Markdown

Thanks for the fixes and for reviewing the PR! I will merge the branch into my fork, and I'll be attentive to comments/questions and updates.

Comment thread star/private/phase_separation.f90 Outdated
Comment thread star/private/phase_separation.f90 Outdated
Comment thread star/private/phase_separation.f90 Outdated
if(s% phase(s% nz) < eos_phase_boundary) then !!! prevent to move the core size inwards if the core is suddently "melted" leaving everything liquid under phi<0.9
if (s% crystal_core_boundary_mass>0d0)then
s% crystal_core_boundary_mass=s% crystal_core_boundary_mass
return

@evbauer evbauer Apr 13, 2026

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

I see why you might need something like this, but I'm not sure this is the best approach in general. One alternative I've experimented with is just redistributing the phase separation heating over a significant fraction of the interior. That way you avoid transient local heating spikes that might melt the core, but still get the net right amount of energy deposited in the interior, which seems to work for capturing the effect on cooling rate. @mcastrotapia do you think that could be a viable alternative here?

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

I think it is a good alternative. At some point, I tried something similar, but I didn't have success, and I ended up doing this because it seemed easier and faster to implement.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

Ok, I introduced the heat redistribution in 5519a13. Let's see if that works instead.

Comment on lines -90 to -93
! Check that we're still in C/O or O/Ne dominated material as appropriate,
! otherwise skip phase separation
if(components == 'CO'.and. XO + XC < 0.9d0) return
if(components == 'ONe'.and. XNe + XO < 0.8d0) return ! O/Ne mixtures tend to have more byproducts of burning mixed in

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

I believe we need to bring these lines back. Is there an argument for deleting them?

They shouldn't affect the new 3-componenent functionality that we're trying to add here, and I'd like to keep the behavior of the 2-component options unchanged unless there is a compelling reason to change them.

@mcastrotapia mcastrotapia Apr 14, 2026

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

I deleted them when trying to let the code decide for itself if doing C/O or O/Ne in the case of 2-component phase separation, this is because in ultramassive WD models the core is usually O/Ne, but towards the outer layers there is a C/O dominated zone before reaching the H/He atmosphere (for example, Figure 2 of Camisassa et al., 2019). In the 3-component, I was also letting the code check which were the 3 most abundant elements in the liquid zone to decide which phase diagram must be used.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

The bigger concern here is when you get all the way out to the interface with the He envelope, at which point I want to make sure phase separation ends. We can return to make a final decision on this once I refactor into separate 2-component and 3-component logic.

Comment thread star/private/phase_separation.f90 Outdated
Comment thread star/private/phase_separation.f90 Outdated

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

Note to self for later: update run_star_extras, rn script, etc to make this a fully-fledged test case and integrate it into do1_test_source for the test suite.

Comment thread star/private/phase_separation.f90 Outdated
@evbauer

evbauer commented Apr 15, 2026

Copy link
Copy Markdown
Member Author

We'll also need to add some documentation of the new options in controls.defaults.

Comment thread star/private/phase_separation.f90 Outdated
Comment on lines +568 to +578
iounit=998
! setup interpolation table for tau sob eta
if (components=='CONe') then
open(unit=iounit, file='CONe_deltaO.dat', action='read',status='old')
else if (components=='NeOMg') then
open(unit=iounit, file='NeOMg_deltaO.dat', action='read',status='old')
else if (components=='ONeNa') then
open(unit=iounit, file='ONeNa_deltaO.dat', action='read',status='old')
else if (components=='COMg') then
open(unit=iounit, file='COMg_deltaMg.dat', action='read',status='old')
end if

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Use newunit:

Suggested change
iounit=998
! setup interpolation table for tau sob eta
if (components=='CONe') then
open(unit=iounit, file='CONe_deltaO.dat', action='read',status='old')
else if (components=='NeOMg') then
open(unit=iounit, file='NeOMg_deltaO.dat', action='read',status='old')
else if (components=='ONeNa') then
open(unit=iounit, file='ONeNa_deltaO.dat', action='read',status='old')
else if (components=='COMg') then
open(unit=iounit, file='COMg_deltaMg.dat', action='read',status='old')
end if
! setup interpolation table for tau sob eta
if (components=='CONe') then
open(newunit=iounit, file='CONe_deltaO.dat', action='read',status='old')
else if (components=='NeOMg') then
open(newunit=iounit, file='NeOMg_deltaO.dat', action='read',status='old')
else if (components=='ONeNa') then
open(newunit=iounit, file='ONeNa_deltaO.dat', action='read',status='old')
else if (components=='COMg') then
open(newunit=iounit, file='COMg_deltaMg.dat', action='read',status='old')
end if

Comment thread star/private/phase_separation.f90 Outdated
Comment on lines +491 to +501
iounit=999
! setup interpolation table for x1 x2 dx1
if (components=='CONe') then
open(unit=iounit, file='CONe_deltaC.dat', action='read',status='old')
else if (components=='NeOMg') then
open(unit=iounit, file='NeOMg_deltaMg.dat', action='read',status='old')
else if (components=='ONeNa') then
open(unit=iounit, file='ONeNa_deltaNa.dat', action='read',status='old')
else if (components=='COMg') then
open(unit=iounit, file='COMg_deltaC.dat', action='read',status='old')
end if

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Use newunit:

Suggested change
iounit=999
! setup interpolation table for x1 x2 dx1
if (components=='CONe') then
open(unit=iounit, file='CONe_deltaC.dat', action='read',status='old')
else if (components=='NeOMg') then
open(unit=iounit, file='NeOMg_deltaMg.dat', action='read',status='old')
else if (components=='ONeNa') then
open(unit=iounit, file='ONeNa_deltaNa.dat', action='read',status='old')
else if (components=='COMg') then
open(unit=iounit, file='COMg_deltaC.dat', action='read',status='old')
end if
! setup interpolation table for x1 x2 dx1
if (components=='CONe') then
open(newunit=iounit, file='CONe_deltaC.dat', action='read',status='old')
else if (components=='NeOMg') then
open(newunit=iounit, file='NeOMg_deltaMg.dat', action='read',status='old')
else if (components=='ONeNa') then
open(newunit=iounit, file='ONeNa_deltaNa.dat', action='read',status='old')
else if (components=='COMg') then
open(newunit=iounit, file='COMg_deltaC.dat', action='read',status='old')
end if

@evbauer

evbauer commented Jun 15, 2026

Copy link
Copy Markdown
Member Author

Converting the plain text .dat files to hdf5 has saved quite a bit of space. The previous files took up about 250 MB, and the hdf5 files now take up only 5.4 MB. This will probably save some time on file i/o as well. However, I'm now getting a crash in a call to set_micro_vars after 3 component phase separation gets underway in the test case, so I'll need to check if I've translated everything properly.

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.

4 participants