63#define NUM_STATE_VAR_ this%condensed_data_int(1) 
   64#define NUM_INT_PROP_ 1 
   65#define NUM_REAL_PROP_ 0 
   66#define SPEC_TYPE_(x) this%condensed_data_int(NUM_INT_PROP_+x) 
   67#define MW_(x) this%condensed_data_real(NUM_REAL_PROP_+x) 
   68#define DENSITY_(x) this%condensed_data_real(NUM_REAL_PROP_+NUM_STATE_VAR_+x) 
   81    character(len=:), 
allocatable :: phase_name
 
   83    integer(kind=i_kind) :: num_spec = 0
 
   88    type(
string_t), 
pointer :: spec_name(:) => null()
 
  100    real(kind=
dp), 
allocatable, 
public :: condensed_data_real(:)
 
  105    integer(kind=i_kind), 
allocatable, 
public ::  condensed_data_int(:)
 
  150    procedure :: constructor
 
 
  173    character(len=*), 
intent(in), 
optional :: phase_name
 
  175    integer(kind=i_kind), 
intent(in), 
optional :: init_size
 
  179    if (
present(init_size)) alloc_size = init_size
 
  181    if (
present(phase_name)) 
then 
  182      new_obj%phase_name = phase_name
 
  184      new_obj%phase_name = 
"" 
  186    allocate(new_obj%spec_name(alloc_size))
 
 
  233  subroutine load(this, json, j_obj)
 
  238    type(json_core), 
pointer, 
intent(in) :: json
 
  240    type(json_value), 
pointer, 
intent(in) :: j_obj
 
  242    type(json_value), 
pointer :: child, next, species, species_child
 
  243    type(json_value), 
pointer :: species_obj
 
  244    character(kind=json_ck, len=:), 
allocatable :: key, unicode_str_val
 
  245    character(kind=json_ck, len=:), 
allocatable :: species_name
 
  246    integer(kind=i_kind) :: var_type, num_spec, i_spec
 
  248    character(len=:), 
allocatable :: str_val
 
  250    type(
property_t), 
pointer :: spec_property_set
 
  258    call json%get_child(j_obj, child)
 
  260    do while (
associated(child))
 
  261      call json%info(child, name=key, var_type=var_type)
 
  263      if (key.eq.
"name") 
then 
  264        if (var_type.ne.json_string) 
call die_msg(429142134, &
 
  265                "Received non-string aerosol phase name.")
 
  266        call json%get(child, unicode_str_val)
 
  267        this%phase_name = unicode_str_val
 
  269      else if (key.eq.
"species") 
then 
  270        if (var_type.ne.json_array) 
