File ProcessWetDepInterface_Mod.F90¶
File List > process > wetdep > ProcessWetDepInterface_Mod.F90
Go to the documentation of this file
module processwetdepinterface_mod
! Core CATChem infrastructure
use precision_mod, only: fp
use processinterface_mod, only: processinterface, columnprocessinterface
use statemanager_mod, only: statemanagertype
use gridmanager_mod, only: gridmanagertype
use error_mod, only: cc_success, cc_failure, cc_error, cc_warning, errormanagertype
use diagnosticmanager_mod, only: diagnosticmanagertype
use diagnosticinterface_mod, only: diagnosticregistrytype, diagnosticfieldtype, diagnosticdatatype
use virtualcolumn_mod, only: virtualcolumntype, virtualmettype
use constants, only: g0, airmw ! Gravitational acceleration for tendency physics and air molecular weight for unit conversion
! Core utilities (leverage existing infrastructure)
use configmanager_mod, only: configmanagertype
use chemstate_mod, only: chemstatetype
use metstate_mod, only: metstatetype
! Common utilities - unified configuration
use wetdepcommon_mod, only: wetdepprocessconfig
! Scheme modules
use wetdepscheme_jacob_mod, only: compute_jacob
implicit none
private
public :: processwetdepinterface
type, extends(columnprocessinterface) :: processwetdepinterface
private
! Unified process configuration (bridges ConfigManager to process-specific config)
type(WetDepProcessConfig), public :: process_config
! Process utilities (leverage core infrastructure)
type(ChemStateType), pointer :: chem_state => null()
type(MetStateType), pointer :: met_state => null()
! Note: state_manager pointer removed as it was never used
! Process-specific diagnostic indices (base class handles storage)
integer :: diag_wetdep_mass_per_species_per_level_idx = -1
integer :: diag_wetdep_flux_per_species_per_level_idx = -1
! Column-level diagnostic storage for interfacing with DiagManager
! These are allocated per-column during processing and can be used to
! accumulate data for DiagManager updates
real(fp), allocatable :: column_wetdep_mass_per_species_per_level(:,:) ! 2D: levels x species - per column
real(fp), allocatable :: column_wetdep_flux_per_species_per_level(:,:) ! 2D: levels x species - per column
! Scheme-specific diagnostic storage (shared across all schemes that use them)
contains
! Required ProcessInterface implementations
procedure :: init => process_init
procedure :: run => process_run
procedure :: finalize => process_finalize
procedure :: parse_process_config => parse_wetdep_config
! Required ColumnProcessInterface implementations
procedure :: init_column_processing => init_column_processing
procedure :: run_column => run_column
procedure :: finalize_column_processing => finalize_column_processing
! ProcessInterface capability registration
procedure :: get_required_met_fields => get_required_met_fields
procedure :: get_required_diagnostic_fields => get_required_diagnostic_fields
! Public testing interface for scheme manipulation
procedure :: set_scheme => set_wetdep_scheme
procedure :: get_scheme => get_wetdep_scheme
! Process-specific implementations (column virtualization)
procedure, private :: run_active_scheme_column
procedure, private :: run_jacob_scheme_column
! Diagnostic procedures (override base class method)
procedure :: register_diagnostics => register_and_allocate_diagnostics
procedure, private :: register_and_allocate_diagnostics
procedure, private :: calculate_and_update_diagnostics
end type processwetdepinterface
contains
subroutine process_init(this, container, rc)
class(ProcessWetDepInterface), intent(inout) :: this
type(StateManagerType), intent(inout) :: container
integer, intent(out) :: rc
type(ErrorManagerType), pointer :: error_manager
rc = cc_success
! Get error manager
error_manager => container%get_error_manager()
! Initialize column processing capabilities
call this%init_column_processing(container, rc)
if (rc /= cc_success) return
! Set process-specific name and info
this%name = 'wetdep'
this%version = '1.0.0'
this%description = 'Process for computing wet deposition of gas and aerosol species'
! Parse process-specific configuration using unified approach
call this%parse_process_config(container, error_manager, rc)
if (rc /= cc_success) then
return
end if
! Get state pointers from container (needed for species loading)
this%chem_state => container%get_chem_state_ptr()
this%met_state => container%get_met_state_ptr()
! Load species from ChemState based on is_wetdep property
call this%process_config%load_species_from_chem_state(this%chem_state, error_manager)
! Note: Error handling managed by error_manager internally
! Map diagnostic species names to indices in the species array
call this%process_config%map_diagnostic_species_indices(error_manager)
! Validate the configuration with StateManager
call this%process_config%validate(container, error_manager)
! Note: validate doesn't return rc, but error_manager tracks errors
! Register diagnostics for this process (only if diagnostics enabled)
call this%register_diagnostics(container, rc)
if (rc /= cc_success) then
return
end if
! Mark process as initialized and active
call this%activate()
end subroutine process_init
subroutine process_run(this, container, rc)
class(ProcessWetDepInterface), intent(inout) :: this
type(StateManagerType), intent(inout) :: container
integer, intent(out) :: rc
rc = cc_success
! Check if process is active
if (.not. this%process_config%is_active) then
return
end if
! For ColumnProcessInterface processes, the ProcessManager handles column iteration
! and calls run_column() for each virtual column. This method is mainly a placeholder
! for any global 3D operations that need to happen before/after column processing.
! Currently no global 3D operations needed for wetdep process
! All processing happens in run_column() method
end subroutine process_run
subroutine process_finalize(this, rc)
class(ProcessWetDepInterface), intent(inout) :: this
integer, intent(out) :: rc
rc = cc_success
! Finalize column processing
call this%finalize_column_processing(rc)
if (rc /= cc_success) return
! Deallocate diagnostic class members
if (allocated(this%column_wetdep_mass_per_species_per_level)) deallocate(this%column_wetdep_mass_per_species_per_level)
if (allocated(this%column_wetdep_flux_per_species_per_level)) deallocate(this%column_wetdep_flux_per_species_per_level)
! Deallocate scheme-specific diagnostic fields (only deallocate unique fields once)
! Finalize unified configuration
call this%process_config%finalize()
end subroutine process_finalize
subroutine parse_wetdep_config(this, state_manager, error_manager, rc)
class(ProcessWetDepInterface), intent(inout) :: this
type(StateManagerType), intent(inout) :: state_manager ! Changed to inout for function call
type(ErrorManagerType), intent(inout) :: error_manager
integer, intent(out) :: rc
type(ConfigManagerType), pointer :: config_manager
rc = cc_success
! Get configuration manager from state manager
config_manager => state_manager%get_config_ptr()
if (.not. associated(config_manager)) then
call error_manager%report_error(1003, &
'ConfigManager not available from StateManager', rc)
return
end if
! Use the unified configuration loader from WetDepCommon_Mod
! This handles the complexity of parsing hierarchical YAML into process-specific types
call this%process_config%load_from_config(config_manager, error_manager)
! Note: Error handling managed by error_manager internally
! Process is now configured - the unified config contains all scheme-specific settings
end subroutine parse_wetdep_config
!========================================================================
! Column Processing Interface Implementation
!========================================================================
subroutine init_column_processing(this, container, rc)
class(ProcessWetDepInterface), intent(inout) :: this
type(StateManagerType), intent(inout) :: container
integer, intent(out) :: rc
rc = cc_success
! Enable column processing and set batch size for optimal performance
call this%enable_column_processing()
call this%set_column_batch_size(50) ! Process 50 columns at a time
! Any process-specific column processing setup would go here
! For wetdep, no additional setup is needed
end subroutine init_column_processing
subroutine run_column(this, column, container, rc)
class(ProcessWetDepInterface), intent(inout) :: this
type(VirtualColumnType), intent(inout) :: column
type(StateManagerType), intent(inout) :: container
integer, intent(out) :: rc
rc = cc_success
! Check if process is active
if (.not. this%process_config%is_active) return
! Delegate to the active scheme for column processing
call this%run_active_scheme_column(column, rc)
! Calculate and update diagnostics if enabled
if (this%process_config%wetdep_config%diagnostics .and. rc == cc_success) then
call this%calculate_and_update_diagnostics(column, container, rc)
end if
end subroutine run_column
subroutine finalize_column_processing(this, rc)
class(ProcessWetDepInterface), intent(inout) :: this
integer, intent(out) :: rc
rc = cc_success
! Clean up column processing
call this%disable_column_processing()
! Any process-specific cleanup would go here
end subroutine finalize_column_processing
subroutine run_active_scheme_column(this, column, rc)
class(ProcessWetDepInterface), intent(inout) :: this
type(VirtualColumnType), intent(inout) :: column
integer, intent(out) :: rc
rc = cc_success
! Delegate to appropriate scheme using unified config
select case (trim(this%process_config%wetdep_config%scheme))
case ('jacob')
call this%run_jacob_scheme_column(column, rc)
case default
rc = cc_failure
end select
end subroutine run_active_scheme_column
subroutine run_jacob_scheme_column(this, column, rc)
class(ProcessWetDepInterface), intent(inout) :: this
type(VirtualColumnType), intent(inout) :: column
integer, intent(out) :: rc
! Local variables for scheme calculation
type(VirtualMetType), pointer :: met => null() ! Pointer to meteorological data
! Meteorological fields
real(fp), allocatable :: airden_dry(:)
real(fp), allocatable :: mairden(:)
real(fp), allocatable :: pedge(:)
real(fp), allocatable :: pfilsan(:)
real(fp), allocatable :: pfllsan(:)
real(fp), allocatable :: reevapls(:)
real(fp), allocatable :: t(:)
real(fp), allocatable :: tstep(:)
! Species properties
logical, allocatable :: species_is_aerosol(:)
real(fp), allocatable :: species_henry_cr(:)
real(fp), allocatable :: species_henry_k0(:)
real(fp), allocatable :: species_henry_pKa(:)
real(fp), allocatable :: species_wd_retfactor(:)
logical, allocatable :: species_wd_LiqAndGas(:)
real(fp), allocatable :: species_wd_convfacI2G(:)
real(fp), allocatable :: species_wd_rainouteff(:,:)
real(fp), allocatable :: species_radius(:)
real(fp), allocatable :: species_mw_g(:)
real(fp), allocatable :: species_conc(:,:)
real(fp), allocatable :: species_tendencies(:,:)
integer :: n_species, n_levels, n_chem, n_emis, i, k
integer, allocatable :: species_indices(:)
rc = cc_success
! Get dimensions from virtual column
call column%get_dimensions(n_levels, n_chem, n_emis) ! Full column processing
! Get wetdep species information from process configuration
n_species = this%process_config%wetdep_config%n_species
if (n_species <= 0) then
return
end if
! Get species indices directly from configuration (pre-computed)
allocate(species_indices(n_species))
species_indices(1:n_species) = this%process_config%wetdep_config%species_indices(1:n_species)
! Allocate arrays
allocate(species_conc(n_levels, n_species))
allocate(species_tendencies(n_levels, n_species))
! Allocate meteorological field arrays based on field type and process configuration
allocate(airden_dry(n_levels)) ! Atmospheric field - always n_levels
allocate(mairden(n_levels)) ! Atmospheric field - always n_levels
allocate(pedge(n_levels+1)) ! Edge field - always n_levels+1
allocate(pfilsan(n_levels+1)) ! Edge field - always n_levels+1
allocate(pfllsan(n_levels+1)) ! Edge field - always n_levels+1
allocate(reevapls(n_levels)) ! Atmospheric field - always n_levels
allocate(t(n_levels)) ! Atmospheric field - always n_levels
allocate(tstep(1)) ! Special timestep field - scalar
allocate(species_is_aerosol(n_species))
allocate(species_henry_cr(n_species))
allocate(species_henry_k0(n_species))
allocate(species_henry_pka(n_species))
allocate(species_wd_retfactor(n_species))
allocate(species_wd_liqandgas(n_species))
allocate(species_wd_convfaci2g(n_species))
allocate(species_wd_rainouteff(n_species, 3))
allocate(species_radius(n_species))
allocate(species_mw_g(n_species))
species_tendencies = 0.0_fp
! Get meteorological data pointer from virtual column (VirtualMet pattern)
met => column%get_met()
! Now allocate categorical fields using the met pointer dimensions
! Extract required fields from met pointer based on field type and processing mode
airden_dry(1:n_levels) = met%AIRDEN_DRY(1:n_levels) ! Atmospheric field - always n_levels
mairden(1:n_levels) = met%MAIRDEN(1:n_levels) ! Atmospheric field - always n_levels
pedge(1:n_levels+1) = met%PEDGE(1:n_levels+1) ! Edge field - always n_levels+1
pfilsan(1:n_levels+1) = met%PFILSAN(1:n_levels+1) ! Edge field - always n_levels+1
pfllsan(1:n_levels+1) = met%PFLLSAN(1:n_levels+1) ! Edge field - always n_levels+1
reevapls(1:n_levels) = met%REEVAPLS(1:n_levels) ! Atmospheric field - always n_levels
t(1:n_levels) = met%T(1:n_levels) ! Atmospheric field - always n_levels
tstep(1) = this%get_timestep() ! Special timestep field - retrieved from ProcessInterface
! Get species concentrations from virtual column
! Full column processing - get concentrations for all levels
do k = 1, n_levels
do i = 1, n_species
species_conc(k, i) = column%get_chem_field(species_indices(i), k)
end do
end do
! Get species properties from configuration (pre-loaded during initialization)
! Use species properties from process configuration
species_is_aerosol(1:n_species) = this%process_config%wetdep_config%species_is_aerosol(1:n_species)
! Use species properties from process configuration
species_henry_cr(1:n_species) = this%process_config%wetdep_config%species_henry_cr(1:n_species)
! Use species properties from process configuration
species_henry_k0(1:n_species) = this%process_config%wetdep_config%species_henry_k0(1:n_species)
! Use species properties from process configuration
species_henry_pka(1:n_species) = this%process_config%wetdep_config%species_henry_pKa(1:n_species)
! Use species properties from process configuration
species_wd_retfactor(1:n_species) = this%process_config%wetdep_config%species_wd_retfactor(1:n_species)
! Use species properties from process configuration
species_wd_liqandgas(1:n_species) = this%process_config%wetdep_config%species_wd_LiqAndGas(1:n_species)
! Use species properties from process configuration
species_wd_convfaci2g(1:n_species) = this%process_config%wetdep_config%species_wd_convfacI2G(1:n_species)
! Use species properties from process configuration
species_wd_rainouteff(1:n_species, :) = this%process_config%wetdep_config%species_wd_rainouteff(1:n_species, :)
! Use species properties from process configuration
species_radius(1:n_species) = this%process_config%wetdep_config%species_radius(1:n_species)
! Use species properties from process configuration
species_mw_g(1:n_species) = this%process_config%wetdep_config%species_mw_g(1:n_species)
! Call the science scheme with optional diagnostic parameters
! Note: jacob uses the following diagnostic fields (if diagnostics enabled):
! - wetdep_mass_per_species_per_level (Wet deposition mass loss per species per level)
! - wetdep_flux_per_species_per_level (Wet deposition flux per species per level)
if (this%process_config%wetdep_config%diagnostics) then
! Call with diagnostic outputs enabled
call compute_jacob( &
n_levels, &
n_species, &
this%process_config%jacob_config, &
airden_dry, &
mairden, &
pedge, &
pfilsan, &
pfllsan, &
reevapls, &
t, &
tstep(1) , &
species_is_aerosol, &
this%process_config%wetdep_config%species_names, &
species_henry_cr, &
species_henry_k0, &
species_henry_pka, &
species_wd_retfactor, &
species_wd_liqandgas, &
species_wd_convfaci2g, &
species_wd_rainouteff, &
species_radius, &
species_mw_g, &
species_conc, &
species_tendencies, &
this%column_wetdep_mass_per_species_per_level, &
this%column_wetdep_flux_per_species_per_level, &
this%process_config%wetdep_config%diagnostic_species_id )
else
! Call without diagnostic outputs (optional parameters not passed)
call compute_jacob( &
n_levels, &
n_species, &
this%process_config%jacob_config, &
airden_dry, &
mairden, &
pedge, &
pfilsan, &
pfllsan, &
reevapls, &
t, &
tstep(1) , &
species_is_aerosol, &
this%process_config%wetdep_config%species_names, &
species_henry_cr, &
species_henry_k0, &
species_henry_pka, &
species_wd_retfactor, &
species_wd_liqandgas, &
species_wd_convfaci2g, &
species_wd_rainouteff, &
species_radius, &
species_mw_g, &
species_conc, &
species_tendencies &
)
end if
! Apply tendencies back to virtual column based on tendency_mode
! Full column processing - apply tendencies to all levels
do k = 1, n_levels
do i = 1, n_species
! Replacement tendency: new_conc = tendency (tendency is the new value)
call column%set_chem_field(k, species_indices(i), &
species_tendencies(k, i))
end do
end do
end subroutine run_jacob_scheme_column
function get_required_met_fields(this) result(field_names)
class(ProcessWetDepInterface), intent(in) :: this
character(len=32), allocatable :: field_names(:)
character(len=32), allocatable :: scheme_fields(:)
character(len=32), allocatable :: process_fields(:)
character(len=32), allocatable :: unique_fields(:)
integer :: total_fields, scheme_count, process_count, i, j, unique_count
logical :: is_duplicate
! No process-level required fields
process_count = 0
allocate(process_fields(0))
! Get scheme-specific fields based on selected scheme
select case (trim(this%process_config%wetdep_config%scheme))
case ('jacob')
scheme_count = 8
allocate(scheme_fields(scheme_count))
scheme_fields(1) = 'T'
scheme_fields(2) = 'TSTEP'
scheme_fields(3) = 'AIRDEN_DRY'
scheme_fields(4) = 'MAIRDEN'
scheme_fields(5) = 'PFLLSAN'
scheme_fields(6) = 'PFILSAN'
scheme_fields(7) = 'PEDGE'
scheme_fields(8) = 'REEVAPLS'
case default
scheme_count = 0
allocate(scheme_fields(0))
end select
! Combine process-level and scheme-specific fields and remove duplicates
! First estimate maximum possible size (without duplicates)
total_fields = process_count + scheme_count
allocate(unique_fields(total_fields))
unique_count = 0
! Add process-level fields first
do i = 1, process_count
unique_count = unique_count + 1
unique_fields(unique_count) = process_fields(i)
end do
! Add scheme-specific fields (check for duplicates)
do i = 1, scheme_count
is_duplicate = .false.
do j = 1, unique_count
if (trim(scheme_fields(i)) == trim(unique_fields(j))) then
is_duplicate = .true.
exit
end if
end do
if (.not. is_duplicate) then
unique_count = unique_count + 1
unique_fields(unique_count) = scheme_fields(i)
end if
end do
! Allocate final result array with exact size
allocate(field_names(unique_count))
field_names(1:unique_count) = unique_fields(1:unique_count)
! Clean up temporary arrays
if (allocated(unique_fields)) deallocate(unique_fields)
if (allocated(process_fields)) deallocate(process_fields)
if (allocated(scheme_fields)) deallocate(scheme_fields)
end function get_required_met_fields
function get_required_diagnostic_fields(this) result(field_names)
class(ProcessWetDepInterface), intent(in) :: this
character(len=64), allocatable :: field_names(:)
allocate(field_names(2))
field_names(1) = 'wetdep_mass_per_species_per_level'
field_names(2) = 'wetdep_flux_per_species_per_level'
end function get_required_diagnostic_fields
subroutine register_and_allocate_diagnostics(this, container, rc)
use diagnosticinterface_mod, only: diagnosticregistrytype, diag_real_3d
class(ProcessWetDepInterface), intent(inout) :: this
type(StateManagerType), intent(inout) :: container
integer, intent(out) :: rc
type(DiagnosticManagerType), pointer :: diag_mgr
type(DiagnosticRegistryType), pointer :: registry
type(GridManagerType), pointer :: grid_mgr
character(len=256) :: field_name ! For constructing species-specific field names
integer :: i ! Loop variable for diagnostic species
integer :: nx, ny, nz
integer :: dims_2d(2)
integer :: dims_3d_levels(3)
rc = cc_success
! Only register diagnostics if enabled in config
if (.not. this%process_config%wetdep_config%diagnostics) then
return
endif
! Get managers
diag_mgr => container%get_diagnostic_manager()
grid_mgr => container%get_grid_manager()
! Register this process with diagnostic manager (only once per process)
call diag_mgr%register_process('wetdep', rc)
if (rc /= cc_success) return
! Get the process registry for registering individual diagnostics
call diag_mgr%get_process_registry('wetdep', registry, rc)
if (rc /= cc_success) return
! Get grid dimensions
call grid_mgr%get_shape(nx, ny, nz)
dims_2d = [nx, ny]
dims_3d_levels = [nx, ny, nz]
! Register wetdep_mass_per_species_per_level
! Register individual 3D fields for each diagnostic species (level + species diagnostics)
if (this%process_config%wetdep_config%n_diagnostic_species > 0) then
do i = 1, this%process_config%wetdep_config%n_diagnostic_species
write(field_name, '(A,A,A)') 'wetdep_mass_', &
trim(this%process_config%wetdep_config%diagnostic_species(i))
call this%register_diagnostic_field(registry, trim(field_name), &
'Wet deposition mass loss per species per level', &
'kg/m2', diag_real_3d, &
'wetdep', dims_3d_levels, rc=rc)
if (rc /= cc_success) return
end do
end if
if (rc /= cc_success) return
! Register wetdep_flux_per_species_per_level
! Register individual 3D fields for each diagnostic species (level + species diagnostics)
if (this%process_config%wetdep_config%n_diagnostic_species > 0) then
do i = 1, this%process_config%wetdep_config%n_diagnostic_species
write(field_name, '(A,A,A)') 'wetdep_flux_', &
trim(this%process_config%wetdep_config%diagnostic_species(i))
call this%register_diagnostic_field(registry, trim(field_name), &
'Wet deposition flux per species per level', &
'kg/m2/s', diag_real_3d, &
'wetdep', dims_3d_levels, rc=rc)
if (rc /= cc_success) return
end do
end if
if (rc /= cc_success) return
! Get selected scheme(s)
! Register scheme-specific diagnostics based on selected scheme
select case (trim(this%process_config%wetdep_config%scheme))
case ('jacob')
! Register jacob-specific diagnostics
case default
! Unknown scheme - only register common diagnostics
! (already done above)
end select
! Now allocate diagnostic class members after successful registration
! First, deallocate if already allocated (for scheme switching)
if (allocated(this%column_wetdep_mass_per_species_per_level)) deallocate(this%column_wetdep_mass_per_species_per_level)
if (allocated(this%column_wetdep_flux_per_species_per_level)) deallocate(this%column_wetdep_flux_per_species_per_level)
! Allocate and initialize scheme-specific diagnostic fields based on selected scheme
! For non-gas/aero differentiated process, allocate diagnostics normally
! Allocate common diagnostic fields (used by all schemes)
! 2D diagnostic: levels x diagnostic_species
if (nz > 0 .and. this%process_config%wetdep_config%n_diagnostic_species > 0) then
allocate(this%column_wetdep_mass_per_species_per_level(nz, this%process_config%wetdep_config%n_diagnostic_species))
end if
if (allocated(this%column_wetdep_mass_per_species_per_level)) this%column_wetdep_mass_per_species_per_level = 0.0_fp
! 2D diagnostic: levels x diagnostic_species
if (nz > 0 .and. this%process_config%wetdep_config%n_diagnostic_species > 0) then
allocate(this%column_wetdep_flux_per_species_per_level(nz, this%process_config%wetdep_config%n_diagnostic_species))
end if
if (allocated(this%column_wetdep_flux_per_species_per_level)) this%column_wetdep_flux_per_species_per_level = 0.0_fp
! Allocate scheme-specific diagnostics
select case (trim(this%process_config%wetdep_config%scheme))
case ('jacob')
! Scheme-specific diagnostics for jacob
case default
! No scheme-specific diagnostics for unknown schemes
end select
end subroutine register_and_allocate_diagnostics
subroutine calculate_and_update_diagnostics(this, column, container, rc)
class(ProcessWetDepInterface), intent(inout) :: this
type(VirtualColumnType), intent(in) :: column
type(StateManagerType), intent(inout) :: container
integer, intent(out) :: rc
integer :: i_col, j_col ! Column grid position
integer :: i ! Loop variable for diagnostic species
character(len=256) :: field_name ! For constructing species-specific field names
rc = cc_success
! Skip if diagnostics not enabled
if (.not. this%process_config%wetdep_config%diagnostics) return
! Get column grid position (x, y indices)
call column%get_position(i_col, j_col)
! Update common diagnostic fields (used by all schemes)
! Update individual 3D fields for each diagnostic species (level + species diagnostics)
if (this%process_config%wetdep_config%n_diagnostic_species > 0) then
do i = 1, this%process_config%wetdep_config%n_diagnostic_species
write(field_name, '(A,A,A)') 'wetdep_mass_', &
trim(this%process_config%wetdep_config%diagnostic_species(i))
call this%update_1d_diagnostic_column(trim(field_name), &
this%column_wetdep_mass_per_species_per_level(:,i), &
i_col, j_col, container, rc)
if (rc /= cc_success) return
end do
end if
! Update individual 3D fields for each diagnostic species (level + species diagnostics)
if (this%process_config%wetdep_config%n_diagnostic_species > 0) then
do i = 1, this%process_config%wetdep_config%n_diagnostic_species
write(field_name, '(A,A,A)') 'wetdep_flux_', &
trim(this%process_config%wetdep_config%diagnostic_species(i))
call this%update_1d_diagnostic_column(trim(field_name), &
this%column_wetdep_flux_per_species_per_level(:,i), &
i_col, j_col, container, rc)
if (rc /= cc_success) return
end do
end if
! Update scheme-specific diagnostic fields based on active scheme
select case (trim(this%process_config%wetdep_config%scheme))
case ("jacob")
! Scheme-specific diagnostics for jacob
end select
end subroutine calculate_and_update_diagnostics
subroutine set_wetdep_scheme(this, scheme_name)
class(ProcessWetDepInterface), intent(inout) :: this
character(len=*), intent(in) :: scheme_name
this%process_config%wetdep_config%scheme = trim(scheme_name)
end subroutine set_wetdep_scheme
function get_wetdep_scheme(this) result(scheme_name)
class(ProcessWetDepInterface), intent(in) :: this
character(len=64) :: scheme_name
scheme_name = trim(this%process_config%wetdep_config%scheme)
end function get_wetdep_scheme
end module processwetdepinterface_mod