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 use camp_util, only : string_t, i_kind
281 import :: aero_rep_data_t
282
283 !> List of unique names
284 type(string_t), allocatable :: unique_names(:)
285 !> Aerosol representation data
286 class(aero_rep_data_t), intent(in) :: this
287 !> Aerosol phase name
288 character(len=*), optional, intent(in) :: phase_name
289 !> Tracer type
290 integer(kind=i_kind), optional, intent(in) :: tracer_type
291 !> Aerosol-phase species name
292 character(len=*), optional, intent(in) :: spec_name
293
294 end function unique_names
295
296!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
297
298 !> Get a species id on the \c camp_camp_state::camp_state_t::state_var
299 !! array by unique name. These are unique ids for each element on the
300 !! state array for this \ref camp_aero_rep "aerosol representation" and
301 !! are numbered:
302 !!
303 !! \f[x_u \in x_f ... (x_f+n-1)\f]
304 !!
305 !! where \f$x_u\f$ is the id of the element corresponding to the species
306 !! with unique name \f$u\f$ on the \c
307 !! camp_camp_state::camp_state_t::state_var array, \f$x_f\f$ is the index
308 !! of the first element for this aerosol representation on the state array
309 !! and \f$n\f$ is the total number of variables on the state array from
310 !! this aerosol representation.
311 !!
312 !! If the name is not found, the return value is 0.
313 function spec_state_id(this, unique_name) result (spec_id)
314 use camp_util, only : i_kind
315 import :: aero_rep_data_t
316
317 !> Species state id
318 integer(kind=i_kind) :: spec_id
319 !> Aerosol representation data
320 class(aero_rep_data_t), intent(in) :: this
321 !> Unique name
322 character(len=*), intent(in) :: unique_name
323
324 end function spec_state_id
325
326!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
327
328 !> Get the non-unique name of a chemical species by its unique name
329 function spec_name(this, unique_name)
330 use camp_util, only : i_kind
331 import :: aero_rep_data_t
332
333 !> Chemical species name
334 character(len=:), allocatable :: spec_name
335 !> Aerosol representation data
336 class(aero_rep_data_t), intent(in) :: this
337 !> Unique name of the species in this aerosol representation
338 character(len=*), intent(in) :: unique_name
339
340 end function spec_name
341
342!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
343
344 !> Get the number of instances of a specified aerosol phase
345 function num_phase_instances(this, phase_name)
346 use camp_util, only : i_kind
347 import :: aero_rep_data_t
348
349 !> Number of instances of the aerosol phase
350 integer(kind=i_kind) :: num_phase_instances
351 !> Aerosol representation data
352 class(aero_rep_data_t), intent(in) :: this
353 !> Aerosol phase name
354 character(len=*), intent(in) :: phase_name
355
356 end function num_phase_instances
357
358!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
359
360 !> Get the number of Jacobian elements used in calculations of aerosol mass,
361 !! volume, number, etc. for a particular phase
362 function num_jac_elem(this, phase_id)
363 use camp_util, only : i_kind
364 import :: aero_rep_data_t
365
366 !> Number of Jacobian elements used
367 integer(kind=i_kind) :: num_jac_elem
368 !> Aerosol respresentation data
369 class(aero_rep_data_t), intent(in) :: this
370 !> Aerosol phase id
371 integer(kind=i_kind), intent(in) :: phase_id
372
373 end function num_jac_elem
374
375!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
376
377end interface
378
379contains
380
381!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
382
383 !> \page input_format_aero_rep Input JSON Object Format: Aerosol Representation (general)
384 !!
385 !! A \c json object containing information about an \ref camp_aero_rep
386 !! "aerosol representation" has the following format:
387 !! \code{.json}
388 !! { "camp-data" : [
389 !! {
390 !! "name" : "my aero rep",
391 !! "type" : "AERO_REP_TYPE",
392 !! "some parameter" : 123.34,
393 !! "some other parameter" : true,
394 !! "nested parameters" : {
395 !! "sub param 1" : 12.43,
396 !! "sub param other" : "some text",
397 !! ...
398 !! },
399 !! ...
400 !! },
401 !! ...
402 !! ]}
403 !! \endcode
404 !! Aerosol representations must have a unique \b name that will be used to
405 !! identify the aerosol representation during initialization. The key-value
406 !! pair \b type is also required and must correspond to a valid aerosol
407 !! representation type. These include:
408 !!
409 !! - \subpage camp_aero_rep_single_particle "AERO_REP_SINGLE_PARTICLE"
410 !! - \subpage camp_aero_rep_modal_binned_mass
411 !! "AERO_REP_MODAL_BINNED_MASS"
412 !!
413 !! All remaining data are optional and may include any valid \c json value.
414 !! However, extending types will have specific requirements for the
415 !! remaining data.
416
417!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
418
419 !> Load an aerosol representation from an input file
420#ifdef CAMP_USE_JSON
421 subroutine load(this, json, j_obj)
422
423 !> Aerosol representation data
424 class(aero_rep_data_t), intent(inout) :: this
425 !> JSON core
426 type(json_core), pointer, intent(in) :: json
427 !> JSON object
428 type(json_value), pointer, intent(in) :: j_obj
429
430 type(json_value), pointer :: child, next
431 character(kind=json_ck, len=:), allocatable :: key, unicode_str_val
432 integer(kind=json_ik) :: var_type
433 logical :: found_name
434
435 ! allocate space for the aerosol representation property set
436 this%property_set => property_t()
437
438 if (.not.allocated(this%rep_name)) &
439 this%rep_name = "unknown aerosol representation"
440 found_name = .false.
441
442 ! cycle through the aerosol representation properties to find the name and
443 ! load the remaining data into the aerosol representation property set
444 next => null()
445 call json%get_child(j_obj, child)
446 do while (associated(child))
447 call json%info(child, name=key, var_type=var_type)
448
449 ! aerosol representation name
450 if (key.eq."name") then
451 call assert_msg(196193896, var_type.eq.json_string, &
452 "Received non-string value for aerosol rep name")
453 call json%get(child, unicode_str_val)
454 this%rep_name = unicode_str_val
455 found_name = .true.
456
457 ! load remaining data tinto the property set
458 else if (key.ne."type") then
459 call this%property_set%load(json, child, .false., this%rep_name)
460 end if
461
462 call json%get_next(child, next)
463 child => next
464 end do
465 call assert_msg(420903951, found_name, &
466 "Received unnamed aerosol representation.")
467#else
468 subroutine load(this)
469
470 !> Aerosol representation data
471 class(aero_rep_data_t), intent(inout) :: this
472
473 call warn_msg(433045149, "No support for input files")
474#endif
475
476 end subroutine load
477
478!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
479
480 !> Get the name of the aerosol representation
481 function get_name(this)
482
483 !> Aerosol representation name
484 character(len=:), allocatable :: get_name
485 !> Aerosol representation data
486 class(aero_rep_data_t), intent(in) :: this
487
488 get_name = this%rep_name
489
490 end function get_name
491
492!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
493
494 !> Get a set of ids for all instances of a phase in this aerosol
495 !! representation for use during solving
496 function phase_ids(this, phase_name, is_at_surface)
497
498 !> List of phase ids
499 integer(kind=i_kind), allocatable :: phase_ids(:)
500 !> Aerosol representation data
501 class(aero_rep_data_t), intent(in) :: this
502 !> Aerosol phase name
503 character(len=*), intent(in) :: phase_name
504 !> Indicates if aerosol phase is at the surface of particle
505 logical, intent(in), optional :: is_at_surface
506
507 integer(kind=i_kind) :: num_instances, i_instance, i_phase
508
509 num_instances = this%num_phase_instances(phase_name)
510 allocate(phase_ids(num_instances))
511 if (present(is_at_surface)) then
512 if (is_at_surface) then
513 i_instance = 1
514 do i_phase = 1, size(this%aero_phase)
515 if (this%aero_phase(i_phase)%val%name().eq. phase_name .and. &
516 this%aero_phase_is_at_surface(i_phase)) then
517 phase_ids(i_instance) = i_phase
518 i_instance = i_instance + 1
519 end if
520 end do
521 else
522 i_instance = 1
523 do i_phase = 1, size(this%aero_phase)
524 if (this%aero_phase(i_phase)%val%name().eq. phase_name .and. &
525 .not. this%aero_phase_is_at_surface(i_phase)) then
526 phase_ids(i_instance) = i_phase
527 i_instance = i_instance + 1
528 end if
529 end do
530 end if
531 else
532 i_instance = 1
533 do i_phase = 1, size(this%aero_phase)
534 if (this%aero_phase(i_phase)%val%name().eq.phase_name) then
535 phase_ids(i_instance) = i_phase
536 i_instance = i_instance + 1
537 end if
538 end do
539 end if
540
541 end function phase_ids
542
543!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
544
545 !> Determine the size of a binary required to pack the aerosol
546 !! representation data
547 integer(kind=i_kind) function pack_size(this, comm)
548
549 !> Aerosol representation data
550 class(aero_rep_data_t), intent(in) :: this
551 !> MPI communicator
552 integer, intent(in) :: comm
553
554 pack_size = &
555 camp_mpi_pack_size_real_array(this%condensed_data_real, comm) + &
556 camp_mpi_pack_size_integer_array(this%condensed_data_int, comm) + &
557 camp_mpi_pack_size_integer(this%num_env_params, comm)
558
559 end function pack_size
560
561!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
562
563 !> Pack the given value to the buffer, advancing position
564 subroutine bin_pack(this, buffer, pos, comm)
565
566 !> Aerosol representation data
567 class(aero_rep_data_t), intent(in) :: this
568 !> Memory buffer
569 character, intent(inout) :: buffer(:)
570 !> Current buffer position
571 integer, intent(inout) :: pos
572 !> MPI communicator
573 integer, intent(in) :: comm
574
575#ifdef CAMP_USE_MPI
576 integer :: prev_position
577
578 prev_position = pos
579 call camp_mpi_pack_real_array(buffer, pos, this%condensed_data_real, comm)
580 call camp_mpi_pack_integer_array(buffer, pos, this%condensed_data_int,comm)
581 call camp_mpi_pack_integer(buffer, pos, this%num_env_params,comm)
582 call assert(257024095, &
583 pos - prev_position <= this%pack_size(comm))
584#endif
585
586 end subroutine bin_pack
587
588!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
589
590 !> Unpack the given value from the buffer, advancing position
591 subroutine bin_unpack(this, buffer, pos, comm)
592
593 !> Aerosol representation data
594 class(aero_rep_data_t), intent(out) :: this
595 !> Memory buffer
596 character, intent(inout) :: buffer(:)
597 !> Current buffer position
598 integer, intent(inout) :: pos
599 !> MPI communicator
600 integer, intent(in) :: comm
601
602#ifdef CAMP_USE_MPI
603 integer :: prev_position
604
605 prev_position = pos
606 call camp_mpi_unpack_real_array(buffer, pos, this%condensed_data_real,comm)
607 call camp_mpi_unpack_integer_array(buffer, pos, this%condensed_data_int, &
608 comm)
609 call camp_mpi_unpack_integer(buffer, pos, this%num_env_params,comm)
610 call assert(954732699, &
611 pos - prev_position <= this%pack_size(comm))
612#endif
613
614 end subroutine bin_unpack
615
616!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
617
618 !> Print the aerosol representation data
619 subroutine do_print(this, file_unit)
620
621 !> Aerosol representation data
622 class(aero_rep_data_t), intent(in) :: this
623 !> File unit for output
624 integer(kind=i_kind), optional :: file_unit
625
626 integer(kind=i_kind) :: f_unit
627
628 file_unit = 6
629
630 if (present(file_unit)) f_unit = file_unit
631 write(f_unit,*) "*** Aerosol Representation: ",trim(this%rep_name)," ***"
632 if (associated(this%property_set)) call this%property_set%print(f_unit)
633 if (allocated(this%condensed_data_int)) &
634 write(f_unit,*) " *** condensed data int: ",this%condensed_data_int(:)
635 if (allocated(this%condensed_data_real)) &
636 write(f_unit,*) " *** condensed data real: ",this%condensed_data_real(:)
637
638 end subroutine do_print
639
640!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
641
642 !> Deference a pointer to an aerosol representation
643 elemental subroutine dereference(this)
644
645 !> Pointer to an aerosol representation
646 class(aero_rep_data_ptr), intent(inout) :: this
647
648 this%val => null()
649
650 end subroutine dereference
651
652!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
653
654 !> Finalize a pointer to an aerosol representation
655 elemental subroutine ptr_finalize(this)
656
657 !> Pointer to an aerosol representation
658 type(aero_rep_data_ptr), intent(inout) :: this
659
660 if (associated(this%val)) deallocate(this%val)
661
662 end subroutine ptr_finalize
663
664!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
665
666 !> Get the update data aerosol representation type
667 function aero_rep_update_data_get_type(this) result (aero_rep_type)
668
669 !> Aerosol representation type
670 integer(kind=c_int) :: aero_rep_type
671 !> Update data
672 class(aero_rep_update_data_t), intent(in) :: this
673
674 aero_rep_type = this%aero_rep_type
675
677
678!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
679
680 !> Get the grid cell id to update
681 function aero_rep_update_data_get_cell_id(this) result(cell_id)
682
683 !> Grid cell id
684 integer(kind=c_int) :: cell_id
685 !> Update data
686 class(aero_rep_update_data_t), intent(in) :: this
687
688 cell_id = this%cell_id
689
691
692!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
693
694 !> Get the update data
695 function aero_rep_update_data_get_data(this) result (update_data)
696
697 !> Update data ptr
698 type(c_ptr) :: update_data
699 !> Update data
700 class(aero_rep_update_data_t), intent(in) :: this
701
702 update_data = this%update_data
703
705
706!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
707
708!> Determine the size of a binary required to pack the reaction data
709 integer(kind=i_kind) function aero_rep_update_data_pack_size(this, comm) &
710 result(pack_size)
711
712 !> Aerosol representation update data
713 class(aero_rep_update_data_t), intent(in) :: this
714 !> MPI communicator
715 integer, intent(in), optional :: comm
716
717#ifdef CAMP_USE_MPI
718 integer :: l_comm
719
720 if (present(comm)) then
721 l_comm = comm
722 else
723 l_comm = mpi_comm_world
724 endif
725
726 pack_size = &
727 camp_mpi_pack_size_integer(int(this%aero_rep_type, kind=i_kind), &
728 l_comm) + &
729 camp_mpi_pack_size_integer(int(this%aero_rep_solver_id, kind=i_kind), &
730 l_comm) + &
731 this%internal_pack_size(l_comm)
732#else
733 pack_size = 0
734#endif
735
737
738!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
739
740 !> Pack the given value to the buffer, advancing position
741 subroutine aero_rep_update_data_bin_pack(this, buffer, pos, comm)
742
743 !> Aerosol representation update data
744 class(aero_rep_update_data_t), intent(in) :: this
745 !> Memory buffer
746 character, intent(inout) :: buffer(:)
747 !> Current buffer position
748 integer, intent(inout) :: pos
749 !> MPI communicator
750 integer, intent(in), optional :: comm
751
752#ifdef CAMP_USE_MPI
753 integer :: prev_position, l_comm
754
755 if (present(comm)) then
756 l_comm = comm
757 else
758 l_comm = mpi_comm_world
759 endif
760
761 prev_position = pos
762 call camp_mpi_pack_integer(buffer, pos, &
763 int(this%aero_rep_type, kind=i_kind), l_comm)
764 call camp_mpi_pack_integer(buffer, pos, &
765 int(this%aero_rep_solver_id, kind=i_kind), &
766 l_comm)
767 call this%internal_bin_pack(buffer, pos, l_comm)
768 call assert(538137635, &
769 pos - prev_position <= this%pack_size(l_comm))
770#endif
771
772 end subroutine aero_rep_update_data_bin_pack
773
774!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
775
776 !> Unpack the given value from the buffer, advancing position
777 subroutine aero_rep_update_data_bin_unpack(this, buffer, pos, comm)
778
779 !> Aerosol representation update data
780 class(aero_rep_update_data_t), intent(out) :: this
781 !> Memory buffer
782 character, intent(inout) :: buffer(:)
783 !> Current buffer position
784 integer, intent(inout) :: pos
785 !> MPI communicator
786 integer, intent(in), optional :: comm
787
788#ifdef CAMP_USE_MPI
789 integer :: prev_position, l_comm
790 integer(kind=i_kind) :: temp_int
791
792 if (present(comm)) then
793 l_comm = comm
794 else
795 l_comm = mpi_comm_world
796 endif
797
798 prev_position = pos
799 call camp_mpi_unpack_integer(buffer, pos, temp_int, l_comm)
800 this%aero_rep_type = int(temp_int, kind=c_int)
801 call camp_mpi_unpack_integer(buffer, pos, temp_int, l_comm)
802 this%aero_rep_solver_id = int(temp_int, kind=c_int)
803 call this%internal_bin_unpack(buffer, pos, l_comm)
804 call assert(257567920, &
805 pos - prev_position <= this%pack_size(l_comm))
806#endif
807
809
810!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
811
812 !> Print the update data
813 subroutine do_aero_rep_update_data_print(this, file_unit)
814
815 !> Aerosol representation update data
816 class(aero_rep_update_data_t), intent(in) :: this
817 !> File unit for output
818 integer(kind=i_kind), optional :: file_unit
819
820 integer(kind=i_kind) :: f_unit
821
822 f_unit = 6
823
824 if (present(file_unit)) f_unit = file_unit
825
826 write(f_unit,*) "*** Aerosol representation update data ***"
827 write(f_unit,*) "Aerosol representation type", this%aero_rep_type
828 write(f_unit,*) "Aerosol representation solver id", this%aero_rep_solver_id
829
830 end subroutine do_aero_rep_update_data_print
831
832!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
833
834end 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 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.
elemental 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.
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.
elemental subroutine ptr_finalize(this)
Finalize a pointer to an aerosol representation.
character(len=:) function, allocatable get_name(this)
Get the name of the aerosol representation.
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:38