call die_msg(293312378, &
 
  271                "Received non-array list of aerosol phase species: "//&
 
  273        call json%get_child(child, species)
 
  274        do while (
associated(species))
 
  275          num_spec = num_spec + 1
 
  276          call json%info(species, var_type=var_type)
 
  277          if (var_type.eq.json_object) 
then 
  279            call json%get(species, 
"name", species_name)
 
  280            call this%add(species_name)
 
  281          else if (var_type.eq.json_string) 
then 
  283            call json%get(species, unicode_str_val)
 
  284            str_val = unicode_str_val
 
  285            call this%add(str_val)
 
  287            call die_msg(391082805, 
"Invalid species format: must be object or string.")
 
  289          call json%get_next(species, next)
 
  294      else if (key.ne.
"type") 
then 
  295        call property_set%load(json, child, .false., this%phase_name)
 
  298      call json%get_next(child, next)
 
  303    if (
associated(this%property_set)) 
then 
  304      call this%property_set%update(property_set, this%phase_name)
 
  305      deallocate (property_set)
 
  307      this%property_set => property_set
 
  314    allocate(this%spec_property_set(num_spec))
 
  316    call json%get_child(j_obj, child)
 
  317    do while (
associated(child))
 
  318      call json%info(child, name=key, var_type=var_type)
 
  320      if (key.eq.
"species") 
then 
  321        call json%get_child(child, species)
 
  322        do while (
associated(species))
 
  324          allocate(spec_property_set)
 
  325          call json%info(species, var_type=var_type)
 
  326          if (var_type.eq.json_object) 
then 
  327            call json%get_child(species, species_child)
 
  328            do while (
associated(species_child))
 
  329              call json%info(species_child, name=key, var_type=var_type)
 
  331              if (key.ne.
"name".and.key.ne.
"type") 
then 
  332                call spec_property_set%load(json, species_child, .false., this%spec_name(i_spec)%string)
 
  334              call json%get_next(species_child, next)
 
  335              species_child => next
 
  337            this%spec_property_set(i_spec)%val_ => spec_property_set
 
  338            spec_property_set => null()
 
  339          else if (var_type.eq.json_string) 
then 
  341            this%spec_property_set(i_spec)%val_ => spec_property_set
 
  342            spec_property_set => null()
 
  344            deallocate(spec_property_set)
 
  345            call die_msg(195829403, 
"Invalid type for Phase species")
 
  347          call json%get_next(species, next)
 
  351      call json%get_next(child, next)
 
  356  subroutine load(this)
 
  361    call warn_msg(236665532, 
"No support for input files.")
 
 
  376    integer(kind=i_kind) :: i_spec, i_spec_phase_type
 
  377    character(len=:), 
allocatable :: key_name
 
  380    allocate(this%condensed_data_int(num_int_prop_+this%num_spec))
 
  381    allocate(this%condensed_data_real(num_real_prop_+2*this%num_spec))
 
  384    num_state_var_ = this%num_spec
 
  387    do i_spec = 1, num_state_var_
 
  390      call assert_msg(140971956, chem_spec_data%get_property_set( &
 
  391              this%spec_name(i_spec)%string, spec_props), &
 
  392              "Missing property set for species '"// &
 
  393              this%spec_name(i_spec)%string// &
 
  394              "' in aerosol phase '"//this%phase_name//
"'")
 
  397      call assert_msg(129442398, chem_spec_data%get_type( &
 
  398              this%spec_name(i_spec)%string, spec_type_(i_spec)), &
 
  399              "Missing type for species '"// &
 
  400              this%spec_name(i_spec)%string// &
 
  401              "' in aerosol phase '"//this%phase_name//
"'")
 
  404      call assert_msg(136357145, chem_spec_data%get_phase( &
 
  405              this%spec_name(i_spec)%string, i_spec_phase_type ), &
 
  406              "Error getting phase for species "// &
 
  407              this%spec_name(i_spec)%string)
 
  409              "Trying to add non-aerosol phase species to aerosol phase "// &
 
  410              this%phase_name//
"; species: "//this%spec_name(i_spec)%string)
 
  419        key_name = 
"molecular weight [kg mol-1]" 
  421                spec_props%get_real(key_name, mw_(i_spec)), &
 
  422                "Missing molecular weight for species '"// &
 
  423                this%spec_name(i_spec)%string// &
 
  424                "' in aerosol phase '"//this%phase_name//
"'")
 
  427        key_name = 
"density [kg m-3]" 
  429                spec_props%get_real(key_name, density_(i_spec)), &
 
  430                "Missing density for species '"// &
 
  431                this%spec_name(i_spec)%string// &
 
  432                "' in aerosol phase '"//this%phase_name//
"'")
 
  438        density_(i_spec) = 0.0
 
  445    this%chem_spec_data => chem_spec_data
 
 
  455    character(len=:), 
allocatable :: phase_name
 
  459    phase_name = this%phase_name
 
 
  466  integer(kind=i_kind) function get_size(this) 
result(num_spec)
 
  471    num_spec = this%num_spec
 
 
  486    do i_spec = 1, this%num_spec
 
  490          num_elem = num_elem + 1
 
 
  506    property_set => this%property_set
 
 
  516    class(
property_t), 
pointer :: spec_property_set
 
  518    character(len=*), 
