109 subroutine output_state(prefix, output_type, aero_data, aero_state, &
110 gas_data, gas_state, env_state, index, time, del_t, i_repeat, &
111 record_removals, record_optical, uuid)
114 character(len=*),
intent(in) :: prefix
116 integer,
intent(in) :: output_type
128 integer,
intent(in) :: index
130 real(kind=dp),
intent(in) :: time
132 real(kind=dp),
intent(in) :: del_t
134 integer,
intent(in) :: i_repeat
136 logical,
intent(in) :: record_removals
138 logical,
intent(in) :: record_optical
140 character(len=PMC_UUID_LEN),
intent(in) :: uuid
142 integer :: rank, n_proc
147 integer :: ierr, status(mpi_status_size), i_proc, position
148 character,
allocatable :: buffer(:)
157 call output_state_to_file(prefix, aero_data, aero_state, gas_data, &
158 gas_state, env_state, index, time, del_t, i_repeat, &
159 record_removals, record_optical, uuid, rank, n_proc)
161 do i_proc = 1,(n_proc - 1)
163 index, time, del_t, i_repeat, record_removals, &
164 record_optical, uuid, i_proc)
172 call output_state_to_file(prefix, aero_data, aero_state, gas_data, &
173 gas_state, env_state, index, time, del_t, i_repeat, &
174 record_removals, record_optical, uuid, rank, n_proc)
176 if (n_proc == 1)
then 177 call output_state_to_file(prefix, aero_data, aero_state, gas_data, &
178 gas_state, env_state, index, time, del_t, i_repeat, &
179 record_removals, record_optical, uuid, rank, n_proc)
184 env_state_write = env_state
185 gas_state_write = gas_state
190 call output_state_to_file(prefix, aero_data, aero_state_write, &
191 gas_data, gas_state_write, env_state_write, index, time, &
192 del_t, i_repeat, record_removals, record_optical, uuid, &
198 call die_msg(626743323,
"Unknown output_type: " &
207 subroutine make_filename(filename, prefix, suffix, index, i_repeat, &
208 write_rank, write_n_proc)
211 character(len=*),
intent(out) :: filename
213 character(len=*),
intent(in) :: prefix
215 character(len=*),
intent(in) :: suffix
217 integer,
intent(in),
optional :: index
219 integer,
intent(in),
optional :: i_repeat
221 integer,
intent(in),
optional :: write_rank
223 integer,
intent(in),
optional :: write_n_proc
225 integer :: ncid, use_rank, use_n_proc
226 character(len=100) :: proc_string, index_string, repeat_string
228 if (
present(write_rank))
then 229 use_rank = write_rank
233 if (
present(write_n_proc))
then 234 use_n_proc = write_n_proc
242 if (
present(i_repeat))
write(repeat_string,
'(a,i4.4)')
'_', i_repeat
243 if (use_n_proc > 1)
write(proc_string,
'(a,i4.4)')
'_', (use_rank + 1)
244 if (
present(index))
write(index_string,
'(a,i8.8)')
'_', index
245 write(filename,
'(a,a,a,a,a)') trim(prefix), trim(repeat_string), &
246 trim(proc_string), trim(index_string), trim(suffix)
253 subroutine write_time(ncid, time, del_t, index)
256 integer,
intent(in) :: ncid
258 real(kind=dp),
intent(in) :: time
260 real(kind=dp),
intent(in) :: del_t
262 integer,
intent(in) :: index
265 description=
"time elapsed since simulation start")
267 description=
"current timestep size")
269 description=
"an integer that is 1 on the first timestep, " &
270 //
"2 on the second timestep, etc.")
278 subroutine output_state_to_file(prefix, aero_data, aero_state, gas_data, &
279 gas_state, env_state, index, time, del_t, i_repeat, record_removals, &
280 record_optical, uuid, write_rank, write_n_proc)
283 character(len=*),
intent(in) :: prefix
295 integer,
intent(in) :: index
297 real(kind=dp),
intent(in) :: time
299 real(kind=dp),
intent(in) :: del_t
301 integer,
intent(in) :: i_repeat
303 logical,
intent(in) :: record_removals
305 logical,
intent(in) :: record_optical
307 character(len=PMC_UUID_LEN),
intent(in) :: uuid
309 integer,
intent(in),
optional :: write_rank
311 integer,
intent(in),
optional :: write_n_proc
313 character(len=len(prefix)+100) :: filename
363 call make_filename(filename, prefix,
".nc", index, i_repeat, write_rank, &
367 "PartMC version " // trim(
partmc_version), write_rank, write_n_proc)
370 description=
"repeat number of this simulation (starting from 1)")
372 call env_state_output_netcdf(env_state, ncid)
373 call gas_data_output_netcdf(gas_data, ncid)
374 call gas_state_output_netcdf(gas_state, ncid, gas_data)
375 call aero_data_output_netcdf(aero_data, ncid)
376 call aero_state_output_netcdf(aero_state, ncid, aero_data, &
377 record_removals, record_optical)
381 end subroutine output_state_to_file
396 integer :: buffer_size, max_buffer_size, position, ierr
397 character,
allocatable :: buffer(:)
402 max_buffer_size = max_buffer_size &
404 max_buffer_size = max_buffer_size &
406 max_buffer_size = max_buffer_size &
408 allocate(buffer(max_buffer_size))
413 call assert(839343839, position <= max_buffer_size)
414 buffer_size = position
415 call mpi_send(buffer, buffer_size, mpi_character, 0, &
428 time, del_t, i_repeat, record_removals, record_optical, uuid, &
432 character(len=*),
intent(in) :: prefix
438 integer,
intent(in) :: index
440 real(kind=dp),
intent(in) :: time
442 real(kind=dp),
intent(in) :: del_t
444 integer,
intent(in) :: i_repeat
446 logical,
intent(in) :: record_removals
448 logical,
intent(in) :: record_optical
450 character(len=PMC_UUID_LEN),
intent(in) :: uuid
452 integer,
intent(in) :: remote_proc
458 integer :: buffer_size, position, status(mpi_status_size)
459 integer :: n_proc, ierr
460 character,
allocatable :: buffer(:)
463 call assert(291452117, remote_proc /= 0)
470 call mpi_get_count(status, mpi_character, buffer_size, ierr)
473 allocate(buffer(buffer_size))
474 call mpi_recv(buffer, buffer_size, mpi_character, remote_proc, &
483 call assert(279581330, position == buffer_size)
486 call output_state_to_file(prefix, aero_data, aero_state, gas_data, &
487 gas_state, env_state, index, time, del_t, i_repeat, &
488 record_removals, record_optical, uuid, remote_proc, n_proc)
496 subroutine input_state(filename, index, time, del_t, i_repeat, uuid, &
497 aero_data, aero_state, gas_data, gas_state, env_state)
500 character(len=*),
intent(in) :: filename
502 integer,
intent(out) :: index
504 real(kind=dp),
intent(out) :: time
506 real(kind=dp),
intent(out) :: del_t
508 integer,
intent(out) :: i_repeat
510 character(len=PMC_UUID_LEN),
intent(out) :: uuid
512 type(
aero_data_t),
optional,
intent(inout) :: aero_data
514 type(
aero_state_t),
optional,
intent(inout) :: aero_state
516 type(
gas_data_t),
optional,
intent(inout) :: gas_data
518 type(
gas_state_t),
optional,
intent(inout) :: gas_state
520 type(
env_state_t),
optional,
intent(inout) :: env_state
525 "can only call from process 0")
529 call pmc_nc_check(nf90_get_att(ncid, nf90_global,
"UUID", uuid))
536 if (
present(aero_data))
then 538 if (
present(aero_state))
then 542 call assert_msg(289621231,
present(aero_state) .eqv. .false., &
543 "cannot input aero_state without aero_data")
546 if (
present(gas_data))
then 548 if (
present(gas_state))
then 552 call assert_msg(874298496,
present(gas_state) .eqv. .false., &
553 "cannot input gas_state without gas_data")
556 if (
present(env_state))
then 570 character(len=*),
intent(in) :: prefix
572 character(len=*),
intent(inout),
allocatable :: filename_list(:)
574 integer :: n_file, index, unit, ios
575 character(len=len(prefix)+100) :: filename
579 "can only call from process 0")
584 do while (.not. done)
585 write(filename,
'(a,a,i8.8,a)') trim(prefix),
'_', index,
'.nc' 586 open(unit=unit, file=filename, status=
'old', iostat=ios)
599 write(filename,
'(a,a,i8.8,a)') trim(prefix),
'_', index,
'.nc' 600 filename_list(index) = filename
611 character(len=*),
intent(in) :: prefix
613 integer,
intent(out) :: n_repeat
615 integer,
intent(out) :: n_index
617 integer :: repeat, index, unit, ios
618 character(len=len(prefix)+100) :: filename
622 "can only call from process 0")
629 do while (.not. done)
631 open(unit=unit, file=filename, status=
'old', iostat=ios)
639 n_repeat = repeat - 1
641 "no files found with prefix: " // trim(prefix))
646 do while (.not. done)
648 open(unit=unit, file=filename, status=
'old', iostat=ios)
664 gas_data, gas_state, env_state, index, time, del_t, uuid)
667 character(len=*),
intent(in) :: prefix
681 integer,
intent(in) :: index
683 real(kind=dp),
intent(in) :: time
685 real(kind=dp),
intent(in) :: del_t
687 character(len=PMC_UUID_LEN),
intent(in) :: uuid
690 character(len=len(prefix)+100) :: filename
692 write(filename,
'(a,a,i8.8,a)') trim(prefix), &
700 call env_state_output_netcdf(env_state, ncid)
701 call gas_data_output_netcdf(gas_data, ncid)
702 call gas_state_output_netcdf(gas_state, ncid, gas_data)
703 call aero_data_output_netcdf(aero_data, ncid)
704 call aero_binned_output_netcdf(aero_binned, ncid, bin_grid, &
714 subroutine input_sectional(filename, index, time, del_t, uuid, bin_grid, &
715 aero_data, aero_binned, gas_data, gas_state, env_state)
718 character(len=*),
intent(in) :: filename
720 integer,
intent(out) :: index
722 real(kind=dp),
intent(out) :: time
724 real(kind=dp),
intent(out) :: del_t
726 character(len=PMC_UUID_LEN),
intent(out) :: uuid
728 type(
bin_grid_t),
optional,
intent(inout) :: bin_grid
730 type(
aero_data_t),
optional,
intent(inout) :: aero_data
734 type(
gas_data_t),
optional,
intent(inout) :: gas_data
736 type(
gas_state_t),
optional,
intent(inout) :: gas_state
738 type(
env_state_t),
optional,
intent(inout) :: env_state
743 "can only call from process 0")
747 call pmc_nc_check(nf90_get_att(ncid, nf90_global,
"UUID", uuid))
753 if (
present(bin_grid))
then 756 if (
present(aero_data))
then 759 if (
present(aero_binned))
then 761 present(bin_grid) .and.
present(aero_data), &
762 "cannot input aero_binned without bin_grid and aero_data")
767 if (
present(gas_data))
then 769 if (
present(gas_state))
then 773 call assert_msg(214545112,
present(gas_state) .eqv. .false., &
774 "cannot input gas_state without gas_data")
777 if (
present(env_state))
then 789 subroutine spec_file_read_output_type(file, output_type)
794 integer,
intent(out) :: output_type
796 character(len=SPEC_LINE_MAX_VAR_LEN) :: output_type_name
811 if (trim(output_type_name) ==
'central')
then 813 elseif (trim(output_type_name) ==
'dist')
then 815 elseif (trim(output_type_name) ==
'single')
then 819 "Unknown output type: " // trim(output_type_name))
822 end subroutine spec_file_read_output_type
subroutine aero_state_input_netcdf(aero_state, ncid, aero_data)
Read full state.
subroutine assert_msg(code, condition_ok, error_msg)
Errors unless condition_ok is true.
An input file with extra data for printing messages.
subroutine pmc_nc_write_info(ncid, uuid, source, write_rank, write_n_proc)
Write basic information to a NetCDF file.
subroutine output_state(prefix, output_type, aero_data, aero_state, gas_data, gas_state, env_state, index, time, del_t, i_repeat, record_removals, record_optical, uuid)
Write the current state.
Wrapper functions for NetCDF. These all take a NetCDF ncid in data mode and return with it again in d...
integer, parameter output_type_single
Type code for single output (one file for all processes, written by process 0).
subroutine input_n_files(prefix, n_repeat, n_index)
Find the number of repeats and indices for the given prefix.
integer function pmc_mpi_rank()
Returns the rank of the current process.
subroutine gas_state_input_netcdf(gas_state, ncid, gas_data)
Read full state.
The bin_grid_t structure and associated subroutines.
subroutine pmc_nc_open_read(filename, ncid)
Open a NetCDF file for reading.
subroutine env_state_reduce_avg(val)
Average val over all processes, with the result only on the root process.
The env_state_t structure and associated subroutines.
integer function pmc_mpi_pack_size_env_state(val)
Determines the number of bytes required to pack the given value.
subroutine pmc_nc_close(ncid)
Close a NetCDF file.
The gas_data_t structure and associated subroutines.
subroutine aero_state_mpi_gather(aero_state, aero_state_total, aero_data)
Gathers data from all processes into one aero_state on process 0.
subroutine assert(code, condition_ok)
Errors unless condition_ok is true.
subroutine pmc_nc_open_write(filename, ncid)
Open a NetCDF file for writing.
integer function pmc_mpi_pack_size_aero_state(val)
Determines the number of bytes required to pack the given value.
The aero_state_t structure and assocated subroutines.
subroutine output_sectional(prefix, bin_grid, aero_data, aero_binned, gas_data, gas_state, env_state, index, time, del_t, uuid)
Write the current sectional data.
subroutine pmc_nc_read_integer(ncid, var, name, must_be_present)
Read a single integer from a NetCDF file.
subroutine pmc_nc_check(status)
Check the status of a NetCDF function call.
subroutine send_output_state_central(aero_state, gas_state, env_state)
Send the state for the "central" output method to the root process.
Current environment state.
subroutine gas_data_input_netcdf(gas_data, ncid)
Read full state.
subroutine input_filename_list(prefix, filename_list)
Find all NetCDF (.nc) filenames that match the given prefix.
subroutine die_msg(code, error_msg)
Error immediately.
Write data in NetCDF format.
subroutine input_sectional(filename, index, time, del_t, uuid, bin_grid, aero_data, aero_binned, gas_data, gas_state, env_state)
Input sectional data.
subroutine aero_binned_input_netcdf(aero_binned, ncid, bin_grid, aero_data)
Read full state.
integer function get_unit()
Returns an available unit number. This should be freed by free_unit().
subroutine pmc_mpi_pack_aero_state(buffer, position, val)
Packs the given value into the buffer, advancing position.
subroutine pmc_nc_write_integer(ncid, var, name, unit, long_name, standard_name, description)
Write a single integer to a NetCDF file.
integer, parameter tag_output_state_central
Internal-use variable only.
subroutine make_filename(filename, prefix, suffix, index, i_repeat, write_rank, write_n_proc)
Make a filename from a given prefix and other information.
subroutine ensure_string_array_size(x, n)
Allocate or reallocate the given array to ensure it is of the given size, without preserving data...
subroutine aero_data_input_netcdf(aero_data, ncid)
Read full state.
The current collection of aerosol particles.
subroutine spec_file_die_msg(code, file, msg)
Exit with an error message containing filename and line number.
subroutine pmc_mpi_unpack_aero_state(buffer, position, val)
Unpacks the given value from the buffer, advancing position.
The aero_data_t structure and associated subroutines.
subroutine pmc_nc_read_real(ncid, var, name, must_be_present)
Read a single real from a NetCDF file.
integer, parameter tag_output_state_single
Internal-use variable only.
1D grid, either logarithmic or linear.
The gas_state_t structure and associated subroutines.
integer, parameter output_type_invalid
Type code for undefined or invalid output.
subroutine pmc_mpi_check_ierr(ierr)
Dies if ierr is not ok.
subroutine recv_output_state_central(prefix, aero_data, gas_data, index, time, del_t, i_repeat, record_removals, record_optical, uuid, remote_proc)
Receive the state for the "central" output method on the root process.
integer, parameter output_type_dist
Type code for distributed output (one file per process, written by each process). ...
subroutine pmc_nc_write_real(ncid, var, name, unit, long_name, standard_name, description)
Write a single real to a NetCDF file.
subroutine env_state_input_netcdf(env_state, ncid)
Read full state.
Current state of the gas mixing ratios in the system.
subroutine input_state(filename, index, time, del_t, i_repeat, uuid, aero_data, aero_state, gas_data, gas_state, env_state)
Read the current state.
subroutine gas_state_reduce_avg(val)
Average val over all processes, with the result only on the root process.
subroutine pmc_mpi_unpack_env_state(buffer, position, val)
Unpacks the given value from the buffer, advancing position.
subroutine write_time(ncid, time, del_t, index)
Helper routine to write time variables. Do not call directly.
integer, parameter output_type_central
Type code for centralized output (one file per process, all written by process 0).
character(len=100), parameter partmc_version
PartMC verson number.
subroutine pmc_mpi_unpack_gas_state(buffer, position, val)
Unpacks the given value from the buffer, advancing position.
subroutine pmc_mpi_pack_env_state(buffer, position, val)
Packs the given value into the buffer, advancing position.
subroutine spec_file_read_string(file, name, var)
Read a string from a spec file that must have a given name.
character(len=pmc_util_convert_string_len) function integer_to_string(val)
Convert an integer to a string format.
integer function pmc_mpi_size()
Returns the total number of processes.
Aerosol material properties and associated data.
subroutine pmc_mpi_pack_gas_state(buffer, position, val)
Packs the given value into the buffer, advancing position.
subroutine bin_grid_input_netcdf(bin_grid, ncid, dim_name, scale)
Read full state.
Common utility subroutines.
The aero_binned_t structure and associated subroutines.
Wrapper functions for MPI.
integer function pmc_mpi_pack_size_gas_state(val)
Determines the number of bytes required to pack the given value.
subroutine free_unit(unit)
Frees a unit number returned by get_unit().
Aerosol number and volume distributions stored per bin.