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