CAMP 1.0.0
Chemistry Across Multiple Phases
rxn_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_rxn_data module.
7
8!> \page camp_rxn CAMP: Reactions (general)
9!!
10!! A reaction represents a transformation of the model state due to a physical
11!! or chemical process that occurs within a phase (gas or \ref
12!! camp_aero_phase "aerosol") or across the interface between two phases. In
13!! the \ref index "camp-chem" model, reactions are grouped into \ref
14!! camp_mechanism "mechanisms", which are solved over time-steps specified by
15!! the host model.
16!!
17!! The primary function of a reaction in the \ref index "camp-chem"
18!! model is to provide the solver with contributions to the time derivative
19!! and Jacobian matrix for \ref camp_species "chemical species"
20!! concentrations based on the current model state described in a \c
21!! camp_camp_state::camp_state_t object.
22!!
23!! Specific reaction types extend the abstract \c camp_rxn_data::rxn_data_t
24!! type and generally accept a set of reactants and products whose names
25!! correspond to \ref camp_species "chemical species" names, as well as a
26!! set of reaction parameters needed to describe a particular reaction.
27!! During initialization, a reaction will have access to its set of parameters
28!! as well as the parameters of any \ref camp_species "species" and \ref
29!! camp_aero_rep "aerosol phase" in the \ref index "camp-chem" model,
30!! however this information will not be available during a model run. The
31!! information required by the reaction instance to calculate its contribution
32!! to the time derivatve and Jacobian matrix must therefore be packed into
33!! the condensed data arrays of the \c camp_rxn_data::rxn_data_t object during
34!! intialization.
35!!
36!! Valid reaction types include:
37!!
38!! - \subpage camp_rxn_aqueous_equilibrium "aqueous-phase equilibrium"
39!! - \subpage camp_rxn_arrhenius "Arrhenius"
40!! - \subpage camp_rxn_CMAQ_H2O2 "CMAQ special reaction type for 2HO2 (+ H2O) -> H2O2"
41!! - \subpage camp_rxn_CMAQ_OH_HNO3 "CMAQ special reaction type for OH + HNO3 -> NO3 + H2O"
42!! - \subpage camp_rxn_condensed_phase_arrhenius "condensed-chase Arrhenius"
43!! - \subpage camp_rxn_condensed_phase_photolysis "condensed-chase photolysis"
44!! - \subpage camp_rxn_emission "emission"
45!! - \subpage camp_rxn_first_order_loss "first-order loss"
46!! - \subpage camp_rxn_HL_phase_transfer "Henry's Law phase transfer"
47!! - \subpage camp_rxn_photolysis "photolysis"
48!! - \subpage camp_rxn_SIMPOL_phase_transfer "SIMPOL.1 phase transfer"
49!! - \subpage camp_rxn_ternary_chemical_activation "ternary chemical activation"
50!! - \subpage camp_rxn_surface "surface (heterogeneous)"
51!! - \subpage camp_rxn_troe "Troe (fall-off)"
52!! - \subpage camp_rxn_wennberg_no_ro2 "Wennberg NO + RO2"
53!! - \subpage camp_rxn_wennberg_tunneling "Wennberg tunneling"
54!! - \subpage camp_rxn_wet_deposition "wet deposition"
55!!
56!! The general input format for a reaction can be found
57!! \subpage input_format_rxn "here".
58
59!> The rxn_data_t structure and associated subroutines.
61
62#ifdef CAMP_USE_JSON
63 use json_module
64#endif
65#ifdef CAMP_USE_MPI
66 use mpi
67#endif
70 use camp_constants, only : i_kind, dp
71 use camp_mpi
74 use camp_util, only : die_msg, string_t
75
76 use iso_c_binding
77
78 implicit none
79 private
80
82
83 !> Gas-phase reaction
84 integer(kind=i_kind), parameter, public :: gas_rxn = 1
85 !> Mixed-phase (gas and aerosol) reaction
86 integer(kind=i_kind), parameter, public :: gas_aero_rxn = 2
87 !> Aerosol-phase reaction
88 integer(kind=i_kind), parameter, public :: aero_rxn = 3
89
90 !> Abstract reaction data type
91 !!
92 !! Time-invariant data related to a \ref camp_rxn "reaction". Types
93 !! extending \c rxn_data_t should represent specific reaction types, with
94 !! unique rate equations. Extending types should not have data members, as
95 !! these will not be passed to the child nodes after initialization. Instead
96 !! all data required by an extending type during a model run should be
97 !! packed into the condensed_data arrays during initialization.
98 type, abstract :: rxn_data_t
99 private
100 !> Reaction phase
101 integer(kind=i_kind), public :: rxn_phase
102 !> Reaction parameters. These will be available during initialization,
103 !! but not during integration. All information required to calculate
104 !! the time derivatives and Jacobian matrix constributions must be
105 !! saved by the exdending type.
106 type(property_t), pointer, public :: property_set => null()
107 !> Condensed reaction data. Theses arrays will be available during
108 !! integration, and should contain any information required by the
109 !! rate and Jacobian constribution functions that cannot be obtained
110 !! from the \c camp_camp_state::camp_state_t object. (floating-point)
111 real(kind=dp), allocatable, public :: condensed_data_real(:)
112 !> Condensed reaction data. Theses arrays will be available during
113 !! integration, and should contain any information required by the
114 !! rate and Jacobian constribution functions that cannot be obtained
115 !! from the \c camp_camp_state::camp_state_t object. (integer)
116 integer(kind=i_kind), allocatable, public :: condensed_data_int(:)
117 !> Number of environment-dependent parameters
118 !! These are parameters that need updated when environmental conditions
119 !! change
120 integer(kind=i_kind), public :: num_env_params = 0
121 contains
122 !> Reaction initialization. Takes species, phase and reaction parameters
123 !! and packs required information into the condensed data arrays for use
124 !! during the model run.
125 !!
126 !! This routine should be called once for each reaction
127 !! at the beginning of a model run after all the input files have been
128 !! read in.
129 procedure(initialize), deferred :: initialize
130 !> Load data from an input file
131 procedure :: load
132 !> Check the phase of the reaction against the phase being solved for.
133 !! During GAS_RXN integrations, only GAS_RXN reactions are solved.
134 !! During AERO_RXN integrations, only AERO_RXN and GAS_AERO_RXN
135 !! reactions are solved. During GAS_AERO_RXN integrations, all
136 !! reactions are solved.
137 procedure :: check_phase
138 !> Determine the number of bytes required to pack the given value
139 procedure :: pack_size
140 !> Packs the given value into the buffer, advancing position
141 procedure :: bin_pack
142 !> Unpacks the given value from the buffer, advancing position
143 procedure :: bin_unpack
144 !> Print the reaction data
145 procedure :: print => do_print
146 end type rxn_data_t
147
148 !> Pointer type for building arrays of mixed reactions
150 class(rxn_data_t), pointer :: val => null()
151 contains
152 !> Dereference the pointer
153 procedure :: dereference
154 !> Finalize the pointer
156 end type rxn_data_ptr
157
158 !> Update cookie
159 type, abstract :: rxn_update_data_t
160 !> Reaction type
161 integer(kind=c_int) :: rxn_type
162 !> Index for this reaction in the solver data
163 integer(kind=c_int) :: rxn_solver_id = 0
164 !> Grid cell to update
165 integer(kind=c_int) :: cell_id = 1
166 !> Update data
167 type(c_ptr) :: update_data
168 contains
169 !> Get the reaction type
171 !> Get the grid cell to update
172 procedure :: get_cell_id => rxn_update_data_get_cell_id
173 !> Get the update data
174 procedure :: get_data => rxn_update_data_get_data
175 !> Determine the number of bytes required to pack the given value
177 !> Packs the given value into the buffer, advancing position
179 !> Unpacks the given value from the buffer, advancing position
181 !> Extending type pack size (internal use only)
183 !> Extending type bin pack (internal use only)
184 procedure(internal_bin_pack), deferred :: internal_bin_pack
185 !> Extending type bin unpack (internal use only)
187 !> Print the update data
188 procedure :: print => do_rxn_update_data_print
189 end type rxn_update_data_t
190
191interface
192
193!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
194
195 !> Reaction initialization. Takes species, phase and reaction parameters
196 !! and packs required information into the condensed data arrays for use
197 !! during the model run.
198 !!
199 !! This routine should be called once for each reaction
200 !! at the beginning of a model run after all the input files have been
201 !! read in.
202 subroutine initialize(this, chem_spec_data, aero_rep, n_cells)
203 use camp_util, only : i_kind
205
206 !> Reaction data
207 class(rxn_data_t), intent(inout) :: this
208 !> Chemical species data
209 type(chem_spec_data_t), intent(in) :: chem_spec_data
210 !> Aerosol representations
211 type(aero_rep_data_ptr), pointer, intent(in) :: aero_rep(:)
212 !> Number of grid cells to solve simultaneously
213 integer(kind=i_kind), intent(in) :: n_cells
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 :: rxn_update_data_t
223
224 !> Reaction data
225 class(rxn_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 :: rxn_update_data_t
236
237 !> Reaction data
238 class(rxn_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 :: rxn_update_data_t
253
254 !> Reaction data
255 class(rxn_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
267end interface
268
269contains
270
271!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
272
273 !> \page input_format_rxn Input JSON Object Format: Reaction (general)
274 !!
275 !! A \c json object containing information about a chemical reaction or
276 !! physical process in the gas phase, in an \ref camp_aero_phase
277 !! "aerosol phase", or between two phases (phase-transfer). \ref camp_rxn
278 !! "Reactions" are used to build \ref camp_mechanism "mechanisms" and are
279 !! only found within an input \ref input_format_mechanism "mechanism object"
280 !! in an array labelled \b reactions.
281 !! \code{.json}
282 !! { "camp-data" : [
283 !! {
284 !! "name" : "my mechanism",
285 !! "type" : "MECHANISM",
286 !! "reactions" : [
287 !! {
288 !! "type" : "REACTION_TYPE",
289 !! "reactants" : {
290 !! "some species" : {},
291 !! "another species" : { "qty" : 2 }
292 !! },
293 !! "products" : {
294 !! "product species" : { "yield" : 0.42 },
295 !! "another prod species" : {}
296 !! },
297 !! "some parameter" : 123.34,
298 !! "some other parameter" : true,
299 !! "nested parameters" : {
300 !! "sub param 1" : 12.43,
301 !! "sub param other" : "some text"
302 !! },
303 !! ...
304 !! },
305 !! {
306 !! "type" : "REACTION_TYPE",
307 !! "reactants" : {
308 !! "that one species" : { "qty" : 3 }
309 !! },
310 !! "some parameter" : 123.34,
311 !! ...
312 !! },
313 !! ...
314 !! ]},
315 !! ...
316 !! ]}
317 !! \endcode
318 !! The key-value pair \b type is required and its value must correspond
319 !! to a valid reaction type. Valid reaction types include:
320 !!
321 !! - \subpage camp_rxn_arrhenius "ARRHENIUS"
322 !! - \subpage camp_rxn_aqueous_equilibrium "AQUEOUS_EQUILIBRIUM"
323 !! - \subpage camp_rxn_CMAQ_H2O2 "CMAQ_H2O2"
324 !! - \subpage camp_rxn_CMAQ_OH_HNO3 "CMAQ_OH_HNO3"
325 !! - \subpage camp_rxn_condensed_phase_arrhenius "CONDENSED_PHASE_ARRHENIUS"
326 !! - \subpage camp_rxn_HL_phase_transfer "HL_PHASE_TRANSFER"
327 !! - \subpage camp_rxn_SIMPOL_phase_transfer "SIMPOL_PHASE_TRANSFER"
328 !! - \subpage camp_rxn_photolysis "PHOTOLYSIS"
329 !! - \subpage camp_rxn_troe "TROE"
330 !!
331 !! All remaining data are optional and may include any valid \c json value,
332 !! including nested objects. However, extending types (i.e. reactions) will
333 !! have specific requirements for the remaining data. Additionally it is
334 !! recommended to use the above format for reactants and products when
335 !! developing derived types that extend \c rxn_data_t, and to use \b type
336 !! values that match the name of the extending derived-type. For example, the
337 !! reaction type \c rxn_photolysis_t would have a \b type of \b PHOTOLYSIS.
338
339!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
340
341 !> Load reactions from an input file
342#ifdef CAMP_USE_JSON
343 subroutine load(this, json, j_obj)
344
345 !> Reaction data
346 class(rxn_data_t), intent(inout) :: this
347 !> JSON core
348 type(json_core), pointer, intent(in) :: json
349 !> JSON object
350 type(json_value), pointer, intent(in) :: j_obj
351
352 type(json_value), pointer :: child, next
353 character(kind=json_ck, len=:), allocatable :: key
354 character(len=:), allocatable :: owner_name
355
356 ! allocate space for the reaction property set
357 this%property_set => property_t()
358
359 ! No names currently for reactions, so use generic label
360 owner_name = "reaction"
361
362 ! cycle through the reaction properties, loading them into the reaction
363 ! property set
364 next => null()
365 call json%get_child(j_obj, child)
366 do while (associated(child))
367 call json%info(child, name=key)
368 if (key.ne."rxn type") call this%property_set%load(json, child, &
369 .false., owner_name)
370
371 call json%get_next(child, next)
372 child => next
373 end do
374#else
375 subroutine load(this)
376
377 !> Reaction data
378 class(rxn_data_t), intent(inout) :: this
379
380 call warn_msg(332862889, "No support for input files")
381#endif
382
383 end subroutine load
384
385!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
386
387 !> Check the phase of the reaction against the phase being solved for.
388 !! During GAS_RXN integrations, only GAS_RXN reactions are solved.
389 !! During AERO_RXN integrations, only AERO_RXN and GAS_AERO_RXN
390 !! reactions are solved. During GAS_AERO_RXN integrations, all
391 !! reactions are solved.
392 logical function check_phase(this, rxn_phase) result (valid_rxn)
393
394 !> Reaction data
395 class(rxn_data_t), intent(in) :: this
396 !> Phase being solved
397 integer(kind=i_kind), intent(in) :: rxn_phase
398
399 if (rxn_phase.eq.gas_aero_rxn .or. &
400 rxn_phase.eq.this%rxn_phase .or. &
401 (rxn_phase.eq.aero_rxn .and. this%rxn_phase.eq.gas_aero_rxn)) then
402 valid_rxn = .true.
403 else
404 valid_rxn = .false.
405 end if
406
407 end function check_phase
408
409!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
410
411 !> Determine the size of a binary required to pack the reaction data
412 integer(kind=i_kind) function pack_size(this, comm)
413
414 !> Reaction data
415 class(rxn_data_t), intent(in) :: this
416 !> MPI communicator
417 integer, intent(in) :: comm
418
419 pack_size = &
420 camp_mpi_pack_size_integer(this%rxn_phase, comm) + &
421 camp_mpi_pack_size_real_array(this%condensed_data_real, comm) + &
422 camp_mpi_pack_size_integer_array(this%condensed_data_int, comm) + &
423 camp_mpi_pack_size_integer(this%num_env_params, comm)
424
425 end function pack_size
426
427!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
428
429 !> Pack the given value to the buffer, advancing position
430 subroutine bin_pack(this, buffer, pos, comm)
431
432 !> Reaction data
433 class(rxn_data_t), intent(in) :: this
434 !> Memory buffer
435 character, intent(inout) :: buffer(:)
436 !> Current buffer position
437 integer, intent(inout) :: pos
438 !> MPI communicator
439 integer, intent(in) :: comm
440
441#ifdef CAMP_USE_MPI
442 integer :: prev_position
443
444 prev_position = pos
445 call camp_mpi_pack_integer(buffer, pos, this%rxn_phase, comm)
446 call camp_mpi_pack_real_array(buffer, pos, this%condensed_data_real, comm)
447 call camp_mpi_pack_integer_array(buffer, pos, this%condensed_data_int, comm)
448 call camp_mpi_pack_integer(buffer, pos, this%num_env_params, comm)
449 call assert(149359274, &
450 pos - prev_position <= this%pack_size(comm))
451#endif
452
453 end subroutine bin_pack
454
455!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
456
457 !> Unpack the given value from the buffer, advancing position
458 subroutine bin_unpack(this, buffer, pos, comm)
459
460 !> Reaction data
461 class(rxn_data_t), intent(out) :: this
462 !> Memory buffer
463 character, intent(inout) :: buffer(:)
464 !> Current buffer position
465 integer, intent(inout) :: pos
466 !> MPI communicator
467 integer, intent(in) :: comm
468
469#ifdef CAMP_USE_MPI
470 integer :: prev_position
471
472 prev_position = pos
473 call camp_mpi_unpack_integer(buffer, pos, this%rxn_phase, comm)
474 call camp_mpi_unpack_real_array(buffer, pos, this%condensed_data_real,comm)
475 call camp_mpi_unpack_integer_array(buffer, pos, this%condensed_data_int, &
476 comm)
477 call camp_mpi_unpack_integer(buffer, pos, this%num_env_params, comm)
478 call assert(168345796, &
479 pos - prev_position <= this%pack_size(comm))
480#endif
481
482 end subroutine bin_unpack
483
484!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
485
486 !> Print the reaction data
487 subroutine do_print(this, file_unit)
488
489 !> Reaction data
490 class(rxn_data_t), intent(in) :: this
491 !> File unit for output
492 integer(kind=i_kind), optional :: file_unit
493
494 integer(kind=i_kind) :: f_unit
495
496 f_unit = 6
497
498 if (present(file_unit)) f_unit = file_unit
499 write(f_unit,*) "*** Rxn ***"
500 if (associated(this%property_set)) call this%property_set%print(f_unit)
501 if (allocated(this%condensed_data_int)) &
502 write (f_unit,*) " *** condensed data int: ", &
503 this%condensed_data_int(:)
504 if (allocated(this%condensed_data_real)) &
505 write (f_unit,*) " *** condensed data real: ", &
506 this%condensed_data_real(:)
507 end subroutine do_print
508
509!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
510
511 !> Dereference a pointer to a reaction
512 elemental subroutine dereference(this)
513
514 !> Pointer to a reaction
515 class(rxn_data_ptr), intent(inout) :: this
516
517 this%val => null()
518
519 end subroutine dereference
520
521!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
522
523 !> Finalize a pointer to a reaction
524 subroutine ptr_finalize(this)
525
526 !> Pointer to a reaction
527 type(rxn_data_ptr), intent(inout) :: this
528
529 if (associated(this%val)) deallocate(this%val)
530
531 end subroutine ptr_finalize
532
533!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
534
535 !> Finalize an array of pointers to reactions
536 subroutine ptr_finalize_array(this)
537
538 !> Pointer to a reaction
539 type(rxn_data_ptr), intent(inout) :: this(:)
540
541 integer :: i
542
543 do i = 1, size(this)
544 call ptr_finalize(this(i))
545 end do
546
547 end subroutine ptr_finalize_array
548
549!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
550
551 !> Get the update data reaction type
552 function rxn_update_data_get_type(this) result(rxn_type)
553
554 !> Reaction type
555 integer(kind=c_int) :: rxn_type
556 !> Update data
557 class(rxn_update_data_t), intent(in) :: this
558
559 rxn_type = this%rxn_type
560
561 end function rxn_update_data_get_type
562
563!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
564
565 !> Get the grid cell id to update
566 function rxn_update_data_get_cell_id(this) result(cell_id)
567
568 !> Grid cell id
569 integer(kind=c_int) :: cell_id
570 !> Update data
571 class(rxn_update_data_t), intent(in) :: this
572
573 cell_id = this%cell_id
574
575 end function rxn_update_data_get_cell_id
576
577!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
578
579 !> Get the update data
580 function rxn_update_data_get_data(this) result(update_data)
581
582 !> Update data ptr
583 type(c_ptr) :: update_data
584 !> Update data
585 class(rxn_update_data_t), intent(in) :: this
586
587 update_data = this%update_data
588
589 end function rxn_update_data_get_data
590
591!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
592
593 !> Determine the size of a binary required to pack the reaction data
594 integer(kind=i_kind) function rxn_update_data_pack_size(this, comm) &
595 result(pack_size)
596
597 !> Reaction update data
598 class(rxn_update_data_t), intent(in) :: this
599 !> MPI communicator
600 integer, intent(in), optional :: comm
601
602#ifdef CAMP_USE_MPI
603 integer :: l_comm
604
605 if (present(comm)) then
606 l_comm = comm
607 else
608 l_comm = mpi_comm_world
609 endif
610
611 pack_size = &
612 camp_mpi_pack_size_integer(int(this%rxn_type, kind=i_kind), l_comm) + &
613 camp_mpi_pack_size_integer(int(this%rxn_solver_id, kind=i_kind), &
614 l_comm) + &
615 this%internal_pack_size(l_comm)
616#else
617 pack_size = 0
618#endif
619
620 end function rxn_update_data_pack_size
621
622!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
623
624 !> Pack the given value to the buffer, advancing position
625 subroutine rxn_update_data_bin_pack(this, buffer, pos, comm)
626
627 !> Reaction update data
628 class(rxn_update_data_t), intent(in) :: this
629 !> Memory buffer
630 character, intent(inout) :: buffer(:)
631 !> Current buffer position
632 integer, intent(inout) :: pos
633 !> MPI communicator
634 integer, intent(in), optional :: comm
635
636#ifdef CAMP_USE_MPI
637 integer :: prev_position, l_comm
638
639 if (present(comm)) then
640 l_comm = comm
641 else
642 l_comm = mpi_comm_world
643 endif
644
645 prev_position = pos
646 call camp_mpi_pack_integer(buffer, pos, &
647 int(this%rxn_type, kind=i_kind), l_comm)
648 call camp_mpi_pack_integer(buffer, pos, &
649 int(this%rxn_solver_id, kind=i_kind), l_comm)
650 call this%internal_bin_pack(buffer, pos, l_comm)
651 call assert(713360087, &
652 pos - prev_position <= this%pack_size(l_comm))
653#endif
654
655 end subroutine rxn_update_data_bin_pack
656
657!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
658
659 !> Unpack the given value from the buffer, advancing position
660 subroutine rxn_update_data_bin_unpack(this, buffer, pos, comm)
661
662 !> Reaction update data
663 class(rxn_update_data_t), intent(out) :: this
664 !> Memory buffer
665 character, intent(inout) :: buffer(:)
666 !> Current buffer position
667 integer, intent(inout) :: pos
668 !> MPI communicator
669 integer, intent(in), optional :: comm
670
671#ifdef CAMP_USE_MPI
672 integer :: prev_position, l_comm
673 integer(kind=i_kind) :: temp_int
674
675 if (present(comm)) then
676 l_comm = comm
677 else
678 l_comm = mpi_comm_world
679 endif
680
681 prev_position = pos
682 call camp_mpi_unpack_integer(buffer, pos, temp_int, l_comm)
683 this%rxn_type = int(temp_int, kind=c_int)
684 call camp_mpi_unpack_integer(buffer, pos, temp_int, l_comm)
685 this%rxn_solver_id = int(temp_int, kind=c_int)
686 call this%internal_bin_unpack(buffer, pos, l_comm)
687 call assert(107364895, &
688 pos - prev_position <= this%pack_size(l_comm))
689#endif
690
691 end subroutine rxn_update_data_bin_unpack
692
693!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
694
695 !> Print the update data
696 subroutine do_rxn_update_data_print(this, file_unit)
697
698 !> Reaction update data
699 class(rxn_update_data_t), intent(in) :: this
700 !> File unit for output
701 integer(kind=i_kind), optional :: file_unit
702
703 integer(kind=i_kind) :: f_unit
704
705 file_unit = 6
706
707 if (present(file_unit)) f_unit = file_unit
708
709 write(f_unit,*) "*** Reaction update data ***"
710 write(f_unit,*) "Rxn type", this%rxn_type
711 write(f_unit,*) "Rxn solver id", this%rxn_solver_id
712
713 end subroutine do_rxn_update_data_print
714
715!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
716
717end module camp_rxn_data
Reaction initialization. Takes species, phase and reaction parameters and packs required information ...
Definition rxn_data.F90:202
Extending-type binary pack function (Internal use only)
Definition rxn_data.F90:234
Extending-type binary unpack function (Internal use only)
Definition rxn_data.F90:251
Extending-type binary pack size (internal use only)
Definition rxn_data.F90:220
The abstract aero_rep_data_t structure and associated subroutines.
subroutine do_print(this, file_unit)
Print the aerosol representation data.
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 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.
subroutine bin_pack(this, buffer, pos, comm)
Pack the given value to the buffer, advancing position.
subroutine ptr_finalize_array(this)
Finalize an array of pointers to aerosol representations.
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
The rxn_data_t structure and associated subroutines.
Definition rxn_data.F90:60
subroutine do_rxn_update_data_print(this, file_unit)
Print the update data.
Definition rxn_data.F90:697
integer(kind=c_int) function rxn_update_data_get_cell_id(this)
Get the grid cell id to update.
Definition rxn_data.F90:567
integer(kind=i_kind), parameter, public gas_rxn
Gas-phase reaction.
Definition rxn_data.F90:84
integer(kind=i_kind), parameter, public gas_aero_rxn
Mixed-phase (gas and aerosol) reaction.
Definition rxn_data.F90:86
integer(kind=i_kind), parameter, public aero_rxn
Aerosol-phase reaction.
Definition rxn_data.F90:88
subroutine rxn_update_data_bin_pack(this, buffer, pos, comm)
Pack the given value to the buffer, advancing position.
Definition rxn_data.F90:626
subroutine rxn_update_data_bin_unpack(this, buffer, pos, comm)
Unpack the given value from the buffer, advancing position.
Definition rxn_data.F90:661
integer(kind=c_int) function rxn_update_data_get_type(this)
Get the update data reaction type.
Definition rxn_data.F90:553
type(c_ptr) function rxn_update_data_get_data(this)
Get the update data.
Definition rxn_data.F90:581
logical function check_phase(this, rxn_phase)
Check the phase of the reaction against the phase being solved for. During GAS_RXN integrations,...
Definition rxn_data.F90:393
integer(kind=i_kind) function rxn_update_data_pack_size(this, comm)
Determine the size of a binary required to pack the reaction data.
Definition rxn_data.F90:596
Common utility subroutines.
Definition util.F90:9
subroutine die_msg(code, error_msg)
Error immediately.
Definition util.F90:196
Pointer to aero_rep_data_t extending types.
Pointer type for building arrays of mixed reactions.
Definition rxn_data.F90:149
Abstract reaction data type.
Definition rxn_data.F90:98
String type for building arrays of string of various size.
Definition util.F90:53