intent(in) :: spec_name
 
  522    integer(i_kind) :: i_spec   
 
  524    i_spec = this%find(spec_name)
 
  525    spec_property_set => this%spec_property_set(i_spec)%val_
 
 
  535    type(
string_t), 
allocatable :: spec_names(:)
 
  539    integer(kind=i_kind) :: i_spec
 
  541    allocate(spec_names(this%num_spec))
 
  542    do i_spec = 1, this%num_spec
 
  543      spec_names(i_spec)%string = this%spec_name(i_spec)%string
 
 
  554    integer(kind=i_kind) :: spec_type
 
  558    character(len=*), 
intent(in) :: spec_name
 
  560    call assert_msg(163269315, this%find(spec_name).gt.0, &
 
  561            "Species '"//spec_name//
"' is not in aerosol phase '"// &
 
  562            this%phase_name//
"'.")
 
  563    call assert(255786656, this%chem_spec_data%get_type(spec_name, spec_type))
 
 
  576    integer, 
intent(in) :: comm
 
 
  592    character, 
intent(inout) :: buffer(:)
 
  594    integer, 
intent(inout) :: pos
 
  596    integer, 
intent(in) :: comm
 
  599    integer :: prev_position
 
  605         pos - prev_position <= this%pack_size(comm))
 
 
  618    character, 
intent(inout) :: buffer(:)
 
  620    integer, 
intent(inout) :: pos
 
  622    integer, 
intent(in) :: comm
 
  625    integer :: prev_position
 
  632         pos - prev_position <= this%pack_size(comm))
 
 
  645    integer(kind=i_kind), 
optional :: file_unit
 
  647    integer(kind=i_kind) :: f_unit
 
  648    integer(kind=i_kind) :: i_spec
 
  652    if (
present(file_unit)) f_unit = file_unit
 
  653    write(f_unit,*) 
"Aerosol phase: ", this%phase_name
 
  654    write(f_unit,*) 
"Number of species: ", this%num_spec
 
  655    write(f_unit,*) 
"Species: [" 
  656    do i_spec = 1, this%num_spec
 
  657      write(*,*) this%spec_name(i_spec)%string
 
  660    call this%property_set%print(f_unit)
 
  661    write(f_unit,*) 
"End aerosol phase: ", this%phase_name
 
 
  672    integer(kind=i_kind) :: i
 
  674    if (
allocated(this%phase_name))    
deallocate(this%phase_name)
 
  675    if (
associated(this%spec_name))    
deallocate(this%spec_name)
 
  676    if (
associated(this%property_set)) 
deallocate(this%property_set)
 
  677    if (
allocated(this%condensed_data_real)) &
 
  678                                       deallocate(this%condensed_data_real)
 
  679    if (
allocated(this%condensed_data_int)) &
 
  680                                       deallocate(this%condensed_data_int)
 
  682    if (
allocated(this%spec_property_set)) 
then 
  683      do i = 1, 
size(this%spec_property_set)
 
  684        if (
associated(this%spec_property_set(i)%val_)) 
then 
  685          deallocate(this%spec_property_set(i)%val_)
 
  688      deallocate(this%spec_property_set)
 
 
  701    integer(kind=i_kind) :: i_phase
 
  703    do i_phase = 1, 
size(this)
 
 
  718    integer(kind=i_kind), 
intent(in) :: num_spec
 
  721    type(
string_t), 
pointer :: new_name(:)
 
  723    if (
size(this%spec_name) .ge. this%num_spec + num_spec) 
return 
  725    allocate(new_name(new_size))
 
  726    new_name(1:this%num_spec) = this%spec_name(1:this%num_spec)
 
  727    deallocate(this%spec_name)
 
  728    this%spec_name => new_name
 
 
  735  subroutine add(this, spec_name)
 
  740    character(len=*), 
intent(in) :: spec_name
 
  742    integer(kind=i_kind) :: i_spec
 
  744    i_spec = this%find(spec_name)
 
  745    if (i_spec.ne.0) 
