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