From 4ec7a83824b56487a893389b798a2f761af04274 Mon Sep 17 00:00:00 2001 From: Nicole Jeffery Date: Wed, 9 Nov 2022 10:57:09 -0600 Subject: [PATCH 1/5] Adds a 1D forcing testcase with BGC (ISPOL) Atmospheric, ocean and biogeochemical data from the 2004 Ice Station Polarstern (ISPOL) Weddell Sea (67.9S, 54W) experiment from June 16, 2004 to December 31, 2004. Core 2 from the ISPOL location fills out the remainder of the year. A uniform_1D initial condition was added for flexible initialization. A new testcase - single_cell_ispol - was added to MPAS-Dev/MPAS-Seaice_standalone_framework to verify this forcing and initializtion. BFB --- .../namelist_definition_mpassi.xml | 6 +- components/mpas-seaice/src/Registry.xml | 163 +++- .../src/shared/mpas_seaice_constants.F | 16 + .../src/shared/mpas_seaice_forcing.F | 816 +++++++++++++++++- .../src/shared/mpas_seaice_initialize.F | 124 +++ 5 files changed, 1120 insertions(+), 5 deletions(-) diff --git a/components/mpas-seaice/bld/namelist_files/namelist_definition_mpassi.xml b/components/mpas-seaice/bld/namelist_files/namelist_definition_mpassi.xml index 3b50dd9fd798..9d25a90af84f 100644 --- a/components/mpas-seaice/bld/namelist_files/namelist_definition_mpassi.xml +++ b/components/mpas-seaice/bld/namelist_files/namelist_definition_mpassi.xml @@ -319,7 +319,7 @@ Default: Defined in namelist_defaults.xml category="initialize" group="initialize"> Initial condition type for sea ice state. -Valid values: 'restart', 'uniform', 'circle', 'square' or 'uniform_interior' +Valid values: 'restart', 'uniform', 'circle', 'square', 'uniform_interior' or 'uniform_1D' Default: Defined in namelist_defaults.xml @@ -461,7 +461,7 @@ Default: Defined in namelist_defaults.xml category="forcing" group="forcing"> Atmospheric forcing type. -Valid values: 'CORE' +Valid values: 'CORE' or 'ISPOL' Default: Defined in namelist_defaults.xml @@ -501,7 +501,7 @@ Default: Defined in namelist_defaults.xml category="forcing" group="forcing"> Sea surface temperature ocean forcing type. -Valid values: 'ncar' +Valid values: 'ncar' or 'ISPOL' Default: Defined in namelist_defaults.xml diff --git a/components/mpas-seaice/src/Registry.xml b/components/mpas-seaice/src/Registry.xml index fa2be3495b76..e5412e7a2f8c 100644 --- a/components/mpas-seaice/src/Registry.xml +++ b/components/mpas-seaice/src/Registry.xml @@ -450,7 +450,7 @@ /> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \brief Initialize the forcing objects +!> \author Nicole Jeffery, LANL +!> \date Nov, 2022 +!> \details +!> This routine calls the MPAS_forcing module subroutines that initializes +!> a 1D forcing dataset. The data corresponds to the Weddell Sea (67.9S, 54W) +!> from June 16, 2004 to December 31, 2004, and is from the 2004 +!> Ice Station Polarstern (ISPOL) field experiment. +! +!----------------------------------------------------------------------- + + subroutine init_atmospheric_forcing_ISPOL(domain) + + type(domain_type) :: domain + + real(kind=RKIND), pointer :: & + config_dt + + character(len=strKIND), pointer :: & + config_forcing_start_time, & + config_forcing_cycle_start, & + config_forcing_cycle_duration + + logical, pointer :: & + config_do_restart + + character(len=strKIND) :: & + forcingIntervalSixHourly, & + forcingReferenceTimeSixHourly, & + forcingIntervalDaily, & + forcingReferenceTimeDaily + + ! get atmospheric forcing configuration options + call MPAS_pool_get_config(domain % configs, "config_forcing_start_time", config_forcing_start_time) + call MPAS_pool_get_config(domain % configs, "config_dt", config_dt) + call MPAS_pool_get_config(domain % configs, "config_forcing_cycle_start", config_forcing_cycle_start) + call MPAS_pool_get_config(domain % configs, "config_forcing_cycle_duration", config_forcing_cycle_duration) + call MPAS_pool_get_config(domain % configs, "config_do_restart", config_do_restart) + + ! create the six hourly forcing group + call MPAS_forcing_init_group(& + seaiceForcingGroups, & + "seaice_atmospheric_forcing_sixhrly", & + domain, & + config_forcing_start_time, & + config_forcing_cycle_start, & + config_forcing_cycle_duration, & + config_do_restart, & + .false.) + + forcingIntervalSixHourly = "06:00:00" + forcingReferenceTimeSixHourly = "2004-01-01_00:00:00" + + call MPAS_forcing_init_field(& + domain % streamManager, & + seaiceForcingGroups, & + "seaice_atmospheric_forcing_sixhrly", & + "shortwaveDown1D", & + "ISPOLSixHourlyForcing", & + "1D_atmos_forcing", & + "shortwaveDown1D", & + "linear", & + forcingReferenceTimeSixHourly, & + forcingIntervalSixHourly, & + "next") + + call MPAS_forcing_init_field(& + domain % streamManager, & + seaiceForcingGroups, & + "seaice_atmospheric_forcing_sixhrly", & + "longwaveDown1D", & + "ISPOLSixHourlyForcing", & + "1D_atmos_forcing", & + "longwaveDown1D", & + "linear", & + forcingReferenceTimeSixHourly, & + forcingIntervalSixHourly, & + "next") + + call MPAS_forcing_init_field_data(& + seaiceForcingGroups, & + "seaice_atmospheric_forcing_sixhrly", & + domain % streamManager, & + config_do_restart, & + .false.) + + ! create the daily forcing group + call MPAS_forcing_init_group(& + seaiceForcingGroups, & + "seaice_atmospheric_forcing_daily", & + domain, & + config_forcing_start_time, & + config_forcing_cycle_start, & + config_forcing_cycle_duration, & + config_do_restart) + + forcingIntervalDaily = "00-00-01_00:00:00" + forcingReferenceTimeDaily = "2004-01-01_00:00:00" + + call MPAS_forcing_init_field(& + domain % streamManager, & + seaiceForcingGroups, & + "seaice_atmospheric_forcing_daily", & + "airTemperature1D", & + "ISPOLDailyForcing", & + "1D_atmos_forcing", & + "airTemperature1D", & + "linear", & + forcingReferenceTimeDaily, & + forcingIntervalDaily, & + "next") + + call MPAS_forcing_init_field(& + domain % streamManager, & + seaiceForcingGroups, & + "seaice_atmospheric_forcing_daily", & + "airSpecificHumidity1D", & + "ISPOLDailyForcing", & + "1D_atmos_forcing", & + "airSpecificHumidity1D", & + "linear", & + forcingReferenceTimeDaily, & + forcingIntervalDaily, & + "next") + + call MPAS_forcing_init_field(& + domain % streamManager, & + seaiceForcingGroups, & + "seaice_atmospheric_forcing_daily", & + "uAirVelocity1D", & + "ISPOLDailyForcing", & + "1D_atmos_forcing", & + "uAirVelocity1D", & + "linear", & + forcingReferenceTimeDaily, & + forcingIntervalDaily, & + "next") + + call MPAS_forcing_init_field(& + domain % streamManager, & + seaiceForcingGroups, & + "seaice_atmospheric_forcing_daily", & + "vAirVelocity1D", & + "ISPOLDailyForcing", & + "1D_atmos_forcing", & + "vAirVelocity1D", & + "linear", & + forcingReferenceTimeDaily, & + forcingIntervalDaily, & + "next") + + call MPAS_forcing_init_field(& + domain % streamManager, & + seaiceForcingGroups, & + "seaice_atmospheric_forcing_daily", & + "rainfallRate1D", & + "ISPOLDailyForcing", & + "1D_atmos_forcing", & + "rainfallRate1D", & + "linear", & + forcingReferenceTimeDaily, & + forcingIntervalDaily, & + "next") + + call MPAS_forcing_init_field_data(& + seaiceForcingGroups, & + "seaice_atmospheric_forcing_daily", & + domain % streamManager, & + config_do_restart, & + .false.) + + end subroutine init_atmospheric_forcing_ISPOL + !||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||| ! ! init_atmospheric_forcing_hourly_velocities @@ -501,6 +680,20 @@ subroutine atmospheric_forcing(& streamManager, & config_dt) + else if (trim(config_atmospheric_forcing_type) == "ISPOL") then + + call MPAS_forcing_get_forcing(& + seaiceForcingGroups, & + "seaice_atmospheric_forcing_sixhrly", & + streamManager, & + config_dt) + + call MPAS_forcing_get_forcing(& + seaiceForcingGroups, & + "seaice_atmospheric_forcing_daily", & + streamManager, & + config_dt) + endif block => domain % blocklist @@ -510,6 +703,8 @@ subroutine atmospheric_forcing(& select case (trim(config_atmospheric_forcing_type)) case ("CORE") call prepare_atmospheric_coupling_variables_CORE(block) + case ("ISPOL") + call prepare_atmospheric_coupling_variables_ISPOL(block) end select ! perform post coupling operations @@ -690,6 +885,188 @@ subroutine prepare_atmospheric_coupling_variables_CORE(block) end subroutine prepare_atmospheric_coupling_variables_CORE +!||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||| +! +! prepare_atmospheric_coupling_variables_ISPOL +! +!> \brief +!> \author Nicole Jeffery, LANL +!> \date +!> \details +!> Defines the cell fields corresponding to the 1D forcing fields. +! +!----------------------------------------------------------------------- + + subroutine prepare_atmospheric_coupling_variables_ISPOL(block) + + use seaice_constants, only: & + seaiceFreshWaterFreezingPoint, & + pii + + type (block_type), pointer :: block + + type (mpas_pool_type), pointer :: & + mesh, & + atmosCoupling, & + atmosForcing, & + atmos1DForcing, & + oceanCoupling, & + tracers_aggregate + + real(kind=RKIND), dimension(:), pointer :: & + airLevelHeight, & + airPotentialTemperature, & + airTemperature, & + airSpecificHumidity, & + airDensity, & + shortwaveDown, & + shortwaveVisibleDirectDown, & + shortwaveVisibleDiffuseDown, & + shortwaveIRDirectDown, & + shortwaveIRDiffuseDown, & + longwaveDown, & + rainfallRate, & + snowfallRate, & + cloudFraction, & + uAirVelocity, & + vAirVelocity, & + lonCell, & + latCell, & + iceAreaCell + + real(kind=RKIND), pointer :: & + seaSurfaceTemperature1D, & + airTemperature1D, & + airSpecificHumidity1D, & + shortwaveDown1D, & + longwaveDown1D, & + rainfallRate1D, & + uAirVelocity1D, & + vAirVelocity1D + + type (MPAS_time_type) :: & + currentForcingTime + + real(kind=RKIND) :: & + secondsToday + + integer, pointer :: & + nCellsSolve + + integer :: & + dayOfYear, & + iCell + + call MPAS_pool_get_subpool(block % structs, "mesh", mesh) + call MPAS_pool_get_subpool(block % structs, "atmos_coupling", atmosCoupling) + call MPAS_pool_get_subpool(block % structs, "1D_atmos_forcing", atmos1DForcing) + call MPAS_pool_get_subpool(block % structs, "ocean_coupling", oceanCoupling) + call MPAS_pool_get_subpool(block % structs, "tracers_aggregate", tracers_aggregate) + call MPAS_pool_get_subpool(block % structs, "atmos_forcing", atmosForcing) + + call MPAS_pool_get_dimension(mesh, "nCellsSolve", nCellsSolve) + + call MPAS_pool_get_array(mesh, "lonCell", lonCell) + call MPAS_pool_get_array(mesh, "latCell", latCell) + + call MPAS_pool_get_array(atmosCoupling, "airLevelHeight", airLevelHeight) + call MPAS_pool_get_array(atmosCoupling, "airPotentialTemperature", airPotentialTemperature) + call MPAS_pool_get_array(atmosCoupling, "airTemperature", airTemperature) + call MPAS_pool_get_array(atmosCoupling, "airSpecificHumidity", airSpecificHumidity) + call MPAS_pool_get_array(atmosCoupling, "airDensity", airDensity) + call MPAS_pool_get_array(atmosCoupling, "shortwaveVisibleDirectDown", shortwaveVisibleDirectDown) + call MPAS_pool_get_array(atmosCoupling, "shortwaveVisibleDiffuseDown", shortwaveVisibleDiffuseDown) + call MPAS_pool_get_array(atmosCoupling, "shortwaveIRDirectDown", shortwaveIRDirectDown) + call MPAS_pool_get_array(atmosCoupling, "shortwaveIRDiffuseDown", shortwaveIRDiffuseDown) + call MPAS_pool_get_array(atmosCoupling, "longwaveDown", longwaveDown) + call MPAS_pool_get_array(atmosCoupling, "rainfallRate", rainfallRate) + call MPAS_pool_get_array(atmosCoupling, "snowfallRate", snowfallRate) + call MPAS_pool_get_array(atmosCoupling, "uAirVelocity", uAirVelocity) + call MPAS_pool_get_array(atmosCoupling, "vAirVelocity", vAirVelocity) + call MPAS_pool_get_array(atmos1DForcing, "airTemperature1D", airTemperature1D) + call MPAS_pool_get_array(atmos1DForcing, "airSpecificHumidity1D", airSpecificHumidity1D) + call MPAS_pool_get_array(atmos1DForcing, "shortwaveDown1D", shortwaveDown1D) + call MPAS_pool_get_array(atmos1DForcing, "longwaveDown1D", longwaveDown1D) + call MPAS_pool_get_array(atmos1DForcing, "rainfallRate1D", rainfallRate1D) + call MPAS_pool_get_array(atmos1DForcing, "uAirVelocity1D", uAirVelocity1D) + call MPAS_pool_get_array(atmos1DForcing, "vAirVelocity1D", vAirVelocity1D) + + call MPAS_pool_get_array(atmosForcing, "cloudFraction", cloudFraction) + call MPAS_pool_get_array(atmosForcing, "shortwaveDown", shortwaveDown) + + call MPAS_pool_get_array(tracers_aggregate, "iceAreaCell", iceAreaCell) + + ! get the current time + call MPAS_forcing_get_forcing_time(& + seaiceForcingGroups, & + "seaice_atmospheric_forcing_sixhrly", & + currentForcingTime) + + ! get the number of seconds so far today + call get_seconds_today(& + currentForcingTime, & + secondsToday, & + dayOfYear) + + do iCell = 1, nCellsSolve + + ! not sure if we need this + cloudFraction(iCell) = 0.5_RKIND + + ! define cell quantities + airTemperature(iCell) = airTemperature1D + shortwaveDown(iCell) = shortwaveDown1D + longwaveDown(iCell) = longwaveDown1D + airSpecificHumidity(iCell) = airSpecificHumidity1D + uAirVelocity(iCell) = uAirVelocity1D + vAirVelocity(iCell) = vAirVelocity1D + rainfallRate(iCell) = rainfallRate1D + + ! limit air temperature values where ice is present + if (iceAreaCell(iCell) > 0.1_RKIND) then + airTemperature(iCell) = min(airTemperature(iCell), seaiceFreshWaterFreezingPoint + 0.1_RKIND) + endif + + ! prevent supersaturated humidity + call limit_specific_humidity(& + airTemperature(iCell), & + airSpecificHumidity(iCell)) + + shortwaveVisibleDirectDown(iCell) = shortwaveDown(iCell) * fracShortwaveVisibleDirect + shortwaveVisibleDiffuseDown(iCell) = shortwaveDown(iCell) * fracShortwaveVisibleDiffuse + shortwaveIRDirectDown(iCell) = shortwaveDown(iCell) * fracShortwaveIRDirectDown + shortwaveIRDiffuseDown(iCell) = shortwaveDown(iCell) * fracShortwaveIRDiffuseDown + + ! ensure physically realistic values + shortwaveDown(iCell) = max(shortwaveDown(iCell),0.0_RKIND) + rainfallRate(iCell) = max(rainfallRate(iCell),0.0_RKIND) + airSpecificHumidity(iCell) = max(airSpecificHumidity(iCell),0.0_RKIND) + + ! atmospheric level height + airLevelHeight(iCell) = 10.0_RKIND ! for velocities, 2-m for air T and specific humidity + + ! air potential temperature + airPotentialTemperature(iCell) = airTemperature(iCell) + + ! air density + airDensity(iCell) = 1.3_RKIND + + ! precipitation + + ! divide total precipitation between rain and snow + snowfallRate(iCell) = 0.0_RKIND + + if (airTemperature(iCell) < seaiceFreshWaterFreezingPoint) then + + snowfallRate(iCell) = rainfallRate(iCell) + rainfallRate(iCell) = 0.0_RKIND + + endif + + enddo ! iCell + + end subroutine prepare_atmospheric_coupling_variables_ISPOL + !||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||| ! ! post_atmospheric_coupling @@ -1281,6 +1658,8 @@ subroutine init_oceanic_forcing(domain) select case (trim(config_forcing_sst_type)) case ("ncar") call init_oceanic_forcing_ncar(domain) + case ("ISPOL") + call init_oceanic_forcing_ISPOL(domain) case ("hourly_velocities") call init_oceanic_forcing_hourly_velocities(domain) case default @@ -1458,6 +1837,225 @@ subroutine init_oceanic_forcing_ncar(domain) end subroutine init_oceanic_forcing_ncar +!||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||| +! +! init_oceanic_forcing_ISPOL +! +!> \brief +!> \author Nicole Jeffery, LANL +!> \date October 2022 +!> \details +!> The physical data corresponds to the Weddell Sea (67.9S, 54W) location from a +!> POP 1-degree (gx1v3) field derived from an ocean-ice simulation +!> forced with Ice Station Polarstern (ISPOL) 2004 atmospheric data. +!> Biogeochemical data is World Ocean Atlas (NCEP 2013) surface nutrient data. +! +!----------------------------------------------------------------------- + + subroutine init_oceanic_forcing_ISPOL(domain) + + type (domain_type) :: domain + + logical, pointer :: & + config_do_restart, & + config_use_column_biogeochemistry + + character(len=strKIND), pointer :: & + config_forcing_start_time, & + config_forcing_cycle_start, & + config_forcing_cycle_duration + + character(len=strKIND) :: & + forcingIntervalMonthly, & + forcingReferenceTimeMonthly, & + forcingIntervaldaily, & + forcingReferenceTimedaily + + ! get oceanic forcing configuration options + call MPAS_pool_get_config(domain % configs, "config_do_restart", config_do_restart) + call MPAS_pool_get_config(domain % configs, "config_use_column_biogeochemistry", config_use_column_biogeochemistry) + + ! get ispol forcing configuration options + call MPAS_pool_get_config(domain % configs, "config_forcing_start_time", config_forcing_start_time) + call MPAS_pool_get_config(domain % configs, "config_forcing_cycle_start", config_forcing_cycle_start) + call MPAS_pool_get_config(domain % configs, "config_forcing_cycle_duration", config_forcing_cycle_duration) + + ! create the sea surface temperature forcing group + call MPAS_forcing_init_group(& + seaiceForcingGroups, & + "seaice_oceanic_forcing_monthly", & + domain, & + config_forcing_start_time, & + config_forcing_cycle_start, & + config_forcing_cycle_duration, & + config_do_restart) + + forcingIntervalMonthly = "00-01-00_00:00:00" + forcingReferenceTimeMonthly = "0001-01-15_00:00:00" + + ! sea surface temperature + call MPAS_forcing_init_field(& + domain % streamManager, & + seaiceForcingGroups, & + "seaice_oceanic_forcing_monthly", & + "seaSurfaceTemperature1D", & + "ISPOLMonthlyForcing", & + "1D_ocean_forcing", & + "seaSurfaceTemperature1D", & + "linear", & + forcingReferenceTimeMonthly, & + forcingIntervalMonthly) + + ! sea surface salinity + call MPAS_forcing_init_field(& + domain % streamManager, & + seaiceForcingGroups, & + "seaice_oceanic_forcing_monthly", & + "seaSurfaceSalinity1D", & + "ISPOLMonthlyForcing", & + "1D_ocean_forcing", & + "seaSurfaceSalinity1D", & + "linear", & + forcingReferenceTimeMonthly, & + forcingIntervalMonthly) + + ! u ocean velocity + call MPAS_forcing_init_field(& + domain % streamManager, & + seaiceForcingGroups, & + "seaice_oceanic_forcing_monthly", & + "uOceanVelocity1D", & + "ISPOLMonthlyForcing", & + "1D_ocean_forcing", & + "uOceanVelocity1D", & + "linear", & + forcingReferenceTimeMonthly, & + forcingIntervalMonthly) + + ! v ocean velocity + call MPAS_forcing_init_field(& + domain % streamManager, & + seaiceForcingGroups, & + "seaice_oceanic_forcing_monthly", & + "vOceanVelocity1D", & + "ISPOLMonthlyForcing", & + "1D_ocean_forcing", & + "vOceanVelocity1D", & + "linear", & + forcingReferenceTimeMonthly, & + forcingIntervalMonthly) + + ! ocean mixed layer depth + call MPAS_forcing_init_field(& + domain % streamManager, & + seaiceForcingGroups, & + "seaice_oceanic_forcing_monthly", & + "oceanMixedLayerDepth1D", & + "ISPOLMonthlyForcing", & + "1D_ocean_forcing", & + "oceanMixedLayerDepth1D", & + "linear", & + forcingReferenceTimeMonthly, & + forcingIntervalMonthly) + + ! ocean sea surface tilt + call MPAS_forcing_init_field(& + domain % streamManager, & + seaiceForcingGroups, & + "seaice_oceanic_forcing_monthly", & + "seaSurfaceTiltU1D", & + "ISPOLMonthlyForcing", & + "1D_ocean_forcing", & + "seaSurfaceTiltU1D", & + "linear", & + forcingReferenceTimeMonthly, & + forcingIntervalMonthly) + + call MPAS_forcing_init_field(& + domain % streamManager, & + seaiceForcingGroups, & + "seaice_oceanic_forcing_monthly", & + "seaSurfaceTiltV1D", & + "ISPOLMonthlyForcing", & + "1D_ocean_forcing", & + "seaSurfaceTiltV1D", & + "linear", & + forcingReferenceTimeMonthly, & + forcingIntervalMonthly) + + ! deep ocean heat flux convergence + call MPAS_forcing_init_field(& + domain % streamManager, & + seaiceForcingGroups, & + "seaice_oceanic_forcing_monthly", & + "oceanHeatFluxConvergence1D", & + "ISPOLMonthlyForcing", & + "1D_ocean_forcing", & + "oceanHeatFluxConvergence1D", & + "linear", & + forcingReferenceTimeMonthly, & + forcingIntervalMonthly) + + call MPAS_forcing_init_field_data(& + seaiceForcingGroups, & + "seaice_oceanic_forcing_monthly", & + domain % streamManager, & + config_do_restart, & + .false.) + + ! ocean surface biogeochemistry fields + if (config_use_column_biogeochemistry) then + + ! create the sea surface biogeochemistry forcing group + call MPAS_forcing_init_group(& + seaiceForcingGroups, & + "seaice_oceanic_biogeochemistry_forcing_daily", & + domain, & + config_forcing_start_time, & + config_forcing_cycle_start, & + config_forcing_cycle_duration, & + config_do_restart) + + forcingIntervalDaily = "00-00-01_00:00:00" + forcingReferenceTimeDaily = "2004-01-01_00:00:00" + + ! sea surface nitrate + call MPAS_forcing_init_field(& + domain % streamManager, & + seaiceForcingGroups, & + "seaice_oceanic_biogeochemistry_forcing_daily", & + "oceanNitrateConc1D", & + "ISPOLDailyWOAForcing", & + "1D_ocean_biogeochemistry_forcing", & + "oceanNitrateConc1D", & + "linear", & + forcingReferenceTimeDaily, & + forcingIntervalDaily) + + ! sea surface silicate + call MPAS_forcing_init_field(& + domain % streamManager, & + seaiceForcingGroups, & + "seaice_oceanic_biogeochemistry_forcing_daily", & + "oceanSilicateConc1D", & + "ISPOLDailyWOAForcing", & + "1D_ocean_biogeochemistry_forcing", & + "oceanSilicateConc1D", & + "linear", & + forcingReferenceTimeDaily, & + forcingIntervalDaily) + + call MPAS_forcing_init_field_data(& + seaiceForcingGroups, & + "seaice_oceanic_biogeochemistry_forcing_daily", & + domain % streamManager, & + config_do_restart, & + .false.) + + end if + + end subroutine init_oceanic_forcing_ISPOL + !||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||| ! ! init_oceanic_forcing_hourly_velocities @@ -1585,12 +2183,14 @@ subroutine oceanic_forcing(& config_forcing_sst_type logical, pointer :: & - config_do_restart + config_do_restart, & + config_use_column_biogeochemistry ! configurations call mpas_pool_get_config(domain % configs, 'config_dt', config_dt) call mpas_pool_get_config(domain % configs, 'config_forcing_sst_type', config_forcing_sst_type) call mpas_pool_get_config(domain % configs, 'config_do_restart', config_do_restart) + call mpas_pool_get_config(domain % configs, 'config_use_column_biogeochemistry', config_use_column_biogeochemistry) ! use the forcing layer to get data if (trim(config_forcing_sst_type) == 'ncar') then @@ -1620,6 +2220,21 @@ subroutine oceanic_forcing(& streamManager, & config_dt) + else if (trim(config_forcing_sst_type) == 'ISPOL') then + + call MPAS_forcing_get_forcing(& + seaiceForcingGroups, & + "seaice_oceanic_forcing_monthly", & + streamManager, & + config_dt) + if (config_use_column_biogeochemistry) & + + call MPAS_forcing_get_forcing(& + seaiceForcingGroups, & + "seaice_oceanic_biogeochemistry_forcing_daily", & + streamManager, & + config_dt) + endif block => domain % blocklist @@ -1629,6 +2244,8 @@ subroutine oceanic_forcing(& select case (trim(config_forcing_sst_type)) case ("ncar") call prepare_oceanic_coupling_variables_ncar(block, firstTimeStep) + case ("ISPOL") + call prepare_oceanic_coupling_variables_ISPOL(block, firstTimeStep) end select call post_oceanic_coupling(block) @@ -1722,6 +2339,203 @@ subroutine prepare_oceanic_coupling_variables_ncar(block, firstTimeStep) end subroutine prepare_oceanic_coupling_variables_ncar +!||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||| +! +! prepare_oceanic_coupling_variables_ISPOL +! +!> \brief +!> \author Nicole Jeffery, LANL +!> \date October, 2022 +!> \details +!> Defines the ocean cell fields corresponding to the 1D forcing fields. +! +!----------------------------------------------------------------------- + + subroutine prepare_oceanic_coupling_variables_ISPOL(block, firstTimeStep) + + use ice_colpkg, only: & + colpkg_sea_freezing_temperature + + use seaice_constants, only: & + oceanAmmoniumISPOL, oceanDMSISPOL, oceanDMSPISPOL, oceanDiatomsISPOL, & + oceanSmallAlgaeISPOL, oceanPhaeocystisISPOL, oceanPolysaccharidsISPOL, & + oceanLipidsISPOL, oceanDICISPOL, oceanProteinsISPOL, oceanDissolvedIronISPOL, & + oceanParticulateIronISPOL, oceanHumicsISPOL, oceanProteinsCarbonISPOL + + type (block_type), pointer :: block + + logical, intent(in) :: & + firstTimeStep + + type (mpas_pool_type), pointer :: & + mesh, & + ocean_coupling, & + ocean1DForcing, & + oceanBGCForcing, & + biogeochemistry + + real(kind=RKIND), dimension(:,:), pointer :: & + oceanDONConc, & + oceanDICConc, & + oceanDOCConc, & + oceanAlgaeConc, & + oceanParticulateIronConc, & + oceanDissolvedIronConc + + real(kind=RKIND), dimension(:), pointer :: & + seaSurfaceTemperature, & + seaSurfaceSalinity, & + oceanMixedLayerDepth, & + seaFreezingTemperature, & + seaSurfaceTiltU, & + seaSurfaceTiltV, & + uOceanVelocity, & + vOceanVelocity, & + oceanHeatFluxConvergence, & + oceanNitrateConc, & + oceanSilicateConc, & + oceanAmmoniumConc, & + oceanDMSConc, & + oceanDMSPConc, & + oceanHumicsConc + + real(kind=RKIND), pointer :: & + seaSurfaceTemperature1D, & + seaSurfaceSalinity1D, & + oceanMixedLayerDepth1D, & + uOceanVelocity1D, & + vOceanVelocity1D, & + seaSurfaceTiltU1D, & + seaSurfaceTiltV1D, & + oceanHeatFluxConvergence1D, & + oceanNitrateConc1D, & + oceanSilicateConc1D + + character(len=strKIND), pointer :: & + config_sea_freezing_temperature_type + + logical, pointer :: & + config_do_restart, & + config_use_column_biogeochemistry + + integer, pointer :: & + nCellsSolve, & + nCells + + integer :: & + iCell + + call MPAS_pool_get_config(block % configs, "config_do_restart", config_do_restart) + call MPAS_pool_get_config(block % configs, "config_use_column_biogeochemistry", config_use_column_biogeochemistry) + call MPAS_pool_get_config(block % configs, "config_sea_freezing_temperature_type", config_sea_freezing_temperature_type) + + call MPAS_pool_get_subpool(block % structs, "mesh", mesh) + call MPAS_pool_get_subpool(block % structs, "ocean_coupling", ocean_coupling) + call MPAS_pool_get_subpool(block % structs, "1D_ocean_forcing", ocean1DForcing) + + call MPAS_pool_get_dimension(mesh, "nCellsSolve", nCellsSolve) + call MPAS_pool_get_dimension(mesh, "nCells", nCells) + + call MPAS_pool_get_array(ocean_coupling, "seaSurfaceTemperature", seaSurfaceTemperature) + call MPAS_pool_get_array(ocean_coupling, "seaSurfaceSalinity", seaSurfaceSalinity) + call MPAS_pool_get_array(ocean_coupling, "oceanMixedLayerDepth", oceanMixedLayerDepth) + call MPAS_pool_get_array(ocean_coupling, "seaFreezingTemperature", seaFreezingTemperature) + call MPAS_pool_get_array(ocean_coupling, "seaSurfaceTiltU", seaSurfaceTiltU) + call MPAS_pool_get_array(ocean_coupling, "seaSurfaceTiltV", seaSurfaceTiltV) + call MPAS_pool_get_array(ocean_coupling, "uOceanVelocity", uOceanVelocity) + call MPAS_pool_get_array(ocean_coupling, "vOceanVelocity", vOceanVelocity) + call MPAS_pool_get_array(ocean_coupling, "oceanHeatFluxConvergence", oceanHeatFluxConvergence) + + call MPAS_pool_get_array(ocean1DForcing, "seaSurfaceTemperature1D", seaSurfaceTemperature1D) + call MPAS_pool_get_array(ocean1DForcing, "seaSurfaceSalinity1D", seaSurfaceSalinity1D) + call MPAS_pool_get_array(ocean1DForcing, "oceanMixedLayerDepth1D", oceanMixedLayerDepth1D) + call MPAS_pool_get_array(ocean1DForcing, "uOceanVelocity1D", uOceanVelocity1D) + call MPAS_pool_get_array(ocean1DForcing, "vOceanVelocity1D", vOceanVelocity1D) + call MPAS_pool_get_array(ocean1DForcing, "seaSurfaceTiltU1D", seaSurfaceTiltU1D) + call MPAS_pool_get_array(ocean1DForcing, "seaSurfaceTiltV1D", seaSurfaceTiltV1D) + call MPAS_pool_get_array(ocean1DForcing, "oceanHeatFluxConvergence1D", oceanHeatFluxConvergence1D) + + do iCell = 1, nCellsSolve + + ! define cell quantities + seaSurfaceTemperature(iCell) = seaSurfaceTemperature1D + seaSurfaceSalinity(iCell) = seaSurfaceSalinity1D + oceanMixedLayerDepth(iCell) = oceanMixedLayerDepth1D + uOceanVelocity(iCell) = uOceanVelocity1D + vOceanVelocity(iCell) = vOceanVelocity1D + oceanHeatFluxConvergence(iCell) = oceanHeatFluxConvergence1D + seaSurfaceTiltU(iCell) = seaSurfaceTiltU1D + seaSurfaceTiltV(iCell) = seaSurfaceTiltV1D + + ! ensure physical realism + seaSurfaceSalinity(iCell) = max(seaSurfaceSalinity(iCell), 0.0_RKIND) + oceanMixedLayerDepth(iCell) = max(oceanMixedLayerDepth(iCell), 0.0_RKIND) + + ! sea freezing temperature + seaFreezingTemperature(iCell) = colpkg_sea_freezing_temperature(seaSurfaceSalinity(iCell)) + + enddo ! iCell + + ! only update sea surface temperature on first non-restart timestep + if (firstTimeStep .and. .not. config_do_restart) then + + do iCell = 1, nCellsSolve + + ! sea surface temperature + seaSurfaceTemperature(iCell) = max(seaSurfaceTemperature(iCell), seaFreezingTemperature(iCell)) + + enddo ! iCell + + endif + + if (config_use_column_biogeochemistry) then + call MPAS_pool_get_subpool(block % structs, "biogeochemistry",biogeochemistry) + call MPAS_pool_get_subpool(block % structs, "1D_ocean_biogeochemistry_forcing", & + oceanBGCForcing) + + call MPAS_pool_get_array(oceanBGCForcing, "oceanNitrateConc1D", oceanNitrateConc1D) + call MPAS_pool_get_array(oceanBGCForcing, "oceanSilicateConc1D", oceanSilicateConc1D) + call MPAS_pool_get_array(biogeochemistry, "oceanSilicateConc", oceanSilicateConc) + call MPAS_pool_get_array(biogeochemistry, "oceanNitrateConc", oceanNitrateConc) + call MPAS_pool_get_array(biogeochemistry, "oceanAlgaeConc", oceanAlgaeConc) + call MPAS_pool_get_array(biogeochemistry, "oceanAmmoniumConc", oceanAmmoniumConc) + call MPAS_pool_get_array(biogeochemistry, "oceanDMSConc", oceanDMSConc) + call MPAS_pool_get_array(biogeochemistry, "oceanDMSPConc", oceanDMSPConc) + call MPAS_pool_get_array(biogeochemistry, "oceanHumicsConc", oceanHumicsConc) + call MPAS_pool_get_array(biogeochemistry, "oceanDONConc", oceanDONConc) + call MPAS_pool_get_array(biogeochemistry, "oceanDICConc", oceanDICConc) + call MPAS_pool_get_array(biogeochemistry, "oceanDOCConc", oceanDOCConc) + call MPAS_pool_get_array(biogeochemistry, "oceanParticulateIronConc", oceanParticulateIronConc) + call MPAS_pool_get_array(biogeochemistry, "oceanDissolvedIronConc", oceanDissolvedIronConc) + + do iCell = 1, nCellsSolve + ! define cell quantities + oceanNitrateConc(iCell) = oceanNitrateConc1D + oceanSilicateConc(iCell) = oceanSilicateConc1D + end do + + if (firstTimeStep) then + do iCell = 1, nCellsSolve + oceanAmmoniumConc(iCell) = oceanAmmoniumISPOL + oceanDMSConc(iCell) = oceanDMSISPOL + oceanDMSPConc(iCell) = oceanDMSPISPOL + oceanAlgaeConc(:,iCell) = oceanDiatomsISPOL + oceanAlgaeConc(2,iCell) = oceanSmallAlgaeISPOL + oceanAlgaeConc(3,iCell) = oceanPhaeocystisISPOL + oceanDOCConc(:,iCell) = oceanPolysaccharidsISPOL + oceanDOCConc(2,iCell) = oceanLipidsISPOL + oceanDOCConc(3,iCell) = oceanProteinsCarbonISPOL + oceanDONConc(:,iCell) = oceanProteinsISPOL + oceanDICConc(:,iCell) = oceanDICISPOL + oceanHumicsConc(iCell) = oceanHumicsISPOL + oceanParticulateIronConc(:,iCell) = oceanParticulateIronISPOL + oceanDissolvedIronConc(:,iCell) = oceanDissolvedIronISPOL + enddo ! iCell + endif + end if + + end subroutine prepare_oceanic_coupling_variables_ISPOL + !||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||| ! ! post_oceanic_coupling diff --git a/components/mpas-seaice/src/shared/mpas_seaice_initialize.F b/components/mpas-seaice/src/shared/mpas_seaice_initialize.F index 49686fbd5cc2..86fc9a1588ff 100644 --- a/components/mpas-seaice/src/shared/mpas_seaice_initialize.F +++ b/components/mpas-seaice/src/shared/mpas_seaice_initialize.F @@ -317,6 +317,12 @@ subroutine init_ice_state(& block, & domain % configs) + else if (trim(config_initial_condition_type) == "uniform_1D") then + + call init_ice_state_uniform_1D(& + block, & + domain % configs) + else if (trim(config_initial_condition_type) == "special") then call init_ice_state_special(& @@ -558,6 +564,124 @@ subroutine init_ice_state_uniform_ice(& end subroutine init_ice_state_uniform_ice!}}} +!||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||| +! +! init_ice_state_uniform_1D +! +!> \brief +!> \author Nicole Jeffery, LANL +!> \date November, 2022 +!> \details +!> Initializes sea ice in the first category only with constant +!> values and latitude bounds defined in the namelist. +! +!----------------------------------------------------------------------- + + subroutine init_ice_state_uniform_1D(& + block, & + configs)!{{{ + + use seaice_constants, only: & + seaiceDegreesToRadians + + type(block_type), intent(inout) :: & + block !< Input/Output: + + type (MPAS_pool_type), pointer, intent(in) :: & + configs !< Input: + + type (MPAS_pool_type), pointer :: & + mesh, & + tracers, & + tracers_aggregate + + integer, pointer :: & + nCellsSolve + + real(kind=RKIND), dimension(:), pointer :: & + latCell + + real(kind=RKIND), dimension(:,:,:), pointer :: & + iceAreaCategory, & + iceVolumeCategory, & + snowVolumeCategory, & + surfaceTemperature + + real(kind=RKIND), dimension(:), pointer :: & + iceAreaCell, & + surfaceTemperatureCell + + real(kind=RKIND), pointer :: & + config_initial_ice_area, & + config_initial_ice_volume, & + config_initial_snow_volume, & + config_initial_latitude_north, & + config_initial_latitude_south + + integer :: & + iCell + + call MPAS_pool_get_config(configs, "config_initial_ice_area", config_initial_ice_area) + call MPAS_pool_get_config(configs, "config_initial_ice_volume", config_initial_ice_volume) + call MPAS_pool_get_config(configs, "config_initial_snow_volume", config_initial_snow_volume) + call MPAS_pool_get_config(configs, "config_initial_latitude_north", config_initial_latitude_north) + call MPAS_pool_get_config(configs, "config_initial_latitude_south", config_initial_latitude_south) + + call MPAS_pool_get_subpool(block % structs, "mesh", mesh) + call MPAS_pool_get_subpool(block % structs, "tracers", tracers) + call MPAS_pool_get_subpool(block % structs, "tracers_aggregate", tracers_aggregate) + + call MPAS_pool_get_dimension(mesh, "nCells", nCellsSolve) + + call MPAS_pool_get_array(mesh, "latCell", latCell) + + call MPAS_pool_get_array(tracers, "iceAreaCategory", iceAreaCategory, 1) + call MPAS_pool_get_array(tracers, "iceVolumeCategory", iceVolumeCategory, 1) + call MPAS_pool_get_array(tracers, "snowVolumeCategory", snowVolumeCategory, 1) + call MPAS_pool_get_array(tracers, "surfaceTemperature", surfaceTemperature, 1) + + call MPAS_pool_get_array(tracers_aggregate, "iceAreaCell", iceAreaCell) + call MPAS_pool_get_array(tracers_aggregate, "surfaceTemperatureCell", surfaceTemperatureCell) + + do iCell = 1, nCellsSolve + + if (latCell(iCell) > config_initial_latitude_north * seaiceDegreesToRadians .or. & + latCell(iCell) < config_initial_latitude_south * seaiceDegreesToRadians) then + + + iceAreaCategory(1,:,iCell) = 0.0_RKIND + iceVolumeCategory(1,:,iCell) = 0.0_RKIND + snowVolumeCategory(1,:,iCell) = 0.0_RKIND + surfaceTemperature(1,:,iCell) = 0.0_RKIND + + ! has ice + iceAreaCategory(1,1,iCell) = config_initial_ice_area + iceVolumeCategory(1,1,iCell) = config_initial_ice_volume + snowVolumeCategory(1,1,iCell) = config_initial_snow_volume + surfaceTemperature(1,1,iCell) = -1.0_RKIND + + else + + ! no ice + iceAreaCategory(1,:,iCell) = 0.0_RKIND + iceVolumeCategory(1,:,iCell) = 0.0_RKIND + snowVolumeCategory(1,:,iCell) = 0.0_RKIND + surfaceTemperature(1,:,iCell) = 0.0_RKIND + + endif + + enddo ! iCell + + ! integrated quantities + do iCell = 1, nCellsSolve + + iceAreaCell(iCell) = sum(iceAreaCategory(1,:,iCell)) + surfaceTemperatureCell(iCell) = -20.15_RKIND + + enddo ! iCell + + end subroutine init_ice_state_uniform_1D!}}} + !||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||| ! ! init_ice_cice_default From 626fe2dc827fa501ce0456120084aea73024e71f Mon Sep 17 00:00:00 2001 From: Nicole Jeffery Date: Tue, 6 Dec 2022 13:23:29 -0600 Subject: [PATCH 2/5] Added active tracer initialization to uniform_1D Properly initializes enthalpy and salinity using colpkg_init_trcr --- .../src/shared/mpas_seaice_initialize.F | 94 ++++++++++++++----- 1 file changed, 72 insertions(+), 22 deletions(-) diff --git a/components/mpas-seaice/src/shared/mpas_seaice_initialize.F b/components/mpas-seaice/src/shared/mpas_seaice_initialize.F index 86fc9a1588ff..5e5d130603d2 100644 --- a/components/mpas-seaice/src/shared/mpas_seaice_initialize.F +++ b/components/mpas-seaice/src/shared/mpas_seaice_initialize.F @@ -584,6 +584,10 @@ subroutine init_ice_state_uniform_1D(& use seaice_constants, only: & seaiceDegreesToRadians + use ice_colpkg, only: & + colpkg_init_trcr, & + colpkg_enthalpy_snow + type(block_type), intent(inout) :: & block !< Input/Output: @@ -593,19 +597,35 @@ subroutine init_ice_state_uniform_1D(& type (MPAS_pool_type), pointer :: & mesh, & tracers, & - tracers_aggregate + tracers_aggregate, & + atmos_coupling, & + ocean_coupling, & + initial integer, pointer :: & - nCellsSolve + nCellsSolve, & + nSnowLayers, & + nIceLayers, & + nCategories real(kind=RKIND), dimension(:), pointer :: & - latCell + latCell, & + airTemperature, & + seaSurfaceTemperature, & + seaFreezingTemperature + + real(kind=RKIND), dimension(:,:), pointer :: & + initialSalinityProfile, & + initialMeltingTemperatureProfile real(kind=RKIND), dimension(:,:,:), pointer :: & iceAreaCategory, & iceVolumeCategory, & snowVolumeCategory, & - surfaceTemperature + surfaceTemperature, & + snowEnthalpy, & + iceEnthalpy, & + iceSalinity real(kind=RKIND), dimension(:), pointer :: & iceAreaCell, & @@ -619,7 +639,10 @@ subroutine init_ice_state_uniform_1D(& config_initial_latitude_south integer :: & - iCell + iCell, & + iSnowLayer, & + iIceLayer, & + iCategory call MPAS_pool_get_config(configs, "config_initial_ice_area", config_initial_ice_area) call MPAS_pool_get_config(configs, "config_initial_ice_volume", config_initial_ice_volume) @@ -630,8 +653,14 @@ subroutine init_ice_state_uniform_1D(& call MPAS_pool_get_subpool(block % structs, "mesh", mesh) call MPAS_pool_get_subpool(block % structs, "tracers", tracers) call MPAS_pool_get_subpool(block % structs, "tracers_aggregate", tracers_aggregate) + call MPAS_pool_get_subpool(block % structs, "ocean_coupling", ocean_coupling) + call MPAS_pool_get_subpool(block % structs, "atmos_coupling", atmos_coupling) + call MPAS_pool_get_subpool(block % structs, "initial", initial) call MPAS_pool_get_dimension(mesh, "nCells", nCellsSolve) + call MPAS_pool_get_dimension(mesh, "nSnowLayers", nSnowLayers) + call MPAS_pool_get_dimension(mesh, "nIceLayers", nIceLayers) + call MPAS_pool_get_dimension(mesh, "nCategories", nCategories) call MPAS_pool_get_array(mesh, "latCell", latCell) @@ -640,19 +669,34 @@ subroutine init_ice_state_uniform_1D(& call MPAS_pool_get_array(tracers, "snowVolumeCategory", snowVolumeCategory, 1) call MPAS_pool_get_array(tracers, "surfaceTemperature", surfaceTemperature, 1) + call MPAS_pool_get_array(atmos_coupling, "airTemperature", airTemperature) + + call MPAS_pool_get_array(ocean_coupling, "seaSurfaceTemperature", seaSurfaceTemperature) + call MPAS_pool_get_array(ocean_coupling, "seaFreezingTemperature", seaFreezingTemperature) + call MPAS_pool_get_array(tracers_aggregate, "iceAreaCell", iceAreaCell) call MPAS_pool_get_array(tracers_aggregate, "surfaceTemperatureCell", surfaceTemperatureCell) + call MPAS_pool_get_array(tracers, "snowEnthalpy", snowEnthalpy, 1) + call MPAS_pool_get_array(tracers, "iceEnthalpy", iceEnthalpy, 1) + call MPAS_pool_get_array(tracers, "iceSalinity", iceSalinity, 1) + + call MPAS_pool_get_array(initial, "initialSalinityProfile", initialSalinityProfile) + call MPAS_pool_get_array(initial, "initialMeltingTemperatureProfile", initialMeltingTemperatureProfile) do iCell = 1, nCellsSolve - if (latCell(iCell) > config_initial_latitude_north * seaiceDegreesToRadians .or. & - latCell(iCell) < config_initial_latitude_south * seaiceDegreesToRadians) then + iceAreaCategory(1,:,iCell) = 0.0_RKIND + iceVolumeCategory(1,:,iCell) = 0.0_RKIND + snowVolumeCategory(1,:,iCell) = 0.0_RKIND + surfaceTemperature(1,:,iCell) = seaFreezingTemperature(iCell) + iceEnthalpy(:,:,iCell) = 0.0_RKIND + do iSnowLayer = 1, nSnowLayers + snowEnthalpy(iSnowLayer,:,iCell) = colpkg_enthalpy_snow(0.0_RKIND) + end do - iceAreaCategory(1,:,iCell) = 0.0_RKIND - iceVolumeCategory(1,:,iCell) = 0.0_RKIND - snowVolumeCategory(1,:,iCell) = 0.0_RKIND - surfaceTemperature(1,:,iCell) = 0.0_RKIND + if (latCell(iCell) > config_initial_latitude_north * seaiceDegreesToRadians .or. & + latCell(iCell) < config_initial_latitude_south * seaiceDegreesToRadians) then ! has ice iceAreaCategory(1,1,iCell) = config_initial_ice_area @@ -660,24 +704,30 @@ subroutine init_ice_state_uniform_1D(& snowVolumeCategory(1,1,iCell) = config_initial_snow_volume surfaceTemperature(1,1,iCell) = -1.0_RKIND - else - - ! no ice - iceAreaCategory(1,:,iCell) = 0.0_RKIND - iceVolumeCategory(1,:,iCell) = 0.0_RKIND - snowVolumeCategory(1,:,iCell) = 0.0_RKIND - surfaceTemperature(1,:,iCell) = 0.0_RKIND - + call colpkg_init_trcr(& + airTemperature(iCell), & + seaFreezingTemperature(iCell), & + initialSalinityProfile(:,iCell), & + initialMeltingTemperatureProfile(:,iCell), & + surfaceTemperature(1,1,iCell), & + nIceLayers, & + nSnowLayers, & + iceEnthalpy(:,1,iCell), & + snowEnthalpy(:,1,iCell)) endif - - enddo ! iCell + !enddo ! iCell ! integrated quantities - do iCell = 1, nCellsSolve + !do iCell = 1, nCellsSolve iceAreaCell(iCell) = sum(iceAreaCategory(1,:,iCell)) surfaceTemperatureCell(iCell) = -20.15_RKIND + do iCategory = 1, nCategories + do iIceLayer = 1, nIceLayers + iceSalinity(iIceLayer,iCategory,iCell) = initialSalinityProfile(iIceLayer,iCell) + enddo ! iIceLayer + enddo ! iCategory enddo ! iCell end subroutine init_ice_state_uniform_1D!}}} From 3ee5547a5d669f6f0e7fb616a6d3ad583d890537 Mon Sep 17 00:00:00 2001 From: Nicole Jeffery Date: Tue, 6 Dec 2022 13:52:26 -0600 Subject: [PATCH 3/5] Cleaned comments --- components/mpas-seaice/src/shared/mpas_seaice_initialize.F | 4 ---- 1 file changed, 4 deletions(-) diff --git a/components/mpas-seaice/src/shared/mpas_seaice_initialize.F b/components/mpas-seaice/src/shared/mpas_seaice_initialize.F index 5e5d130603d2..40754cfac8f4 100644 --- a/components/mpas-seaice/src/shared/mpas_seaice_initialize.F +++ b/components/mpas-seaice/src/shared/mpas_seaice_initialize.F @@ -715,10 +715,6 @@ subroutine init_ice_state_uniform_1D(& iceEnthalpy(:,1,iCell), & snowEnthalpy(:,1,iCell)) endif - !enddo ! iCell - - ! integrated quantities - !do iCell = 1, nCellsSolve iceAreaCell(iCell) = sum(iceAreaCategory(1,:,iCell)) surfaceTemperatureCell(iCell) = -20.15_RKIND From 57c834fe7f13180ff193822d54033f92081b99e3 Mon Sep 17 00:00:00 2001 From: Nicole Jeffery Date: Mon, 6 Mar 2023 15:30:40 -0600 Subject: [PATCH 4/5] Separates bgc forcing from ocean physics forcing Seasonal bgc forcing is time-dependent only and can be used for a DTESTM-BGC -Adds nCells dimension to ocean and atm ISPOL forcing to simplify code -Updates ISPOL forcing files -Adds a new namelist option: config_forcing_bgc_type='ISPOL' BFB --- components/mpas-seaice/bld/build-namelist | 1 + .../mpas-seaice/bld/build-namelist-section | 1 + .../namelist_defaults_mpassi.xml | 1 + .../namelist_definition_mpassi.xml | 8 + components/mpas-seaice/cime_config/buildnml | 7 + components/mpas-seaice/src/Registry.xml | 135 +---- .../src/shared/mpas_seaice_forcing.F | 541 ++++++++++-------- 7 files changed, 334 insertions(+), 360 deletions(-) diff --git a/components/mpas-seaice/bld/build-namelist b/components/mpas-seaice/bld/build-namelist index 9e033e906da2..b896e1ece06c 100755 --- a/components/mpas-seaice/bld/build-namelist +++ b/components/mpas-seaice/bld/build-namelist @@ -567,6 +567,7 @@ add_default($nl, 'config_forcing_cycle_start'); add_default($nl, 'config_forcing_cycle_duration'); add_default($nl, 'config_forcing_precipitation_units'); add_default($nl, 'config_forcing_sst_type'); +add_default($nl, 'config_forcing_bgc_type'); add_default($nl, 'config_update_ocean_fluxes'); add_default($nl, 'config_include_pond_freshwater_feedback'); diff --git a/components/mpas-seaice/bld/build-namelist-section b/components/mpas-seaice/bld/build-namelist-section index 167a235cc1ed..47a33cfd8ed2 100644 --- a/components/mpas-seaice/bld/build-namelist-section +++ b/components/mpas-seaice/bld/build-namelist-section @@ -109,6 +109,7 @@ add_default($nl, 'config_forcing_cycle_start'); add_default($nl, 'config_forcing_cycle_duration'); add_default($nl, 'config_forcing_precipitation_units'); add_default($nl, 'config_forcing_sst_type'); +add_default($nl, 'config_forcing_bgc_type'); add_default($nl, 'config_update_ocean_fluxes'); add_default($nl, 'config_include_pond_freshwater_feedback'); diff --git a/components/mpas-seaice/bld/namelist_files/namelist_defaults_mpassi.xml b/components/mpas-seaice/bld/namelist_files/namelist_defaults_mpassi.xml index 6603145e403c..6141a8913047 100644 --- a/components/mpas-seaice/bld/namelist_files/namelist_defaults_mpassi.xml +++ b/components/mpas-seaice/bld/namelist_files/namelist_defaults_mpassi.xml @@ -107,6 +107,7 @@ '2-00-00_00:00:00' 'mm_per_sec' 'ncar' +'ISPOL' true false diff --git a/components/mpas-seaice/bld/namelist_files/namelist_definition_mpassi.xml b/components/mpas-seaice/bld/namelist_files/namelist_definition_mpassi.xml index 9d25a90af84f..3766e0b5c4c0 100644 --- a/components/mpas-seaice/bld/namelist_files/namelist_definition_mpassi.xml +++ b/components/mpas-seaice/bld/namelist_files/namelist_definition_mpassi.xml @@ -505,6 +505,14 @@ Valid values: 'ncar' or 'ISPOL' Default: Defined in namelist_defaults.xml + +Ocean biogeochemistry forcing type. + +Valid values: 'ISPOL' +Default: Defined in namelist_defaults.xml + + diff --git a/components/mpas-seaice/cime_config/buildnml b/components/mpas-seaice/cime_config/buildnml index bc08b6380614..c03ab0264dc0 100755 --- a/components/mpas-seaice/cime_config/buildnml +++ b/components/mpas-seaice/cime_config/buildnml @@ -505,6 +505,13 @@ def buildnml(case, caseroot, compname): lines.append(' filename_interval="none"') lines.append(' input_interval="initial_only" />') lines.append('') + lines.append('') + lines.append('') lines.append('') diff --git a/components/mpas-seaice/src/Registry.xml b/components/mpas-seaice/src/Registry.xml index e5412e7a2f8c..fa3faf382b38 100644 --- a/components/mpas-seaice/src/Registry.xml +++ b/components/mpas-seaice/src/Registry.xml @@ -544,6 +544,10 @@ description="Sea surface temperature ocean forcing type." possible_values="'ncar'" /> + - - + + - - - - - + + + + + - - - - - - - - + + + + + + + + - - - - - - - - - - - - - - - - - - - - - - - - - +▶ 0.1_RKIND) then airTemperature(iCell) = min(airTemperature(iCell), seaiceFreshWaterFreezingPoint + 0.1_RKIND) @@ -1668,6 +1640,34 @@ subroutine init_oceanic_forcing(domain) end subroutine init_oceanic_forcing +!||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||| +! +! init_ocean_bgc_forcing +! +!> \brief +!> \author Nicole Jeffery, LANL +!> \date 3rd March 2023 +!> \details +!> Uses an ocean biogeochemistry forcing file +! for bgc enabled sea ice only test cases. +!----------------------------------------------------------------------- + + subroutine init_oceanic_bgc_forcing(domain) + + type (domain_type) :: domain + + character(len=strKIND), pointer :: & + config_forcing_bgc_type + + call MPAS_pool_get_config(domain % configs, "config_forcing_bgc_type", config_forcing_bgc_type) + + select case (trim(config_forcing_bgc_type)) + case ("ISPOL") + call init_oceanic_bgc_forcing_ISPOL(domain) + end select + + end subroutine init_oceanic_bgc_forcing + !||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||| ! ! init_oceanic_forcing_ncar @@ -1857,8 +1857,7 @@ subroutine init_oceanic_forcing_ISPOL(domain) type (domain_type) :: domain logical, pointer :: & - config_do_restart, & - config_use_column_biogeochemistry + config_do_restart character(len=strKIND), pointer :: & config_forcing_start_time, & @@ -1873,7 +1872,6 @@ subroutine init_oceanic_forcing_ISPOL(domain) ! get oceanic forcing configuration options call MPAS_pool_get_config(domain % configs, "config_do_restart", config_do_restart) - call MPAS_pool_get_config(domain % configs, "config_use_column_biogeochemistry", config_use_column_biogeochemistry) ! get ispol forcing configuration options call MPAS_pool_get_config(domain % configs, "config_forcing_start_time", config_forcing_start_time) @@ -1898,10 +1896,10 @@ subroutine init_oceanic_forcing_ISPOL(domain) domain % streamManager, & seaiceForcingGroups, & "seaice_oceanic_forcing_monthly", & - "seaSurfaceTemperature1D", & + "seaSurfaceTemperature", & "ISPOLMonthlyForcing", & - "1D_ocean_forcing", & - "seaSurfaceTemperature1D", & + "ocean_coupling", & + "seaSurfaceTemperature", & "linear", & forcingReferenceTimeMonthly, & forcingIntervalMonthly) @@ -1911,10 +1909,10 @@ subroutine init_oceanic_forcing_ISPOL(domain) domain % streamManager, & seaiceForcingGroups, & "seaice_oceanic_forcing_monthly", & - "seaSurfaceSalinity1D", & + "seaSurfaceSalinity", & "ISPOLMonthlyForcing", & - "1D_ocean_forcing", & - "seaSurfaceSalinity1D", & + "ocean_coupling", & + "seaSurfaceSalinity", & "linear", & forcingReferenceTimeMonthly, & forcingIntervalMonthly) @@ -1924,10 +1922,10 @@ subroutine init_oceanic_forcing_ISPOL(domain) domain % streamManager, & seaiceForcingGroups, & "seaice_oceanic_forcing_monthly", & - "uOceanVelocity1D", & + "uOceanVelocity", & "ISPOLMonthlyForcing", & - "1D_ocean_forcing", & - "uOceanVelocity1D", & + "ocean_coupling", & + "uOceanVelocity", & "linear", & forcingReferenceTimeMonthly, & forcingIntervalMonthly) @@ -1937,10 +1935,10 @@ subroutine init_oceanic_forcing_ISPOL(domain) domain % streamManager, & seaiceForcingGroups, & "seaice_oceanic_forcing_monthly", & - "vOceanVelocity1D", & + "vOceanVelocity", & "ISPOLMonthlyForcing", & - "1D_ocean_forcing", & - "vOceanVelocity1D", & + "ocean_coupling", & + "vOceanVelocity", & "linear", & forcingReferenceTimeMonthly, & forcingIntervalMonthly) @@ -1950,10 +1948,10 @@ subroutine init_oceanic_forcing_ISPOL(domain) domain % streamManager, & seaiceForcingGroups, & "seaice_oceanic_forcing_monthly", & - "oceanMixedLayerDepth1D", & + "oceanMixedLayerDepth", & "ISPOLMonthlyForcing", & - "1D_ocean_forcing", & - "oceanMixedLayerDepth1D", & + "ocean_coupling", & + "oceanMixedLayerDepth", & "linear", & forcingReferenceTimeMonthly, & forcingIntervalMonthly) @@ -1963,10 +1961,10 @@ subroutine init_oceanic_forcing_ISPOL(domain) domain % streamManager, & seaiceForcingGroups, & "seaice_oceanic_forcing_monthly", & - "seaSurfaceTiltU1D", & + "seaSurfaceTiltU", & "ISPOLMonthlyForcing", & - "1D_ocean_forcing", & - "seaSurfaceTiltU1D", & + "ocean_coupling", & + "seaSurfaceTiltU", & "linear", & forcingReferenceTimeMonthly, & forcingIntervalMonthly) @@ -1975,10 +1973,10 @@ subroutine init_oceanic_forcing_ISPOL(domain) domain % streamManager, & seaiceForcingGroups, & "seaice_oceanic_forcing_monthly", & - "seaSurfaceTiltV1D", & + "seaSurfaceTiltV", & "ISPOLMonthlyForcing", & - "1D_ocean_forcing", & - "seaSurfaceTiltV1D", & + "ocean_coupling", & + "seaSurfaceTiltV", & "linear", & forcingReferenceTimeMonthly, & forcingIntervalMonthly) @@ -1988,10 +1986,10 @@ subroutine init_oceanic_forcing_ISPOL(domain) domain % streamManager, & seaiceForcingGroups, & "seaice_oceanic_forcing_monthly", & - "oceanHeatFluxConvergence1D", & + "oceanHeatFluxConvergence", & "ISPOLMonthlyForcing", & - "1D_ocean_forcing", & - "oceanHeatFluxConvergence1D", & + "ocean_coupling", & + "oceanHeatFluxConvergence", & "linear", & forcingReferenceTimeMonthly, & forcingIntervalMonthly) @@ -2003,58 +2001,97 @@ subroutine init_oceanic_forcing_ISPOL(domain) config_do_restart, & .false.) + end subroutine init_oceanic_forcing_ISPOL + +!||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||| +! +! init_oceanic_forcing_ISPOL +! +!> \brief +!> \author Nicole Jeffery, LANL +!> \date March 2023 +!> \details +!> surface nutrient data corresponds to the Weddell Sea (67.9S, 54W) location from +!> the World Ocean Atlas (NCEP 2013). +! +!----------------------------------------------------------------------- + + subroutine init_oceanic_bgc_forcing_ISPOL(domain) + + type (domain_type) :: domain + + logical, pointer :: & + config_do_restart + + character(len=strKIND), pointer :: & + config_forcing_start_time, & + config_forcing_cycle_start, & + config_forcing_cycle_duration + + character(len=strKIND) :: & + forcingIntervalMonthly, & + forcingReferenceTimeMonthly, & + forcingIntervaldaily, & + forcingReferenceTimedaily + + ! get oceanic forcing configuration options + call MPAS_pool_get_config(domain % configs, "config_do_restart", config_do_restart) + + ! get ispol forcing configuration options + call MPAS_pool_get_config(domain % configs, "config_forcing_start_time", config_forcing_start_time) + call MPAS_pool_get_config(domain % configs, "config_forcing_cycle_start", config_forcing_cycle_start) + call MPAS_pool_get_config(domain % configs, "config_forcing_cycle_duration", config_forcing_cycle_duration) + + ! ocean surface biogeochemistry fields - if (config_use_column_biogeochemistry) then - ! create the sea surface biogeochemistry forcing group - call MPAS_forcing_init_group(& - seaiceForcingGroups, & - "seaice_oceanic_biogeochemistry_forcing_daily", & - domain, & - config_forcing_start_time, & - config_forcing_cycle_start, & - config_forcing_cycle_duration, & - config_do_restart) + ! create the sea surface biogeochemistry forcing group + call MPAS_forcing_init_group(& + seaiceForcingGroups, & + "seaice_oceanic_biogeochemistry_forcing_daily", & + domain, & + config_forcing_start_time, & + config_forcing_cycle_start, & + config_forcing_cycle_duration, & + config_do_restart) - forcingIntervalDaily = "00-00-01_00:00:00" - forcingReferenceTimeDaily = "2004-01-01_00:00:00" + forcingIntervalDaily = "00-00-01_00:00:00" + forcingReferenceTimeDaily = "2004-01-01_00:00:00" - ! sea surface nitrate - call MPAS_forcing_init_field(& - domain % streamManager, & - seaiceForcingGroups, & - "seaice_oceanic_biogeochemistry_forcing_daily", & - "oceanNitrateConc1D", & - "ISPOLDailyWOAForcing", & - "1D_ocean_biogeochemistry_forcing", & - "oceanNitrateConc1D", & - "linear", & - forcingReferenceTimeDaily, & - forcingIntervalDaily) - - ! sea surface silicate - call MPAS_forcing_init_field(& - domain % streamManager, & - seaiceForcingGroups, & - "seaice_oceanic_biogeochemistry_forcing_daily", & - "oceanSilicateConc1D", & - "ISPOLDailyWOAForcing", & - "1D_ocean_biogeochemistry_forcing", & - "oceanSilicateConc1D", & - "linear", & - forcingReferenceTimeDaily, & - forcingIntervalDaily) - - call MPAS_forcing_init_field_data(& - seaiceForcingGroups, & - "seaice_oceanic_biogeochemistry_forcing_daily", & - domain % streamManager, & - config_do_restart, & - .false.) + ! sea surface nitrate + call MPAS_forcing_init_field(& + domain % streamManager, & + seaiceForcingGroups, & + "seaice_oceanic_biogeochemistry_forcing_daily", & + "oceanNitrateConc1D", & + "ISPOLDailyWOAForcing", & + "1D_ocean_biogeochemistry_forcing", & + "oceanNitrateConc1D", & + "linear", & + forcingReferenceTimeDaily, & + forcingIntervalDaily) - end if + ! sea surface silicate + call MPAS_forcing_init_field(& + domain % streamManager, & + seaiceForcingGroups, & + "seaice_oceanic_biogeochemistry_forcing_daily", & + "oceanSilicateConc1D", & + "ISPOLDailyWOAForcing", & + "1D_ocean_biogeochemistry_forcing", & + "oceanSilicateConc1D", & + "linear", & + forcingReferenceTimeDaily, & + forcingIntervalDaily) - end subroutine init_oceanic_forcing_ISPOL + call MPAS_forcing_init_field_data(& + seaiceForcingGroups, & + "seaice_oceanic_biogeochemistry_forcing_daily", & + domain % streamManager, & + config_do_restart, & + .false.) + + end subroutine init_oceanic_bgc_forcing_ISPOL !||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||| ! @@ -2180,7 +2217,8 @@ subroutine oceanic_forcing(& config_dt character(len=strKIND), pointer :: & - config_forcing_sst_type + config_forcing_sst_type, & + config_forcing_bgc_type logical, pointer :: & config_do_restart, & @@ -2189,6 +2227,7 @@ subroutine oceanic_forcing(& ! configurations call mpas_pool_get_config(domain % configs, 'config_dt', config_dt) call mpas_pool_get_config(domain % configs, 'config_forcing_sst_type', config_forcing_sst_type) + call mpas_pool_get_config(domain % configs, 'config_forcing_bgc_type', config_forcing_bgc_type) call mpas_pool_get_config(domain % configs, 'config_do_restart', config_do_restart) call mpas_pool_get_config(domain % configs, 'config_use_column_biogeochemistry', config_use_column_biogeochemistry) @@ -2227,14 +2266,16 @@ subroutine oceanic_forcing(& "seaice_oceanic_forcing_monthly", & streamManager, & config_dt) - if (config_use_column_biogeochemistry) & + endif + if (config_use_column_biogeochemistry) then + if (trim(config_forcing_bgc_type) == 'ISPOL') then call MPAS_forcing_get_forcing(& seaiceForcingGroups, & "seaice_oceanic_biogeochemistry_forcing_daily", & streamManager, & config_dt) - + endif endif block => domain % blocklist @@ -2248,6 +2289,14 @@ subroutine oceanic_forcing(& call prepare_oceanic_coupling_variables_ISPOL(block, firstTimeStep) end select + if (config_use_column_biogeochemistry) then + ! convert the input forcing variables to the coupling variables + select case (trim(config_forcing_bgc_type)) + case ("ISPOL") + call prepare_oceanic_coupling_bgc_variables_ISPOL(block, firstTimeStep) + end select + end if + call post_oceanic_coupling(block) block => block % next @@ -2347,7 +2396,7 @@ end subroutine prepare_oceanic_coupling_variables_ncar !> \author Nicole Jeffery, LANL !> \date October, 2022 !> \details -!> Defines the ocean cell fields corresponding to the 1D forcing fields. +!> Prepares the ocean coupling variables from the ISPOL 1D forcing ! !----------------------------------------------------------------------- @@ -2356,12 +2405,6 @@ subroutine prepare_oceanic_coupling_variables_ISPOL(block, firstTimeStep) use ice_colpkg, only: & colpkg_sea_freezing_temperature - use seaice_constants, only: & - oceanAmmoniumISPOL, oceanDMSISPOL, oceanDMSPISPOL, oceanDiatomsISPOL, & - oceanSmallAlgaeISPOL, oceanPhaeocystisISPOL, oceanPolysaccharidsISPOL, & - oceanLipidsISPOL, oceanDICISPOL, oceanProteinsISPOL, oceanDissolvedIronISPOL, & - oceanParticulateIronISPOL, oceanHumicsISPOL, oceanProteinsCarbonISPOL - type (block_type), pointer :: block logical, intent(in) :: & @@ -2369,54 +2412,19 @@ subroutine prepare_oceanic_coupling_variables_ISPOL(block, firstTimeStep) type (mpas_pool_type), pointer :: & mesh, & - ocean_coupling, & - ocean1DForcing, & - oceanBGCForcing, & - biogeochemistry - - real(kind=RKIND), dimension(:,:), pointer :: & - oceanDONConc, & - oceanDICConc, & - oceanDOCConc, & - oceanAlgaeConc, & - oceanParticulateIronConc, & - oceanDissolvedIronConc + ocean_coupling real(kind=RKIND), dimension(:), pointer :: & seaSurfaceTemperature, & seaSurfaceSalinity, & oceanMixedLayerDepth, & - seaFreezingTemperature, & - seaSurfaceTiltU, & - seaSurfaceTiltV, & - uOceanVelocity, & - vOceanVelocity, & - oceanHeatFluxConvergence, & - oceanNitrateConc, & - oceanSilicateConc, & - oceanAmmoniumConc, & - oceanDMSConc, & - oceanDMSPConc, & - oceanHumicsConc - - real(kind=RKIND), pointer :: & - seaSurfaceTemperature1D, & - seaSurfaceSalinity1D, & - oceanMixedLayerDepth1D, & - uOceanVelocity1D, & - vOceanVelocity1D, & - seaSurfaceTiltU1D, & - seaSurfaceTiltV1D, & - oceanHeatFluxConvergence1D, & - oceanNitrateConc1D, & - oceanSilicateConc1D + seaFreezingTemperature character(len=strKIND), pointer :: & config_sea_freezing_temperature_type logical, pointer :: & - config_do_restart, & - config_use_column_biogeochemistry + config_do_restart integer, pointer :: & nCellsSolve, & @@ -2426,12 +2434,10 @@ subroutine prepare_oceanic_coupling_variables_ISPOL(block, firstTimeStep) iCell call MPAS_pool_get_config(block % configs, "config_do_restart", config_do_restart) - call MPAS_pool_get_config(block % configs, "config_use_column_biogeochemistry", config_use_column_biogeochemistry) call MPAS_pool_get_config(block % configs, "config_sea_freezing_temperature_type", config_sea_freezing_temperature_type) call MPAS_pool_get_subpool(block % structs, "mesh", mesh) call MPAS_pool_get_subpool(block % structs, "ocean_coupling", ocean_coupling) - call MPAS_pool_get_subpool(block % structs, "1D_ocean_forcing", ocean1DForcing) call MPAS_pool_get_dimension(mesh, "nCellsSolve", nCellsSolve) call MPAS_pool_get_dimension(mesh, "nCells", nCells) @@ -2440,33 +2446,9 @@ subroutine prepare_oceanic_coupling_variables_ISPOL(block, firstTimeStep) call MPAS_pool_get_array(ocean_coupling, "seaSurfaceSalinity", seaSurfaceSalinity) call MPAS_pool_get_array(ocean_coupling, "oceanMixedLayerDepth", oceanMixedLayerDepth) call MPAS_pool_get_array(ocean_coupling, "seaFreezingTemperature", seaFreezingTemperature) - call MPAS_pool_get_array(ocean_coupling, "seaSurfaceTiltU", seaSurfaceTiltU) - call MPAS_pool_get_array(ocean_coupling, "seaSurfaceTiltV", seaSurfaceTiltV) - call MPAS_pool_get_array(ocean_coupling, "uOceanVelocity", uOceanVelocity) - call MPAS_pool_get_array(ocean_coupling, "vOceanVelocity", vOceanVelocity) - call MPAS_pool_get_array(ocean_coupling, "oceanHeatFluxConvergence", oceanHeatFluxConvergence) - - call MPAS_pool_get_array(ocean1DForcing, "seaSurfaceTemperature1D", seaSurfaceTemperature1D) - call MPAS_pool_get_array(ocean1DForcing, "seaSurfaceSalinity1D", seaSurfaceSalinity1D) - call MPAS_pool_get_array(ocean1DForcing, "oceanMixedLayerDepth1D", oceanMixedLayerDepth1D) - call MPAS_pool_get_array(ocean1DForcing, "uOceanVelocity1D", uOceanVelocity1D) - call MPAS_pool_get_array(ocean1DForcing, "vOceanVelocity1D", vOceanVelocity1D) - call MPAS_pool_get_array(ocean1DForcing, "seaSurfaceTiltU1D", seaSurfaceTiltU1D) - call MPAS_pool_get_array(ocean1DForcing, "seaSurfaceTiltV1D", seaSurfaceTiltV1D) - call MPAS_pool_get_array(ocean1DForcing, "oceanHeatFluxConvergence1D", oceanHeatFluxConvergence1D) do iCell = 1, nCellsSolve - ! define cell quantities - seaSurfaceTemperature(iCell) = seaSurfaceTemperature1D - seaSurfaceSalinity(iCell) = seaSurfaceSalinity1D - oceanMixedLayerDepth(iCell) = oceanMixedLayerDepth1D - uOceanVelocity(iCell) = uOceanVelocity1D - vOceanVelocity(iCell) = vOceanVelocity1D - oceanHeatFluxConvergence(iCell) = oceanHeatFluxConvergence1D - seaSurfaceTiltU(iCell) = seaSurfaceTiltU1D - seaSurfaceTiltV(iCell) = seaSurfaceTiltV1D - ! ensure physical realism seaSurfaceSalinity(iCell) = max(seaSurfaceSalinity(iCell), 0.0_RKIND) oceanMixedLayerDepth(iCell) = max(oceanMixedLayerDepth(iCell), 0.0_RKIND) @@ -2488,53 +2470,122 @@ subroutine prepare_oceanic_coupling_variables_ISPOL(block, firstTimeStep) endif - if (config_use_column_biogeochemistry) then - call MPAS_pool_get_subpool(block % structs, "biogeochemistry",biogeochemistry) - call MPAS_pool_get_subpool(block % structs, "1D_ocean_biogeochemistry_forcing", & + end subroutine prepare_oceanic_coupling_variables_ISPOL + +!||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||| +! +! prepare_oceanic_coupling_variables_ISPOL +! +!> \brief +!> \author Nicole Jeffery, LANL +!> \date March, 2023 +!> \details +!> Defines the ocean bgc cell fields corresponding to the 1D forcing fields. +! +!----------------------------------------------------------------------- + + subroutine prepare_oceanic_coupling_bgc_variables_ISPOL(block, firstTimeStep) + + use seaice_constants, only: & + oceanAmmoniumISPOL, oceanDMSISPOL, oceanDMSPISPOL, oceanDiatomsISPOL, & + oceanSmallAlgaeISPOL, oceanPhaeocystisISPOL, oceanPolysaccharidsISPOL, & + oceanLipidsISPOL, oceanDICISPOL, oceanProteinsISPOL, oceanDissolvedIronISPOL, & + oceanParticulateIronISPOL, oceanHumicsISPOL, oceanProteinsCarbonISPOL + + type (block_type), pointer :: block + + logical, intent(in) :: & + firstTimeStep + + type (mpas_pool_type), pointer :: & + mesh, & + oceanBGCForcing, & + biogeochemistry + + real(kind=RKIND), dimension(:,:), pointer :: & + oceanDONConc, & + oceanDICConc, & + oceanDOCConc, & + oceanAlgaeConc, & + oceanParticulateIronConc, & + oceanDissolvedIronConc + + real(kind=RKIND), dimension(:), pointer :: & + oceanNitrateConc, & + oceanSilicateConc, & + oceanAmmoniumConc, & + oceanDMSConc, & + oceanDMSPConc, & + oceanHumicsConc + + real(kind=RKIND), pointer :: & + oceanNitrateConc1D, & + oceanSilicateConc1D + + logical, pointer :: & + config_do_restart, & + config_use_column_biogeochemistry + + integer, pointer :: & + nCellsSolve, & + nCells + + integer :: & + iCell + + call MPAS_pool_get_config(block % configs, "config_do_restart", config_do_restart) + call MPAS_pool_get_config(block % configs, "config_use_column_biogeochemistry", config_use_column_biogeochemistry) + + call MPAS_pool_get_subpool(block % structs, "mesh", mesh) + + call MPAS_pool_get_dimension(mesh, "nCellsSolve", nCellsSolve) + call MPAS_pool_get_dimension(mesh, "nCells", nCells) + + call MPAS_pool_get_subpool(block % structs, "biogeochemistry",biogeochemistry) + call MPAS_pool_get_subpool(block % structs, "1D_ocean_biogeochemistry_forcing", & oceanBGCForcing) - call MPAS_pool_get_array(oceanBGCForcing, "oceanNitrateConc1D", oceanNitrateConc1D) - call MPAS_pool_get_array(oceanBGCForcing, "oceanSilicateConc1D", oceanSilicateConc1D) - call MPAS_pool_get_array(biogeochemistry, "oceanSilicateConc", oceanSilicateConc) - call MPAS_pool_get_array(biogeochemistry, "oceanNitrateConc", oceanNitrateConc) - call MPAS_pool_get_array(biogeochemistry, "oceanAlgaeConc", oceanAlgaeConc) - call MPAS_pool_get_array(biogeochemistry, "oceanAmmoniumConc", oceanAmmoniumConc) - call MPAS_pool_get_array(biogeochemistry, "oceanDMSConc", oceanDMSConc) - call MPAS_pool_get_array(biogeochemistry, "oceanDMSPConc", oceanDMSPConc) - call MPAS_pool_get_array(biogeochemistry, "oceanHumicsConc", oceanHumicsConc) - call MPAS_pool_get_array(biogeochemistry, "oceanDONConc", oceanDONConc) - call MPAS_pool_get_array(biogeochemistry, "oceanDICConc", oceanDICConc) - call MPAS_pool_get_array(biogeochemistry, "oceanDOCConc", oceanDOCConc) - call MPAS_pool_get_array(biogeochemistry, "oceanParticulateIronConc", oceanParticulateIronConc) - call MPAS_pool_get_array(biogeochemistry, "oceanDissolvedIronConc", oceanDissolvedIronConc) + call MPAS_pool_get_array(oceanBGCForcing, "oceanNitrateConc1D", oceanNitrateConc1D) + call MPAS_pool_get_array(oceanBGCForcing, "oceanSilicateConc1D", oceanSilicateConc1D) + call MPAS_pool_get_array(biogeochemistry, "oceanSilicateConc", oceanSilicateConc) + call MPAS_pool_get_array(biogeochemistry, "oceanNitrateConc", oceanNitrateConc) + call MPAS_pool_get_array(biogeochemistry, "oceanAlgaeConc", oceanAlgaeConc) + call MPAS_pool_get_array(biogeochemistry, "oceanAmmoniumConc", oceanAmmoniumConc) + call MPAS_pool_get_array(biogeochemistry, "oceanDMSConc", oceanDMSConc) + call MPAS_pool_get_array(biogeochemistry, "oceanDMSPConc", oceanDMSPConc) + call MPAS_pool_get_array(biogeochemistry, "oceanHumicsConc", oceanHumicsConc) + call MPAS_pool_get_array(biogeochemistry, "oceanDONConc", oceanDONConc) + call MPAS_pool_get_array(biogeochemistry, "oceanDICConc", oceanDICConc) + call MPAS_pool_get_array(biogeochemistry, "oceanDOCConc", oceanDOCConc) + call MPAS_pool_get_array(biogeochemistry, "oceanParticulateIronConc", oceanParticulateIronConc) + call MPAS_pool_get_array(biogeochemistry, "oceanDissolvedIronConc", oceanDissolvedIronConc) + do iCell = 1, nCellsSolve + ! define cell quantities + oceanNitrateConc(iCell) = oceanNitrateConc1D + oceanSilicateConc(iCell) = oceanSilicateConc1D + end do + + if (firstTimeStep) then do iCell = 1, nCellsSolve - ! define cell quantities - oceanNitrateConc(iCell) = oceanNitrateConc1D - oceanSilicateConc(iCell) = oceanSilicateConc1D - end do - - if (firstTimeStep) then - do iCell = 1, nCellsSolve - oceanAmmoniumConc(iCell) = oceanAmmoniumISPOL - oceanDMSConc(iCell) = oceanDMSISPOL - oceanDMSPConc(iCell) = oceanDMSPISPOL - oceanAlgaeConc(:,iCell) = oceanDiatomsISPOL - oceanAlgaeConc(2,iCell) = oceanSmallAlgaeISPOL - oceanAlgaeConc(3,iCell) = oceanPhaeocystisISPOL - oceanDOCConc(:,iCell) = oceanPolysaccharidsISPOL - oceanDOCConc(2,iCell) = oceanLipidsISPOL - oceanDOCConc(3,iCell) = oceanProteinsCarbonISPOL - oceanDONConc(:,iCell) = oceanProteinsISPOL - oceanDICConc(:,iCell) = oceanDICISPOL - oceanHumicsConc(iCell) = oceanHumicsISPOL - oceanParticulateIronConc(:,iCell) = oceanParticulateIronISPOL - oceanDissolvedIronConc(:,iCell) = oceanDissolvedIronISPOL - enddo ! iCell - endif - end if + oceanAmmoniumConc(iCell) = oceanAmmoniumISPOL + oceanDMSConc(iCell) = oceanDMSISPOL + oceanDMSPConc(iCell) = oceanDMSPISPOL + oceanAlgaeConc(:,iCell) = oceanDiatomsISPOL + oceanAlgaeConc(2,iCell) = oceanSmallAlgaeISPOL + oceanAlgaeConc(3,iCell) = oceanPhaeocystisISPOL + oceanDOCConc(:,iCell) = oceanPolysaccharidsISPOL + oceanDOCConc(2,iCell) = oceanLipidsISPOL + oceanDOCConc(3,iCell) = oceanProteinsCarbonISPOL + oceanDONConc(:,iCell) = oceanProteinsISPOL + oceanDICConc(:,iCell) = oceanDICISPOL + oceanHumicsConc(iCell) = oceanHumicsISPOL + oceanParticulateIronConc(:,iCell) = oceanParticulateIronISPOL + oceanDissolvedIronConc(:,iCell) = oceanDissolvedIronISPOL + enddo ! iCell + endif - end subroutine prepare_oceanic_coupling_variables_ISPOL + end subroutine prepare_oceanic_coupling_bgc_variables_ISPOL !||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||| ! From 78328912030f64123efa1ee76ef9c74f6ccaee22 Mon Sep 17 00:00:00 2001 From: Jon Wolfe Date: Tue, 25 Apr 2023 11:24:29 -0500 Subject: [PATCH 5/5] Clean up Registry to it is consistent with documentation --- components/mpas-seaice/src/Registry.xml | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/components/mpas-seaice/src/Registry.xml b/components/mpas-seaice/src/Registry.xml index fa3faf382b38..f3dbe7d107d2 100644 --- a/components/mpas-seaice/src/Registry.xml +++ b/components/mpas-seaice/src/Registry.xml @@ -450,7 +450,7 @@ /> @@ -991,7 +991,7 @@ />