PartMC  2.9.0
run_modal.F90
Go to the documentation of this file.
1 !> \file
2 !> The pmc_run_modal module.
3 
4 !> 1D modal simulation.
5 
7 
8  use pmc_util
9  use pmc_aero_dist
10  use pmc_scenario
11  use pmc_env_state
12  use pmc_aero_data
13  use pmc_output
14  use pmc_bin_grid
15  use pmc_aero_binned
16  use pmc_gas_data
17  use pmc_gas_state
18  use pmc_constants
19 
20  !> Options controlling the operation of run_modal()
22  !> Final time (s).
23  real(kind=dp) :: t_max
24  !> Timestep (s).
25  real(kind=dp) :: del_t
26  !> Output interval (0 disables) (s).
27  real(kind=dp) :: t_output
28  !> Progress interval (0 disables) (s).
29  real(kind=dp) :: t_progress
30  !> Output prefix.
31  character(len=300) :: prefix
32  !> Whether to run CAMP.
33  logical :: do_camp_chem
34  !> Whether to run TChem.
35  logical :: do_tchem
36  !> Whether to do coagulation.
37  logical :: do_coagulation
38  !> Whether to do condensation.
39  logical :: do_condensation
40  !> Whether to run MOSAIC.
41  logical :: do_mosaic
42  !> Whether to compute optical properties.
43  logical :: do_optical
44  !> Whether to do nucleation.
45  logical :: do_nucleation
46  !> Whether to do immersion freezing.
47  logical :: do_immersion_freezing
48  !> UUID of the simulation.
49  character(len=PMC_UUID_LEN) :: uuid
50  end type run_modal_opt_t
51 
52 contains
53 
54  !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
55 
56  !> Run a modal simulation.
57  subroutine run_modal(aero_data, aero_dist, scenario, env_state, &
58  gas_data, bin_grid, run_modal_opt)
59 
60  !> Aerosol data.
61  type(aero_data_t), intent(in) :: aero_data
62  !> Aerosol distribution.
63  type(aero_dist_t), intent(inout) :: aero_dist
64  !> Environment data.
65  type(scenario_t), intent(in) :: scenario
66  !> Environment state.
67  type(env_state_t), intent(inout) :: env_state
68  !> Gas data.
69  type(gas_data_t), intent(in) :: gas_data
70  !> Bin grid.
71  type(bin_grid_t), intent(in) :: bin_grid
72  !> Modal options.
73  type(run_modal_opt_t), intent(in) :: run_modal_opt
74 
75  type(env_state_t) :: old_env_state
76  type(gas_state_t) :: gas_state
77  type(aero_binned_t) :: aero_binned
78 
79  real(kind=dp) time, last_output_time, last_progress_time
80 
81  integer i_time, n_time, i_summary
82  logical do_output, do_progress
83 
84  call check_time_multiple("t_max", run_modal_opt%t_max, &
85  "del_t", run_modal_opt%del_t)
86  call check_time_multiple("t_output", run_modal_opt%t_output, &
87  "del_t", run_modal_opt%del_t)
88  call check_time_multiple("t_progress", run_modal_opt%t_progress, &
89  "del_t", run_modal_opt%del_t)
90 
91  if (aero_data_n_spec(aero_data) /= 1) then
92  call die_msg(927384615, 'run_modal() can only use one aerosol species')
93  end if
94 
95  ! output data structure
96  call gas_state_set_size(gas_state, gas_data_n_spec(gas_data))
97 
98  ! Initialize time.
99  time = 0d0
100  last_output_time = 0d0
101  last_progress_time = 0d0
102  i_summary = 1
103 
104  ! initial output
105  call check_event(time, run_modal_opt%del_t, run_modal_opt%t_output, &
106  last_output_time, do_output)
107  if (do_output) then
108  call aero_binned_add_aero_dist(aero_binned, bin_grid, aero_data, &
109  aero_dist)
110  call output_modal(run_modal_opt%prefix, aero_binned, aero_dist, &
111  aero_data, env_state, gas_data, gas_state, bin_grid, scenario, &
112  i_summary, time, run_modal_opt%del_t, run_modal_opt%uuid)
113  call aero_binned_zero(aero_binned)
114  end if
115 
116  ! Main time-stepping loop
117  n_time = nint(run_modal_opt%t_max / run_modal_opt%del_t)
118  do i_time = 1,n_time
119  time = run_modal_opt%t_max * real(i_time, kind=dp) &
120  / real(n_time, kind=dp)
121 
122  old_env_state = env_state
123 
124  call scenario_update_env_state(scenario, env_state, time)
125  call scenario_update_gas_state(scenario, run_modal_opt%del_t, &
126  env_state, old_env_state, gas_data, gas_state)
127  call scenario_update_aero_modes(aero_dist, run_modal_opt%del_t, &
128  env_state, aero_data%density(1), scenario)
129 
130  call check_event(time, run_modal_opt%del_t, run_modal_opt%t_output, &
131  last_output_time, do_output)
132  if (do_output) then
133  i_summary = i_summary + 1
134  call aero_binned_add_aero_dist(aero_binned, bin_grid, aero_data, &
135  aero_dist)
136  call output_modal(run_modal_opt%prefix, aero_binned, aero_dist, &
137  aero_data, env_state, gas_data, gas_state, bin_grid, &
138  scenario, i_summary, time, run_modal_opt%del_t, &
139  run_modal_opt%uuid)
140  call aero_binned_zero(aero_binned)
141  end if
142 
143  call check_event(time, run_modal_opt%del_t, run_modal_opt%t_progress, &
144  last_progress_time, do_progress)
145  if (do_progress) then
146  write(*, '(a6,a8)') 'step', 'time'
147  write(*, '(i6,f8.1)') i_time, time
148  end if
149  end do
150 
151  end subroutine run_modal
152 
153  !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
154 
155  !> Read the specification for a run_modal simulation from a spec file.
156  subroutine spec_file_read_run_modal(file, run_modal_opt, aero_data, &
157  bin_grid, gas_data, env_state, aero_dist_init, scenario)
158 
159  !> Spec file.
160  type(spec_file_t), intent(inout) :: file
161  !> Options controlling the operation of run_modal().
162  type(run_modal_opt_t), intent(inout) :: run_modal_opt
163  !> Aerosol data.
164  type(aero_data_t), intent(out) :: aero_data
165  !> Bin grid.
166  type(bin_grid_t), intent(out) :: bin_grid
167  !> Gas data.
168  type(gas_data_t), intent(out) :: gas_data
169  !> Environment state.
170  type(env_state_t), intent(out) :: env_state
171  !> Initial aerosol distribution.
172  type(aero_dist_t), intent(out) :: aero_dist_init
173  !> Scenario.
174  type(scenario_t), intent(out) :: scenario
175 
176  character(len=PMC_MAX_FILENAME_LEN) :: sub_filename
177  type(spec_file_t) :: sub_file
178 
179  call spec_file_read_string(file, 'output_prefix', run_modal_opt%prefix)
180 
181  call spec_file_read_real(file, 't_max', run_modal_opt%t_max)
182  call spec_file_read_real(file, 'del_t', run_modal_opt%del_t)
183  call spec_file_read_real(file, 't_output', run_modal_opt%t_output)
184  call spec_file_read_real(file, 't_progress', run_modal_opt%t_progress)
185 
186  call spec_file_read_radius_bin_grid(file, bin_grid)
187 
188  call spec_file_read_logical(file, 'do_camp_chem', &
189  run_modal_opt%do_camp_chem)
190  if (run_modal_opt%do_camp_chem) then
191  call spec_file_die_msg(263948175, file, &
192  "modal run does not support CAMP chemistry")
193  end if
194 
195  call spec_file_read_logical(file, 'do_tchem', run_modal_opt%do_tchem)
196  if (run_modal_opt%do_tchem) then
197  call spec_file_die_msg(195837264, file, &
198  "modal run does not support TChem chemistry")
199  end if
200 
201  call spec_file_read_string(file, 'gas_data', sub_filename)
202  call spec_file_open(sub_filename, sub_file)
203  call spec_file_read_gas_data(sub_file, gas_data)
204  call spec_file_close(sub_file)
205 
206  call spec_file_read_string(file, 'aerosol_data', sub_filename)
207  call spec_file_open(sub_filename, sub_file)
208  call spec_file_read_aero_data(sub_file, aero_data)
209  call spec_file_close(sub_file)
210 
211  call spec_file_read_fractal(file, aero_data%fractal)
212 
213  call spec_file_read_string(file, 'aerosol_init', sub_filename)
214  call spec_file_open(sub_filename, sub_file)
215  call spec_file_read_aero_dist(sub_file, aero_data, .false., aero_dist_init)
216  call spec_file_close(sub_file)
217 
218  call spec_file_read_scenario(file, gas_data, aero_data, .false., scenario)
219  call spec_file_read_env_state(file, env_state)
220 
221  call spec_file_read_logical(file, 'do_coagulation', &
222  run_modal_opt%do_coagulation)
223  if (run_modal_opt%do_coagulation) then
224  call spec_file_die_msg(473829156, file, &
225  "modal run does not support coagulation")
226  end if
227 
228  call spec_file_read_logical(file, 'do_condensation', &
229  run_modal_opt%do_condensation)
230  if (run_modal_opt%do_condensation) then
231  call spec_file_die_msg(612938475, file, &
232  "modal run does not support condensation")
233  end if
234 
235  call spec_file_read_logical(file, 'do_mosaic', run_modal_opt%do_mosaic)
236  if (run_modal_opt%do_mosaic) then
237  call spec_file_die_msg(584729163, file, &
238  "modal run does not support MOSAIC chemistry")
239  end if
240 
241  call spec_file_read_logical(file, 'do_optical', run_modal_opt%do_optical)
242  if (run_modal_opt%do_optical) then
243  call spec_file_die_msg(527436819, file, &
244  "modal run does not support optical properties calculation")
245  end if
246 
247  call spec_file_read_logical(file, 'do_nucleation', &
248  run_modal_opt%do_nucleation)
249  if (run_modal_opt%do_nucleation) then
250  call spec_file_die_msg(391847265, file, &
251  "modal run does not support nucleation")
252  end if
253 
254  call spec_file_read_logical(file, 'do_immersion_freezing', &
255  run_modal_opt%do_immersion_freezing)
256  if (run_modal_opt%do_immersion_freezing) then
257  call spec_file_die_msg(748291635, file, &
258  "modal run does not support immersion freezing")
259  end if
260 
261  call spec_file_close(file)
262 
263  ! Modal runs do not support aerosol emissions, background dilution,
264  ! or loss functions other than drydep/none.
265  if (size(scenario%aero_emission_rate_scale) > 0) then
266  call assert_msg(583920417, &
267  all(scenario%aero_emission_rate_scale == 0.0d0), &
268  "modal run does not support aerosol emissions: " &
269  // "all aero_emission rates must be zero")
270  end if
271  if (size(scenario%aero_dilution_rate) > 0) then
272  call assert_msg(742916380, all(scenario%aero_dilution_rate == 0.0d0), &
273  "modal run does not support aerosol background dilution: " &
274  // "all aero_dilution rates must be zero")
275  end if
276  call assert_msg(631804952, &
277  scenario%loss_function_type == scenario_loss_function_none &
278  .or. scenario%loss_function_type == scenario_loss_function_drydep, &
279  "modal run only supports loss_function none or drydep")
280 
281  ! All data from spec file read. Do the modal run.
282 
283  call pmc_srand(0,0)
284 
285  call uuid4_str(run_modal_opt%uuid)
286 
287  call scenario_init_env_state(scenario, env_state, 0d0)
288 
289  end subroutine spec_file_read_run_modal
290 
291  !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
292 
293 end module pmc_run_modal
pmc_run_modal::run_modal
subroutine run_modal(aero_data, aero_dist, scenario, env_state, gas_data, bin_grid, run_modal_opt)
Run a modal simulation.
Definition: run_modal.F90:59
pmc_aero_data::aero_data_n_spec
elemental integer function aero_data_n_spec(aero_data)
Return the number of aerosol species, or -1 if uninitialized.
Definition: aero_data.F90:250
pmc_gas_data::gas_data_t
Constant gas data.
Definition: gas_data.F90:35
pmc_run_modal::run_modal_opt_t
Options controlling the operation of run_modal()
Definition: run_modal.F90:21
pmc_spec_file::spec_file_close
subroutine spec_file_close(file)
Close a spec file.
Definition: spec_file.F90:135
pmc_run_modal
1D modal simulation.
Definition: run_modal.F90:6
pmc_gas_state::gas_state_set_size
subroutine gas_state_set_size(gas_state, n_spec)
Sets the sizes of the gas state.
Definition: gas_state.F90:56
pmc_scenario
The scenario_t structure and associated subroutines.
Definition: scenario.F90:9
pmc_scenario::scenario_t
Scenario data.
Definition: scenario.F90:86
pmc_gas_data
The gas_data_t structure and associated subroutines.
Definition: gas_data.F90:9
pmc_util::die_msg
subroutine die_msg(code, error_msg)
Error immediately.
Definition: util.F90:135
pmc_scenario::scenario_loss_function_none
integer, parameter scenario_loss_function_none
Type code for a zero loss function.
Definition: scenario.F90:31
pmc_constants::dp
integer, parameter dp
Kind of a double precision real number.
Definition: constants.F90:12
pmc_spec_file::spec_file_read_logical
subroutine spec_file_read_logical(file, name, var)
Read a logical from a spec file that must have a given name.
Definition: spec_file.F90:603
pmc_env_state::env_state_t
Current environment state.
Definition: env_state.F90:29
pmc_scenario::scenario_update_gas_state
subroutine scenario_update_gas_state(scenario, delta_t, env_state, old_env_state, gas_data, gas_state)
Do gas emissions and background dilution.
Definition: scenario.F90:243
pmc_run_modal::spec_file_read_run_modal
subroutine spec_file_read_run_modal(file, run_modal_opt, aero_data, bin_grid, gas_data, env_state, aero_dist_init, scenario)
Read the specification for a run_modal simulation from a spec file.
Definition: run_modal.F90:158
pmc_scenario::scenario_update_env_state
subroutine scenario_update_env_state(scenario, env_state, time)
Update time-dependent contents of the environment. scenario_init_env_state() should have been called ...
Definition: scenario.F90:168
pmc_spec_file::spec_file_t
An input file with extra data for printing messages.
Definition: spec_file.F90:59
pmc_rand::pmc_srand
subroutine pmc_srand(seed, offset)
Initializes the random number generator to the state defined by the given seed plus offset....
Definition: rand.F90:67
pmc_gas_state
The gas_state_t structure and associated subroutines.
Definition: gas_state.F90:9
pmc_aero_binned::aero_binned_add_aero_dist
subroutine aero_binned_add_aero_dist(aero_binned, bin_grid, aero_data, aero_dist)
Add an aero_dist_t to an aero_binned_t.
Definition: aero_binned.F90:229
pmc_spec_file::spec_file_read_real
subroutine spec_file_read_real(file, name, var)
Read a real number from a spec file that must have the given name.
Definition: spec_file.F90:582
pmc_util::check_time_multiple
subroutine check_time_multiple(first_name, first_time, second_name, second_time)
Check that the first time interval is close to an integer multiple of the second, and warn if it is n...
Definition: util.F90:377
pmc_util::assert_msg
subroutine assert_msg(code, condition_ok, error_msg)
Errors unless condition_ok is true.
Definition: util.F90:78
pmc_aero_dist
The aero_dist_t structure and associated subroutines.
Definition: aero_dist.F90:18
pmc_scenario::scenario_update_aero_modes
subroutine scenario_update_aero_modes(aero_dist, del_t, env_state, density, scenario)
Update the modal aerosol distribution to account for particle loss.
Definition: scenario.F90:434
pmc_spec_file::spec_file_open
subroutine spec_file_open(filename, file)
Open a spec file for reading.
Definition: spec_file.F90:112
pmc_env_state
The env_state_t structure and associated subroutines.
Definition: env_state.F90:9
pmc_gas_state::gas_state_t
Current state of the gas mixing ratios in the system.
Definition: gas_state.F90:33
pmc_rand::uuid4_str
subroutine uuid4_str(uuid)
Generate a version 4 UUID as a string.
Definition: rand.F90:661
pmc_aero_data::aero_data_t
Aerosol material properties and associated data.
Definition: aero_data.F90:55
pmc_output
Write data in NetCDF format.
Definition: output.F90:68
pmc_constants
Physical constants.
Definition: constants.F90:9
pmc_aero_dist::aero_dist_t
A complete aerosol distribution, consisting of several modes.
Definition: aero_dist.F90:33
pmc_scenario::scenario_loss_function_drydep
integer, parameter scenario_loss_function_drydep
Type code for a loss rate function based on dry deposition.
Definition: scenario.F90:37
pmc_util
Common utility subroutines.
Definition: util.F90:9
pmc_util::check_event
subroutine check_event(time, timestep, interval, last_time, do_event)
Computes whether an event is scheduled to take place.
Definition: util.F90:408
pmc_gas_data::gas_data_n_spec
elemental integer function gas_data_n_spec(gas_data)
Return the number of gas species.
Definition: gas_data.F90:109
pmc_scenario::scenario_init_env_state
subroutine scenario_init_env_state(scenario, env_state, time)
Initialize the time-dependent contents of the environment. Thereafter scenario_update_env_state() sho...
Definition: scenario.F90:145
pmc_spec_file::spec_file_die_msg
subroutine spec_file_die_msg(code, file, msg)
Exit with an error message containing filename and line number.
Definition: spec_file.F90:74
pmc_aero_binned::aero_binned_zero
subroutine aero_binned_zero(aero_binned)
Set all internal data in an aero_binned_t structure to zero.
Definition: aero_binned.F90:93
pmc_aero_binned
The aero_binned_t structure and associated subroutines.
Definition: aero_binned.F90:9
pmc_spec_file::spec_file_read_string
subroutine spec_file_read_string(file, name, var)
Read a string from a spec file that must have a given name.
Definition: spec_file.F90:624
pmc_aero_binned::aero_binned_t
Aerosol number and volume distributions stored per bin.
Definition: aero_binned.F90:37
pmc_bin_grid
The bin_grid_t structure and associated subroutines.
Definition: bin_grid.F90:9
pmc_aero_data
The aero_data_t structure and associated subroutines.
Definition: aero_data.F90:9
pmc_bin_grid::bin_grid_t
1D grid, either logarithmic or linear.
Definition: bin_grid.F90:33
pmc_output::output_modal
subroutine output_modal(prefix, aero_binned, aero_dist, aero_data, env_state, gas_data, gas_state, bin_grid, scenario, index, time, del_t, uuid)
Write the current modal data.
Definition: output.F90:792