PartMC  2.6.1
camp_interface.F90
Go to the documentation of this file.
1 ! Copyright (C) 2017-2018 Matt Dawson
2 ! Licensed under the GNU General Public License version 2 or (at your
3 ! option) any later version. See the file COPYING for details.
4 
5 !> \file
6 !> The pmc_camp_interface module.
7 
8 !> An interface between PartMC and the CAMP
10 
11  use pmc_aero_data
13  use pmc_aero_state
14  use pmc_constants, only : dp
15  use pmc_gas_data
16  use pmc_gas_state
17 #ifdef PMC_USE_CAMP
18  use camp_camp_core
19  use camp_camp_state
20  use pmc_photolysis
21  use camp_rxn_data
22  use camp_solver_stats
23  use camp_util, only: split_string
24 #endif
26 
27  implicit none
28 
29 contains
30 
31 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
32 #ifdef PMC_USE_CAMP
33  !> Run the CAMP module for the current PartMC state
34  subroutine pmc_camp_interface_solve(camp_core, camp_state, &
35  camp_pre_aero_state, camp_post_aero_state, env_state, aero_data, &
36  aero_state, gas_data, gas_state, photolysis, del_t)
37 
38  !> CAMP core
39  type(camp_core_t), intent(in) :: camp_core
40  !> CAMP state
41  type(camp_state_t), intent(inout) :: camp_state
42  !> Working CAMP state
43  type(camp_state_t), intent(inout) :: camp_pre_aero_state
44  !> Working CAMP state
45  type(camp_state_t), intent(inout) :: camp_post_aero_state
46  !> Environment.
47  type(env_state_t), intent(inout) :: env_state
48  !> Aerosol data
49  type(aero_data_t), intent(in) :: aero_data
50  !> Aerosol state
51  type(aero_state_t), intent(inout) :: aero_state
52  !> Gas data
53  type(gas_data_t), intent(in) :: gas_data
54  !> Gas state
55  type(gas_state_t), intent(inout) :: gas_state
56  !> Photolysis calculator
57  type(photolysis_t), intent(inout) :: photolysis
58  !> Time step (s)
59  real(kind=dp), intent(in) :: del_t
60 
61  integer :: i_part
62  real(kind=dp) :: num_conc
63  integer :: camp_state_size
64  type(solver_stats_t), target :: solver_stats
65  type(camp_state_t) :: camp_state_pre_aero
66 
67  ! Set the CAMP environmental state.
68  call env_state_set_camp_env_state(env_state, camp_state)
69 
70  ! Set the CAMP gas-phase species concentrations
71  call gas_state_set_camp_conc(gas_state, camp_state, gas_data)
72 
73  ! Recalculate the photolysis rate constants
74  call photolysis%update_rate_constants()
75 
76  ! Update the number concentrations and composition for all particles
77  call pmc_camp_interface_set_camp_aerosol(aero_data, aero_state, &
78  camp_core, camp_state)
79 
80  ! We're modifying particle diameters, so the bin sort is now invalid
81  aero_state%valid_sort = .false.
82 
83  ! Solve the multi-phase chemical system
84  call camp_core%solve(camp_state, del_t, solver_stats = solver_stats)
85 
86  call assert_msg(592148911, solver_stats%status_code == 0, &
87  "Solver failed for aerosol-phase with code "// &
88  integer_to_string(solver_stats%solver_flag))
89 
90  ! Update the PartMC aerosol state
91  call pmc_camp_interface_set_partmc_aerosol(aero_data, aero_state, &
92  camp_state)
93 
94  ! Update the PartMC gas-phase state
95  call gas_state_get_camp_conc(gas_state, camp_state)
96 
97  end subroutine pmc_camp_interface_solve
98 
99 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
100 
101  !> Set the CAMP aerosol-phase species and number concentrations
102  subroutine pmc_camp_interface_set_camp_aerosol(aero_data, aero_state, &
103  camp_core, camp_state)
104 
105  !> Aerosol data.
106  type(aero_data_t), intent(in) :: aero_data
107  !> Aerosol state.
108  type(aero_state_t), intent(inout) :: aero_state
109  !> CAMP core.
110  type(camp_core_t), intent(in) :: camp_core
111  !> CAMP state.
112  type(camp_state_t), intent(inout) :: camp_state
113 
114  real(kind=dp) :: num_conc
115  integer :: i_part, i_spec
116 
117  associate(aero_rep => aero_data%aero_rep_ptr)
118  select type (aero_rep)
119  type is (aero_rep_single_particle_t)
120  call assert_msg(858496327, aero_state_n_part(aero_state) <= &
121  aero_rep%maximum_computational_particles(), &
122  "Exceeded CAMP maximum number of particles. Number "// &
123  "of computational particles: "// &
124  trim(integer_to_string(aero_state_n_part(aero_state)))// &
125  ". CAMP maximum: "// &
126  trim(integer_to_string( &
127  aero_rep%maximum_computational_particles())))
128  do i_part = 1, aero_state_n_part(aero_state)
129  associate(part => aero_state%apa%particle(i_part))
130  num_conc = aero_weight_array_num_conc(aero_state%awa, part, &
131  aero_data)
132  call aero_state%update_number%set_number__n_m3(i_part, num_conc)
133  call camp_core%update_data(aero_state%update_number)
134  do i_spec = 1, size(aero_data%camp_particle_spec_id)
135  camp_state%state_var(aero_data%camp_spec_id(i_part, i_spec)) &
136  = part%vol(i_spec) * aero_data%density(i_spec) ! kg m-3
137  end do
138  end associate
139  end do
140  do i_part = aero_state_n_part(aero_state) + 1, &
141  aero_rep%maximum_computational_particles()
142  call aero_state%update_number%set_number__n_m3(i_part, 0.0d0)
143  call camp_core%update_data(aero_state%update_number)
144  do i_spec = 1,size(aero_data%camp_particle_spec_id)
145  camp_state%state_var(aero_data%camp_spec_id(i_part, i_spec)) &
146  = 0.0d0
147  end do
148  end do
149  class default
150  call die_msg(780366884, &
151  "Wrong type for PartMC aerosol representation.")
152  end select
153  end associate
154 
155  end subroutine pmc_camp_interface_set_camp_aerosol
156 
157 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
158 
159  !> Set PartMC aerosol-phase species concentrations
160  subroutine pmc_camp_interface_set_partmc_aerosol(aero_data, aero_state, &
161  camp_state)
162 
163  !> Aerosol particle
164  type(aero_data_t), intent (in) :: aero_data
165  !> Aerosol state
166  type(aero_state_t), intent(inout) :: aero_state
167  !> CAMP state
168  type(camp_state_t), intent(in) :: camp_state
169 
170  integer :: i_part, i_spec
171 
172  associate(aero_rep => aero_data%aero_rep_ptr)
173  select type (aero_rep)
174  type is (aero_rep_single_particle_t)
175  call assert_msg(464490945, aero_state_n_part(aero_state) <= &
176  aero_rep%maximum_computational_particles(), &
177  "Exceeded CAMP maximum number of particles")
178  do i_part = 1, aero_state_n_part(aero_state)
179  associate(part => aero_state%apa%particle(i_part))
180  do i_spec = 1, size(aero_data%camp_particle_spec_id)
181  part%vol(i_spec) = &
182  camp_state%state_var(aero_data%camp_spec_id(i_part, i_spec)) &
183  / aero_data%density(i_spec) ! m3
184  end do
185  end associate
186  end do
187  class default
188  call die_msg(773649338, &
189  "Wrong type for PartMC aerosol representation.")
190  end select
191  end associate
192 
193  end subroutine pmc_camp_interface_set_partmc_aerosol
194 
195 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
196 #endif
197 end module pmc_camp_interface
pmc_aero_state::aero_state_n_part
elemental integer function aero_state_n_part(aero_state)
Return the current number of particles.
Definition: aero_state.F90:88
pmc_aero_particle
The aero_particle_t structure and associated subroutines.
Definition: aero_particle.F90:9
pmc_gas_data
The gas_data_t structure and associated subroutines.
Definition: gas_data.F90:9
pmc_util::warn_assert_msg
subroutine warn_assert_msg(code, condition_ok, warning_msg)
Prints a warning message if condition_ok is false.
Definition: util.F90:59
pmc_util::die_msg
subroutine die_msg(code, error_msg)
Error immediately.
Definition: util.F90:134
pmc_constants::dp
integer, parameter dp
Kind of a double precision real number.
Definition: constants.F90:12
pmc_aero_state
The aero_state_t structure and assocated subroutines.
Definition: aero_state.F90:9
pmc_gas_state
The gas_state_t structure and associated subroutines.
Definition: gas_state.F90:9
pmc_util::assert_msg
subroutine assert_msg(code, condition_ok, error_msg)
Errors unless condition_ok is true.
Definition: util.F90:77
pmc_photolysis
The photolysis_t type and related functions.
Definition: photolysis.F90:9
pmc_constants
Physical constants.
Definition: constants.F90:9
pmc_util
Common utility subroutines.
Definition: util.F90:9
pmc_camp_interface
An interface between PartMC and the CAMP.
Definition: camp_interface.F90:9
pmc_aero_data
The aero_data_t structure and associated subroutines.
Definition: aero_data.F90:9