2121#endif
2222#ifdef NSE_NET
2323#include < nse_solver.H>
24- #include < nse_eos.H>
2524#endif
2625
2726using namespace amrex ::literals;
@@ -314,41 +313,43 @@ void nse_derivs(const amrex::Real rho0, const amrex::Real rhoe0,
314313 amrex::Real &drhoyedt_weak, amrex::Real& drhoedt,
315314 const amrex::Real T_fixed) {
316315
317- // start with the current state and compute T
316+ // initialize burn_state for NSE state
318317
319318 amrex::Real Ye0 = rhoYe0 / rho0;
320- amrex::Real abar{0 .0_rt};
321-
322- // Get initial temperature.
323-
324- if (T_fixed > 0 ) {
325- T0 = T_fixed;
326- } else {
327- // updates T0 to be consistent with e0 and NSE
328- amrex::Real e0 = rhoe0 / rho0;
329- nse_T_abar_from_e (rho0, e0 , Ye0, T0, abar, mu_p, mu_n);
330- }
331-
332- // initialize burn_state for NSE state
333319
334320 burn_t burn_state;
335321
336- burn_state.T = T0;
322+ burn_state.T = (T_fixed > 0 .0_rt) ? T_fixed : T0;
337323 burn_state.rho = rho0;
324+ burn_state.e = rhoe0 / rho0;
338325 burn_state.y_e = Ye0;
339326 burn_state.mu_p = mu_p;
340327 burn_state.mu_n = mu_n;
341328
342- // get NSE state at t0
329+ // Since internal energy is updated during integration,
330+ // we use (rho, e, Ye) as input to find the NSE state.
331+ // If T is fixed, i.e. T_fixed > 0, then use (rho, T, Ye)
332+
333+ auto nse_input = (T_fixed > 0 .0_rt) ? nse_input_rty : nse_input_rey;
334+ auto nse_state = get_actual_nse_state (nse_input, burn_state,
335+ 1 .0e-10_rt, true );
343336
344- auto nse_state0 = get_actual_nse_state (burn_state, 1 .0e-10_rt, true );
337+ // Update the input temperature, mu_p and mu_n with the new NSE state.
338+
339+ if (T_fixed <= 0 .0_rt) {
340+ T0 = nse_state.T ;
341+ }
342+ mu_p = nse_state.mu_p ;
343+ mu_n = nse_state.mu_n ;
345344
346345#ifdef NEUTRINOS
347346 // compute the plasma neutrino losses
348347
349- // Get abar
348+ // Get abar for neutrino
349+
350+ amrex::Real abar{0 .0_rt};
350351 for (int n = 0 ; n < NumSpec; ++n) {
351- abar += nse_state0 .xn [n] * aion_inv[n];
352+ abar += nse_state .xn [n] * aion_inv[n];
352353 }
353354 abar = 1 .0_rt / abar;
354355
@@ -373,13 +374,13 @@ void nse_derivs(const amrex::Real rho0, const amrex::Real rhoe0,
373374 amrex::Real e_nu {0 .0_rt};
374375
375376 for (int n = 1 ; n <= NumSpec; ++n) {
376- Y (n) = nse_state0 .xn [n-1 ] * aion_inv[n-1 ];
377+ Y (n) = nse_state .xn [n-1 ] * aion_inv[n-1 ];
377378 }
378379
379380 // Fill in ydot with only weak rates contributing
380381
381382 amrex::Array1D<amrex::Real, 1 , neqs> ydot_weak;
382- get_ydot_weak (nse_state0 , ydot_weak, e_nu, Y);
383+ get_ydot_weak (nse_state , ydot_weak, e_nu, Y);
383384
384385 // Find drhoyedt_weak from weak reaction
385386
@@ -431,34 +432,30 @@ void sdc_nse_burn(BurnT& state, const amrex::Real dt) {
431432 amrex::Real mu_p = state.mu_p ;
432433 amrex::Real mu_n = state.mu_n ;
433434
434- // density and momentum have no reactive sources
435-
436- state.y [SRHO] += dt * state.ydot_a [SRHO];
437- state.y [SMX] += dt * state.ydot_a [SMX];
438- state.y [SMY] += dt * state.ydot_a [SMY];
439- state.y [SMZ] += dt * state.ydot_a [SMZ];
440-
441435 // do an RK2 integration
442436
437+ // initialize derivatives needed
438+
443439 amrex::Real drhoedt{0 .0_rt};
444440 amrex::Real drhoyedt_weak{0 .0_rt};
445441 amrex::Real drhoyedt_a{0 .0_rt};
446442
447443 // find the advection contribution for ye: drhoyedt_a
444+ // The advection contribution is already time-centered
448445
449446 for (int n = 0 ; n < NumSpec; ++n) {
450447 drhoyedt_a += state.ydot_a [SFS+n] * zion[n] * aion_inv[n];
451448 }
452449
453- // get the derivatives, drhoyedt_weak and drhoedt at t = t^n
450+ // get the derivatives: drhoyedt_weak and drhoedt at t = t^n
454451
455452 nse_derivs (rho_old, rhoe_old,
456453 rhoye_old, T_old,
457454 mu_p, mu_n,
458455 drhoyedt_weak, drhoedt,
459456 state.T_fixed );
460457
461- // evolve to the midpoint in time
458+ // evolve to the midpoint in time and the midpoint NSE state.
462459
463460 amrex::Real rho_tmp = rho_old + 0 .5_rt * dt * state.ydot_a [SRHO];
464461 amrex::Real rhoe_tmp = rhoe_old + 0 .5_rt * dt * (state.ydot_a [SEINT] + drhoedt);
@@ -478,31 +475,19 @@ void sdc_nse_burn(BurnT& state, const amrex::Real dt) {
478475 amrex::Real rhoe_new = rhoe_old + dt * (state.ydot_a [SEINT] + drhoedt);
479476 amrex::Real rhoye_new = rhoye_old + dt * (drhoyedt_weak + drhoyedt_a);
480477
481- // Update the temperature with new internal energy
482-
483- amrex::Real T_new;
484- amrex::Real Ye_new = rhoye_new / rho_new;
485-
486- if (state.T_fixed > 0 ) {
487- T_new = state.T_fixed ;
488- } else {
489- // initial eos guess
490- T_new = T_old;
491- amrex::Real e_new = rhoe_new / rho_new;
492- amrex::Real abar_new;
493- nse_T_abar_from_e (rho_new, e_new, Ye_new, T_new, abar_new, mu_p, mu_n);
494- }
495-
496478 // With updated temp, rho, and Ye get final NSE state
497479
498480 burn_t burn_state;
499- burn_state.T = T_new ;
481+ burn_state.T = (state. T_fixed > 0 .0_rt) ? state. T_fixed : T_old ;
500482 burn_state.rho = rho_new;
501- burn_state.y_e = Ye_new;
483+ burn_state.e = rhoe_new / rho_new;
484+ burn_state.y_e = rhoye_new / rho_new;
502485 burn_state.mu_p = mu_p;
503486 burn_state.mu_n = mu_n;
504487
505- auto nse_state = get_actual_nse_state (burn_state, 1 .0e-10_rt, true );
488+ auto nse_input = (state.T_fixed > 0 .0_rt) ? nse_input_rty : nse_input_rey;
489+ auto nse_state = get_actual_nse_state (nse_input, burn_state,
490+ 1 .0e-10_rt, true );
506491
507492 // Update rho X using new NSE state
508493 // These should be already normalized due to NSE constraint
@@ -511,14 +496,23 @@ void sdc_nse_burn(BurnT& state, const amrex::Real dt) {
511496 state.y [SFS+n] = nse_state.y [SFS+n];
512497 }
513498
499+ // Update density and momentum, which have no reactive sources
500+
501+ state.y [SRHO] += dt * state.ydot_a [SRHO];
502+ state.y [SMX] += dt * state.ydot_a [SMX];
503+ state.y [SMY] += dt * state.ydot_a [SMY];
504+ state.y [SMZ] += dt * state.ydot_a [SMZ];
505+
514506 // Update total and internal energy.
515- // Note that density and momenta have already been updated before.
516507
517508 state.y [SEINT] = rhoe_new;
518509 state.y [SEDEN] += dt * (state.ydot_a [SEDEN] + drhoedt);
519510
520- // store the chemical potentials
511+ // Update chemical potentials and temperature
521512
513+ if (state.T_fixed <= 0 .0_rt) {
514+ state.T = nse_state.T ;
515+ }
522516 state.mu_p = nse_state.mu_p ;
523517 state.mu_n = nse_state.mu_n ;
524518}
0 commit comments