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