-
Notifications
You must be signed in to change notification settings - Fork 2
Expand file tree
/
Copy pathmodpk_errorhandling.f90
More file actions
220 lines (162 loc) · 6.43 KB
/
modpk_errorhandling.f90
File metadata and controls
220 lines (162 loc) · 6.43 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
module modpk_errorhandling
!Module for handling exceptions and warnings.
!More info is sometimes printed to screen where these occur.
use modpk_io, only : out_opt
implicit none
private
public :: raise, run_outcome, assert
!General class for errors
type :: error
contains
procedure, public :: fatal_code => raise_exception_code
procedure, public :: fatal_cosmo => raise_exception_cosmo
procedure, public :: warning => raise_warning
end type
!Type that contains indices for classifying bad sets of parameters
type :: run_outcome_type
!Success
integer :: success = 0
!Failure, not fatal > 0
integer :: infl_didnt_start = 1
integer :: pivot_didnt_leaveH = 2
integer :: cant_set_modeIC = 3
integer :: cant_init_scalefact = 4
integer :: ref_efold_didnt_leaveH = 5
integer :: bad_reheat = 6
!Fatal < 0
integer :: underflow = -1
contains
procedure, public :: is_fatal => compare_params_fatal
procedure, public :: print_outcome => output_the_outcome
end type
type :: asserter
logical :: use_assertions = .true.
contains
procedure, public :: check => check_an_assertion
end type asserter
type(error) :: raise
type(asserter) :: assert
type(run_outcome_type) :: run_outcome
contains
!Code-related warnings handled here.
subroutine raise_warning(self, msg, fname, line)
class(error) :: self
character(*), intent(in) :: msg
character(*), intent(in), optional :: fname
integer, intent(in), optional :: line
if (out_opt%modpkoutput) then
if (.not. out_opt%output_reduced) then
print*, "**********************************************"
if (present(fname)) &
print*, "WARNING: Occured in file ", fname
if (present(fname)) &
print*, "WARNING: At line number ", line
print*, "**********************************************"
end if
print*, "MODECODE: ", trim(msg)
end if
end subroutine raise_warning
subroutine raise_exception_code(self, msg, fname, line)
class(error) :: self
character(*), intent(in) :: msg
character(*), intent(in), optional :: fname
integer, intent(in), optional :: line
!Print out even if asking for no output (modpkoutput=.false.)
print*, "**********************************************"
print*, "ERROR: Encountered a fatal exception."
if (present(fname)) &
print*, "ERROR: Occured in file ", fname
if (present(line)) &
print*, "ERROR: At line number ", line
print*, "ERROR: The error is code-related."
print*, "**********************************************"
print*, "MODECODE: ", trim(msg)
stop
end subroutine raise_exception_code
subroutine raise_exception_cosmo(self, msg, fname, line)
class(error) :: self
character(*), intent(in) :: msg
character(*), intent(in), optional :: fname
integer, intent(in), optional :: line
!Print out even if asking for no output (modpkoutput=.false.)
print*, "**********************************************"
print*, "ERROR: Encountered a fatal exception."
if (present(fname)) &
print*, "ERROR: Occured in file ", fname
if (present(line)) &
print*, "ERROR: At line number ", line
print*, "ERROR: The error is cosmology-related."
print*, "**********************************************"
print*, "MODECODE: ", trim(msg)
stop
end subroutine raise_exception_cosmo
subroutine compare_params_fatal(self, outcome)
class(run_outcome_type) :: self
integer, intent(in) :: outcome
logical :: is_fatal
if (outcome < 0) then
!Fatal
is_fatal = .true.
call raise%fatal_cosmo(&
"This set of parameters gives a fatal error &
and it's not worth trying new parameters.",&
__FILE__, __LINE__)
else
!Not fatal
is_fatal = .false.
end if
end subroutine compare_params_fatal
subroutine output_the_outcome(self, outcome)
class(run_outcome_type) :: self
integer, intent(in) :: outcome
logical :: is_fatal
if (outcome == self%success) then
if (out_opt%modpkoutput) &
print*, "MODECODE: Successful set of parameters.", outcome
else if (outcome == self%infl_didnt_start) then
if (out_opt%modpkoutput) &
print*, "MODECODE: Inflation didn't start.", outcome
else if (outcome == self%pivot_didnt_leaveH) then
if (out_opt%modpkoutput) &
print*, "MODECODE: The pivot scale didn't leave the horizon.", outcome
else if (outcome == self%cant_set_modeIC) then
if (out_opt%modpkoutput) &
print*, "MODECODE: A modes' IC couldn't be consistently set.", outcome
else if (outcome == self%cant_init_scalefact) then
if (out_opt%modpkoutput) &
print*, "MODECODE: Too many e-folds; can't initialize the scale factor.", outcome
else if (outcome == self%ref_efold_didnt_leaveH) then
if (out_opt%modpkoutput) &
print*, "MODECODE: Trying to save the field values at some reference N, &
but got less evolution than that.", outcome
else if (outcome == self%bad_reheat) then
if (out_opt%modpkoutput) &
print*, "MODECODE: Didn't satisfy reheating bounds.", outcome
else if (outcome == self%underflow) then
if (out_opt%modpkoutput) &
print*, "MODECODE: Numerical underflow error in odeint.", outcome
else
print*, "MODECODE: pk_bad=", outcome
call raise%fatal_code(&
"The outcome flag pk_bad was set to a value that &
wasn't caught by the run_outcome type.", &
__FILE__, __LINE__)
end if
!Check if the whole run should be stopped because of the outcome
call self%is_fatal(outcome)
if (out_opt%modpkoutput) &
print*, "............... RESTARTING ..............."
end subroutine output_the_outcome
subroutine check_an_assertion(self, flag, fname, line)
class(asserter) :: self
logical, intent(in) :: flag
character(*), intent(in) :: fname
integer, intent(in) :: line
!Turn off assertions
if (.not. self%use_assertions) return
if (.not. flag) then
call raise%fatal_code(&
"An assertion failed.", fname, line)
end if
end subroutine check_an_assertion
end module modpk_errorhandling