CAMP 1.0.0
Chemistry Across Multiple Phases
part_4_code/box_model.F90
Go to the documentation of this file.
1program box_model
2
11
12 !! [MPI modules]
13#ifdef CAMP_USE_MPI
14 use mpi
15 use camp_mpi
16#endif
17 !! [MPI modules]
18
19 implicit none
20
21 type(camp_core_t), pointer :: camp_core
22 type(camp_state_t), pointer :: camp_state
23
24 integer(kind=i_kind) :: idx_o3, idx_no, idx_no2, idx_o2
25 type(chem_spec_data_t), pointer :: chem_spec_data
26
27 character(len=*), parameter :: fmt_hdr = "(A10,',',A10,',',A10,',',A10,',',A10)"
28 character(len=*), parameter :: fmt_dat = "(ES10.4,',',ES10.4,',',ES10.4,',',ES10.4,',',ES10.4)"
29
30 integer(kind=i_kind) :: i_time
31
32 integer(kind=i_kind) :: i_rxn
33 character(len=:), allocatable :: photo_label
34 type(mechanism_data_t), pointer :: mechanism
35 type(rxn_factory_t) :: rxn_factory
36 class(rxn_data_t), pointer :: photo_rxn
37 type(rxn_update_data_photolysis_t) :: no2_photolysis
38
39 !! [MPI variables]
40#ifdef CAMP_USE_MPI
41 integer(kind=i_kind) :: pos, pack_size
42 character, allocatable :: buffer(:)
43#endif
44 !! [MPI variables]
45
46 !! [wrap initialization]
47#ifdef CAMP_USE_MPI
48 call camp_mpi_init( )
49
50 if( camp_mpi_rank( ) .eq. 0 ) then
51#endif
52
53 camp_core => camp_core_t( "my_config_file.json" )
54 call camp_core%initialize( )
55 !! [wrap initialization]
56
57 if( .not.camp_core%get_chem_spec_data( chem_spec_data ) ) then
58 write(*,*) "Something's gone wrong!"
59 stop 3
60 end if
61
62 idx_o3 = chem_spec_data%gas_state_id( "O3" )
63 idx_no = chem_spec_data%gas_state_id( "NO" )
64 idx_no2 = chem_spec_data%gas_state_id( "NO2" )
65 idx_o2 = chem_spec_data%gas_state_id( "O2" )
66 if( idx_o3.eq.0 .or. idx_no2.eq.0 .or.idx_o2.eq.0 ) then
67 write(*,*) "Missing species!"
68 stop 3
69 end if
70
71 if( .not.camp_core%get_mechanism( "my simple mechanism", mechanism ) ) then
72 write(*,*) "Missing mechanism!"
73 stop 3
74 end if
75
76 do i_rxn = 1, mechanism%size( )
77 photo_rxn => mechanism%get_rxn( i_rxn )
78 select type( photo_rxn )
79 class is( rxn_photolysis_t )
80 if( photo_rxn%property_set%get_string( "my photo label", photo_label ) ) then
81 if( photo_label .eq. "NO2 photolysis" ) then
82 call camp_core%initialize_update_object( photo_rxn, no2_photolysis )
83 end if
84 end if
85 end select
86 end do
87
88 !! [get pack size]
89#ifdef CAMP_USE_MPI
90 ! Pack the core and the NO2 photolysis update data object
91 pack_size = camp_core%pack_size( ) + &
92 no2_photolysis%pack_size( )
93 allocate( buffer( pack_size ) )
94 !! [get pack size]
95
96 !! [pack objects]
97 pos = 0
98 call camp_core%bin_pack( buffer, pos )
99 call no2_photolysis%bin_pack( buffer, pos )
100
101 end if ! primary process
102 !! [pack objects]
103
104 !! [pass indices]
105 call camp_mpi_bcast_integer( idx_o3 )
106 call camp_mpi_bcast_integer( idx_no )
107 call camp_mpi_bcast_integer( idx_no2 )
108 call camp_mpi_bcast_integer( idx_o2 )
109 !! [pass indices]
110
111 !! [pass the buffer]
113
114 if( camp_mpi_rank( ) .gt. 0 ) then
115 allocate( buffer( pack_size ) )
116 end if
117
118 call camp_mpi_bcast_packed( buffer )
119 !! [pass the buffer]
120
121 !! [unpack the objects]
122 if( camp_mpi_rank( ) .gt. 0 ) then
123
124 camp_core => camp_core_t( )
125 pos = 0
126 call camp_core%bin_unpack( buffer, pos )
127 call no2_photolysis%bin_unpack( buffer, pos )
128
129 end if
130
131 deallocate( buffer )
132#endif
133 !! [unpack the objects]
134
135 call camp_core%solver_initialize( )
136 camp_state => camp_core%new_state( )
137
138 call camp_state%env_states(1)%set_temperature_K( 275.4_dp )
139 call camp_state%env_states(1)%set_pressure_Pa( 101532.2_dp )
140
141 camp_state%state_var( idx_o3 ) = 0.13 ! [O3] in ppm
142 camp_state%state_var( idx_no ) = 0.02 ! [NO] in ppm
143 camp_state%state_var( idx_no2 ) = 0.053 ! [NO2] in ppm
144 camp_state%state_var( idx_o2 ) = 2.1e5 ! [O2] in ppm
145
146 !! [Set NO2 photolysis]
147 call no2_photolysis%set_rate( 12.2d0 ) ! rate in s-1
148 call camp_core%update_data( no2_photolysis )
149 !! [Set NO2 photolysis]
150
151 !! [output]
152#ifdef CAMP_USE_MPI
153 if( camp_mpi_rank( ) .eq. 1 ) then
154#endif
155
156 write(*,fmt_hdr) "time", "O3", "NO", "NO2", "O2"
157 do i_time = 1, 100
158 call camp_core%solve( camp_state, 1.0d-15 ) ! time step in s
159 write(*,fmt_dat) i_time*1.0e-15, &
160 camp_state%state_var( idx_o3 ), &
161 camp_state%state_var( idx_no ), &
162 camp_state%state_var( idx_no2 ), &
163 camp_state%state_var( idx_o2 )
164 end do
165
166#ifdef CAMP_USE_MPI
167 end if
168
169 call camp_mpi_finalize( )
170#endif
171 !! [output]
172
173 deallocate( camp_core )
174 deallocate( camp_state )
175
176end program box_model
The camp_core_t structure and associated subroutines.
Definition camp_core.F90:87
integer(kind=i_kind) function pack_size(this, comm)
Determine the size of a binary required to pack the mechanism.
The camp_state_t structure and associated subroutines.
Definition camp_state.F90:9
The chem_spec_data_t structure and associated subroutines.
Physical constants.
Definition constants.F90:9
The mechanism_data_t structure and associated subroutines.
Wrapper functions for MPI.
Definition mpi.F90:13
subroutine camp_mpi_init()
Initialize MPI.
Definition mpi.F90:58
integer function camp_mpi_rank(comm)
Returns the rank of the current process.
Definition mpi.F90:128
subroutine camp_mpi_bcast_packed(val, comm)
Broadcast the given value from process 0 to all other processes.
Definition mpi.F90:371
subroutine camp_mpi_finalize()
Shut down MPI.
Definition mpi.F90:91
subroutine camp_mpi_bcast_integer(val, comm)
Broadcast the given value from process 0 to all other processes.
Definition mpi.F90:317
The rxn_data_t structure and associated subroutines.
Definition rxn_data.F90:60
The abstract rxn_factory_t structure and associated subroutines.
The rxn_photolysis_t type and associated functions.
program box_model
Part-MC model data.
Abstract reaction data type.
Definition rxn_data.F90:98
Factory type for chemical reactions.
Generic test reaction data type.