Line data Source code
1 : ! ***********************************************************************
2 : !
3 : ! Copyright (C) 2010-2019 The MESA Team
4 : !
5 : ! This program is free software: you can redistribute it and/or modify
6 : ! it under the terms of the GNU Lesser General Public License
7 : ! as published by the Free Software Foundation,
8 : ! either version 3 of the License, or (at your option) any later version.
9 : !
10 : ! This program is distributed in the hope that it will be useful,
11 : ! but WITHOUT ANY WARRANTY; without even the implied warranty of
12 : ! MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
13 : ! See the GNU Lesser General Public License for more details.
14 : !
15 : ! You should have received a copy of the GNU Lesser General Public License
16 : ! along with this program. If not, see <https://www.gnu.org/licenses/>.
17 : !
18 : ! ***********************************************************************
19 :
20 : module do_one_utils
21 :
22 : use star_private_def
23 : use const_def, only: dp, ln10, secday, dayyer, clight, msun, rsun
24 : use utils_lib, only: is_bad
25 :
26 : implicit none
27 :
28 : private
29 : public :: do_one_check_model
30 : public :: write_terminal_header
31 : public :: do_bare_bones_check_model
32 : public :: do_check_limits
33 : public :: do_show_log_description
34 : public :: do_show_terminal_header
35 : public :: do_terminal_summary
36 :
37 : ! model log priorities
38 : integer, parameter :: delta_priority = 1
39 : integer, parameter :: phase_priority = 2
40 :
41 : contains
42 :
43 11 : logical function model_is_okay(s)
44 : type (star_info), pointer :: s
45 : ! for now, just check for valid number in the final dynamic timescale
46 : model_is_okay = ((s% dynamic_timescale - s% dynamic_timescale) == 0d0) &
47 : .and. ((s% dynamic_timescale + 1d0) > 1d0)
48 : end function model_is_okay
49 :
50 2 : subroutine set_save_profiles_info(s, model_priority)
51 : type (star_info), pointer :: s
52 : integer, intent(in) :: model_priority
53 2 : s% need_to_save_profiles_now = .true.
54 2 : s% save_profiles_model_priority = model_priority
55 2 : end subroutine set_save_profiles_info
56 :
57 :
58 2 : subroutine write_terminal_header(s)
59 : type (star_info), pointer :: s
60 2 : if (s% model_number <= s% recent_log_header) return
61 2 : if (s% just_wrote_terminal_header) return
62 2 : s% recent_log_header = s% model_number
63 2 : call do_show_terminal_header(s)
64 2 : s% just_wrote_terminal_header = .true.
65 : end subroutine write_terminal_header
66 :
67 :
68 0 : subroutine do_show_log_description(id, ierr)
69 : integer, intent(in) :: id
70 : integer, intent(out) :: ierr
71 : type (star_info), pointer :: s
72 : ierr = 0
73 0 : call get_star_ptr(id, s, ierr)
74 0 : if (ierr /= 0) return
75 0 : write(*,'(A)')
76 0 : write(*,'(a)') " The terminal output contains the following information"
77 0 : write(*,'(A)')
78 0 : write(*,'(a)') " 'step' is the number of steps since the start of the run,"
79 0 : write(*,'(a)') " 'lg_dt' is log10 timestep in years,"
80 0 : write(*,'(a)') " 'age_yr' is the simulated years since the start run,"
81 0 : write(*,'(a)') " 'lg_Tcntr' is log10 center temperature (K),"
82 0 : write(*,'(a)') " 'lg_Dcntr' is log10 center density (g/cm^3),"
83 0 : write(*,'(a)') " 'lg_Tmax' is log10 max temperature (K),"
84 0 : write(*,'(a)') " 'Teff' is the surface temperature (K),"
85 0 : write(*,'(a)') " 'lg_R' is log10 surface radius (Rsun),"
86 0 : write(*,'(a)') " 'lg_L' is log10 surface luminosity (Lsun),"
87 0 : write(*,'(a)') " 'lg_LH' is log10 total PP and CNO hydrogen burning power (Lsun),"
88 0 : write(*,'(a)') " 'lg_L3a' is log10 total triple-alpha helium burning power (Lsun),"
89 0 : write(*,'(a)') " 'lg_gsurf' is log10 surface gravity,"
90 0 : write(*,'(a)') " 'lg_Lnuc' is log10 nuclear power (Lsun),"
91 0 : write(*,'(a)') " 'lg_Lneu' is log10 total neutrino power (Lsun),"
92 0 : write(*,'(a)') " 'lg_Lphoto' is log10 total photodisintegration (Lsun),"
93 0 : write(*,'(a)') " 'Mass' is the total stellar baryonic mass (Msun),"
94 0 : write(*,'(a)') " 'lg_Mdot' is log10 magnitude of rate of change of mass (Msun/year),"
95 0 : write(*,'(a)') " 'lg_Dsurf' is log10 surface density (g/cm^3),"
96 0 : write(*,'(a)') " 'H_env' is the amount of mass where H is dominant,"
97 0 : write(*,'(a,e9.2)') " 'He_core' is the largest mass where He is dominant."
98 0 : write(*,'(a,e9.2)') " 'CO_core' is the largest mass where CO is dominant."
99 0 : write(*,'(a)') " 'H_cntr' is the center H1 mass fraction,"
100 0 : write(*,'(a)') " 'He_cntr' is the center He4 mass fraction,"
101 0 : write(*,'(a)') " 'C_cntr' is the center C12 mass fraction,"
102 0 : write(*,'(a)') " 'N_cntr' is the center N14 mass fraction,"
103 0 : write(*,'(a)') " 'O_cntr' is the center O16 mass fraction,"
104 0 : write(*,'(a)') " 'Ne_cntr' is the center Ne20 mass fraction,"
105 0 : write(*,'(a)') " 'gam_cntr' is the center plasma interaction parameter,"
106 0 : write(*,'(a)') " 'eta_cntr' is the center electron degeneracy parameter,"
107 0 : write(*,'(a)') " 'zones' is the number of zones in the current model,"
108 0 : write(*,'(a)') " 'iters' is the number of solver iterations for the current step,"
109 0 : write(*,'(a)') " 'retry' is the number of step retries required during the run,"
110 0 : write(*,'(a)') " 'dt_limit' is an indication of what limited the timestep."
111 0 : write(*,'(A)')
112 0 : write(*,'(a)') " All this and more are saved in the LOGS directory during the run."
113 : end subroutine do_show_log_description
114 :
115 :
116 3 : subroutine do_show_terminal_header(s)
117 : type (star_info), pointer :: s
118 : integer :: ierr, io
119 3 : call output_terminal_header(s,terminal_iounit)
120 3 : if (len_trim(s% extra_terminal_output_file) > 0) then
121 0 : ierr = 0
122 : open(newunit=io, file=trim(s% extra_terminal_output_file), &
123 0 : action='write', position='append', iostat=ierr)
124 0 : if (ierr == 0) then
125 0 : call output_terminal_header(s,io)
126 0 : close(io)
127 : else
128 : write(*,*) 'failed to open extra_terminal_output_file ' // &
129 0 : trim(s% extra_terminal_output_file)
130 : end if
131 : end if
132 3 : end subroutine do_show_terminal_header
133 :
134 :
135 3 : subroutine output_terminal_header(s,io)
136 : use chem_def, only: isi28
137 : type (star_info), pointer :: s
138 : integer, intent(in) :: io
139 : character (len=5) :: iters
140 3 : iters = 'iters'
141 :
142 : include 'formats'
143 :
144 : write(io,'(a)') &
145 : '_______________________________________________________________________' // &
146 3 : '___________________________________________________________________________'
147 3 : write(io,'(A)')
148 : write(io,'(a)') &
149 : ' step lg_Tmax Teff lg_LH lg_Lnuc_tot Mass ' // &
150 3 : 'H_rich H_cntr N_cntr Y_surf eta_cntr zones retry'
151 :
152 : ! note that if the age is in days, then the timestep is automatically in seconds.
153 3 : if (trim(s% terminal_show_timestep_units) == 'seconds' .or. &
154 : trim(s% terminal_show_timestep_units) == 'secs') then
155 0 : if (s% terminal_show_log_dt) then
156 0 : write(io,'(a)',advance='no') ' lg_dt_sec'
157 : else
158 0 : write(io,'(a)',advance='no') ' dt_sec'
159 : end if
160 3 : else if (trim(s% terminal_show_timestep_units) == 'days') then
161 0 : if (s% terminal_show_log_dt) then
162 0 : write(io,'(a)',advance='no') ' lg_dt_days'
163 : else
164 0 : write(io,'(a)',advance='no') ' dt_days'
165 : end if
166 3 : else if (trim(s% terminal_show_timestep_units) == 'years' .or. &
167 : trim(s% terminal_show_timestep_units) == 'yrs') then
168 3 : if (s% terminal_show_log_dt) then
169 3 : write(io,'(a)',advance='no') ' lg_dt_yrs'
170 : else
171 0 : write(io,'(a)',advance='no') ' dt_yrs'
172 : end if
173 : else
174 0 : write(*,*) 'unrecognized option for terminal_show_timestep_units ' // trim(s% terminal_show_timestep_units)
175 0 : return
176 : end if
177 :
178 3 : if (s% initial_z >= 1d-5) then
179 : write(io,'(a)') &
180 : ' lg_Tcntr lg_R lg_L3a lg_Lneu lg_Mdot ' // &
181 3 : 'He_core He_cntr O_cntr Z_surf gam_cntr ' // iters // ' '
182 : else
183 : write(io,'(a)') &
184 : ' lg_Tcntr lg_R lg_L3a lg_Lneu lg_Mdot ' // &
185 0 : 'He_core He_cntr O_cntr lg_Z_surf gam_cntr ' // iters // ' '
186 : end if
187 :
188 3 : if (trim(s% terminal_show_age_units) == 'seconds' .or. &
189 : trim(s% terminal_show_age_units) == 'secs') then
190 0 : if (s% terminal_show_log_age) then
191 0 : write(io,'(a)',advance='no') 'lg_age_secs'
192 : else
193 0 : write(io,'(a)',advance='no') ' age_secs'
194 : end if
195 3 : else if (trim(s% terminal_show_age_units) == 'days') then
196 0 : if (s% terminal_show_log_age) then
197 0 : write(io,'(a)',advance='no') 'lg_age_days'
198 : else
199 0 : write(io,'(a)',advance='no') ' age_days'
200 : end if
201 3 : else if (trim(s% terminal_show_age_units) == 'years' .or. &
202 : trim(s% terminal_show_age_units) == 'yrs') then
203 3 : if (s% terminal_show_log_age) then
204 0 : write(io,'(a)',advance='no') ' lg_age_yrs'
205 : else
206 3 : write(io,'(a)',advance='no') ' age_yrs'
207 : end if
208 : else
209 0 : write(*,*) 'unrecognized option for terminal_show_age_units ' // trim(s% terminal_show_age_units)
210 0 : return
211 : end if
212 :
213 3 : if (s% net_iso(isi28) == 0) then
214 : write(io,'(a)') &
215 : ' lg_Dcntr lg_L lg_LZ lg_Lphoto lg_Dsurf ' // &
216 3 : 'CO_core C_cntr Ne_cntr Z_cntr v_div_cs dt_limit'
217 : else
218 : write(io,'(a)') &
219 : ' lg_Dcntr lg_L lg_LZ lg_Lphoto lg_Dsurf ' // &
220 0 : 'CO_core C_cntr Ne_cntr Si_cntr v_div_cs dt_limit'
221 : end if
222 : write(io,'(a)') &
223 : '_______________________________________________________________________' // &
224 3 : '___________________________________________________________________________'
225 3 : write(io,'(A)')
226 :
227 3 : end subroutine output_terminal_header
228 :
229 :
230 12 : subroutine do_terminal_summary(s)
231 : type (star_info), pointer :: s
232 : integer :: ierr, io
233 12 : call output_terminal_summary(s,terminal_iounit)
234 12 : if (len_trim(s% extra_terminal_output_file) > 0) then
235 0 : ierr = 0
236 : open(newunit=io, file=trim(s% extra_terminal_output_file), &
237 0 : action='write', position='append', iostat=ierr)
238 0 : if (ierr == 0) then
239 0 : call output_terminal_summary(s,io)
240 0 : close(io)
241 : else
242 : write(*,*) 'failed to open extra_terminal_output_file ' // &
243 0 : trim(s% extra_terminal_output_file)
244 : end if
245 : end if
246 3 : end subroutine do_terminal_summary
247 :
248 :
249 12 : subroutine output_terminal_summary(s,io)
250 : use num_def, only:banded_matrix_type
251 : use const_def, only:secyer
252 : use chem_def
253 : use rates_def, only: i_rate
254 : use star_utils, only:eval_current_y, eval_current_z
255 : type (star_info), pointer :: s
256 : integer, intent(in) :: io
257 :
258 12 : real(dp) :: time_step, age, dt, Xmax, v, vsurf_div_csound, tmp, &
259 12 : sum_Lnuc, sum_LH, sum_LHe, sum_Lz, sum_Lphoto
260 : integer :: model, ierr, nz, iters
261 : character (len=3) :: id_str
262 : character (len=32) :: why
263 : character (len=90) :: fmt, fmt1, fmt2, fmt3, fmt4, fmt5
264 :
265 : include 'formats'
266 :
267 12 : age = s% star_age ! in years
268 12 : if (trim(s% terminal_show_age_units) == 'seconds' .or. &
269 : trim(s% terminal_show_age_units) == 'secs') then
270 0 : age = age*secyer
271 12 : else if (trim(s% terminal_show_age_units) == 'days') then
272 0 : age = age*dayyer
273 : end if
274 :
275 12 : time_step = s% time_step ! in years
276 12 : if (trim(s% terminal_show_timestep_units) == 'seconds' .or. &
277 : trim(s% terminal_show_timestep_units) == 'secs') then
278 0 : time_step = time_step*secyer
279 12 : else if (trim(s% terminal_show_timestep_units) == 'days') then
280 0 : time_step = time_step*dayyer
281 : end if
282 :
283 12 : if (s% terminal_show_log_age) age = safe_log10(age)
284 12 : if (s% terminal_show_log_dt) time_step = safe_log10(time_step)
285 :
286 12 : model = s% model_number
287 12 : nz = s% nz
288 :
289 12 : ierr = 0
290 :
291 12 : Xmax = dot_product(s% dq(1:nz), s% xa(s% species,1:nz))
292 :
293 12 : if (s% u_flag) then
294 0 : v = s% u(1)
295 12 : else if (s% v_flag) then
296 0 : v = s% v(1)
297 : else
298 : v = 0d0
299 : end if
300 12 : vsurf_div_csound = v / s% csound(1)
301 :
302 12 : dt = s% time_step*secyer
303 :
304 12 : sum_Lnuc = s% power_nuc_burn
305 12 : sum_LH = s% power_h_burn
306 12 : sum_LHe = s% power_he_burn
307 12 : sum_Lphoto = abs(s% power_photo)
308 12 : sum_Lz = s% power_z_burn
309 :
310 12 : if (how_many_allocated_star_ids() == 1) then
311 12 : id_str = ''
312 : else
313 0 : write(id_str,'(i3)') s% id
314 : end if
315 :
316 12 : fmt1 = '(a3,i8,f11.6,'
317 :
318 12 : if (s% Teff < 1d4) then
319 0 : fmt2 = 'f11.3,'
320 : else
321 12 : fmt2 = '1pe11.3,0p,'
322 : end if
323 :
324 12 : if (s% star_mass >= 1d2) then
325 0 : fmt3 = '2f11.6,2(1pe11.3),0p,'
326 : else
327 12 : fmt3 = '4f11.6,'
328 : end if
329 :
330 12 : if (s% eta(s% nz) >= 1d3) then
331 0 : fmt4 = '3f11.6,e11.3,'
332 : else
333 12 : fmt4 = '3f11.6,f11.6,'
334 : end if
335 12 : fmt5 = '2i7)'
336 :
337 12 : fmt = trim(fmt1) // trim(fmt2) // trim(fmt3) // trim(fmt4) // trim(fmt5)
338 : !write(*,*) 'fmt line1 ' // trim(fmt)
339 : write(io,fmt=fmt) &
340 12 : id_str, model, &
341 12 : s% log_max_temperature, & ! fmt1
342 12 : s% Teff, & ! fmt2
343 12 : safe_log10(sum_LH), & ! fmt3
344 12 : safe_log10(sum_Lnuc), &
345 12 : s% star_mass, &
346 12 : s% star_mass - max(s% he_core_mass, s% co_core_mass), &
347 12 : s% center_h1, & ! fmt4
348 12 : s% center_n14, &
349 12 : s% surface_he3 + s% surface_he4, &
350 12 : s% eta(s% nz), &
351 12 : s% nz, & ! fmt5
352 24 : s% num_retries
353 :
354 12 : tmp = max(0d0, min(1d0, 1 - (s% surface_h1 + s% surface_he3 + s% surface_he4)))
355 12 : if (s% initial_z >= 1d-5) then
356 12 : fmt1 = '(1pe11.4, 0p, 9f11.6, '
357 : else
358 0 : tmp = safe_log10(tmp)
359 0 : fmt1 = '(1pe11.4, 0p, 8f11.6, e11.2, '
360 : end if
361 12 : if (s% gam(s% nz) >= 1d3) then
362 0 : fmt2 = 'e11.3, '
363 : else
364 12 : fmt2 = 'f11.6, '
365 : end if
366 12 : fmt3 = ' i7)'
367 12 : fmt = trim(fmt1) // trim(fmt2) // trim(fmt3)
368 : !write(*,*) 'fmt line2 ' // trim(fmt)
369 12 : iters = s% num_solver_iterations
370 : write(io,fmt=fmt) &
371 12 : time_step, &
372 12 : s% log_center_temperature, &
373 12 : s% log_surface_radius, &
374 12 : safe_log10(sum_LHe), &
375 12 : safe_log10(abs(s% power_neutrinos)), &
376 12 : safe_log10(abs(s% star_mdot)), &
377 12 : s% he_core_mass, &
378 12 : s% center_he3 + s% center_he4, &
379 12 : s% center_o16, &
380 12 : tmp, &
381 12 : s% gam(s% nz), &
382 24 : iters
383 :
384 12 : if (s% why_Tlim < 0) then
385 0 : why = ''
386 12 : else if (s% why_Tlim == 0) then
387 1 : why = 'initial dt'
388 : else
389 11 : why = dt_why_str(min(numTlim,s% why_Tlim))
390 : if (s% why_Tlim == Tlim_dX .and. s% Tlim_dX_species > 0 &
391 11 : .and. s% Tlim_dX_species <= s% species) then
392 : why = trim(dt_why_str(s% why_Tlim)) // ' ' // &
393 0 : trim(chem_isos% name(s% chem_id(s% Tlim_dX_species)))
394 : else if (s% why_Tlim == Tlim_dX_div_X .and. s% Tlim_dX_div_X_species > 0 &
395 11 : .and. s% Tlim_dX_div_X_species <= s% species) then
396 : why = trim(dt_why_str(s% why_Tlim)) // ' ' // &
397 0 : trim(chem_isos% name(s% chem_id(s% Tlim_dX_div_X_species)))
398 : else if (s% why_Tlim == Tlim_dX_nuc_drop .and. s% dX_nuc_drop_max_j > 0 &
399 11 : .and. s% dX_nuc_drop_max_j <= s% species) then
400 : why = trim(dt_why_str(s% why_Tlim)) // ' ' // &
401 0 : trim(chem_isos% name(s% chem_id(s% dX_nuc_drop_max_j)))
402 11 : else if (s% why_Tlim == Tlim_dlgL_nuc_cat) then
403 : if (s% Tlim_dlgL_nuc_category > 0 &
404 0 : .and. s% Tlim_dlgL_nuc_category <= num_categories ) then
405 0 : why = trim(category_name(s% Tlim_dlgL_nuc_category))
406 : else
407 0 : why = '???'
408 : end if
409 : end if
410 : end if
411 :
412 12 : if (s% net_iso(isi28) == 0) then
413 12 : tmp = 1 - (s% center_h1 + s% center_he3 + s% center_he4)
414 12 : fmt = '(1pe11.4, 0p, 5f11.6, 0p4f11.6, 0p, e11.3, a14)'
415 : !write(*,*) 'fmt line3 ' // trim(fmt)
416 : write(io,fmt) &
417 12 : age, &
418 12 : s% log_center_density, &
419 12 : s% log_surface_luminosity, &
420 12 : safe_log10(sum_Lz), &
421 12 : safe_log10(abs(s% power_photo)), &
422 12 : s% lnd(1)/ln10, &
423 12 : s% co_core_mass, &
424 12 : s% center_c12, &
425 12 : s% center_ne20, &
426 12 : tmp, &
427 12 : vsurf_div_csound, &
428 24 : trim(why)
429 : else
430 0 : tmp = s% center_si28
431 0 : fmt = '(1pe11.4, 0p, 5f11.6, 0p4f11.6, 0p, e11.3, a14)'
432 : !write(*,*) 'fmt line3 ' // trim(fmt)
433 : write(io,fmt) &
434 0 : age, &
435 0 : s% log_center_density, &
436 0 : s% log_surface_luminosity, &
437 0 : safe_log10(sum_Lz), &
438 0 : safe_log10(abs(s% power_photo)), &
439 0 : s% lnd(1)/ln10, &
440 0 : s% co_core_mass, &
441 0 : s% center_c12, &
442 0 : s% center_ne20, &
443 0 : tmp, &
444 0 : vsurf_div_csound, &
445 0 : trim(why)
446 : end if
447 :
448 12 : call show_trace_history_values(max(0, s% num_trace_history_values))
449 12 : write(io,'(A)')
450 :
451 12 : s% just_wrote_terminal_header = .false.
452 :
453 :
454 : contains
455 :
456 :
457 12 : subroutine show_trace_history_values(num)
458 : use history, only: do_get_data_for_history_columns, &
459 12 : get_history_specs, get_history_values, get1_hist_value
460 : integer, intent(in) :: num
461 12 : real(dp) :: values(num)
462 24 : integer :: int_values(num), specs(num)
463 24 : logical :: is_int_value(num)
464 12 : logical :: failed_to_find_value(num)
465 12 : real(dp) :: val
466 : integer :: i
467 : include 'formats'
468 12 : if (num == 0) return
469 : call do_get_data_for_history_columns(s, ierr)
470 0 : if (ierr /= 0) return
471 0 : call get_history_specs(s, num, s% trace_history_value_name, specs, .false.)
472 : call get_history_values( &
473 0 : s, num, specs, is_int_value, int_values, values, failed_to_find_value)
474 0 : do i = 1, num
475 0 : if (failed_to_find_value(i)) then
476 0 : if (.not. get1_hist_value(s, s% trace_history_value_name(i), val)) then
477 0 : write(*,*) 'failed to find history value ' // trim(s% trace_history_value_name(i))
478 0 : cycle
479 : end if
480 0 : values(i) = val
481 0 : if (is_bad(values(i))) then
482 0 : call mesa_error(__FILE__,__LINE__,'show_trace_history_values bad from get1_hist_value')
483 : end if
484 0 : else if (is_int_value(i)) then
485 : write(io,'(a40,i14)') &
486 0 : trim(s% trace_history_value_name(i)), int_values(i)
487 0 : cycle
488 : end if
489 0 : if ((values(i) == 0) .or. &
490 0 : (abs(values(i)) > 1d-4 .and. abs(values(i)) < 1d4)) then
491 : write(io,'(a40,99(f26.16))') &
492 0 : trim(s% trace_history_value_name(i)), values(i)
493 : else
494 : write(io,'(a40,99(1pd26.16))') &
495 0 : trim(s% trace_history_value_name(i)), values(i)
496 0 : if (is_bad(values(i))) then
497 0 : call mesa_error(__FILE__,__LINE__,'show_trace_history_values')
498 : end if
499 : end if
500 : end do
501 12 : end subroutine show_trace_history_values
502 :
503 :
504 : end subroutine output_terminal_summary
505 :
506 :
507 11 : logical function get_history_info(s, do_write)
508 : type (star_info), pointer :: s
509 : logical, intent(in) :: do_write
510 : integer :: model
511 : logical :: write_history, write_terminal
512 : include 'formats'
513 11 : model = s% model_number
514 11 : if (s% history_interval > 0) then
515 11 : write_history = (mod(model, s% history_interval) == 0) .or. do_write
516 : else
517 : write_history = .false.
518 : end if
519 11 : if (s% terminal_interval > 0) then
520 11 : write_terminal = (mod(model, s% terminal_interval) == 0) .or. do_write
521 : else
522 : write_terminal = .false.
523 : end if
524 11 : get_history_info = write_history .or. write_terminal
525 11 : if (.not. get_history_info) return
526 11 : if (s% write_header_frequency*s% terminal_interval > 0) then
527 : if ( mod(model, s% write_header_frequency*s% terminal_interval) == 0 &
528 11 : .and. .not. s% doing_first_model_of_run) then
529 1 : write(*,'(A)')
530 1 : call write_terminal_header(s)
531 : end if
532 : end if
533 11 : if (write_terminal) call do_terminal_summary(s)
534 11 : if (write_history) s% need_to_update_history_now = .true.
535 :
536 : end function get_history_info
537 :
538 :
539 0 : integer function do_bare_bones_check_model(id)
540 : integer, intent(in) :: id
541 : integer :: ierr
542 : logical :: logged
543 : type (star_info), pointer :: s
544 0 : call get_star_ptr(id, s, ierr)
545 0 : if (ierr /= 0) then
546 0 : do_bare_bones_check_model = terminate
547 : return
548 : end if
549 0 : logged = get_history_info( s, .false. )
550 0 : do_bare_bones_check_model = keep_going
551 0 : end function do_bare_bones_check_model
552 :
553 :
554 : subroutine save_profile(id, ierr)
555 : integer, intent(in) :: id
556 : integer, intent(out) :: ierr
557 : type (star_info), pointer :: s
558 : ierr = 0
559 : call get_star_ptr(id, s, ierr)
560 : if (ierr /= 0) return
561 : call set_save_profiles_info(s, phase_priority)
562 : end subroutine save_profile
563 :
564 :
565 11 : integer function do_check_limits(id)
566 : use rates_def
567 : use chem_def
568 : use chem_lib, only: chem_get_iso_id
569 : use star_utils
570 : integer, intent(in) :: id
571 : type (star_info), pointer :: s
572 : integer :: ierr, i, j, k, cid, k_omega, nz, max_abs_vel_loc, &
573 : period_number, max_period_number
574 11 : real(dp) :: log_surface_gravity, log_surface_temperature, log_surface_density, &
575 11 : log_surface_pressure, v_div_csound_max, remnant_mass, ejecta_mass, &
576 11 : power_nuc_burn, power_h_burn, power_he_burn, power_z_burn, logQ, max_logQ, min_logQ, &
577 11 : envelope_fraction_left, avg_x, v_surf, csound_surf, delta_nu, v_surf_div_v_esc, &
578 11 : peak_burn_vconv_div_cs, min_pgas_div_p, v_surf_div_v_kh, GREKM_avg_abs, &
579 11 : max_omega_div_omega_crit, omega_div_omega_crit, log_Teff, Lnuc_div_L, max_abs_vel, &
580 11 : species_mass_for_min_limit, species_mass_for_max_limit, center_gamma
581 :
582 : include 'formats'
583 :
584 : ierr = 0
585 11 : call get_star_ptr(id, s, ierr)
586 11 : if (ierr /= 0) then
587 0 : do_check_limits = terminate
588 0 : return
589 : end if
590 :
591 11 : if (s% RSP_flag) then
592 0 : max_period_number = s% RSP_max_num_periods
593 0 : period_number = s% RSP_num_periods
594 0 : GREKM_avg_abs = s% rsp_GREKM_avg_abs
595 : else
596 11 : max_period_number = 0
597 11 : period_number = -1
598 11 : GREKM_avg_abs = 1d99
599 : end if
600 :
601 11 : nz = s% nz
602 11 : do_check_limits = keep_going
603 :
604 11 : species_mass_for_min_limit = get_species_mass(s% star_species_mass_min_limit_iso)
605 11 : species_mass_for_max_limit = get_species_mass(s% star_species_mass_max_limit_iso)
606 :
607 11 : csound_surf = s% csound_face(1)
608 11 : if (s% u_flag) then
609 0 : v_surf = s% u(1)
610 0 : v_div_csound_max = maxval(abs(s% u(1:nz)/s% csound(1:nz)))
611 11 : else if (s% v_flag) then
612 0 : v_surf = s% v(1)
613 0 : v_div_csound_max = maxval(abs(s% v(1:nz)/s% csound_face(1:nz)))
614 : else
615 11 : v_surf = 0d0
616 11 : v_div_csound_max = 0d0
617 : end if
618 :
619 11 : remnant_mass = get_remnant_mass(s)/Msun
620 11 : ejecta_mass = get_ejecta_mass(s)/Msun
621 :
622 11 : if(s%u_flag) then
623 0 : max_abs_vel_loc = maxloc(abs(s%u(1:nz)),dim=1)
624 0 : max_abs_vel = s%u(max_abs_vel_loc)
625 11 : else if (s%v_flag) then
626 0 : max_abs_vel_loc = maxloc(abs(s%v(1:nz)),dim=1)
627 0 : max_abs_vel = s%v(max_abs_vel_loc)
628 : else
629 11 : max_abs_vel_loc = -1
630 11 : max_abs_vel = 0d0
631 : end if
632 :
633 :
634 11 : if (s% photosphere_r > 0d0) then
635 11 : v_surf_div_v_kh = abs(v_surf)*s% kh_timescale/s% photosphere_r
636 11 : if (s% cgrav(1) <= 0d0) then
637 0 : v_surf_div_v_esc = 0d0
638 : else
639 11 : v_surf_div_v_esc = v_surf/sqrt(2*s% cgrav(1)*s% m(1)/(s% photosphere_r*Rsun))
640 : end if
641 : else
642 0 : v_surf_div_v_kh = 0d0
643 0 : v_surf_div_v_esc = 0d0
644 : end if
645 :
646 11 : log_surface_gravity = safe_log10(s%grav(1))
647 11 : log_surface_temperature = s% lnT(1) / ln10
648 11 : log_surface_density = s% lnd(1)/ln10 ! log10(density at surface)
649 11 : log_surface_pressure = s% lnPeos(1)/ln10 ! log10(eos pressure at surface)
650 :
651 11 : center_gamma = center_value(s, s% gam)
652 :
653 11 : power_nuc_burn = s% power_nuc_burn
654 11 : power_h_burn = s% power_h_burn
655 11 : power_he_burn = s% power_he_burn
656 11 : power_z_burn = s% power_z_burn
657 11 : log_Teff = safe_log10(s% Teff)
658 11 : if (s% L_phot > 0d0) then
659 11 : Lnuc_div_L = s% L_nuc_burn_total / s% L_phot
660 11 : if (.not. s% get_delta_nu_from_scaled_solar) then
661 11 : delta_nu = 1d6/(2*s% photosphere_acoustic_r) ! microHz
662 : else
663 : delta_nu = &
664 : s% delta_nu_sun*sqrt(s% star_mass)*pow3(s% Teff/s% astero_Teff_sun) / &
665 0 : pow(s% L_phot,0.75d0)
666 : end if
667 : else
668 0 : Lnuc_div_L = 0d0
669 0 : delta_nu = 0d0
670 : end if
671 :
672 11 : if (s% dxdt_nuc_factor > 0d0) then
673 13109 : k = maxloc(s% eps_nuc(1:nz), dim=1)
674 11 : peak_burn_vconv_div_cs = s% conv_vel(k)/s% csound(k)
675 : else
676 0 : peak_burn_vconv_div_cs = 0d0
677 : end if
678 :
679 11 : if (s% initial_mass > s% he_core_mass) then
680 : envelope_fraction_left = &
681 11 : (s% star_mass - s% he_core_mass)/(s% initial_mass - s% he_core_mass)
682 : else
683 0 : envelope_fraction_left = 1
684 : end if
685 :
686 11 : max_logQ = -99
687 11 : min_logQ = 100
688 13098 : do k = 1, s% nz
689 13087 : logQ = s% lnd(k)/ln10 - 2*s% lnT(k)/ln10 + 12
690 : if (s% lnT(k)/ln10 < 5.5d0) then ! only worry about lower T cases
691 : if (logQ > max_logQ) max_logQ = logQ
692 : end if
693 11 : if (logQ < min_logQ) min_logQ = logQ
694 : end do
695 :
696 11 : min_pgas_div_p = 1d99
697 5617 : do k = s% nz, 1, -1
698 5617 : if (s% q(k) > s% Pgas_div_P_limit_max_q) exit
699 5617 : if (s% pgas(k)/s% Peos(k) < min_pgas_div_p) min_pgas_div_p = s% pgas(k)/s% Peos(k)
700 : end do
701 :
702 11 : max_omega_div_omega_crit = 0; k_omega = 0
703 11 : if (s% rotation_flag .and. s% omega_div_omega_crit_limit > 0) then
704 0 : do k = 1, s% nz
705 0 : omega_div_omega_crit = abs(s% omega(k))/omega_crit(s,k)
706 0 : if (omega_div_omega_crit > max_omega_div_omega_crit) then
707 0 : k_omega = k
708 0 : max_omega_div_omega_crit = omega_div_omega_crit
709 : end if
710 : end do
711 : end if
712 :
713 11 : if(s% max_abs_rel_run_E_err > 0d0) then
714 : if (abs(s% cumulative_energy_error/s% total_energy) > s% max_abs_rel_run_E_err &
715 0 : .and. .not. s% doing_relax) then
716 : write(*, '(/,a,/, 2e20.10)') &
717 0 : 'stop because abs rel_run_E_err exceeds limit (max_abs_rel_run_E_err) ', &
718 0 : abs(s% cumulative_energy_error/s% total_energy), s% max_abs_rel_run_E_err
719 0 : do_check_limits = terminate
720 0 : s% termination_code = t_max_abs_rel_run_E_err
721 0 : s% result_reason = abs_rel_run_E_err
722 0 : return
723 : end if
724 : end if
725 :
726 11 : if (max_abs_vel > clight) then
727 0 : if (s% retry_for_v_above_clight) then
728 : write(*, '(/,a,/, I5,1X,2e20.10)') &
729 0 : 'retry because maximum velocity exceeds speed of light ',max_abs_vel_loc,max_abs_vel,max_abs_vel/clight
730 0 : do_check_limits = retry
731 0 : return
732 : else
733 : write(*, '(/,a,/, I5,1X,2e20.10)') &
734 0 : 'Warning: maximum velocity exceeds speed of light ',max_abs_vel_loc,max_abs_vel,max_abs_vel/clight
735 : end if
736 : end if
737 :
738 11 : if (peak_burn_vconv_div_cs > 0.75d0*s% peak_burn_vconv_div_cs_limit) then
739 0 : write(*,1) 'peak_burn_vconv_div_cs: ', &
740 0 : peak_burn_vconv_div_cs / s% peak_burn_vconv_div_cs_limit, &
741 0 : peak_burn_vconv_div_cs, s% peak_burn_vconv_div_cs_limit
742 0 : k = maxloc(s% eps_nuc(1:nz), dim=1)
743 0 : write(*,2) 'maxloc eps_nuc', k, s% conv_vel(k), s% csound(k), s% eps_nuc(k)
744 0 : call mesa_error(__FILE__,__LINE__,'test do_one_utils')
745 : end if
746 :
747 11 : if (s% fe_core_infall < s% fe_core_infall_limit .and. &
748 : s% fe_core_infall > 0.99d0*s% fe_core_infall_limit) &
749 0 : write(*,1) 'nearing fe_core_infall limit', &
750 0 : s% fe_core_infall, s% fe_core_infall_limit
751 :
752 11 : if (s% non_fe_core_infall < s% non_fe_core_infall_limit .and. &
753 : s% non_fe_core_infall > 0.99d0*s% non_fe_core_infall_limit) &
754 0 : write(*,1) 'nearing non_fe_core_infall limit', &
755 0 : s% non_fe_core_infall, s% non_fe_core_infall_limit
756 :
757 11 : if (s% non_fe_core_rebound > 0.99d0*s% non_fe_core_rebound_limit) &
758 0 : write(*,1) 'nearing non_fe_core_rebound limit', &
759 0 : s% non_fe_core_rebound, s% non_fe_core_rebound_limit
760 :
761 : if (max_omega_div_omega_crit > 0.75d0*s% omega_div_omega_crit_limit .and. &
762 11 : s% omega_div_omega_crit_limit > 0 .and. k_omega > 0) &
763 0 : write(*,2) 'omega_div_omega_crit', k_omega, &
764 0 : max_omega_div_omega_crit, s% omega_div_omega_crit_limit, &
765 0 : s% m(k_omega)/Msun, s% r_equatorial(k_omega)/Rsun, &
766 0 : s% omega(k_omega), &
767 0 : sqrt(s% cgrav(k_omega)*s% m(k_omega)/ pow3(s% r_equatorial(k_omega)))
768 :
769 11 : if (s% star_age >= s% max_age .and. s% max_age > 0) then
770 : call compare_to_target('star_age >= max_age', s% star_age, s% max_age, &
771 1 : t_max_age)
772 :
773 10 : else if (s% time >= s% max_age_in_days*secday .and. s% max_age_in_days > 0) then
774 : call compare_to_target('time >= max_age_in_days', &
775 0 : s% time/secday, s% max_age_in_days, t_max_age)
776 :
777 10 : else if (s% time >= s% max_age_in_seconds .and. s% max_age_in_seconds > 0) then
778 : call compare_to_target('time >= max_age_in_seconds', &
779 0 : s% time, s% max_age_in_seconds, t_max_age)
780 :
781 10 : else if (max_omega_div_omega_crit >= s% omega_div_omega_crit_limit .and. &
782 : s% omega_div_omega_crit_limit > 0) then
783 : write(*, '(/,a,/, 2e20.10)') &
784 0 : 'stop max_omega_div_omega_crit >= omega_div_omega_crit_limit', &
785 0 : max_omega_div_omega_crit, s% omega_div_omega_crit_limit
786 0 : do_check_limits = terminate
787 0 : s% termination_code = t_max_omega_div_omega_crit
788 0 : s% result_reason = result_reason_normal
789 :
790 10 : else if (peak_burn_vconv_div_cs >= s% peak_burn_vconv_div_cs_limit) then
791 : write(*, '(/,a,/, 2e20.10)') &
792 0 : 'stop peak_burn_vconv_div_cs >= peak_burn_vconv_div_cs_limit', &
793 0 : peak_burn_vconv_div_cs, s% peak_burn_vconv_div_cs_limit
794 0 : do_check_limits = terminate
795 0 : s% termination_code = t_peak_burn_vconv_div_cs_limit
796 0 : s% result_reason = result_reason_normal
797 :
798 10 : else if (s% model_number >= s% max_model_number .and. s% max_model_number >= 0) then
799 0 : write(*, '(/,a,/, 2i9)') 'stop because model_number >= max_model_number', &
800 0 : s% model_number, s% max_model_number
801 0 : do_check_limits = terminate
802 0 : s% termination_code = t_max_model_number
803 0 : s% result_reason = result_reason_normal
804 :
805 10 : else if (period_number >= max_period_number .and. max_period_number >= 0) then
806 0 : write(*, '(/,a,/, 2i9)') 'stop because period_number >= max_period_number', &
807 0 : period_number, max_period_number
808 0 : do_check_limits = terminate
809 0 : s% termination_code = t_max_period_number
810 0 : s% result_reason = result_reason_normal
811 :
812 : else if (GREKM_avg_abs < s% RSP_GREKM_avg_abs_limit &
813 : .and. s% RSP_GREKM_avg_abs_limit >= 0 &
814 10 : .and. period_number >= 10) then
815 : write(*, '(/,a,/, 2e20.10)') &
816 0 : 'stop because GREKM_avg_abs < RSP_GREKM_avg_abs_limit', &
817 0 : GREKM_avg_abs, s% RSP_GREKM_avg_abs_limit
818 0 : do_check_limits = terminate
819 0 : s% termination_code = 0
820 0 : s% result_reason = result_reason_normal
821 :
822 10 : else if (s% center_degeneracy >= s% eta_center_limit) then
823 : call compare_to_target('center_degeneracy >= eta_center_limit', &
824 0 : s% center_degeneracy, s% eta_center_limit, t_eta_center_limit)
825 :
826 10 : else if (s% log_center_temperature >= s% log_center_temp_upper_limit) then
827 : call compare_to_target('log_center_temperature >= log_center_temp_upper_limit', &
828 0 : center_value(s, s% lnT)/ln10, s% log_center_temp_upper_limit, t_log_center_temp_upper_limit)
829 :
830 10 : else if (s% log_center_temperature <= s% log_center_temp_lower_limit) then
831 : call compare_to_target('log_center_temperature <= log_center_temp_lower_limit', &
832 : center_value(s, s% lnT)/ln10, s% log_center_temp_lower_limit, &
833 0 : t_log_center_temp_lower_limit)
834 :
835 10 : else if (s% max_entropy >= s% max_entropy_upper_limit) then
836 : call compare_to_target('max_entropy >= max_entropy_upper_limit', &
837 0 : s% max_entropy, s% max_entropy_upper_limit, t_max_entropy_upper_limit)
838 :
839 10 : else if (s% max_entropy <= s% max_entropy_lower_limit) then
840 : call compare_to_target('max_entropy <= max_entropy_lower_limit', &
841 : s% max_entropy, s% max_entropy_lower_limit, &
842 0 : t_max_entropy_lower_limit)
843 :
844 10 : else if (s% center_entropy >= s% center_entropy_upper_limit) then
845 : call compare_to_target('center_entropy >= center_entropy_upper_limit', &
846 0 : s% center_entropy, s% center_entropy_upper_limit, t_center_entropy_upper_limit)
847 :
848 10 : else if (s% center_entropy <= s% center_entropy_lower_limit) then
849 : call compare_to_target('center_entropy <= center_entropy_lower_limit', &
850 : s% center_entropy, s% center_entropy_lower_limit, &
851 0 : t_center_entropy_lower_limit)
852 :
853 10 : else if (s% log_center_density <= s% log_center_density_lower_limit) then
854 : call compare_to_target('log_center_density <= log_center_density_lower_limit', &
855 : center_value(s, s% lnd)/ln10, s% log_center_density_lower_limit, &
856 0 : t_log_center_density_lower_limit)
857 :
858 10 : else if (s% log_center_density >= s% log_center_density_upper_limit) then
859 : call compare_to_target('log_center_density >= log_center_density_upper_limit', &
860 0 : center_value(s, s% lnd)/ln10, s% log_center_density_upper_limit, t_log_center_density_upper_limit)
861 :
862 10 : else if (center_gamma > s% gamma_center_limit) then
863 : call compare_to_target('center_gamma > gamma_center_limit', &
864 0 : center_gamma, s% gamma_center_limit, t_gamma_center_limit)
865 :
866 10 : else if (s% log_max_temperature >= s% log_max_temp_upper_limit) then
867 : call compare_to_target('log_max_temperature >= log_max_temp_upper_limit', &
868 0 : s% log_max_temperature, s% log_max_temp_upper_limit, t_log_max_temp_upper_limit)
869 :
870 10 : else if (s% log_max_temperature <= s% log_max_temp_lower_limit) then
871 : call compare_to_target('log_max_temperature <= log_max_temp_lower_limit', &
872 0 : s% log_max_temperature, s% log_max_temp_lower_limit, t_log_max_temp_lower_limit)
873 :
874 10 : else if (s% center_he4 < s% HB_limit .and. s% center_h1 < 1d-4) then
875 0 : call compare_to_target('center he4 < HB_limit', s% center_he4, s% HB_limit, t_HB_limit)
876 :
877 10 : else if (s% star_mass_min_limit > 0 .and. s% star_mass <= s% star_mass_min_limit) then
878 : call compare_to_target('star_mass <= star_mass_min_limit', &
879 0 : s% star_mass, s% star_mass_min_limit, t_star_mass_min_limit)
880 :
881 10 : else if (s% star_mass_max_limit > 0 .and. s% star_mass >= s% star_mass_max_limit) then
882 : call compare_to_target('star_mass >= star_mass_max_limit', &
883 0 : s% star_mass, s% star_mass_max_limit, t_star_mass_max_limit)
884 :
885 10 : else if (s% remnant_mass_min_limit > 0 .and. remnant_mass <= s% remnant_mass_min_limit) then
886 : call compare_to_target('remnant_mass <= remnant_mass_min_limit', &
887 0 : remnant_mass, s% remnant_mass_min_limit, t_remnant_mass_min_limit)
888 :
889 10 : else if (s% ejecta_mass_max_limit > 0 .and. ejecta_mass >= s% ejecta_mass_max_limit) then
890 : call compare_to_target('ejecta_mass >= ejecta_mass_max_limit', &
891 0 : ejecta_mass, s% ejecta_mass_max_limit, t_ejecta_mass_max_limit)
892 :
893 10 : else if (species_mass_for_min_limit >= 0 .and. &
894 : species_mass_for_min_limit <= s% star_species_mass_min_limit) then
895 : call compare_to_target( &
896 : trim(s% star_species_mass_min_limit_iso) // ' total mass <= star_species_mass_min_limit', &
897 0 : species_mass_for_min_limit, s% star_species_mass_min_limit, t_star_species_mass_min_limit)
898 :
899 10 : else if (species_mass_for_max_limit >= s% star_species_mass_max_limit) then
900 : call compare_to_target( &
901 : trim(s% star_species_mass_max_limit_iso) // ' total mass >= star_species_mass_max_limit', &
902 0 : species_mass_for_max_limit, s% star_species_mass_max_limit, t_star_species_mass_max_limit)
903 :
904 10 : else if (s% xmstar_min_limit > 0 .and. s% xmstar <= s% xmstar_min_limit) then
905 : call compare_to_target('xmstar <= xmstar_min_limit', &
906 0 : s% xmstar, s% xmstar_min_limit, t_xmstar_min_limit)
907 :
908 10 : else if (s% xmstar_max_limit > 0 .and. s% xmstar >= s% xmstar_max_limit) then
909 : call compare_to_target('xmstar >= xmstar_max_limit', &
910 0 : s% xmstar, s% xmstar_max_limit, t_xmstar_max_limit)
911 :
912 10 : else if (s% star_mass - s% he_core_mass < s% envelope_mass_limit) then
913 : call compare_to_target('envelope mass < envelope_mass_limit', &
914 : s% star_mass - s% he_core_mass, s% envelope_mass_limit, &
915 0 : t_envelope_mass_limit)
916 :
917 10 : else if (envelope_fraction_left < s% envelope_fraction_left_limit) then
918 : call compare_to_target('envelope_fraction_left < limit', &
919 : envelope_fraction_left, s% envelope_fraction_left_limit, &
920 0 : t_envelope_fraction_left_limit)
921 :
922 10 : else if (s% he_core_mass >= s% he_core_mass_limit) then
923 : call compare_to_target('he_core_mass >= he_core_mass_limit', &
924 0 : s% he_core_mass, s% he_core_mass_limit, t_he_core_mass_limit)
925 :
926 10 : else if (s% co_core_mass >= s% co_core_mass_limit) then
927 : call compare_to_target('co_core_mass >= co_core_mass_limit', &
928 0 : s% co_core_mass, s% co_core_mass_limit, t_co_core_mass_limit)
929 :
930 10 : else if (s% one_core_mass >= s% one_core_mass_limit) then
931 : call compare_to_target('one_core_mass >= one_core_mass_limit', &
932 0 : s% one_core_mass, s% one_core_mass_limit, t_one_core_mass_limit)
933 :
934 10 : else if (s% fe_core_mass >= s% fe_core_mass_limit) then
935 : call compare_to_target('fe_core_mass >= fe_core_mass_limit', &
936 0 : s% fe_core_mass, s% fe_core_mass_limit, t_fe_core_mass_limit)
937 :
938 10 : else if (s% neutron_rich_core_mass >= s% neutron_rich_core_mass_limit) then
939 : call compare_to_target('neutron_rich_core_mass >= neutron_rich_core_mass_limit', &
940 0 : s% neutron_rich_core_mass, s% neutron_rich_core_mass_limit, t_neutron_rich_core_mass_limit)
941 :
942 : else if ( &
943 : s% he_core_mass >= s% co_core_mass .and. &
944 : s% co_core_mass > 0 .and. &
945 10 : s% center_he4 < 1d-4 .and. &
946 : s% he_core_mass - s% co_core_mass < s% he_layer_mass_lower_limit) then
947 : call compare_to_target('he layer mass < he_layer_mass_lower_limit', &
948 : s% he_core_mass - s% co_core_mass, s% he_layer_mass_lower_limit, &
949 0 : t_he_layer_mass_lower_limit)
950 :
951 : else if (abs(safe_log10(power_h_burn) - s% log_surface_luminosity) <= &
952 : s% abs_diff_lg_LH_lg_Ls_limit &
953 10 : .and. s% abs_diff_lg_LH_lg_Ls_limit > 0) then
954 : call compare_to_target('abs(lg_LH - lg_Ls) <= limit', &
955 : abs(safe_log10(power_h_burn) - s% log_surface_luminosity), &
956 0 : s% abs_diff_lg_LH_lg_Ls_limit, t_abs_diff_lg_LH_lg_Ls_limit)
957 :
958 10 : else if (s% Teff <= s% Teff_lower_limit) then
959 : call compare_to_target('Teff <= Teff_lower_limit', &
960 0 : s% Teff, s% Teff_lower_limit, t_Teff_lower_limit)
961 :
962 10 : else if (s% Teff >= s% Teff_upper_limit) then
963 : call compare_to_target('Teff >= Teff_upper_limit', &
964 0 : s% Teff, s% Teff_upper_limit, t_Teff_upper_limit)
965 :
966 10 : else if (delta_nu <= s% delta_nu_lower_limit .and. s% delta_nu_lower_limit > 0) then
967 : call compare_to_target('delta_nu <= delta_nu_lower_limit', &
968 0 : delta_nu, s% delta_nu_lower_limit, t_delta_nu_lower_limit)
969 :
970 10 : else if (delta_nu >= s% delta_nu_upper_limit .and. s% delta_nu_upper_limit > 0) then
971 : call compare_to_target('delta_nu >= delta_nu_upper_limit', &
972 0 : delta_nu, s% delta_nu_upper_limit, t_delta_nu_upper_limit)
973 :
974 10 : else if (s% delta_Pg <= s% delta_Pg_lower_limit .and. s% delta_Pg_lower_limit > 0) then
975 : call compare_to_target('delta_Pg <= delta_Pg_lower_limit', &
976 0 : s% delta_Pg, s% delta_Pg_lower_limit, t_delta_Pg_lower_limit)
977 :
978 10 : else if (s% delta_Pg >= s% delta_Pg_upper_limit .and. s% delta_Pg_upper_limit > 0) then
979 : call compare_to_target('delta_Pg >= delta_Pg_upper_limit', &
980 0 : s% delta_Pg, s% delta_Pg_upper_limit, t_delta_Pg_upper_limit)
981 :
982 10 : else if (s% photosphere_m - s% M_center/Msun <= s% photosphere_m_sub_M_center_limit) then
983 : call compare_to_target( &
984 : 'photosphere_m - M_center/Msun <= photosphere_m_sub_M_center_limit', &
985 : s% photosphere_m - s% M_center/Msun, &
986 : s% photosphere_m_sub_M_center_limit, &
987 0 : t_photosphere_m_sub_M_center_limit)
988 :
989 10 : else if (s% photosphere_m <= s% photosphere_m_lower_limit) then
990 : call compare_to_target('photosphere_m <= photosphere_m_lower_limit', &
991 0 : s% photosphere_m, s% photosphere_m_lower_limit, t_photosphere_m_lower_limit)
992 :
993 10 : else if (s% photosphere_m >= s% photosphere_m_upper_limit) then
994 : call compare_to_target('photosphere_m >= photosphere_m_upper_limit', &
995 0 : s% photosphere_m, s% photosphere_m_upper_limit, t_photosphere_m_upper_limit)
996 :
997 10 : else if (s% photosphere_r <= s% photosphere_r_lower_limit) then
998 : call compare_to_target('photosphere_r <= photosphere_r_lower_limit', &
999 0 : s% photosphere_r, s% photosphere_r_lower_limit, t_photosphere_r_lower_limit)
1000 :
1001 10 : else if (s% photosphere_r >= s% photosphere_r_upper_limit) then
1002 : call compare_to_target('photosphere_r >= photosphere_r_upper_limit', &
1003 0 : s% photosphere_r, s% photosphere_r_upper_limit, t_photosphere_r_upper_limit)
1004 :
1005 10 : else if (log_Teff <= s% log_Teff_lower_limit) then
1006 : call compare_to_target('log_Teff <= log_Teff_lower_limit', &
1007 0 : log_Teff, s% log_Teff_lower_limit, t_log_Teff_lower_limit)
1008 :
1009 10 : else if (log_Teff >= s% log_Teff_upper_limit) then
1010 : call compare_to_target('log_Teff >= log_Teff_upper_limit', &
1011 0 : log_Teff, s% log_Teff_upper_limit, t_log_Teff_upper_limit)
1012 :
1013 10 : else if (log_surface_temperature <= s% log_Tsurf_lower_limit) then
1014 : call compare_to_target('log_surface_temperature <= log_Tsurf_lower_limit', &
1015 0 : log_surface_temperature, s% log_Tsurf_lower_limit, t_log_Tsurf_lower_limit)
1016 :
1017 10 : else if (log_surface_temperature >= s% log_Tsurf_upper_limit) then
1018 : call compare_to_target('log_surface_temperature >= log_Tsurf_upper_limit', &
1019 0 : log_surface_temperature, s% log_Tsurf_upper_limit, t_log_Tsurf_upper_limit)
1020 :
1021 10 : else if (s% log_surface_radius <= s% log_Rsurf_lower_limit) then
1022 : call compare_to_target('log_surface_radius <= log_Rsurf_lower_limit', &
1023 0 : s% log_surface_radius, s% log_Rsurf_lower_limit, t_log_Rsurf_lower_limit)
1024 :
1025 10 : else if (s% log_surface_radius >= s% log_Rsurf_upper_limit) then
1026 : call compare_to_target('log_surface_radius >= log_Rsurf_upper_limit', &
1027 0 : s% log_surface_radius, s% log_Rsurf_upper_limit, t_log_Rsurf_upper_limit)
1028 :
1029 10 : else if (log_surface_pressure <= s% log_Psurf_lower_limit) then
1030 : call compare_to_target('log_surface_pressure <= log_Psurf_lower_limit', &
1031 0 : log_surface_pressure, s% log_Psurf_lower_limit, t_log_Psurf_lower_limit)
1032 :
1033 10 : else if (log_surface_pressure >= s% log_Psurf_upper_limit) then
1034 : call compare_to_target('log_surface_pressure >= log_Psurf_upper_limit', &
1035 0 : log_surface_pressure, s% log_Psurf_upper_limit, t_log_Psurf_upper_limit)
1036 :
1037 10 : else if (log_surface_density <= s% log_Dsurf_lower_limit) then
1038 : call compare_to_target('log_surface_density <= log_Dsurf_lower_limit', &
1039 0 : log_surface_density, s% log_Dsurf_lower_limit, t_log_Dsurf_lower_limit)
1040 :
1041 10 : else if (log_surface_density >= s% log_Dsurf_upper_limit) then
1042 : call compare_to_target('log_surface_density >= log_Dsurf_upper_limit', &
1043 0 : log_surface_density, s% log_Dsurf_upper_limit, t_log_Dsurf_upper_limit)
1044 :
1045 10 : else if (s% log_surface_luminosity <= s% log_L_lower_limit) then
1046 : call compare_to_target('log_surface_luminosity <= log_L_lower_limit', &
1047 0 : s% log_surface_luminosity, s% log_L_lower_limit, t_log_L_lower_limit)
1048 :
1049 10 : else if (s% log_surface_luminosity >= s% log_L_upper_limit) then
1050 : call compare_to_target('log_surface_luminosity >= log_L_upper_limit', &
1051 0 : s% log_surface_luminosity, s% log_L_upper_limit, t_log_L_upper_limit)
1052 :
1053 10 : else if (log_surface_gravity <= s% log_g_lower_limit) then
1054 : call compare_to_target('log_surface_gravity <= log_g_lower_limit', &
1055 0 : log_surface_gravity, s% log_g_lower_limit, t_log_g_lower_limit)
1056 :
1057 10 : else if (log_surface_gravity >= s% log_g_upper_limit) then
1058 : call compare_to_target('log_surface_gravity >= log_g_upper_limit', &
1059 0 : log_surface_gravity, s% log_g_upper_limit, t_log_g_upper_limit)
1060 :
1061 10 : else if (power_nuc_burn >= s% power_nuc_burn_upper_limit) then
1062 : call compare_to_target('power_nuc_burn >= power_nuc_burn_upper_limit', &
1063 0 : power_nuc_burn, s% power_nuc_burn_upper_limit, t_power_nuc_burn_upper_limit)
1064 :
1065 10 : else if (power_h_burn >= s% power_h_burn_upper_limit) then
1066 : call compare_to_target('power_h_burn >= power_h_burn_upper_limit', &
1067 0 : power_h_burn, s% power_h_burn_upper_limit, t_power_h_burn_upper_limit)
1068 :
1069 10 : else if (power_he_burn >= s% power_he_burn_upper_limit) then
1070 : call compare_to_target('power_he_burn >= power_he_burn_upper_limit', &
1071 0 : power_he_burn, s% power_he_burn_upper_limit, t_power_he_burn_upper_limit)
1072 :
1073 10 : else if (power_z_burn >= s% power_z_burn_upper_limit) then
1074 : call compare_to_target('power_z_burn >= power_z_burn_upper_limit', &
1075 0 : power_z_burn, s% power_z_burn_upper_limit, t_power_z_burn_upper_limit)
1076 :
1077 10 : else if (power_nuc_burn < s% power_nuc_burn_lower_limit) then
1078 : call compare_to_target('power_nuc_burn < power_nuc_burn_lower_limit', &
1079 0 : power_nuc_burn, s% power_nuc_burn_lower_limit, t_power_nuc_burn_lower_limit)
1080 :
1081 10 : else if (power_h_burn < s% power_h_burn_lower_limit) then
1082 : call compare_to_target('power_h_burn < power_h_burn_lower_limit', &
1083 0 : power_h_burn, s% power_h_burn_lower_limit, t_power_h_burn_lower_limit)
1084 :
1085 10 : else if (power_he_burn < s% power_he_burn_lower_limit) then
1086 : call compare_to_target('power_he_burn < power_he_burn_lower_limit', &
1087 0 : power_he_burn, s% power_he_burn_lower_limit, t_power_he_burn_lower_limit)
1088 :
1089 10 : else if (power_z_burn < s% power_z_burn_lower_limit) then
1090 : call compare_to_target('power_z_burn < power_z_burn_lower_limit', &
1091 0 : power_z_burn, s% power_z_burn_lower_limit, t_power_z_burn_lower_limit)
1092 :
1093 10 : else if (s% center_Ye < s% center_Ye_lower_limit) then
1094 : call compare_to_target('center_Ye < center_Ye_lower_limit', &
1095 0 : s% center_Ye, s% center_Ye_lower_limit, t_center_Ye_lower_limit)
1096 :
1097 10 : else if (s% R_center < s% center_R_lower_limit) then
1098 : call compare_to_target('R_center < center_R_lower_limit', &
1099 0 : s% R_center, s% center_R_lower_limit, t_center_R_lower_limit)
1100 :
1101 10 : else if (s% fe_core_infall > s% fe_core_infall_limit) then
1102 0 : if (abs(s% error_in_energy_conservation/s% total_energy_end) < &
1103 : s% hard_limit_for_rel_error_in_energy_conservation) then
1104 0 : do_check_limits = terminate
1105 0 : s% result_reason = result_reason_normal
1106 0 : s% termination_code = t_fe_core_infall_limit
1107 : write(*, '(/,a,/, 99e20.10)') &
1108 0 : 'stop because fe_core_infall > fe_core_infall_limit', &
1109 0 : s% fe_core_infall, s% fe_core_infall_limit
1110 : else
1111 0 : write(*,2) 'rel_E_err too large for fe_core_infall termination', &
1112 0 : s% model_number, s% error_in_energy_conservation/abs(s% total_energy_end)
1113 : end if
1114 :
1115 10 : else if (s% non_fe_core_infall > s% non_fe_core_infall_limit) then
1116 : call compare_to_target('non_fe_core_infall > non_fe_core_infall_limit', &
1117 0 : s% non_fe_core_infall, s% non_fe_core_infall_limit, t_non_fe_core_infall_limit)
1118 :
1119 10 : else if (s% non_fe_core_rebound > s% non_fe_core_rebound_limit) then
1120 : call compare_to_target('non_fe_core_rebound > non_fe_core_rebound_limit', &
1121 0 : s% non_fe_core_rebound, s% non_fe_core_rebound_limit, t_non_fe_core_rebound_limit)
1122 :
1123 10 : else if (v_surf/csound_surf > s% v_div_csound_surf_limit) then
1124 : call compare_to_target('v_surf/csound_surf > v_div_csound_surf_limit', &
1125 0 : v_surf/csound_surf, s% v_div_csound_surf_limit, t_v_div_csound_surf_limit)
1126 :
1127 10 : else if (v_div_csound_max > s% v_div_csound_max_limit) then
1128 : call compare_to_target('v_div_csound_max > v_div_csound_max_limit', &
1129 0 : v_div_csound_max, s% v_div_csound_max_limit, t_v_div_csound_max_limit)
1130 :
1131 10 : else if (s% min_gamma1 < s% gamma1_limit) then
1132 : call compare_to_target('min_gamma1 < gamma1_limit', &
1133 0 : s% min_gamma1, s% gamma1_limit, t_gamma1_limit)
1134 :
1135 10 : else if (min_pgas_div_p < s% Pgas_div_P_limit) then
1136 : call compare_to_target('min_pgas_div_p < Pgas_div_P_limit', &
1137 0 : min_pgas_div_p, s% Pgas_div_P_limit, t_Pgas_div_P_limit)
1138 :
1139 10 : else if (Lnuc_div_L <= s% Lnuc_div_L_lower_limit) then
1140 : call compare_to_target('Lnuc_div_L <= Lnuc_div_L_lower_limit', &
1141 0 : Lnuc_div_L, s% Lnuc_div_L_lower_limit, t_Lnuc_div_L_lower_limit)
1142 :
1143 10 : else if (Lnuc_div_L >= s% Lnuc_div_L_upper_limit) then
1144 : call compare_to_target('Lnuc_div_L >= Lnuc_div_L_upper_limit', &
1145 0 : Lnuc_div_L, s% Lnuc_div_L_upper_limit, t_Lnuc_div_L_upper_limit)
1146 :
1147 10 : else if (v_surf_div_v_kh <= s% v_surf_div_v_kh_lower_limit) then
1148 : call compare_to_target('v_surf_div_v_kh <= v_surf_div_v_kh_lower_limit', &
1149 0 : v_surf_div_v_kh, s% v_surf_div_v_kh_lower_limit, t_v_surf_div_v_kh_lower_limit)
1150 :
1151 10 : else if (v_surf_div_v_kh >= s% v_surf_div_v_kh_upper_limit) then
1152 : call compare_to_target('v_surf_div_v_kh >= v_surf_div_v_kh_upper_limit', &
1153 0 : v_surf_div_v_kh, s% v_surf_div_v_kh_upper_limit, t_v_surf_div_v_kh_upper_limit)
1154 :
1155 10 : else if (v_surf_div_v_esc >= s% v_surf_div_v_esc_limit) then
1156 : call compare_to_target('v_surf_div_v_esc >= v_surf_div_v_esc_limit', &
1157 0 : v_surf_div_v_esc, s% v_surf_div_v_esc_limit, t_v_surf_div_v_esc_limit)
1158 :
1159 10 : else if (v_surf*1d-5 >= s% v_surf_kms_limit) then
1160 : call compare_to_target('v_surf_kms >= v_surf_kms_limit', &
1161 0 : v_surf*1d-5, s% v_surf_kms_limit, t_v_surf_kms_limit)
1162 :
1163 : else if (s% cumulative_extra_heating >= &
1164 10 : s% stop_when_reach_this_cumulative_extra_heating .and.&
1165 : s% stop_when_reach_this_cumulative_extra_heating > 0) then
1166 : call compare_to_target( &
1167 : 'cumulative_extra_heating >= limit', &
1168 : s% cumulative_extra_heating, &
1169 : s% stop_when_reach_this_cumulative_extra_heating, &
1170 0 : t_cumulative_extra_heating_limit)
1171 :
1172 10 : else if (s% stop_near_zams .and. &
1173 : Lnuc_div_L >= s% Lnuc_div_L_zams_limit) then
1174 0 : do_check_limits = terminate
1175 0 : s% termination_code = t_Lnuc_div_L_zams_limit
1176 0 : s% result_reason = result_reason_normal
1177 : write(*, '(/,a,/, 99e20.10)') &
1178 0 : 'stop because Lnuc_div_L >= Lnuc_div_L_zams_limit', Lnuc_div_L, s% Lnuc_div_L_zams_limit
1179 :
1180 10 : else if (s% stop_at_phase_PreMS .and. s% phase_of_evolution == phase_PreMS) then
1181 0 : do_check_limits = terminate
1182 0 : s% termination_code = t_phase_PreMS
1183 0 : s% result_reason = result_reason_normal
1184 0 : write(*, '(/,a,/)') 'stop because phase_of_evolution == phase_PreMS'
1185 :
1186 10 : else if (s% stop_at_phase_ZAMS .and. s% phase_of_evolution == phase_ZAMS) then
1187 0 : do_check_limits = terminate
1188 0 : s% termination_code = t_phase_ZAMS
1189 0 : s% result_reason = result_reason_normal
1190 0 : write(*, '(/,a,/)') 'stop because phase_of_evolution == phase_ZAMS'
1191 :
1192 10 : else if (s% stop_at_phase_IAMS .and. s% phase_of_evolution == phase_IAMS) then
1193 0 : do_check_limits = terminate
1194 0 : s% termination_code = t_phase_IAMS
1195 0 : s% result_reason = result_reason_normal
1196 0 : write(*, '(/,a,/)') 'stop because phase_of_evolution == phase_IAMS'
1197 :
1198 10 : else if (s% stop_at_phase_TAMS .and. s% phase_of_evolution == phase_TAMS) then
1199 0 : do_check_limits = terminate
1200 0 : s% termination_code = t_phase_TAMS
1201 0 : s% result_reason = result_reason_normal
1202 0 : write(*, '(/,a,/)') 'stop because phase_of_evolution == phase_TAMS'
1203 :
1204 10 : else if (s% stop_at_phase_He_Burn .and. s% phase_of_evolution == phase_He_Burn) then
1205 0 : do_check_limits = terminate
1206 0 : s% termination_code = t_phase_He_Burn
1207 0 : s% result_reason = result_reason_normal
1208 0 : write(*, '(/,a,/)') 'stop because phase_of_evolution == phase_He_Burn'
1209 :
1210 10 : else if (s% stop_at_phase_ZACHeB .and. s% phase_of_evolution == phase_ZACHeB) then
1211 0 : do_check_limits = terminate
1212 0 : s% termination_code = t_phase_ZACHeB
1213 0 : s% result_reason = result_reason_normal
1214 0 : write(*, '(/,a,/)') 'stop because phase_of_evolution == phase_ZACHeB'
1215 :
1216 10 : else if (s% stop_at_phase_TACHeB .and. s% phase_of_evolution == phase_TACHeB) then
1217 0 : do_check_limits = terminate
1218 0 : s% termination_code = t_phase_TACHeB
1219 0 : s% result_reason = result_reason_normal
1220 0 : write(*, '(/,a,/)') 'stop because phase_of_evolution == phase_TACHeB'
1221 :
1222 10 : else if (s% stop_at_phase_TP_AGB .and. s% phase_of_evolution == phase_TP_AGB) then
1223 0 : do_check_limits = terminate
1224 0 : s% termination_code = t_phase_TP_AGB
1225 0 : s% result_reason = result_reason_normal
1226 0 : write(*, '(/,a,/)') 'stop because phase_of_evolution == phase_TP_AGB'
1227 :
1228 10 : else if (s% stop_at_phase_C_Burn .and. s% phase_of_evolution == phase_C_Burn) then
1229 0 : do_check_limits = terminate
1230 0 : s% termination_code = t_phase_C_Burn
1231 0 : s% result_reason = result_reason_normal
1232 0 : write(*, '(/,a,/)') 'stop because phase_of_evolution == phase_C_Burn'
1233 :
1234 10 : else if (s% stop_at_phase_Ne_Burn .and. s% phase_of_evolution == phase_Ne_Burn) then
1235 0 : do_check_limits = terminate
1236 0 : s% termination_code = t_phase_Ne_Burn
1237 0 : s% result_reason = result_reason_normal
1238 0 : write(*, '(/,a,/)') 'stop because phase_of_evolution == phase_Ne_Burn'
1239 :
1240 10 : else if (s% stop_at_phase_O_Burn .and. s% phase_of_evolution == phase_O_Burn) then
1241 0 : do_check_limits = terminate
1242 0 : s% termination_code = t_phase_O_Burn
1243 0 : s% result_reason = result_reason_normal
1244 0 : write(*, '(/,a,/)') 'stop because phase_of_evolution == phase_O_Burn'
1245 :
1246 10 : else if (s% stop_at_phase_Si_Burn .and. s% phase_of_evolution == phase_Si_Burn) then
1247 0 : do_check_limits = terminate
1248 0 : s% termination_code = t_phase_Si_Burn
1249 0 : s% result_reason = result_reason_normal
1250 0 : write(*, '(/,a,/)') 'stop because phase_of_evolution == phase_Si_Burn'
1251 :
1252 10 : else if (s% stop_at_phase_WDCS .and. s% phase_of_evolution == phase_WDCS) then
1253 0 : do_check_limits = terminate
1254 0 : s% termination_code = t_phase_WDCS
1255 0 : s% result_reason = result_reason_normal
1256 0 : write(*, '(/,a,/)') 'stop because phase_of_evolution == phase_WDCS'
1257 :
1258 : end if
1259 :
1260 11 : if (s% u_flag .or. s% v_flag) then ! Things that depend on hydro related quantities
1261 0 : if (s% shock_mass >= s% shock_mass_upper_limit .and. s% shock_mass_upper_limit > 0) then
1262 : call compare_to_target('shock_mass >= shock_mass_upper_limit', &
1263 0 : s% shock_mass, s% shock_mass_upper_limit, t_shock_mass_upper_limit)
1264 : end if
1265 : end if
1266 :
1267 11 : if (do_check_limits /= keep_going) return
1268 :
1269 100 : do j=1,num_xa_central_limits
1270 90 : if (s% xa_central_lower_limit(j) <= 0) cycle
1271 0 : if (len_trim(s% xa_central_lower_limit_species(j)) == 0) cycle
1272 0 : cid = chem_get_iso_id(s% xa_central_lower_limit_species(j))
1273 0 : if (cid <= 0) then
1274 0 : write(*,'(A)')
1275 0 : write(*,2) '<' // trim(s% xa_central_lower_limit_species(j)) // '>'
1276 0 : write(*,2) 'is invalid for xa_central_lower_limit_species', j
1277 0 : write(*,'(A)')
1278 0 : do_check_limits = terminate
1279 0 : return
1280 : end if
1281 0 : i = s% net_iso(cid)
1282 0 : if (i == 0) cycle
1283 0 : avg_x = center_avg_x(s,i)
1284 10 : if (avg_x < s% xa_central_lower_limit(j)) then
1285 : call compare_to_target('have dropped below central lower limit for ' // &
1286 : trim(s% xa_central_lower_limit_species(j)), &
1287 0 : avg_x, s% xa_central_lower_limit(j), t_xa_central_lower_limit)
1288 0 : exit
1289 : end if
1290 : end do
1291 :
1292 10 : if (do_check_limits /= keep_going) return
1293 :
1294 100 : do j=1,num_xa_central_limits
1295 90 : if (s% xa_central_upper_limit(j) <= 0) cycle
1296 0 : if (s% xa_central_upper_limit(j) >= 1) cycle
1297 0 : if (len_trim(s% xa_central_upper_limit_species(j)) == 0) cycle
1298 0 : cid = chem_get_iso_id(s% xa_central_upper_limit_species(j))
1299 0 : if (cid <= 0) then
1300 : !cycle
1301 0 : write(*,'(A)')
1302 0 : write(*,2) '<' // trim(s% xa_central_upper_limit_species(j)) // '>'
1303 0 : write(*,2) 'is invalid for xa_central_upper_limit_species', j
1304 0 : write(*,'(A)')
1305 0 : do_check_limits = terminate
1306 0 : return
1307 : end if
1308 0 : i = s% net_iso(cid)
1309 0 : if (i == 0) cycle
1310 0 : avg_x = center_avg_x(s,i)
1311 10 : if (avg_x > s% xa_central_upper_limit(j)) then
1312 : call compare_to_target('have risen above central upper limit for ' // &
1313 : trim(s% xa_central_upper_limit_species(j)), &
1314 0 : avg_x, s% xa_central_upper_limit(j), t_xa_central_upper_limit)
1315 0 : exit
1316 : end if
1317 : end do
1318 :
1319 10 : if (do_check_limits /= keep_going) return
1320 :
1321 100 : do j=1,num_xa_surface_limits
1322 90 : if (s% xa_surface_lower_limit(j) <= 0) cycle
1323 0 : if (len_trim(s% xa_surface_lower_limit_species(j)) == 0) cycle
1324 0 : cid = chem_get_iso_id(s% xa_surface_lower_limit_species(j))
1325 0 : if (cid <= 0) then
1326 0 : write(*,'(A)')
1327 0 : write(*,2) '<' // trim(s% xa_surface_lower_limit_species(j)) // '>'
1328 0 : write(*,2) 'is invalid for xa_surface_lower_limit_species', j
1329 0 : write(*,'(A)')
1330 0 : do_check_limits = terminate
1331 0 : return
1332 : end if
1333 0 : i = s% net_iso(cid)
1334 0 : if (i == 0) cycle
1335 0 : avg_x = surface_avg_x(s,i)
1336 10 : if (avg_x < s% xa_surface_lower_limit(j)) then
1337 : call compare_to_target('have dropped below surface lower limit for ' // &
1338 : trim(s% xa_surface_lower_limit_species(j)), &
1339 0 : avg_x, s% xa_surface_lower_limit(j), t_xa_surface_lower_limit)
1340 0 : exit
1341 : end if
1342 : end do
1343 :
1344 10 : if (do_check_limits /= keep_going) return
1345 :
1346 100 : do j=1,num_xa_surface_limits
1347 90 : if (s% xa_surface_upper_limit(j) <= 0) cycle
1348 0 : if (s% xa_surface_upper_limit(j) >= 1) cycle
1349 0 : if (len_trim(s% xa_surface_upper_limit_species(j)) == 0) cycle
1350 0 : cid = chem_get_iso_id(s% xa_surface_upper_limit_species(j))
1351 0 : if (cid <= 0) then
1352 : !cycle
1353 0 : write(*,'(A)')
1354 0 : write(*,2) '<' // trim(s% xa_surface_upper_limit_species(j)) // '>'
1355 0 : write(*,2) 'is invalid for xa_surface_upper_limit_species', j
1356 0 : write(*,'(A)')
1357 0 : do_check_limits = terminate
1358 0 : return
1359 : end if
1360 0 : i = s% net_iso(cid)
1361 0 : if (i == 0) cycle
1362 0 : avg_x = surface_avg_x(s,i)
1363 10 : if (avg_x > s% xa_surface_upper_limit(j)) then
1364 : call compare_to_target('have risen above surface upper limit for ' // &
1365 : trim(s% xa_surface_upper_limit_species(j)), &
1366 0 : avg_x, s% xa_surface_upper_limit(j), t_xa_surface_upper_limit)
1367 0 : exit
1368 : end if
1369 : end do
1370 :
1371 10 : if (do_check_limits /= keep_going) return
1372 :
1373 100 : do j=1,num_xa_average_limits
1374 90 : if (s% xa_average_lower_limit(j) <= 0) cycle
1375 0 : if (len_trim(s% xa_average_lower_limit_species(j)) == 0) cycle
1376 0 : cid = chem_get_iso_id(s% xa_average_lower_limit_species(j))
1377 0 : if (cid <= 0) then
1378 : !cycle
1379 0 : write(*,'(A)')
1380 0 : write(*,2) '<' // trim(s% xa_average_lower_limit_species(j)) // '>'
1381 0 : write(*,2) 'is invalid for xa_average_lower_limit_species', j
1382 0 : write(*,'(A)')
1383 0 : do_check_limits = terminate
1384 0 : return
1385 : end if
1386 0 : i = s% net_iso(cid)
1387 0 : if (i == 0) cycle
1388 0 : avg_x = dot_product(s% dq(1:nz), s% xa(i,1:nz))
1389 10 : if (avg_x < s% xa_average_lower_limit(j)) then
1390 : call compare_to_target('have dropped below average lower limit for ' // &
1391 : trim(s% xa_average_lower_limit_species(j)), &
1392 0 : avg_x, s% xa_average_lower_limit(j), t_xa_average_lower_limit)
1393 0 : exit
1394 : end if
1395 : end do
1396 :
1397 10 : if (do_check_limits /= keep_going) return
1398 :
1399 111 : do j=1,num_xa_average_limits
1400 90 : if (s% xa_average_upper_limit(j) <= 0) cycle
1401 0 : if (s% xa_average_upper_limit(j) >= 1) cycle
1402 0 : if (len_trim(s% xa_average_upper_limit_species(j)) == 0) cycle
1403 0 : cid = chem_get_iso_id(s% xa_average_upper_limit_species(j))
1404 0 : if (cid <= 0) then
1405 0 : write(*,'(A)')
1406 0 : write(*,2) '<' // trim(s% xa_average_upper_limit_species(j)) // '>'
1407 0 : write(*,2) 'is invalid for xa_average_upper_limit_species', j
1408 0 : write(*,'(A)')
1409 0 : do_check_limits = terminate
1410 0 : return
1411 : end if
1412 0 : i = s% net_iso(cid)
1413 0 : if (i == 0) cycle
1414 0 : avg_x = dot_product(s% dq(1:nz), s% xa(i,1:nz))
1415 10 : if (avg_x > s% xa_average_upper_limit(j)) then
1416 : call compare_to_target('have risen above average upper limit for ' // &
1417 : trim(s% xa_average_upper_limit_species(j)), &
1418 0 : avg_x, s% xa_average_upper_limit(j), t_xa_average_upper_limit)
1419 0 : exit
1420 : end if
1421 : end do
1422 :
1423 :
1424 : contains
1425 :
1426 :
1427 23 : subroutine compare_to_target(str, value, target_value, termination_code)
1428 : character (len=*), intent(in) :: str
1429 : real(dp), intent(in) :: value, target_value
1430 : integer, intent(in) :: termination_code
1431 1 : real(dp) :: err
1432 : include 'formats'
1433 : err = abs(value - target_value)/ &
1434 1 : (s% when_to_stop_atol + s% when_to_stop_rtol*max(abs(value),abs(target_value)))
1435 1 : if (err > 1) then
1436 0 : do_check_limits = redo
1437 0 : s% dt = 0.5d0*s% dt
1438 : write(*,'(/,a,5e20.10)') &
1439 0 : 'redo with smaller timestep to get closer to stopping target ' // trim(str), &
1440 0 : value, target_value
1441 : else
1442 1 : do_check_limits = terminate
1443 1 : s% result_reason = result_reason_normal
1444 1 : s% termination_code = termination_code
1445 1 : write(*, '(/,a,/, 99e20.10)') 'stop because ' // trim(str), value, target_value
1446 : end if
1447 11 : end subroutine compare_to_target
1448 :
1449 :
1450 22 : real(dp) function get_species_mass(str) ! Msun
1451 : use chem_lib, only: chem_get_iso_id
1452 : character(len=*), intent(in) :: str
1453 : integer :: id, j
1454 22 : get_species_mass = -1d0
1455 22 : id = chem_get_iso_id(str)
1456 22 : if (id > 0) then
1457 0 : j = s% net_iso(id)
1458 0 : if (j > 0) then
1459 0 : get_species_mass = dot_product(s% dm(1:s% nz),s% xa(j,1:s% nz))/Msun
1460 : end if
1461 : end if
1462 22 : end function get_species_mass
1463 :
1464 :
1465 : end function do_check_limits
1466 :
1467 :
1468 11 : integer function do_one_check_model(id)
1469 : use rates_def, only: i_rate
1470 : use chem_def, only: i_burn_c
1471 : use star_utils, only: update_time, total_times
1472 : integer, intent(in) :: id
1473 :
1474 : logical :: must_do_profile
1475 : real(dp), parameter :: log_he_temp = 7.8d0
1476 : real(dp), parameter :: d_tau_min = 1d-2, d_tau_max = 1d0
1477 : real(dp), parameter :: little_step_factor = 10d0, little_step_size = 10d0
1478 11 : real(dp) :: v, power_he_burn, power_z_burn, &
1479 11 : power_neutrinos
1480 : integer :: model, profile_priority, ierr
1481 : integer, parameter :: tau_ramp = 50
1482 : type (star_info), pointer :: s
1483 : logical :: logged
1484 : integer :: nz
1485 : logical, parameter :: dbg = .false.
1486 :
1487 : include 'formats'
1488 :
1489 11 : call get_star_ptr(id, s, ierr)
1490 11 : if (ierr /= 0) then
1491 11 : do_one_check_model = terminate
1492 : return
1493 : end if
1494 :
1495 11 : nz = s% nz
1496 11 : must_do_profile = .false.
1497 11 : profile_priority = delta_priority
1498 11 : model = s% model_number
1499 11 : do_one_check_model = keep_going
1500 :
1501 11 : do_one_check_model = do_check_limits(id)
1502 11 : if (do_one_check_model /= keep_going) then
1503 : if (dbg) write(*,*) 'do_check_limits /= keep_going'
1504 1 : write(*,'(A)')
1505 1 : must_do_profile = .true.
1506 : end if
1507 :
1508 11 : if (s% u_flag) then
1509 : v = s% u(1)
1510 : else if (s% v_flag) then
1511 : v = s% v(1)
1512 : else
1513 11 : v = 0d0
1514 : end if
1515 :
1516 11 : power_he_burn = s% power_he_burn
1517 11 : power_z_burn = s% power_z_burn
1518 11 : power_neutrinos = s% power_neutrinos
1519 :
1520 11 : if (must_do_profile) profile_priority = phase_priority
1521 :
1522 11 : logged = get_history_info(s, must_do_profile)
1523 :
1524 11 : if (logged .and. s% write_profiles_flag) then
1525 : if (s% model_number == s% profile_model &
1526 11 : .or. (s% profile_interval > 0 .and. &
1527 : (s% doing_first_model_of_run .or. &
1528 : mod(s% model_number,s% profile_interval) == 0))) then
1529 1 : if (s% write_profiles_flag) must_do_profile = .true.
1530 : if (s% model_number == s% profile_model .or. &
1531 1 : s% doing_first_model_of_run .or. &
1532 : (mod(s% model_number, s% priority_profile_interval) == 0)) then
1533 11 : profile_priority = phase_priority
1534 : end if
1535 : end if
1536 11 : if ( must_do_profile ) then
1537 : if (dbg) write(*,*) 'do_one_check_model: call set_save_profiles_info'
1538 2 : call set_save_profiles_info(s, profile_priority)
1539 : end if
1540 : end if
1541 :
1542 11 : end function do_one_check_model
1543 :
1544 : end module do_one_utils
|