@@ -36,24 +36,25 @@ module phase_separation
36
36
37
37
logical , parameter :: dbg = .false.
38
38
39
- integer , parameter :: FIXED_PT_MODE = 5
40
- integer , parameter :: FIXED_DT_MODE = 6
41
-
42
39
! offset to higher phase than 0.5 to avoid interference
43
40
! between phase separation mixing and latent heat for Skye.
44
41
real (dp), parameter :: eos_phase_boundary = 0.9d0
45
42
46
43
contains
47
44
48
45
49
- subroutine do_phase_separation (s , ierr )
46
+ subroutine do_phase_separation (s , dt , ierr )
50
47
use chem_def, only: chem_isos, ic12, io16
51
48
use chem_lib, only: chem_get_iso_id
52
49
type (star_info), pointer :: s
50
+ real (dp), intent (in ) :: dt
53
51
integer , intent (out ) :: ierr
54
52
55
53
real (dp) :: dq_crystal, XO, XC, pad
56
54
integer :: k, k_bound, kstart, net_ic12, net_io16
55
+ logical :: save_Skye_use_ion_offsets
56
+
57
+ s% eps_phase_separation(:) = 0d0
57
58
58
59
if (s% phase(s% nz) < eos_phase_boundary) then
59
60
s% crystal_core_boundary_mass = 0d0
@@ -93,6 +94,15 @@ subroutine do_phase_separation(s, ierr)
93
94
exit
94
95
end if
95
96
end do
97
+
98
+ ! calculate energy associated with phase separation, ignoring the ionization
99
+ ! energy term that Skye sometimes calculates
100
+ save_Skye_use_ion_offsets = s% eos_rq% Skye_use_ion_offsets
101
+ s% eos_rq% Skye_use_ion_offsets = .false.
102
+ call update_model_(s,1 ,s% nz,.false. )
103
+ do k= 1 ,s% nz
104
+ s% eps_phase_separation(k) = s% energy(k)
105
+ end do
96
106
97
107
! loop runs outward starting at previous crystallization boundary
98
108
do k = kstart,1 ,- 1
@@ -111,6 +121,13 @@ subroutine do_phase_separation(s, ierr)
111
121
112
122
end do
113
123
124
+ call update_model_(s,1 ,s% nz,.false. )
125
+
126
+ ! phase separation heating term for use by energy equation
127
+ do k= 1 ,s% nz
128
+ s% eps_phase_separation(k) = (s% eps_phase_separation(k) - s% energy(k)) / dt
129
+ end do
130
+ s% eos_rq% Skye_use_ion_offsets = save_Skye_use_ion_offsets
114
131
s% need_to_setvars = .true.
115
132
end if
116
133
@@ -126,9 +143,6 @@ subroutine move_one_zone(s,k,dq_crystal)
126
143
127
144
real (dp) :: XC, XO, XC1, XO1, dXO, Xfac, dqsum
128
145
integer :: net_ic12, net_io16
129
- integer :: update_mode(s% nz)
130
-
131
- update_mode(:) = FIXED_DT_MODE
132
146
133
147
dq_crystal = dq_crystal + s% dq(k)
134
148
@@ -156,7 +170,7 @@ subroutine move_one_zone(s,k,dq_crystal)
156
170
s% xa(net_ic12,k-1 ) = XC1 + Xfac* dXO * s% dq(k) / s% dq(k-1 )
157
171
s% xa(net_io16,k-1 ) = XO1 - Xfac* dXO * s% dq(k) / s% dq(k-1 )
158
172
159
- call update_model_(s,update_mode, k-1 ,s% nz,.true. )
173
+ call update_model_(s,k-1 ,s% nz,.true. )
160
174
161
175
end subroutine move_one_zone
162
176
@@ -168,12 +182,10 @@ subroutine mix_outward(s,kbot)
168
182
integer , intent (in ) :: kbot
169
183
170
184
real (dp) :: avg_xa(s% species)
171
- real (dp) :: mass, XHe_out, dXC_top, dXC_bot, dXO_top, dXO_bot, B_term, grada, gradr
185
+ real (dp) :: mass, dXC_top, dXC_bot, dXO_top, dXO_bot, B_term, grada, gradr
172
186
integer :: k, l, ktop, net_ihe4, net_ic12, net_io16
173
- integer :: update_mode(s% nz)
174
187
logical :: use_brunt
175
188
176
- update_mode(:) = FIXED_DT_MODE
177
189
use_brunt = s% phase_separation_mixing_use_brunt
178
190
net_ihe4 = s% net_iso(ihe4)
179
191
net_ic12 = s% net_iso(ic12)
@@ -195,32 +207,14 @@ subroutine mix_outward(s,kbot)
195
207
! avg_xa = MAX(MIN(avg_xa, 1._dp), 0._dp)
196
208
! avg_xa = avg_xa/SUM(avg_xa)
197
209
198
- XHe_out = max (s% xa(net_ihe4,ktop),s% xa(net_ihe4,ktop-1 ))
199
- if (XHe_out < s% eos_rq% mass_fraction_limit_for_Skye) then
200
- ! ok to mix all species
201
- do l = 1 , s% species
202
- s% xa(l,ktop:kbot) = avg_xa(l)
203
- end do
204
- else
205
- ! Mixing He can cause energy problems for eps_phase_separation
206
- ! when using Skye, so once we encounter enough He that it is
207
- ! included in Skye energy calculation, stop mixing all species.
208
- ! Instead, just flatten out the O16 profile, and mix in exchange
209
- ! for C12.
210
- dXO_top = avg_xa(net_io16) - s% xa(net_io16,ktop)
211
- dXO_bot = avg_xa(net_io16) - s% xa(net_io16,kbot)
212
- s% xa(net_io16,ktop:kbot) = avg_xa(net_io16)
213
- dXC_top = - dXO_top
214
- dXC_bot = - dXO_bot
215
- s% xa(net_ic12,ktop) = s% xa(net_ic12,ktop) + dXC_top
216
- s% xa(net_ic12,ktop+1 :kbot) = s% xa(net_ic12,kbot) + dXC_bot
217
- end if
218
-
210
+ do l = 1 , s% species
211
+ s% xa(l,ktop:kbot) = avg_xa(l)
212
+ end do
219
213
220
214
! updates, eos, opacities, mu, etc now that abundances have changed,
221
215
! but only in the cells near the boundary where we need to check here.
222
216
! Will call full update over mixed region after exiting loop.
223
- call update_model_(s, update_mode, ktop-1 , ktop+1 , use_brunt)
217
+ call update_model_(s, ktop-1 , ktop+1 , use_brunt)
224
218
225
219
if (use_brunt) then
226
220
B_term = s% unsmoothed_brunt_B(ktop)
@@ -240,7 +234,7 @@ subroutine mix_outward(s,kbot)
240
234
end do
241
235
242
236
! Call a final update over all mixed cells now.
243
- call update_model_(s, update_mode, ktop, kbot, .true. )
237
+ call update_model_(s, ktop, kbot, .true. )
244
238
245
239
end subroutine mix_outward
246
240
@@ -276,30 +270,35 @@ real(dp) function blouin_delta_xo(Xin)
276
270
blouin_delta_xo = Xnew - Xin
277
271
end function blouin_delta_xo
278
272
279
- subroutine update_model_ (s , update_mode , kc_t , kc_b , do_brunt )
273
+ subroutine update_model_ (s , kc_t , kc_b , do_brunt )
280
274
281
275
use turb_info, only: set_mlt_vars
282
276
use brunt, only: do_brunt_B
283
277
use micro
284
278
285
279
type (star_info), pointer :: s
286
- integer , intent (in ) :: update_mode(:)
287
280
integer , intent (in ) :: kc_t
288
281
integer , intent (in ) :: kc_b
289
282
logical , intent (in ) :: do_brunt
290
283
291
284
integer :: ierr
292
285
integer :: kf_t
293
286
integer :: kf_b
294
-
287
+
288
+ logical :: mask(s% nz)
289
+
290
+ mask(:) = .true.
291
+
295
292
! Update the model to reflect changes in the abundances across
296
- ! cells kc_t:kc_b
297
-
298
- call set_eos_with_mask(s, kc_t, kc_b, update_mode== FIXED_DT_MODE, ierr)
293
+ ! cells kc_t:kc_b (the mask part of this call is unused, mask=true for all zones).
294
+ ! Do updates at constant (P,T) rather than constant (rho,T).
295
+ s% fix_Pgas = .true.
296
+ call set_eos_with_mask(s, kc_t, kc_b, mask, ierr)
299
297
if (ierr /= 0 ) then
300
298
write (* ,* ) ' phase_separation: error from call to set_eos_with_mask'
301
299
stop
302
300
end if
301
+ s% fix_Pgas = .false.
303
302
304
303
! Update opacities across cells kc_t:kc_b (this also sets rho_face
305
304
! and related quantities on faces kc_t:kc_b)
0 commit comments