CAMP 1.0.0
Chemistry Across Multiple Phases
aero_rep_data.F90
Go to the documentation of this file.
1! Copyright (C) 2021 Barcelona Supercomputing Center and University of
2! Illinois at Urbana-Champaign
3! SPDX-License-Identifier: MIT
4
5!> \file
6!> The camp_aero_rep_data module.
7
8!> \page camp_aero_rep CAMP: Aerosol Representation (general)
9!!
10!! An aerosol representation acts as an interface between an aerosol
11!! micro-physics model and \ref index "CAMP".
12!! Types that extend the abstract \c aero_rep_data_t type should be developed
13!! for each type of aerosol representation used by an external model (e.g.,
14!! binned, modal, single particle).
15!!
16!! The available aerosol representations are:
17!! - \subpage camp_aero_rep_single_particle "Single Particle"
18!! - \subpage camp_aero_rep_modal_binned_mass "Mass-only Binned/Modal"
19!!
20!! The general input format for an aerosol representation can be found
21!! \subpage input_format_aero_rep "here".
22
23!> The abstract aero_rep_data_t structure and associated subroutines.
25
26#ifdef CAMP_USE_JSON
27 use json_module
28#endif
29#ifdef CAMP_USE_MPI
30 use mpi
31#endif
34 use camp_constants, only : i_kind, dp
35 use camp_mpi
38 use camp_util, only : die_msg, string_t
39
40 use iso_c_binding
41
42 implicit none
43 private
44
47
48 !> Abstract aerosol representation data type
49 !!
50 !! Time-invariant data related to an aerosol representation. Derived types
51 !! extending aero_rep_data_t should describe specific types of aerosol
52 !! schemes (e.g., binned, modal, particle-resolved).
53 !!
54 !! See \ref camp_aero_rep "Aerosol Representations" for details.
55 type, abstract :: aero_rep_data_t
56 private
57 !> Name of the aerosol representation
58 character(len=:), allocatable, public :: rep_name
59 !> Aerosol phases associated with this aerosol scheme
60 !!
61 !! See \ref camp_aero_phase "Aerosol Phases" for details.
62 type(aero_phase_data_ptr), allocatable, public :: aero_phase(:)
63 !> Aerosol representation parameters. These will be available during
64 !! initialization, but not during solving. All information required
65 !! by functions of the aerosol representation must be saved by the
66 !! exdending type in the condensed data arrays.
67 type(property_t), pointer, public :: property_set => null()
68 !> Condensed representation data. Theses arrays will be available during
69 !! solving, and should contain any information required by the
70 !! functions of the aerosol representation that cannot be obtained
71 !! from the camp_camp_state::camp_state_t object. (floating-point)
72 real(kind=dp), allocatable, public :: condensed_data_real(:)
73 !> Condensed representation data. Theses arrays will be available during
74 !! solving, and should contain any information required by the
75 !! functions of the aerosol representation that cannot be obtained
76 !! from the camp_camp_state::camp_state_t object. (integer)
77 integer(kind=i_kind), allocatable, public :: condensed_data_int(:)
78 !> Array of booleans indicating if phase exists at the surface of a
79 !! particle. Used in SIMPOL and HL reactions for single particle
80 !! representation.
81 logical, allocatable, public :: aero_phase_is_at_surface(:)
82 !> Number of environment-dependent parameters
83 !! These are parameters that need updated when environmental conditions
84 !! change
85 integer(kind=i_kind), public :: num_env_params = 0
86 contains
87 !> Initialize the aerosol representation data, validating component data and
88 !! loading any required information from the \c
89 !! aero_rep_data_t::property_set. This routine should be called once for
90 !! each aerosol representation at the beginning of a model run after all
91 !! the input files have been read in. It ensures all data required during
92 !! the model run are included in the condensed data arrays.
93 procedure(initialize), deferred :: initialize
94 !> Get the size of the section of the
95 !! \c camp_camp_state::camp_state_t::state_var array required for this
96 !! aerosol representation
97 procedure(get_size), deferred :: size
98 !> Get a list of unique names for each element on the
99 !! \c camp_camp_state::camp_state_t::state_var array for this aerosol
100 !! representation. The list may be restricted to a particular phase and/or
101 !! aerosol species by including the phase_name and spec_name arguments.
102 procedure(unique_names), deferred :: unique_names
103 !> Get a species id on the \c camp_camp_state::camp_state_t::state_var
104 !! array by its unique name. These are unique ids for each element on the
105 !! state array for this \ref camp_aero_rep "aerosol representation" and
106 !! are numbered:
107 !!
108 !! \f[x_u \in x_f ... (x_f+n-1)\f]
109 !!
110 !! where \f$x_u\f$ is the id of the element corresponding to the species
111 !! with unique name \f$u\f$ on the \c
112 !! camp_camp_state::camp_state_t::state_var array, \f$x_f\f$ is the index
113 !! of the first element for this aerosol representation on the state array
114 !! and \f$n\f$ is the total number of variables on the state array from
115 !! this aerosol representation.
116 procedure(spec_state_id), deferred :: spec_state_id
117 !> Get the non-unique name of a species by its unique name
118 procedure(spec_name), deferred :: spec_name
119 !> Get the number of instances of an aerosol phase
121 !> Get the number of Jacobian elements for calculations of mass, volume,
122 !! number, etc for a particular phase
123 procedure(num_jac_elem), deferred :: num_jac_elem
124 !> Load data from an input file
125 procedure :: load
126 !> Get the name of the aerosol representation
127 procedure :: name => get_name
128 !> Get ids for all instances of a phase in this aerosol representation for
129 !! use during solving
130 procedure :: phase_ids
131 !> Determine the number of bytes required to pack the given value
132 procedure :: pack_size
133 !> Packs the given value into the buffer, advancing position
134 procedure :: bin_pack
135 !> Unpacks the given value from the buffer, advancing position
136 procedure :: bin_unpack
137 !> Print the aerosol representation data
138 procedure :: print => do_print
139 end type aero_rep_data_t
140
141 !> Pointer to aero_rep_data_t extending types
143 !> Pointer to an aerosol representation
144 class(aero_rep_data_t), pointer :: val => null()
145 contains
146 !> Dereference the pointer
147 procedure :: dereference
148 !> Finalize the pointer
150 end type aero_rep_data_ptr
151
152 !> Update cookie
153 type, abstract :: aero_rep_update_data_t
154 !> Aerosol representation type
155 integer(kind=c_int) :: aero_rep_type
156 !> Aerosol representation solver id
157 integer(kind=c_int) :: aero_rep_solver_id = 0
158 !> Grid cell to update
159 integer(kind=c_int) :: cell_id = 1
160 !> Update data
161 type(c_ptr) :: update_data
162 contains
163 !> Get the aerosol representation type
165 !> Get the grid cell to update
166 procedure :: get_cell_id => aero_rep_update_data_get_cell_id
167 !> Get the update data
168 procedure :: get_data => aero_rep_update_data_get_data
169 !> Determine the number of bytes required to pack the given value
171 !> Packs the given value into the buffer, advancing position
173 !> Unpacks the given value from the buffer, advancing position
175 !> Extending type pack size (internal use only)
177 !> Extending type bin pack (internal use only)
178 procedure(internal_bin_pack), deferred :: internal_bin_pack
179 !> Extending type bin unpack (internal use only)
181 !> Print the update data
182 procedure :: print => do_aero_rep_update_data_print
184
185 !> Define index_pair array for adjacent_phases functions
187 integer :: first_ = -9999
188 integer :: second_ = -9999
189 end type index_pair_t
190
191interface
192!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
193
194 !> Initialize the aerosol representation data, validating component data and
195 !! loading any required information from the \c
196 !! aero_rep_data_t::property_set. This routine should be called once for
197 !! each aerosol representation at the beginning of a model run after all
198 !! the input files have been read in. It ensures all data required during
199 !! the model run are included in the condensed data arrays.
200 subroutine initialize(this, aero_phase_set, spec_state_id)
201 use camp_util, only : i_kind
204 import :: aero_rep_data_t
205
206 !> Aerosol representation data
207 class(aero_rep_data_t), intent(inout) :: this
208 !> The set of aerosol phases. Note that an aerosol representation may
209 !! implement any number of instances of each phase.
210 type(aero_phase_data_ptr), pointer, intent(in) :: aero_phase_set(:)
211 !> Beginning state id for this aerosol representation in the
212 !! \c camp_camp_state::camp_state_t::state_var array
213 integer(kind=i_kind), intent(in) :: spec_state_id
214
215 end subroutine initialize
216
217!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
218
219 !> Extending-type binary pack size (internal use only)
220 integer(kind=i_kind) function internal_pack_size(this, comm)
221 use camp_util, only : i_kind
222 import :: aero_rep_update_data_t
223
224 !> Aerosol representation data
225 class(aero_rep_update_data_t), intent(in) :: this
226 !> MPI communicator
227 integer, intent(in) :: comm
228
229 end function internal_pack_size
230
231!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
232
233 !> Extending-type binary pack function (Internal use only)
234 subroutine internal_bin_pack(this, buffer, pos, comm)
235 import :: aero_rep_update_data_t
236
237 !> Aerosol representation data
238 class(aero_rep_update_data_t), intent(in) :: this
239 !> Memory buffer
240 character, intent(inout) :: buffer(:)
241 !> Current buffer position
242 integer, intent(inout) :: pos
243 !> MPI communicator
244 integer, intent(in) :: comm
245
246 end subroutine internal_bin_pack
247
248!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
249
250 !> Extending-type binary unpack function (Internal use only)
251 subroutine internal_bin_unpack(this, buffer, pos, comm)
252 import :: aero_rep_update_data_t
253
254 !> Aerosol representation data
255 class(aero_rep_update_data_t), intent(inout) :: this
256 !> Memory buffer
257 character, intent(inout) :: buffer(:)
258 !> Current buffer position
259 integer, intent(inout) :: pos
260 !> MPI communicator
261 integer, intent(in) :: comm
262
263 end subroutine internal_bin_unpack
264
265!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
266
267 !> Get the size of the section of the
268 !! \c camp_camp_state::camp_state_t::state_var array required for this
269 !! aerosol representation
270 function get_size(this) result (state_size)
271 use camp_util, only : i_kind
272 import :: aero_rep_data_t
273
274 !> Size of the state array section
275 integer(kind=i_kind) :: state_size
276 !> Aerosol representation data
277 class(aero_rep_data_t), intent(in) :: this
278
279 end function get_size
280
281!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
282
283 !> Get a list of unique names for each element on the
284 !! \c camp_camp_state::camp_state_t::state_var array for this aerosol
285 !! representation.
286 function unique_names(this, phase_name, tracer_type, spec_name, &
287 phase_is_at_surface)
288 use camp_util, only : string_t, i_kind
289 import :: aero_rep_data_t
290
291 !> List of unique names
292 type(string_t), allocatable :: unique_names(:)
293 !> Aerosol representation data
294 class(aero_rep_data_t), intent(in) :: this
295 !> Aerosol phase name
296 character(len=*), optional, intent(in) :: phase_name
297 !> Tracer type
298 integer(kind=i_kind), optional, intent(in) :: tracer_type
299 !> Aerosol-phase species name
300 character(len=*), optional, intent(in) :: spec_name
301 !> Indicates if aerosol phase is at the surface of particle
302 logical, optional, intent(in) :: phase_is_at_surface
303
304 end function unique_names
305
306!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
307
308 !> Get a species id on the \c camp_camp_state::camp_state_t::state_var
309 !! array by unique name. These are unique ids for each element on the
310 !! state array for this \ref camp_aero_rep "aerosol representation" and
311 !! are numbered:
312 !!
313 !! \f[x_u \in x_f ... (x_f+n-1)\f]
314 !!
315 !! where \f$x_u\f$ is the id of the element corresponding to the species
316 !! with unique name \f$u\f$ on the \c
317 !! camp_camp_state::camp_state_t::state_var array, \f$x_f\f$ is the index
318 !! of the first element for this aerosol representation on the state array
319 !! and \f$n\f$ is the total number of variables on the state array from
320 !! this aerosol representation.
321 !!
322 !! If the name is not found, the return value is 0.
323 function spec_state_id(this, unique_name) result (spec_id)
324 use camp_util, only : i_kind
325 import :: aero_rep_data_t
326
327 !> Species state id
328 integer(kind=i_kind) :: spec_id
329 !> Aerosol representation data
330 class(aero_rep_data_t), intent(in) :: this
331 !> Unique name
332 character(len=*), intent(in) :: unique_name
333
334 end function spec_state_id
335
336!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
337
338 !> Get the non-unique name of a chemical species by its unique name
339 function spec_name(this, unique_name)
340 use camp_util, only : i_kind
341 import :: aero_rep_data_t
342
343 !> Chemical species name
344 character(len=:), allocatable :: spec_name
345 !> Aerosol representation data
346 class(aero_rep_data_t), intent(in) :: this
347 !> Unique name of the species in this aerosol representation
348 character(len=*), intent(in) :: unique_name
349
350 end function spec_name
351
352!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
353
354 !> Get the number of instances of a specified aerosol phase
355 function num_phase_instances(this, phase_name, is_at_surface)
356 use camp_util, only : i_kind
357 import :: aero_rep_data_t
358
359 !> Number of instances of the aerosol phase
360 integer(kind=i_kind) :: num_phase_instances
361 !> Aerosol representation data
362 class(aero_rep_data_t), intent(in) :: this
363 !> Aerosol phase name
364 character(len=*), intent(in) :: phase_name
365 !> Indicates if aerosol phase is at the surface of particle
366 logical, intent(in), optional :: is_at_surface
367
368 end function num_phase_instances
369
370!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
371
372 !> Get the number of Jacobian elements used in calculations of aerosol mass,
373 !! volume, number, etc. for a particular phase
374 function num_jac_elem(this, phase_id)
375 use camp_util, only : i_kind
376 import :: aero_rep_data_t
377
378 !> Number of Jacobian elements used
379 integer(kind=i_kind) :: num_jac_elem
380 !> Aerosol respresentation data
381 class(aero_rep_data_t), intent(in) :: this
382 !> Aerosol phase id
383 integer(kind=i_kind), intent(in) :: phase_id
384
385 end function num_jac_elem
386
387!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
388
389end interface
390
391contains
392
393!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
394
395 !> \page input_format_aero_rep Input JSON Object Format: Aerosol Representation (general)
396 !!
397 !! A \c json object containing information about an \ref camp_aero_rep
398 !! "aerosol representation" has the following format:
399 !! \code{.json}
400 !! { "camp-data" : [
401 !! {
402 !! "name" : "my aero rep",
403 !! "type" : "AERO_REP_TYPE",
404 !! "some parameter" : 123.34,
405 !! "some other parameter" : true,
406 !! "nested parameters" : {
407 !! "sub param 1" : 12.43,
408 !! "sub param other" : "some text",
409 !! ...
410 !! },
411 !! ...
412 !! },
413 !! ...
414 !! ]}
415 !! \endcode
416 !! Aerosol representations must have a unique \b name that will be used to
417 !! identify the aerosol representation during initialization. The key-value
418 !! pair \b type is also required and must correspond to a valid aerosol
419 !! representation type. These include:
420 !!
421 !! - \subpage camp_aero_rep_single_particle "AERO_REP_SINGLE_PARTICLE"
422 !! - \subpage camp_aero_rep_modal_binned_mass
423 !! "AERO_REP_MODAL_BINNED_MASS"
424 !!
425 !! All remaining data are optional and may include any valid \c json value.
426 !! However, extending types will have specific requirements for the
427 !! remaining data.
428
429!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
430
431 !> Load an aerosol representation from an input file
432#ifdef CAMP_USE_JSON
433 subroutine load(this, json, j_obj)
434
435 !> Aerosol representation data
436 class(aero_rep_data_t), intent(inout) :: this
437 !> JSON core
438 type(json_core), pointer, intent(in) :: json
439 !> JSON object
440 type(json_value), pointer, intent(in) :: j_obj
441
442 type(json_value), pointer :: child, next
443 character(kind=json_ck, len=:), allocatable :: key, unicode_str_val
444 integer(kind=json_ik) :: var_type
445 logical :: found_name
446
447 ! allocate space for the aerosol representation property set
448 this%property_set => property_t()
449
450 if (.not.allocated(this%rep_name)) &
451 this%rep_name = "unknown aerosol representation"
452 found_name = .false.
453
454 ! cycle through the aerosol representation properties to find the name and
455 ! load the remaining data into the aerosol representation property set
456 next => null()
457 call json%get_child(j_obj, child)
458 do while (associated(child))
459 call json%info(child, name=key, var_type=var_type)
460
461 ! aerosol representation name
462 if (key.eq."name") then
463 call assert_msg(196193896, var_type.eq.json_string, &
464 "Received non-string value for aerosol rep name")
465 call json%get(child, unicode_str_val)
466 this%rep_name = unicode_str_val
467 found_name = .true.
468
469 ! load remaining data tinto the property set
470 else if (key.ne."type") then
471 call this%property_set%load(json, child, .false., this%rep_name)
472 end if
473
474 call json%get_next(child, next)
475 child => next
476 end do
477 call assert_msg(420903951, found_name, &
478 "Received unnamed aerosol representation.")
479#else
480 subroutine load(this)
481
482 !> Aerosol representation data
483 class(aero_rep_data_t), intent(inout) :: this
484
485 call warn_msg(433045149, "No support for input files")
486#endif
487
488 end subroutine load
489
490!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
491
492 !> Get the name of the aerosol representation
493 function get_name(this)
494
495 !> Aerosol representation name
496 character(len=:), allocatable :: get_name
497 !> Aerosol representation data
498 class(aero_rep_data_t), intent(in) :: this
499
500 get_name = this%rep_name
501
502 end function get_name
503
504!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
505
506 !> Get a set of ids for all instances of a phase in this aerosol
507 !! representation for use during solving
508 function phase_ids(this, phase_name, is_at_surface)
509
510 !> List of phase ids
511 integer(kind=i_kind), allocatable :: phase_ids(:)
512 !> Aerosol representation data
513 class(aero_rep_data_t), intent(in) :: this
514 !> Aerosol phase name
515 character(len=*), intent(in) :: phase_name
516 !> Indicates if aerosol phase is at the surface of particle
517 logical, intent(in), optional :: is_at_surface
518
519 integer(kind=i_kind) :: num_instances, i_instance, i_phase
520
521 num_instances = this%num_phase_instances(phase_name, is_at_surface)
522 allocate(phase_ids(num_instances))
523 if (present(is_at_surface)) then
524 if (is_at_surface) then
525 i_instance = 1
526 do i_phase = 1, size(this%aero_phase)
527 if (this%aero_phase(i_phase)%val%name().eq. phase_name .and. &
528 this%aero_phase_is_at_surface(i_phase)) then
529 phase_ids(i_instance) = i_phase
530 i_instance = i_instance + 1
531 end if
532 end do
533 else
534 i_instance = 1
535 do i_phase = 1, size(this%aero_phase)
536 if (this%aero_phase(i_phase)%val%name().eq. phase_name .and. &
537 .not. this%aero_phase_is_at_surface(i_phase)) then
538 phase_ids(i_instance) = i_phase
539 i_instance = i_instance + 1
540 end if
541 end do
542 end if
543 else
544 i_instance = 1
545 do i_phase = 1, size(this%aero_phase)
546 if (this%aero_phase(i_phase)%val%name().eq.phase_name) then
547 phase_ids(i_instance) = i_phase
548 i_instance = i_instance + 1
549 end if
550 end do
551 end if
552 call assert(642387392, num_instances == i_instance-1)
553
554 end function phase_ids
555
556!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
557
558 !> Determine the size of a binary required to pack the aerosol
559 !! representation data
560 integer(kind=i_kind) function pack_size(this, comm)
561
562 !> Aerosol representation data
563 class(aero_rep_data_t), intent(in) :: this
564 !> MPI communicator
565 integer, intent(in) :: comm
566
567 pack_size = &
568 camp_mpi_pack_size_real_array(this%condensed_data_real, comm) + &
569 camp_mpi_pack_size_integer_array(this%condensed_data_int, comm) + &
570 camp_mpi_pack_size_integer(this%num_env_params, comm)
571
572 end function pack_size
573
574!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
575
576 !> Pack the given value to the buffer, advancing position
577 subroutine bin_pack(this, buffer, pos, comm)
578
579 !> Aerosol representation data
580 class(aero_rep_data_t), intent(in) :: this
581 !> Memory buffer
582 character, intent(inout) :: buffer(:)
583 !> Current buffer position
584 integer, intent(inout) :: pos
585 !> MPI communicator
586 integer, intent(in) :: comm
587
588#ifdef CAMP_USE_MPI
589 integer :: prev_position
590
591 prev_position = pos
592 call camp_mpi_pack_real_array(buffer, pos, this%condensed_data_real, comm)
593 call camp_mpi_pack_integer_array(buffer, pos, this%condensed_data_int,comm)
594 call camp_mpi_pack_integer(buffer, pos, this%num_env_params,comm)
595 call assert(257024095, &
596 pos - prev_position <= this%pack_size(comm))
597#endif
598
599 end subroutine bin_pack
600
601!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
602
603 !> Unpack the given value from the buffer, advancing position
604 subroutine bin_unpack(this, buffer, pos, comm)
605
606 !> Aerosol representation data
607 class(aero_rep_data_t), intent(out) :: this
608 !> Memory buffer
609 character, intent(inout) :: buffer(:)
610 !> Current buffer position
611 integer, intent(inout) :: pos
612 !> MPI communicator
613 integer, intent(in) :: comm
614
615#ifdef CAMP_USE_MPI
616 integer :: prev_position
617
618 prev_position = pos
619 call camp_mpi_unpack_real_array(buffer, pos, this%condensed_data_real,comm)
620 call camp_mpi_unpack_integer_array(buffer, pos, this%condensed_data_int, &
621 comm)
622 call camp_mpi_unpack_integer(buffer, pos, this%num_env_params,comm)
623 call assert(954732699, &
624 pos - prev_position <= this%pack_size(comm))
625#endif
626
627 end subroutine bin_unpack
628
629!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
630
631 !> Print the aerosol representation data
632 subroutine do_print(this, file_unit)
633
634 !> Aerosol representation data
635 class(aero_rep_data_t), intent(in) :: this
636 !> File unit for output
637 integer(kind=i_kind), optional :: file_unit
638
639 integer(kind=i_kind) :: f_unit
640
641 file_unit = 6
642
643 if (present(file_unit)) f_unit = file_unit
644 write(f_unit,*) "*** Aerosol Representation: ",trim(this%rep_name)," ***"
645 if (associated(this%property_set)) call this%property_set%print(f_unit)
646 if (allocated(this%condensed_data_int)) &
647 write(f_unit,*) " *** condensed data int: ",this%condensed_data_int(:)
648 if (allocated(this%condensed_data_real)) &
649 write(f_unit,*) " *** condensed data real: ",this%condensed_data_real(:)
650
651 end subroutine do_print
652
653!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
654
655 !> Deference a pointer to an aerosol representation
656 elemental subroutine dereference(this)
657
658 !> Pointer to an aerosol representation
659 class(aero_rep_data_ptr), intent(inout) :: this
660
661 this%val => null()
662
663 end subroutine dereference
664
665!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
666
667 !> Finalize a pointer to an aerosol representation
668 subroutine ptr_finalize(this)
669
670 !> Pointer to an aerosol representation
671 type(aero_rep_data_ptr), intent(inout) :: this
672
673 if (associated(this%val)) deallocate(this%val)
674
675 end subroutine ptr_finalize
676
677!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
678
679 !> Finalize an array of pointers to aerosol representations
680 subroutine ptr_finalize_array(this)
681
682 !> Array of pointers to aerosol representations
683 type(aero_rep_data_ptr), intent(inout) :: this(:)
684
685 integer(kind=i_kind) :: i
686
687 do i = 1, size(this)
688 call ptr_finalize(this(i))
689 end do
690
691 end subroutine ptr_finalize_array
692
693!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
694
695 !> Get the update data aerosol representation type
696 function aero_rep_update_data_get_type(this) result (aero_rep_type)
697
698 !> Aerosol representation type
699 integer(kind=c_int) :: aero_rep_type
700 !> Update data
701 class(aero_rep_update_data_t), intent(in) :: this
702
703 aero_rep_type = this%aero_rep_type
704
706
707!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
708
709 !> Get the grid cell id to update
710 function aero_rep_update_data_get_cell_id(this) result(cell_id)
711
712 !> Grid cell id
713 integer(kind=c_int) :: cell_id
714 !> Update data
715 class(aero_rep_update_data_t), intent(in) :: this
716
717 cell_id = this%cell_id
718
720
721!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
722
723 !> Get the update data
724 function aero_rep_update_data_get_data(this) result (update_data)
725
726 !> Update data ptr
727 type(c_ptr) :: update_data
728 !> Update data
729 class(aero_rep_update_data_t), intent(in) :: this
730
731 update_data = this%update_data
732
734
735!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
736
737!> Determine the size of a binary required to pack the reaction data
738 integer(kind=i_kind) function aero_rep_update_data_pack_size(this, comm) &
739 result(pack_size)
740
741 !> Aerosol representation update data
742 class(aero_rep_update_data_t), intent(in) :: this
743 !> MPI communicator
744 integer, intent(in), optional :: comm
745
746#ifdef CAMP_USE_MPI
747 integer :: l_comm
748
749 if (present(comm)) then
750 l_comm = comm
751 else
752 l_comm = mpi_comm_world
753 endif
754
755 pack_size = &
756 camp_mpi_pack_size_integer(int(this%aero_rep_type, kind=i_kind), &
757 l_comm) + &
758 camp_mpi_pack_size_integer(int(this%aero_rep_solver_id, kind=i_kind), &
759 l_comm) + &
760 this%internal_pack_size(l_comm)
761#else
762 pack_size = 0
763#endif
764
766
767!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
768
769 !> Pack the given value to the buffer, advancing position
770 subroutine aero_rep_update_data_bin_pack(this, buffer, pos, comm)
771
772 !> Aerosol representation update data
773 class(aero_rep_update_data_t), intent(in) :: this
774 !> Memory buffer
775 character, intent(inout) :: buffer(:)
776 !> Current buffer position
777 integer, intent(inout) :: pos
778 !> MPI communicator
779 integer, intent(in), optional :: comm
780
781#ifdef CAMP_USE_MPI
782 integer :: prev_position, l_comm
783
784 if (present(comm)) then
785 l_comm = comm
786 else
787 l_comm = mpi_comm_world
788 endif
789
790 prev_position = pos
791 call camp_mpi_pack_integer(buffer, pos, &
792 int(this%aero_rep_type, kind=i_kind), l_comm)
793 call camp_mpi_pack_integer(buffer, pos, &
794 int(this%aero_rep_solver_id, kind=i_kind), &
795 l_comm)
796 call this%internal_bin_pack(buffer, pos, l_comm)
797 call assert(538137635, &
798 pos - prev_position <= this%pack_size(l_comm))
799#endif
800
801 end subroutine aero_rep_update_data_bin_pack
802
803!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
804
805 !> Unpack the given value from the buffer, advancing position
806 subroutine aero_rep_update_data_bin_unpack(this, buffer, pos, comm)
807
808 !> Aerosol representation update data
809 class(aero_rep_update_data_t), intent(out) :: this
810 !> Memory buffer
811 character, intent(inout) :: buffer(:)
812 !> Current buffer position
813 integer, intent(inout) :: pos
814 !> MPI communicator
815 integer, intent(in), optional :: comm
816
817#ifdef CAMP_USE_MPI
818 integer :: prev_position, l_comm
819 integer(kind=i_kind) :: temp_int
820
821 if (present(comm)) then
822 l_comm = comm
823 else
824 l_comm = mpi_comm_world
825 endif
826
827 prev_position = pos
828 call camp_mpi_unpack_integer(buffer, pos, temp_int, l_comm)
829 this%aero_rep_type = int(temp_int, kind=c_int)
830 call camp_mpi_unpack_integer(buffer, pos, temp_int, l_comm)
831 this%aero_rep_solver_id = int(temp_int, kind=c_int)
832 call this%internal_bin_unpack(buffer, pos, l_comm)
833 call assert(257567920, &
834 pos - prev_position <= this%pack_size(l_comm))
835#endif
836
838
839!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
840
841 !> Print the update data
842 subroutine do_aero_rep_update_data_print(this, file_unit)
843
844 !> Aerosol representation update data
845 class(aero_rep_update_data_t), intent(in) :: this
846 !> File unit for output
847 integer(kind=i_kind), optional :: file_unit
848
849 integer(kind=i_kind) :: f_unit
850
851 f_unit = 6
852
853 if (present(file_unit)) f_unit = file_unit
854
855 write(f_unit,*) "*** Aerosol representation update data ***"
856 write(f_unit,*) "Aerosol representation type", this%aero_rep_type
857 write(f_unit,*) "Aerosol representation solver id", this%aero_rep_solver_id
858
859 end subroutine do_aero_rep_update_data_print
860
861!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
862
863end module camp_aero_rep_data
Get the size of the section of the camp_camp_state::camp_state_t::state_var array required for this a...
Initialize the aerosol representation data, validating component data and loading any required inform...
Extending-type binary pack function (Internal use only)
Extending-type binary unpack function (Internal use only)
Extending-type binary pack size (internal use only)
Get the number of Jacobian elements used in calculations of aerosol mass, volume, number,...
Get the number of instances of a specified aerosol phase.
Get the non-unique name of a chemical species by its unique name.
Get a species id on the camp_camp_state::camp_state_t::state_var array by unique name....
Get a list of unique names for each element on the camp_camp_state::camp_state_t::state_var array for...
The abstract aero_phase_data_t structure and associated subroutines.
subroutine bin_unpack(this, buffer, pos, comm)
Unpack the given value from the buffer, advancing position.
character(len=:) function, allocatable get_name(this)
Get the aerosol phase name.
subroutine ptr_finalize_array(this)
Finalize an array of pointers to aerosol phase data.
subroutine bin_pack(this, buffer, pos, comm)
Pack the given value to the buffer, advancing position.
subroutine load(this, json, j_obj)
Load species from an input file.
integer(kind=i_kind) function pack_size(this, comm)
Determine the size of a binary required to pack the aerosol representation data.
subroutine ptr_finalize(this)
Finalize a pointer to aerosol phase data.
subroutine do_print(this, file_unit)
Print out the aerosol phase data.
elemental subroutine dereference(this)
Dereference a pointer to aerosol phase data.
The abstract aero_rep_data_t structure and associated subroutines.
subroutine do_aero_rep_update_data_print(this, file_unit)
Print the update data.
integer(kind=i_kind) function, dimension(:), allocatable phase_ids(this, phase_name, is_at_surface)
Get a set of ids for all instances of a phase in this aerosol representation for use during solving.
type(c_ptr) function aero_rep_update_data_get_data(this)
Get the update data.
integer(kind=i_kind) function aero_rep_update_data_pack_size(this, comm)
Determine the size of a binary required to pack the reaction data.
subroutine do_print(this, file_unit)
Print the aerosol representation data.
subroutine aero_rep_update_data_bin_pack(this, buffer, pos, comm)
Pack the given value to the buffer, advancing position.
subroutine ptr_finalize(this)
Finalize a pointer to an aerosol representation.
integer(kind=i_kind) function pack_size(this, comm)
Determine the size of a binary required to pack the aerosol representation data.
subroutine load(this, json, j_obj)
Load an aerosol representation from an input file.
subroutine aero_rep_update_data_bin_unpack(this, buffer, pos, comm)
Unpack the given value from the buffer, advancing position.
subroutine bin_unpack(this, buffer, pos, comm)
Unpack the given value from the buffer, advancing position.
elemental subroutine dereference(this)
Deference a pointer to an aerosol representation.
integer(kind=c_int) function aero_rep_update_data_get_type(this)
Get the update data aerosol representation type.
subroutine bin_pack(this, buffer, pos, comm)
Pack the given value to the buffer, advancing position.
character(len=:) function, allocatable get_name(this)
Get the name of the aerosol representation.
subroutine ptr_finalize_array(this)
Finalize an array of pointers to aerosol representations.
integer(kind=c_int) function aero_rep_update_data_get_cell_id(this)
Get the grid cell id to update.
The camp_state_t structure and associated subroutines.
Definition camp_state.F90:9
The chem_spec_data_t structure and associated subroutines.
logical function get_type(this, spec_name, spec_type)
Get a species type by species name. Returns true if the species is found or false otherwise.
Physical constants.
Definition constants.F90:9
integer, parameter dp
Kind of a double precision real number.
Definition constants.F90:16
integer, parameter i_kind
Kind of an integer.
Definition constants.F90:21
Wrapper functions for MPI.
Definition mpi.F90:13
subroutine camp_mpi_pack_integer_array(buffer, position, val, comm)
Packs the given value into the buffer, advancing position.
Definition mpi.F90:858
subroutine camp_mpi_pack_real_array(buffer, position, val, comm)
Packs the given value into the buffer, advancing position.
Definition mpi.F90:899
subroutine camp_mpi_unpack_integer_array(buffer, position, val, comm)
Unpacks the given value from the buffer, advancing position.
Definition mpi.F90:1201
subroutine camp_mpi_unpack_integer(buffer, position, val, comm)
Unpacks the given value from the buffer, advancing position.
Definition mpi.F90:1023
integer function camp_mpi_pack_size_real_array(val, comm)
Determines the number of bytes required to pack the given value.
Definition mpi.F90:578
integer function camp_mpi_pack_size_integer_array(val, comm)
Determines the number of bytes required to pack the given value.
Definition mpi.F90:540
subroutine camp_mpi_pack_integer(buffer, position, val, comm)
Packs the given value into the buffer, advancing position.
Definition mpi.F90:691
integer function camp_mpi_pack_size_integer(val, comm)
Determines the number of bytes required to pack the given value.
Definition mpi.F90:398
subroutine camp_mpi_unpack_real_array(buffer, position, val, comm)
Unpacks the given value from the buffer, advancing position.
Definition mpi.F90:1242
The property_t structure and associated subroutines.
Definition property.F90:9
Common utility subroutines.
Definition util.F90:9
subroutine die_msg(code, error_msg)
Error immediately.
Definition util.F90:196
Pointer type for building arrays.
Pointer to aero_rep_data_t extending types.
Abstract aerosol representation data type.
Define index_pair array for adjacent_phases functions.
String type for building arrays of string of various size.
Definition util.F90:53