31 use camp_env_state,
only: camp_env_state_t =>
env_state_t
33 #ifdef PMC_USE_SUNDIALS
50 real(kind=
dp) :: t_max
52 real(kind=
dp) :: t_output
54 real(kind=
dp) :: t_progress
56 real(kind=
dp) :: del_t
58 character(len=300) :: output_prefix
60 integer :: coag_kernel_type
62 integer :: nucleate_type
64 integer :: nucleate_source
66 logical :: do_coagulation
68 logical :: do_nucleation
70 logical :: allow_doubling
72 logical :: allow_halving
74 logical :: do_condensation
80 logical :: do_select_weighting
82 integer :: weighting_type
84 real(kind=
dp) :: weighting_exponent
90 real(kind=
dp) :: t_wall_start
92 logical :: record_removals
94 logical :: do_parallel
96 integer :: output_type
98 real(kind=
dp) :: mix_timescale
100 logical :: gas_average
102 logical :: env_average
104 integer :: parallel_coag_type
106 logical :: do_camp_chem
108 character(len=PMC_UUID_LEN) :: uuid
117 subroutine run_part(scenario, env_state, aero_data, aero_state, gas_data, &
118 gas_state, run_part_opt, camp_core, photolysis)
120 subroutine run_part(scenario, env_state, aero_data, aero_state, gas_data, &
121 gas_state, run_part_opt)
139 type(camp_core_t),
pointer,
intent(inout),
optional :: camp_core
141 type(photolysis_t),
pointer,
intent(inout),
optional :: photolysis
143 type(camp_state_t),
pointer :: camp_state
144 type(camp_state_t),
pointer :: camp_pre_aero_state, camp_post_aero_state
147 real(kind=
dp) :: time, pre_time, pre_del_t, prop_done
148 real(kind=
dp) :: last_output_time, last_progress_time
149 integer :: rank, n_proc, pre_index, ncid
150 integer :: pre_i_repeat
151 integer :: n_samp, n_coag, n_emit, n_dil_in, n_dil_out, n_nuc
152 integer :: progress_n_samp, progress_n_coag
153 integer :: progress_n_emit, progress_n_dil_in, progress_n_dil_out
154 integer :: progress_n_nuc, n_part_before
155 integer :: global_n_part, global_n_samp, global_n_coag
156 integer :: global_n_emit, global_n_dil_in, global_n_dil_out
157 integer :: global_n_nuc
158 logical :: do_output, do_state, do_state_netcdf, do_progress, did_coag
159 real(kind=
dp) :: t_start, t_wall_now, t_wall_elapsed, t_wall_remain
161 integer :: n_time, i_time, i_time_start, pre_i_time
162 integer :: i_state, i_state_netcdf, i_output
164 type(camp_env_state_t) :: camp_env_state
178 progress_n_dil_in = 0
179 progress_n_dil_out = 0
183 "del_t", run_part_opt%del_t)
185 "del_t", run_part_opt%del_t)
187 "del_t", run_part_opt%del_t)
189 if (run_part_opt%do_camp_chem)
then
190 camp_env_state%temp = env_state%temp
191 camp_env_state%pressure = env_state%pressure
192 camp_state => camp_core%new_state_one_cell(camp_env_state)
193 camp_pre_aero_state => camp_core%new_state_one_cell(camp_env_state)
194 camp_post_aero_state => camp_core%new_state_one_cell(camp_env_state)
198 if (run_part_opt%do_mosaic)
then
199 call mosaic_init(env_state, aero_data, run_part_opt%del_t, &
200 run_part_opt%do_optical)
201 if (run_part_opt%do_optical)
then
203 aero_state, gas_data, gas_state)
207 if (run_part_opt%t_output > 0d0)
then
209 run_part_opt%output_type, aero_data, aero_state, gas_data, &
210 gas_state, env_state, i_state, time, run_part_opt%del_t, &
211 run_part_opt%i_repeat, run_part_opt%record_removals, &
212 run_part_opt%do_optical, run_part_opt%uuid)
213 call aero_info_array_zero(aero_state%aero_info_array)
217 run_part_opt%allow_doubling, &
218 run_part_opt%allow_halving, initial_state_warning=.true.)
220 t_start = env_state%elapsed_time
221 last_output_time = time
222 last_progress_time = time
223 n_time = nint(run_part_opt%t_max / run_part_opt%del_t)
224 i_time_start = nint(time / run_part_opt%del_t) + 1
229 if (run_part_opt%i_repeat == 1)
then
233 call cpu_time(t_wall_now)
234 prop_done = real(run_part_opt%i_repeat - 1, kind=
dp) &
235 / real(run_part_opt%n_repeat, kind=
dp)
236 t_wall_elapsed = t_wall_now - run_part_opt%t_wall_start
237 t_wall_remain = (1d0 - prop_done) / prop_done &
241 global_n_part, 0, 0, 0, 0, 0, t_wall_elapsed, t_wall_remain)
244 do i_time = i_time_start,n_time
246 time = real(i_time, kind=
dp) * run_part_opt%del_t
248 old_env_state = env_state
251 if (run_part_opt%do_nucleation)
then
253 call nucleate(run_part_opt%nucleate_type, &
254 run_part_opt%nucleate_source, env_state, gas_data, aero_data, &
255 aero_state, gas_state, run_part_opt%del_t, &
256 run_part_opt%allow_doubling, run_part_opt%allow_halving)
259 progress_n_nuc = progress_n_nuc + n_nuc
262 if (run_part_opt%do_coagulation)
then
263 if (run_part_opt%parallel_coag_type &
265 call mc_coag(run_part_opt%coag_kernel_type, env_state, &
266 aero_data, aero_state, run_part_opt%del_t, n_samp, n_coag)
267 elseif (run_part_opt%parallel_coag_type &
269 call mc_coag_dist(run_part_opt%coag_kernel_type, env_state, &
270 aero_data, aero_state, run_part_opt%del_t, n_samp, n_coag)
272 call die_msg(323011762,
"unknown parallel coagulation type: " &
275 progress_n_samp = progress_n_samp + n_samp
276 progress_n_coag = progress_n_coag + n_coag
279 #ifdef PMC_USE_SUNDIALS
280 if (run_part_opt%do_condensation)
then
282 env_state, run_part_opt%del_t)
287 env_state, old_env_state, gas_data, gas_state)
289 env_state, old_env_state, aero_data, aero_state, n_emit, &
290 n_dil_in, n_dil_out, run_part_opt%allow_doubling, &
291 run_part_opt%allow_halving)
292 progress_n_emit = progress_n_emit + n_emit
293 progress_n_dil_in = progress_n_dil_in + n_dil_in
294 progress_n_dil_out = progress_n_dil_out + n_dil_out
296 if (run_part_opt%do_camp_chem)
then
298 call pmc_camp_interface_solve(camp_core, camp_state, &
299 camp_pre_aero_state, camp_post_aero_state, env_state, &
300 aero_data, aero_state, gas_data, gas_state, photolysis, &
305 if (run_part_opt%do_mosaic)
then
307 gas_state, run_part_opt%do_optical)
310 if (run_part_opt%mix_timescale > 0d0)
then
312 run_part_opt%mix_timescale, aero_data)
314 if (run_part_opt%gas_average)
then
317 if (run_part_opt%gas_average)
then
322 run_part_opt%allow_doubling, &
323 run_part_opt%allow_halving, initial_state_warning=.false.)
329 if (run_part_opt%t_output > 0d0)
then
330 call check_event(time, run_part_opt%del_t, run_part_opt%t_output, &
331 last_output_time, do_output)
333 i_output = i_output + 1
335 run_part_opt%output_type, aero_data, aero_state, gas_data, &
336 gas_state, env_state, i_output, time, run_part_opt%del_t, &
337 run_part_opt%i_repeat, run_part_opt%record_removals, &
338 run_part_opt%do_optical, run_part_opt%uuid)
339 call aero_info_array_zero(aero_state%aero_info_array)
343 if (.not. run_part_opt%record_removals)
then
347 call aero_info_array_zero(aero_state%aero_info_array)
350 if (run_part_opt%t_progress > 0d0)
then
352 run_part_opt%t_progress, last_progress_time, do_progress)
353 if (do_progress)
then
365 call cpu_time(t_wall_now)
366 prop_done = (real(run_part_opt%i_repeat - 1, kind=
dp) &
367 + time / run_part_opt%t_max) &
368 / real(run_part_opt%n_repeat, kind=
dp)
369 t_wall_elapsed = t_wall_now - run_part_opt%t_wall_start
370 t_wall_remain = (1d0 - prop_done) / prop_done &
373 global_n_part, global_n_coag, global_n_emit, &
374 global_n_dil_in, global_n_dil_out, global_n_nuc, &
375 t_wall_elapsed, t_wall_remain)
382 progress_n_dil_in = 0
383 progress_n_dil_out = 0
390 if (run_part_opt%do_mosaic)
then
400 n_emit, n_dil_in, n_dil_out, n_nuc, t_wall_elapsed, t_wall_remain)
403 integer,
intent(in) :: i_repeat
405 real(kind=
dp),
intent(in) :: t_sim_elapsed
407 integer,
intent(in) :: n_part
409 integer,
intent(in) :: n_coag
411 integer,
intent(in) :: n_emit
413 integer,
intent(in) :: n_dil_in
415 integer,
intent(in) :: n_dil_out
417 integer,
intent(in) :: n_nuc
419 real(kind=
dp),
intent(in) :: t_wall_elapsed
421 real(kind=
dp),
intent(in) :: t_wall_remain
423 write(*,
'(a6,a1,a6,a1,a7,a1,a7,a1,a7,a1,a8,a1,a9,a1,a7,a1,a6,a1,a6)') &
424 "repeat",
" ",
"t_sim",
" ",
"n_part",
" ",
"n_coag",
" ", &
425 "n_emit",
" ",
"n_dil_in",
" ",
"n_dil_out",
" ",
"n_nuc",
" ", &
426 "t_wall",
" ",
"t_rem"
427 write(*,
'(a6,a1,a6,a1,a7,a1,a7,a1,a7,a1,a8,a1,a9,a1,a7,a1,a6,a1,a6)') &
488 character,
intent(inout) :: buffer(:)
490 integer,
intent(inout) :: position
495 integer :: prev_position
497 prev_position = position
539 character,
intent(inout) :: buffer(:)
541 integer,
intent(inout) :: position
546 integer :: prev_position
548 prev_position = position
587 subroutine spec_file_read_parallel_coag_type(file, parallel_coag_type)
592 integer,
intent(out) :: parallel_coag_type
594 character(len=SPEC_LINE_MAX_VAR_LEN) :: parallel_coag_type_name
609 parallel_coag_type_name)
610 if (trim(parallel_coag_type_name) ==
'local')
then
612 elseif (trim(parallel_coag_type_name) ==
'dist')
then
616 "Unknown parallel coagulation type: " &
617 // trim(parallel_coag_type_name))
620 end subroutine spec_file_read_parallel_coag_type