Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Rxns with layers #7

Merged
merged 10 commits into from
Jul 2, 2024
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
**/*.d
**/*.dSym
**/.DS_Store
**/*.pyc
CMakeCache.txt
Expand Down
42 changes: 35 additions & 7 deletions src/aero_rep_data.F90
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,10 @@ module camp_aero_rep_data
!! functions of the aerosol representation that cannot be obtained
!! from the camp_camp_state::camp_state_t object. (integer)
integer(kind=i_kind), allocatable, public :: condensed_data_int(:)
!> Array of booleans indicating if phase exists at the surface of a
!! particle. Used in SIMPOL and HL reactions for single particle
!! representation.
logical, allocatable, public :: aero_phase_is_at_surface(:)
!> Number of environment-dependent parameters
!! These are parameters that need updated when environmental conditions
!! change
Expand Down Expand Up @@ -489,26 +493,50 @@ end function get_name

!> Get a set of ids for all instances of a phase in this aerosol
!! representation for use during solving
function phase_ids(this, phase_name)
function phase_ids(this, phase_name, is_at_surface)

!> List of phase ids
integer(kind=i_kind), allocatable :: phase_ids(:)
!> Aerosol representation data
class(aero_rep_data_t), intent(in) :: this
!> Aerosol phase name
character(len=*), intent(in) :: phase_name
!> Indicates if aerosol phase is at the surface of particle
logical, intent(in), optional :: is_at_surface

integer(kind=i_kind) :: num_instances, i_instance, i_phase

num_instances = this%num_phase_instances(phase_name)
allocate(phase_ids(num_instances))
i_instance = 1
do i_phase = 1, size(this%aero_phase)
if (this%aero_phase(i_phase)%val%name().eq.phase_name) then
phase_ids(i_instance) = i_phase
i_instance = i_instance + 1
if (present(is_at_surface)) then
if (is_at_surface) then
i_instance = 1
do i_phase = 1, size(this%aero_phase)
if (this%aero_phase(i_phase)%val%name().eq. phase_name .and. &
this%aero_phase_is_at_surface(i_phase)) then
phase_ids(i_instance) = i_phase
i_instance = i_instance + 1
end if
end do
else
i_instance = 1
do i_phase = 1, size(this%aero_phase)
if (this%aero_phase(i_phase)%val%name().eq. phase_name .and. &
.not. this%aero_phase_is_at_surface(i_phase)) then
phase_ids(i_instance) = i_phase
i_instance = i_instance + 1
end if
end do
end if
end do
else
i_instance = 1
do i_phase = 1, size(this%aero_phase)
if (this%aero_phase(i_phase)%val%name().eq.phase_name) then
phase_ids(i_instance) = i_phase
i_instance = i_instance + 1
end if
end do
end if

end function phase_ids

Expand Down
4 changes: 4 additions & 0 deletions src/aero_reps/aero_rep_modal_binned_mass.F90
Original file line number Diff line number Diff line change
Expand Up @@ -477,6 +477,7 @@ subroutine initialize(this, aero_phase_set, spec_state_id)

! Allocate space for the aerosol phases and species state ids
allocate(this%aero_phase(num_phase))
allocate(this%aero_phase_is_at_surface(num_phase))
allocate(this%phase_state_id(size(this%aero_phase)))

! Allocate condensed data arrays
Expand Down Expand Up @@ -616,6 +617,9 @@ subroutine initialize(this, aero_phase_set, spec_state_id)

! Add the aerosol phase to the list
this%aero_phase(i_phase) = aero_phase_set(k_phase)

! No species exist at surface
this%aero_phase_is_at_surface(i_phase) = .true.

! Save the starting id for this phase on the state array
this%phase_state_id(i_phase) = curr_spec_state_id
Expand Down
8 changes: 8 additions & 0 deletions src/aero_reps/aero_rep_single_particle.F90
Original file line number Diff line number Diff line change
Expand Up @@ -358,6 +358,7 @@ subroutine initialize(this, aero_phase_set, spec_state_id)
! each layer in each particle, and set PHASE_STATE_ID and
! PHASE_MODEL_DATA_ID for each phase
allocate(this%aero_phase(num_phases * num_particles))
allocate(this%aero_phase_is_at_surface(num_phases * num_particles))
curr_phase = 1
do i_layer = 1, size(ordered_layer_id)
j_layer = ordered_layer_id(i_layer)
Expand Down Expand Up @@ -395,6 +396,13 @@ subroutine initialize(this, aero_phase_set, spec_state_id)
do i_particle = 0, num_particles-1
this%aero_phase(i_particle*num_phases + curr_phase) = &
aero_phase_set(j_phase)
if (i_layer .eq. NUM_LAYERS_) then
this%aero_phase_is_at_surface(i_particle*num_phases + curr_phase) = &
.true.
else
this%aero_phase_is_at_surface(i_particle*num_phases + curr_phase) = &
.false.
end if
end do
PHASE_STATE_ID_(i_layer,i_phase) = curr_id
PHASE_MODEL_DATA_ID_(i_layer,i_phase) = j_phase
Expand Down
3 changes: 2 additions & 1 deletion src/aero_reps/aero_rep_single_particle.c
Original file line number Diff line number Diff line change
Expand Up @@ -437,8 +437,9 @@ void aero_rep_single_particle_print(int *aero_rep_int_data,
printf("\nAerosol representation id: %d", AERO_REP_ID_);
printf("\nMax computational particles: %d", MAX_PARTICLES_);
printf("\nParticle state size: %d", PARTICLE_STATE_SIZE_);
printf("\n\n - Phases -");
for(int i_layer = 0; i_layer < NUM_LAYERS_; ++i_layer){
printf("\nLayer: %d", i_layer);
printf("\n\n - Phases -");
mattldawson marked this conversation as resolved.
Show resolved Hide resolved
for (int i_phase = 0; i_phase < NUM_PHASES_(i_layer); ++i_phase) {
printf("\n state id: %d model data id: %d num Jac elements: %d",
PHASE_STATE_ID_(i_layer,i_phase), PHASE_MODEL_DATA_ID_(i_layer,i_phase),
Expand Down
4 changes: 2 additions & 2 deletions src/rxns/rxn_HL_phase_transfer.F90
Original file line number Diff line number Diff line change
Expand Up @@ -257,7 +257,7 @@ subroutine initialize(this, chem_spec_data, aero_rep, n_cells)

! Get the number of Jacobian elements for calculations of mass, volume,
! number, etc. for this partitioning into this phase
phase_ids = aero_rep(i_aero_rep)%val%phase_ids(phase_name)
phase_ids = aero_rep(i_aero_rep)%val%phase_ids(phase_name,is_at_surface=.true.)
do i_phase = 1, size(phase_ids)
n_aero_jac_elem = n_aero_jac_elem + &
aero_rep(i_aero_rep)%val%num_jac_elem(phase_ids(i_phase))
Expand Down Expand Up @@ -316,7 +316,7 @@ subroutine initialize(this, chem_spec_data, aero_rep, n_cells)
phase_name = phase_name, spec_name = water_name)

! Get the phase ids for this aerosol phase
phase_ids = aero_rep(i_aero_rep)%val%phase_ids(phase_name)
phase_ids = aero_rep(i_aero_rep)%val%phase_ids(phase_name,is_at_surface=.true.)

! Add the species concentration and activity coefficient ids to
! the condensed data, and set the number of jacobian elements for
Expand Down
5 changes: 2 additions & 3 deletions src/rxns/rxn_SIMPOL_phase_transfer.F90
Original file line number Diff line number Diff line change
Expand Up @@ -255,7 +255,7 @@ subroutine initialize(this, chem_spec_data, aero_rep, n_cells)

! Get the number of Jacobian elements for calculations of mass, volume,
! number, etc. for this partitioning into this phase
phase_ids = aero_rep(i_aero_rep)%val%phase_ids(phase_name)
phase_ids = aero_rep(i_aero_rep)%val%phase_ids(phase_name,is_at_surface=.true.)
do i_phase = 1, size(phase_ids)
n_aero_jac_elem = n_aero_jac_elem + &
aero_rep(i_aero_rep)%val%num_jac_elem(phase_ids(i_phase))
Expand Down Expand Up @@ -319,8 +319,7 @@ subroutine initialize(this, chem_spec_data, aero_rep, n_cells)
end if

! Get the phase ids for this aerosol phase
phase_ids = aero_rep(i_aero_rep)%val%phase_ids(phase_name)

phase_ids = aero_rep(i_aero_rep)%val%phase_ids(phase_name,is_at_surface=.true.)
! Add the species concentration and activity coefficient ids to
! the condensed data, and set the number of Jacobian elements for
! the aerosol representations and the locations of the real data
Expand Down
15 changes: 15 additions & 0 deletions test/unit_aero_rep_data/test_aero_rep_single_particle.F90
Original file line number Diff line number Diff line change
Expand Up @@ -192,6 +192,21 @@ subroutine test_config_read()
call assert(603635677, aero_rep%phase_state_size(layer=2,phase=2) .eq. 2)
call assert(768528274, aero_rep%phase_state_size(layer=3,phase=1) .eq. 3)

! check boolean surface array
call assert(438901931, aero_rep%aero_phase_is_at_surface(1) .eqv. .false.)
call assert(545268641, aero_rep%aero_phase_is_at_surface(2) .eqv. .false.)
call assert(450505920, aero_rep%aero_phase_is_at_surface(3) .eqv. .false.)
call assert(160921440, aero_rep%aero_phase_is_at_surface(4) .eqv. .true.)
call assert(013254644, aero_rep%aero_phase_is_at_surface(5) .eqv. .false.)
call assert(691645657, aero_rep%aero_phase_is_at_surface(6) .eqv. .false.)
call assert(916896739, aero_rep%aero_phase_is_at_surface(7) .eqv. .false.)
call assert(668436322, aero_rep%aero_phase_is_at_surface(8) .eqv. .true.)
call assert(952270724, aero_rep%aero_phase_is_at_surface(9) .eqv. .false.)
call assert(410924438, aero_rep%aero_phase_is_at_surface(10) .eqv. .false.)
call assert(266324037, aero_rep%aero_phase_is_at_surface(11) .eqv. .false.)
call assert(008760891, aero_rep%aero_phase_is_at_surface(12) .eqv. .true.)

call assert(768528274, aero_rep%phase_state_size(layer=3,phase=1) .eq. 3)
! test num_phase_instances funtion
phase_name_test = "bread"
num_bread = 2
Expand Down