diff --git a/.gitignore b/.gitignore index 9960679a0..2ab95fc72 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,5 @@ +**/*.d +**/*.dSym **/.DS_Store **/*.pyc CMakeCache.txt diff --git a/src/aero_rep_data.F90 b/src/aero_rep_data.F90 index 867480f8e..160d758b4 100644 --- a/src/aero_rep_data.F90 +++ b/src/aero_rep_data.F90 @@ -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 @@ -489,7 +493,7 @@ 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(:) @@ -497,18 +501,42 @@ function phase_ids(this, phase_name) 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 diff --git a/src/aero_reps/aero_rep_modal_binned_mass.F90 b/src/aero_reps/aero_rep_modal_binned_mass.F90 index 61feba003..7ae58d7c3 100644 --- a/src/aero_reps/aero_rep_modal_binned_mass.F90 +++ b/src/aero_reps/aero_rep_modal_binned_mass.F90 @@ -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 @@ -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 diff --git a/src/aero_reps/aero_rep_single_particle.F90 b/src/aero_reps/aero_rep_single_particle.F90 index 7c71093be..b76074a0a 100644 --- a/src/aero_reps/aero_rep_single_particle.F90 +++ b/src/aero_reps/aero_rep_single_particle.F90 @@ -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) @@ -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 diff --git a/src/aero_reps/aero_rep_single_particle.c b/src/aero_reps/aero_rep_single_particle.c index 94b5438f6..84abbe012 100644 --- a/src/aero_reps/aero_rep_single_particle.c +++ b/src/aero_reps/aero_rep_single_particle.c @@ -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 -"); 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), diff --git a/src/rxns/rxn_HL_phase_transfer.F90 b/src/rxns/rxn_HL_phase_transfer.F90 index 3841db99c..b461e0fe2 100644 --- a/src/rxns/rxn_HL_phase_transfer.F90 +++ b/src/rxns/rxn_HL_phase_transfer.F90 @@ -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)) @@ -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 diff --git a/src/rxns/rxn_SIMPOL_phase_transfer.F90 b/src/rxns/rxn_SIMPOL_phase_transfer.F90 index c37e27a54..110279311 100644 --- a/src/rxns/rxn_SIMPOL_phase_transfer.F90 +++ b/src/rxns/rxn_SIMPOL_phase_transfer.F90 @@ -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)) @@ -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 diff --git a/test/unit_aero_rep_data/test_aero_rep_single_particle.F90 b/test/unit_aero_rep_data/test_aero_rep_single_particle.F90 index 44e05fd45..f9d6d8b5d 100644 --- a/test/unit_aero_rep_data/test_aero_rep_single_particle.F90 +++ b/test/unit_aero_rep_data/test_aero_rep_single_particle.F90 @@ -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