From e6a0e8da9ae74912da2b80799fdbe3372dbf0f43 Mon Sep 17 00:00:00 2001 From: Michael Barlage Date: Thu, 6 Mar 2025 11:56:01 -0600 Subject: [PATCH 1/3] add soil color data to init_atmosphere --- src/core_init_atmosphere/Registry.xml | 6 ++ .../mpas_init_atm_static.F | 78 +++++++++++++++++++ 2 files changed, 84 insertions(+) diff --git a/src/core_init_atmosphere/Registry.xml b/src/core_init_atmosphere/Registry.xml index 63e7facc60..4004ae03de 100644 --- a/src/core_init_atmosphere/Registry.xml +++ b/src/core_init_atmosphere/Registry.xml @@ -481,6 +481,7 @@ + @@ -589,6 +590,7 @@ + @@ -920,6 +922,10 @@ + + + diff --git a/src/core_init_atmosphere/mpas_init_atm_static.F b/src/core_init_atmosphere/mpas_init_atm_static.F index 9de9913f08..0ad3edb19c 100644 --- a/src/core_init_atmosphere/mpas_init_atm_static.F +++ b/src/core_init_atmosphere/mpas_init_atm_static.F @@ -1202,6 +1202,16 @@ subroutine init_atm_static(mesh, dims, configs) call mpas_log_write('--- end interpolate ALBEDO12M') +! +! Interpolate soil_color +! + geog_sub_path = 'soil_color/' + + call mpas_log_write('--- start interpolate soil_color') + call interp_soil_color(mesh, tree, trim(geog_data_path)//trim(geog_sub_path), & + supersample_fac=supersample_fac) + call mpas_log_write('--- end interpolate soil_color') + ! ! Interpolate SOILCOMP ! @@ -1767,6 +1777,74 @@ subroutine interp_terrain(mesh, kdtree, geog_data_path, supersample_fac) end subroutine interp_terrain + !*********************************************************************** + ! + ! routine interp_soil_color + ! + !> \brief Interpolate soil color + !> \author Michael Barlage + !> \date 25 February 2025 + !> \details + !> Interpolate soil color by using the init_atm_map_static_data routine and + !> accumulating the pixel values into each cell using categorical_interp_accumulation. + !> + !> following the method outlined for landuse + ! + !----------------------------------------------------------------------- + subroutine interp_soil_color(mesh, kdtree, geog_data_path, supersample_fac) + + implicit none + + ! Input variables + type (mpas_pool_type), intent(inout) :: mesh + type (mpas_kd_type), pointer, intent(in) :: kdtree + character (len=*), intent(in) :: geog_data_path + integer, intent(in), optional :: supersample_fac + + ! Local variables + type (mpas_geotile_mgr_type) :: mgr + integer, pointer :: nCells + integer, dimension(:), pointer :: soil_color + + integer :: iCell + integer :: ierr + + ierr = mgr % init(trim(geog_data_path)) + if (ierr /= 0) then + call mpas_log_write("Error occured initalizing interpolation for "//trim(geog_data_path), messageType=MPAS_LOG_CRIT) + return ! Program execution should not reach this statement since the preceding message is a critical error + end if + + call mpas_pool_get_dimension(mesh, 'nCells', nCells) + call mpas_pool_get_config(mgr % pool, 'category_min', category_min) + call mpas_pool_get_config(mgr % pool, 'category_max', category_max) + call mpas_pool_get_array(mesh, 'soil_color', soil_color) + + allocate(ncat(category_min:category_max, nCells)) + ncat(:,:) = 0 + + call init_atm_map_static_data(mesh, mgr, kdtree, categorical_interp_criteria, categorical_interp_accumulation, & + supersample_fac=supersample_fac) + do iCell = 1, nCells + ! Because maxloc returns the location of the maximum value of an array as if the + ! starting index of the array is 1, and dataset categories do not necessarily start + ! at 1, we need to use category_min to ensure the correct category location is chosen. + if (all(ncat(:,iCell) == 0)) then + soil_color(iCell) = 11 ! all missing, e.g. water, so choose a neutral value + else + soil_color(iCell) = maxloc(ncat(:,iCell), dim=1) - 1 + category_min + end if + end do + deallocate(ncat) + + ierr = mgr % finalize() + if (ierr /= 0) then + call mpas_log_write("Error occured finalizing interpolation for "//trim(geog_data_path), messageType=MPAS_LOG_CRIT) + return ! Program execution should not reach this statement since the preceding message is a critical error + end if + + end subroutine interp_soil_color + !*********************************************************************** ! ! routine interp_soilcomp From 6b1cfc90232277ba24db049e9857809228789537 Mon Sep 17 00:00:00 2001 From: Michael Barlage Date: Wed, 2 Apr 2025 08:37:44 -0500 Subject: [PATCH 2/3] add soil color --- src/core_atmosphere/Registry.xml | 1 + src/core_atmosphere/physics/Registry_noahmp.xml | 4 ++++ src/core_atmosphere/physics/mpas_atmphys_lsm_noahmpinit.F | 3 +++ .../physics_noahmp/drivers/mpas/ConfigVarInTransferMod.F90 | 2 +- .../physics_noahmp/drivers/mpas/NoahmpIOVarFinalizeMod.F90 | 1 + .../physics_noahmp/drivers/mpas/NoahmpIOVarInitMod.F90 | 2 ++ .../physics/physics_noahmp/drivers/mpas/NoahmpIOVarType.F90 | 1 + 7 files changed, 13 insertions(+), 1 deletion(-) diff --git a/src/core_atmosphere/Registry.xml b/src/core_atmosphere/Registry.xml index a54ca0aef1..e654f9ad00 100644 --- a/src/core_atmosphere/Registry.xml +++ b/src/core_atmosphere/Registry.xml @@ -543,6 +543,7 @@ + #endif diff --git a/src/core_atmosphere/physics/Registry_noahmp.xml b/src/core_atmosphere/physics/Registry_noahmp.xml index 89d980f724..b09b57f51c 100644 --- a/src/core_atmosphere/physics/Registry_noahmp.xml +++ b/src/core_atmosphere/physics/Registry_noahmp.xml @@ -44,6 +44,10 @@ description="soil texture class level 4 needed as input for the NOAH-MP land surface model" packages="sf_noahmp_in"/> + + diff --git a/src/core_atmosphere/physics/mpas_atmphys_lsm_noahmpinit.F b/src/core_atmosphere/physics/mpas_atmphys_lsm_noahmpinit.F index c4bc8fc980..eae2817320 100644 --- a/src/core_atmosphere/physics/mpas_atmphys_lsm_noahmpinit.F +++ b/src/core_atmosphere/physics/mpas_atmphys_lsm_noahmpinit.F @@ -231,6 +231,7 @@ subroutine noahmp_init(configs,mesh,diag_physics,diag_physics_noahmp,output_noah integer,pointer:: nsoilcomps integer,dimension(:),pointer:: isltyp,ivgtyp + integer,dimension(:),pointer:: soil_color integer,dimension(:),pointer:: isnowxy integer,dimension(:),pointer:: irnumsi,irnummi,irnumfi @@ -315,10 +316,12 @@ subroutine noahmp_init(configs,mesh,diag_physics,diag_physics_noahmp,output_noah call mpas_pool_get_array(sfc_input,'dzs' ,dzs ) call mpas_pool_get_array(sfc_input,'isltyp',isltyp) call mpas_pool_get_array(sfc_input,'ivgtyp',ivgtyp) + call mpas_pool_get_array(sfc_input,'soil_color',soil_color) do i = its, ite mpas_noahmp%isltyp(i) = isltyp(i) mpas_noahmp%ivgtyp(i) = ivgtyp(i) + mpas_noahmp%soil_color(i) = soil_color(i) enddo do ns = 1, nsoil mpas_noahmp%dzs(ns) = dzs(ns,its) diff --git a/src/core_atmosphere/physics/physics_noahmp/drivers/mpas/ConfigVarInTransferMod.F90 b/src/core_atmosphere/physics/physics_noahmp/drivers/mpas/ConfigVarInTransferMod.F90 index 2de35ed9c2..288d77f098 100644 --- a/src/core_atmosphere/physics/physics_noahmp/drivers/mpas/ConfigVarInTransferMod.F90 +++ b/src/core_atmosphere/physics/physics_noahmp/drivers/mpas/ConfigVarInTransferMod.F90 @@ -62,7 +62,7 @@ subroutine ConfigVarInTransfer(noahmp, NoahmpIO) ! config domain variable noahmp%config%domain%SurfaceType = 1 noahmp%config%domain%NumSwRadBand = 2 - noahmp%config%domain%SoilColor = 4 + noahmp%config%domain%SoilColor = NoahmpIO%soil_color(I) noahmp%config%domain%NumCropGrowStage = 8 noahmp%config%domain%FlagSoilProcess = NoahmpIO%calculate_soil noahmp%config%domain%NumSoilTimeStep = NoahmpIO%soil_update_steps diff --git a/src/core_atmosphere/physics/physics_noahmp/drivers/mpas/NoahmpIOVarFinalizeMod.F90 b/src/core_atmosphere/physics/physics_noahmp/drivers/mpas/NoahmpIOVarFinalizeMod.F90 index 66458d638e..2782d8bf49 100644 --- a/src/core_atmosphere/physics/physics_noahmp/drivers/mpas/NoahmpIOVarFinalizeMod.F90 +++ b/src/core_atmosphere/physics/physics_noahmp/drivers/mpas/NoahmpIOVarFinalizeMod.F90 @@ -37,6 +37,7 @@ subroutine NoahmpIOVarFinalizeDefault(NoahmpIO) if ( allocated (NoahmpIO%zsoil) ) deallocate ( NoahmpIO%zsoil ) ! depth to soil interfaces [m] if ( allocated (NoahmpIO%ivgtyp) ) deallocate ( NoahmpIO%ivgtyp ) ! vegetation type if ( allocated (NoahmpIO%isltyp) ) deallocate ( NoahmpIO%isltyp ) ! soil type + if ( allocated (NoahmpIO%soil_color)) deallocate ( NoahmpIO%soil_color ) ! soil color if ( allocated (NoahmpIO%vegfra) ) deallocate ( NoahmpIO%vegfra ) ! vegetation fraction [] if ( allocated (NoahmpIO%tmn) ) deallocate ( NoahmpIO%tmn ) ! deep soil temperature [K] if ( allocated (NoahmpIO%xland) ) deallocate ( NoahmpIO%xland ) ! =2 ocean; =1 land/seaice diff --git a/src/core_atmosphere/physics/physics_noahmp/drivers/mpas/NoahmpIOVarInitMod.F90 b/src/core_atmosphere/physics/physics_noahmp/drivers/mpas/NoahmpIOVarInitMod.F90 index 4f3c3f4f2c..b7fa7077c1 100644 --- a/src/core_atmosphere/physics/physics_noahmp/drivers/mpas/NoahmpIOVarInitMod.F90 +++ b/src/core_atmosphere/physics/physics_noahmp/drivers/mpas/NoahmpIOVarInitMod.F90 @@ -41,6 +41,7 @@ subroutine NoahmpIOVarInitDefault(NoahmpIO) if ( .not. allocated (NoahmpIO%zsoil) ) allocate ( NoahmpIO%zsoil (1:nsoil ) ) ! depth to soil interfaces [m] if ( .not. allocated (NoahmpIO%ivgtyp) ) allocate ( NoahmpIO%ivgtyp (its:ite ) ) ! vegetation type if ( .not. allocated (NoahmpIO%isltyp) ) allocate ( NoahmpIO%isltyp (its:ite ) ) ! soil type + if ( .not. allocated (NoahmpIO%soil_color)) allocate ( NoahmpIO%soil_color (its:ite ) ) ! soil color if ( .not. allocated (NoahmpIO%vegfra) ) allocate ( NoahmpIO%vegfra (its:ite ) ) ! vegetation fraction [] if ( .not. allocated (NoahmpIO%tmn) ) allocate ( NoahmpIO%tmn (its:ite ) ) ! deep soil temperature [K] if ( .not. allocated (NoahmpIO%xland) ) allocate ( NoahmpIO%xland (its:ite ) ) ! =2 ocean; =1 land/seaice @@ -469,6 +470,7 @@ subroutine NoahmpIOVarInitDefault(NoahmpIO) NoahmpIO%ice = undefined_int NoahmpIO%ivgtyp = undefined_int NoahmpIO%isltyp = undefined_int + NoahmpIO%soil_color = undefined_int NoahmpIO%isnowxy = undefined_int NoahmpIO%coszen = undefined_real NoahmpIO%xlat = undefined_real diff --git a/src/core_atmosphere/physics/physics_noahmp/drivers/mpas/NoahmpIOVarType.F90 b/src/core_atmosphere/physics/physics_noahmp/drivers/mpas/NoahmpIOVarType.F90 index 05a29d7035..2b228c571e 100644 --- a/src/core_atmosphere/physics/physics_noahmp/drivers/mpas/NoahmpIOVarType.F90 +++ b/src/core_atmosphere/physics/physics_noahmp/drivers/mpas/NoahmpIOVarType.F90 @@ -117,6 +117,7 @@ module NoahmpIOVarType real(kind=kind_noahmp), allocatable, dimension(:) :: soilcl2 ! Soil texture class with depth real(kind=kind_noahmp), allocatable, dimension(:) :: soilcl3 ! Soil texture class with depth real(kind=kind_noahmp), allocatable, dimension(:) :: soilcl4 ! Soil texture class with depth + real(kind=kind_noahmp), allocatable, dimension(:) :: soil_color ! Soil color class real(kind=kind_noahmp), allocatable, dimension(:,:) :: bexp_3D ! C-H B exponent real(kind=kind_noahmp), allocatable, dimension(:,:) :: smcdry_3D ! Soil Moisture Limit: Dry real(kind=kind_noahmp), allocatable, dimension(:,:) :: smcwlt_3D ! Soil Moisture Limit: Wilt From 88f314c6a82a1466b50d6d92f6857e6e3e29e728 Mon Sep 17 00:00:00 2001 From: Michael Barlage Date: Tue, 9 Dec 2025 19:22:06 +0000 Subject: [PATCH 3/3] add ncar change to grid specific humidity to mixing ratio conversion --- .../physics_noahmp/drivers/mpas/EnergyVarOutTransferMod.F90 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/core_atmosphere/physics/physics_noahmp/drivers/mpas/EnergyVarOutTransferMod.F90 b/src/core_atmosphere/physics/physics_noahmp/drivers/mpas/EnergyVarOutTransferMod.F90 index a3124b3a2e..a150bf9b6e 100644 --- a/src/core_atmosphere/physics/physics_noahmp/drivers/mpas/EnergyVarOutTransferMod.F90 +++ b/src/core_atmosphere/physics/physics_noahmp/drivers/mpas/EnergyVarOutTransferMod.F90 @@ -136,7 +136,7 @@ subroutine EnergyVarOutTransfer(noahmp, NoahmpIO) NoahmpIO%CHB2XY (I) = noahmp%energy%state%ExchCoeffSh2mBare NoahmpIO%Q2MVXY (I) = noahmp%energy%state%SpecHumidity2mVeg /(1.0-noahmp%energy%state%SpecHumidity2mVeg) ! spec humidity to mixing ratio NoahmpIO%Q2MBXY (I) = noahmp%energy%state%SpecHumidity2mBare/(1.0-noahmp%energy%state%SpecHumidity2mBare) - NoahmpIO%Q2MXY (I) = noahmp%energy%state%SpecHumidity2m/(1.0-noahmp%energy%state%SpecHumidity2m) + NoahmpIO%Q2MXY (I) = NoahmpIO%Q2MBXY(I) * ( 1 - NoahmpIO%FVEGXY(I) ) + NoahmpIO%Q2MVXY(I) * NoahmpIO%FVEGXY(I) NoahmpIO%IRRSPLH (I) = NoahmpIO%IRRSPLH(I) + & (noahmp%energy%flux%HeatLatentIrriEvap * noahmp%config%domain%MainTimeStep) NoahmpIO%TSLB (I,1:NumSoilLayer) = noahmp%energy%state%TemperatureSoilSnow(1:NumSoilLayer)