then 
  746      call warn_msg(980242449, 
"Species "//spec_name//&
 
  747              " added more than once to phase "//this%name())
 
  750    call this%ensure_size(1)
 
  751    this%num_spec = this%num_spec + 1
 
  752    this%spec_name(this%num_spec)%string = spec_name
 
 
  760  integer(kind=i_kind) function find(this, spec_name) &
 
  766    character(len=*), 
intent(in) :: spec_name
 
  768    integer(kind=i_kind) :: i_spec
 
  771    do i_spec = 1, this%num_spec
 
  772      if (this%spec_name(i_spec)%string .eq. spec_name) 
then 
 
  800    if (
associated(this%val)) 
deallocate(this%val)
 
 
  812    integer(kind=i_kind) :: i_ptr
 
  814    do i_ptr = 1, 
size(this)
 
 
Interface for to_string functions.
 
The abstract aero_phase_data_t structure and associated subroutines.
 
integer(kind=i_kind), parameter realloc_inc
Reallocation increment.
 
subroutine finalize_array(this)
Finalize the aerosol phase data.
 
subroutine bin_unpack(this, buffer, pos, comm)
Unpack the given value from the buffer, advancing position.
 
class(property_t) function, pointer get_spec_property_set(this, spec_name)
Get the aerosol phase species property set.
 
integer(kind=i_kind) function get_size(this)
Get the number of species in the phase.
 
subroutine initialize(this, chem_spec_data)
Initialize the aerosol phase data, validating species names.
 
class(property_t) function, pointer get_property_set(this)
Get the aerosol phase property set.
 
character(len=:) function, allocatable get_name(this)
Get the aerosol phase name.
 
type(string_t) function, dimension(:), allocatable get_species_names(this)
Get an aerosol phase species name.
 
type(aero_phase_data_t) function, pointer constructor(phase_name, init_size)
Constructor for aero_phase_data_t.
 
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.
 
subroutine add(this, spec_name)
Add a new chemical species to the phase.
 
integer(kind=i_kind) function num_jac_elem(this)
Get the number of Jacobian row elements needed during solving.
 
subroutine ensure_size(this, num_spec)
Ensure there is enough room in the species dataset to add a specified number of species.
 
integer(kind=i_kind) function find(this, spec_name)
Get the index of an aerosol-phase species by name. Return 0 if the species is not found.
 
subroutine finalize(this)
Finalize the aerosol phase data.
 
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.
 
integer(kind=i_kind) function get_species_type(this, spec_name)
Get an aerosol phase species type.
 
elemental subroutine dereference(this)
Dereference a pointer to aerosol phase data.
 
The camp_state_t structure and associated subroutines.
 
The chem_spec_data_t structure and associated subroutines.
 
integer(kind=i_kind), parameter, public chem_spec_aero_phase
 
integer(kind=i_kind), parameter, public chem_spec_constant
 
integer(kind=i_kind), parameter, public chem_spec_variable
 
integer(kind=i_kind), parameter, public chem_spec_pssa
 
integer, parameter dp
Kind of a double precision real number.
 
integer, parameter i_kind
Kind of an integer.
 
Wrapper functions for MPI.
 
subroutine camp_mpi_pack_integer_array(buffer, position, val, comm)
Packs the given value into the buffer, advancing position.
 
subroutine camp_mpi_pack_real_array(buffer, position, val, comm)
Packs the given value into the buffer, advancing position.
 
subroutine camp_mpi_unpack_integer_array(buffer, position, val, comm)
Unpacks the given value from the buffer, advancing position.
 
integer function camp_mpi_pack_size_real_array(val, comm)
Determines the number of bytes required to pack the given value.
 
integer function camp_mpi_pack_size_integer_array(val, comm)
Determines the number of bytes required to pack the given value.
 
subroutine camp_mpi_unpack_real_array(buffer, position, val, comm)
Unpacks the given value from the buffer, advancing position.
 
The property_t structure and associated subroutines.
 
Common utility subroutines.
 
subroutine assert(code, condition_ok)
Errors unless condition_ok is true.
 
subroutine die_msg(code, error_msg)
Error immediately.
 
subroutine assert_msg(code, condition_ok, error_msg)
Errors unless condition_ok is true.
 
subroutine warn_msg(code, warning_msg, already_warned)
Prints a warning message.
 
Pointer type for building arrays.
 
String type for building arrays of string of various size.