From 246b7f5d03355a49adbe152245beaea10030a469 Mon Sep 17 00:00:00 2001 From: Nicole Jeffery Date: Wed, 11 Oct 2023 17:00:31 -0500 Subject: [PATCH 001/451] Adds mpas interface for icepack bgc Needs to be tested and merged with main icepack-integration branch BFB in the physics. --- .../namelist_defaults_mpassi.xml | 12 +- components/mpas-seaice/driver/ice_comp_mct.F | 107 +- components/mpas-seaice/src/Registry.xml | 12 +- .../mpas-seaice/src/column/ice_algae.F90 | 5 +- .../mpas-seaice/src/column/ice_colpkg.F90 | 1 + .../mpas_seaice_core_interface.F | 8 +- .../src/shared/mpas_seaice_column.F | 95 +- .../src/shared/mpas_seaice_icepack.F | 1191 ++++++++--------- .../src/shared/mpas_seaice_initialize.F | 6 +- 9 files changed, 711 insertions(+), 726 deletions(-) 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 735be1ce8e11..fe88816d271a 100644 --- a/components/mpas-seaice/bld/namelist_files/namelist_defaults_mpassi.xml +++ b/components/mpas-seaice/bld/namelist_files/namelist_defaults_mpassi.xml @@ -317,12 +317,12 @@ 0.0 0.0 0.5 -0.0 -0.0 -0.0 -0.0 -0.0 -0.0 +-1.0 +-1.0 +-1.0 +-1.0 +-1.0 +-1.0 7.0 7.0 7.0 diff --git a/components/mpas-seaice/driver/ice_comp_mct.F b/components/mpas-seaice/driver/ice_comp_mct.F index 8649380aad8a..3385fa0c37d2 100644 --- a/components/mpas-seaice/driver/ice_comp_mct.F +++ b/components/mpas-seaice/driver/ice_comp_mct.F @@ -1909,6 +1909,7 @@ subroutine ice_import_mct(x2i_i, errorCode)!{{{ call mpas_pool_get_config(configs, "config_use_aerosols", config_use_aerosols) call mpas_pool_get_config(configs, "config_use_modal_aerosols", config_use_modal_aerosols) call mpas_pool_get_config(configs, "config_use_column_biogeochemistry", config_use_column_biogeochemistry) + call mpas_pool_get_config(configs, "config_use_zaerosols", config_use_zaerosols) call mpas_pool_get_subpool(block_ptr % structs, 'mesh', meshPool) call mpas_pool_get_subpool(block_ptr % structs, 'ocean_coupling', oceanCoupling) @@ -1947,9 +1948,13 @@ subroutine ice_import_mct(x2i_i, errorCode)!{{{ call mpas_pool_get_array(aerosols, "atmosAerosolFlux", atmosAerosolFlux) endif + call mpas_pool_get_subpool(block_ptr % structs, 'biogeochemistry', biogeochemistry) + if (config_use_zaerosols) then + call mpas_pool_get_array(biogeochemistry, 'oceanZAerosolConc', oceanZAerosolConc) + call mpas_pool_get_array(biogeochemistry, 'atmosBlackCarbonFlux', atmosBlackCarbonFlux) + call mpas_pool_get_array(biogeochemistry, 'atmosDustFlux', atmosDustFlux) + endif if (config_use_column_biogeochemistry) then - call mpas_pool_get_config(configs, "config_use_zaerosols", config_use_zaerosols) - call mpas_pool_get_subpool(block_ptr % structs, 'biogeochemistry', biogeochemistry) call mpas_pool_get_array(biogeochemistry, 'oceanAlgaeConc', oceanAlgaeConc) call mpas_pool_get_array(biogeochemistry, 'oceanDOCConc', oceanDOCConc) @@ -1963,15 +1968,10 @@ subroutine ice_import_mct(x2i_i, errorCode)!{{{ call mpas_pool_get_array(biogeochemistry, 'oceanHumicsConc', oceanHumicsConc) call mpas_pool_get_array(biogeochemistry, 'oceanParticulateIronConc', oceanParticulateIronConc) call mpas_pool_get_array(biogeochemistry, 'oceanDissolvedIronConc', oceanDissolvedIronConc) - call mpas_pool_get_array(biogeochemistry, 'oceanZAerosolConc', oceanZAerosolConc) call mpas_pool_get_array(biogeochemistry, 'carbonToNitrogenRatioAlgae', carbonToNitrogenRatioAlgae) call mpas_pool_get_array(biogeochemistry, 'carbonToNitrogenRatioDON', carbonToNitrogenRatioDON) call mpas_pool_get_array(biogeochemistry, 'DOCPoolFractions', DOCPoolFractions) - if (config_use_zaerosols) then - call mpas_pool_get_array(biogeochemistry, "atmosBlackCarbonFlux", atmosBlackCarbonFlux) - call mpas_pool_get_array(biogeochemistry, "atmosDustFlux", atmosDustFlux) - endif endif do i = 1, nCellsSolve @@ -2060,6 +2060,42 @@ subroutine ice_import_mct(x2i_i, errorCode)!{{{ endif endif + ! set aerosols, if configured + if (config_use_zaerosols) then + oceanZAerosolConc(1,i) = 0.0_RKIND !x2i_i % rAttr(index_x2i_So_zaer1, n) + oceanZAerosolConc(2,i) = 0.0_RKIND !x2i_i % rAttr(index_x2i_So_zaer2, n) + oceanZAerosolConc(3,i) = 0.0_RKIND !x2i_i % rAttr(index_x2i_So_zaer3, n) + oceanZAerosolConc(4,i) = 0.0_RKIND !x2i_i % rAttr(index_x2i_So_zaer4, n) + oceanZAerosolConc(5,i) = 0.0_RKIND !x2i_i % rAttr(index_x2i_So_zaer5, n) + oceanZAerosolConc(6,i) = 0.0_RKIND !x2i_i % rAttr(index_x2i_So_zaer6, n) + if (config_use_modal_aerosols) then + atmosBlackCarbonFlux(1,i) = x2i_i % rAttr(index_x2i_Faxa_bcphodry, n) & + + x2i_i % rAttr(index_x2i_Faxa_bcphidry, n) + atmosBlackCarbonFlux(2,i) = x2i_i % rAttr(index_x2i_Faxa_bcphiwet, n) + !combine wet and dry dust + atmosDustFlux(1,i) = x2i_i % rAttr(index_x2i_Faxa_dstwet1, n) & + + x2i_i % rAttr(index_x2i_Faxa_dstdry1, n) + atmosDustFlux(2,i) = x2i_i % rAttr(index_x2i_Faxa_dstwet2, n) & + + x2i_i % rAttr(index_x2i_Faxa_dstdry2, n) + atmosDustFlux(3,i) = x2i_i % rAttr(index_x2i_Faxa_dstwet3, n) & + + x2i_i % rAttr(index_x2i_Faxa_dstdry3, n) + atmosDustFlux(4,i) = x2i_i % rAttr(index_x2i_Faxa_dstwet4, n) & + + x2i_i % rAttr(index_x2i_Faxa_dstdry4, n) + else + atmosBlackCarbonFlux(1,i) = x2i_i % rAttr(index_x2i_Faxa_bcphodry, n) + atmosBlackCarbonFlux(2,i) = x2i_i % rAttr(index_x2i_Faxa_bcphidry, n) & + + x2i_i % rAttr(index_x2i_Faxa_bcphiwet, n) + ! combine wet and dry dust + atmosDustFlux(1,i) = x2i_i % rAttr(index_x2i_Faxa_dstwet1, n) & + + x2i_i % rAttr(index_x2i_Faxa_dstdry1, n) + atmosDustFlux(2,i) = x2i_i % rAttr(index_x2i_Faxa_dstwet2, n) & + + x2i_i % rAttr(index_x2i_Faxa_dstdry2, n) + atmosDustFlux(3,i) = x2i_i % rAttr(index_x2i_Faxa_dstwet3, n) & + + x2i_i % rAttr(index_x2i_Faxa_dstdry3, n) + atmosDustFlux(4,i) = x2i_i % rAttr(index_x2i_Faxa_dstwet4, n) & + + x2i_i % rAttr(index_x2i_Faxa_dstdry4, n) + endif + endif ! import biogeochemistry fields, if configured if (config_use_column_biogeochemistry) then oceanAlgaeConc(1,i) = x2i_i % rAttr(index_x2i_So_algae1, n) @@ -2081,42 +2117,6 @@ subroutine ice_import_mct(x2i_i, errorCode)!{{{ oceanParticulateIronConc(2,i) = x2i_i % rAttr(index_x2i_So_fep2, n) oceanDissolvedIronConc(1,i) = x2i_i % rAttr(index_x2i_So_fed1, n) oceanDissolvedIronConc(2,i) = x2i_i % rAttr(index_x2i_So_fed2, n) - oceanZAerosolConc(1,i) = 0.0_RKIND !x2i_i % rAttr(index_x2i_So_zaer1, n) - oceanZAerosolConc(2,i) = 0.0_RKIND !x2i_i % rAttr(index_x2i_So_zaer2, n) - oceanZAerosolConc(3,i) = 0.0_RKIND !x2i_i % rAttr(index_x2i_So_zaer3, n) - oceanZAerosolConc(4,i) = 0.0_RKIND !x2i_i % rAttr(index_x2i_So_zaer4, n) - oceanZAerosolConc(5,i) = 0.0_RKIND !x2i_i % rAttr(index_x2i_So_zaer5, n) - oceanZAerosolConc(6,i) = 0.0_RKIND !x2i_i % rAttr(index_x2i_So_zaer6, n) - ! set aerosols, if configured - if (config_use_zaerosols) then - if (config_use_modal_aerosols) then - atmosBlackCarbonFlux(1,i) = x2i_i % rAttr(index_x2i_Faxa_bcphodry, n) & - + x2i_i % rAttr(index_x2i_Faxa_bcphidry, n) - atmosBlackCarbonFlux(2,i) = x2i_i % rAttr(index_x2i_Faxa_bcphiwet, n) - ! combine wet and dry dust - atmosDustFlux(1,i) = x2i_i % rAttr(index_x2i_Faxa_dstwet1, n) & - + x2i_i % rAttr(index_x2i_Faxa_dstdry1, n) - atmosDustFlux(2,i) = x2i_i % rAttr(index_x2i_Faxa_dstwet2, n) & - + x2i_i % rAttr(index_x2i_Faxa_dstdry2, n) - atmosDustFlux(3,i) = x2i_i % rAttr(index_x2i_Faxa_dstwet3, n) & - + x2i_i % rAttr(index_x2i_Faxa_dstdry3, n) - atmosDustFlux(4,i) = x2i_i % rAttr(index_x2i_Faxa_dstwet4, n) & - + x2i_i % rAttr(index_x2i_Faxa_dstdry4, n) - else - atmosBlackCarbonFlux(1,i) = x2i_i % rAttr(index_x2i_Faxa_bcphodry, n) - atmosBlackCarbonFlux(2,i) = x2i_i % rAttr(index_x2i_Faxa_bcphidry, n) & - + x2i_i % rAttr(index_x2i_Faxa_bcphiwet, n) - ! combine wet and dry dust - atmosDustFlux(1,i) = x2i_i % rAttr(index_x2i_Faxa_dstwet1, n) & - + x2i_i % rAttr(index_x2i_Faxa_dstdry1, n) - atmosDustFlux(2,i) = x2i_i % rAttr(index_x2i_Faxa_dstwet2, n) & - + x2i_i % rAttr(index_x2i_Faxa_dstdry2, n) - atmosDustFlux(3,i) = x2i_i % rAttr(index_x2i_Faxa_dstwet3, n) & - + x2i_i % rAttr(index_x2i_Faxa_dstdry3, n) - atmosDustFlux(4,i) = x2i_i % rAttr(index_x2i_Faxa_dstwet4, n) & - + x2i_i % rAttr(index_x2i_Faxa_dstdry4, n) - endif - endif endif end do @@ -2179,6 +2179,11 @@ subroutine ice_import_mct(x2i_i, errorCode)!{{{ call mpas_pool_get_field(aerosols, "atmosAerosolFlux", atmosAerosolFluxField) endif + if (config_use_zaerosols) then + call mpas_pool_get_field(biogeochemistry, "atmosBlackCarbonFlux", atmosBlackCarbonFluxField) + call mpas_pool_get_field(biogeochemistry, "atmosDustFlux", atmosDustFluxField) + call mpas_pool_get_field(biogeochemistry, 'oceanZAerosolConc', oceanZAerosolConcField) + endif if (config_use_column_biogeochemistry) then call mpas_pool_get_subpool(domain % blocklist % structs, 'biogeochemistry', biogeochemistry) @@ -2194,11 +2199,6 @@ subroutine ice_import_mct(x2i_i, errorCode)!{{{ call mpas_pool_get_field(biogeochemistry, 'oceanHumicsConc', oceanHumicsConcField) call mpas_pool_get_field(biogeochemistry, 'oceanParticulateIronConc', oceanParticulateIronConcField) call mpas_pool_get_field(biogeochemistry, 'oceanDissolvedIronConc', oceanDissolvedIronConcField) - call mpas_pool_get_field(biogeochemistry, 'oceanZAerosolConc', oceanZAerosolConcField) - if (config_use_zaerosols) then - call mpas_pool_get_field(biogeochemistry, "atmosBlackCarbonFlux", atmosBlackCarbonFluxField) - call mpas_pool_get_field(biogeochemistry, "atmosDustFlux", atmosDustFluxField) - endif endif call mpas_dmpar_exch_halo_field(seaSurfaceTemperatureField) @@ -2229,7 +2229,11 @@ subroutine ice_import_mct(x2i_i, errorCode)!{{{ if (config_use_aerosols) then call mpas_dmpar_exch_halo_field(atmosAerosolFluxField) endif - + if (config_use_zaerosols) then + call mpas_dmpar_exch_halo_field(atmosBlackCarbonFluxField) + call mpas_dmpar_exch_halo_field(atmosDustFluxField) + call mpas_dmpar_exch_halo_field(oceanZAerosolConcField) + endif if (config_use_column_biogeochemistry) then call mpas_dmpar_exch_halo_field(oceanAlgaeConcField) call mpas_dmpar_exch_halo_field(oceanDOCConcField) @@ -2243,11 +2247,6 @@ subroutine ice_import_mct(x2i_i, errorCode)!{{{ call mpas_dmpar_exch_halo_field(oceanHumicsConcField) call mpas_dmpar_exch_halo_field(oceanParticulateIronConcField) call mpas_dmpar_exch_halo_field(oceanDissolvedIronConcField) - call mpas_dmpar_exch_halo_field(oceanZAerosolConcField) - if (config_use_zaerosols) then - call mpas_dmpar_exch_halo_field(atmosBlackCarbonFluxField) - call mpas_dmpar_exch_halo_field(atmosDustFluxField) - endif endif ! REVISION HISTORY: diff --git a/components/mpas-seaice/src/Registry.xml b/components/mpas-seaice/src/Registry.xml index c99741fe66ab..c424b92c718c 100644 --- a/components/mpas-seaice/src/Registry.xml +++ b/components/mpas-seaice/src/Registry.xml @@ -1414,32 +1414,32 @@ possible_values="-1 = entirely in the mobile phase; 0 = retention dominated; 1 = release dominated; 0.5 = equal but rapid exchange; 2 = equal but slow exchange" icepack_name="feptype_1" /> - - - - - - domain % blocklist do while (associated(block)) @@ -3206,7 +3214,7 @@ subroutine column_radiation(domain, clock, lInitialization) allocate(aerosolsArray(4*nAerosols,nCategories)) allocate(index_shortwaveAerosol(maxAerosolType)) - if (.not. config_use_column_biogeochemistry) then + if (.not. config_use_zaerosols) then index_shortwaveAerosol(1:maxAerosolType) = 1 else do iAerosol = 1, maxAerosolType @@ -3215,7 +3223,7 @@ subroutine column_radiation(domain, clock, lInitialization) endif setGetPhysicsTracers = .true. - setGetBGCTracers = config_use_column_biogeochemistry + setGetBGCTracers = (config_use_column_biogeochemistry .or. config_use_zaerosols) !$omp parallel do default(shared) firstprivate(aerosolsArray,index_shortwaveAerosol) & !$omp& private(iCategory,iAerosol,lonCellColumn) @@ -3382,7 +3390,8 @@ subroutine column_ridging(domain) ! configs logical, pointer :: & - config_use_column_biogeochemistry + config_use_column_biogeochemistry, & + config_use_zaerosols real(kind=RKIND), pointer :: & config_dt @@ -3479,6 +3488,7 @@ subroutine column_ridging(domain) call MPAS_pool_get_config(block % configs, "config_dynamics_subcycle_number", config_dynamics_subcycle_number) call MPAS_pool_get_config(block % configs, "config_use_column_biogeochemistry", config_use_column_biogeochemistry) + call MPAS_pool_get_config(block % configs, "config_use_zaerosols", config_use_zaerosols) call MPAS_pool_get_array(velocity_solver, "dynamicsTimeStep", dynamicsTimeStep) @@ -3535,7 +3545,7 @@ subroutine column_ridging(domain) allocate(newlyFormedIceLogical(nCategories)) setGetPhysicsTracers = .true. - setGetBGCTracers = config_use_column_biogeochemistry + setGetBGCTracers = (config_use_column_biogeochemistry .or. config_use_zaerosols) ! code abort abortFlag = .false. @@ -3994,12 +4004,14 @@ subroutine column_biogeochemistry(domain) endif setGetPhysicsTracers = .true. - setGetBGCTracers = config_use_column_biogeochemistry + setGetBGCTracers = (config_use_column_biogeochemistry .or. config_use_zaerosols) ! code abort abortFlag = .false. abortMessage = "" + atmosBioFluxes(:,:) = 0.0_RKIND + do iCell = 1, nCellsSolve ! newly formed ice do iCategory = 1, nCategories @@ -4041,7 +4053,6 @@ subroutine column_biogeochemistry(domain) atmosDustFlux(iBioTracers,iCell) = 1.e-13_RKIND enddo #endif - atmosBioFluxes(:,:) = 0.0_RKIND if (config_use_zaerosols) then indexj = ciceTracerObject % index_verticalAerosolsConcLayer(1) do iBioTracers = 1, maxBCType @@ -4492,7 +4503,8 @@ subroutine seaice_column_aggregate(domain) ocean_coupling logical, pointer :: & - config_use_column_biogeochemistry + config_use_column_biogeochemistry, & + config_use_zaerosols real(kind=RKIND), dimension(:), pointer :: & iceAreaCell, & @@ -4527,6 +4539,7 @@ subroutine seaice_column_aggregate(domain) call MPAS_pool_get_subpool(block % structs, "ocean_coupling", ocean_coupling) call MPAS_pool_get_config(block % configs, "config_use_column_biogeochemistry", config_use_column_biogeochemistry) + call MPAS_pool_get_config(block % configs, "config_use_zaerosols", config_use_zaerosols) call MPAS_pool_get_dimension(mesh, "nCellsSolve", nCellsSolve) call MPAS_pool_get_dimension(mesh, "nCategories", nCategories) @@ -4544,7 +4557,7 @@ subroutine seaice_column_aggregate(domain) call MPAS_pool_get_array(ocean_coupling, "seaFreezingTemperature", seaFreezingTemperature) setGetPhysicsTracers = .true. - setGetBGCTracers = config_use_column_biogeochemistry + setGetBGCTracers = (config_use_column_biogeochemistry .or. config_use_zaerosols) do iCell = 1, nCellsSolve @@ -4691,7 +4704,8 @@ subroutine seaice_column_coupling_prep(domain) logical, pointer :: & config_use_ocean_mixed_layer, & config_include_pond_freshwater_feedback, & - config_use_column_biogeochemistry + config_use_column_biogeochemistry, & + config_use_zaerosols type(MPAS_pool_type), pointer :: & oceanCoupling, & @@ -4802,6 +4816,7 @@ subroutine seaice_column_coupling_prep(domain) call MPAS_pool_get_config(domain % configs, "config_dt", config_dt) call MPAS_pool_get_config(domain % configs, "config_include_pond_freshwater_feedback", config_include_pond_freshwater_feedback) call MPAS_pool_get_config(domain % configs, "config_use_column_biogeochemistry", config_use_column_biogeochemistry) + call MPAS_pool_get_config(domain % configs, "config_use_zaerosols", config_use_zaerosols) call MPAS_pool_get_config(domain % configs, "config_ratio_C_to_N_diatoms", config_ratio_C_to_N_diatoms) call MPAS_pool_get_config(domain % configs, "config_ratio_C_to_N_small_plankton", config_ratio_C_to_N_small_plankton) call MPAS_pool_get_config(domain % configs, "config_ratio_C_to_N_phaeocystis", config_ratio_C_to_N_phaeocystis) @@ -4994,10 +5009,12 @@ subroutine seaice_column_coupling_prep(domain) !----------------------------------------------------------------- ! Define ocean biogeochemical flux variables !----------------------------------------------------------------- - if (config_use_column_biogeochemistry) then + + oceanBioFluxesAll(:) = 0.0_RKIND + + if (config_use_column_biogeochemistry .or. config_use_zaerosols) then totalOceanCarbonFlux(iCell) = 0.0_RKIND - oceanBioFluxesAll(:) = 0.0_RKIND oceanAlgaeFlux(:,iCell) = 0.0_RKIND oceanDOCFlux(:,iCell) = 0.0_RKIND oceanDICFlux(:,iCell) = 0.0_RKIND @@ -5108,7 +5125,7 @@ subroutine seaice_column_coupling_prep(domain) totalOceanCarbonFlux(iCell) = totalOceanCarbonFlux(iCell) + & oceanHumicsFlux(iCell) - endif ! config_use_column_biogeochemistry + endif ! config_use_column_biogeochemistry .or. config_use_zaerosols enddo ! iCell @@ -5156,7 +5173,8 @@ subroutine seaice_column_scale_fluxes(domain) mesh logical, pointer :: & - config_use_column_biogeochemistry + config_use_column_biogeochemistry, & + config_use_zaerosols real(kind=RKIND), dimension(:), pointer :: & iceAreaCell, & @@ -5216,6 +5234,7 @@ subroutine seaice_column_scale_fluxes(domain) iBioTracers call MPAS_pool_get_config(domain % configs, "config_use_column_biogeochemistry", config_use_column_biogeochemistry) + call MPAS_pool_get_config(domain % configs, "config_use_zaerosols", config_use_zaerosols) block => domain % blocklist do while (associated(block)) @@ -5308,6 +5327,9 @@ subroutine seaice_column_scale_fluxes(domain) albedoVisibleDiffuseCell(iCell) = albedoVisibleDiffuseCell(iCell) * iceAreaInverse albedoIRDiffuseCell(iCell) = albedoIRDiffuseCell(iCell) * iceAreaInverse + if (config_use_zaerosols) & + oceanDustIronFlux(iCell) = oceanDustIronFlux(iCell) * iceAreaInverse + if (config_use_column_biogeochemistry) then oceanNitrateFlux(iCell) = oceanNitrateFlux(iCell) * iceAreaInverse @@ -5317,7 +5339,6 @@ subroutine seaice_column_scale_fluxes(domain) oceanDMSPdFlux(iCell) = oceanDMSPdFlux(iCell) * iceAreaInverse oceanDMSFlux(iCell) = oceanDMSFlux(iCell) * iceAreaInverse oceanHumicsFlux(iCell) = oceanHumicsFlux(iCell) * iceAreaInverse - oceanDustIronFlux(iCell) = oceanDustIronFlux(iCell) * iceAreaInverse do iBioTracers = 1, maxAlgaeType oceanAlgaeFlux(iBioTracers,iCell) = oceanAlgaeFlux(iBioTracers,iCell) * iceAreaInverse @@ -5360,6 +5381,9 @@ subroutine seaice_column_scale_fluxes(domain) albedoVisibleDiffuseCell(iCell) = 0.0_RKIND albedoIRDiffuseCell(iCell) = 0.0_RKIND + if (config_use_zaerosols) & + oceanDustIronFlux(iCell) = 0.0_RKIND + if (config_use_column_biogeochemistry) then oceanNitrateFlux(iCell) = 0.0_RKIND @@ -5369,7 +5393,6 @@ subroutine seaice_column_scale_fluxes(domain) oceanDMSPdFlux(iCell) = 0.0_RKIND oceanDMSFlux(iCell) = 0.0_RKIND oceanHumicsFlux(iCell) = 0.0_RKIND - oceanDustIronFlux(iCell) = 0.0_RKIND oceanAlgaeFlux(:,iCell) = 0.0_RKIND oceanDOCFlux(:,iCell) = 0.0_RKIND oceanDICFlux(:,iCell) = 0.0_RKIND @@ -6399,12 +6422,14 @@ subroutine init_column_tracer_object(domain, tracerObject) nZBGCTracers logical, pointer :: & - config_use_column_biogeochemistry + config_use_column_biogeochemistry, & + config_use_zaerosols call MPAS_pool_get_dimension(domain % blocklist % dimensions, "nCategories", nCategories) call MPAS_pool_get_dimension(domain % blocklist % dimensions, "nZBGCTracers", nZBGCTracers) call MPAS_pool_get_config(domain % configs, "config_use_column_biogeochemistry", config_use_column_biogeochemistry) + call MPAS_pool_get_config(domain % configs, "config_use_zaerosols", config_use_zaerosols) ! get the number of CICE tracers in trcrn call init_column_tracer_object_tracer_number(domain, tracerObject) @@ -6428,7 +6453,7 @@ subroutine init_column_tracer_object(domain, tracerObject) call init_column_tracer_object_ancestor_indices(domain, tracerObject) ! biogeochemistry - if (config_use_column_biogeochemistry) then + if (config_use_column_biogeochemistry .or. config_use_zaerosols) then allocate(tracerObject % index_LayerIndexToDataArray(nZBGCTracers)) allocate(tracerObject % index_LayerIndexToBioIndex(nZBGCTracers)) @@ -6636,7 +6661,7 @@ subroutine init_column_tracer_object_tracer_number(domain, tracerObject) ! biogeochemistry !----------------------------------------------------------------------- - if (config_use_column_biogeochemistry) then + if (config_use_column_biogeochemistry .or. config_use_zaerosols) then ! save tracer number without bio tracers counted tracerObject % nTracersNotBio = tracerObject % nTracers @@ -10257,11 +10282,11 @@ subroutine check_column_package_configs(domain) endif ! check biogeochemistry flags: - if (.not. config_use_column_biogeochemistry .and. (config_use_brine .or. config_use_vertical_zsalinity .or. & - config_use_vertical_biochemistry .or. config_use_shortwave_bioabsorption .or. config_use_vertical_tracers .or. & + if (.not. config_use_column_biogeochemistry .and. (config_use_vertical_zsalinity .or. & + config_use_vertical_biochemistry .or. & config_use_skeletal_biochemistry .or. config_use_nitrate .or. config_use_carbon .or. config_use_chlorophyll .or. & config_use_ammonium .or. config_use_silicate .or. config_use_DMS .or. config_use_nonreactive .or. config_use_humics .or. & - config_use_DON .or. config_use_iron .or. config_use_modal_aerosols .or. config_use_zaerosols)) then + config_use_DON .or. config_use_iron)) then call mpas_log_write(& "check_column_package_configs: config_use_column_biogeochemistry = false. "//& "All biogeochemistry namelist flags must also be false", & @@ -14775,8 +14800,9 @@ subroutine seaice_column_reinitialize_diagnostics_bgc(domain) config_use_column_biogeochemistry, & config_use_column_shortwave, & config_use_column_package, & - config_use_vertical_biochemistry, & - config_use_vertical_zsalinity + config_use_vertical_tracers, & + config_use_vertical_zsalinity, & + config_use_zaerosols call MPAS_pool_get_config(domain % blocklist % configs, "config_use_column_package", config_use_column_package) @@ -14787,15 +14813,16 @@ subroutine seaice_column_reinitialize_diagnostics_bgc(domain) ! biogeochemistry call MPAS_pool_get_config(block % configs, "config_use_column_biogeochemistry", config_use_column_biogeochemistry) - call MPAS_pool_get_config(block % configs, "config_use_vertical_biochemistry", config_use_vertical_biochemistry) + call MPAS_pool_get_config(block % configs, "config_use_zaerosols", config_use_zaerosols) + call MPAS_pool_get_config(block % configs, "config_use_vertical_tracers", config_use_vertical_tracers) call MPAS_pool_get_config(block % configs, "config_use_vertical_zsalinity", config_use_vertical_zsalinity) - if (config_use_column_biogeochemistry) then + if (config_use_column_biogeochemistry .or. config_use_zaerosols) then call MPAS_pool_get_subpool(block % structs, "biogeochemistry", biogeochemistryPool) call MPAS_pool_get_subpool(block % structs, "diagnostics_biogeochemistry", diagnostics_biogeochemistryPool) - if (config_use_vertical_biochemistry) then + if (config_use_vertical_tracers) then call MPAS_pool_get_array(biogeochemistryPool, "primaryProduction", primaryProduction) call MPAS_pool_get_array(biogeochemistryPool, "totalChlorophyll", totalChlorophyll) call MPAS_pool_get_array(biogeochemistryPool, "netSpecificAlgalGrowthRate", netSpecificAlgalGrowthRate) @@ -14842,7 +14869,7 @@ subroutine seaice_column_reinitialize_diagnostics_bgc(domain) call MPAS_pool_get_config(block % configs, "config_use_column_shortwave", config_use_column_shortwave) - if (config_use_column_biogeochemistry .or. config_use_column_shortwave) then + if (config_use_column_biogeochemistry .or. config_use_column_shortwave .or. config_use_zaerosols) then call MPAS_pool_get_subpool(block % structs, "biogeochemistry", biogeochemistryPool) call MPAS_pool_get_array(biogeochemistryPool, "bioTracerShortwave", bioTracerShortwave) diff --git a/components/mpas-seaice/src/shared/mpas_seaice_icepack.F b/components/mpas-seaice/src/shared/mpas_seaice_icepack.F index 9f039b8bb8a5..0b0e2216df46 100644 --- a/components/mpas-seaice/src/shared/mpas_seaice_icepack.F +++ b/components/mpas-seaice/src/shared/mpas_seaice_icepack.F @@ -264,10 +264,12 @@ subroutine seaice_init_icepack_physics_package_variables(domain, clock) config_do_restart, & config_use_column_biogeochemistry, & config_use_column_shortwave, & - config_use_column_snow_tracers + config_use_column_snow_tracers, & + config_use_zaerosols call MPAS_pool_get_config(domain % configs, "config_use_column_package", config_use_column_package) call MPAS_pool_get_config(domain % configs, "config_use_column_biogeochemistry", config_use_column_biogeochemistry) + call MPAS_pool_get_config(domain % configs, "config_use_zaerosols", config_use_zaerosols) if (config_use_column_package) then @@ -281,7 +283,7 @@ subroutine seaice_init_icepack_physics_package_variables(domain, clock) call init_column_thermodynamic_profiles(domain) ! initialize biogoechemistry profiles - if (config_use_column_biogeochemistry) & + if (config_use_column_biogeochemistry .or. config_use_zaerosols) & call init_column_biogeochemistry_profiles(domain, ciceTracerObject) ! history variables @@ -1032,7 +1034,8 @@ subroutine seaice_icepack_predynamics_time_integration(domain, clock) config_use_column_biogeochemistry, & config_use_column_itd_thermodynamics, & config_calc_surface_temperature, & - config_use_vertical_tracers + config_use_vertical_tracers, & + config_use_zaerosols real(kind=RKIND), pointer :: & config_dt @@ -1045,6 +1048,7 @@ subroutine seaice_icepack_predynamics_time_integration(domain, clock) call MPAS_pool_get_config(domain % configs, "config_use_column_vertical_thermodynamics", & config_use_column_vertical_thermodynamics) call MPAS_pool_get_config(domain % configs, "config_use_column_biogeochemistry", config_use_column_biogeochemistry) + call MPAS_pool_get_config(domain % configs, "config_use_zaerosols", config_use_zaerosols) call MPAS_pool_get_config(domain % configs, "config_use_column_itd_thermodynamics", config_use_column_itd_thermodynamics) call MPAS_pool_get_config(domain % configs, "config_calc_surface_temperature", config_calc_surface_temperature) call MPAS_pool_get_config(domain % configs, "config_use_vertical_tracers", config_use_vertical_tracers) @@ -1074,7 +1078,7 @@ subroutine seaice_icepack_predynamics_time_integration(domain, clock) !----------------------------------------------------------------- call mpas_timer_start("Column biogeochemistry") - if (config_use_column_biogeochemistry) & + if (config_use_column_biogeochemistry .or. config_use_zaerosols) & call column_biogeochemistry(domain) call mpas_timer_stop("Column biogeochemistry") @@ -2126,7 +2130,8 @@ subroutine column_itd_thermodynamics(domain, clock) logical, pointer :: & config_update_ocean_fluxes, & - config_use_column_biogeochemistry + config_use_column_biogeochemistry, & + config_use_zaerosols ! dimensions integer, pointer :: & @@ -2263,6 +2268,7 @@ subroutine column_itd_thermodynamics(domain, clock) call MPAS_pool_get_config(block % configs, "config_dt", config_dt) call MPAS_pool_get_config(block % configs, "config_update_ocean_fluxes", config_update_ocean_fluxes) call MPAS_pool_get_config(block % configs, "config_use_column_biogeochemistry", config_use_column_biogeochemistry) + call MPAS_pool_get_config(block % configs, "config_use_zaerosols", config_use_zaerosols) call MPAS_pool_get_dimension(mesh, "nCellsSolve", nCellsSolve) call MPAS_pool_get_dimension(mesh, "nCategories", nCategories) @@ -2348,7 +2354,7 @@ subroutine column_itd_thermodynamics(domain, clock) verticalGridSpace(nBioLayersP1) = verticalGridSpace(1) setGetPhysicsTracers = .true. - setGetBGCTracers = config_use_column_biogeochemistry + setGetBGCTracers = (config_use_column_biogeochemistry .or. config_use_zaerosols) ! code abort abortFlag = .false. @@ -2926,7 +2932,8 @@ subroutine column_radiation(domain, clock, lInitialization) config_use_shortwave_bioabsorption, & config_use_brine, & config_use_modal_aerosols, & - config_use_column_biogeochemistry + config_use_column_biogeochemistry, & + config_use_zaerosols character(len=strKIND), pointer :: & config_snow_redistribution_scheme @@ -3049,6 +3056,7 @@ subroutine column_radiation(domain, clock, lInitialization) call MPAS_pool_get_config(domain % configs, "config_use_shortwave_bioabsorption", config_use_shortwave_bioabsorption) call MPAS_pool_get_config(domain % configs, "config_use_modal_aerosols",config_use_modal_aerosols) call MPAS_pool_get_config(domain % configs, "config_use_column_biogeochemistry",config_use_column_biogeochemistry) + call MPAS_pool_get_config(domain % configs, "config_use_zaerosols",config_use_zaerosols) block => domain % blocklist do while (associated(block)) @@ -3140,28 +3148,31 @@ subroutine column_radiation(domain, clock, lInitialization) allocate(index_shortwaveAerosol(maxAerosolType)) allocate(index_verticalAerosolsConc(maxAerosolType)) allocate(index_algaeConc(nAlgae)) - if (.not. config_use_column_biogeochemistry) then + if (.not. config_use_zaerosols) then index_shortwaveAerosol(1:maxAerosolType) = 1 index_verticalAerosolsConc(1:maxAerosolType) = 1 - index_algaeConc(1:nAlgae) = 1 else do iAerosol = 1, maxAerosolType index_shortwaveAerosol(iAerosol) = ciceTracerObject % index_verticalAerosolsConcShortwave(iAerosol) index_verticalAerosolsConc(iAerosol) = ciceTracerObject % index_verticalAerosolsConc(iAerosol) enddo + endif + if (.not. config_use_column_biogeochemistry) then + index_algaeConc(1:nAlgae) = 1 + else do iBioTracers = 1, nAlgae index_algaeConc(iBioTracers) = ciceTracerObject % index_algaeConc(iBioTracers) enddo endif setGetPhysicsTracers = .true. - setGetBGCTracers = config_use_column_biogeochemistry + setGetBGCTracers = (config_use_column_biogeochemistry .or. config_use_zaerosols) ! snow grain radius array allocate(snow_grain_radius(nSnowLayers,nCategories)) - !$omp parallel do default(shared) firstprivate(aerosolsArray,index_shortwaveAerosol) & - !$omp& private(iCategory,iAerosol,lonCellColumn) + !$omp parallel do default(shared) firstprivate(aerosolsArray,index_shortwaveAerosol,snow_grain_radius) & + !$omp& private(iCategory,iAerosol,iSnowLayer,lonCellColumn) do iCell = 1, nCellsSolve ! set aerosols array @@ -3177,7 +3188,7 @@ subroutine column_radiation(domain, clock, lInitialization) enddo ! iCategory snow_grain_radius(:,:) = 0.0_RKIND - if (config_use_snow_grain_radius) then + if (config_use_snow_grain_radius) then do iCategory = 1, nCategories do iSnowLayer = 1, nSnowLayers snow_grain_radius(iSnowLayer, iCategory) = snowGrainRadius(iSnowLayer,iCategory,iCell) @@ -3306,7 +3317,8 @@ subroutine column_ridging(domain) ! configs logical, pointer :: & - config_use_column_biogeochemistry + config_use_column_biogeochemistry, & + config_use_zaerosols real(kind=RKIND), pointer :: & config_dt @@ -3398,6 +3410,7 @@ subroutine column_ridging(domain) call MPAS_pool_get_config(block % configs, "config_dynamics_subcycle_number", config_dynamics_subcycle_number) call MPAS_pool_get_config(block % configs, "config_use_column_biogeochemistry", config_use_column_biogeochemistry) + call MPAS_pool_get_config(block % configs, "config_use_zaerosols", config_use_zaerosols) call MPAS_pool_get_array(velocity_solver, "dynamicsTimeStep", dynamicsTimeStep) @@ -3454,7 +3467,7 @@ subroutine column_ridging(domain) allocate(newlyFormedIceLogical(nCategories)) setGetPhysicsTracers = .true. - setGetBGCTracers = config_use_column_biogeochemistry + setGetBGCTracers = (config_use_column_biogeochemistry .or. config_use_zaerosols) do iCell = 1, nCellsSolve @@ -3547,10 +3560,10 @@ end subroutine column_ridging subroutine column_biogeochemistry(domain) - use ice_colpkg, only: & - colpkg_biogeochemistry, & - colpkg_init_OceanConcArray, & - colpkg_clear_warnings + use icepack_intfc, only: & + icepack_biogeochemistry, & + icepack_load_ocean_bio_array, & + icepack_warnings_clear use seaice_constants, only: & seaicePuny @@ -3597,15 +3610,8 @@ subroutine column_biogeochemistry(domain) nDON, & nParticulateIron, & nDissolvedIron, & - nZBGCTracers, & - maxAlgaeType, & - maxDOCType, & - maxDICType, & - maxDONType, & - maxIronType, & maxBCType, & - maxDustType, & - maxAerosolType + maxDustType ! variables @@ -3625,9 +3631,6 @@ subroutine column_biogeochemistry(domain) seaSurfaceSalinity, & seaFreezingTemperature, & snowfallRate, & - zSalinityFlux, & - zSalinityGDFlux, & - oceanMixedLayerDepth, & totalSkeletalAlgae, & oceanNitrateConc, & oceanSilicateConc, & @@ -3652,7 +3655,6 @@ subroutine column_biogeochemistry(domain) totalVerticalBiologyIce, & totalVerticalBiologySnow, & penetratingShortwaveFlux, & - zSalinityIceDensity, & basalIceMeltCategory, & surfaceIceMeltCategory, & congelationCategory, & @@ -3779,13 +3781,6 @@ subroutine column_biogeochemistry(domain) call MPAS_pool_get_dimension(mesh, "nDON", nDON) call MPAS_pool_get_dimension(mesh, "nParticulateIron", nParticulateIron) call MPAS_pool_get_dimension(mesh, "nDissolvedIron", nDissolvedIron) - call MPAS_pool_get_dimension(mesh, "nZBGCTracers", nZBGCTracers) - call MPAS_pool_get_dimension(mesh, "maxAlgaeType", maxAlgaeType) - call MPAS_pool_get_dimension(mesh, "maxDOCType", maxDOCType) - call MPAS_pool_get_dimension(mesh, "maxDICType", maxDICType) - call MPAS_pool_get_dimension(mesh, "maxDONType", maxDONType) - call MPAS_pool_get_dimension(mesh, "maxAerosolType", maxAerosolType) - call MPAS_pool_get_dimension(mesh, "maxIronType", maxIronType) call MPAS_pool_get_dimension(mesh, "maxBCType", maxBCType) call MPAS_pool_get_dimension(mesh, "maxDustType", maxDustType) @@ -3824,9 +3819,6 @@ subroutine column_biogeochemistry(domain) call MPAS_pool_get_array(biogeochemistry, "oceanBioConcentrations", oceanBioConcentrations) call MPAS_pool_get_array(biogeochemistry, "totalVerticalBiologyIce", totalVerticalBiologyIce) call MPAS_pool_get_array(biogeochemistry, "totalVerticalBiologySnow", totalVerticalBiologySnow) - call MPAS_pool_get_array(biogeochemistry, "zSalinityIceDensity", zSalinityIceDensity) - call MPAS_pool_get_array(biogeochemistry, "zSalinityFlux", zSalinityFlux) - call MPAS_pool_get_array(biogeochemistry, "zSalinityGDFlux", zSalinityGDFlux) call MPAS_pool_get_array(biogeochemistry, "atmosBioFluxes", atmosBioFluxes) call MPAS_pool_get_array(biogeochemistry, "atmosBlackCarbonFlux", atmosBlackCarbonFlux) call MPAS_pool_get_array(biogeochemistry, "atmosDustFlux", atmosDustFlux) @@ -3856,7 +3848,6 @@ subroutine column_biogeochemistry(domain) 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, "seaFreezingTemperature", seaFreezingTemperature) - call MPAS_pool_get_array(ocean_coupling, "oceanMixedLayerDepth", oceanMixedLayerDepth) call MPAS_pool_get_array(atmos_coupling, "snowfallRate", snowfallRate) @@ -3896,12 +3887,14 @@ subroutine column_biogeochemistry(domain) endif setGetPhysicsTracers = .true. - setGetBGCTracers = config_use_column_biogeochemistry + setGetBGCTracers = (config_use_column_biogeochemistry .or. config_use_zaerosols) - ! code abort - abortFlag = .false. - abortMessage = "" + atmosBioFluxes(:,:) = 0.0_RKIND + !$omp parallel do default(shared) private(iCategory,iBioTracers,iAlgae, rayleighCriteria, & + !$omp& rayleighCriteriaReal) firstprivate(atmosBioFluxes,atmosBlackCarbonFlux, & + !$omp& atmosDustFlux, bioShortwaveFluxCell, newlyFormedIce) + ! do iCell = 1, nCellsSolve ! newly formed ice do iCategory = 1, nCategories @@ -3913,28 +3906,23 @@ subroutine column_biogeochemistry(domain) !update ocean concentrations fields and atmospheric fluxes into allocated array #ifdef coupled - call colpkg_init_OceanConcArray(& - nZBGCTracers, & - maxAlgaeType, & - maxDONType, & - maxDOCType, & - maxDICType, & - maxAerosolType, & - maxIronType, & - oceanNitrateConc(iCell), & - oceanAmmoniumConc(iCell), & - oceanSilicateConc(iCell),& - oceanDMSPConc(iCell), & - oceanDMSConc(iCell), & - oceanAlgaeConc(:,iCell), & - oceanDOCConc(:,iCell), & - oceanDONConc(:,iCell), & - oceanDICConc(:,iCell), & - oceanDissolvedIronConc(:,iCell), & - oceanParticulateIronConc(:,iCell), & - oceanZAerosolConc(:,iCell), & - oceanBioConcentrations(:,iCell), & - oceanHumicsConc(iCell)) + + call icepack_load_ocean_bio_array(& + nit=oceanNitrateConc(iCell), & + amm=oceanAmmoniumConc(iCell), & + sil=oceanSilicateConc(iCell), & + dmsp=oceanDMSPConc(iCell), & + dms=oceanDMSConc(iCell), & + algalN=oceanAlgaeConc(:,iCell), & + doc=oceanDOCConc(:,iCell), & + don=oceanDONConc(:,iCell), & + dic=oceanDICConc(:,iCell), & + fed=oceanDissolvedIronConc(:,iCell), & + fep=oceanParticulateIronConc(:,iCell), & + zaeros=oceanZAerosolConc(:,iCell), & + ocean_bio_all=oceanBioConcentrations(:,iCell), & + hum=oceanHumicsConc(iCell)) + #else do iBioTracers = 1, maxBCType atmosBlackCarbonFlux(iBioTracers,iCell) = 1.e-12_RKIND @@ -3943,7 +3931,6 @@ subroutine column_biogeochemistry(domain) atmosDustFlux(iBioTracers,iCell) = 1.e-13_RKIND enddo #endif - atmosBioFluxes(:,:) = 0.0_RKIND if (config_use_zaerosols) then indexj = ciceTracerObject % index_verticalAerosolsConcLayer(1) do iBioTracers = 1, maxBCType @@ -3959,94 +3946,90 @@ subroutine column_biogeochemistry(domain) oceanBioConcentrationsUsed(iBioTracers) = oceanBioConcentrations(iBioData,iCell) enddo ! iBioTracers - abortFlag = .false. - call set_cice_tracer_array_category(block, ciceTracerObject, & tracerArrayCategory, iCell, setGetPhysicsTracers, setGetBGCTracers) if (checkCarbon) call seaice_total_carbon_content_category(block,& totalCarbonCatInitial,iceAreaCategoryInitial,iceVolumeCategoryInitial,iCell) - call colpkg_clear_warnings() - call colpkg_biogeochemistry(& - config_dt, & - ciceTracerObject % nTracers, & - ciceTracerObject % nBioTracers, & - netNitrateUptake(iCell), & - netAmmoniumUptake(iCell), & - bioDiffusivity(:,:,iCell), & - bioPermeability(:,:,iCell), & - bioShortwaveFlux(:,:,iCell), & - totalVerticalSalinity(iCell), & - darcyVelocityBio(:,iCell), & - netSpecificAlgalGrowthRate(iCell), & - primaryProduction(iCell), & - netBrineHeight(iCell), & - brineBottomChange(:,iCell), & - brineTopChange(:,iCell), & - verticalNitrogenLosses(:,:,iCell), & - snowIceBioFluxes(:,iCell), & - atmosIceBioFluxes(:,iCell), & - oceanBioConcentrationsUsed(:), & - newlyFormedIceLogical(:), & - shortwaveLayerPenetration(:,:,iCell), & - bioPorosity(:,:,iCell), & - bioTemperature(:,:,iCell), & - totalVerticalBiologyIce(:,iCell), & - totalVerticalBiologySnow(:,iCell), & - totalChlorophyll(iCell), & - penetratingShortwaveFlux(:,iCell), & - rayleighCriteria, & - zSalinityIceDensity(:,iCell), & - zSalinityFlux(iCell), & - zSalinityGDFlux(iCell), & - biologyGrid, & - interfaceBiologyGrid, & - interfaceGrid, & - verticalGrid, & - nBioLayers, & - nIceLayers, & - nSnowLayers, & - nAlgae, & - nzAerosols, & - nCategories, & - nDOC, & - nDIC, & - nDON, & - nDissolvedIron, & - nParticulateIron, & - basalIceMeltCategory(:,iCell), & - surfaceIceMeltCategory(:,iCell), & - congelationCategory(:,iCell), & - snowiceFormationCategory(:,iCell), & - seaSurfaceTemperature(iCell), & - seaSurfaceSalinity(iCell), & - seaFreezingTemperature(iCell), & - snowfallRate(iCell), & - snowMeltCategory(:,iCell), & - oceanMixedLayerDepth(iCell), & - initialSalinityProfile(:,iCell), & - iceThicknessCategoryInitial(:,iCell), & - oceanBioFluxes(:,iCell), & - atmosBioFluxes(:,iCell), & - iceAreaCategoryInitial(:,iCell), & - iceVolumeCategoryInitial(:,iCell), & - iceAreaCategory(1,:,iCell), & - iceVolumeCategory(1,:,iCell), & - snowVolumeCategory(1,:,iCell), & - openWaterArea(iCell), & - tracerArrayCategory, & - snowVolumeCategoryInitial(:,iCell), & - config_use_skeletal_biochemistry, & - maxAlgaeType, & - nZBGCTracers, & - oceanBioFluxesCategory(:,:,iCell), & - bgridPorosityIceCell(:,iCell), & - bgridSalinityIceCell(:,iCell), & - bgridTemperatureIceCell(:,iCell), & - abortFlag, & - abortMessage) - call column_write_warnings(abortFlag) + ! code abort + abortFlag = .false. + abortMessage = "" + + call icepack_warnings_clear() + call icepack_biogeochemistry(& + dt=config_dt, & + ntrcr=ciceTracerObject % nTracers, & + nbtrcr=ciceTracerObject % nBioTracers, & + upNO=netNitrateUptake(iCell), & + upNH=netAmmoniumUptake(iCell), & + iDi=bioDiffusivity(:,:,iCell), & + iki=bioPermeability(:,:,iCell), & + zfswin=bioShortwaveFlux(:,:,iCell), & + zsal_tot=totalVerticalSalinity(iCell), & + darcy_V=darcyVelocityBio(:,iCell), & + grow_net=netSpecificAlgalGrowthRate(iCell), & + PP_net=primaryProduction(iCell), & + hbri=netBrineHeight(iCell), & + dhbr_bot=brineBottomChange(:,iCell), & + dhbr_top=brineTopChange(:,iCell), & + Zoo=verticalNitrogenLosses(:,:,iCell), & + fbio_snoice=snowIceBioFluxes(:,iCell), & + fbio_atmice=atmosIceBioFluxes(:,iCell), & + ocean_bio=oceanBioConcentrationsUsed(:), & + first_ice=newlyFormedIceLogical(:), & + fswpenln=shortwaveLayerPenetration(:,:,iCell), & + bphi=bioPorosity(:,:,iCell), & + bTiz=bioTemperature(:,:,iCell), & + ice_bio_net=totalVerticalBiologyIce(:,iCell), & + snow_bio_net=totalVerticalBiologySnow(:,iCell), & + totalChla=totalChlorophyll(iCell), & + fswthrun=penetratingShortwaveFlux(:,iCell), & + Rayleigh_criteria=rayleighCriteria, & + bgrid=biologyGrid, & + igrid=interfaceBiologyGrid, & + icgrid=interfaceGrid, & + cgrid=verticalGrid, & + nblyr=nBioLayers, & + nilyr=nIceLayers, & + nslyr=nSnowLayers, & + n_algae=nAlgae, & + n_zaero=nzAerosols, & + ncat=nCategories, & + n_doc=nDOC, & + n_dic=nDIC, & + n_don=nDON, & + n_fed=nDissolvedIron, & + n_fep=nParticulateIron, & + meltbn=basalIceMeltCategory(:,iCell), & + melttn=surfaceIceMeltCategory(:,iCell), & + congeln=congelationCategory(:,iCell), & + snoicen=snowiceFormationCategory(:,iCell), & + sst=seaSurfaceTemperature(iCell), & + sss=seaSurfaceSalinity(iCell), & + Tf=seaFreezingTemperature(iCell), & + fsnow=snowfallRate(iCell), & + meltsn=snowMeltCategory(:,iCell), & + !initialSalinityProfile(:,iCell), & !!!! + hin_old=iceThicknessCategoryInitial(:,iCell), & + flux_bio=oceanBioFluxes(:,iCell), & + flux_bio_atm=atmosBioFluxes(:,iCell), & + aicen_init=iceAreaCategoryInitial(:,iCell), & + vicen_init=iceVolumeCategoryInitial(:,iCell), & + aicen=iceAreaCategory(1,:,iCell), & + vicen=iceVolumeCategory(1,:,iCell), & + vsnon=snowVolumeCategory(1,:,iCell), & + aice0=openWaterArea(iCell), & + trcrn=tracerArrayCategory, & + vsnon_init=snowVolumeCategoryInitial(:,iCell), & + skl_bgc=config_use_skeletal_biochemistry, & + flux_bion=oceanBioFluxesCategory(:,:,iCell), & + bioPorosityIceCell=bgridPorosityIceCell(:,iCell), & + bioSalinityIceCell=bgridSalinityIceCell(:,iCell), & + bioTemperatureIceCell=bgridTemperatureIceCell(:,iCell)) + + abortFlag = icepack_warnings_aborted() + call seaice_icepack_write_warnings(abortFlag) call get_cice_tracer_array_category(block, ciceTracerObject, & tracerArrayCategory, iCell, setGetPhysicsTracers, setGetBGCTracers) @@ -4076,9 +4059,6 @@ subroutine column_biogeochemistry(domain) enddo endif - ! code abort - if (abortFlag) exit - totalSkeletalAlgae(iCell) = 0.0_RKIND bioShortwaveFluxCell(:,iCell) = 0.0_RKIND @@ -4396,7 +4376,8 @@ subroutine seaice_icepack_aggregate(domain) ocean_coupling logical, pointer :: & - config_use_column_biogeochemistry + config_use_column_biogeochemistry, & + config_use_zaerosols real(kind=RKIND), dimension(:), pointer :: & iceAreaCell, & @@ -4431,6 +4412,7 @@ subroutine seaice_icepack_aggregate(domain) call MPAS_pool_get_subpool(block % structs, "ocean_coupling", ocean_coupling) call MPAS_pool_get_config(block % configs, "config_use_column_biogeochemistry", config_use_column_biogeochemistry) + call MPAS_pool_get_config(block % configs, "config_use_zaerosols", config_use_zaerosols) call MPAS_pool_get_dimension(mesh, "nCellsSolve", nCellsSolve) call MPAS_pool_get_dimension(mesh, "nCategories", nCategories) @@ -4448,7 +4430,7 @@ subroutine seaice_icepack_aggregate(domain) call MPAS_pool_get_array(ocean_coupling, "seaFreezingTemperature", seaFreezingTemperature) setGetPhysicsTracers = .true. - setGetBGCTracers = config_use_column_biogeochemistry + setGetBGCTracers = (config_use_column_biogeochemistry .or. config_use_zaerosols) do iCell = 1, nCellsSolve @@ -4597,7 +4579,8 @@ subroutine seaice_icepack_coupling_prep(domain) logical, pointer :: & config_use_ocean_mixed_layer, & config_include_pond_freshwater_feedback, & - config_use_column_biogeochemistry + config_use_column_biogeochemistry, & + config_use_zaerosols type(MPAS_pool_type), pointer :: & oceanCoupling, & @@ -4708,6 +4691,7 @@ subroutine seaice_icepack_coupling_prep(domain) call MPAS_pool_get_config(domain % configs, "config_dt", config_dt) call MPAS_pool_get_config(domain % configs, "config_include_pond_freshwater_feedback", config_include_pond_freshwater_feedback) call MPAS_pool_get_config(domain % configs, "config_use_column_biogeochemistry", config_use_column_biogeochemistry) + call MPAS_pool_get_config(domain % configs, "config_use_zaerosols", config_use_zaerosols) call MPAS_pool_get_config(domain % configs, "config_ratio_C_to_N_diatoms", config_ratio_C_to_N_diatoms) call MPAS_pool_get_config(domain % configs, "config_ratio_C_to_N_small_plankton", config_ratio_C_to_N_small_plankton) call MPAS_pool_get_config(domain % configs, "config_ratio_C_to_N_phaeocystis", config_ratio_C_to_N_phaeocystis) @@ -4900,10 +4884,12 @@ subroutine seaice_icepack_coupling_prep(domain) !----------------------------------------------------------------- ! Define ocean biogeochemical flux variables !----------------------------------------------------------------- - if (config_use_column_biogeochemistry) then + + oceanBioFluxesAll(:) = 0.0_RKIND + + if (config_use_column_biogeochemistry .or. config_use_zaerosols) then totalOceanCarbonFlux(iCell) = 0.0_RKIND - oceanBioFluxesAll(:) = 0.0_RKIND oceanAlgaeFlux(:,iCell) = 0.0_RKIND oceanDOCFlux(:,iCell) = 0.0_RKIND oceanDICFlux(:,iCell) = 0.0_RKIND @@ -5014,7 +5000,7 @@ subroutine seaice_icepack_coupling_prep(domain) totalOceanCarbonFlux(iCell) = totalOceanCarbonFlux(iCell) + & oceanHumicsFlux(iCell) - endif ! config_use_column_biogeochemistry + endif ! config_use_column_biogeochemistry .or. config_use_zaerosols enddo ! iCell @@ -5062,7 +5048,8 @@ subroutine seaice_column_scale_fluxes(domain) mesh logical, pointer :: & - config_use_column_biogeochemistry + config_use_column_biogeochemistry, & + config_use_zaerosols real(kind=RKIND), dimension(:), pointer :: & iceAreaCell, & @@ -5122,6 +5109,7 @@ subroutine seaice_column_scale_fluxes(domain) iBioTracers call MPAS_pool_get_config(domain % configs, "config_use_column_biogeochemistry", config_use_column_biogeochemistry) + call MPAS_pool_get_config(domain % configs, "config_use_zaerosols", config_use_zaerosols) block => domain % blocklist do while (associated(block)) @@ -5214,6 +5202,9 @@ subroutine seaice_column_scale_fluxes(domain) albedoVisibleDiffuseCell(iCell) = albedoVisibleDiffuseCell(iCell) * iceAreaInverse albedoIRDiffuseCell(iCell) = albedoIRDiffuseCell(iCell) * iceAreaInverse + if (config_use_zaerosols) & + oceanDustIronFlux(iCell) = oceanDustIronFlux(iCell) * iceAreaInverse + if (config_use_column_biogeochemistry) then oceanNitrateFlux(iCell) = oceanNitrateFlux(iCell) * iceAreaInverse @@ -5223,7 +5214,6 @@ subroutine seaice_column_scale_fluxes(domain) oceanDMSPdFlux(iCell) = oceanDMSPdFlux(iCell) * iceAreaInverse oceanDMSFlux(iCell) = oceanDMSFlux(iCell) * iceAreaInverse oceanHumicsFlux(iCell) = oceanHumicsFlux(iCell) * iceAreaInverse - oceanDustIronFlux(iCell) = oceanDustIronFlux(iCell) * iceAreaInverse do iBioTracers = 1, maxAlgaeType oceanAlgaeFlux(iBioTracers,iCell) = oceanAlgaeFlux(iBioTracers,iCell) * iceAreaInverse @@ -5266,6 +5256,9 @@ subroutine seaice_column_scale_fluxes(domain) albedoVisibleDiffuseCell(iCell) = 0.0_RKIND albedoIRDiffuseCell(iCell) = 0.0_RKIND + if (config_use_zaerosols) & + oceanDustIronFlux(iCell) = 0.0_RKIND + if (config_use_column_biogeochemistry) then oceanNitrateFlux(iCell) = 0.0_RKIND @@ -5275,7 +5268,6 @@ subroutine seaice_column_scale_fluxes(domain) oceanDMSPdFlux(iCell) = 0.0_RKIND oceanDMSFlux(iCell) = 0.0_RKIND oceanHumicsFlux(iCell) = 0.0_RKIND - oceanDustIronFlux(iCell) = 0.0_RKIND oceanAlgaeFlux(:,iCell) = 0.0_RKIND oceanDOCFlux(:,iCell) = 0.0_RKIND oceanDICFlux(:,iCell) = 0.0_RKIND @@ -5994,12 +5986,14 @@ subroutine init_column_tracer_object(domain, tracerObject) nZBGCTracers logical, pointer :: & - config_use_column_biogeochemistry + config_use_column_biogeochemistry, & + config_use_zaerosols call MPAS_pool_get_dimension(domain % blocklist % dimensions, "nCategories", nCategories) call MPAS_pool_get_dimension(domain % blocklist % dimensions, "nZBGCTracers", nZBGCTracers) call MPAS_pool_get_config(domain % configs, "config_use_column_biogeochemistry", config_use_column_biogeochemistry) + call MPAS_pool_get_config(domain % configs, "config_use_zaerosols", config_use_zaerosols) ! get the number of CICE tracers in trcrn call init_column_tracer_object_tracer_number(domain, tracerObject) @@ -6023,7 +6017,7 @@ subroutine init_column_tracer_object(domain, tracerObject) call init_column_tracer_object_ancestor_indices(domain, tracerObject) ! biogeochemistry - if (config_use_column_biogeochemistry) then + if (config_use_column_biogeochemistry .or. config_use_zaerosols) then allocate(tracerObject % index_LayerIndexToDataArray(nZBGCTracers)) allocate(tracerObject % index_LayerIndexToBioIndex(nZBGCTracers)) @@ -6231,7 +6225,7 @@ subroutine init_column_tracer_object_tracer_number(domain, tracerObject) ! biogeochemistry !----------------------------------------------------------------------- - if (config_use_column_biogeochemistry) then + if (config_use_column_biogeochemistry .or. config_use_zaerosols) then ! save tracer number without bio tracers counted tracerObject % nTracersNotBio = tracerObject % nTracers @@ -6244,10 +6238,10 @@ subroutine init_column_tracer_object_tracer_number(domain, tracerObject) tracerObject % nTracers = tracerObject % nTracers + 1 ! vertical zSalinity - if (config_use_vertical_zsalinity) then - tracerObject % nTracers = tracerObject % nTracers + nBioLayers - tracerObject % nBioTracersLayer = tracerObject % nBioTracersLayer + 1 - endif + !if (config_use_vertical_zsalinity) then + ! tracerObject % nTracers = tracerObject % nTracers + nBioLayers + ! tracerObject % nBioTracersLayer = tracerObject % nBioTracersLayer + 1 + !endif nMobileTracers = 0 ! Skeletal Biogeochemistry @@ -9901,7 +9895,7 @@ subroutine check_column_package_configs(domain) config_use_vertical_biochemistry .or. config_use_shortwave_bioabsorption .or. config_use_vertical_tracers .or. & config_use_skeletal_biochemistry .or. config_use_nitrate .or. config_use_carbon .or. config_use_chlorophyll .or. & config_use_ammonium .or. config_use_silicate .or. config_use_DMS .or. config_use_nonreactive .or. config_use_humics .or. & - config_use_DON .or. config_use_iron .or. config_use_modal_aerosols .or. config_use_zaerosols)) then + config_use_DON .or. config_use_iron)) then call mpas_log_write(& "check_column_package_configs: config_use_column_biogeochemistry = false. "//& "All biogeochemistry namelist flags must also be false", & @@ -9909,12 +9903,12 @@ subroutine check_column_package_configs(domain) endif ! check vertical zSalinity requirements - if (config_use_vertical_zsalinity .and. ((.not. config_use_brine) .or. & - (.not. (trim(config_thermodynamics_type) == "BL99")))) then - call mpas_log_write(& - "check_column_package_configs: vertical zSalinity requires config_use_brine = true and 'BL99' ", & - messageType=MPAS_LOG_CRIT) - endif + !if (config_use_vertical_zsalinity .and. ((.not. config_use_brine) .or. & + ! (.not. (trim(config_thermodynamics_type) == "BL99")))) then + ! call mpas_log_write(& + ! "check_column_package_configs: vertical zSalinity requires config_use_brine = true and 'BL99' ", & + ! messageType=MPAS_LOG_CRIT) + !endif ! check that vertical bio tracers use brine height if ((config_use_vertical_biochemistry .or. config_use_zaerosols) .and. & @@ -10265,13 +10259,27 @@ subroutine init_icepack_package_tracer_sizes(domain, tracerObject) nIceLayers, & nSnowLayers, & nAerosols, & - nBioLayers + nBioLayers, & + nAlgae, & + nDOC, & + nDIC, & + nDON, & + nParticulateIron, & + nDissolvedIron, & + nzAerosols call MPAS_pool_get_dimension(domain % blocklist % dimensions, "nCategories", nCategories) call MPAS_pool_get_dimension(domain % blocklist % dimensions, "nIceLayers", nIceLayers) call MPAS_pool_get_dimension(domain % blocklist % dimensions, "nSnowLayers", nSnowLayers) call MPAS_pool_get_dimension(domain % blocklist % dimensions, "nBioLayers", nBioLayers) call MPAS_pool_get_dimension(domain % blocklist % dimensions, "nAerosols", nAerosols) + call MPAS_pool_get_dimension(domain % blocklist % dimensions, "nzAerosols", nzAerosols) + call MPAS_pool_get_dimension(domain % blocklist % dimensions, "nAlgae", nAlgae) + call MPAS_pool_get_dimension(domain % blocklist % dimensions, "nDOC", nDOC) + call MPAS_pool_get_dimension(domain % blocklist % dimensions, "nDIC", nDIC) + call MPAS_pool_get_dimension(domain % blocklist % dimensions, "nDON", nDON) + call MPAS_pool_get_dimension(domain % blocklist % dimensions, "nParticulateIron", nParticulateIron) + call MPAS_pool_get_dimension(domain % blocklist % dimensions, "nDissolvedIron", nDissolvedIron) call icepack_init_tracer_sizes(& ncat_in = nCategories, & @@ -10279,17 +10287,17 @@ subroutine init_icepack_package_tracer_sizes(domain, tracerObject) nslyr_in = nSnowLayers, & nblyr_in = nBioLayers, & !nfsd_in = , & - !n_algae_in = , & - !n_DOC_in = , & - n_aero_in = nAerosols, & !n_iso_in = , & - !n_DON_in = , & - !n_DIC_in = , & - !n_fed_in = , & - !n_fep_in = , & - !n_zaero_in = , & + !n_aero_in = nAerosols, & + n_algae_in = nAlgae, & + n_DOC_in = nDOC, & + n_DON_in = nDON, & + n_DIC_in = nDIC, & + n_fed_in = nDissolvedIron, & + n_fep_in = nParticulateIron, & + n_zaero_in = nzAerosols, & ntrcr_in = tracerObject % nTracers, & - !ntrcr_o_in = , & + ntrcr_o_in = tracerObject % nTracersNotBio, & nbtrcr_in = tracerObject % nBioTracers, & nbtrcr_sw_in = tracerObject % nBioTracersShortwave) @@ -10500,15 +10508,15 @@ subroutine init_column_package_tracer_indices(tracerObject) !nt_zbgc_S = tracerObject % index_verticalSalinity !nlt_chl_sw = tracerObject % index_chlorophyllShortwave !nlt_zaero_sw = tracerObject % index_verticalAerosolsConcShortwave - !max_algae = tracerObject % nAlgaeIndex - !max_algae = tracerObject % nAlgalCarbonIndex - !max_algae = tracerObject % nAlgalChlorophyllIndex - !max_doc = tracerObject % nDOCIndex - !max_don = tracerObject % nDONIndex - !max_dic = tracerObject % nDICIndex - !max_fe = tracerObject % nDissolvedIronIndex - !max_fe = tracerObject % nParticulateIronIndex - !max_aero = tracerObject % nzAerosolsIndex + !n_algae = tracerObject % nAlgaeIndex + !n_algae = tracerObject % nAlgalCarbonIndex + !n_algae = tracerObject % nAlgalChlorophyllIndex + !n_doc = tracerObject % nDOCIndex + !n_don = tracerObject % nDONIndex + !n_dic = tracerObject % nDICIndex + !n_fed = tracerObject % nDissolvedIronIndex + !n_fep = tracerObject % nParticulateIronIndex + !n_zaero = tracerObject % nzAerosolsIndex !bio_index_o = tracerObject % index_LayerIndexToDataArray !bio_index = tracerObject % index_LayerIndexToBioIndex !nbtrcr = tracerObject % nBioTracers @@ -12353,6 +12361,8 @@ subroutine init_icepack_package_configs(domain) config_use_skeletal_biochemistry, & config_use_vertical_zsalinity, & config_use_modal_aerosols, & + config_use_macromolecules, & + config_do_restart_bgc, & config_use_snow_liquid_ponds, & config_use_snow_grain_radius @@ -12607,6 +12617,8 @@ subroutine init_icepack_package_configs(domain) call MPAS_pool_get_config(domain % configs, "config_use_vertical_biochemistry", config_use_vertical_biochemistry) call MPAS_pool_get_config(domain % configs, "config_use_shortwave_bioabsorption", config_use_shortwave_bioabsorption) call MPAS_pool_get_config(domain % configs, "config_use_modal_aerosols", config_use_modal_aerosols) + call MPAS_pool_get_config(domain % configs, "config_use_macromolecules", config_use_macromolecules) + call MPAS_pool_get_config(domain % configs, "config_do_restart_bgc", config_do_restart_bgc) call MPAS_pool_get_config(domain % configs, "config_use_skeletal_biochemistry", config_use_skeletal_biochemistry) call MPAS_pool_get_config(domain % configs, "config_use_vertical_zsalinity", config_use_vertical_zsalinity) call MPAS_pool_get_config(domain % configs, "config_biogrid_bottom_molecular_sublayer", & @@ -13040,37 +13052,137 @@ subroutine init_icepack_package_configs(domain) z_tracers_in = config_use_vertical_tracers, & scale_bgc_in = config_scale_initial_vertical_bgc, & solve_zbgc_in = config_use_vertical_biochemistry, & + dEdd_algae_in = config_use_shortwave_bioabsorption, & modal_aero_in = config_use_modal_aerosols, & + use_macromolecules_in = config_use_macromolecules, & + restartbgc_in = config_do_restart_bgc, & skl_bgc_in = config_use_skeletal_biochemistry, & solve_zsal_in = config_use_vertical_zsalinity, & grid_o_in = config_biogrid_bottom_molecular_sublayer, & l_sk_in = config_bio_gravity_drainage_length_scale, & - initbio_frac_in = config_new_ice_fraction_biotracer, & + grid_o_t_in = config_biogrid_top_molecular_sublayer, & + !initbio_frac_in = config_new_ice_fraction_biotracer, & + !frazil_scav_in = config_fraction_biotracer_in_frazil, & grid_oS_in = config_zsalinity_molecular_sublayer, & l_skS_in = config_zsalinity_gravity_drainage_scale, & - dEdd_algae_in = config_use_shortwave_bioabsorption, & phi_snow_in = config_snow_porosity_at_ice_surface, & - !T_max_in = , & ! BGC - !fsal_in = , & - !fr_resp_in = , & - !algal_vel_in = , & - !R_dFe2dust_in = , & - !dustFe_sol_in = , & - !op_dep_min_in = , & - !fr_graze_s_in = , & - !fr_graze_e_in = , & - !fr_mort2min_in = , & - !fr_dFe_in = , & - !k_nitrif_in = , & - !t_iron_conv_in = , & - !max_loss_in = , & - !max_dfe_doc1_in = , & - !fr_resp_s_in = , & + !ratio_Si2N_diatoms_in = config_ratio_Si_to_N_diatoms, & + !ratio_Si2N_sp_in = config_ratio_Si_to_N_small_plankton, & + !ratio_Si2N_phaeo_in = config_ratio_Si_to_N_phaeocystis, & + !ratio_S2N_diatoms_in = config_ratio_S_to_N_diatoms, & + !ratio_S2N_sp_in = config_ratio_S_to_N_small_plankton, & + !ratio_S2N_phaeo_in = config_ratio_S_to_N_phaeocystis, & + !ratio_Fe2C_diatoms_in = config_ratio_Fe_to_C_diatoms, & + !ratio_Fe2C_sp_in = config_ratio_Fe_to_C_small_plankton, & + !ratio_Fe2C_phaeo_in = config_ratio_Fe_to_C_phaeocystis, & + !ratio_Fe2N_diatoms_in = config_ratio_Fe_to_N_diatoms, & + !ratio_Fe2N_sp_in = config_ratio_Fe_to_N_small_plankton, & + !ratio_Fe2N_phaeo_in = config_ratio_Fe_to_N_phaeocystis, & + !ratio_Fe2DON_in = config_ratio_Fe_to_DON, & + !ratio_Fe2DOC_s_in = config_ratio_Fe_to_DOC_saccharids, & + !ratio_Fe2DOC_l_in = config_ratio_Fe_to_DOC_lipids, & + fr_resp_in = config_respiration_fraction_of_growth, & + tau_min_in = config_rapid_mobile_to_stationary_time, & + tau_max_in = config_long_mobile_to_stationary_time, & + algal_vel_in = config_algal_maximum_velocity, & + R_dFe2dust_in = config_ratio_Fe_to_dust, & + dustFe_sol_in = config_solubility_of_Fe_in_dust, & + !chlabs_diatoms_in = config_chla_absorptivity_of_diatoms, & + !chlabs_sp_in = config_chla_absorptivity_of_small_plankton, & + !chlabs_phaeo_in = config_chla_absorptivity_of_phaeocystis, & + !alpha2max_low_diatoms_in = config_light_attenuation_diatoms, & + !alpha2max_low_sp_in = config_light_attenuation_small_plankton, & + !alpha2max_low_phaeo_in = config_light_attenuation_phaeocystis, & + !beta2max_diatoms_in = config_light_inhibition_diatoms, & + !beta2max_sp_in = config_light_inhibition_small_plankton, & + !beta2max_phaeo_in = config_light_inhibition_phaeocystis, & + !mu_max_diatoms_in = config_maximum_growth_rate_diatoms, & + !mu_max_sp_in = config_maximum_growth_rate_small_plankton, & + !mu_max_phaeo_in = config_maximum_growth_rate_phaeocystis, & + !grow_Tdep_diatoms_in = config_temperature_growth_diatoms, & + !grow_Tdep_sp_in = config_temperature_growth_small_plankton, & + !grow_Tdep_phaeo_in = config_temperature_growth_phaeocystis, & + !fr_graze_diatoms_in = config_grazed_fraction_diatoms, & + !fr_graze_sp_in = config_grazed_fraction_small_plankton, & + !fr_graze_phaeo_in = config_grazed_fraction_phaeocystis, & + !mort_pre_diatoms_in = config_mortality_diatoms, & + !mort_pre_sp_in = config_mortality_small_plankton, & + !mort_pre_phaeo_in = config_mortality_phaeocystis, & + !mort_Tdep_diatoms_in = config_temperature_mortality_diatoms, & + !mort_Tdep_sp_in = config_temperature_mortality_small_plankton, & + !mort_Tdep_phaeo_in = config_temperature_mortality_phaeocystis, & + !k_exude_diatoms_in = config_exudation_diatoms, & + !k_exude_sp_in = config_exudation_small_plankton, & + !k_exude_phaeo_in = config_exudation_phaeocystis, & + !K_Nit_diatoms_in = config_nitrate_saturation_diatoms, & + !K_Nit_sp_in = config_nitrate_saturation_small_plankton, & + !K_Nit_phaeo_in = config_nitrate_saturation_phaeocystis, & + !K_Am_diatoms_in = config_ammonium_saturation_diatoms, & + !K_Am_sp_in = config_ammonium_saturation_small_plankton, & + !K_Am_phaeo_in = config_ammonium_saturation_phaeocystis, & + !K_Sil_diatoms_in = config_silicate_saturation_diatoms, & + !K_Sil_sp_in = config_silicate_saturation_small_plankton, & + !K_Sil_phaeo_in = config_silicate_saturation_phaeocystis, & + !K_Fe_diatoms_in = config_iron_saturation_diatoms, & + !K_Fe_sp_in = config_iron_saturation_small_plankton, & + !K_Fe_phaeo_in = config_iron_saturation_phaeocystis, & + !f_don_protein_in = config_fraction_spilled_to_DON, & + !kn_bac_protein_in = config_degredation_of_DON, & + !f_don_Am_protein_in = config_fraction_DON_ammonium, & + !f_doc_s_in = config_fraction_loss_to_saccharids, & + !f_doc_l_in = config_fraction_loss_to_lipids, & + !f_exude_s_in = config_fraction_exudation_to_saccharids, & + !f_exude_l_in = config_fraction_exudation_to_lipids, & + !k_bac_s_in = config_remineralization_saccharids, & + !k_bac_l_in = config_remineralization_lipids, & + T_max_in = config_maximum_brine_temperature, & + fsal_in = config_salinity_dependence_of_growth, & + op_dep_min_in = config_minimum_optical_depth, & + fr_graze_s_in = config_slopped_grazing_fraction, & + fr_graze_e_in = config_excreted_fraction, & + fr_mort2min_in = config_fraction_mortality_to_ammonium, & + fr_dFe_in = config_fraction_iron_remineralized, & + k_nitrif_in = config_nitrification_rate, & + t_iron_conv_in = config_desorption_loss_particulate_iron, & + max_loss_in = config_maximum_loss_fraction, & + max_dfe_doc1_in = config_maximum_ratio_iron_to_saccharids, & + fr_resp_s_in = config_respiration_loss_to_DMSPd, & + y_sk_DMS_in = config_DMSP_to_DMS_conversion_fraction, & + t_sk_conv_in = config_DMSP_to_DMS_conversion_time, & + t_sk_ox_in = config_DMS_oxidation_time, & + algaltype_diatoms_in = config_mobility_type_diatoms, & + algaltype_sp_in = config_mobility_type_small_plankton, & + algaltype_phaeo_in = config_mobility_type_phaeocystis, & + nitratetype_in = config_mobility_type_nitrate, & + ammoniumtype_in = config_mobility_type_ammonium, & + silicatetype_in = config_mobility_type_silicate, & + dmspptype_in = config_mobility_type_DMSPp, & + dmspdtype_in = config_mobility_type_DMSPd, & + humtype_in = config_mobility_type_humics, & + doctype_s_in = config_mobility_type_saccharids, & + doctype_l_in = config_mobility_type_lipids, & + dictype_1_in = config_mobility_type_inorganic_carbon, & + dontype_protein_in = config_mobility_type_proteins, & + fedtype_1_in = config_mobility_type_dissolved_iron, & + feptype_1_in = config_mobility_type_particulate_iron, & + zaerotype_bc1_in = config_mobility_type_black_carbon1, & + zaerotype_bc2_in = config_mobility_type_black_carbon2, & + zaerotype_dust1_in = config_mobility_type_dust1, & + zaerotype_dust2_in = config_mobility_type_dust2, & + zaerotype_dust3_in = config_mobility_type_dust3, & + zaerotype_dust4_in = config_mobility_type_dust4, & + ratio_C2N_diatoms_in = config_ratio_C_to_N_diatoms, & + ratio_C2N_sp_in = config_ratio_C_to_N_small_plankton, & + ratio_C2N_phaeo_in = config_ratio_C_to_N_phaeocystis, & + ratio_chl2N_diatoms_in = config_ratio_chla_to_N_diatoms, & + ratio_chl2N_sp_in = config_ratio_chla_to_N_small_plankton, & + ratio_chl2N_phaeo_in = config_ratio_chla_to_N_phaeocystis, & + F_abs_chl_diatoms_in = config_scales_absorption_diatoms, & + F_abs_chl_sp_in = config_scales_absorption_small_plankton, & + F_abs_chl_phaeo_in = config_scales_absorption_phaeocystis, & + ratio_C2N_proteins_in = config_ratio_C_to_N_proteins, & !conserv_check_in = , & - !y_sk_DMS_in = , & - !t_sk_conv_in = , & - !t_sk_ox_in = , & - !frazil_scav_in = , & + ! !sw_redist_in = , & ! not yet implemented in MPAS-SI (stealth feature) !sw_frac_in = , & ! not yet implemented in MPAS-SI (stealth feature) !sw_dtemp_in = , & ! not yet implemented in MPAS-SI (stealth feature) @@ -13153,124 +13265,6 @@ subroutine init_icepack_package_configs(domain) !call icepack_init_parameters(& ! shortwave = config_shortwave_type, & ! not working correctly above ! oceanmixed_ice = config_use_ocean_mixed_layer, & ! not used in Icepack/columnphysics (driver only) - ! grid_o_t = config_biogrid_top_molecular_sublayer, & ! not used in Icepack - ! frazil_scav = config_fraction_biotracer_in_frazil, & ! BGC - ! ratio_Si2N_diatoms = config_ratio_Si_to_N_diatoms, & - ! ratio_Si2N_sp = config_ratio_Si_to_N_small_plankton, & - ! ratio_Si2N_phaeo = config_ratio_Si_to_N_phaeocystis, & - ! ratio_S2N_diatoms = config_ratio_S_to_N_diatoms, & - ! ratio_S2N_sp = config_ratio_S_to_N_small_plankton, & - ! ratio_S2N_phaeo = config_ratio_S_to_N_phaeocystis, & - ! ratio_Fe2C_diatoms = config_ratio_Fe_to_C_diatoms, & - ! ratio_Fe2C_sp = config_ratio_Fe_to_C_small_plankton, & - ! ratio_Fe2C_phaeo = config_ratio_Fe_to_C_phaeocystis, & - ! ratio_Fe2N_diatoms = config_ratio_Fe_to_N_diatoms, & - ! ratio_Fe2N_sp = config_ratio_Fe_to_N_small_plankton, & - ! ratio_Fe2N_phaeo = config_ratio_Fe_to_N_phaeocystis, & - ! ratio_Fe2DON = config_ratio_Fe_to_DON, & - ! ratio_Fe2DOC_s = config_ratio_Fe_to_DOC_saccharids, & - ! ratio_Fe2DOC_l = config_ratio_Fe_to_DOC_lipids, & - ! fr_resp = config_respiration_fraction_of_growth, & - ! tau_min = config_rapid_mobile_to_stationary_time, & - ! tau_max = config_long_mobile_to_stationary_time, & - ! algal_vel = config_algal_maximum_velocity, & - ! R_dFe2dust = config_ratio_Fe_to_dust, & - ! dustFe_sol = config_solubility_of_Fe_in_dust, & - ! chlabs_diatoms = config_chla_absorptivity_of_diatoms, & - ! chlabs_sp = config_chla_absorptivity_of_small_plankton, & - ! chlabs_phaeo = config_chla_absorptivity_of_phaeocystis, & - ! alpha2max_low_diatoms = config_light_attenuation_diatoms, & - ! alpha2max_low_sp = config_light_attenuation_small_plankton, & - ! alpha2max_low_phaeo = config_light_attenuation_phaeocystis, & - ! beta2max_diatoms = config_light_inhibition_diatoms, & - ! beta2max_sp = config_light_inhibition_small_plankton, & - ! beta2max_phaeo = config_light_inhibition_phaeocystis, & - ! mu_max_diatoms = config_maximum_growth_rate_diatoms, & - ! mu_max_sp = config_maximum_growth_rate_small_plankton, & - ! mu_max_phaeo = config_maximum_growth_rate_phaeocystis, & - ! mu_max_diatoms = config_temperature_growth_diatoms, & ! rename - ! mu_max_sp = config_temperature_growth_small_plankton, & - ! mu_max_phaeo = config_temperature_growth_phaeocystis, & - ! fr_graze_diatoms = config_grazed_fraction_diatoms, & - ! fr_graze_sp = config_grazed_fraction_small_plankton, & - ! fr_graze_phaeo = config_grazed_fraction_phaeocystis, & - ! mort_pre_diatoms = config_mortality_diatoms, & - ! mort_pre_sp = config_mortality_small_plankton, & - ! mort_pre_phaeo = config_mortality_phaeocystis, & - ! mort_Tdep_diatoms = config_temperature_mortality_diatoms, & - ! mort_Tdep_sp = config_temperature_mortality_small_plankton, & - ! mort_Tdep_phaeo = config_temperature_mortality_phaeocystis, & - ! k_exude_diatoms = config_exudation_diatoms, & - ! k_exude_sp = config_exudation_small_plankton, & - ! k_exude_phaeo = config_exudation_phaeocystis, & - ! K_Nit_diatoms = config_nitrate_saturation_diatoms, & - ! K_Nit_sp = config_nitrate_saturation_small_plankton, & - ! K_Nit_phaeo = config_nitrate_saturation_phaeocystis, & - ! K_Am_diatoms = config_ammonium_saturation_diatoms, & - ! K_Am_sp = config_ammonium_saturation_small_plankton, & - ! K_Am_phaeo = config_ammonium_saturation_phaeocystis, & - ! K_Sil_diatoms = config_silicate_saturation_diatoms, & - ! K_Sil_sp = config_silicate_saturation_small_plankton, & - ! K_Sil_phaeo = config_silicate_saturation_phaeocystis, & - ! K_Fe_diatoms = config_iron_saturation_diatoms, & - ! K_Fe_sp = config_iron_saturation_small_plankton, & - ! K_Fe_phaeo = config_iron_saturation_phaeocystis, & - ! f_don_protein = config_fraction_spilled_to_DON, & - ! kn_bac_protein = config_degredation_of_DON, & - ! f_don_Am_protein = config_fraction_DON_ammonium, & - ! f_doc_s = config_fraction_loss_to_saccharids, & - ! f_doc_l = config_fraction_loss_to_lipids, & - ! f_exude_s = config_fraction_exudation_to_saccharids, & - ! f_exude_l = config_fraction_exudation_to_lipids, & - ! k_bac_s = config_remineralization_saccharids, & - ! k_bac_l = config_remineralization_lipids, & - ! T_max = config_maximum_brine_temperature, & - ! fsal = config_salinity_dependence_of_growth, & - ! op_dep_min = config_minimum_optical_depth, & - ! fr_graze_s = config_slopped_grazing_fraction, & - ! fr_graze_e = config_excreted_fraction, & - ! fr_mort2min = config_fraction_mortality_to_ammonium, & - ! fr_dFe = config_fraction_iron_remineralized, & - ! k_nitrif = config_nitrification_rate, & - ! t_iron_conv = config_desorption_loss_particulate_iron, & - ! max_loss = config_maximum_loss_fraction, & - ! max_dfe_doc1 = config_maximum_ratio_iron_to_saccharids, & - ! fr_resp_s = config_respiration_loss_to_DMSPd, & - ! y_sk_DMS = config_DMSP_to_DMS_conversion_fraction, & - ! t_sk_conv = config_DMSP_to_DMS_conversion_time, & - ! t_sk_ox = config_DMS_oxidation_time, & - ! algaltype_diatoms = config_mobility_type_diatoms, & - ! algaltype_sp = config_mobility_type_small_plankton, & - ! algaltype_phaeo = config_mobility_type_phaeocystis, & - ! nitratetype = config_mobility_type_nitrate, & - ! ammoniumtype = config_mobility_type_ammonium, & - ! silicatetype = config_mobility_type_silicate, & - ! dmspptype = config_mobility_type_DMSPp, & - ! dmspdtype = config_mobility_type_DMSPd, & - ! humicstype = config_mobility_type_humics, & - ! doctype_s = config_mobility_type_saccharids, & - ! dictype_1 = config_mobility_type_lipids, & - ! dictype_1 = config_mobility_type_inorganic_carbon, & - ! dontype_protein = config_mobility_type_proteins, & - ! fedtype_1 = config_mobility_type_dissolved_iron, & - ! feptype_1 = config_mobility_type_particulate_iron, & - ! zaerotype_bc1 = config_mobility_type_black_carbon1, & - ! zaerotype_bc2 = config_mobility_type_black_carbon2, & - ! zaerotype_dust1 = config_mobility_type_dust1, & - ! zaerotype_dust2 = config_mobility_type_dust2, & - ! zaerotype_dust3 = config_mobility_type_dust3, & - ! zaerotype_dust4 = config_mobility_type_dust4, & - ! ratio_C2N_diatoms = config_ratio_C_to_N_diatoms, & - ! ratio_C2N_sp = config_ratio_C_to_N_small_plankton, & - ! ratio_C2N_phaeo = config_ratio_C_to_N_phaeocystis, & - ! ratio_chl2N_diatoms = config_ratio_chla_to_N_diatoms, & - ! ratio_chl2N_sp = config_ratio_chla_to_N_small_plankton, & - ! ratio_chl2N_phaeo = config_ratio_chla_to_N_phaeocystis, & - ! F_abs_chl_diatoms = config_scales_absorption_diatoms, & - ! F_abs_chl_sp = config_scales_absorption_small_plankton, & - ! F_abs_chl_phaeo = config_scales_absorption_phaeocystis, & - ! ratio_C2N_proteins = config_ratio_C_to_N_proteins, & - !----------------------------------------------------------------------- ! Parameters for thermodynamics !----------------------------------------------------------------------- @@ -15210,7 +15204,8 @@ end subroutine seaice_column_reinitialize_oceanic_fluxes subroutine init_column_tracer_object_for_biogeochemistry(domain, tracerObject) - use ice_colpkg, only: colpkg_init_zbgc + !use ice_colpkg, only: colpkg_init_zbgc + use icepack_intfc, only: icepack_init_zbgc type(domain_type), intent(in) :: & domain @@ -15550,188 +15545,186 @@ subroutine init_column_tracer_object_for_biogeochemistry(domain, tracerObject) allocate(tracerObject % index_dissolvedIronConcLayer(maxIronType)) tracerObject % nDissolvedIronIndex = nDissolvedIron - call colpkg_init_zbgc(& - nBioLayers, & - nIceLayers, & - nSnowLayers, & - nAlgae, & - nzAerosols, & - nDOC, & - nDIC, & - nDON, & - nDissolvedIron, & - nParticulateIron, & - tracerObject % firstAncestorMask, & - tracerObject % parentIndex, & - tracerObject % ancestorNumber, & - tracerObject % ancestorIndices, & - tracerObject % nBioTracersShortwave, & - config_use_brine, & - tracerObject % index_brineFraction,& - tracerObject % nTracers, & - tracerObject % nBioTracers, & - tracerObject % index_nitrateConc, & - tracerObject % index_ammoniumConc, & - tracerObject % index_silicateConc, & - tracerObject % index_DMSConc, & - tracerObject % index_nonreactiveConc, & - tracerObject % index_verticalSalinity, & - tracerObject % index_algaeConc, & - tracerObject % index_algalCarbon, & - tracerObject % index_algalChlorophyll, & - tracerObject % index_DOCConc, & - tracerObject % index_DONConc, & - tracerObject % index_DICConc, & - tracerObject % index_verticalAerosolsConc, & - tracerObject % index_DMSPpConc, & - tracerObject % index_DMSPdConc, & - tracerObject % index_dissolvedIronConc, & - tracerObject % index_particulateIronConc, & - tracerObject % index_mobileFraction, & - config_use_nitrate, & - config_use_ammonium, & - config_use_silicate, & - config_use_DMS, & - config_use_nonreactive, & - config_use_vertical_zsalinity, & - use_nitrogen, & - config_use_carbon, & - config_use_chlorophyll, & - config_use_DON, & - config_use_iron,& - config_use_zaerosols, & - tracerObject % index_verticalAerosolsConcShortwave, & - tracerObject % index_chlorophyllShortwave, & - tracerObject % index_algaeConcLayer, & - tracerObject % index_nitrateConcLayer, & - tracerObject % index_ammoniumConcLayer, & - tracerObject % index_silicateConcLayer, & - tracerObject % index_DMSConcLayer, & - tracerObject % index_DMSPpConcLayer, & - tracerObject % index_DMSPdConcLayer, & - tracerObject % index_algalCarbonLayer, & - tracerObject % index_algalChlorophyllLayer, & - tracerObject % index_DICConcLayer, & - tracerObject % index_DOCConcLayer, & - tracerObject % index_nonreactiveConcLayer, & - tracerObject % index_DONConcLayer, & - tracerObject % index_dissolvedIronConcLayer, & - tracerObject % index_particulateIronConcLayer, & - tracerObject % index_verticalAerosolsConcLayer, & - tracerObject % index_humicsConc, & - tracerObject % index_humicsConcLayer, & - config_use_humics, & - config_use_vertical_zsalinity, & - config_use_skeletal_biochemistry, & - config_use_vertical_tracers, & - config_use_shortwave_bioabsorption, & - config_use_vertical_biochemistry, & - config_fraction_biotracer_in_frazil, & - config_new_ice_fraction_biotracer, & - tracerObject % index_LayerIndexToDataArray, & - tracerObject % index_LayerIndexToBioIndex, & - tracerObject % nTracersNotBio, & - maxAlgaeType, & - maxDOCType, & - maxDICType, & - maxDONType, & - maxIronType, & - config_ratio_Si_to_N_diatoms, & - config_ratio_Si_to_N_small_plankton, & - config_ratio_Si_to_N_phaeocystis, & - config_ratio_S_to_N_diatoms, & - config_ratio_S_to_N_small_plankton, & - config_ratio_S_to_N_phaeocystis, & - config_ratio_Fe_to_C_diatoms, & - config_ratio_Fe_to_C_small_plankton, & - config_ratio_Fe_to_C_phaeocystis, & - config_ratio_Fe_to_N_diatoms, & - config_ratio_Fe_to_N_small_plankton, & - config_ratio_Fe_to_N_phaeocystis, & - config_ratio_Fe_to_DON, & - config_ratio_Fe_to_DOC_saccharids, & - config_ratio_Fe_to_DOC_lipids, & - config_chla_absorptivity_of_diatoms, & - config_chla_absorptivity_of_small_plankton, & - config_chla_absorptivity_of_phaeocystis, & - config_light_attenuation_diatoms, & - config_light_attenuation_small_plankton, & - config_light_attenuation_phaeocystis, & - config_light_inhibition_diatoms, & - config_light_inhibition_small_plankton, & - config_light_inhibition_phaeocystis, & - config_maximum_growth_rate_diatoms, & - config_maximum_growth_rate_small_plankton, & - config_maximum_growth_rate_phaeocystis, & - config_temperature_growth_diatoms, & - config_temperature_growth_small_plankton, & - config_temperature_growth_phaeocystis, & - config_grazed_fraction_diatoms, & - config_grazed_fraction_small_plankton, & - config_grazed_fraction_phaeocystis, & - config_mortality_diatoms, & - config_mortality_small_plankton, & - config_mortality_phaeocystis, & - config_temperature_mortality_diatoms, & - config_temperature_mortality_small_plankton, & - config_temperature_mortality_phaeocystis, & - config_exudation_diatoms, & - config_exudation_small_plankton, & - config_exudation_phaeocystis, & - config_nitrate_saturation_diatoms, & - config_nitrate_saturation_small_plankton, & - config_nitrate_saturation_phaeocystis, & - config_ammonium_saturation_diatoms, & - config_ammonium_saturation_small_plankton, & - config_ammonium_saturation_phaeocystis, & - config_silicate_saturation_diatoms, & - config_silicate_saturation_small_plankton, & - config_silicate_saturation_phaeocystis, & - config_iron_saturation_diatoms, & - config_iron_saturation_small_plankton, & - config_iron_saturation_phaeocystis, & - config_fraction_spilled_to_DON, & - config_degredation_of_DON, & - config_fraction_DON_ammonium, & - config_fraction_loss_to_saccharids, & - config_fraction_loss_to_lipids, & - config_fraction_exudation_to_saccharids, & - config_fraction_exudation_to_lipids, & - config_remineralization_saccharids, & - config_remineralization_lipids, & - config_mobility_type_diatoms, & - config_mobility_type_small_plankton, & - config_mobility_type_phaeocystis, & - config_mobility_type_saccharids, & - config_mobility_type_lipids, & - config_mobility_type_inorganic_carbon, & - config_mobility_type_proteins, & - config_mobility_type_dissolved_iron, & - config_mobility_type_particulate_iron, & - config_mobility_type_black_carbon1, & - config_mobility_type_black_carbon2, & - config_mobility_type_dust1, & - config_mobility_type_dust2, & - config_mobility_type_dust3, & - config_mobility_type_dust4, & - config_ratio_C_to_N_diatoms, & - config_ratio_C_to_N_small_plankton, & - config_ratio_C_to_N_phaeocystis, & - config_ratio_chla_to_N_diatoms, & - config_ratio_chla_to_N_small_plankton, & - config_ratio_chla_to_N_phaeocystis, & - config_scales_absorption_diatoms, & - config_scales_absorption_small_plankton, & - config_scales_absorption_phaeocystis, & - config_ratio_C_to_N_proteins, & - config_mobility_type_nitrate, & - config_mobility_type_ammonium, & - config_mobility_type_DMSPp, & - config_mobility_type_DMSPd, & - config_mobility_type_silicate, & - config_mobility_type_humics, & - config_rapid_mobile_to_stationary_time, & - config_long_mobile_to_stationary_time) + call icepack_init_zbgc(& + nblyr=nBioLayers, & + nilyr=nIceLayers, & + nslyr=nSnowLayers, & + n_algae=nAlgae, & + n_zaero=nzAerosols, & + n_doc=nDOC, & + n_dic=nDIC, & + n_don=nDON, & + n_fed=nDissolvedIron, & + n_fep=nParticulateIron, & + trcr_base=tracerObject % firstAncestorMask, & + trcr_depend=tracerObject % parentIndex, & + n_trcr_strata=tracerObject % ancestorNumber, & + nt_strata=tracerObject % ancestorIndices, & + nbtrcr_sw=tracerObject % nBioTracersShortwave, & + tr_brine=config_use_brine, & + nt_fbri=tracerObject % index_brineFraction,& + ntrcr=tracerObject % nTracers, & + nbtrcr=tracerObject % nBioTracers, & + nt_bgc_Nit=tracerObject % index_nitrateConc, & + nt_bgc_Am=tracerObject % index_ammoniumConc, & + nt_bgc_Sil=tracerObject % index_silicateConc, & + nt_bgc_DMS=tracerObject % index_DMSConc, & + nt_bgc_PON=tracerObject % index_nonreactiveConc, & + nt_bgc_S=tracerObject % index_verticalSalinity, & + nt_bgc_N=tracerObject % index_algaeConc, & + nt_bgc_C=tracerObject % index_algalCarbon, & + nt_bgc_chl=tracerObject % index_algalChlorophyll, & + nt_bgc_DOC=tracerObject % index_DOCConc, & + nt_bgc_DON=tracerObject % index_DONConc, & + nt_bgc_DIC=tracerObject % index_DICConc, & + nt_zaero=tracerObject % index_verticalAerosolsConc, & + nt_bgc_DMSPp=tracerObject % index_DMSPpConc, & + nt_bgc_DMSPd=tracerObject % index_DMSPdConc, & + nt_bgc_Fed=tracerObject % index_dissolvedIronConc, & + nt_bgc_Fep=tracerObject % index_particulateIronConc, & + nt_zbgc_frac=tracerObject % index_mobileFraction, & + tr_bgc_Nit=config_use_nitrate, & + tr_bgc_Am=config_use_ammonium, & + tr_bgc_Sil=config_use_silicate, & + tr_bgc_DMS=config_use_DMS, & + tr_bgc_PON=config_use_nonreactive, & + tr_bgc_N=use_nitrogen, & + tr_bgc_C=config_use_carbon, & + tr_bgc_chl=config_use_chlorophyll, & + tr_bgc_DON=config_use_DON, & + tr_bgc_Fe=config_use_iron,& + tr_zaero=config_use_zaerosols, & + nlt_zaero_sw=tracerObject % index_verticalAerosolsConcShortwave, & + nlt_chl_sw=tracerObject % index_chlorophyllShortwave, & + nlt_bgc_N=tracerObject % index_algaeConcLayer, & + nlt_bgc_Nit=tracerObject % index_nitrateConcLayer, & + nlt_bgc_Am=tracerObject % index_ammoniumConcLayer, & + nlt_bgc_Sil=tracerObject % index_silicateConcLayer, & + nlt_bgc_DMS=tracerObject % index_DMSConcLayer, & + nlt_bgc_DMSPp=tracerObject % index_DMSPpConcLayer, & + nlt_bgc_DMSPd=tracerObject % index_DMSPdConcLayer, & + nlt_bgc_C=tracerObject % index_algalCarbonLayer, & + nlt_bgc_chl=tracerObject % index_algalChlorophyllLayer, & + nlt_bgc_DIC=tracerObject % index_DICConcLayer, & + nlt_bgc_DOC=tracerObject % index_DOCConcLayer, & + nlt_bgc_PON=tracerObject % index_nonreactiveConcLayer, & + nlt_bgc_DON=tracerObject % index_DONConcLayer, & + nlt_bgc_Fed=tracerObject % index_dissolvedIronConcLayer, & + nlt_bgc_Fep=tracerObject % index_particulateIronConcLayer, & + nlt_zaero=tracerObject % index_verticalAerosolsConcLayer, & + nt_bgc_hum=tracerObject % index_humicsConc, & + nlt_bgc_hum=tracerObject % index_humicsConcLayer, & + tr_bgc_hum=config_use_humics, & + skl_bgc=config_use_skeletal_biochemistry, & + z_tracers=config_use_vertical_tracers, & + dEdd_algae=config_use_shortwave_bioabsorption, & + solve_zbgc=config_use_vertical_biochemistry, & + frazil_scav_in=config_fraction_biotracer_in_frazil, & + initbio_frac_in=config_new_ice_fraction_biotracer, & + bio_index_o_out=tracerObject % index_LayerIndexToDataArray, & + bio_index_out=tracerObject % index_LayerIndexToBioIndex, & + ntrcr_o=tracerObject % nTracersNotBio, & + max_algae_in=maxAlgaeType, & + max_doc_in=maxDOCType, & + max_dic_in=maxDICType, & + max_don_in=maxDONType, & + max_fe_in=maxIronType, & + ratio_Si2N_diatoms_in=config_ratio_Si_to_N_diatoms, & + ratio_Si2N_sp_in=config_ratio_Si_to_N_small_plankton, & + ratio_Si2N_phaeo_in=config_ratio_Si_to_N_phaeocystis, & + ratio_S2N_diatoms_in=config_ratio_S_to_N_diatoms, & + ratio_S2N_sp_in=config_ratio_S_to_N_small_plankton, & + ratio_S2N_phaeo_in=config_ratio_S_to_N_phaeocystis, & + ratio_Fe2C_diatoms_in=config_ratio_Fe_to_C_diatoms, & + ratio_Fe2C_sp_in=config_ratio_Fe_to_C_small_plankton, & + ratio_Fe2C_phaeo_in=config_ratio_Fe_to_C_phaeocystis, & + ratio_Fe2N_diatoms_in=config_ratio_Fe_to_N_diatoms, & + ratio_Fe2N_sp_in=config_ratio_Fe_to_N_small_plankton, & + ratio_Fe2N_phaeo_in=config_ratio_Fe_to_N_phaeocystis, & + ratio_Fe2DON_in=config_ratio_Fe_to_DON, & + ratio_Fe2DOC_s_in=config_ratio_Fe_to_DOC_saccharids, & + ratio_Fe2DOC_l_in=config_ratio_Fe_to_DOC_lipids, & + chlabs_diatoms_in=config_chla_absorptivity_of_diatoms, & + chlabs_sp_in=config_chla_absorptivity_of_small_plankton, & + chlabs_phaeo_in=config_chla_absorptivity_of_phaeocystis, & + alpha2max_low_diatoms_in=config_light_attenuation_diatoms, & + alpha2max_low_sp_in=config_light_attenuation_small_plankton, & + alpha2max_low_phaeo_in=config_light_attenuation_phaeocystis, & + beta2max_diatoms_in=config_light_inhibition_diatoms, & + beta2max_sp_in=config_light_inhibition_small_plankton, & + beta2max_phaeo_in=config_light_inhibition_phaeocystis, & + mu_max_diatoms_in=config_maximum_growth_rate_diatoms, & + mu_max_sp_in=config_maximum_growth_rate_small_plankton, & + mu_max_phaeo_in=config_maximum_growth_rate_phaeocystis, & + grow_Tdep_diatoms_in=config_temperature_growth_diatoms, & + grow_Tdep_sp_in=config_temperature_growth_small_plankton, & + grow_Tdep_phaeo_in=config_temperature_growth_phaeocystis, & + fr_graze_diatoms_in=config_grazed_fraction_diatoms, & + fr_graze_sp_in=config_grazed_fraction_small_plankton, & + fr_graze_phaeo_in=config_grazed_fraction_phaeocystis, & + mort_pre_diatoms_in=config_mortality_diatoms, & + mort_pre_sp_in=config_mortality_small_plankton, & + mort_pre_phaeo_in=config_mortality_phaeocystis, & + mort_Tdep_diatoms_in=config_temperature_mortality_diatoms, & + mort_Tdep_sp_in=config_temperature_mortality_small_plankton, & + mort_Tdep_phaeo_in=config_temperature_mortality_phaeocystis, & + k_exude_diatoms_in=config_exudation_diatoms, & + k_exude_sp_in=config_exudation_small_plankton, & + k_exude_phaeo_in=config_exudation_phaeocystis, & + K_Nit_diatoms_in=config_nitrate_saturation_diatoms, & + K_Nit_sp_in=config_nitrate_saturation_small_plankton, & + K_Nit_phaeo_in=config_nitrate_saturation_phaeocystis, & + K_Am_diatoms_in=config_ammonium_saturation_diatoms, & + K_Am_sp_in=config_ammonium_saturation_small_plankton, & + K_Am_phaeo_in=config_ammonium_saturation_phaeocystis, & + K_Sil_diatoms_in=config_silicate_saturation_diatoms, & + K_Sil_sp_in=config_silicate_saturation_small_plankton, & + K_Sil_phaeo_in=config_silicate_saturation_phaeocystis, & + K_Fe_diatoms_in=config_iron_saturation_diatoms, & + K_Fe_sp_in=config_iron_saturation_small_plankton, & + K_Fe_phaeo_in=config_iron_saturation_phaeocystis, & + f_don_protein_in=config_fraction_spilled_to_DON, & + kn_bac_protein_in=config_degredation_of_DON, & + f_don_Am_protein_in=config_fraction_DON_ammonium, & + f_doc_s_in=config_fraction_loss_to_saccharids, & + f_doc_l_in=config_fraction_loss_to_lipids, & + f_exude_s_in=config_fraction_exudation_to_saccharids, & + f_exude_l_in=config_fraction_exudation_to_lipids, & + k_bac_s_in=config_remineralization_saccharids, & + k_bac_l_in=config_remineralization_lipids, & + algaltype_diatoms_in=config_mobility_type_diatoms, & + algaltype_sp_in=config_mobility_type_small_plankton, & + algaltype_phaeo_in=config_mobility_type_phaeocystis, & + doctype_s_in=config_mobility_type_saccharids, & + doctype_l_in=config_mobility_type_lipids, & + dictype_1_in=config_mobility_type_inorganic_carbon, & + dontype_protein_in=config_mobility_type_proteins, & + fedtype_1_in=config_mobility_type_dissolved_iron, & + feptype_1_in=config_mobility_type_particulate_iron, & + zaerotype_bc1_in=config_mobility_type_black_carbon1, & + zaerotype_bc2_in=config_mobility_type_black_carbon2, & + zaerotype_dust1_in=config_mobility_type_dust1, & + zaerotype_dust2_in=config_mobility_type_dust2, & + zaerotype_dust3_in=config_mobility_type_dust3, & + zaerotype_dust4_in=config_mobility_type_dust4, & + ratio_C2N_diatoms_in=config_ratio_C_to_N_diatoms, & + ratio_C2N_sp_in=config_ratio_C_to_N_small_plankton, & + ratio_C2N_phaeo_in=config_ratio_C_to_N_phaeocystis, & + ratio_chl2N_diatoms_in=config_ratio_chla_to_N_diatoms, & + ratio_chl2N_sp_in=config_ratio_chla_to_N_small_plankton, & + ratio_chl2N_phaeo_in=config_ratio_chla_to_N_phaeocystis, & + F_abs_chl_diatoms_in=config_scales_absorption_diatoms, & + F_abs_chl_sp_in=config_scales_absorption_small_plankton, & + F_abs_chl_phaeo_in=config_scales_absorption_phaeocystis, & + ratio_C2N_proteins_in=config_ratio_C_to_N_proteins, & + nitratetype_in=config_mobility_type_nitrate, & + ammoniumtype_in=config_mobility_type_ammonium, & + dmspptype_in=config_mobility_type_DMSPp, & + dmspdtype_in=config_mobility_type_DMSPd, & + silicatetype_in=config_mobility_type_silicate, & + humtype_in=config_mobility_type_humics, & + tau_min_in=config_rapid_mobile_to_stationary_time, & + tau_max_in=config_long_mobile_to_stationary_time) ! check calculated tracer array size if (nTracers_temp /= tracerObject % nTracers) then @@ -15756,10 +15749,15 @@ end subroutine init_column_tracer_object_for_biogeochemistry subroutine init_column_biogeochemistry_profiles(domain, tracerObject) - use ice_colpkg, only: & - colpkg_init_bgc, & - colpkg_init_hbrine, & - colpkg_init_zsalinity + !use ice_colpkg, only: & + ! colpkg_init_bgc, & + ! colpkg_init_hbrine, & + ! colpkg_init_zsalinity + + use icepack_intfc, only: & + icepack_init_bgc, & + icepack_init_hbrine, & + icepack_load_ocean_bio_array type(domain_type), intent(inout) :: domain @@ -15781,9 +15779,7 @@ subroutine init_column_biogeochemistry_profiles(domain, tracerObject) config_use_vertical_tracers, & config_use_skeletal_biochemistry, & config_do_restart_zsalinity, & - config_do_restart_bgc, & - config_do_restart_hbrine, & - config_use_macromolecules + config_do_restart_hbrine real(kind=RKIND), pointer :: & config_dt, & @@ -15837,14 +15833,7 @@ subroutine init_column_biogeochemistry_profiles(domain, tracerObject) nBioLayersP1, & nBioLayersP2, & nCategories, & - nShortwaveBio, & - nZBGCTracers, & - maxAerosolType, & - maxAlgaeType, & - maxDOCType, & - maxDICType, & - maxDONType, & - maxIronType + nShortwaveBio integer :: & iCell @@ -15860,14 +15849,12 @@ subroutine init_column_biogeochemistry_profiles(domain, tracerObject) call MPAS_pool_get_config(domain % configs, "config_use_brine", config_use_brine) call MPAS_pool_get_config(domain % configs, "config_do_restart_zsalinity", config_do_restart_zsalinity) - call MPAS_pool_get_config(domain % configs, "config_do_restart_bgc", config_do_restart_bgc) call MPAS_pool_get_config(domain % configs, "config_do_restart_hbrine", config_do_restart_hbrine) call MPAS_pool_get_config(domain % configs, "config_use_vertical_zsalinity", config_use_vertical_zsalinity) call MPAS_pool_get_config(domain % configs, "config_use_skeletal_biochemistry", config_use_skeletal_biochemistry) call MPAS_pool_get_config(domain % configs, "config_use_vertical_tracers", config_use_vertical_tracers) call MPAS_pool_get_config(domain % configs, "config_dt", config_dt) call MPAS_pool_get_config(domain % configs, "config_snow_porosity_at_ice_surface", config_snow_porosity_at_ice_surface) - call MPAS_pool_get_config(domain % configs, "config_use_macromolecules", config_use_macromolecules) abortFlag = .false. @@ -15926,23 +15913,15 @@ subroutine init_column_biogeochemistry_profiles(domain, tracerObject) call MPAS_pool_get_dimension(block % dimensions, "nBioLayersP1", nBioLayersP1) call MPAS_pool_get_dimension(block % dimensions, "nBioLayersP2", nBioLayersP2) call MPAS_pool_get_dimension(block % dimensions, "nShortwaveBio", nShortwaveBio) - call MPAS_pool_get_dimension(block % dimensions, "nZBGCTracers", nZBGCTracers) - call MPAS_pool_get_dimension(block % dimensions, "maxAerosolType", maxAerosolType) - call MPAS_pool_get_dimension(block % dimensions, "maxAlgaeType", maxAlgaeType) - call MPAS_pool_get_dimension(block % dimensions, "maxDOCType", maxDOCType) - call MPAS_pool_get_dimension(block % dimensions, "maxDICType", maxDICType) - call MPAS_pool_get_dimension(block % dimensions, "maxDONType", maxDONType) - call MPAS_pool_get_dimension(block % dimensions, "maxIronType", maxIronType) - - call colpkg_init_hbrine(& - biologyGrid, & - interfaceBiologyGrid, & - verticalGrid, & - interfaceGrid, & - verticalShortwaveGrid, & - nBioLayers, & - nIceLayers, & - config_snow_porosity_at_ice_surface) + call icepack_init_hbrine(& + bgrid=biologyGrid, & + igrid=interfaceBiologyGrid, & + cgrid=verticalGrid, & + icgrid=interfaceGrid, & + swgrid=verticalShortwaveGrid, & + nblyr=nBioLayers, & + nilyr=nIceLayers, & + phi_snow=config_snow_porosity_at_ice_surface) do iCell = 1, nCellsSolve if (.not. config_do_restart_hbrine) then @@ -15957,65 +15936,41 @@ subroutine init_column_biogeochemistry_profiles(domain, tracerObject) call set_cice_tracer_array_category(block, tracerObject, & tracerArrayCategory, iCell, setGetPhysicsTracers, setGetBGCTracers) - if (config_use_vertical_zsalinity) then - call colpkg_init_zsalinity(& - nBioLayers, & - tracerObject % nTracersNotBio, & - config_do_restart_zsalinity, & - rayleighCriteria, & - rayleighCriteriaReal(iCell), & - tracerArrayCategory(tracerObject % nTracersNotBio+1:tracerObject % nTracers,:), & - tracerObject % index_verticalSalinity, & - nCategories, & - seaSurfaceSalinity(iCell)) - endif - if (config_use_vertical_tracers .or. config_use_skeletal_biochemistry) then - call colpkg_init_bgc(& - config_dt, & - nCategories, & - nBioLayers, & - nIceLayers, & - tracerObject % nTracersNotBio, & - verticalGrid, & - interfaceBiologyGrid, & - config_do_restart_bgc, & - tracerObject % nTracers, & - tracerObject % nBiotracers, & - iceSalinity(:,:,iCell), & - tracerArrayCategory(tracerObject % nTracersNotBio+1:tracerObject % nTracers,:), & - seaSurfaceSalinity(iCell), & - oceanNitrateConc(iCell), & - oceanAmmoniumConc(iCell), & - oceanSilicateConc(iCell), & - oceanDMSPConc(iCell), & - oceanDMSConc(iCell), & - oceanAlgaeConc(:,iCell), & - oceanDOCConc(:,iCell), & - oceanDONConc(:,iCell), & - oceanDICConc(:,iCell), & - oceanDissolvedIronConc(:,iCell), & - oceanParticulateIronConc(:,iCell), & - oceanZAerosolConc(:,iCell), & - oceanHumicsConc(iCell), & - oceanBioConcentrations(:,iCell), & - maxAlgaeType, & - maxDOCType, & - maxDICType, & - maxDONType, & - maxIronType, & - nZBGCTracers, & - maxAerosolType, & - DOCPoolFractions, & - config_use_macromolecules, & - abortFlag, & - abortMessage) - - if (abortFlag) then - call mpas_log_write(& - "init_column_biogeochemistry_profiles: colpkg_init_bgc: "//trim(abortMessage), & - messageType=MPAS_LOG_CRIT) - endif + + call icepack_load_ocean_bio_array(& + nit=oceanNitrateConc(iCell), & + amm=oceanAmmoniumConc(iCell), & + sil=oceanSilicateConc(iCell), & + dmsp=oceanDMSPConc(iCell), & + dms=oceanDMSConc(iCell), & + algalN=oceanAlgaeConc(:,iCell), & + doc=oceanDOCConc(:,iCell), & + don=oceanDONConc(:,iCell), & + dic=oceanDICConc(:,iCell), & + fed=oceanDissolvedIronConc(:,iCell), & + fep=oceanParticulateIronConc(:,iCell), & + zaeros=oceanZAerosolConc(:,iCell), & + ocean_bio_all=oceanBioConcentrations(:,iCell), & + hum=oceanHumicsConc(iCell)) + + call icepack_init_bgc(& + ncat=nCategories, & + nblyr=nBioLayers, & + nilyr=nIceLayers, & + ntrcr_o=tracerObject % nTracersNotBio, & + cgrid=verticalGrid, & + igrid=interfaceBiologyGrid, & + ntrcr=tracerObject % nTracers, & + nbtrcr=tracerObject % nBiotracers, & + sicen=iceSalinity(:,:,iCell), & + trcrn=tracerArrayCategory(tracerObject % nTracersNotBio+1:tracerObject % nTracers,:), & + sss=seaSurfaceSalinity(iCell), & + ocean_bio_all=oceanBioConcentrations(:,iCell), & + DOCPoolFractions=DOCPoolFractions) + + call seaice_icepack_write_warnings(icepack_warnings_aborted()) + endif ! biogeochemistry ! get the category tracer array @@ -16527,8 +16482,9 @@ subroutine seaice_icepack_reinitialize_diagnostics_bgc(domain) config_use_column_biogeochemistry, & config_use_column_shortwave, & config_use_column_package, & - config_use_vertical_biochemistry, & - config_use_vertical_zsalinity + config_use_vertical_tracers, & + config_use_vertical_zsalinity, & + config_use_zaerosols call MPAS_pool_get_config(domain % blocklist % configs, "config_use_column_package", config_use_column_package) @@ -16539,15 +16495,16 @@ subroutine seaice_icepack_reinitialize_diagnostics_bgc(domain) ! biogeochemistry call MPAS_pool_get_config(block % configs, "config_use_column_biogeochemistry", config_use_column_biogeochemistry) - call MPAS_pool_get_config(block % configs, "config_use_vertical_biochemistry", config_use_vertical_biochemistry) + call MPAS_pool_get_config(block % configs, "config_use_zaerosols", config_use_zaerosols) + call MPAS_pool_get_config(block % configs, "config_use_vertical_tracers", config_use_vertical_tracers) call MPAS_pool_get_config(block % configs, "config_use_vertical_zsalinity", config_use_vertical_zsalinity) - if (config_use_column_biogeochemistry) then + if (config_use_column_biogeochemistry .or. config_use_zaerosols) then call MPAS_pool_get_subpool(block % structs, "biogeochemistry", biogeochemistryPool) call MPAS_pool_get_subpool(block % structs, "diagnostics_biogeochemistry", diagnostics_biogeochemistryPool) - if (config_use_vertical_biochemistry) then + if (config_use_vertical_tracers) then call MPAS_pool_get_array(biogeochemistryPool, "primaryProduction", primaryProduction) call MPAS_pool_get_array(biogeochemistryPool, "totalChlorophyll", totalChlorophyll) call MPAS_pool_get_array(biogeochemistryPool, "netSpecificAlgalGrowthRate", netSpecificAlgalGrowthRate) @@ -16594,7 +16551,7 @@ subroutine seaice_icepack_reinitialize_diagnostics_bgc(domain) call MPAS_pool_get_config(block % configs, "config_use_column_shortwave", config_use_column_shortwave) - if (config_use_column_biogeochemistry .or. config_use_column_shortwave) then + if (config_use_column_biogeochemistry .or. config_use_column_shortwave .or. config_use_zaerosols) then call MPAS_pool_get_subpool(block % structs, "biogeochemistry", biogeochemistryPool) call MPAS_pool_get_array(biogeochemistryPool, "bioTracerShortwave", bioTracerShortwave) diff --git a/components/mpas-seaice/src/shared/mpas_seaice_initialize.F b/components/mpas-seaice/src/shared/mpas_seaice_initialize.F index ddbbaf0af2cd..3aa80c434277 100644 --- a/components/mpas-seaice/src/shared/mpas_seaice_initialize.F +++ b/components/mpas-seaice/src/shared/mpas_seaice_initialize.F @@ -2305,7 +2305,8 @@ subroutine initialize_coupler_fields(domain) config_do_restart, & config_use_column_biogeochemistry, & config_use_column_package, & - config_use_aerosols + config_use_aerosols, & + config_use_zaerosols integer, pointer :: & nCells @@ -2402,8 +2403,9 @@ subroutine initialize_coupler_fields(domain) endif call MPAS_pool_get_config(block % configs, "config_use_column_biogeochemistry", config_use_column_biogeochemistry) + call MPAS_pool_get_config(block % configs, "config_use_zaerosols", config_use_zaerosols) - if (config_use_column_biogeochemistry) then + if (config_use_column_biogeochemistry .or. config_use_zaerosols) then call MPAS_pool_get_subpool(block % structs, "biogeochemistry", biogeochemistry) From e09f1873484ffa3c20ad3bdc5ae1d4e16b52941a Mon Sep 17 00:00:00 2001 From: Nicole Jeffery Date: Fri, 13 Oct 2023 14:28:40 -0500 Subject: [PATCH 002/451] Clean-up from the merge --- components/mpas-seaice/src/column/ice_algae.F90 | 16 +++++++++++++--- .../model_forward/mpas_seaice_core_interface.F | 8 ++++---- .../mpas-seaice/src/shared/mpas_seaice_column.F | 1 + .../mpas-seaice/src/shared/mpas_seaice_icepack.F | 6 +++--- .../src/shared/mpas_seaice_initialize.F | 4 ++-- 5 files changed, 23 insertions(+), 12 deletions(-) diff --git a/components/mpas-seaice/src/column/ice_algae.F90 b/components/mpas-seaice/src/column/ice_algae.F90 index f5c97b8f0a6a..6ba380a4f048 100644 --- a/components/mpas-seaice/src/column/ice_algae.F90 +++ b/components/mpas-seaice/src/column/ice_algae.F90 @@ -2259,6 +2259,10 @@ subroutine algal_dyn (dt, & write(warning, *) 'Conservation error!' call add_warning(warning) if (tr_bgc_DON) then + write(warning, *) 'Error bound = max(puny,maxval(abs(reactb(:)))*1.0e-13_dbl_kind)' + call add_warning(warning) + write(warning, *) max(puny,maxval(abs(reactb(:)))*1.0e-13_dbl_kind) + call add_warning(warning) write(warning, *) 'dN,DONin(1), kn_bac(1),secday,dt,n_doc' call add_warning(warning) write(warning, *) dN, DONin(1),kn_bac(1),secday,dt,n_doc @@ -2272,10 +2276,16 @@ subroutine algal_dyn (dt, & call add_warning(warning) write(warning, *) dN,secday,dt,n_doc call add_warning(warning) - write(warning, *) 'reactb(nlt_bgc_Nit),reactb(nlt_bgc_N(1)),reactb(nlt_bgc_N(2)' + write(warning, *) 'reactb(nlt_bgc_Nit),fr_resp' call add_warning(warning) - write(warning, *) reactb(nlt_bgc_Nit),reactb(nlt_bgc_N(1)),reactb(nlt_bgc_N(2)) + write(warning, *) reactb(nlt_bgc_Nit),fr_resp call add_warning(warning) + do k = 1,n_algae + write(warning, *) 'reactb(nlt_bgc_N(k)),fr_graze(k), grow_N(k), mort(k)' + call add_warning(warning) + write(warning, *) reactb(nlt_bgc_N(k)),fr_graze(k), grow_N(k), mort(k) + call add_warning(warning) + enddo if (tr_bgc_Am) then write(warning, *) 'reactb(nlt_bgc_Am),Am_r, Am_s' call add_warning(warning) @@ -2298,6 +2308,7 @@ subroutine algal_dyn (dt, & write(warning, *) 'DOC_r,DOC_s' call add_warning(warning) write(warning, *) DOC_r(k),DOC_s(k) + call add_warning(warning) end do do k = 1,n_dic write(warning, *) 'DICin' @@ -2312,7 +2323,6 @@ subroutine algal_dyn (dt, & call add_warning(warning) write(warning, *) DIC_r(k),DIC_s(k) end do - call add_warning(warning) write(warning, *) 'Zoo' call add_warning(warning) write(warning, *) Zoo diff --git a/components/mpas-seaice/src/model_forward/mpas_seaice_core_interface.F b/components/mpas-seaice/src/model_forward/mpas_seaice_core_interface.F index 5e83f651daba..d89cf9dd0db6 100644 --- a/components/mpas-seaice/src/model_forward/mpas_seaice_core_interface.F +++ b/components/mpas-seaice/src/model_forward/mpas_seaice_core_interface.F @@ -315,14 +315,14 @@ subroutine setup_packages_column_physics(configPool, packagePool, ierr)!{{{ call MPAS_pool_get_config(configPool, "config_use_column_physics", config_use_column_physics) call MPAS_pool_get_config(configPool, "config_use_column_biogeochemistry", config_use_column_biogeochemistry) - call MPAS_pool_get_config(configPool, "config_use_column_zaerosols", config_use_zaerosols) + call MPAS_pool_get_config(configPool, "config_use_zaerosols", config_use_zaerosols) call MPAS_pool_get_package(packagePool, "pkgColumnPackageActive", pkgColumnPackageActive) call MPAS_pool_get_package(packagePool, "pkgColumnBiogeochemistryActive", pkgColumnBiogeochemistryActive) - pkgColumnPackageActive = config_use_column_package + pkgColumnPackageActive = config_use_column_physics pkgColumnBiogeochemistryActive = ((config_use_column_biogeochemistry .or. config_use_zaerosols) & - .and. config_use_column_package) + .and. config_use_column_physics) !pkgColumnPackageActive = .true. !pkgColumnBiogeochemistryActive = .true. @@ -494,7 +494,7 @@ subroutine setup_packages_column_physics(configPool, packagePool, ierr)!{{{ pkgColumnTracerSnowGrainRadiusActive = .false. endif - if (.not. config_use_column_biogeochemistry .and. config_use_column_package) then + if (.not. config_use_column_biogeochemistry .and. config_use_column_physics) then pkgTracerSkeletalAlgaeActive = .false. pkgTracerSkeletalNitrateActive = .false. pkgTracerSkeletalCarbonActive = .false. diff --git a/components/mpas-seaice/src/shared/mpas_seaice_column.F b/components/mpas-seaice/src/shared/mpas_seaice_column.F index 78155f0f73e1..4364e808a8e0 100644 --- a/components/mpas-seaice/src/shared/mpas_seaice_column.F +++ b/components/mpas-seaice/src/shared/mpas_seaice_column.F @@ -14830,6 +14830,7 @@ subroutine seaice_column_reinitialize_diagnostics_bgc(domain) bioTracerShortwave logical, pointer :: & + config_use_column_physics, & config_use_column_biogeochemistry, & config_use_column_shortwave, & config_use_column_package, & diff --git a/components/mpas-seaice/src/shared/mpas_seaice_icepack.F b/components/mpas-seaice/src/shared/mpas_seaice_icepack.F index 729707271286..050ec91c0741 100644 --- a/components/mpas-seaice/src/shared/mpas_seaice_icepack.F +++ b/components/mpas-seaice/src/shared/mpas_seaice_icepack.F @@ -12502,8 +12502,8 @@ subroutine init_icepack_package_configs(domain) grid_o_t_in = config_biogrid_top_molecular_sublayer, & !initbio_frac_in = config_new_ice_fraction_biotracer, & !frazil_scav_in = config_fraction_biotracer_in_frazil, & - grid_oS_in = config_zsalinity_molecular_sublayer, & - l_skS_in = config_zsalinity_gravity_drainage_scale, & + !grid_oS_in = config_zsalinity_molecular_sublayer, & + !l_skS_in = config_zsalinity_gravity_drainage_scale, & phi_snow_in = config_snow_porosity_at_ice_surface, & !ratio_Si2N_diatoms_in = config_ratio_Si_to_N_diatoms, & !ratio_Si2N_sp_in = config_ratio_Si_to_N_small_plankton, & @@ -15942,7 +15942,7 @@ subroutine seaice_icepack_reinitialize_diagnostics_bgc(domain) logical, pointer :: & config_use_column_biogeochemistry, & config_use_column_shortwave, & - config_use_column_package, & + config_use_column_physics, & config_use_vertical_tracers, & config_use_vertical_zsalinity, & config_use_zaerosols diff --git a/components/mpas-seaice/src/shared/mpas_seaice_initialize.F b/components/mpas-seaice/src/shared/mpas_seaice_initialize.F index 87245eaecc80..e2ca0dbf2216 100644 --- a/components/mpas-seaice/src/shared/mpas_seaice_initialize.F +++ b/components/mpas-seaice/src/shared/mpas_seaice_initialize.F @@ -2577,10 +2577,10 @@ subroutine initialize_coupler_fields(domain) maxAerosolType, & nZBGCTracers - logical, pointer :: & + logical, pointer :: & config_do_restart, & config_use_column_biogeochemistry, & - config_use_column_package, & + config_use_column_physics, & config_use_aerosols, & config_use_zaerosols From e5b6cda92fdee34f2f7eab102c9539ce28494546 Mon Sep 17 00:00:00 2001 From: Nicole Jeffery Date: Fri, 13 Oct 2023 15:02:50 -0500 Subject: [PATCH 003/451] Modified algal growth by mistake in merge. Changed back to original formulation. --- components/mpas-seaice/src/column/ice_algae.F90 | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/components/mpas-seaice/src/column/ice_algae.F90 b/components/mpas-seaice/src/column/ice_algae.F90 index 6ba380a4f048..c450e8ee059c 100644 --- a/components/mpas-seaice/src/column/ice_algae.F90 +++ b/components/mpas-seaice/src/column/ice_algae.F90 @@ -2016,9 +2016,8 @@ subroutine algal_dyn (dt, & N_r_g = graze(k) * dt N_r_r = resp(k) * dt N_r_mo = mort(k) * dt - N_s(k) = (c1- fr_resp - fr_graze(k)) * grow_N(k) *dt !N_s_p - N_r(k) = mort(k) * dt !N_r_g + N_r_mo + N_r_r - + N_s(k) = N_s_p !(c1- fr_resp - fr_graze(k)) * grow_N(k) *dt + N_r(k) = N_r_g + N_r_mo + N_r_r !mort(k) * dt graze_N = graze_N + graze(k) graze_C = graze_C + R_C2N(k)*graze(k) mort_N = mort_N + mort(k) From 4b776941b3eb936f43e83e2a6f3092ed01373489 Mon Sep 17 00:00:00 2001 From: Nicole Jeffery Date: Tue, 24 Oct 2023 13:15:07 -0500 Subject: [PATCH 004/451] Adds the interface for icepack zaerosols and zbgc -bugfix in carbon conservation - Fluxes scaled by aicen not aicen_init -puts snow aerosols into ice rather than ocean for small snow volumes -Changes vertical z-tracer flags so that aerosols and bgc are turned on separately: 1) config_use_column_biogeochemistry indicates biogeochemical tracers are on 2) config_use_zaerosols indicates dust and black carbon are on BFB in the default configuration. nonBFB with zaerosols or column_biogeochemistry --- .../mpas-seaice/src/column/ice_aerosol.F90 | 20 ++- .../mpas-seaice/src/column/ice_algae.F90 | 22 ++- .../mpas-seaice/src/column/ice_warnings.F90 | 2 +- .../mpas-seaice/src/column/ice_zbgc.F90 | 6 +- .../src/shared/mpas_seaice_column.F | 22 ++- .../src/shared/mpas_seaice_icepack.F | 144 ++++++------------ 6 files changed, 101 insertions(+), 115 deletions(-) diff --git a/components/mpas-seaice/src/column/ice_aerosol.F90 b/components/mpas-seaice/src/column/ice_aerosol.F90 index c3e6a9d0bf27..a4a270713a80 100644 --- a/components/mpas-seaice/src/column/ice_aerosol.F90 +++ b/components/mpas-seaice/src/column/ice_aerosol.F90 @@ -580,17 +580,21 @@ subroutine update_snow_bgc (dt, nblyr, & if (dzssl_new .lt. hs_ssl_min) then ! Put atm BC/dust flux directly into the sea ice do k=1,nbtrcr - flux_bio(k) = flux_bio(k) + & + flux_bio_o(k) = flux_bio(k) + if (hilyr .lt. hs_ssl_min) then + flux_bio(k) = flux_bio(k) + & (trcrn(bio_index(k)+ nblyr+1)*dzssl+ & trcrn(bio_index(k)+ nblyr+2)*dzint)/dt - trcrn(bio_index(k) + nblyr+1) = c0 - trcrn(bio_index(k) + nblyr+2) = c0 - if (hilyr .lt. hs_ssl_min) then flux_bio(k) = flux_bio(k) + flux_bio_atm(k) else + zbgc_snow(k) = zbgc_snow(k) + & + (trcrn(bio_index(k)+ nblyr+1)*dzssl+ & + trcrn(bio_index(k)+ nblyr+2)*dzint) zbgc_atm(k) = zbgc_atm(k) & + flux_bio_atm(k)*dt end if + trcrn(bio_index(k) + nblyr+1) = c0 + trcrn(bio_index(k) + nblyr+2) = c0 enddo else @@ -616,7 +620,7 @@ subroutine update_snow_bgc (dt, nblyr, & end if if (dzint <= puny) then do k = 1,nbtrcr - flux_bio(k) = flux_bio(k) + (aerosno(k,2) + aerosno(k,1))/dt + zbgc_snow(k) = zbgc_snow(k) + (aerosno(k,2) + aerosno(k,1)) aerosno(k,2) = c0 aerosno(k,1) = c0 end do @@ -636,6 +640,7 @@ subroutine update_snow_bgc (dt, nblyr, & dzssl = dzssl - dz + fsnow/rhos*dt dzint = dzint + dz end if + if (dzssl <= puny) then do k = 1,nbtrcr aerosno(k,2) = aerosno(k,2) + aerosno(k,1) @@ -644,7 +649,7 @@ subroutine update_snow_bgc (dt, nblyr, & end if if (dzint <= puny) then do k = 1,nbtrcr - flux_bio(k) = flux_bio(k) + (aerosno(k,2) + aerosno(k,1))/dt + zbgc_snow(k) = zbgc_snow(k) + (aerosno(k,2) + aerosno(k,1)) aerosno(k,2) = c0 aerosno(k,1) = c0 end do @@ -664,7 +669,7 @@ subroutine update_snow_bgc (dt, nblyr, & sloss2 = kscavz(bio_index_o(k))*aerosno(k,2) & *max(-dhs_melts-dzssl,c0)/dzint aerosno(k,2) = max(c0,aerosno(k,2) - sloss2) - flux_bio(k) = flux_bio(k) + (sloss1+sloss2)/dt ! all not scavenged ends in ocean + zbgc_snow(k) = zbgc_snow(k) + (sloss1+sloss2) ! all not scavenged ends in ice enddo ! update snow thickness @@ -795,6 +800,7 @@ subroutine update_snow_bgc (dt, nblyr, & else if (aerotot(k) > c0) then aero_cons(k) = aero_cons(k)/aerotot(k) end if + if (aero_cons(k) > puny .or. zbgc_snow(k) + zbgc_atm(k) < c0) then write(warning,*) 'Conservation failure: aerosols in snow' call add_warning(warning) diff --git a/components/mpas-seaice/src/column/ice_algae.F90 b/components/mpas-seaice/src/column/ice_algae.F90 index c450e8ee059c..ec7afff60733 100644 --- a/components/mpas-seaice/src/column/ice_algae.F90 +++ b/components/mpas-seaice/src/column/ice_algae.F90 @@ -347,8 +347,12 @@ subroutine zbio (dt, nblyr, & call add_warning(warning) write(warning,*) Tot_BGC_i(mm) + flux_bio_atm(mm)*dt - flux_bion(mm)*dt call add_warning(warning) - !l_stop = .true. - !stop_label = "carbon conservation in ice_algae.F90" + write(warning,*) 'hbri, hbri_old' + call add_warning(warning) + write(warning,*) hbri, hbri_old + call add_warning(warning) + l_stop = .true. + stop_label = "carbon conservation in ice_algae.F90" enddo endif endif @@ -1021,7 +1025,7 @@ subroutine z_biogeochemistry (n_cat, dt, & Nquota_I = 0.0408_dbl_kind, & ! Intercept in N quota to cell volume fit f_s = p1, & ! fracton of sites available for saturation f_a = 0.3_dbl_kind, & !c1 , & ! fraction of collector available for attachment - f_v = 0.7854 ! fraction of algal coverage on area availabel for attachment + f_v = 0.7854_dbl_kind ! fraction of algal coverage on area availabel for attachment ! 4(pi r^2)/(4r)^2 [Johnson et al, 1995, water res. research] integer, parameter :: & @@ -1413,8 +1417,16 @@ subroutine z_biogeochemistry (n_cat, dt, & call add_warning(warning) write(warning, *) m, nlt_bgc_DIC(1), bio_tmp, react(k,m) call add_warning(warning) - flux_bio(m) = flux_bio(m) + bio_tmp*dz(k)*hbri_old/dt + write(warning,*)'flux_bio(m) Initial, hbri_old, dz(k)' + call add_warning(warning) + write(warning,*) flux_bio(m), hbri_old, dz(k) + call add_warning(warning) + flux_bio(m) = flux_bio(m) + bio_tmp*dz(k)*hbri/dt bio_tmp = c0 + write(warning,*) 'flux_bio(m)' + call add_warning(warning) + write(warning,*) flux_bio(m) + call add_warning(warning) end if if (m .eq. nlt_bgc_Nit) then initcons_mobile(k) = max(c0,(biomat_brine(k,m)-nitrification(k) + & @@ -1442,7 +1454,7 @@ subroutine z_biogeochemistry (n_cat, dt, & l_stop = .true. stop_label = 'C in algal_dyn not conserved' elseif (abs(bio_tmp) < puny) then - flux_bio(m) = flux_bio(m) + bio_tmp*dz(k)*hbri_old/dt + flux_bio(m) = flux_bio(m) + bio_tmp*dz(k)*hbri/dt bio_tmp = c0 elseif (bio_tmp > 1.0e8_dbl_kind) then write(warning, *) 'very large bgc value' diff --git a/components/mpas-seaice/src/column/ice_warnings.F90 b/components/mpas-seaice/src/column/ice_warnings.F90 index a3424c176bb7..091c8b2be944 100644 --- a/components/mpas-seaice/src/column/ice_warnings.F90 +++ b/components/mpas-seaice/src/column/ice_warnings.F90 @@ -82,7 +82,7 @@ subroutine add_warning(warning) deallocate(warningsTmp) endif - + endif ! increase warning number diff --git a/components/mpas-seaice/src/column/ice_zbgc.F90 b/components/mpas-seaice/src/column/ice_zbgc.F90 index 1f1c6a7d9106..e8cef6dcad9f 100644 --- a/components/mpas-seaice/src/column/ice_zbgc.F90 +++ b/components/mpas-seaice/src/column/ice_zbgc.F90 @@ -679,9 +679,9 @@ subroutine merge_bgc_fluxes (dt, nblyr, & snow_bio_net(mm) = snow_bio_net(mm) & + trcrn(bio_index(mm)+nblyr+1)*dvssl & + trcrn(bio_index(mm)+nblyr+2)*dvint - flux_bio (mm) = flux_bio (mm) + flux_bion (mm)*aice_init - zbgc_snow (mm) = zbgc_snow(mm) + zbgc_snown(mm)*aice_init/dt - zbgc_atm (mm) = zbgc_atm (mm) + zbgc_atmn (mm)*aice_init/dt + flux_bio (mm) = flux_bio (mm) + flux_bion (mm)*aicen + zbgc_snow (mm) = zbgc_snow(mm) + zbgc_snown(mm)*aicen/dt + zbgc_atm (mm) = zbgc_atm (mm) + zbgc_atmn (mm)*aicen/dt enddo ! mm ! diagnostics : mean cell bio interface grid profiles diff --git a/components/mpas-seaice/src/shared/mpas_seaice_column.F b/components/mpas-seaice/src/shared/mpas_seaice_column.F index 4364e808a8e0..cfebdab2e200 100644 --- a/components/mpas-seaice/src/shared/mpas_seaice_column.F +++ b/components/mpas-seaice/src/shared/mpas_seaice_column.F @@ -2664,7 +2664,8 @@ subroutine column_snow(domain) logical, pointer :: & config_use_effective_snow_density, & config_use_snow_grain_radius, & - config_use_column_biogeochemistry + config_use_column_biogeochemistry, & + config_use_zaerosols real(kind=RKIND), dimension(:,:,:), pointer :: & snowIceMass, & @@ -2755,6 +2756,7 @@ subroutine column_snow(domain) call MPAS_pool_get_config(block % configs, "config_wind_compaction_factor", config_wind_compaction_factor) call MPAS_pool_get_config(block % configs, "config_snow_redistribution_factor", config_snow_redistribution_factor) call MPAS_pool_get_config(block % configs, "config_use_column_biogeochemistry", config_use_column_biogeochemistry) + call MPAS_pool_get_config(block % configs, "config_use_zaerosols", config_use_zaerosols) call MPAS_pool_get_dimension(block % dimensions, "nCellsSolve", nCellsSolve) call MPAS_pool_get_dimension(block % dimensions, "nCategories", nCategories) @@ -2798,7 +2800,7 @@ subroutine column_snow(domain) call MPAS_pool_get_array(ocean_fluxes, "oceanHeatFlux", oceanHeatFlux) setGetPhysicsTracers = .true. - setGetBGCTracers = config_use_column_biogeochemistry + setGetBGCTracers = (config_use_column_biogeochemistry .or. config_use_zaerosols) ! code abort abortFlag = .false. @@ -10326,10 +10328,20 @@ subroutine check_column_package_configs(domain) messageType=MPAS_LOG_CRIT) endif - ! check that vertical bio tracers and not used with skeletal bio tracers - if (config_use_vertical_tracers .and. config_use_skeletal_biochemistry) then + ! check that vertical bio tracers use brine height + if ((config_use_vertical_biochemistry .or. config_use_zaerosols) .and. & + (.not. config_use_brine .or. .not. config_use_vertical_tracers )) then + call mpas_log_write(& + "check_column_package_configs: vertical biochemistry and zaerosols require " //& + "config_use_brine and config_use_vertical_tracer = true", & + messageType=MPAS_LOG_CRIT) + endif + + ! check that brine height is used with either aerosols or bgc + if (config_use_brine .and. & + (.not. config_use_column_biogeochemistry .and. .not. config_use_zaerosols)) then call mpas_log_write(& - "check_column_package_configs: vertical bio tracers and skeletal bio tracers cannot both be true", & + "check_column_package_configs: brine tracer must be used with vertical tracers - config_use_column_biogeochemistry and/or config_use_zaerosols equal to true", & messageType=MPAS_LOG_CRIT) endif diff --git a/components/mpas-seaice/src/shared/mpas_seaice_icepack.F b/components/mpas-seaice/src/shared/mpas_seaice_icepack.F index 050ec91c0741..2c26fd08f400 100644 --- a/components/mpas-seaice/src/shared/mpas_seaice_icepack.F +++ b/components/mpas-seaice/src/shared/mpas_seaice_icepack.F @@ -2990,7 +2990,9 @@ subroutine column_radiation(domain, clock, lInitialization) iceBodyAerosol, & brineFraction, & bioTracerShortwave, & - snowGrainRadius + snowGrainRadius, & + verticalAerosolsConc, & + verticalAlgaeConc real(kind=RKIND), pointer :: & dayOfNextShortwaveCalculation ! needed for CESM like coupled simulations @@ -3060,11 +3062,11 @@ subroutine column_radiation(domain, clock, lInitialization) call MPAS_pool_get_config(block % configs, "config_dt", config_dt) call MPAS_pool_get_config(block % configs, "config_snow_redistribution_scheme", config_snow_redistribution_scheme) - call MPAS_pool_get_dimension(mesh, "nCellsSolve", nCellsSolve) - call MPAS_pool_get_dimension(mesh, "nCategories", nCategories) - call MPAS_pool_get_dimension(mesh, "nIceLayers", nIceLayers) - call MPAS_pool_get_dimension(mesh, "nSnowLayers", nSnowLayers) - call MPAS_pool_get_dimension(mesh, "nAerosols", nAerosols) + call MPAS_pool_get_dimension(block % dimensions, "nCellsSolve", nCellsSolve) + call MPAS_pool_get_dimension(block % dimensions, "nCategories", nCategories) + call MPAS_pool_get_dimension(block % dimensions, "nIceLayers", nIceLayers) + call MPAS_pool_get_dimension(block % dimensions, "nSnowLayers", nSnowLayers) + call MPAS_pool_get_dimension(block % dimensions, "nAerosols", nAerosols) call MPAS_pool_get_dimension(block % dimensions, "nAlgae", nAlgae) call MPAS_pool_get_dimension(block % dimensions, "nBioLayers", nBioLayers) call MPAS_pool_get_dimension(block % dimensions, "nzAerosols", nzAerosols) @@ -3087,6 +3089,8 @@ subroutine column_radiation(domain, clock, lInitialization) call MPAS_pool_get_array(tracers, "iceBodyAerosol", iceBodyAerosol, 1) call MPAS_pool_get_array(tracers, "brineFraction", brineFraction, 1) call MPAS_pool_get_array(tracers, "snowGrainRadius", snowGrainRadius, 1) + call MPAS_pool_get_array(tracers, "verticalAlgaeConc", verticalAlgaeConc, 1) + call MPAS_pool_get_array(tracers, "verticalAerosolsConc", verticalAerosolsConc, 1) call MPAS_pool_get_array(atmos_coupling, "shortwaveVisibleDirectDown", shortwaveVisibleDirectDown) call MPAS_pool_get_array(atmos_coupling, "shortwaveVisibleDiffuseDown", shortwaveVisibleDiffuseDown) @@ -3137,6 +3141,7 @@ subroutine column_radiation(domain, clock, lInitialization) allocate(index_shortwaveAerosol(maxAerosolType)) allocate(index_verticalAerosolsConc(maxAerosolType)) allocate(index_algaeConc(nAlgae)) + if (.not. config_use_zaerosols) then index_shortwaveAerosol(1:maxAerosolType) = 1 index_verticalAerosolsConc(1:maxAerosolType) = 1 @@ -3146,6 +3151,7 @@ subroutine column_radiation(domain, clock, lInitialization) index_verticalAerosolsConc(iAerosol) = ciceTracerObject % index_verticalAerosolsConc(iAerosol) enddo endif + if (.not. config_use_column_biogeochemistry) then index_algaeConc(1:nAlgae) = 1 else @@ -3190,10 +3196,6 @@ subroutine column_radiation(domain, clock, lInitialization) lonCellColumn = lonCell(iCell) if (lonCellColumn > seaicePi) lonCellColumn = lonCellColumn - 2.0_RKIND * seaicePi - ! set the category tracer array - call set_cice_tracer_array_category(block, ciceTracerObject, & - tracerArrayCategory, iCell, setGetPhysicsTracers, setGetBGCTracers) - call icepack_step_radiation(& dt=config_dt, & swgrid=verticalShortwaveGrid(:), & @@ -3208,8 +3210,8 @@ subroutine column_radiation(domain, clock, lInitialization) hpndn=pondDepth(1,:,iCell), & ipndn=pondLidThickness(1,:,iCell), & aeron=aerosolsArray, & - bgcNn=tracerArrayCategory(index_algaeConc(:),:), & - zaeron=tracerArrayCategory(index_verticalAerosolsConc(:),:), & + bgcNn=verticalAlgaeConc(:,:,iCell), & + zaeron=verticalAerosolsConc(:,:,iCell), & trcrn_bgcsw=bioTracerShortwave(:,:,iCell), & TLAT=latCell(iCell), & TLON=lonCellColumn, & @@ -3249,10 +3251,6 @@ subroutine column_radiation(domain, clock, lInitialization) l_print_point=.false., & initonly=lInitialization) - ! set the category tracer array - call get_cice_tracer_array_category(block, ciceTracerObject, & - tracerArrayCategory, iCell, setGetPhysicsTracers, setGetBGCTracers) - enddo ! iCell deallocate(snow_grain_radius) @@ -3603,7 +3601,6 @@ subroutine column_biogeochemistry(domain) ! variables real(kind=RKIND), dimension(:), pointer :: & - rayleighCriteriaReal, & netNitrateUptake, & netAmmoniumUptake, & totalVerticalSalinity, & @@ -3722,7 +3719,6 @@ subroutine column_biogeochemistry(domain) logical :: & abortFlag, & - rayleighCriteria, & setGetPhysicsTracers, & setGetBGCTracers, & checkCarbon @@ -3791,7 +3787,6 @@ subroutine column_biogeochemistry(domain) call MPAS_pool_get_array(biogeochemistry, "brineBottomChange", brineBottomChange) call MPAS_pool_get_array(biogeochemistry, "brineTopChange", brineTopChange) call MPAS_pool_get_array(biogeochemistry, "bioPorosity", bioPorosity) - call MPAS_pool_get_array(biogeochemistry, "rayleighCriteriaReal", rayleighCriteriaReal) call MPAS_pool_get_array(biogeochemistry, "biologyGrid", biologyGrid) call MPAS_pool_get_array(biogeochemistry, "interfaceBiologyGrid", interfaceBiologyGrid) call MPAS_pool_get_array(biogeochemistry, "interfaceGrid", interfaceGrid) @@ -3878,8 +3873,8 @@ subroutine column_biogeochemistry(domain) atmosBioFluxes(:,:) = 0.0_RKIND - !$omp parallel do default(shared) private(iCategory,iBioTracers,iAlgae, rayleighCriteria, & - !$omp& rayleighCriteriaReal) firstprivate(atmosBioFluxes,atmosBlackCarbonFlux, & + !$omp parallel do default(shared) private(iCategory,iBioTracers,iAlgae) & + !$omp& firstprivate(atmosBioFluxes,atmosBlackCarbonFlux, & !$omp& atmosDustFlux, bioShortwaveFluxCell, newlyFormedIce) ! do iCell = 1, nCellsSolve @@ -3889,7 +3884,6 @@ subroutine column_biogeochemistry(domain) brineHeightCatInitial(iCategory) = brineFraction(1,iCategory,iCell) * & iceVolumeCategoryInitial(iCategory,iCell)/(iceAreaCategoryInitial(iCategory,iCell) + seaicePuny) enddo ! iCategory - rayleighCriteria = (rayleighCriteriaReal(iCell) > 0.5_RKIND) !update ocean concentrations fields and atmospheric fluxes into allocated array #ifdef coupled @@ -3972,7 +3966,6 @@ subroutine column_biogeochemistry(domain) snow_bio_net=totalVerticalBiologySnow(:,iCell), & totalChla=totalChlorophyll(iCell), & fswthrun=penetratingShortwaveFlux(:,iCell), & - Rayleigh_criteria=rayleighCriteria, & bgrid=biologyGrid, & igrid=interfaceBiologyGrid, & icgrid=interfaceGrid, & @@ -4068,8 +4061,6 @@ subroutine column_biogeochemistry(domain) if (newlyFormedIceLogical(iCategory)) newlyFormedIce(iCategory,iCell) = 1 enddo ! iCategory - if (.not. rayleighCriteria) rayleighCriteriaReal(iCell) = 0.0_RKIND - enddo ! iCell ! code abort @@ -5585,8 +5576,8 @@ subroutine seaice_icepack_init_ocean_conc(& carbonToNitrogenRatioAlgae, & carbonToNitrogenRatioDON) - use ice_colpkg, only: & - colpkg_init_ocean_conc + use icepack_intfc, only: & + icepack_init_ocean_bio integer, intent(in) :: & maxDICType, & @@ -5615,26 +5606,26 @@ subroutine seaice_icepack_init_ocean_conc(& carbonToNitrogenRatioAlgae, & ! carbon to nitrogen ratio for algae carbonToNitrogenRatioDON ! nitrogen to carbon ratio for proteins - call colpkg_init_ocean_conc(& - oceanAmmoniumConc, & - oceanDMSPConc, & - oceanDMSConc, & - oceanAlgaeConc, & - oceanDOCConc, & - oceanDICConc, & - oceanDONConc, & - oceanDissolvedIronConc, & - oceanParticulateIronConc, & - oceanHumicsConc, & - oceanNitrateConc, & - oceanSilicateConc,& - oceanZAerosolConc, & - maxDICType, & - maxDONType, & - maxIronType, & - maxAerosolType, & - carbonToNitrogenRatioAlgae, & - carbonToNitrogenRatioDON) + call icepack_init_ocean_bio(& + amm=oceanAmmoniumConc, & + dmsp=oceanDMSPConc, & + dms=oceanDMSConc, & + algalN=oceanAlgaeConc, & + doc=oceanDOCConc, & + dic=oceanDICConc, & + don=oceanDONConc, & + fed=oceanDissolvedIronConc, & + fep=oceanParticulateIronConc, & + hum=oceanHumicsConc, & + nit=oceanNitrateConc, & + sil=oceanSilicateConc,& + zaeros=oceanZAerosolConc, & + max_dic=maxDICType, & + max_don=maxDONType, & + max_fe=maxIronType, & + max_aero=maxAerosolType, & + CToN=carbonToNitrogenRatioAlgae, & + CToN_DON=carbonToNitrogenRatioDON) end subroutine seaice_icepack_init_ocean_conc @@ -9560,10 +9551,10 @@ subroutine check_column_package_configs(domain) ! check biogeochemistry flags: ! if (.not. config_use_column_biogeochemistry .and. (config_use_brine .or. config_use_vertical_zsalinity .or. & - if (.not. config_use_column_biogeochemistry .and. (config_use_brine .or. & - config_use_vertical_biochemistry .or. config_use_shortwave_bioabsorption .or. config_use_vertical_tracers .or. & - config_use_skeletal_biochemistry .or. config_use_nitrate .or. config_use_carbon .or. config_use_chlorophyll .or. & - config_use_ammonium .or. config_use_silicate .or. config_use_DMS .or. config_use_nonreactive .or. config_use_humics .or. & + if (.not. config_use_column_biogeochemistry .and. (config_use_vertical_biochemistry .or. & + config_use_skeletal_biochemistry .or. config_use_nitrate .or. config_use_carbon .or. & + config_use_chlorophyll .or. config_use_ammonium .or. config_use_silicate .or. & + config_use_DMS .or. config_use_nonreactive .or. config_use_humics .or. & config_use_DON .or. config_use_iron)) then call mpas_log_write(& "check_column_package_configs: config_use_column_biogeochemistry = false. "//& @@ -9595,6 +9586,14 @@ subroutine check_column_package_configs(domain) messageType=MPAS_LOG_CRIT) endif + ! check that brine height is used with either aerosols or bgc + if (config_use_brine .and. & + (.not. config_use_column_biogeochemistry .and. .not. config_use_zaerosols)) then + call mpas_log_write(& + "check_column_package_configs: brine tracer must be used with vertical tracers - config_use_column_biogeochemistry and/or config_use_zaerosols equal to true", & + messageType=MPAS_LOG_CRIT) + endif + ! check that the shortwave scheme and bioabsorption is consistent if (config_use_shortwave_bioabsorption .and. .not. (trim(config_shortwave_type(1:4)) == "dEdd")) then call mpas_log_write(& @@ -14662,7 +14661,6 @@ end subroutine seaice_column_reinitialize_oceanic_fluxes subroutine init_column_tracer_object_for_biogeochemistry(domain, tracerObject) - !use ice_colpkg, only: colpkg_init_zbgc use icepack_intfc, only: icepack_init_zbgc type(domain_type), intent(in) :: & @@ -15207,11 +15205,6 @@ end subroutine init_column_tracer_object_for_biogeochemistry subroutine init_column_biogeochemistry_profiles(domain, tracerObject) - !use ice_colpkg, only: & - ! colpkg_init_bgc, & - ! colpkg_init_hbrine, & - ! colpkg_init_zsalinity - use icepack_intfc, only: & icepack_init_bgc, & icepack_init_hbrine, & @@ -15256,7 +15249,6 @@ subroutine init_column_biogeochemistry_profiles(domain, tracerObject) biologyGrid, & ! bgrid verticalShortwaveGrid, & ! swgrid interfaceGrid, & ! icgrid - rayleighCriteriaReal, & DOCPoolFractions real(kind=RKIND), dimension(:,:), pointer :: & @@ -15298,7 +15290,6 @@ subroutine init_column_biogeochemistry_profiles(domain, tracerObject) logical :: & abortFlag, & - rayleighCriteria, & setGetPhysicsTracers, & setGetBGCTracers @@ -15337,7 +15328,6 @@ subroutine init_column_biogeochemistry_profiles(domain, tracerObject) call MPAS_pool_get_array(biogeochemistry, "bioTracerShortwave", bioTracerShortwave) call MPAS_pool_get_array(biogeochemistry, "interfaceBiologyGrid", interfaceBiologyGrid) call MPAS_pool_get_array(biogeochemistry, "interfaceGrid", interfaceGrid) - call MPAS_pool_get_array(biogeochemistry, "rayleighCriteriaReal", rayleighCriteriaReal) call MPAS_pool_get_array(biogeochemistry, "verticalGrid", verticalGrid) call MPAS_pool_get_array(biogeochemistry, "biologyGrid", biologyGrid) call MPAS_pool_get_array(biogeochemistry, "verticalShortwaveGrid", verticalShortwaveGrid) @@ -17409,40 +17399,6 @@ subroutine seaice_total_carbon_content_category(block,totalCarbonContentCategory end subroutine seaice_total_carbon_content_category -!||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||| -!----------------------------------------------------------------------- -! Warning messages -!----------------------------------------------------------------------- - -!echmod: remove this subroutine and all calls to it - - subroutine column_write_warnings(logAsErrors) - - use ice_colpkg, only: colpkg_get_warnings - - character(len=strKINDWarnings), dimension(:), allocatable :: & - warnings - - logical, intent(in) :: & - logAsErrors - - integer :: & - iWarning - - call colpkg_get_warnings(warnings) - - if (logAsErrors) then - do iWarning = 1, size(warnings) - call mpas_log_write(trim(warnings(iWarning)), messageType=MPAS_LOG_ERR) - enddo ! iWarning - else - do iWarning = 1, size(warnings) - call mpas_log_write(trim(warnings(iWarning)), messageType=MPAS_LOG_WARN) - enddo ! iWarning - endif - - end subroutine column_write_warnings - !----------------------------------------------------------------------- subroutine seaice_icepack_write_warnings(logAsErrors) From fb48cef43718554e736a903685a32b282ba90fcd Mon Sep 17 00:00:00 2001 From: Nicole Jeffery Date: Tue, 31 Oct 2023 15:29:58 -0500 Subject: [PATCH 005/451] Removed init_column_package_tracer_indices from mpas_seaice_icepack This column_package subroutine was accidentally added during the merge. BFB --- components/mpas-seaice/src/icepack | 2 +- .../src/shared/mpas_seaice_icepack.F | 218 ------------------ 2 files changed, 1 insertion(+), 219 deletions(-) diff --git a/components/mpas-seaice/src/icepack b/components/mpas-seaice/src/icepack index 96f2fc707fc7..37a6f97a4ea8 160000 --- a/components/mpas-seaice/src/icepack +++ b/components/mpas-seaice/src/icepack @@ -1 +1 @@ -Subproject commit 96f2fc707fc743d7ce6eb8f543bd449a35a1a649 +Subproject commit 37a6f97a4ea83d37a214b8dcde5d3630fe3a3316 diff --git a/components/mpas-seaice/src/shared/mpas_seaice_icepack.F b/components/mpas-seaice/src/shared/mpas_seaice_icepack.F index 2c26fd08f400..79f5452c7309 100644 --- a/components/mpas-seaice/src/shared/mpas_seaice_icepack.F +++ b/components/mpas-seaice/src/shared/mpas_seaice_icepack.F @@ -9790,224 +9790,6 @@ subroutine init_icepack_package_tracer_sizes(domain, tracerObject) end subroutine init_icepack_package_tracer_sizes -!||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||| -! -! init_column_package_tracer_indices -! -!> \brief -!> \author Adrian K. Turner, LANL -!> \date 5th Feburary 2015 -!> \details -!> -! -!----------------------------------------------------------------------- - - subroutine init_column_package_tracer_indices(tracerObject) - - !use ice_colpkg_tracers, only: & - ! nt_Tsfc, & ! ice/snow temperature - ! nt_qice, & ! volume-weighted ice enthalpy (in layers) - ! nt_qsno, & ! volume-weighted snow enthalpy (in layers) - ! nt_sice, & ! volume-weighted ice bulk salinity (CICE grid layers) - ! nt_fbri, & ! volume fraction of ice with dynamic salt (hinS/vicen*aicen) - ! nt_iage, & ! volume-weighted ice age - ! nt_FY, & ! area-weighted first-year ice area - ! nt_alvl, & ! level ice area fraction - ! nt_vlvl, & ! level ice volume fraction - ! nt_apnd, & ! melt pond area fraction - ! nt_hpnd, & ! melt pond depth - ! nt_ipnd, & ! melt pond refrozen lid thickness - ! nt_aero, & ! starting index for aerosols in ice - ! nt_smice, & ! snow ice mass - ! nt_smliq, & ! snow liquid mass - ! nt_rsnw, & ! snow grain radius - ! nt_rhos, & ! snow density tracer - ! nt_fbri, & ! volume fraction of ice with dynamic salt (hinS/vicen*aicen) - ! nt_bgc_Nit, & ! nutrients - ! nt_bgc_Am, & ! - ! nt_bgc_Sil, & ! - ! nt_bgc_DMSPp, & ! trace gases (skeletal layer) - ! nt_bgc_DMSPd, & ! - ! nt_bgc_DMS, & ! - ! nt_bgc_PON, & ! zooplankton and detritus - ! nt_bgc_hum, & ! humic material - ! ! bio layer indicess - ! nlt_bgc_Nit, & ! nutrients - ! nlt_bgc_Am, & ! - ! nlt_bgc_Sil, & ! - ! nlt_bgc_DMSPp, & ! trace gases (skeletal layer) - ! nlt_bgc_DMSPd, & ! - ! nlt_bgc_DMS, & ! - ! nlt_bgc_PON, & ! zooplankton and detritus - ! nlt_bgc_hum, & ! humic material - ! nlt_chl_sw, & ! points to total chla in trcrn_sw - ! nt_zbgc_frac, & ! fraction of tracer in the mobile phase - ! nt_bgc_S, & ! Bulk salinity in fraction ice with dynamic salinity (Bio grid) - ! nt_bgc_N, & ! diatoms, phaeocystis, pico/small - ! nt_bgc_C, & ! diatoms, phaeocystis, pico/small - ! nt_bgc_chl, & ! diatoms, phaeocystis, pico/small - ! nlt_bgc_N, & ! diatoms, phaeocystis, pico/small - ! nlt_bgc_C, & ! diatoms, phaeocystis, pico/small - ! nlt_bgc_chl, & ! diatoms, phaeocystis, pico/small - ! nt_bgc_DOC, & ! dissolved organic carbon - ! nlt_bgc_DOC, & ! dissolved organic carbon - ! nt_bgc_DON, & ! dissolved organic nitrogen - ! nlt_bgc_DON, & ! dissolved organic nitrogen - ! nt_bgc_DIC, & ! dissolved inorganic carbon - ! nlt_bgc_DIC, & ! dissolved inorganic carbon - ! nt_bgc_Fed, & ! dissolved iron - ! nt_bgc_Fep, & ! particulate iron - ! nlt_bgc_Fed, & ! dissolved iron - ! nlt_bgc_Fep, & ! particulate iron - ! nt_zaero, & ! black carbon and other aerosols - ! nlt_zaero, & ! black carbon and other aerosols - ! nlt_zaero_sw ! black carbon and other aerosols - - use ice_colpkg, only: & - colpkg_init_tracer_indices - - type(ciceTracerObjectType), intent(in) :: & - tracerObject - - call colpkg_init_tracer_indices(& - tracerObject % index_surfaceTemperature, & - tracerObject % index_iceEnthalpy, & - tracerObject % index_snowEnthalpy, & - tracerObject % index_iceSalinity, & - tracerObject % index_brineFraction, & - tracerObject % index_iceAge, & - tracerObject % index_firstYearIceArea, & - tracerObject % index_levelIceArea, & - tracerObject % index_levelIceVolume, & - tracerObject % index_pondArea, & - tracerObject % index_pondDepth, & - tracerObject % index_pondLidThickness, & - tracerObject % index_aerosols, & - tracerObject % index_snowIceMass, & - tracerObject % index_snowLiquidMass, & - tracerObject % index_snowGrainRadius, & - tracerObject % index_snowDensity, & - tracerObject % index_verticalAerosolsConc, & - tracerObject % index_algaeConc, & - tracerObject % index_algalCarbon, & - tracerObject % index_algalChlorophyll, & - tracerObject % index_DOCConc, & - tracerObject % index_DONConc, & - tracerObject % index_DICConc, & - tracerObject % index_dissolvedIronConc, & - tracerObject % index_particulateIronConc, & - tracerObject % index_nitrateConc, & - tracerObject % index_ammoniumConc, & - tracerObject % index_silicateConc, & - tracerObject % index_DMSPpConc, & - tracerObject % index_DMSPdConc, & - tracerObject % index_DMSConc, & - tracerObject % index_humicsConc, & - tracerObject % index_nonreactiveConc, & - tracerObject % index_verticalAerosolsConcLayer, & - tracerObject % index_algaeConcLayer, & - tracerObject % index_algalCarbonLayer, & - tracerObject % index_algalChlorophyllLayer, & - tracerObject % index_DOCConcLayer, & - tracerObject % index_DONConcLayer, & - tracerObject % index_DICConcLayer, & - tracerObject % index_dissolvedIronConcLayer, & - tracerObject % index_particulateIronConcLayer, & - tracerObject % index_nitrateConcLayer, & - tracerObject % index_ammoniumConcLayer, & - tracerObject % index_silicateConcLayer, & - tracerObject % index_DMSPpConcLayer, & - tracerObject % index_DMSPdConcLayer, & - tracerObject % index_DMSConcLayer, & - tracerObject % index_humicsConcLayer, & - tracerObject % index_nonreactiveConcLayer, & - tracerObject % index_mobileFraction, & - tracerObject % index_verticalSalinity, & - tracerObject % index_chlorophyllShortwave, & - tracerObject % index_verticalAerosolsConcShortwave, & - tracerObject % nAlgaeIndex, & - tracerObject % nAlgalCarbonIndex, & - tracerObject % nAlgalChlorophyllIndex, & - tracerObject % nDOCIndex, & - tracerObject % nDONIndex, & - tracerObject % nDICIndex, & - tracerObject % nDissolvedIronIndex, & - tracerObject % nParticulateIronIndex, & - tracerObject % nzAerosolsIndex, & - tracerObject % index_LayerIndexToDataArray, & - tracerObject % index_LayerIndexToBioIndex, & - tracerObject % nBioTracers) - - !nt_Tsfc = tracerObject % index_surfaceTemperature - !nt_qice = tracerObject % index_iceEnthalpy - !nt_qsno = tracerObject % index_snowEnthalpy - !nt_sice = tracerObject % index_iceSalinity - !nt_iage = tracerObject % index_iceAge - !nt_FY = tracerObject % index_firstYearIceArea - !nt_alvl = tracerObject % index_levelIceArea - !nt_vlvl = tracerObject % index_levelIceVolume - !nt_apnd = tracerObject % index_pondArea - !nt_hpnd = tracerObject % index_pondDepth - !nt_ipnd = tracerObject % index_pondLidThickness - !nt_aero = tracerObject % index_aerosols - !nt_smice = tracerObject % index_snowIceMass - !nt_rsnw = tracerObject % index_snowGrainRadius - !nt_rhos = tracerObject % index_snowDensity - !nt_smliq = tracerObject % index_snowLiquidMass - !nt_fbri = tracerObject % index_brineFraction - !nt_zaeros = tracerObject % index_verticalAerosolsConc - !nt_bgc_N = tracerObject % index_algaeConc - !nt_bgc_C = tracerObject % index_algalCarbon - !nt_bgc_chl = tracerObject % index_algalChlorophyll - !nt_bgc_DOC = tracerObject % index_DOCConc - !nt_bgc_DON = tracerObject % index_DONConc - !nt_bgc_DIC = tracerObject % index_DICConc - !nt_bgc_Fed = tracerObject % index_dissolvedIronConc - !nt_bgc_Fep = tracerObject % index_particulateIronConc - !nt_bgc_Nit = tracerObject % index_nitrateConc - !nt_bgc_Am = tracerObject % index_ammoniumConc - !nt_bgc_Sil = tracerObject % index_silicateConc - !nt_bgc_DMSPp = tracerObject % index_DMSPpConc - !nt_bgc_DMSPd = tracerObject % index_DMSPdConc - !nt_bgc_DMS = tracerObject % index_DMSConc - !nt_bgc_hum = tracerObject % index_humicsConc - !nt_bgc_PON = tracerObject % index_nonreactiveConc - !nlt_zaero = tracerObject % index_verticalAerosolsConcLayer - !nlt_bgc_N = tracerObject % index_algaeConcLayer - !nlt_bgc_C = tracerObject % index_algalCarbonLayer - !nlt_bgc_chl = tracerObject % index_algalChlorophyllLayer - !nlt_bgc_DOC = tracerObject % index_DOCConcLayer - !nlt_bgc_DON = tracerObject % index_DONConcLayer - !nlt_bgc_DIC = tracerObject % index_DICConcLayer - !nlt_bgc_Fed = tracerObject % index_dissolvedIronConcLayer - !nlt_bgc_Fep = tracerObject % index_particulateIronConcLayer - !nlt_bgc_Nit = tracerObject % index_nitrateConcLayer - !nlt_bgc_Am = tracerObject % index_ammoniumConcLayer - !nlt_bgc_Sil = tracerObject % index_silicateConcLayer - !nlt_bgc_DMSPp = tracerObject % index_DMSPpConcLayer - !nlt_bgc_DMSPd = tracerObject % index_DMSPdConcLayer - !nlt_bgc_DMS = tracerObject % index_DMSConcLayer - !nlt_bgc_hum = tracerObject % index_humicsConcLayer - !nlt_bgc_PON = tracerObject % index_nonreactiveConcLayer - !nt_zbgc_frac = tracerObject % index_mobileFraction - !nt_zbgc_S = tracerObject % index_verticalSalinity - !nlt_chl_sw = tracerObject % index_chlorophyllShortwave - !nlt_zaero_sw = tracerObject % index_verticalAerosolsConcShortwave - !n_algae = tracerObject % nAlgaeIndex - !n_algae = tracerObject % nAlgalCarbonIndex - !n_algae = tracerObject % nAlgalChlorophyllIndex - !n_doc = tracerObject % nDOCIndex - !n_don = tracerObject % nDONIndex - !n_dic = tracerObject % nDICIndex - !n_fed = tracerObject % nDissolvedIronIndex - !n_fep = tracerObject % nParticulateIronIndex - !n_zaero = tracerObject % nzAerosolsIndex - !bio_index_o = tracerObject % index_LayerIndexToDataArray - !bio_index = tracerObject % index_LayerIndexToBioIndex - !nbtrcr = tracerObject % nBioTracers - - end subroutine init_column_package_tracer_indices - !||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||| ! ! init_icepack_package_tracer_indices From 961ca5907851d724e95ddff580e2c8a485494a54 Mon Sep 17 00:00:00 2001 From: Nicole Jeffery Date: Thu, 16 Nov 2023 15:51:36 -0600 Subject: [PATCH 006/451] Updates mpas icepack bgc interface for optional arguments Most of the updates are for use in init_zbgc which now initializes many of the configs, indices and size declarations for bgc Contains updates to column package to make puny and accuracy consistent with carbon conservation check BFB with bgc and aerosols off --- components/mpas-seaice/src/build_options.mk | 2 +- .../mpas-seaice/src/column/ice_algae.F90 | 12 +- .../src/shared/mpas_seaice_icepack.F | 180 +++++++----------- .../src/shared/mpas_seaice_initialize.F | 4 - 4 files changed, 78 insertions(+), 120 deletions(-) diff --git a/components/mpas-seaice/src/build_options.mk b/components/mpas-seaice/src/build_options.mk index 5f2bdcfe2771..0ef6fc91e5d7 100644 --- a/components/mpas-seaice/src/build_options.mk +++ b/components/mpas-seaice/src/build_options.mk @@ -3,7 +3,7 @@ ifeq "$(ROOT_DIR)" "" endif EXE_NAME=seaice_model NAMELIST_SUFFIX=seaice -FCINCLUDES += -I$(ROOT_DIR)/column -I$(ROOT_DIR)/shared -I$(ROOT_DIR)/analysis_members -I$(ROOT_DIR)/model_forward +FCINCLUDES += -I$(ROOT_DIR)/icepack/columnphysics -I$(ROOT_DIR)/column -I$(ROOT_DIR)/shared -I$(ROOT_DIR)/analysis_members -I$(ROOT_DIR)/model_forward override CPPFLAGS += -DCORE_SEAICE -DUSE_SNICARHC ifneq "$(ESM)" "" override CPPFLAGS += -Dcoupled -DCCSMCOUPLED diff --git a/components/mpas-seaice/src/column/ice_algae.F90 b/components/mpas-seaice/src/column/ice_algae.F90 index ec7afff60733..78dce86e2d31 100644 --- a/components/mpas-seaice/src/column/ice_algae.F90 +++ b/components/mpas-seaice/src/column/ice_algae.F90 @@ -304,7 +304,7 @@ subroutine zbio (dt, nblyr, & carbonError = carbonInitial-carbonFlux*dt-carbonFinal - if (abs(carbonError) > accuracy * maxval ((/carbonInitial, carbonFinal/))) then + if (abs(carbonError) > max(puny,accuracy * maxval ((/carbonInitial, carbonFinal/)))) then write(warning,*) 'carbonError:', carbonError call add_warning(warning) write(warning,*) 'carbonInitial:', carbonInitial @@ -315,6 +315,8 @@ subroutine zbio (dt, nblyr, & call add_warning(warning) write(warning,*) 'accuracy * maxval ((/carbonInitial, carbonFinal/:)', accuracy * maxval ((/carbonInitial, carbonFinal/)) call add_warning(warning) + write(warning,*) 'puny', puny + call add_warning(warning) if (aicen > c0) then hsnow_f = vsnon/aicen write(warning,*) 'after z_biogeochemistry' @@ -1016,7 +1018,7 @@ subroutine z_biogeochemistry (n_cat, dt, & ! local parameters real (kind=dbl_kind), parameter :: & - accuracy = 1.0e-14_dbl_kind, & + accuracy = 1.0e-13_dbl_kind, & ! 1.0e-14_dbl_kind, & r_c = 3.0e3_dbl_kind , & ! ice crystal radius (um) r_bac= 4.7_dbl_kind , & ! diatom large radius (um) r_alg= 10.0_dbl_kind , & ! diatom small radius (um) @@ -1062,7 +1064,7 @@ subroutine z_biogeochemistry (n_cat, dt, & iphin_N(k) = iphin(k) bphin_N(1) = bphi_min - if (abs(trcrn(bio_index(m) + k-1)) < puny) then + if (abs(trcrn(bio_index(m) + k-1)) < accuracy) then flux_bio(m) = flux_bio(m) + trcrn(bio_index(m) + k-1)* hbri_old * dz(k)/dt trcrn(bio_index(m) + k-1) = c0 in_init_cons(k,m) = c0 @@ -1410,7 +1412,7 @@ subroutine z_biogeochemistry (n_cat, dt, & do m = 1,nbtrcr do k = 1,nblyr+1 ! back to bulk quantity bio_tmp = (biomat_brine(k,m) + react(k,m))*iphin_N(k) - if (tr_bgc_C .and. m .eq. nlt_bgc_DIC(1) .and. bio_tmp < -puny) then ! satisfy DIC demands from ocean + if (tr_bgc_C .and. m .eq. nlt_bgc_DIC(1) .and. bio_tmp .le. -accuracy) then ! satisfy DIC demands from ocean write(warning, *) 'DIC demand from ocean' call add_warning(warning) write(warning, *) 'm, nlt_bgc_DIC(1), bio_tmp, react(k,m):' @@ -1453,7 +1455,7 @@ subroutine z_biogeochemistry (n_cat, dt, & call add_warning(warning) l_stop = .true. stop_label = 'C in algal_dyn not conserved' - elseif (abs(bio_tmp) < puny) then + elseif (abs(bio_tmp) < accuracy) then flux_bio(m) = flux_bio(m) + bio_tmp*dz(k)*hbri/dt bio_tmp = c0 elseif (bio_tmp > 1.0e8_dbl_kind) then diff --git a/components/mpas-seaice/src/shared/mpas_seaice_icepack.F b/components/mpas-seaice/src/shared/mpas_seaice_icepack.F index 79f5452c7309..fa228e9daf37 100644 --- a/components/mpas-seaice/src/shared/mpas_seaice_icepack.F +++ b/components/mpas-seaice/src/shared/mpas_seaice_icepack.F @@ -3590,11 +3590,6 @@ subroutine column_biogeochemistry(domain) nBioLayers, & nBioLayersP1, & nAlgae, & - nDOC, & - nDIC, & - nDON, & - nParticulateIron, & - nDissolvedIron, & maxBCType, & maxDustType @@ -3603,7 +3598,6 @@ subroutine column_biogeochemistry(domain) real(kind=RKIND), dimension(:), pointer :: & netNitrateUptake, & netAmmoniumUptake, & - totalVerticalSalinity, & netSpecificAlgalGrowthRate, & primaryProduction, & netBrineHeight, & @@ -3759,11 +3753,6 @@ subroutine column_biogeochemistry(domain) call MPAS_pool_get_dimension(mesh, "nBioLayers", nBioLayers) call MPAS_pool_get_dimension(mesh, "nBioLayersP1", nBioLayersP1) call MPAS_pool_get_dimension(mesh, "nAlgae", nAlgae) - call MPAS_pool_get_dimension(mesh, "nDOC", nDOC) - call MPAS_pool_get_dimension(mesh, "nDIC", nDIC) - call MPAS_pool_get_dimension(mesh, "nDON", nDON) - call MPAS_pool_get_dimension(mesh, "nParticulateIron", nParticulateIron) - call MPAS_pool_get_dimension(mesh, "nDissolvedIron", nDissolvedIron) call MPAS_pool_get_dimension(mesh, "maxBCType", maxBCType) call MPAS_pool_get_dimension(mesh, "maxDustType", maxDustType) @@ -3779,7 +3768,6 @@ subroutine column_biogeochemistry(domain) call MPAS_pool_get_array(biogeochemistry, "newlyFormedIce", newlyFormedIce) call MPAS_pool_get_array(biogeochemistry, "netNitrateUptake", netNitrateUptake) call MPAS_pool_get_array(biogeochemistry, "netAmmoniumUptake", netAmmoniumUptake) - call MPAS_pool_get_array(biogeochemistry, "totalVerticalSalinity", totalVerticalSalinity) call MPAS_pool_get_array(biogeochemistry, "totalChlorophyll", totalChlorophyll) call MPAS_pool_get_array(biogeochemistry, "netSpecificAlgalGrowthRate", netSpecificAlgalGrowthRate) call MPAS_pool_get_array(biogeochemistry, "primaryProduction", primaryProduction) @@ -3940,14 +3928,11 @@ subroutine column_biogeochemistry(domain) call icepack_warnings_clear() call icepack_biogeochemistry(& dt=config_dt, & - ntrcr=ciceTracerObject % nTracers, & - nbtrcr=ciceTracerObject % nBioTracers, & upNO=netNitrateUptake(iCell), & upNH=netAmmoniumUptake(iCell), & iDi=bioDiffusivity(:,:,iCell), & iki=bioPermeability(:,:,iCell), & zfswin=bioShortwaveFlux(:,:,iCell), & - zsal_tot=totalVerticalSalinity(iCell), & darcy_V=darcyVelocityBio(:,iCell), & grow_net=netSpecificAlgalGrowthRate(iCell), & PP_net=primaryProduction(iCell), & @@ -3973,14 +3958,7 @@ subroutine column_biogeochemistry(domain) nblyr=nBioLayers, & nilyr=nIceLayers, & nslyr=nSnowLayers, & - n_algae=nAlgae, & - n_zaero=nzAerosols, & ncat=nCategories, & - n_doc=nDOC, & - n_dic=nDIC, & - n_don=nDON, & - n_fed=nDissolvedIron, & - n_fep=nParticulateIron, & meltbn=basalIceMeltCategory(:,iCell), & melttn=surfaceIceMeltCategory(:,iCell), & congeln=congelationCategory(:,iCell), & @@ -3990,7 +3968,6 @@ subroutine column_biogeochemistry(domain) Tf=seaFreezingTemperature(iCell), & fsnow=snowfallRate(iCell), & meltsn=snowMeltCategory(:,iCell), & - !initialSalinityProfile(:,iCell), & !!!! hin_old=iceThicknessCategoryInitial(:,iCell), & flux_bio=oceanBioFluxes(:,iCell), & flux_bio_atm=atmosBioFluxes(:,iCell), & @@ -4002,7 +3979,6 @@ subroutine column_biogeochemistry(domain) aice0=openWaterArea(iCell), & trcrn=tracerArrayCategory, & vsnon_init=snowVolumeCategoryInitial(:,iCell), & - skl_bgc=config_use_skeletal_biochemistry, & flux_bion=oceanBioFluxesCategory(:,:,iCell), & bioPorosityIceCell=bgridPorosityIceCell(:,iCell), & bioSalinityIceCell=bgridSalinityIceCell(:,iCell), & @@ -5569,22 +5545,12 @@ subroutine seaice_icepack_init_ocean_conc(& oceanNitrateConc, & oceanSilicateConc,& oceanZAerosolConc, & - maxDICType, & - maxDONType, & - maxIronType, & - maxAerosolType, & carbonToNitrogenRatioAlgae, & carbonToNitrogenRatioDON) use icepack_intfc, only: & icepack_init_ocean_bio - integer, intent(in) :: & - maxDICType, & - maxDONType, & - maxIronType, & - maxAerosolType - real(kind=RKIND), intent(out):: & oceanAmmoniumConc, & ! ammonium oceanDMSPConc, & ! DMSPp @@ -5620,10 +5586,6 @@ subroutine seaice_icepack_init_ocean_conc(& nit=oceanNitrateConc, & sil=oceanSilicateConc,& zaeros=oceanZAerosolConc, & - max_dic=maxDICType, & - max_don=maxDONType, & - max_fe=maxIronType, & - max_aero=maxAerosolType, & CToN=carbonToNitrogenRatioAlgae, & CToN_DON=carbonToNitrogenRatioDON) @@ -14787,86 +14749,86 @@ subroutine init_column_tracer_object_for_biogeochemistry(domain, tracerObject) nblyr=nBioLayers, & nilyr=nIceLayers, & nslyr=nSnowLayers, & - n_algae=nAlgae, & - n_zaero=nzAerosols, & - n_doc=nDOC, & - n_dic=nDIC, & - n_don=nDON, & - n_fed=nDissolvedIron, & - n_fep=nParticulateIron, & + n_algae_in=nAlgae, & + n_zaero_in=nzAerosols, & + n_doc_in=nDOC, & + n_dic_in=nDIC, & + n_don_in=nDON, & + n_fed_in=nDissolvedIron, & + n_fep_in=nParticulateIron, & trcr_base=tracerObject % firstAncestorMask, & trcr_depend=tracerObject % parentIndex, & n_trcr_strata=tracerObject % ancestorNumber, & nt_strata=tracerObject % ancestorIndices, & - nbtrcr_sw=tracerObject % nBioTracersShortwave, & - tr_brine=config_use_brine, & - nt_fbri=tracerObject % index_brineFraction,& - ntrcr=tracerObject % nTracers, & - nbtrcr=tracerObject % nBioTracers, & - nt_bgc_Nit=tracerObject % index_nitrateConc, & - nt_bgc_Am=tracerObject % index_ammoniumConc, & - nt_bgc_Sil=tracerObject % index_silicateConc, & - nt_bgc_DMS=tracerObject % index_DMSConc, & - nt_bgc_PON=tracerObject % index_nonreactiveConc, & - nt_bgc_S=tracerObject % index_verticalSalinity, & - nt_bgc_N=tracerObject % index_algaeConc, & - nt_bgc_C=tracerObject % index_algalCarbon, & - nt_bgc_chl=tracerObject % index_algalChlorophyll, & - nt_bgc_DOC=tracerObject % index_DOCConc, & - nt_bgc_DON=tracerObject % index_DONConc, & - nt_bgc_DIC=tracerObject % index_DICConc, & - nt_zaero=tracerObject % index_verticalAerosolsConc, & - nt_bgc_DMSPp=tracerObject % index_DMSPpConc, & - nt_bgc_DMSPd=tracerObject % index_DMSPdConc, & - nt_bgc_Fed=tracerObject % index_dissolvedIronConc, & - nt_bgc_Fep=tracerObject % index_particulateIronConc, & - nt_zbgc_frac=tracerObject % index_mobileFraction, & - tr_bgc_Nit=config_use_nitrate, & - tr_bgc_Am=config_use_ammonium, & - tr_bgc_Sil=config_use_silicate, & - tr_bgc_DMS=config_use_DMS, & - tr_bgc_PON=config_use_nonreactive, & - tr_bgc_N=use_nitrogen, & - tr_bgc_C=config_use_carbon, & - tr_bgc_chl=config_use_chlorophyll, & - tr_bgc_DON=config_use_DON, & - tr_bgc_Fe=config_use_iron,& - tr_zaero=config_use_zaerosols, & - nlt_zaero_sw=tracerObject % index_verticalAerosolsConcShortwave, & - nlt_chl_sw=tracerObject % index_chlorophyllShortwave, & - nlt_bgc_N=tracerObject % index_algaeConcLayer, & - nlt_bgc_Nit=tracerObject % index_nitrateConcLayer, & - nlt_bgc_Am=tracerObject % index_ammoniumConcLayer, & - nlt_bgc_Sil=tracerObject % index_silicateConcLayer, & - nlt_bgc_DMS=tracerObject % index_DMSConcLayer, & - nlt_bgc_DMSPp=tracerObject % index_DMSPpConcLayer, & - nlt_bgc_DMSPd=tracerObject % index_DMSPdConcLayer, & - nlt_bgc_C=tracerObject % index_algalCarbonLayer, & - nlt_bgc_chl=tracerObject % index_algalChlorophyllLayer, & - nlt_bgc_DIC=tracerObject % index_DICConcLayer, & - nlt_bgc_DOC=tracerObject % index_DOCConcLayer, & - nlt_bgc_PON=tracerObject % index_nonreactiveConcLayer, & - nlt_bgc_DON=tracerObject % index_DONConcLayer, & - nlt_bgc_Fed=tracerObject % index_dissolvedIronConcLayer, & - nlt_bgc_Fep=tracerObject % index_particulateIronConcLayer, & - nlt_zaero=tracerObject % index_verticalAerosolsConcLayer, & - nt_bgc_hum=tracerObject % index_humicsConc, & - nlt_bgc_hum=tracerObject % index_humicsConcLayer, & - tr_bgc_hum=config_use_humics, & - skl_bgc=config_use_skeletal_biochemistry, & - z_tracers=config_use_vertical_tracers, & - dEdd_algae=config_use_shortwave_bioabsorption, & - solve_zbgc=config_use_vertical_biochemistry, & - frazil_scav_in=config_fraction_biotracer_in_frazil, & - initbio_frac_in=config_new_ice_fraction_biotracer, & + nbtrcr_sw_out=tracerObject % nBioTracersShortwave, & + tr_brine_in=config_use_brine, & + nt_fbri_out=tracerObject % index_brineFraction,& + ntrcr_out=tracerObject % nTracers, & + nbtrcr_out=tracerObject % nBioTracers, & + ntrcr_o_out=tracerObject % nTracersNotBio, & + nt_bgc_Nit_out=tracerObject % index_nitrateConc, & + nt_bgc_Am_out=tracerObject % index_ammoniumConc, & + nt_bgc_Sil_out=tracerObject % index_silicateConc, & + nt_bgc_DMS_out=tracerObject % index_DMSConc, & + nt_bgc_PON_out=tracerObject % index_nonreactiveConc, & + nt_bgc_N_out=tracerObject % index_algaeConc, & + nt_bgc_C_out=tracerObject % index_algalCarbon, & + nt_bgc_chl_out=tracerObject % index_algalChlorophyll, & + nt_bgc_DOC_out=tracerObject % index_DOCConc, & + nt_bgc_DON_out=tracerObject % index_DONConc, & + nt_bgc_DIC_out=tracerObject % index_DICConc, & + nt_zaero_out=tracerObject % index_verticalAerosolsConc, & + nt_bgc_DMSPp_out=tracerObject % index_DMSPpConc, & + nt_bgc_DMSPd_out=tracerObject % index_DMSPdConc, & + nt_bgc_Fed_out=tracerObject % index_dissolvedIronConc, & + nt_bgc_Fep_out=tracerObject % index_particulateIronConc, & + nt_zbgc_frac_out=tracerObject % index_mobileFraction, & + tr_bgc_Nit_in=config_use_nitrate, & + tr_bgc_Am_in=config_use_ammonium, & + tr_bgc_Sil_in=config_use_silicate, & + tr_bgc_DMS_in=config_use_DMS, & + tr_bgc_PON_in=config_use_nonreactive, & + tr_bgc_N_in=use_nitrogen, & + tr_bgc_C_in=config_use_carbon, & + tr_bgc_chl_in=config_use_chlorophyll, & + tr_bgc_DON_in=config_use_DON, & + tr_bgc_Fe_in=config_use_iron,& + tr_zaero_in=config_use_zaerosols, & + nlt_zaero_sw_out=tracerObject % index_verticalAerosolsConcShortwave, & + nlt_chl_sw_out=tracerObject % index_chlorophyllShortwave, & + nlt_bgc_N_out=tracerObject % index_algaeConcLayer, & + nlt_bgc_Nit_out=tracerObject % index_nitrateConcLayer, & + nlt_bgc_Am_out=tracerObject % index_ammoniumConcLayer, & + nlt_bgc_Sil_out=tracerObject % index_silicateConcLayer, & + nlt_bgc_DMS_out=tracerObject % index_DMSConcLayer, & + nlt_bgc_DMSPp_out=tracerObject % index_DMSPpConcLayer, & + nlt_bgc_DMSPd_out=tracerObject % index_DMSPdConcLayer, & + nlt_bgc_C_out=tracerObject % index_algalCarbonLayer, & + nlt_bgc_chl_out=tracerObject % index_algalChlorophyllLayer, & + nlt_bgc_DIC_out=tracerObject % index_DICConcLayer, & + nlt_bgc_DOC_out=tracerObject % index_DOCConcLayer, & + nlt_bgc_PON_out=tracerObject % index_nonreactiveConcLayer, & + nlt_bgc_DON_out=tracerObject % index_DONConcLayer, & + nlt_bgc_Fed_out=tracerObject % index_dissolvedIronConcLayer, & + nlt_bgc_Fep_out=tracerObject % index_particulateIronConcLayer, & + nlt_zaero_out=tracerObject % index_verticalAerosolsConcLayer, & + nt_bgc_hum_out=tracerObject % index_humicsConc, & + nlt_bgc_hum_out=tracerObject % index_humicsConcLayer, & + tr_bgc_hum_in=config_use_humics, & + skl_bgc_in=config_use_skeletal_biochemistry, & + z_tracers_in=config_use_vertical_tracers, & + dEdd_algae_in=config_use_shortwave_bioabsorption, & + solve_zbgc_in=config_use_vertical_biochemistry, & bio_index_o_out=tracerObject % index_LayerIndexToDataArray, & bio_index_out=tracerObject % index_LayerIndexToBioIndex, & - ntrcr_o=tracerObject % nTracersNotBio, & + frazil_scav_in=config_fraction_biotracer_in_frazil, & + initbio_frac_in=config_new_ice_fraction_biotracer, & max_algae_in=maxAlgaeType, & max_doc_in=maxDOCType, & max_dic_in=maxDICType, & max_don_in=maxDONType, & max_fe_in=maxIronType, & + max_aero_in=maxAerosolType, & ratio_Si2N_diatoms_in=config_ratio_Si_to_N_diatoms, & ratio_Si2N_sp_in=config_ratio_Si_to_N_small_plankton, & ratio_Si2N_phaeo_in=config_ratio_Si_to_N_phaeocystis, & @@ -15143,6 +15105,7 @@ subroutine init_column_biogeochemistry_profiles(domain, tracerObject) call MPAS_pool_get_dimension(block % dimensions, "nBioLayersP1", nBioLayersP1) call MPAS_pool_get_dimension(block % dimensions, "nBioLayersP2", nBioLayersP2) call MPAS_pool_get_dimension(block % dimensions, "nShortwaveBio", nShortwaveBio) + call icepack_init_hbrine(& bgrid=biologyGrid, & igrid=interfaceBiologyGrid, & @@ -15188,11 +15151,8 @@ subroutine init_column_biogeochemistry_profiles(domain, tracerObject) ncat=nCategories, & nblyr=nBioLayers, & nilyr=nIceLayers, & - ntrcr_o=tracerObject % nTracersNotBio, & cgrid=verticalGrid, & igrid=interfaceBiologyGrid, & - ntrcr=tracerObject % nTracers, & - nbtrcr=tracerObject % nBiotracers, & sicen=iceSalinity(:,:,iCell), & trcrn=tracerArrayCategory(tracerObject % nTracersNotBio+1:tracerObject % nTracers,:), & sss=seaSurfaceSalinity(iCell), & diff --git a/components/mpas-seaice/src/shared/mpas_seaice_initialize.F b/components/mpas-seaice/src/shared/mpas_seaice_initialize.F index e2ca0dbf2216..3ae1c14aec9f 100644 --- a/components/mpas-seaice/src/shared/mpas_seaice_initialize.F +++ b/components/mpas-seaice/src/shared/mpas_seaice_initialize.F @@ -2747,10 +2747,6 @@ subroutine initialize_coupler_fields(domain) oceanNitrateConc(iCell), & oceanSilicateConc(iCell),& oceanZAerosolConc(:,iCell), & - maxDICType, & - maxDONType, & - maxIronType, & - maxAerosolType, & carbonToNitrogenRatioAlgae, & carbonToNitrogenRatioDON) From 5f73ff08a62fd0b2decd2eaa72af98746b985f4e Mon Sep 17 00:00:00 2001 From: Nicole Jeffery Date: Mon, 11 Dec 2023 14:57:29 -0600 Subject: [PATCH 007/451] Added bgc parameter checks Removed zsalinity references BFB --- .../src/shared/mpas_seaice_icepack.F | 23 +++++++++++++++---- 1 file changed, 19 insertions(+), 4 deletions(-) diff --git a/components/mpas-seaice/src/shared/mpas_seaice_icepack.F b/components/mpas-seaice/src/shared/mpas_seaice_icepack.F index fa228e9daf37..0588cc790eef 100644 --- a/components/mpas-seaice/src/shared/mpas_seaice_icepack.F +++ b/components/mpas-seaice/src/shared/mpas_seaice_icepack.F @@ -14406,6 +14406,7 @@ end subroutine seaice_column_reinitialize_oceanic_fluxes subroutine init_column_tracer_object_for_biogeochemistry(domain, tracerObject) use icepack_intfc, only: icepack_init_zbgc + use icepack_intfc, only: icepack_query_parameters type(domain_type), intent(in) :: & domain @@ -14558,6 +14559,10 @@ subroutine init_column_tracer_object_for_biogeochemistry(domain, tracerObject) nTracers_temp, & iAerosols + real(kind=RKIND) :: & + rtmp1, & + rtmp2 + ! save tracer array size nTracers_temp = tracerObject % nTracers tracerObject % nTracers = tracerObject % nTracersNotBio @@ -14933,6 +14938,20 @@ subroutine init_column_tracer_object_for_biogeochemistry(domain, tracerObject) messageType=MPAS_LOG_CRIT, intArgs=(/nTracers_temp, tracerObject % nTracers/)) endif + call mpas_log_write(" ----- compare values after init_zbgc -----") + + rtmp1 = config_new_ice_fraction_biotracer + call icepack_query_parameters(initbio_frac_out=rtmp2) + if (rtmp1 /= rtmp2) call mpas_log_write('initbio_frac differs $r $r',realArgs=(/rtmp1,rtmp2/)) + + rtmp1 = config_rapid_mobile_to_stationary_time + call icepack_query_parameters(tau_min_out=rtmp2) + if (rtmp1 /= rtmp2) call mpas_log_write('tau_min differs $r $r',realArgs=(/rtmp1,rtmp2/)) + + rtmp1 = config_long_mobile_to_stationary_time + call icepack_query_parameters(tau_max_out=rtmp2) + if (rtmp1 /= rtmp2) call mpas_log_write('tau_max differs $r $r',realArgs=(/rtmp1,rtmp2/)) + end subroutine init_column_tracer_object_for_biogeochemistry !||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||| @@ -14970,10 +14989,8 @@ subroutine init_column_biogeochemistry_profiles(domain, tracerObject) logical, pointer :: & config_use_brine, & -! config_use_vertical_zsalinity, & !echmod deprecate config_use_vertical_tracers, & config_use_skeletal_biochemistry, & - config_do_restart_zsalinity, & config_do_restart_hbrine real(kind=RKIND), pointer :: & @@ -15041,9 +15058,7 @@ subroutine init_column_biogeochemistry_profiles(domain, tracerObject) abortMessage call MPAS_pool_get_config(domain % configs, "config_use_brine", config_use_brine) - call MPAS_pool_get_config(domain % configs, "config_do_restart_zsalinity", config_do_restart_zsalinity) call MPAS_pool_get_config(domain % configs, "config_do_restart_hbrine", config_do_restart_hbrine) -! call MPAS_pool_get_config(domain % configs, "config_use_vertical_zsalinity", config_use_vertical_zsalinity) !echmod deprecate call MPAS_pool_get_config(domain % configs, "config_use_skeletal_biochemistry", config_use_skeletal_biochemistry) call MPAS_pool_get_config(domain % configs, "config_use_vertical_tracers", config_use_vertical_tracers) call MPAS_pool_get_config(domain % configs, "config_dt", config_dt) From 35bed8a9e64b31497e5fbf1bca0733b4eec7c2ab Mon Sep 17 00:00:00 2001 From: hollyhan Date: Wed, 10 Jan 2024 18:29:59 -0700 Subject: [PATCH 008/451] Add restart option when the SLM is coupled to MALI --- .../mpas-albany-landice/src/Registry.xml | 4 + .../src/mode_forward/mpas_li_bedtopo.F | 193 +++++++++++------- 2 files changed, 123 insertions(+), 74 deletions(-) diff --git a/components/mpas-albany-landice/src/Registry.xml b/components/mpas-albany-landice/src/Registry.xml index 279d7fb3c0a0..c4cd6df05bb9 100644 --- a/components/mpas-albany-landice/src/Registry.xml +++ b/components/mpas-albany-landice/src/Registry.xml @@ -149,6 +149,10 @@ description="Time interval at which the sea-level model is called by MALI. The interval has to be an even multiple of the option 'config_adaptive_timestep_force_interval" possible_values="Any time interval of the format 'YYYY-MM-DD_HH:MM:SS'" /> + Date: Mon, 29 Jan 2024 21:21:10 -0700 Subject: [PATCH 009/451] Fix handling of err codes in thermal solver As written, some errors were not being handled properly, leading to runs being aborted without useful information written to an err log file. This commit writes all error related messages to the err log, sets the err code to 1, and returns control to the calling routine. --- .../src/mode_forward/mpas_li_thermal.F | 23 ++++++++++--------- 1 file changed, 12 insertions(+), 11 deletions(-) diff --git a/components/mpas-albany-landice/src/mode_forward/mpas_li_thermal.F b/components/mpas-albany-landice/src/mode_forward/mpas_li_thermal.F index 4ef8ae672b8c..5fa521705904 100644 --- a/components/mpas-albany-landice/src/mode_forward/mpas_li_thermal.F +++ b/components/mpas-albany-landice/src/mode_forward/mpas_li_thermal.F @@ -792,8 +792,9 @@ subroutine li_thermal_solver(domain, err) call mpas_pool_get_array(meshPool, 'deltat', deltat) if (deltat <= 0.0_RKIND) then + err = ior(err, 1) call mpas_log_write('li_thermal_solver was called with invalid deltat = $r', MPAS_LOG_ERR, realArgs=(/deltat/)) - call mpas_log_write("An error has occurred in li_thermal. Aborting...", MPAS_LOG_CRIT) + return endif @@ -1305,25 +1306,25 @@ subroutine li_thermal_solver(domain, err) mintemp = minval(temperature(:,iCell)) if (maxtemp > maxtempThreshold) then - call mpas_log_write('maxtemp > maxtempThreshold: indexToCellID=$i, maxtemp = $r', intArgs=(/indexToCellID(iCell)/), & + err = ior(err, 1) + call mpas_log_write('maxtemp > maxtempThreshold: indexToCellID=$i, maxtemp = $r', MPAS_LOG_ERR, intArgs=(/indexToCellID(iCell)/), & realArgs=(/maxtemp/)) - call mpas_log_write('thickness = $r', realArgs=(/thickness(iCell)/)) - call mpas_log_write('temperature:') + call mpas_log_write(' thickness = $r', MPAS_LOG_ERR, realArgs=(/thickness(iCell)/)) + call mpas_log_write(' temperature:', MPAS_LOG_ERR) do k = 1, nVertLevels - call mpas_log_write('$i $r', intArgs=(/k/), realArgs=(/temperature(k,iCell)/)) + call mpas_log_write(' $i $r', MPAS_LOG_ERR, intArgs=(/k/), realArgs=(/temperature(k,iCell)/)) enddo - call mpas_log_write("An error has occurred in li_thermal. Aborting...", MPAS_LOG_CRIT) endif if (mintemp < mintempThreshold) then - call mpas_log_write('mintemp < mintempThreshold: indexToCellID=$i, mintemp = $r', intArgs=(/indexToCellID(iCell)/), & + err = ior(err, 1) + call mpas_log_write('mintemp < mintempThreshold: indexToCellID=$i, mintemp = $r', MPAS_LOG_ERR, intArgs=(/indexToCellID(iCell)/), & realArgs=(/mintemp/)) - call mpas_log_write('thickness = $r', realArgs=(/thickness(iCell)/)) - call mpas_log_write('temperature:') + call mpas_log_write(' thickness = $r', MPAS_LOG_ERR, realArgs=(/thickness(iCell)/)) + call mpas_log_write(' temperature:', MPAS_LOG_ERR) do k = 1, nVertLevels - call mpas_log_write('$i $r', intArgs=(/k/), realArgs=(/temperature(k,iCell)/)) + call mpas_log_write(' $i $r', MPAS_LOG_ERR, intArgs=(/k/), realArgs=(/temperature(k,iCell)/)) enddo - call mpas_log_write("An error has occurred in li_thermal. Aborting...", MPAS_LOG_CRIT) endif enddo ! iCell From cfa244be77fd7965af908e2cc339d5c8fbba95aa Mon Sep 17 00:00:00 2001 From: Matthew Hoffman Date: Mon, 29 Jan 2024 21:42:56 -0700 Subject: [PATCH 010/451] Reduce maxTempThreshold to 0.1 deg above melting temp It was previously set to 100 degC, which seems unnecessarily permissive for ice --- .../mpas-albany-landice/src/mode_forward/mpas_li_thermal.F | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/components/mpas-albany-landice/src/mode_forward/mpas_li_thermal.F b/components/mpas-albany-landice/src/mode_forward/mpas_li_thermal.F index 5fa521705904..96d289f400d6 100644 --- a/components/mpas-albany-landice/src/mode_forward/mpas_li_thermal.F +++ b/components/mpas-albany-landice/src/mode_forward/mpas_li_thermal.F @@ -70,7 +70,7 @@ module li_thermal ! Note: kelvin_to_celsius = 273.15 (perhaps it should be called celsius_to_kelvin?) real (kind=RKIND), parameter :: & - maxtempThreshold = 100._RKIND + kelvin_to_celsius, & + maxtempThreshold = 0.1_RKIND + kelvin_to_celsius, & mintempThreshold = -100._RKIND + kelvin_to_celsius !*********************************************************************** From fd298b1420ee9e8a3015e484592d8e95aa9ac158 Mon Sep 17 00:00:00 2001 From: Matthew Hoffman Date: Wed, 31 Jan 2024 13:50:28 -0700 Subject: [PATCH 011/451] Update basal mass balance calculation and basal water accounting Depsite comments suggesting it was the case, the existing code did not limit basal freeze on by the available basal water. This commit corrects that. It also applies the contribution of basal melting to basal water for the temperature solver, which previously was being excluded. --- .../src/mode_forward/mpas_li_thermal.F | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) diff --git a/components/mpas-albany-landice/src/mode_forward/mpas_li_thermal.F b/components/mpas-albany-landice/src/mode_forward/mpas_li_thermal.F index 96d289f400d6..65c300963529 100644 --- a/components/mpas-albany-landice/src/mode_forward/mpas_li_thermal.F +++ b/components/mpas-albany-landice/src/mode_forward/mpas_li_thermal.F @@ -2841,15 +2841,21 @@ subroutine basal_melt_grounded_ice(& ! to the form as Eqn (66) in Aschwanden and others (2012) "An ! enthalpy formulation for glaciers and ice sheets". An extra ! term (1-w) would be more accurate. - basalWaterThickness(iCell) = basalWaterThickness(iCell) - deltat*groundedBasalMassBal(iCell) - ! TZ: allow basalWaterThickness freely accumulate here. Change it to something else for difference cases - if (basalWaterThickness(iCell) < 0.0_RKIND) then - basalWaterThickness(iCell) = 0.0_RKIND - endif else ! temperature solver groundedBasalMassBal(iCell) = -netBasalFlux / (latent_heat_ice * rhoi) ! m/s endif + ! Update basal water thickness based on melting or freezing (same for enthalpy or temperature) + if (groundedBasalMassBal(iCell) > 0.0) then + ! for freezing conditions (+SMB), limit positive BMB to the available basal water + groundedBasalMassBal(iCell) = min(groundedBasalMassBal(iCell), basalWaterThickness(iCell) / deltat) + endif + basalWaterThickness(iCell) = basalWaterThickness(iCell) - deltat*groundedBasalMassBal(iCell) + + ! negative water thickness should not occur, but if round off leads to it, set back to zero + if (basalWaterThickness(iCell) < 0.0_RKIND) then + basalWaterThickness(iCell) = 0.0_RKIND + endif endif ! ice is present and grounded From c9c13aa5d4abb80e398ba361fb362ececb82b478 Mon Sep 17 00:00:00 2001 From: Matthew Hoffman Date: Wed, 17 May 2023 10:38:16 -0600 Subject: [PATCH 012/451] Add missing channel melt source term to mass cons eqn After further inspection, I realized that the mass conservation equation used to evolve sheet thickness is missing a source term from the production of meltwater within the channel. This is the 2nd term on the RHS of Hewitt (2013) Eq. 7, and it is missing from Eq. 54 in the Hoffman et al. 2018 GMD paper. Melt production in the channel is generally a small contribution to the total water balance, which may explain why the model matched GlaDS well for the SHMIP experiments. It's possible this correction will help with channel blowup events, or it could make them worse - it's hard to think through how this affects those events without better characterizing what's causing them. In any case, this is a clear omission and should be used going forward. --- .../src/Registry_subglacial_hydro.xml | 2 ++ .../mode_forward/mpas_li_subglacial_hydro.F | 19 +++++++++++++++++-- 2 files changed, 19 insertions(+), 2 deletions(-) diff --git a/components/mpas-albany-landice/src/Registry_subglacial_hydro.xml b/components/mpas-albany-landice/src/Registry_subglacial_hydro.xml index 754e8385255c..c9087d164def 100644 --- a/components/mpas-albany-landice/src/Registry_subglacial_hydro.xml +++ b/components/mpas-albany-landice/src/Registry_subglacial_hydro.xml @@ -251,6 +251,8 @@ description="divergence due to channel flow in subglacial hydrology system" /> + diff --git a/components/mpas-albany-landice/src/mode_forward/mpas_li_subglacial_hydro.F b/components/mpas-albany-landice/src/mode_forward/mpas_li_subglacial_hydro.F index ad3642622e1f..054b756c1e09 100644 --- a/components/mpas-albany-landice/src/mode_forward/mpas_li_subglacial_hydro.F +++ b/components/mpas-albany-landice/src/mode_forward/mpas_li_subglacial_hydro.F @@ -259,6 +259,7 @@ subroutine li_SGH_solve(domain, err) real (kind=RKIND), dimension(:), pointer :: waterThicknessTendency real (kind=RKIND), dimension(:), pointer :: divergenceChannel real (kind=RKIND), dimension(:), pointer :: channelAreaChangeCell + real (kind=RKIND), dimension(:), pointer :: channelMeltInputCell real (kind=RKIND), dimension(:), pointer :: dvEdge real (kind=RKIND), dimension(:), pointer :: areaCell real (kind=RKIND), dimension(:), pointer :: waterVelocity @@ -534,6 +535,7 @@ subroutine li_SGH_solve(domain, err) call mpas_timer_start("halo updates") call mpas_dmpar_field_halo_exch(domain, 'divergenceChannel') call mpas_dmpar_field_halo_exch(domain, 'channelAreaChangeCell') + call mpas_dmpar_field_halo_exch(domain, 'channelMeltInputCell') call mpas_dmpar_field_halo_exch(domain, 'channelArea') call mpas_timer_stop("halo updates") endif @@ -570,12 +572,16 @@ subroutine li_SGH_solve(domain, err) call mpas_pool_get_array(hydroPool, 'divergence', divergence) call mpas_pool_get_array(hydroPool, 'divergenceChannel', divergenceChannel) call mpas_pool_get_array(hydroPool, 'channelAreaChangeCell', channelAreaChangeCell) + call mpas_pool_get_array(hydroPool, 'channelMeltInputCell', channelMeltInputCell) call mpas_pool_get_array(geometryPool, 'cellMask', cellMask) waterThicknessOld = waterThickness - waterThickness = waterThicknessOld + deltatSGH * ( (basalMeltInput + externalWaterInput) / rho_water - divergence & + waterThickness = waterThicknessOld + deltatSGH * ( & + (basalMeltInput + externalWaterInput) / rho_water & + + channelMeltInputCell & + - divergence & - divergenceChannel - channelAreaChangeCell & - - (Wtill - WtillOld) / deltatSGH) + - (Wtill - WtillOld) / deltatSGH ) waterThickness = waterThickness * li_mask_is_grounded_ice_int(cellMask) ! zero in non-grounded locations waterThickness = max(0.0_RKIND, waterThickness) divergence = divergence * li_mask_is_grounded_ice_int(cellMask) ! zero in non-grounded locations for more convenient viz @@ -1777,6 +1783,7 @@ subroutine update_channel(block, err) end where channelChangeRate = channelOpeningRate - channelClosingRate + !-------------------------------------------------------------------- end subroutine update_channel @@ -1816,9 +1823,11 @@ subroutine evolve_channel(block, err) type (mpas_pool_type), pointer :: meshPool real (kind=RKIND), dimension(:), pointer :: channelArea real (kind=RKIND), dimension(:), pointer :: channelDischarge + real (kind=RKIND), dimension(:), pointer :: channelMelt, channelPressureFreeze real (kind=RKIND), dimension(:), pointer :: channelChangeRate real (kind=RKIND), dimension(:), pointer :: divergenceChannel real (kind=RKIND), dimension(:), pointer :: channelAreaChangeCell + real (kind=RKIND), dimension(:), pointer :: channelMeltInputCell real (kind=RKIND), pointer :: deltatSGH integer, dimension(:), pointer :: nEdgesOnCell integer, dimension(:,:), pointer :: edgesOnCell @@ -1834,9 +1843,12 @@ subroutine evolve_channel(block, err) call mpas_pool_get_array(hydroPool, 'deltatSGH', deltatSGH) call mpas_pool_get_array(hydroPool, 'channelArea', channelArea) call mpas_pool_get_array(hydroPool, 'channelDischarge', channelDischarge) + call mpas_pool_get_array(hydroPool, 'channelMelt', channelMelt) + call mpas_pool_get_array(hydroPool, 'channelPressureFreeze', channelPressureFreeze) call mpas_pool_get_array(hydroPool, 'channelChangeRate', channelChangeRate) call mpas_pool_get_array(hydroPool, 'divergenceChannel', divergenceChannel) call mpas_pool_get_array(hydroPool, 'channelAreaChangeCell', channelAreaChangeCell) + call mpas_pool_get_array(hydroPool, 'channelMeltInputCell', channelMeltInputCell) call mpas_pool_get_dimension(meshPool, 'nCellsSolve', nCellsSolve) call mpas_pool_get_array(meshPool, 'nEdgesOnCell', nEdgesOnCell) call mpas_pool_get_array(meshPool, 'edgesOnCell', edgesOnCell) @@ -1848,6 +1860,7 @@ subroutine evolve_channel(block, err) ! Calculate flux divergence on cells and channel area change on cells divergenceChannel(:) = 0.0_RKIND ! zero div before accumulating channelAreaChangeCell(:) = 0.0_RKIND ! zero before accumulating + channelMeltInputCell(:) = 0.0_RKIND ! zero before accumulating ! loop over locally owned cells do iCell = 1, nCellsSolve ! TODO: could limit to grounded cells only @@ -1858,10 +1871,12 @@ subroutine evolve_channel(block, err) divergenceChannel(iCell) = divergenceChannel(iCell) - channelDischarge(iEdge) * edgeSignOnCell(iEdgeOnCell, iCell) channelAreaChangeCell(iCell) = channelChangeRate(iEdge) * dcEdge(iEdge) * 0.5_RKIND ! < only half of channel is in this cell + channelMeltInputCell(iCell) = 0.5_RKIND * (channelMelt(iEdge) - channelPressureFreeze(iEdge)) * dcEdge(iEdge) / rho_water end do ! edges end do ! cells divergenceChannel(1:nCellsSolve) = divergenceChannel(1:nCellsSolve) / areaCell(1:nCellsSolve) channelAreaChangeCell(1:nCellsSolve) = channelAreaChangeCell(1:nCellsSolve) / areaCell(1:nCellsSolve) + channelMeltInputCell(1:nCellsSolve) = channelMeltInputCell(1:nCellsSolve) / areaCell(1:nCellsSolve) ! Now update channel area channelArea = channelChangeRate * deltatSGH + channelArea From 9e29133edcf20018ce30414b354b812ee28b8098 Mon Sep 17 00:00:00 2001 From: Matthew Hoffman Date: Wed, 17 May 2023 11:30:03 -0600 Subject: [PATCH 013/451] Revert "Ignore the water thickness head in the channel model" This reverts commit ae981817616596be19c52fad5a9089161d9c8d63. It seems like we would want the channel model to see the elevation head produced by a lake's water thickness to ensure that channel flow is consistent with the presence of the lake. This commit reverts the commit that dropped the water thickness elevation head from the hydropotential gradients used by the channel. In the sheet model, the elevation head is removed from the advection equation, but it is handled by the diffusion equation, so it's still represented in the evolution. As the channel model currently exists, the elevation head is almost completely absent (other than its effect on the magnitude of gradMagPhiEdge). It seems like this could lead to channels draining *into* lakes even when the full hydropotential gradient of the lake indicates water flow should be draining the lake. --- .../src/mode_forward/mpas_li_subglacial_hydro.F | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/components/mpas-albany-landice/src/mode_forward/mpas_li_subglacial_hydro.F b/components/mpas-albany-landice/src/mode_forward/mpas_li_subglacial_hydro.F index 054b756c1e09..5d048074bea9 100644 --- a/components/mpas-albany-landice/src/mode_forward/mpas_li_subglacial_hydro.F +++ b/components/mpas-albany-landice/src/mode_forward/mpas_li_subglacial_hydro.F @@ -1652,7 +1652,7 @@ subroutine update_channel(block, err) real (kind=RKIND), dimension(:), pointer :: channelVelocity real (kind=RKIND), dimension(:), pointer :: gradMagPhiEdge real (kind=RKIND), dimension(:), pointer :: waterFlux - real (kind=RKIND), dimension(:), pointer :: hydropotentialBaseSlopeNormal + real (kind=RKIND), dimension(:), pointer :: hydropotentialSlopeNormal real (kind=RKIND), dimension(:), pointer :: waterPressureSlopeNormal real (kind=RKIND), dimension(:), pointer :: channelOpeningRate real (kind=RKIND), dimension(:), pointer :: channelClosingRate @@ -1698,7 +1698,7 @@ subroutine update_channel(block, err) call mpas_pool_get_array(hydroPool, 'channelDischarge', channelDischarge) call mpas_pool_get_array(hydroPool, 'channelVelocity', channelVelocity) call mpas_pool_get_array(hydroPool, 'gradMagPhiEdge', gradMagPhiEdge) - call mpas_pool_get_array(hydroPool, 'hydropotentialBaseSlopeNormal', hydropotentialBaseSlopeNormal) + call mpas_pool_get_array(hydroPool, 'hydropotentialSlopeNormal', hydropotentialSlopeNormal) call mpas_pool_get_array(hydroPool, 'waterPressureSlopeNormal', waterPressureSlopeNormal) call mpas_pool_get_array(hydroPool, 'waterFlux', waterFlux) call mpas_pool_get_array(hydroPool, 'channelOpeningRate', channelOpeningRate) @@ -1720,7 +1720,7 @@ subroutine update_channel(block, err) channelDischarge(:) = 0.0_RKIND elsewhere channelDischarge = -1.0_RKIND * Kc * channelArea**alpha_c * gradMagPhiEdge**(beta_c - 2.0_RKIND) * & - hydropotentialBaseSlopeNormal + hydropotentialSlopeNormal end where where (waterFluxMask == 2) @@ -1752,8 +1752,8 @@ subroutine update_channel(block, err) Kc * channelArea**(alpha_c - 1.0_RKIND) * gradMagPhiEdge**(beta_c - 2.0_RKIND)) end where - channelMelt = (abs(channelDischarge * hydropotentialBaseSlopeNormal) & ! channel dissipation - + abs(waterFlux * hydropotentialBaseSlopeNormal * config_SGH_incipient_channel_width) & !some sheet dissipation + channelMelt = (abs(channelDischarge * hydropotentialSlopeNormal) & ! channel dissipation + + abs(waterFlux * hydropotentialSlopeNormal * config_SGH_incipient_channel_width) & !some sheet dissipation ) / latent_heat_ice channelPressureFreeze = -1.0_RKIND * iceMeltingPointPressureDependence * cp_freshwater * rho_water * & (channelDischarge + waterFlux * config_SGH_incipient_channel_width) & From d10446452ebb2fe4dfb48b9d1e245c9dce565639 Mon Sep 17 00:00:00 2001 From: Matthew Hoffman Date: Thu, 18 May 2023 14:12:10 -0600 Subject: [PATCH 014/451] Disable diffusive water flux at grounding line The water thickness in the ocean is undefined, and if anything we'd have diffusion from the ocean (thick water layer) to the grounded ice, and we don't want any flux from the ocean inward. --- .../src/mode_forward/mpas_li_subglacial_hydro.F | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/components/mpas-albany-landice/src/mode_forward/mpas_li_subglacial_hydro.F b/components/mpas-albany-landice/src/mode_forward/mpas_li_subglacial_hydro.F index 5d048074bea9..d7b7d3deede0 100644 --- a/components/mpas-albany-landice/src/mode_forward/mpas_li_subglacial_hydro.F +++ b/components/mpas-albany-landice/src/mode_forward/mpas_li_subglacial_hydro.F @@ -963,11 +963,15 @@ subroutine calc_edge_quantities(block, err) waterFluxAdvec(iEdge) = waterVelocity(iEdge) * waterThicknessEdgeUpwind(iEdge) ! diffusive flux - ! Note: At the GL, the water thickness for one cell will be 0, meaning a large gradient. However, the - ! diffusivity uses a one sided water thickness. It's unclear what really happens to lakes at the GL/margin. - waterFluxDiffu(iEdge) = -1.0_RKIND * diffusivity(iEdge) * (waterThickness(cell2) - waterThickness(cell1)) & + ! Note: Water thickness at the GL is undefined. I don't think we want to assume it's 0, and + ! we also don't want to assume it's the ocean water column height, because that would imply + ! a diffusive flux inward, which is undesirable. So disabling diffusion at the GL. + if (hydroMarineMarginMask(iEdge) == 1) then + waterFluxDiffu(iEdge) = 0.0_RKIND + else + waterFluxDiffu(iEdge) = -1.0_RKIND * diffusivity(iEdge) * (waterThickness(cell2) - waterThickness(cell1)) & / dcEdge(iEdge) - !endif + endif end do where (waterFluxMask == 2) waterFluxAdvec = 0.0_RKIND From 89b3ca1157e0058c357961164082228b92313765 Mon Sep 17 00:00:00 2001 From: Matthew Hoffman Date: Fri, 19 May 2023 16:43:25 -0600 Subject: [PATCH 015/451] Move call to mpas_calculate_barycentric_weights_for_points Previously the call to mpas_calculate_barycentric_weights_for_points to set up barycentric weights for interpolation from cells to vertices occurred in the mpas_li_sia.F module. However, these weights may also be needed by the subglacial hydro code, which can be called with any (or none) velocity solver. This commit moves that initialization to mpas_li_setup and adds logic to call the weight generation routine if either the SIA or SGH code requires it. --- .../mpas-albany-landice/src/Registry.xml | 4 +- .../src/mode_forward/mpas_li_core.F | 4 + .../src/mode_forward/mpas_li_sia.F | 44 -------- .../src/shared/mpas_li_setup.F | 106 +++++++++++++++++- 4 files changed, 111 insertions(+), 47 deletions(-) diff --git a/components/mpas-albany-landice/src/Registry.xml b/components/mpas-albany-landice/src/Registry.xml index 279d7fb3c0a0..1a8523d39138 100644 --- a/components/mpas-albany-landice/src/Registry.xml +++ b/components/mpas-albany-landice/src/Registry.xml @@ -1125,10 +1125,10 @@ is the value of that variable from the *previous* time level! /> 0) then - call mpas_log_write("The 'from_vertex_barycentric' option for 'config_sia_tangent_slope_calculation' " & - // "does NOT work across the periodicity in periodic meshes. However, it does work within the interior " & - // "of the mesh.", MPAS_LOG_WARN) - endif - call mpas_deallocate_scratch_field(vertexIndicesField, .true.) - endif ! === error check if (err > 0) then diff --git a/components/mpas-albany-landice/src/shared/mpas_li_setup.F b/components/mpas-albany-landice/src/shared/mpas_li_setup.F index e231b4733bbd..a77178001e3c 100644 --- a/components/mpas-albany-landice/src/shared/mpas_li_setup.F +++ b/components/mpas-albany-landice/src/shared/mpas_li_setup.F @@ -53,7 +53,8 @@ module li_setup li_interpolate_vertex_to_cell_2d, & li_cells_to_vertices_1dfield_using_kiteAreas, & li_calculate_layerThickness, & - li_compute_gradient_2d + li_compute_gradient_2d, & + li_init_barycentric_weights_vertex !-------------------------------------------------------------------- @@ -817,6 +818,109 @@ subroutine li_compute_gradient_2d(& end subroutine li_compute_gradient_2d +!||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||| +! +! routine li_init_barycentric_weights_vertex +! +!> \brief compute barycentric weights for interpolating cells to vertices +!> \author Matt Hoffman +!> \date May 2023 +!> \details +!> This routine uses a framework routine to compute the barycentric +!> weights for interpolating from cells to vertices +! +!----------------------------------------------------------------------- + + subroutine li_init_barycentric_weights_vertex(block, err) + + use mpas_geometry_utils, only: mpas_calculate_barycentric_weights_for_points + + !----------------------------------------------------------------- + ! input variables + !----------------------------------------------------------------- + + !----------------------------------------------------------------- + ! input/output variables + !----------------------------------------------------------------- + type (block_type), intent(inout) :: & + block !< Input/Output: block object + + !----------------------------------------------------------------- + ! output variables + !----------------------------------------------------------------- + integer, intent(out) :: err !< Output: error flag + + !----------------------------------------------------------------- + ! local variables + !----------------------------------------------------------------- + type (mpas_pool_type), pointer :: meshPool + type (mpas_pool_type), pointer :: scratchPool + integer :: iCell, iLevel, i, iVertex, err_tmp + integer, pointer :: nVertices + character (len=StrKIND), pointer :: config_velocity_solver + character (len=StrKIND), pointer :: config_sia_tangent_slope_calculation + logical, pointer :: config_SGH + character (len=StrKIND), pointer :: config_SGH_tangent_slope_calculation + integer, dimension(:,:), pointer :: baryCellsOnVertex + real (kind=RKIND), dimension(:,:), pointer :: baryWeightsOnVertex + real (kind=RKIND), dimension(:), pointer :: xVertex, yVertex, zVertex + type (field1dInteger), pointer :: vertexIndicesField + + ! No block init needed. + err = 0 + err_tmp = 0 + + call mpas_pool_get_subpool(block % structs, 'mesh', meshPool) + call mpas_pool_get_subpool(block % structs, 'scratch', scratchPool) + call mpas_pool_get_array(meshPool, 'baryCellsOnVertex', baryCellsOnVertex) + call mpas_pool_get_array(meshPool, 'baryWeightsOnVertex', baryWeightsOnVertex) + call mpas_pool_get_array(meshPool, 'xVertex', xVertex) + call mpas_pool_get_array(meshPool, 'yVertex', yVertex) + call mpas_pool_get_array(meshPool, 'zVertex', zVertex) + call mpas_pool_get_config(liConfigs, 'config_velocity_solver', config_velocity_solver) + call mpas_pool_get_config(liConfigs, 'config_sia_tangent_slope_calculation', config_sia_tangent_slope_calculation) + call mpas_pool_get_config(liConfigs, 'config_SGH', config_SGH) + call mpas_pool_get_config(liConfigs, 'config_SGH_tangent_slope_calculation', config_SGH_tangent_slope_calculation) + call mpas_pool_get_field(scratchPool, 'vertexIndices', vertexIndicesField) + call mpas_pool_get_dimension(meshPool, 'nVertices', nVertices) + + if ( & + (trim(config_velocity_solver) == 'sia' .and. & + trim(config_sia_tangent_slope_calculation) == 'from_vertex_barycentric') & + .or. & + (config_SGH .and. trim(config_SGH_tangent_slope_calculation) == 'from_vertex_barycentric')) then + + call mpas_allocate_scratch_field(vertexIndicesField, .true.) + do iVertex = 1, nVertices + vertexIndicesField % array(iVertex) = iVertex + enddo + call mpas_calculate_barycentric_weights_for_points(meshPool, & + xVertex(1:nVertices), yVertex(1:nVertices), zVertex(1:nVertices), & + vertexIndicesField % array(1:nVertices), & + baryCellsOnVertex(:, 1:nVertices), baryWeightsOnVertex(:, 1:nVertices), err_tmp) + ! TODO: Until framework can handle periodic meshs gracefully, this will return an error + ! for periodic meshes. This error means that the velocity solver will be very wrong across + ! the periodicity, but it will be fine everywhere else. For now, just print a warning but + ! don't make this a fatal error. + !err = ior(err, err_tmp) + if (err_tmp > 0) then + call mpas_log_write("The 'from_vertex_barycentric' option for 'config_sia_tangent_slope_calculation' " & + // "'config_SGH_tangent_slope_calculation' " & + // "does NOT work across the periodicity in periodic meshes. However, it does work within the interior " & + // "of the mesh.", MPAS_LOG_WARN) + endif + call mpas_deallocate_scratch_field(vertexIndicesField, .true.) + + endif + + ! === error check + if (err > 0) then + call mpas_log_write("An error has occurred in li_init_barycentric_weights_vertex", MPAS_LOG_ERR) + endif + + end subroutine li_init_barycentric_weights_vertex + + !*********************************************************************** !*********************************************************************** ! Private subroutines: From 34279d01f978bd0e6639b02baf1dfdade018980f Mon Sep 17 00:00:00 2001 From: Matthew Hoffman Date: Fri, 19 May 2023 13:07:03 -0600 Subject: [PATCH 016/451] Zero gradients at edges of the mesh Without explicitly doing this, the gradients are likely using neighboring values of 0, which would yield unexpectedly large gradients. --- .../src/mode_forward/mpas_li_subglacial_hydro.F | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/components/mpas-albany-landice/src/mode_forward/mpas_li_subglacial_hydro.F b/components/mpas-albany-landice/src/mode_forward/mpas_li_subglacial_hydro.F index d7b7d3deede0..82b4782b3e58 100644 --- a/components/mpas-albany-landice/src/mode_forward/mpas_li_subglacial_hydro.F +++ b/components/mpas-albany-landice/src/mode_forward/mpas_li_subglacial_hydro.F @@ -889,6 +889,16 @@ subroutine calc_edge_quantities(block, err) endif ! GL edge or grounded margin end do + ! zero gradients at boundaries of the mesh + do iEdge = 1, nEdges + cell1 = cellsOnEdge(1, iEdge) + cell2 = cellsOnEdge(2, iEdge) + if ((cell1 == nCells+1) .or. (cell2 == nCells+1)) then + hydropotentialBaseSlopeNormal(iEdge) = 0.0_RKIND + hydropotentialSlopeNormal(iEdge) = 0.0_RKIND + waterPressureSlopeNormal(iEdge) = 0.0_RKIND + endif + end do ! Calculate tangent slope of hydropotentialBase - three possible methods to consider From be959a9c6daddf198fed032a920f53c261dd9919 Mon Sep 17 00:00:00 2001 From: Matthew Hoffman Date: Fri, 19 May 2023 13:29:33 -0600 Subject: [PATCH 017/451] Treat tangent slope calculation near boundary of mesh This commit explicitly treats the calculation of hydropotentialBaseSlopeTangent near mesh boundaries. For the two vertex based methods, edges with vertices on the boundary of the mesh will have invalid values. For the normal slope method, any edges on cells that are at the edge of the mesh will have contaminated values. In those cases, set tangent slope to zero rather than leaving the possibility of garbage values. --- .../mode_forward/mpas_li_subglacial_hydro.F | 27 ++++++++++++++++--- 1 file changed, 24 insertions(+), 3 deletions(-) diff --git a/components/mpas-albany-landice/src/mode_forward/mpas_li_subglacial_hydro.F b/components/mpas-albany-landice/src/mode_forward/mpas_li_subglacial_hydro.F index 82b4782b3e58..35974d867e2a 100644 --- a/components/mpas-albany-landice/src/mode_forward/mpas_li_subglacial_hydro.F +++ b/components/mpas-albany-landice/src/mode_forward/mpas_li_subglacial_hydro.F @@ -744,6 +744,7 @@ subroutine calc_edge_quantities(block, err) integer, dimension(:), pointer :: edgeMask integer, dimension(:,:), pointer :: cellsOnEdge integer, dimension(:,:), pointer :: verticesOnEdge + integer, dimension(:,:), pointer :: cellsOnVertex integer, dimension(:,:), pointer :: baryCellsOnVertex real (kind=RKIND), dimension(:,:), pointer :: baryWeightsOnVertex real (kind=RKIND), pointer :: alpha, beta @@ -758,6 +759,7 @@ subroutine calc_edge_quantities(block, err) integer, pointer :: nCells integer, pointer :: nVertices integer :: iEdge, cell1, cell2 + integer :: i, j, iVertex, iCell real (kind=RKIND) :: velSign integer :: numGroundedCells integer :: err_tmp @@ -917,11 +919,14 @@ subroutine calc_edge_quantities(block, err) end select ! Now perform tangent slope calculation based on method chosen + ! For the two vertex based methods, edges with vertices on the boundary of the mesh will have invalid values + ! For the normal slope method, any edges on cells that are at the edge of the mesh will have + ! contaminated values. + call mpas_pool_get_array(meshPool, 'dvEdge', dvEdge) + call mpas_pool_get_array(meshPool, 'verticesOnEdge', verticesOnEdge) + call mpas_pool_get_array(meshPool, 'cellsOnVertex', cellsOnVertex) select case (trim(config_SGH_tangent_slope_calculation)) case ('from_vertex_barycentric', 'from_vertex_barycentric_kiteareas') - call mpas_pool_get_array(geometryPool, 'edgeMask', edgeMask) - call mpas_pool_get_array(meshPool, 'dvEdge', dvEdge) - call mpas_pool_get_array(meshPool, 'verticesOnEdge', verticesOnEdge) do iEdge = 1, nEdges ! Only calculate slope for edges that have ice on at least one side. if ( li_mask_is_ice(edgeMask(iEdge)) ) then @@ -930,10 +935,26 @@ subroutine calc_edge_quantities(block, err) else hydropotentialBaseSlopeTangent(iEdge) = 0.0_RKIND endif + ! check for edges where a vertex is on the edge of the mesh and zero the tangent slope there + do i = 1, 2 + iVertex = verticesOnEdge(i, iEdge) + do j = 1, 3 + iCell = cellsOnVertex(j, iVertex) + if (iCell == nCells + 1) then + hydropotentialBaseSlopeTangent(iEdge) = 0.0_RKIND + endif + enddo + enddo end do ! edges case ('from_normal_slope') call mpas_tangential_vector_1d(hydropotentialBaseSlopeNormal, meshPool, & includeHalo=.false., tangentialVector=hydropotentialBaseSlopeTangent) + ! ensure that edges that don't have ice on at least one side have tangent slope set to zero + do iEdge = 1, nEdges + if ( .not. li_mask_is_ice(edgeMask(iEdge)) ) then + hydropotentialBaseSlopeTangent(iEdge) = 0.0_RKIND + endif + end do ! edges case default call mpas_log_write('Invalid value for config_SGH_tangent_slope_calculation.', MPAS_LOG_ERR) err = 1 From e78b763bf00499204cf71a2f18207183c9112f22 Mon Sep 17 00:00:00 2001 From: Matthew Hoffman Date: Mon, 22 May 2023 19:22:17 -0600 Subject: [PATCH 018/451] Adjust hydro CFL calculation to ignore invalid edges Without this change, the CFL condition might be overly restrictive because values from cells that aren't part of advection get included in the calculation and they may happen to have values that are more restrictive than the valid edges. --- .../mode_forward/mpas_li_subglacial_hydro.F | 57 ++++++++++++------- 1 file changed, 35 insertions(+), 22 deletions(-) diff --git a/components/mpas-albany-landice/src/mode_forward/mpas_li_subglacial_hydro.F b/components/mpas-albany-landice/src/mode_forward/mpas_li_subglacial_hydro.F index 35974d867e2a..cf02e943785d 100644 --- a/components/mpas-albany-landice/src/mode_forward/mpas_li_subglacial_hydro.F +++ b/components/mpas-albany-landice/src/mode_forward/mpas_li_subglacial_hydro.F @@ -998,6 +998,7 @@ subroutine calc_edge_quantities(block, err) ! we also don't want to assume it's the ocean water column height, because that would imply ! a diffusive flux inward, which is undesirable. So disabling diffusion at the GL. if (hydroMarineMarginMask(iEdge) == 1) then + diffusivity(iEdge) = 0.0_RKIND waterFluxDiffu(iEdge) = 0.0_RKIND else waterFluxDiffu(iEdge) = -1.0_RKIND * diffusivity(iEdge) * (waterThickness(cell2) - waterThickness(cell1)) & @@ -1139,31 +1140,43 @@ subroutine check_timestep(domain, timeLeft, numSubCycles, err) call mpas_pool_get_array(meshPool, 'dcEdge', dcEdge) call mpas_pool_get_array(meshPool, 'indexToEdgeID', indexToEdgeID) - ! Calculate advective CFL-limited time step - dtSGHadvecBlock = 0.5_RKIND * minval(dcEdge(1:nEdgesSolve) / (abs(waterVelocity(1:nEdgesSolve)) & - + 1.0e-12_RKIND)) ! regularize - dtSGHadvecProc = min(dtSGHadvecProc, dtSGHadvecBlock) + dtSGHadvecBlock = bigNumber + dtSGHdiffuBlock = bigNumber + dtSGHpressureBlock = bigNumber + dtSGHadvecChanBlock = bigNumber + dtSGHdiffuChanBlock = bigNumber - ! Calculate diffusive CFL-limited time step - dtSGHdiffuBlock = 0.25_RKIND * minval(dcEdge(1:nEdgesSolve)**2 / (diffusivity(1:nEdgesSolve) + 1.0e-12_RKIND)) - dtSGHdiffuProc = min(dtSGHdiffuProc, dtSGHdiffuBlock) + do iEdge = 1, nEdgesSolve + ! Calculate advective CFL-limited time step + if (abs(waterVelocity(iEdge)) > 0.0) then + dtSGHadvecBlock = min(dtSGHadvecBlock, 0.5_RKIND * dcEdge(iEdge) / abs(waterVelocity(iEdge))) + endif - ! Calculate pressure limited time step - dtSGHpressureBlock = 1.0_RKIND * minval(porosity * dcEdge(1:nEdgesSolve)**2 & - / (2.0_RKIND * diffusivity(1:nEdgesSolve) + 1.0e-12_RKIND)) - dtSGHpressureProc = min(dtSGHpressureProc, dtSGHpressureBlock) + if (diffusivity(iEdge) > 0.0) then + ! Calculate diffusive CFL-limited time step + dtSGHdiffuBlock = min(dtSGHdiffuBlock, 0.25_RKIND * dcEdge(iEdge)**2 / diffusivity(iEdge)) + ! Calculate pressure limited time step + dtSGHpressureBlock = min(dtSGHpressureBlock, 1.0_RKIND * porosity * dcEdge(iEdge)**2 & + / (2.0_RKIND * diffusivity(iEdge))) + endif - if (config_SGH_chnl_active) then - ! Calculate channel advection limited time step - dtSGHadvecChanBlock = 0.5_RKIND * minval(dcEdge(1:nEdgesSolve) / (abs(channelVelocity(1:nEdgesSolve)) & - + 1.0e-12_RKIND)) - ! regularize - dtSGHadvecChanProc = min(dtSGHadvecChanProc, dtSGHadvecChanBlock) - ! Calculate channel diffusion limited time step - dtSGHdiffuChanBlock = 0.25_RKIND * minval(dcEdge(1:nEdgesSolve)**2 / (channelDiffusivity(1:nEdgesSolve) + & - 1.0e-12_RKIND)) - dtSGHdiffuChanProc = min(dtSGHdiffuChanProc, dtSGHdiffuChanBlock) - endif + if (config_SGH_chnl_active) then + if (abs(channelVelocity(iEdge)) > 0.0) then + ! Calculate channel advection limited time step + dtSGHadvecChanBlock = min(dtSGHadvecChanBlock, 0.5_RKIND * dcEdge(iEdge) / (abs(channelVelocity(iEdge)))) + endif + ! Calculate channel diffusion limited time step + if (channelDiffusivity(iEdge) > 0.0) then + dtSGHdiffuChanBlock = min(dtSGHdiffuChanBlock, 0.25_RKIND * dcEdge(iEdge)**2 / channelDiffusivity(iEdge)) + endif + endif + enddo + + dtSGHadvecProc = min(dtSGHadvecProc, dtSGHadvecBlock) + dtSGHdiffuProc = min(dtSGHdiffuProc, dtSGHdiffuBlock) + dtSGHpressureProc = min(dtSGHpressureProc, dtSGHpressureBlock) + dtSGHadvecChanProc = min(dtSGHadvecChanProc, dtSGHadvecChanBlock) + dtSGHdiffuChanProc = min(dtSGHdiffuChanProc, dtSGHdiffuChanBlock) ! Master deltat is needed below, so grab it in this block loop call mpas_pool_get_array(meshPool, 'deltat', deltat) From 4f448669204b5a947760807f6fbd8184d6b96bac Mon Sep 17 00:00:00 2001 From: Matthew Hoffman Date: Thu, 25 May 2023 14:21:24 -0600 Subject: [PATCH 019/451] Update gradient calulations at boundaries of hydro domain Simplify calculation disallowing inflow and move it *before* extra logic limiting outflow gradient. --- .../mode_forward/mpas_li_subglacial_hydro.F | 50 +++++++------------ 1 file changed, 19 insertions(+), 31 deletions(-) diff --git a/components/mpas-albany-landice/src/mode_forward/mpas_li_subglacial_hydro.F b/components/mpas-albany-landice/src/mode_forward/mpas_li_subglacial_hydro.F index cf02e943785d..aeb9da614a00 100644 --- a/components/mpas-albany-landice/src/mode_forward/mpas_li_subglacial_hydro.F +++ b/components/mpas-albany-landice/src/mode_forward/mpas_li_subglacial_hydro.F @@ -833,12 +833,29 @@ subroutine calc_edge_quantities(block, err) waterPressureSlopeNormal(iEdge) = (waterPressure(cell2) - waterPressure(cell1)) / dcEdge(iEdge) end do + ! At boundaries of hydro domain, disallow inflow. Allow outflow if hydropotential gradient requires it. + do iEdge = 1, nEdges + if ( (li_mask_is_margin(edgeMask(iEdge)) .and. li_mask_is_grounded_ice(edgeMask(iEdge))) .or. & + (hydroMarineMarginMask(iEdge)==1)) then + cell1 = cellsOnEdge(1, iEdge) + cell2 = cellsOnEdge(2, iEdge) + if (li_mask_is_grounded_ice(cellMask(cell1))) then ! cell2 is the cell outside the hydro domain + hydropotentialBaseSlopeNormal(iEdge) = min(0.0_RKIND, hydropotentialBaseSlopeNormal(iEdge)) + hydropotentialSlopeNormal(iEdge) = min(0.0_RKIND, hydropotentialSlopeNormal(iEdge)) + else ! cell1 is the cell outside the hydro domain + hydropotentialBaseSlopeNormal(iEdge) = max(0.0_RKIND, hydropotentialBaseSlopeNormal(iEdge)) + hydropotentialSlopeNormal(iEdge) = max(0.0_RKIND, hydropotentialSlopeNormal(iEdge)) + endif ! which cell is icefree + endif ! if edge of grounded ice + end do + ! At terrestrial margin, ignore the downslope bed topography gradient. Including it can lead to unrealistically large ! hydropotential gradients and unstable channel growth. ! We also want to do this at marine margins because otherwise the offshore topography can create a barrier to flow, ! but that is unrealistic. - ! So for all boundaries of the hydro system, the hydropotential at the margin should be determined by the geometry - ! at the edge of the cell in a 1-sided sense + ! So for all boundaries of the hydro system where outflow is occuring, + ! the hydropotential at the margin should be determined by the geometry + ! at the edge of the cell in a 1-sided sense. do iEdge = 1, nEdges if ( (li_mask_is_margin(edgeMask(iEdge)) .and. li_mask_is_grounded_ice(edgeMask(iEdge))) .or. & (hydroMarineMarginMask(iEdge)==1)) then @@ -862,35 +879,6 @@ subroutine calc_edge_quantities(block, err) endif ! if edge of grounded ice end do - ! Disallow flow from ocean to glacier, or land to glacier, - ! which can occur under some circumstances - ! For ocean this is invalid because ocean water has a different density! - ! For land this would only happen if there is a supply of water, which is not currently handled. - ! Do this by simply zeroing the hydropotential gradient in those cases. - ! (Do this step only after the other hydropotential special cases are treated above.) - do iEdge = 1, nEdges - ! Find edges along GL or margin to check for 'backwards' flow - if ((hydroMarineMarginMask(iEdge)==1) .or. & - li_mask_is_margin(edgeMask(iEdge)) ) then - ! Now check if flow is backwards - cell1 = cellsOnEdge(1, iEdge) - cell2 = cellsOnEdge(2, iEdge) - if (hydropotentialBaseSlopeNormal(iEdge) > 0.0_RKIND) then - ! flow is from cell2 to cell1 - if (.not. li_mask_is_grounded_ice(cellMask(cell2))) then - hydropotentialBaseSlopeNormal(iEdge) = 0.0_RKIND - hydropotentialSlopeNormal(iEdge) = 0.0_RKIND - endif - elseif (hydropotentialBaseSlopeNormal(iEdge) < 0.0_RKIND) then - ! flow is from cell1 to cell2 - if (.not. li_mask_is_grounded_ice(cellMask(cell1))) then - hydropotentialBaseSlopeNormal(iEdge) = 0.0_RKIND - hydropotentialSlopeNormal(iEdge) = 0.0_RKIND - endif - endif - endif ! GL edge or grounded margin - end do - ! zero gradients at boundaries of the mesh do iEdge = 1, nEdges cell1 = cellsOnEdge(1, iEdge) From f82cddd6e3f6dd43cb03877cf4897532c3087db7 Mon Sep 17 00:00:00 2001 From: Alexander Hager Date: Thu, 25 May 2023 17:33:37 -0600 Subject: [PATCH 020/451] Channel gradMagPhiEdge dependent on full water hydropotential Channels now use updated version of gradMagPhiEdge, which is dependent on full hydropotential. This is done to keep channels from filling up lakes even when lake is full and hydropotential is in opposite direction. Distributed system is now dependent on new variable gradMagPhiBaseEdge, which is dependent only on hydropotentialBase and is equivalent to gradMagPhiEdge in previous commits. --- .../src/Registry_subglacial_hydro.xml | 8 ++++- .../mode_forward/mpas_li_subglacial_hydro.F | 36 +++++++++++++++---- 2 files changed, 37 insertions(+), 7 deletions(-) diff --git a/components/mpas-albany-landice/src/Registry_subglacial_hydro.xml b/components/mpas-albany-landice/src/Registry_subglacial_hydro.xml index c9087d164def..602b7c11f6d5 100644 --- a/components/mpas-albany-landice/src/Registry_subglacial_hydro.xml +++ b/components/mpas-albany-landice/src/Registry_subglacial_hydro.xml @@ -196,14 +196,20 @@ description="hydropotential in subglacial hydrology system without water thickness contribution" /> + - + + 0.0_RKIND) then ! Use a thickness weighted conductivity coeff. when water thickness exceeds bump height @@ -959,12 +983,12 @@ subroutine calc_edge_quantities(block, err) conduc_coeff_drowned * max(waterThicknessEdge(iEdge) - bedRoughMax, 0.0_RKIND)) / & (waterThicknessEdge(iEdge) + 1.0e-16_RKIND) ! Regularization only applies where value doesn't matter effectiveConducEdge(iEdge) = conduc_coeff_wtd * waterThicknessEdge(iEdge)**(alpha-1.0_RKIND) * & - (gradMagPhiEdge(iEdge)+1.0e-30_RKIND)**(beta - 2.0_RKIND) ! small value used for regularization + (gradMagPhiBaseEdge(iEdge)+1.0e-30_RKIND)**(beta - 2.0_RKIND) ! small value used for regularization end do else ! Just use a single conductivity coeff. effectiveConducEdge(:) = conduc_coeff * waterThicknessEdge(:)**(alpha-1.0_RKIND) *& - (gradMagPhiEdge(:)+1.0e-30_RKIND)**(beta - 2.0_RKIND) ! small value used for regularization + (gradMagPhiBaseEdge(:)+1.0e-30_RKIND)**(beta - 2.0_RKIND) ! small value used for regularization endif ! calculate diffusivity on edges From dc6b48e5f2659b478278957f8bc952c771f6cf88 Mon Sep 17 00:00:00 2001 From: Alexander Hager Date: Mon, 12 Jun 2023 11:01:31 -0600 Subject: [PATCH 021/451] Create hydroTerrestrialMarginMask Creates hydroTerrestrialMarginMask variable, which designates the terrestrial margins of the active subglacial hydrology model --- .../src/Registry_subglacial_hydro.xml | 4 +++- .../src/mode_forward/mpas_li_subglacial_hydro.F | 16 ++++++++++++++++ 2 files changed, 19 insertions(+), 1 deletion(-) diff --git a/components/mpas-albany-landice/src/Registry_subglacial_hydro.xml b/components/mpas-albany-landice/src/Registry_subglacial_hydro.xml index 602b7c11f6d5..66a4a306bbf3 100644 --- a/components/mpas-albany-landice/src/Registry_subglacial_hydro.xml +++ b/components/mpas-albany-landice/src/Registry_subglacial_hydro.xml @@ -174,7 +174,9 @@ description="mask indicating how to handle fluxes on each edge: 0=calculate based on hydropotential gradient; 1=allow outflow based on hydropotential gradient, but no inflow (NOT YET IMPLEMENTED); 2=zero flux" /> - + diff --git a/components/mpas-albany-landice/src/mode_forward/mpas_li_subglacial_hydro.F b/components/mpas-albany-landice/src/mode_forward/mpas_li_subglacial_hydro.F index f7118b3fe850..f73177ab3907 100644 --- a/components/mpas-albany-landice/src/mode_forward/mpas_li_subglacial_hydro.F +++ b/components/mpas-albany-landice/src/mode_forward/mpas_li_subglacial_hydro.F @@ -2183,6 +2183,7 @@ subroutine calc_hydro_mask(domain) type (mpas_pool_type), pointer :: meshPool real (kind=RKIND), dimension(:), pointer :: bedTopography integer, dimension(:), pointer :: hydroMarineMarginMask + integer, dimension(:), pointer :: hydroTerrestrialMarginMask integer, dimension(:,:), pointer :: cellsOnEdge integer, dimension(:), pointer :: cellMask integer, pointer :: nEdgesSolve @@ -2199,6 +2200,7 @@ subroutine calc_hydro_mask(domain) call mpas_pool_get_array(geometryPool, 'bedTopography', bedTopography) call mpas_pool_get_array(geometryPool, 'cellMask', cellMask) call mpas_pool_get_array(hydroPool, 'hydroMarineMarginMask', hydroMarineMarginMask) + call mpas_pool_get_array(hydroPool, 'hydroTerrestrialMarginMask', hydroTerrestrialMarginMask) call mpas_pool_get_array(meshPool, 'cellsOnEdge', cellsOnEdge) call mpas_pool_get_dimension(meshPool, 'nEdgesSolve', nEdgesSolve) @@ -2218,6 +2220,20 @@ subroutine calc_hydro_mask(domain) endif enddo + hydroTerrestrialMarginMask(:) = 0 + do iEdge = 1, nEdgesSolve + cell1 = cellsOnEdge(1, iEdge) + cell2 = cellsOnEdge(2, iEdge) + !Look for edges with 1 cell on grounding ice and the other cell on land without ice + if ((li_mask_is_grounded_ice(cellMask(cell1))) .and. ( .not. li_mask_is_ice(cellMask(cell2))) & + .and. (bedTopography(cell2) > config_sea_level)) then + hydroTerrestrialMarginMask(iEdge) = 1 + elseif ((li_mask_is_grounded_ice(cellMask(cell2))) .and. ( .not. li_mask_is_ice(cellMask(cell1))) & + .and. (bedTopography(cell1) > config_sea_level)) then + hydroTerrestrialMarginMask(iEdge) = 1 + endif + enddo + block => block % next end do From 69d566d521d125f2cded4c458797e8a874ba7634 Mon Sep 17 00:00:00 2001 From: Alexander Hager Date: Tue, 20 Jun 2023 17:29:32 -0600 Subject: [PATCH 022/451] Edit SGH_tangent_slope_calculation description Edits description of config_SGH_tangent_slope_calculation in Registry_subglacial_hydro.xml based on detailed testing of 'from_normal_slope' and 'from_vertex_barycentric' options. --- .../mpas-albany-landice/src/Registry_subglacial_hydro.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/components/mpas-albany-landice/src/Registry_subglacial_hydro.xml b/components/mpas-albany-landice/src/Registry_subglacial_hydro.xml index 66a4a306bbf3..b70e885eb592 100644 --- a/components/mpas-albany-landice/src/Registry_subglacial_hydro.xml +++ b/components/mpas-albany-landice/src/Registry_subglacial_hydro.xml @@ -24,7 +24,7 @@ description="Selection of the method for calculating the tangent component of slope at edges. 'from_vertex_barycentric' interpolates scalar values from cell centers to vertices using the barycentric interpolation routine in operators (mpas_cells_to_points_using_baryweights) and then calculates the slope between vertices. It works for obtuse triangles, but will not work correctly across the edges of periodic meshes. 'from_vertex_barycentric_kiteareas' interpolates scalar values from cell centers to vertices using barycentric interpolation based on kiterea values and then calculates the slope between vertices. It will work across the edges of periodic meshes, but will not work correctly for obtuse triangles. -'from_normal_slope' uses the vector operator mpas_tangential_vector_1d to calculate the tangent slopes from the normal slopes on the edges of the adjacent cells. It will work for any mesh configuration, but is the least accurate method." +'from_normal_slope' uses the vector operator mpas_tangential_vector_1d to calculate the tangent slopes from the normal slopes on the edges of the adjacent cells. It will work for any mesh configuration. 'from_normal_slope' uses a larger stencil, so may therefore produce a smoother 'gradMagPhiEdge' field. Detailed testing yielded nearly identical results between 'from_normal_slope' and 'from_vertex_barycentric' methods, but 'from_normal_slope' seemed to produce slightly more stable results at the grounding line." possible_values="'from_vertex_barycentric', 'from_vertex_barycentric_kiteareas', 'from_normal_slope'" /> Date: Wed, 19 Jul 2023 14:56:46 -0600 Subject: [PATCH 023/451] Zero diffusivity at boundary edges Explicitly sets diffusivity to zero at boundary edges, instead of just waterFluxDiff --- .../src/mode_forward/mpas_li_subglacial_hydro.F | 1 + 1 file changed, 1 insertion(+) diff --git a/components/mpas-albany-landice/src/mode_forward/mpas_li_subglacial_hydro.F b/components/mpas-albany-landice/src/mode_forward/mpas_li_subglacial_hydro.F index f73177ab3907..5a4049f146e3 100644 --- a/components/mpas-albany-landice/src/mode_forward/mpas_li_subglacial_hydro.F +++ b/components/mpas-albany-landice/src/mode_forward/mpas_li_subglacial_hydro.F @@ -1018,6 +1018,7 @@ subroutine calc_edge_quantities(block, err) endif end do where (waterFluxMask == 2) + diffusivity = 0.0_RKIND waterFluxAdvec = 0.0_RKIND waterFluxDiffu = 0.0_RKIND waterVelocity = 0.0_RKIND From 7529d5d5b2042c5212969bd94deca8f0ae6a614b Mon Sep 17 00:00:00 2001 From: Alexander Hager Date: Fri, 1 Dec 2023 12:40:09 -0800 Subject: [PATCH 024/451] hydroTerrestrialMarginMask >= sea level Redfines hydroTerrestiralMarineMargin to AT or above sea level, whereas hydroMarineMarginMask is exclusively below sea level. --- .../src/mode_forward/mpas_li_subglacial_hydro.F | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/components/mpas-albany-landice/src/mode_forward/mpas_li_subglacial_hydro.F b/components/mpas-albany-landice/src/mode_forward/mpas_li_subglacial_hydro.F index 5a4049f146e3..f02e9860e5e4 100644 --- a/components/mpas-albany-landice/src/mode_forward/mpas_li_subglacial_hydro.F +++ b/components/mpas-albany-landice/src/mode_forward/mpas_li_subglacial_hydro.F @@ -2227,10 +2227,10 @@ subroutine calc_hydro_mask(domain) cell2 = cellsOnEdge(2, iEdge) !Look for edges with 1 cell on grounding ice and the other cell on land without ice if ((li_mask_is_grounded_ice(cellMask(cell1))) .and. ( .not. li_mask_is_ice(cellMask(cell2))) & - .and. (bedTopography(cell2) > config_sea_level)) then + .and. (bedTopography(cell2) >= config_sea_level)) then hydroTerrestrialMarginMask(iEdge) = 1 elseif ((li_mask_is_grounded_ice(cellMask(cell2))) .and. ( .not. li_mask_is_ice(cellMask(cell1))) & - .and. (bedTopography(cell1) > config_sea_level)) then + .and. (bedTopography(cell1) >= config_sea_level)) then hydroTerrestrialMarginMask(iEdge) = 1 endif enddo From 6fb6db5a6c8e29b1c6739538272f06e5115bfdde Mon Sep 17 00:00:00 2001 From: Alexander Hager Date: Mon, 5 Feb 2024 14:35:47 -0700 Subject: [PATCH 025/451] channelAreaChangeCell/channelMeltInputCell debug Debugs calculations of channelAreaChangeCell and channelMeltInputCell. Loop where these were being calculated was overwritting cell values each iteration through nEdgesOnCell. Now each cell is the sum of all of its edges as intended. --- .../src/mode_forward/mpas_li_subglacial_hydro.F | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/components/mpas-albany-landice/src/mode_forward/mpas_li_subglacial_hydro.F b/components/mpas-albany-landice/src/mode_forward/mpas_li_subglacial_hydro.F index f02e9860e5e4..e823785f251e 100644 --- a/components/mpas-albany-landice/src/mode_forward/mpas_li_subglacial_hydro.F +++ b/components/mpas-albany-landice/src/mode_forward/mpas_li_subglacial_hydro.F @@ -1930,10 +1930,11 @@ subroutine evolve_channel(block, err) iEdge = edgesOnCell(iEdgeOnCell, iCell) ! add on advective & diffusive fluxes divergenceChannel(iCell) = divergenceChannel(iCell) - channelDischarge(iEdge) * edgeSignOnCell(iEdgeOnCell, iCell) - channelAreaChangeCell(iCell) = channelChangeRate(iEdge) * dcEdge(iEdge) * 0.5_RKIND + channelAreaChangeCell(iCell) = channelChangeRate(iEdge) * dcEdge(iEdge) * 0.5_RKIND + channelAreaChangeCell(iCell) ! < only half of channel is in this cell - channelMeltInputCell(iCell) = 0.5_RKIND * (channelMelt(iEdge) - channelPressureFreeze(iEdge)) * dcEdge(iEdge) / rho_water + channelMeltInputCell(iCell) = 0.5_RKIND * (channelMelt(iEdge) - channelPressureFreeze(iEdge)) * dcEdge(iEdge) / rho_water + channelMeltInputCell(iCell) end do ! edges + end do ! cells divergenceChannel(1:nCellsSolve) = divergenceChannel(1:nCellsSolve) / areaCell(1:nCellsSolve) channelAreaChangeCell(1:nCellsSolve) = channelAreaChangeCell(1:nCellsSolve) / areaCell(1:nCellsSolve) From 489805df75a1054db0f7ee3b3a0e6486b24f6973 Mon Sep 17 00:00:00 2001 From: Matthew Hoffman Date: Tue, 13 Feb 2024 13:24:58 -0700 Subject: [PATCH 026/451] fix typo --- .../src/mode_forward/mpas_li_subglacial_hydro.F | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/components/mpas-albany-landice/src/mode_forward/mpas_li_subglacial_hydro.F b/components/mpas-albany-landice/src/mode_forward/mpas_li_subglacial_hydro.F index e823785f251e..bbabf2e10ec7 100644 --- a/components/mpas-albany-landice/src/mode_forward/mpas_li_subglacial_hydro.F +++ b/components/mpas-albany-landice/src/mode_forward/mpas_li_subglacial_hydro.F @@ -900,7 +900,7 @@ subroutine calc_edge_quantities(block, err) ! Calculate hydropotentialBaseVertex if needed call mpas_pool_get_array(hydroPool, 'hydropotentialBaseVertex', hydropotentialBaseVertex) ! < this array could be protected by logic if desired - ! caluculate hydropotentialVertex if needed + ! calculate hydropotentialVertex if needed call mpas_pool_get_array(hydroPool, 'hydropotentialVertex', hydropotentialVertex) ! < this array could be protected by logic if desired select case (trim(config_SGH_tangent_slope_calculation)) From 58b91c193de583cf483b938744d1263e421452e7 Mon Sep 17 00:00:00 2001 From: Matthew Hoffman Date: Tue, 13 Feb 2024 16:32:42 -0700 Subject: [PATCH 027/451] Add halo updates on two channel variables This is necessary to get BFB results on different decompositions. This addition was made necessary by c9c13aa5d4abb80e398ba361fb362ececb82b478. There may be a way to adjust halo updates to avoid needing to add these both, as they are both local calculations. But it is likely complex, so this solution is adequate in that it works. --- .../src/mode_forward/mpas_li_subglacial_hydro.F | 2 ++ 1 file changed, 2 insertions(+) diff --git a/components/mpas-albany-landice/src/mode_forward/mpas_li_subglacial_hydro.F b/components/mpas-albany-landice/src/mode_forward/mpas_li_subglacial_hydro.F index bbabf2e10ec7..ba5a359301e1 100644 --- a/components/mpas-albany-landice/src/mode_forward/mpas_li_subglacial_hydro.F +++ b/components/mpas-albany-landice/src/mode_forward/mpas_li_subglacial_hydro.F @@ -465,6 +465,8 @@ subroutine li_SGH_solve(domain, err) call mpas_timer_start("halo updates") call mpas_dmpar_field_halo_exch(domain, 'channelChangeRate') call mpas_dmpar_field_halo_exch(domain, 'channelDischarge') + call mpas_dmpar_field_halo_exch(domain, 'channelMelt') + call mpas_dmpar_field_halo_exch(domain, 'channelPressureFreeze') call mpas_timer_stop("halo updates") endif From 4210a61acbdfd197bf00a48728cd575fb1e0dcda Mon Sep 17 00:00:00 2001 From: Walter Hannah Date: Thu, 15 Feb 2024 17:08:59 -0500 Subject: [PATCH 028/451] misc updates for the pam_debug routines --- .../eam/src/physics/crm/pam/pam_debug.h | 117 ++++++++++++------ 1 file changed, 82 insertions(+), 35 deletions(-) diff --git a/components/eam/src/physics/crm/pam/pam_debug.h b/components/eam/src/physics/crm/pam/pam_debug.h index 5186d51c6a9d..f4d8cdb1eda2 100644 --- a/components/eam/src/physics/crm/pam/pam_debug.h +++ b/components/eam/src/physics/crm/pam/pam_debug.h @@ -16,29 +16,33 @@ inline void pam_debug_init( pam::PamCoupler &coupler ) { auto nens = coupler.get_option("ncrms"); //------------------------------------------------------------------------------------------------ dm_device.register_and_allocate("debug_save_temp", "saved temp for debug", {nz,ny,nx,nens}, {"z","y","x","nens"} ); - dm_device.register_and_allocate("debug_save_rhod", "saved rhod for debug", {nz,ny,nx,nens}, {"z","y","x","nens"} ); dm_device.register_and_allocate("debug_save_rhov", "saved rhov for debug", {nz,ny,nx,nens}, {"z","y","x","nens"} ); dm_device.register_and_allocate("debug_save_rhoc", "saved rhoc for debug", {nz,ny,nx,nens}, {"z","y","x","nens"} ); dm_device.register_and_allocate("debug_save_rhoi", "saved rhoi for debug", {nz,ny,nx,nens}, {"z","y","x","nens"} ); + dm_device.register_and_allocate("debug_save_uvel", "saved uvel for debug", {nz,ny,nx,nens}, {"z","y","x","nens"} ); + dm_device.register_and_allocate("debug_save_wvel", "saved wvel for debug", {nz,ny,nx,nens}, {"z","y","x","nens"} ); auto debug_save_temp = dm_device.get("debug_save_temp"); - auto debug_save_rhod = dm_device.get("debug_save_rhod"); auto debug_save_rhov = dm_device.get("debug_save_rhov"); auto debug_save_rhoc = dm_device.get("debug_save_rhoc"); auto debug_save_rhoi = dm_device.get("debug_save_rhoi"); + auto debug_save_uvel = dm_device.get("debug_save_uvel"); + auto debug_save_wvel = dm_device.get("debug_save_wvel"); //------------------------------------------------------------------------------------------------ auto temp = dm_device.get("temp"); - auto rhod = dm_device.get("density_dry"); auto rhov = dm_device.get("water_vapor"); auto rhoc = dm_device.get("cloud_water"); auto rhoi = dm_device.get("ice"); + auto uvel = dm_device.get("uvel"); + auto wvel = dm_device.get("wvel"); //------------------------------------------------------------------------------------------------ parallel_for("copy data to saved debug variables", SimpleBounds<4>(nz,ny,nx,nens), YAKL_LAMBDA (int k, int j, int i, int iens) { debug_save_temp(k,j,i,iens) = temp(k,j,i,iens); - debug_save_rhod(k,j,i,iens) = rhod(k,j,i,iens); debug_save_rhov(k,j,i,iens) = rhov(k,j,i,iens); debug_save_rhoc(k,j,i,iens) = rhoc(k,j,i,iens); debug_save_rhoi(k,j,i,iens) = rhoi(k,j,i,iens); + debug_save_uvel(k,j,i,iens) = uvel(k,j,i,iens); + debug_save_wvel(k,j,i,iens) = wvel(k,j,i,iens); }); //------------------------------------------------------------------------------------------------ } @@ -48,81 +52,124 @@ void pam_debug_check_state( pam::PamCoupler &coupler, int id, int nstep ) { using yakl::c::parallel_for; using yakl::c::SimpleBounds; auto &dm_device = coupler.get_data_manager_device_readwrite(); - auto &dm_host = coupler.get_data_manager_host_readwrite(); + auto &dm_host = coupler.get_data_manager_host_readonly(); auto nx = coupler.get_option("crm_nx"); auto ny = coupler.get_option("crm_ny"); auto nz = coupler.get_option("crm_nz"); auto nens = coupler.get_option("ncrms"); - auto temp = dm_device.get("temp"); - auto rhod = dm_device.get("density_dry"); - auto rhov = dm_device.get("water_vapor"); - auto rhoc = dm_device.get("cloud_water"); - auto rhoi = dm_device.get("ice"); + auto temp = dm_device.get("temp"); + auto rhov = dm_device.get("water_vapor"); + auto rhoc = dm_device.get("cloud_water"); + auto rhoi = dm_device.get("ice"); + auto uvel = dm_device.get("uvel"); + auto wvel = dm_device.get("wvel"); auto debug_save_temp = dm_device.get("debug_save_temp"); - auto debug_save_rhod = dm_device.get("debug_save_rhod"); auto debug_save_rhov = dm_device.get("debug_save_rhov"); auto debug_save_rhoc = dm_device.get("debug_save_rhoc"); auto debug_save_rhoi = dm_device.get("debug_save_rhoi"); - real grav = 9.80616; - auto input_phis = dm_host.get("input_phis").createDeviceCopy(); + auto debug_save_uvel = dm_device.get("debug_save_uvel"); + auto debug_save_wvel = dm_device.get("debug_save_wvel"); auto lat = dm_host.get("latitude" ).createDeviceCopy(); auto lon = dm_host.get("longitude" ).createDeviceCopy(); + auto input_phis = dm_host.get("input_phis").createDeviceCopy(); + real grav = 9.80616; //------------------------------------------------------------------------------------------------ // Check for invalid values parallel_for("", SimpleBounds<4>(nz,ny,nx,nens), YAKL_LAMBDA (int k, int j, int i, int iens) { + auto phis = input_phis(iens)/grav; // Check for NaNs const auto is_nan_t_atm = isnan( temp(k,j,i,iens) ); - const auto is_nan_r_atm = isnan( rhod(k,j,i,iens) ); const auto is_nan_q_atm = isnan( rhov(k,j,i,iens) ); - if ( is_nan_t_atm || is_nan_r_atm || is_nan_q_atm ) { - auto phis = input_phis(iens)/grav; - printf("PAM-DEBUG nan-found - st:%3.3d id:%2.2d k:%3.3d i:%3.3d n:%3.3d y:%5.1f x:%5.1f ph:%6.1f -- t:%8.2g rd:%8.2g rv:%8.2g rc:%8.2g ri:%8.2g -- t:%8.2g rd:%8.2g rv:%8.2g rc:%8.2g ri:%8.2g \n", + if ( is_nan_t_atm || is_nan_q_atm ) { + printf("PAM-DEBUG nan-found - st:%3.3d id:%2.2d k:%3.3d i:%3.3d n:%3.3d y:%5.1f x:%5.1f ph:%6.1f -- t:%8.2g rv:%8.2g rc:%8.2g ri:%8.2g u:%8.2g w:%8.2g -- t:%8.2g rv:%8.2g rc:%8.2g ri:%8.2g u:%8.2g w:%8.2g \n", nstep,id,k,i,iens,lat(iens),lon(iens),phis, temp(k,j,i,iens), - rhod(k,j,i,iens), rhov(k,j,i,iens), rhoc(k,j,i,iens), rhoi(k,j,i,iens), + uvel(k,j,i,iens), + wvel(k,j,i,iens), debug_save_temp(k,j,i,iens), - debug_save_rhod(k,j,i,iens), debug_save_rhov(k,j,i,iens), debug_save_rhoc(k,j,i,iens), - debug_save_rhoi(k,j,i,iens) + debug_save_rhoi(k,j,i,iens), + debug_save_uvel(k,j,i,iens), + debug_save_wvel(k,j,i,iens) ); } // Check for negative values const auto is_neg_t_atm = temp(k,j,i,iens)<0; - const auto is_neg_r_atm = rhod(k,j,i,iens)<0; const auto is_neg_q_atm = rhov(k,j,i,iens)<0; - if ( is_neg_t_atm || is_neg_r_atm || is_neg_q_atm ) { - auto phis = input_phis(iens)/grav; - printf("PAM-DEBUG neg-found - st:%3.3d id:%2.2d k:%3.3d i:%3.3d n:%3.3d y:%5.1f x:%5.1f ph:%6.1f -- t:%8.2g rd:%8.2g rv:%8.2g rc:%8.2g ri:%8.2g -- t:%8.2g rd:%8.2g rv:%8.2g rc:%8.2g ri:%8.2g \n", + if ( is_neg_t_atm || is_neg_q_atm ) { + printf("PAM-DEBUG neg-found - st:%3.3d id:%2.2d k:%3.3d i:%3.3d n:%3.3d y:%5.1f x:%5.1f ph:%6.1f -- t:%8.2g rv:%8.2g rc:%8.2g ri:%8.2g u:%8.2g w:%8.2g -- t:%8.2g rv:%8.2g rc:%8.2g ri:%8.2g u:%8.2g w:%8.2g \n", nstep,id,k,i,iens,lat(iens),lon(iens),phis, temp(k,j,i,iens), - rhod(k,j,i,iens), rhov(k,j,i,iens), rhoc(k,j,i,iens), rhoi(k,j,i,iens), + uvel(k,j,i,iens), + wvel(k,j,i,iens), debug_save_temp(k,j,i,iens), - debug_save_rhod(k,j,i,iens), debug_save_rhov(k,j,i,iens), debug_save_rhoc(k,j,i,iens), - debug_save_rhoi(k,j,i,iens) + debug_save_rhoi(k,j,i,iens), + debug_save_uvel(k,j,i,iens), + debug_save_wvel(k,j,i,iens) + ); + } + // Check for low temperature + const auto is_low_t = temp(k,j,i,iens)<100; + if ( is_low_t ) { + printf("PAM-DEBUG low-T - st:%3.3d id:%2.2d k:%3.3d i:%3.3d n:%3.3d y:%5.1f x:%5.1f ph:%6.1f -- t:%8.2g rv:%8.2g rc:%8.2g ri:%8.2g u:%8.2g w:%8.2g -- t:%8.2g rv:%8.2g rc:%8.2g ri:%8.2g u:%8.2g w:%8.2g \n", + nstep,id,k,i,iens,lat(iens),lon(iens),phis, + temp(k,j,i,iens), + rhov(k,j,i,iens), + rhoc(k,j,i,iens), + rhoi(k,j,i,iens), + uvel(k,j,i,iens), + wvel(k,j,i,iens), + debug_save_temp(k,j,i,iens), + debug_save_rhov(k,j,i,iens), + debug_save_rhoc(k,j,i,iens), + debug_save_rhoi(k,j,i,iens), + debug_save_uvel(k,j,i,iens), + debug_save_wvel(k,j,i,iens) + ); + } + // Check for large vertical velocity + const auto is_large_pos_w = wvel(k,j,i,iens)> 40; + const auto is_large_neg_w = wvel(k,j,i,iens)<-40; + if ( is_large_pos_w || is_large_neg_w ) { + printf("PAM-DEBUG large-W - st:%3.3d id:%2.2d k:%3.3d i:%3.3d n:%3.3d y:%5.1f x:%5.1f ph:%6.1f -- t:%8.2g rv:%8.2g rc:%8.2g ri:%8.2g u:%8.2g w:%8.2g -- t:%8.2g rv:%8.2g rc:%8.2g ri:%8.2g u:%8.2g w:%8.2g \n", + nstep,id,k,i,iens,lat(iens),lon(iens),phis, + temp(k,j,i,iens), + rhov(k,j,i,iens), + rhoc(k,j,i,iens), + rhoi(k,j,i,iens), + uvel(k,j,i,iens), + wvel(k,j,i,iens), + debug_save_temp(k,j,i,iens), + debug_save_rhov(k,j,i,iens), + debug_save_rhoc(k,j,i,iens), + debug_save_rhoi(k,j,i,iens), + debug_save_uvel(k,j,i,iens), + debug_save_wvel(k,j,i,iens) ); } // update saved previous values debug_save_temp(k,j,i,iens) = temp(k,j,i,iens); - debug_save_rhod(k,j,i,iens) = rhod(k,j,i,iens); debug_save_rhov(k,j,i,iens) = rhov(k,j,i,iens); debug_save_rhoc(k,j,i,iens) = rhoc(k,j,i,iens); debug_save_rhoi(k,j,i,iens) = rhoi(k,j,i,iens); + debug_save_uvel(k,j,i,iens) = uvel(k,j,i,iens); + debug_save_wvel(k,j,i,iens) = wvel(k,j,i,iens); }); //------------------------------------------------------------------------------------------------ } // print the min and max of PAM state variables to help look for problems // void print_state_min_max( pam::PamCoupler &coupler, std::string id ) { - // auto &dm_device = coupler.get_data_manager_device_readwrite(); + // auto &dm_device = coupler.get_data_manager_device_readonly(); // auto nz = coupler.get_option("crm_nz"); // auto nx = coupler.get_option("crm_nx"); // auto ny = coupler.get_option("crm_ny"); @@ -184,18 +231,18 @@ void pam_debug_check_state( pam::PamCoupler &coupler, int id, int nstep ) { void pam_debug_print_state( pam::PamCoupler &coupler, int id ) { using yakl::c::parallel_for; using yakl::c::SimpleBounds; - auto &dm_device = coupler.get_data_manager_device_readwrite(); + auto &dm_device = coupler.get_data_manager_device_readonly(); auto nz = coupler.get_option("crm_nz"); auto nx = coupler.get_option("crm_nx"); auto ny = coupler.get_option("crm_ny"); auto nens = coupler.get_option("ncrms"); // auto pmid = coupler.compute_pressure_array(); // auto zmid = dm_device.get("vertical_midpoint_height" ); - auto temp = dm_device.get("temp"); - auto rho_v = dm_device.get("water_vapor"); - auto rho_c = dm_device.get("cloud_water"); - auto rho_d = dm_device.get("density_dry"); - auto rho_i = dm_device.get("ice"); + auto temp = dm_device.get("temp"); + auto rho_v = dm_device.get("water_vapor"); + auto rho_c = dm_device.get("cloud_water"); + auto rho_d = dm_device.get("density_dry"); + auto rho_i = dm_device.get("ice"); // parallel_for("", SimpleBounds<4>(nz,ny,nx,nens), YAKL_LAMBDA (int k, int j, int i, int iens) { parallel_for("pam_debug_print_state", SimpleBounds<2>(nz,nx), YAKL_LAMBDA (int k, int i) { int j = 0; From 0def774fe8d97cc5a890f48604062dcabea96635 Mon Sep 17 00:00:00 2001 From: Walter Hannah Date: Thu, 15 Feb 2024 17:19:56 -0500 Subject: [PATCH 029/451] add MMF_PAM_dyn_per_phys namelist parameter --- components/eam/bld/build-namelist | 3 +++ .../eam/bld/namelist_files/namelist_defaults_eam.xml | 2 +- components/eam/bld/namelist_files/namelist_definition.xml | 6 ++++++ components/eam/src/physics/cam/phys_control.F90 | 8 ++++++-- components/eam/src/physics/crm/crm_physics.F90 | 7 +++++++ 5 files changed, 23 insertions(+), 3 deletions(-) diff --git a/components/eam/bld/build-namelist b/components/eam/bld/build-namelist index 5a29d02bba48..c94bb5054d57 100755 --- a/components/eam/bld/build-namelist +++ b/components/eam/bld/build-namelist @@ -3885,6 +3885,9 @@ if ($cfg->get('use_MMF')) { # MMF CRM domain orientation add_default($nl, 'MMF_orientation_angle'); + + # PAM dynamics sub-stepping parameter + add_default($nl, 'MMF_PAM_dyn_per_phys'); } add_default($nl, 'do_aerocom_ind3'); diff --git a/components/eam/bld/namelist_files/namelist_defaults_eam.xml b/components/eam/bld/namelist_files/namelist_defaults_eam.xml index c5a61b500d21..4768f1799a4e 100755 --- a/components/eam/bld/namelist_files/namelist_defaults_eam.xml +++ b/components/eam/bld/namelist_files/namelist_defaults_eam.xml @@ -879,7 +879,7 @@ 0 .false. .true. - + 2 90.0 0.0 diff --git a/components/eam/bld/namelist_files/namelist_definition.xml b/components/eam/bld/namelist_files/namelist_definition.xml index fb5049df2110..dc63a488a6b6 100644 --- a/components/eam/bld/namelist_files/namelist_definition.xml +++ b/components/eam/bld/namelist_files/namelist_definition.xml @@ -4769,6 +4769,12 @@ Defaults: 3D CRM: 0 + +Number of PAM dycor calls per physics time step. +Default: 2 + + Wavenumber cutoff for filtered MMF variance transport. diff --git a/components/eam/src/physics/cam/phys_control.F90 b/components/eam/src/physics/cam/phys_control.F90 index c4d4b7fba7fa..41cd05e2714e 100644 --- a/components/eam/src/physics/cam/phys_control.F90 +++ b/components/eam/src/physics/cam/phys_control.F90 @@ -72,6 +72,7 @@ module phys_control logical :: use_crm_accel = .false. ! true => use MMF CRM mean-state acceleration (MSA) real(r8) :: crm_accel_factor = 2.D0 ! CRM acceleration factor logical :: crm_accel_uv = .true. ! true => apply MMF CRM MSA to momentum fields +integer :: MMF_PAM_dyn_per_phys = 2 ! PAM CRM dynamics steps per CRM physics steps logical :: use_subcol_microp = .false. ! if .true. then use sub-columns in microphysics @@ -229,7 +230,7 @@ subroutine phys_ctl_readnl(nlfile) eddy_scheme, microp_scheme, macrop_scheme, radiation_scheme, srf_flux_avg, & MMF_microphysics_scheme, MMF_orientation_angle, use_MMF, use_ECPP, & use_MMF_VT, MMF_VT_wn_max, use_MMF_ESMT, & - use_crm_accel, crm_accel_factor, crm_accel_uv, & + use_crm_accel, crm_accel_factor, crm_accel_uv, MMF_PAM_dyn_per_phys, & use_subcol_microp, atm_dep_flux, history_amwg, history_verbose, history_vdiag, & get_presc_aero_data,history_aerosol, history_aero_optics, & is_output_interactive_volc, & @@ -314,6 +315,7 @@ subroutine phys_ctl_readnl(nlfile) call mpibcast(use_crm_accel, 1 , mpilog, 0, mpicom) call mpibcast(crm_accel_factor, 1 , mpir8, 0, mpicom) call mpibcast(crm_accel_uv, 1 , mpilog, 0, mpicom) + call mpibcast(MMF_PAM_dyn_per_phys, 1 , mpiint, 0, mpicom) call mpibcast(use_subcol_microp, 1 , mpilog, 0, mpicom) call mpibcast(atm_dep_flux, 1 , mpilog, 0, mpicom) call mpibcast(history_amwg, 1 , mpilog, 0, mpicom) @@ -598,7 +600,7 @@ subroutine phys_getopts(deep_scheme_out, shallow_scheme_out, eddy_scheme_out, & prog_modal_aero_out, macrop_scheme_out, ideal_phys_option_out, & use_MMF_out, use_ECPP_out, MMF_microphysics_scheme_out, & MMF_orientation_angle_out, use_MMF_VT_out, MMF_VT_wn_max_out, use_MMF_ESMT_out, & - use_crm_accel_out, crm_accel_factor_out, crm_accel_uv_out, & + use_crm_accel_out, crm_accel_factor_out, crm_accel_uv_out, MMF_PAM_dyn_per_phys_out, & do_clubb_sgs_out, do_shoc_sgs_out, do_tms_out, state_debug_checks_out, & linearize_pbl_winds_out, export_gustiness_out, & do_aerocom_ind3_out, & @@ -641,6 +643,7 @@ subroutine phys_getopts(deep_scheme_out, shallow_scheme_out, eddy_scheme_out, & logical, intent(out), optional :: use_crm_accel_out real(r8), intent(out), optional :: crm_accel_factor_out logical, intent(out), optional :: crm_accel_uv_out + integer, intent(out), optional :: MMF_PAM_dyn_per_phys_out logical, intent(out), optional :: use_subcol_microp_out logical, intent(out), optional :: atm_dep_flux_out logical, intent(out), optional :: history_amwg_out @@ -745,6 +748,7 @@ subroutine phys_getopts(deep_scheme_out, shallow_scheme_out, eddy_scheme_out, & if ( present(use_crm_accel_out ) ) use_crm_accel_out = use_crm_accel if ( present(crm_accel_factor_out ) ) crm_accel_factor_out = crm_accel_factor if ( present(crm_accel_uv_out ) ) crm_accel_uv_out = crm_accel_uv + if ( present(MMF_PAM_dyn_per_phys ) ) MMF_PAM_dyn_per_phys_out = MMF_PAM_dyn_per_phys if ( present(use_subcol_microp_out ) ) use_subcol_microp_out = use_subcol_microp if ( present(macrop_scheme_out ) ) macrop_scheme_out = macrop_scheme diff --git a/components/eam/src/physics/crm/crm_physics.F90 b/components/eam/src/physics/crm/crm_physics.F90 index 66e5b57e28eb..31654e2bb7ac 100644 --- a/components/eam/src/physics/crm/crm_physics.F90 +++ b/components/eam/src/physics/crm/crm_physics.F90 @@ -620,6 +620,8 @@ subroutine crm_physics_tend(ztodt, state, tend, ptend, pbuf2d, cam_in, cam_out, logical :: use_MMF_VT_tmp ! flag for MMF variance transport (for Fortran CRM) logical :: use_MMF_ESMT_tmp ! flag for MMF scalar momentum transport (for Fortran CRM) integer :: MMF_VT_wn_max ! wavenumber cutoff for filtered variance transport + + integer :: MMF_PAM_dyn_per_phys ! PAM CRM dynamics steps per CRM physics steps real(r8) :: tmp_e_sat ! temporary saturation vapor pressure real(r8) :: tmp_q_sat ! temporary saturation specific humidity @@ -732,6 +734,9 @@ subroutine crm_physics_tend(ztodt, state, tend, ptend, pbuf2d, cam_in, cam_out, use_crm_accel = use_crm_accel_tmp crm_accel_uv = crm_accel_uv_tmp + ! PAM namelist options + call phys_getopts(MMF_PAM_dyn_per_phys_out = MMF_PAM_dyn_per_phys) + nstep = get_nstep() itim = pbuf_old_tim_idx() ! "Old" pbuf time index (what does all this mean?) @@ -1459,6 +1464,8 @@ subroutine crm_physics_tend(ztodt, state, tend, ptend, pbuf2d, cam_in, cam_out, call pam_set_option('enable_physics_tend_stats', .false. ) + call pam_set_option('crm_dyn_per_phys', MMF_PAM_dyn_per_phys ) + call pam_set_option('is_first_step', (nstep<=1) ) call pam_set_option('is_restart', (nsrest>0) ) call pam_set_option('am_i_root', masterproc ) From 9a25fc689c29fcbcf6725f09859fcb91c3c46a2d Mon Sep 17 00:00:00 2001 From: Walter Hannah Date: Thu, 15 Feb 2024 17:58:22 -0500 Subject: [PATCH 030/451] pam driver updates --- .../eam/src/physics/crm/pam/pam_driver.cpp | 18 ++++++++---------- 1 file changed, 8 insertions(+), 10 deletions(-) diff --git a/components/eam/src/physics/crm/pam/pam_driver.cpp b/components/eam/src/physics/crm/pam/pam_driver.cpp index f131bbd44f09..128974a856e4 100644 --- a/components/eam/src/physics/crm/pam/pam_driver.cpp +++ b/components/eam/src/physics/crm/pam/pam_driver.cpp @@ -24,7 +24,7 @@ #include "p3_f90.hpp" #include "pam_debug.h" -bool constexpr enable_check_state = false; +bool constexpr enable_check_state = true; extern "C" void pam_driver() { //------------------------------------------------------------------------------------------------ @@ -50,12 +50,6 @@ extern "C" void pam_driver() { //------------------------------------------------------------------------------------------------ // set various coupler options coupler.set_option("gcm_physics_dt",gcm_dt); - #ifdef MMF_PAM_DPP - // this is leftover from debugging, but it might still be useful for testing values of crm_per_phys - coupler.set_option("crm_per_phys",MMF_PAM_DPP); - #else - coupler.set_option("crm_per_phys",2); // # of PAM-C dynamics steps per physics - #endif coupler.set_option("sponge_num_layers",crm_nz*0.3); // depth of sponge layer coupler.set_option("sponge_time_scale",60); // minimum damping timescale at top coupler.set_option("crm_acceleration_ceaseflag",false); @@ -143,6 +137,9 @@ extern "C" void pam_driver() { dycore.declare_current_profile_as_hydrostatic(coupler,/*use_gcm_data=*/true); #endif + #ifdef MMF_DISABLE_DENSITY_RECALL + do_density_save_recall = false; + #endif //------------------------------------------------------------------------------------------------ //------------------------------------------------------------------------------------------------ //------------------------------------------------------------------------------------------------ @@ -168,8 +165,9 @@ extern "C" void pam_driver() { // run a PAM time step coupler.run_module( "apply_gcm_forcing_tendencies" , modules::apply_gcm_forcing_tendencies ); - coupler.run_module( "radiation" , [&] (pam::PamCoupler &coupler) {rad .timeStep(coupler);} ); if (enable_check_state) { pam_debug_check_state(coupler, 2, nstep); } + coupler.run_module( "radiation" , [&] (pam::PamCoupler &coupler) {rad .timeStep(coupler);} ); + if (enable_check_state) { pam_debug_check_state(coupler, 3, nstep); } // Dynamics if (enable_physics_tend_stats) { pam_statistics_save_state(coupler); } @@ -177,13 +175,13 @@ extern "C" void pam_driver() { coupler.run_module( "dycore", [&] (pam::PamCoupler &coupler) {dycore.timeStep(coupler);} ); if (do_density_save_recall) { pam_state_recall_dry_density(coupler); } if (enable_physics_tend_stats) { pam_statistics_aggregate_tendency(coupler,"dycor"); } - if (enable_check_state) { pam_debug_check_state(coupler, 3, nstep); } + if (enable_check_state) { pam_debug_check_state(coupler, 4, nstep); } // Sponge layer damping if (enable_physics_tend_stats) { pam_statistics_save_state(coupler); } coupler.run_module( "sponge_layer", modules::sponge_layer ); if (enable_physics_tend_stats) { pam_statistics_aggregate_tendency(coupler,"sponge"); } - if (enable_check_state) { pam_debug_check_state(coupler, 4, nstep); } + // if (enable_check_state) { pam_debug_check_state(coupler, 4, nstep); } // Apply hyperdiffusion to account for lack of horizontal mixing in SHOC pam_hyperdiffusion(coupler); From 0e93989e805d8ae7ecd59d2ffb955d0c10bcba30 Mon Sep 17 00:00:00 2001 From: Walter Hannah Date: Thu, 15 Feb 2024 17:59:05 -0500 Subject: [PATCH 031/451] add temporary MMF_PAM_HDT for debugging --- components/eam/src/physics/crm/pam/pam_hyperdiffusion.h | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/components/eam/src/physics/crm/pam/pam_hyperdiffusion.h b/components/eam/src/physics/crm/pam/pam_hyperdiffusion.h index 83dc83252c68..4452c583afe3 100644 --- a/components/eam/src/physics/crm/pam/pam_hyperdiffusion.h +++ b/components/eam/src/physics/crm/pam/pam_hyperdiffusion.h @@ -25,7 +25,11 @@ inline void pam_hyperdiffusion( pam::PamCoupler &coupler ) { auto uvel = dm_device.get("uvel" ); auto vvel = dm_device.get("vvel" ); //------------------------------------------------------------------------------------------------ + #ifdef MMF_PAM_HDT + real constexpr hd_timescale = MMF_PAM_HDT; // damping time scale [sec] + #else real constexpr hd_timescale = 10.0; // damping time scale [sec] + #endif //------------------------------------------------------------------------------------------------ real4d hd_temp("hd_temp",nz,ny,nx,nens); real4d hd_rhod("hd_rhod",nz,ny,nx,nens); From 047f01af0a3025d1b64d63afce65a90df2bededb Mon Sep 17 00:00:00 2001 From: Walter Hannah Date: Thu, 15 Feb 2024 17:59:38 -0500 Subject: [PATCH 032/451] Add temporary MMF_ALT_DENSITY_RECALL for debugging --- .../eam/src/physics/crm/pam/pam_state.h | 29 +++++++++++++++---- 1 file changed, 24 insertions(+), 5 deletions(-) diff --git a/components/eam/src/physics/crm/pam/pam_state.h b/components/eam/src/physics/crm/pam/pam_state.h index e8f6e4ab668a..34cc42a4a788 100644 --- a/components/eam/src/physics/crm/pam/pam_state.h +++ b/components/eam/src/physics/crm/pam/pam_state.h @@ -261,6 +261,7 @@ inline void pam_state_save_dry_density( pam::PamCoupler &coupler ) { inline void pam_state_recall_dry_density( pam::PamCoupler &coupler ) { using yakl::c::parallel_for; using yakl::c::SimpleBounds; + using yakl::atomicAdd; auto &dm_device = coupler.get_data_manager_device_readwrite(); auto nens = coupler.get_option("ncrms"); auto nz = coupler.get_option("crm_nz"); @@ -269,11 +270,29 @@ inline void pam_state_recall_dry_density( pam::PamCoupler &coupler ) { auto crm_rho_d = dm_device.get("density_dry"); auto tmp_rho_d = dm_device.get("density_dry_save"); //------------------------------------------------------------------------------------------------ - parallel_for( "Recall CRM dry density", - SimpleBounds<4>(nz,ny,nx,nens), - YAKL_LAMBDA (int k_crm, int j, int i, int iens) { - crm_rho_d(k_crm,j,i,iens) = tmp_rho_d(k_crm,j,i,iens); - }); + #ifdef MMF_ALT_DENSITY_RECALL + // initialize horizontal mean of previous CRM dry density + real2d old_hmean_rho_d("old_hmean_rho_d" ,nz,nens); + real2d new_hmean_rho_d("new_hmean_rho_d" ,nz,nens); + parallel_for(SimpleBounds<2>(nz,nens), YAKL_LAMBDA (int k, int iens) { + old_hmean_rho_d(k,iens) = 0; + new_hmean_rho_d(k,iens) = 0; + }); + real r_nx_ny = 1._fp/(nx*ny); // precompute reciprocal to avoid costly divisions + // calculate horizontal mean of previous CRM dry density + parallel_for(SimpleBounds<4>(nz,ny,nx,nens), YAKL_LAMBDA (int k, int j, int i, int iens) { + atomicAdd( old_hmean_rho_d(k,iens), tmp_rho_d(k,j,i,iens) * r_nx_ny ); + atomicAdd( new_hmean_rho_d(k,iens), crm_rho_d(k,j,i,iens) * r_nx_ny ); + }); + // replace horizontal mean dry density with prevoius value + parallel_for(SimpleBounds<4>(nz,ny,nx,nens), YAKL_LAMBDA (int k, int j, int i, int iens) { + crm_rho_d(k,j,i,iens) = crm_rho_d(k,j,i,iens) - new_hmean_rho_d(k,iens) + old_hmean_rho_d(k,iens); + }); + #else + parallel_for( "Recall CRM dry density",SimpleBounds<4>(nz,ny,nx,nens),YAKL_LAMBDA (int k_crm, int j, int i, int iens) { + crm_rho_d(k_crm,j,i,iens) = tmp_rho_d(k_crm,j,i,iens); + }); + #endif //------------------------------------------------------------------------------------------------ } From 37062fe4288ceccb7b759d8651fd490ca9cf26bc Mon Sep 17 00:00:00 2001 From: Matthew Hoffman Date: Fri, 16 Feb 2024 12:08:42 -0700 Subject: [PATCH 033/451] Move pressure calc so it uses consistent time levels of variables As previously ordered, the operations in evolving waterThickness and pressure variables were out of sync, resulting in the full hydropotential variable using the old waterThickness in the term calculating the water layer elevation head. This was causing restarts with the channel model to fail and channel hydropotential gradients to be inaccurate (unknown how significant that was). This commit moves the pressure calculation to eliminate this issue. Code comments explain in more detail. --- .../mode_forward/mpas_li_subglacial_hydro.F | 44 ++++++++++++------- 1 file changed, 29 insertions(+), 15 deletions(-) diff --git a/components/mpas-albany-landice/src/mode_forward/mpas_li_subglacial_hydro.F b/components/mpas-albany-landice/src/mode_forward/mpas_li_subglacial_hydro.F index ba5a359301e1..1878f4ecec7e 100644 --- a/components/mpas-albany-landice/src/mode_forward/mpas_li_subglacial_hydro.F +++ b/components/mpas-albany-landice/src/mode_forward/mpas_li_subglacial_hydro.F @@ -543,19 +543,6 @@ subroutine li_SGH_solve(domain, err) endif - ! ============= - ! Calculate pressure field - ! ============= - block => domain % blocklist - do while (associated(block)) - - call calc_pressure(block, err_tmp) - err = ior(err, err_tmp) - - block => block % next - end do - - ! ============= ! Update water layer thickness ! ============= @@ -592,6 +579,33 @@ subroutine li_SGH_solve(domain, err) block => block % next end do + ! ============= + ! Calculate pressure field + ! ============= + ! Note: In Bueler and van Pelt, pressure is updated before waterThickness + ! (step vii on page 1625). It does not matter which order they are calculated + ! because the update calculations are formulated on intermediate variables + ! such that neither depend directly on the other in the actual update. + ! However, calc_pressure also calculates the full hydropotential (including + ! the water thickness elevation head) which *is* a direct function of water thickness, + ! making the ordering of that calculation important. + ! Because the pressure variables calculated here are meant to be used on the + ! following timestep (forward Euler), the full hydropotential should be using + ! the updated waterThickness, not the old one. To achieve that, calc_pressure + ! is called here, after waterThickness has been updated. + ! Note that the full hydropotential is only used by the channel model, so this + ! ordering choice is only needed to support channels. Without it, runs with + ! channels would use an out of date waterThickness in the hydropotential and + ! do not restart correctly due to the order of operations mismatch. + block => domain % blocklist + do while (associated(block)) + + call calc_pressure(block, err_tmp) + err = ior(err, err_tmp) + + block => block % next + end do + ! ============= ! ============= @@ -972,11 +986,11 @@ subroutine calc_edge_quantities(block, err) ! calculate magnitude of gradient of Phi gradMagPhiEdge = sqrt(hydropotentialSlopeNormal**2 + hydropotentialSlopeTangent**2) - + ! calculate magnitude of gradient of hydropotentialBase gradMagPhiBaseEdge = sqrt(hydropotentialBaseSlopeNormal**2 +& hydropotentialBaseSlopeTangent**2) - + ! calculate effective conductivity on edges if (conduc_coeff_drowned > 0.0_RKIND) then ! Use a thickness weighted conductivity coeff. when water thickness exceeds bump height From 80aa98fed9bb23f7d69b70982d82f744d0cd58eb Mon Sep 17 00:00:00 2001 From: Matthew Hoffman Date: Fri, 16 Feb 2024 12:24:09 -0700 Subject: [PATCH 034/451] Initialize deltatSGH only on a cold start & make it a restart variable This is needed for BFB restarts with the till model. We never use the till model, but I identified this issue while debugging channel restarts. --- components/mpas-albany-landice/src/Registry.xml | 3 ++- .../src/mode_forward/mpas_li_subglacial_hydro.F | 15 ++++++++++++--- 2 files changed, 14 insertions(+), 4 deletions(-) diff --git a/components/mpas-albany-landice/src/Registry.xml b/components/mpas-albany-landice/src/Registry.xml index 1a8523d39138..a1ddaf744018 100644 --- a/components/mpas-albany-landice/src/Registry.xml +++ b/components/mpas-albany-landice/src/Registry.xml @@ -869,7 +869,8 @@ - + + diff --git a/components/mpas-albany-landice/src/mode_forward/mpas_li_subglacial_hydro.F b/components/mpas-albany-landice/src/mode_forward/mpas_li_subglacial_hydro.F index 1878f4ecec7e..cffd631f00b5 100644 --- a/components/mpas-albany-landice/src/mode_forward/mpas_li_subglacial_hydro.F +++ b/components/mpas-albany-landice/src/mode_forward/mpas_li_subglacial_hydro.F @@ -108,6 +108,7 @@ subroutine li_SGH_init(domain, err) integer, dimension(:), pointer :: cellMask real (kind=RKIND), pointer :: tillMax real (kind=RKIND), pointer :: rhoi, rhoo + logical, pointer :: config_do_restart real (kind=RKIND), pointer :: config_sea_level integer, pointer :: config_num_halos integer :: err_tmp @@ -138,6 +139,7 @@ subroutine li_SGH_init(domain, err) err = ior(err, 1) endif + call mpas_pool_get_config(liConfigs, 'config_do_restart', config_do_restart) call mpas_pool_get_config(liConfigs, 'config_SGH_till_max', tillMax) call mpas_pool_get_config(liConfigs, 'config_ice_density', rhoi) call mpas_pool_get_config(liConfigs, 'config_ocean_density', rhoo) @@ -152,9 +154,16 @@ subroutine li_SGH_init(domain, err) call mpas_pool_get_array(hydroPool, 'deltatSGH', deltatSGH) - ! Until init is done properly, make this tiny. It will be updated at the end of the first subcycle. - ! TODO: Set time step appropriately on first subcycle of init - deltatSGH = 1.0e-4_RKIND ! in seconds + if (.not. config_do_restart) then + ! On cold start, set initial timestep to a small value. + ! On a restart we will use the value from the last subcycle of the previous + ! master timestep to make restarts BFB. + ! Note the value here is only used for the first update of thetill model; + ! the sheet and channel models calculate the adaptive timestep, but that is not + ! available for the till model as the code is currently organized. + ! TODO: Move till update until after adaptive timestep has been set + deltatSGH = 1.0e-4_RKIND ! in seconds + endif ! Mask needs to be initialized for pressure calcs to be correct call li_calculate_mask(meshPool, velocityPool, geometryPool, err_tmp) From 6715104cd22fe9c8d238a801f53caa64d57e3f39 Mon Sep 17 00:00:00 2001 From: Courtney Shafer Date: Tue, 27 Jun 2023 14:58:40 -0600 Subject: [PATCH 035/451] Add SGH analysis members to global stats - Add "totalSubglacialWaterVolume" - Add "totalLakeVolume" - Add "totalBasalMeltInput" - Add "totalExternalWaterInput" - Add "totalChannelMelt" - Add "totalGLMeltFlux" - Add "totalTerrestrialMeltFlux" - Add "totalChannelGLMeltFlux" - Add "totalChannelTerrestrialMeltFlux" - Add "totalFlotationFraction" - Add "avgFlotationFraction" --- .../Registry_global_stats.xml | 37 ++++ .../analysis_members/mpas_li_global_stats.F | 159 +++++++++++++++++- 2 files changed, 191 insertions(+), 5 deletions(-) mode change 100644 => 100755 components/mpas-albany-landice/src/analysis_members/Registry_global_stats.xml mode change 100644 => 100755 components/mpas-albany-landice/src/analysis_members/mpas_li_global_stats.F diff --git a/components/mpas-albany-landice/src/analysis_members/Registry_global_stats.xml b/components/mpas-albany-landice/src/analysis_members/Registry_global_stats.xml old mode 100644 new mode 100755 index 622d33933cc0..74e5875d4dde --- a/components/mpas-albany-landice/src/analysis_members/Registry_global_stats.xml +++ b/components/mpas-albany-landice/src/analysis_members/Registry_global_stats.xml @@ -100,6 +100,43 @@ + + + + + + + + + + + + + domain % blocklist @@ -278,6 +326,7 @@ subroutine li_compute_global_stats(domain, memberName, timeLevel, err) call mpas_pool_get_subpool(block % structs, 'globalStatsAM', globalStatsAMPool) call mpas_pool_get_subpool(block % structs, 'geometry', geometryPool) call mpas_pool_get_subpool(block % structs, 'velocity', velocityPool) + call mpas_pool_get_subpool(block % structs, 'hydro', hydroPool) ! get values and arrays from standard pools call mpas_pool_get_dimension(block % dimensions, 'nCellsSolve', nCellsSolve) @@ -285,6 +334,7 @@ subroutine li_compute_global_stats(domain, memberName, timeLevel, err) call mpas_pool_get_array(meshPool, 'deltat', deltat) call mpas_pool_get_array(meshPool, 'areaCell', areaCell) call mpas_pool_get_array(meshPool, 'dvEdge', dvEdge) + call mpas_pool_get_array(meshPool, 'dcEdge', dcEdge) call mpas_pool_get_array(geometryPool, 'thickness', thickness) call mpas_pool_get_array(geometryPool, 'bedTopography', bedTopography) call mpas_pool_get_array(geometryPool, 'cellMask', cellMask) @@ -299,11 +349,21 @@ subroutine li_compute_global_stats(domain, memberName, timeLevel, err) call mpas_pool_get_array(velocityPool, 'surfaceSpeed', surfaceSpeed) call mpas_pool_get_array(velocityPool, 'basalSpeed', basalSpeed) call mpas_pool_get_array(velocityPool, 'fluxAcrossGroundingLine', fluxAcrossGroundingLine) + call mpas_pool_get_array(hydroPool, 'waterThickness', waterThickness) + call mpas_pool_get_array(hydroPool, 'basalMeltInput', basalMeltInput) + call mpas_pool_get_array(hydroPool, 'externalWaterInput', externalWaterInput) + call mpas_pool_get_array(hydroPool, 'channelMelt', channelMelt) + call mpas_pool_get_array(hydroPool, 'hydroMarineMarginMask', hydroMarineMarginMask) + call mpas_pool_get_array(hydroPool, 'hydroTerrestrialMarginMask', hydroTerrestrialMarginMask) + call mpas_pool_get_array(hydroPool, 'waterFlux', waterFlux) + call mpas_pool_get_array(hydroPool, 'channelDischarge', channelDischarge) + call mpas_pool_get_array(hydroPool, 'waterPressure', waterPressure) + ! loop over cells do iCell = 1,nCellsSolve - ! sums of ice area and volume over cells (m^2 and m^3) + ! sums of ice area and volume over cells (m^2 and m^3)i blockSumIceArea = blockSumIceArea + real(li_mask_is_ice_int(cellMask(iCell)),RKIND) & * areaCell(iCell) blockSumIceVolume = blockSumIceVolume + real(li_mask_is_ice_int(cellMask(iCell)),RKIND) & @@ -314,11 +374,13 @@ subroutine li_compute_global_stats(domain, memberName, timeLevel, err) blockSumGroundedIceArea = blockSumGroundedIceArea + real(li_mask_is_grounded_ice_int(cellMask(iCell)),RKIND) & * areaCell(iCell) + blockSumGroundedIceVolume = blockSumGroundedIceVolume + real(li_mask_is_grounded_ice_int(cellMask(iCell)),RKIND) & * areaCell(iCell) * thickness(iCell) blockSumFloatingIceArea = blockSumFloatingIceArea + real(li_mask_is_floating_ice_int(cellMask(iCell)),RKIND) & * areaCell(iCell) + blockSumFloatingIceVolume = blockSumFloatingIceVolume + real(li_mask_is_floating_ice_int(cellMask(iCell)),RKIND) & * areaCell(iCell) * thickness(iCell) @@ -335,6 +397,7 @@ subroutine li_compute_global_stats(domain, memberName, timeLevel, err) blockSumGroundedSfcMassBal = blockSumGroundedSfcMassBal + areaCell(iCell) * groundedSfcMassBalApplied(iCell) * scyr blockSumFloatingSfcMassBal = blockSumFloatingSfcMassBal + & (sfcMassBalApplied(iCell) - groundedSfcMassBalApplied(iCell)) * areaCell(iCell) * scyr + ! BMB (kg yr-1) blockSumBasalMassBal = blockSumBasalMassBal + areaCell(iCell) * basalMassBalApplied(iCell) * scyr blockSumGroundedBasalMassBal = blockSumGroundedBasalMassBal + areaCell(iCell) * groundedBasalMassBalApplied(iCell) * scyr @@ -362,13 +425,57 @@ subroutine li_compute_global_stats(domain, memberName, timeLevel, err) blockGLMigrationFlux = blockGLMigrationFlux + groundedToFloatingThickness(iCell) * areaCell(iCell) & * rhoi / (deltat / scyr) ! convert from m to kg/yr + !! Subglacial Hydrology Calculations + + ! Subglacial Water Volume + blockSumSubglacialWaterVolume = blockSumSubglacialWaterVolume + waterThickness(iCell) * areaCell(iCell) + + ! Basal melt input + blockSumBasalMeltInput = blockSumBasalMeltInput + basalMeltInput(iCell) * areaCell(iCell) + + ! External water input + blockSumExternalWaterInput = blockSumExternalWaterInput + externalWaterInput(iCell) * areaCell(iCell) + + ! Lake Volume + if (waterThickness(iCell) > bedBumpMax) then + blockSumLakeVolume = blockSumLakeVolume + (waterThickness(iCell) - bedBumpMax) * areaCell(iCell) + endif + + ! Lake Area + if (waterThickness(iCell) > bedBumpMax) then + blockSumLakeArea = blockSumLakeArea + areaCell(iCell) + endif + + ! Area-weighted flotation fraction for grounded ice + if (li_mask_is_grounded_ice(cellMask(iCell))) then + blockSumFlotationFraction = blockSumFlotationFraction + ( waterPressure(iCell) / rhow / gravity / thickness(iCell) ) * areaCell(iCell) + endif + + end do ! end loop over cells ! Loop over edges do iEdge = 1, nEdgesSolve + ! Flux across GL, units = kg/yr blockGLflux = blockGLflux + fluxAcrossGroundingLine(iEdge) * dvEdge(iEdge) & * scyr * rhoi ! convert from m^2/s to kg/yr + + ! Channel Melt + blockSumChannelMelt = blockSumChannelMelt + abs(channelMelt(iEdge) * dcEdge(iEdge)) + + ! Meltwater Flux across the grounding line + blockSumGLMeltFlux = blockSumGLMeltFlux + abs(hydroMarineMarginMask(iEdge) * waterFlux(iEdge) * dvEdge(iEdge) * rho_water) + + ! Meltwater Flux across terrestrial margins + blockSumTerrestrialMeltFlux = blockSumTerrestrialMeltFlux + abs(hydroTerrestrialMarginMask(iEdge) * waterFlux(iEdge) * dvEdge(iEdge) * rho_water) + + ! Meltwater Discharge in channels across grounding line + blockSumChannelGLMeltFlux = blockSumChannelGLMeltFlux + abs(hydroMarineMarginMask(iEdge) * channelDischarge(iEdge) * rho_water) + + ! Meltwater discharge in channels across terrestrial margin + blockSumChannelTerrestrialMeltFlux = blockSumChannelTerrestrialMeltFlux + abs( hydroTerrestrialMarginMask(iEdge) * channelDischarge(iEdge) * rho_water) + end do ! end loop over edges block => block % next @@ -409,7 +516,6 @@ subroutine li_compute_global_stats(domain, memberName, timeLevel, err) sums(7) = blockSumSfcMassBal sums(8) = blockSumGroundedSfcMassBal sums(9) = blockSumFloatingSfcMassBal - sums(10) = blockSumBasalMassBal sums(11) = blockSumGroundedBasalMassBal sums(12) = blockSumFloatingBasalMassBal @@ -418,7 +524,18 @@ subroutine li_compute_global_stats(domain, memberName, timeLevel, err) sums(15) = blockSumVAF sums(16) = blockGLflux sums(17) = blockGLMigrationflux - nVars = 17 + sums(18) = blockSumSubglacialWaterVolume + sums(19) = blockSumBasalMeltInput + sums(20) = blockSumExternalWaterInput + sums(21) = blockSumChannelMelt + sums(22) = blockSumLakeVolume + sums(23) = blockSumLakeArea + sums(24) = blockSumGLMeltFlux + sums(25) = blockSumTerrestrialMeltFlux + sums(26) = blockSumChannelGLMeltFlux + sums(27) = blockSumChannelTerrestrialMeltFlux + sums(28) = blockSumFlotationFraction + nVars = 28 call mpas_dmpar_sum_real_array(dminfo, nVars, sums(1:nVars), reductions(1:nVars)) @@ -447,6 +564,18 @@ subroutine li_compute_global_stats(domain, memberName, timeLevel, err) call mpas_pool_get_array(globalStatsAMPool, 'totalFaceMeltingFlux', totalFaceMeltingFlux) call mpas_pool_get_array(globalStatsAMPool, 'groundingLineFlux', groundingLineFlux) call mpas_pool_get_array(globalStatsAMPool, 'groundingLineMigrationFlux', groundingLineMigrationFlux) + call mpas_pool_get_array(globalStatsAMPool, 'totalSubglacialWaterVolume', totalSubglacialWaterVolume) + call mpas_pool_get_array(globalStatsAMPool, 'totalBasalMeltInput', totalBasalMeltInput) + call mpas_pool_get_array(globalStatsAMPool, 'totalExternalWaterInput', totalExternalWaterInput) + call mpas_pool_get_array(globalStatsAMPool, 'totalChannelMelt', totalChannelMelt) + call mpas_pool_get_array(globalStatsAMPool, 'totalLakeVolume', totalLakeVolume) + call mpas_pool_get_array(globalStatsAMPool, 'totalLakeArea', totalLakeArea) + call mpas_pool_get_array(globalStatsAMPool, 'totalGLMeltFlux',totalGLMeltFlux) + call mpas_pool_get_array(globalStatsAMPool, 'totalTerrestrialMeltFlux', totalTerrestrialMeltFlux) + call mpas_pool_get_array(globalStatsAMPool, 'totalChannelGLMeltFlux',totalChannelGLMeltFlux) + call mpas_pool_get_array(globalStatsAMPool, 'totalChannelTerrestrialMeltFlux', totalChannelTerrestrialMeltFlux) + call mpas_pool_get_array(globalStatsAMPool, 'totalFlotationFraction', totalFlotationFraction) + call mpas_pool_get_array(globalStatsAMPool, 'avgFlotationFraction', avgFlotationFraction) totalIceArea = reductions(1) totalIceVolume = reductions(2) @@ -465,6 +594,18 @@ subroutine li_compute_global_stats(domain, memberName, timeLevel, err) volumeAboveFloatation = reductions(15) groundingLineFlux = reductions(16) groundingLineMigrationFlux = reductions(17) + totalSubglacialWaterVolume = reductions(18) + totalBasalMeltInput = reductions(19) + totalExternalWaterInput = reductions(20) + totalChannelMelt = reductions(21) + totalLakevolume = reductions(22) + totalLakeArea = reductions(23) + totalGLMeltFlux = reductions(24) + totalTerrestrialMeltFlux = reductions(25) + totalChannelGLMeltFlux = reductions(26) + totalChannelTerrestrialMeltFlux = reductions(27) + totalFlotationFraction = reductions(28) + if (totalIceArea > 0.0_RKIND) then iceThicknessMean = totalIceVolume / totalIceArea @@ -473,17 +614,25 @@ subroutine li_compute_global_stats(domain, memberName, timeLevel, err) iceThicknessMean = 0.0_RKIND avgNetAccumulation = 0.0_RKIND endif + if (groundedIceArea > 0.0_RKIND) then avgGroundedBasalMelt = -1.0_RKIND * totalGroundedBasalMassBal / groundedIceArea / rhoi else avgGroundedBasalMelt = 0.0_RKIND endif + if (floatingIceArea > 0.0_RKIND) then avgSubshelfMelt = -1.0_RKIND * totalFloatingBasalMassBal / floatingIceArea / rhoi else avgSubshelfMelt = 0.0_RKIND endif + if (groundedIceArea > 0.0_RKIND) then + avgFlotationFraction = totalFlotationFraction / groundedIceArea + else + avgFlotationFraction = 0.0_RKIND + endif + block => block % next end do From f6f653c24192fbfbc2acf80419540f205db0131d Mon Sep 17 00:00:00 2001 From: Alexander Hager Date: Tue, 18 Jul 2023 18:22:18 -0600 Subject: [PATCH 036/451] Fix hydro globalStats bug - protect global stats calcs if SGH disabled Adds conditional statements in mpas_li_global_stats.F to prevent calculating SGH global stats when SGH model is deactivated. --- .../analysis_members/mpas_li_global_stats.F | 209 ++++++++++-------- 1 file changed, 112 insertions(+), 97 deletions(-) diff --git a/components/mpas-albany-landice/src/analysis_members/mpas_li_global_stats.F b/components/mpas-albany-landice/src/analysis_members/mpas_li_global_stats.F index eccc6ff36a00..2f9b75440ac4 100755 --- a/components/mpas-albany-landice/src/analysis_members/mpas_li_global_stats.F +++ b/components/mpas-albany-landice/src/analysis_members/mpas_li_global_stats.F @@ -183,6 +183,7 @@ subroutine li_compute_global_stats(domain, memberName, timeLevel, err) real (kind=RKIND), dimension(:), pointer :: basalSpeed real (kind=RKIND), dimension(:), pointer :: fluxAcrossGroundingLine real (kind=RKIND), dimension(:), pointer :: groundedToFloatingThickness + real (kind=RKIND), dimension(:), pointer :: waterThickness real (kind=RKIND), dimension(:), pointer :: basalMeltInput real (kind=RKIND), dimension(:), pointer :: externalWaterInput @@ -202,6 +203,7 @@ subroutine li_compute_global_stats(domain, memberName, timeLevel, err) real (kind=RKIND), pointer :: rhoi ! config_ice_density real (kind=RKIND), pointer :: rhow ! config_ocean_density real (kind=RKIND), pointer :: bedBumpMax ! config_SGH_bed_roughness_max + logical, pointer :: config_SGH ! Local counters integer :: k, iCell, iEdge, nCellsGrounded @@ -316,6 +318,7 @@ subroutine li_compute_global_stats(domain, memberName, timeLevel, err) call mpas_pool_get_config(liConfigs, 'config_ice_density', rhoi) call mpas_pool_get_config(liConfigs, 'config_ocean_density', rhow) call mpas_pool_get_config(liConfigs, 'config_SGH_bed_roughness_max', bedBumpMax) + call mpas_pool_get_config(liConfigs, 'config_SGH', config_SGH) ! loop over blocks block => domain % blocklist @@ -349,16 +352,17 @@ subroutine li_compute_global_stats(domain, memberName, timeLevel, err) call mpas_pool_get_array(velocityPool, 'surfaceSpeed', surfaceSpeed) call mpas_pool_get_array(velocityPool, 'basalSpeed', basalSpeed) call mpas_pool_get_array(velocityPool, 'fluxAcrossGroundingLine', fluxAcrossGroundingLine) - call mpas_pool_get_array(hydroPool, 'waterThickness', waterThickness) - call mpas_pool_get_array(hydroPool, 'basalMeltInput', basalMeltInput) - call mpas_pool_get_array(hydroPool, 'externalWaterInput', externalWaterInput) - call mpas_pool_get_array(hydroPool, 'channelMelt', channelMelt) - call mpas_pool_get_array(hydroPool, 'hydroMarineMarginMask', hydroMarineMarginMask) - call mpas_pool_get_array(hydroPool, 'hydroTerrestrialMarginMask', hydroTerrestrialMarginMask) - call mpas_pool_get_array(hydroPool, 'waterFlux', waterFlux) - call mpas_pool_get_array(hydroPool, 'channelDischarge', channelDischarge) - call mpas_pool_get_array(hydroPool, 'waterPressure', waterPressure) - + if (config_SGH) then + call mpas_pool_get_array(hydroPool, 'waterThickness', waterThickness) + call mpas_pool_get_array(hydroPool, 'basalMeltInput', basalMeltInput) + call mpas_pool_get_array(hydroPool, 'externalWaterInput', externalWaterInput) + call mpas_pool_get_array(hydroPool, 'channelMelt', channelMelt) + call mpas_pool_get_array(hydroPool, 'hydroMarineMarginMask', hydroMarineMarginMask) + call mpas_pool_get_array(hydroPool, 'hydroTerrestrialMarginMask', hydroTerrestrialMarginMask) + call mpas_pool_get_array(hydroPool, 'waterFlux', waterFlux) + call mpas_pool_get_array(hydroPool, 'channelDischarge', channelDischarge) + call mpas_pool_get_array(hydroPool, 'waterPressure', waterPressure) + endif ! loop over cells do iCell = 1,nCellsSolve @@ -426,58 +430,61 @@ subroutine li_compute_global_stats(domain, memberName, timeLevel, err) * rhoi / (deltat / scyr) ! convert from m to kg/yr !! Subglacial Hydrology Calculations - - ! Subglacial Water Volume - blockSumSubglacialWaterVolume = blockSumSubglacialWaterVolume + waterThickness(iCell) * areaCell(iCell) - - ! Basal melt input - blockSumBasalMeltInput = blockSumBasalMeltInput + basalMeltInput(iCell) * areaCell(iCell) - - ! External water input - blockSumExternalWaterInput = blockSumExternalWaterInput + externalWaterInput(iCell) * areaCell(iCell) - - ! Lake Volume - if (waterThickness(iCell) > bedBumpMax) then - blockSumLakeVolume = blockSumLakeVolume + (waterThickness(iCell) - bedBumpMax) * areaCell(iCell) - endif - - ! Lake Area - if (waterThickness(iCell) > bedBumpMax) then - blockSumLakeArea = blockSumLakeArea + areaCell(iCell) + if (config_SGH) then + + ! Subglacial Water Volume + blockSumSubglacialWaterVolume = blockSumSubglacialWaterVolume + waterThickness(iCell) * areaCell(iCell) + + ! Basal melt input + blockSumBasalMeltInput = blockSumBasalMeltInput + basalMeltInput(iCell) * areaCell(iCell) + + ! External water input + blockSumExternalWaterInput = blockSumExternalWaterInput + externalWaterInput(iCell) * areaCell(iCell) + + ! Lake Volume + if (waterThickness(iCell) > bedBumpMax) then + blockSumLakeVolume = blockSumLakeVolume + (waterThickness(iCell) - bedBumpMax) * areaCell(iCell) + endif + + ! Lake Area + if (waterThickness(iCell) > bedBumpMax) then + blockSumLakeArea = blockSumLakeArea + areaCell(iCell) + endif + + ! Area-weighted flotation fraction for grounded ice + if (li_mask_is_grounded_ice(cellMask(iCell))) then + blockSumFlotationFraction = blockSumFlotationFraction + ( waterPressure(iCell) / rhow / gravity / thickness(iCell) ) * areaCell(iCell) + endif endif - ! Area-weighted flotation fraction for grounded ice - if (li_mask_is_grounded_ice(cellMask(iCell))) then - blockSumFlotationFraction = blockSumFlotationFraction + ( waterPressure(iCell) / rhow / gravity / thickness(iCell) ) * areaCell(iCell) - endif - end do ! end loop over cells - ! Loop over edges - do iEdge = 1, nEdgesSolve - - ! Flux across GL, units = kg/yr - blockGLflux = blockGLflux + fluxAcrossGroundingLine(iEdge) * dvEdge(iEdge) & - * scyr * rhoi ! convert from m^2/s to kg/yr + if (config_SGH) then + ! Loop over edges + do iEdge = 1, nEdgesSolve - ! Channel Melt - blockSumChannelMelt = blockSumChannelMelt + abs(channelMelt(iEdge) * dcEdge(iEdge)) + ! Flux across GL, units = kg/yr + blockGLflux = blockGLflux + fluxAcrossGroundingLine(iEdge) * dvEdge(iEdge) & + * scyr * rhoi ! convert from m^2/s to kg/yr - ! Meltwater Flux across the grounding line - blockSumGLMeltFlux = blockSumGLMeltFlux + abs(hydroMarineMarginMask(iEdge) * waterFlux(iEdge) * dvEdge(iEdge) * rho_water) + ! Channel Melt + blockSumChannelMelt = blockSumChannelMelt + abs(channelMelt(iEdge) * dcEdge(iEdge)) - ! Meltwater Flux across terrestrial margins - blockSumTerrestrialMeltFlux = blockSumTerrestrialMeltFlux + abs(hydroTerrestrialMarginMask(iEdge) * waterFlux(iEdge) * dvEdge(iEdge) * rho_water) + ! Meltwater Flux across the grounding line + blockSumGLMeltFlux = blockSumGLMeltFlux + abs(hydroMarineMarginMask(iEdge) * waterFlux(iEdge) * dvEdge(iEdge) * rho_water) - ! Meltwater Discharge in channels across grounding line - blockSumChannelGLMeltFlux = blockSumChannelGLMeltFlux + abs(hydroMarineMarginMask(iEdge) * channelDischarge(iEdge) * rho_water) + ! Meltwater Flux across terrestrial margins + blockSumTerrestrialMeltFlux = blockSumTerrestrialMeltFlux + abs(hydroTerrestrialMarginMask(iEdge) * waterFlux(iEdge) * dvEdge(iEdge) * rho_water) - ! Meltwater discharge in channels across terrestrial margin - blockSumChannelTerrestrialMeltFlux = blockSumChannelTerrestrialMeltFlux + abs( hydroTerrestrialMarginMask(iEdge) * channelDischarge(iEdge) * rho_water) + ! Meltwater Discharge in channels across grounding line + blockSumChannelGLMeltFlux = blockSumChannelGLMeltFlux + abs(hydroMarineMarginMask(iEdge) * channelDischarge(iEdge) * rho_water) - end do ! end loop over edges + ! Meltwater discharge in channels across terrestrial margin + blockSumChannelTerrestrialMeltFlux = blockSumChannelTerrestrialMeltFlux + abs( hydroTerrestrialMarginMask(iEdge) * channelDischarge(iEdge) * rho_water) + end do ! end loop over edges + endif block => block % next end do ! end loop over blocks @@ -522,20 +529,24 @@ subroutine li_compute_global_stats(domain, memberName, timeLevel, err) sums(13) = blockSumCalvingFlux sums(14) = blockSumFaceMeltingFlux sums(15) = blockSumVAF - sums(16) = blockGLflux - sums(17) = blockGLMigrationflux - sums(18) = blockSumSubglacialWaterVolume - sums(19) = blockSumBasalMeltInput - sums(20) = blockSumExternalWaterInput - sums(21) = blockSumChannelMelt - sums(22) = blockSumLakeVolume - sums(23) = blockSumLakeArea - sums(24) = blockSumGLMeltFlux - sums(25) = blockSumTerrestrialMeltFlux - sums(26) = blockSumChannelGLMeltFlux - sums(27) = blockSumChannelTerrestrialMeltFlux - sums(28) = blockSumFlotationFraction - nVars = 28 + if (config_SGH) then + sums(16) = blockGLflux + sums(17) = blockGLMigrationflux + sums(18) = blockSumSubglacialWaterVolume + sums(19) = blockSumBasalMeltInput + sums(20) = blockSumExternalWaterInput + sums(21) = blockSumChannelMelt + sums(22) = blockSumLakeVolume + sums(23) = blockSumLakeArea + sums(24) = blockSumGLMeltFlux + sums(25) = blockSumTerrestrialMeltFlux + sums(26) = blockSumChannelGLMeltFlux + sums(27) = blockSumChannelTerrestrialMeltFlux + sums(28) = blockSumFlotationFraction + nVars = 28 + else + nVars = 15 + endif call mpas_dmpar_sum_real_array(dminfo, nVars, sums(1:nVars), reductions(1:nVars)) @@ -562,20 +573,22 @@ subroutine li_compute_global_stats(domain, memberName, timeLevel, err) call mpas_pool_get_array(globalStatsAMPool, 'avgSubshelfMelt', avgSubshelfMelt) call mpas_pool_get_array(globalStatsAMPool, 'totalCalvingFlux', totalCalvingFlux) call mpas_pool_get_array(globalStatsAMPool, 'totalFaceMeltingFlux', totalFaceMeltingFlux) - call mpas_pool_get_array(globalStatsAMPool, 'groundingLineFlux', groundingLineFlux) - call mpas_pool_get_array(globalStatsAMPool, 'groundingLineMigrationFlux', groundingLineMigrationFlux) - call mpas_pool_get_array(globalStatsAMPool, 'totalSubglacialWaterVolume', totalSubglacialWaterVolume) - call mpas_pool_get_array(globalStatsAMPool, 'totalBasalMeltInput', totalBasalMeltInput) - call mpas_pool_get_array(globalStatsAMPool, 'totalExternalWaterInput', totalExternalWaterInput) - call mpas_pool_get_array(globalStatsAMPool, 'totalChannelMelt', totalChannelMelt) - call mpas_pool_get_array(globalStatsAMPool, 'totalLakeVolume', totalLakeVolume) - call mpas_pool_get_array(globalStatsAMPool, 'totalLakeArea', totalLakeArea) - call mpas_pool_get_array(globalStatsAMPool, 'totalGLMeltFlux',totalGLMeltFlux) - call mpas_pool_get_array(globalStatsAMPool, 'totalTerrestrialMeltFlux', totalTerrestrialMeltFlux) - call mpas_pool_get_array(globalStatsAMPool, 'totalChannelGLMeltFlux',totalChannelGLMeltFlux) - call mpas_pool_get_array(globalStatsAMPool, 'totalChannelTerrestrialMeltFlux', totalChannelTerrestrialMeltFlux) - call mpas_pool_get_array(globalStatsAMPool, 'totalFlotationFraction', totalFlotationFraction) - call mpas_pool_get_array(globalStatsAMPool, 'avgFlotationFraction', avgFlotationFraction) + if (config_SGH) then + call mpas_pool_get_array(globalStatsAMPool, 'groundingLineFlux', groundingLineFlux) + call mpas_pool_get_array(globalStatsAMPool, 'groundingLineMigrationFlux', groundingLineMigrationFlux) + call mpas_pool_get_array(globalStatsAMPool, 'totalSubglacialWaterVolume', totalSubglacialWaterVolume) + call mpas_pool_get_array(globalStatsAMPool, 'totalBasalMeltInput', totalBasalMeltInput) + call mpas_pool_get_array(globalStatsAMPool, 'totalExternalWaterInput', totalExternalWaterInput) + call mpas_pool_get_array(globalStatsAMPool, 'totalChannelMelt', totalChannelMelt) + call mpas_pool_get_array(globalStatsAMPool, 'totalLakeVolume', totalLakeVolume) + call mpas_pool_get_array(globalStatsAMPool, 'totalLakeArea', totalLakeArea) + call mpas_pool_get_array(globalStatsAMPool, 'totalGLMeltFlux',totalGLMeltFlux) + call mpas_pool_get_array(globalStatsAMPool, 'totalTerrestrialMeltFlux', totalTerrestrialMeltFlux) + call mpas_pool_get_array(globalStatsAMPool, 'totalChannelGLMeltFlux',totalChannelGLMeltFlux) + call mpas_pool_get_array(globalStatsAMPool, 'totalChannelTerrestrialMeltFlux', totalChannelTerrestrialMeltFlux) + call mpas_pool_get_array(globalStatsAMPool, 'totalFlotationFraction', totalFlotationFraction) + call mpas_pool_get_array(globalStatsAMPool, 'avgFlotationFraction', avgFlotationFraction) + endif totalIceArea = reductions(1) totalIceVolume = reductions(2) @@ -592,20 +605,21 @@ subroutine li_compute_global_stats(domain, memberName, timeLevel, err) totalCalvingFlux = reductions(13) totalFaceMeltingFlux = reductions(14) volumeAboveFloatation = reductions(15) - groundingLineFlux = reductions(16) - groundingLineMigrationFlux = reductions(17) - totalSubglacialWaterVolume = reductions(18) - totalBasalMeltInput = reductions(19) - totalExternalWaterInput = reductions(20) - totalChannelMelt = reductions(21) - totalLakevolume = reductions(22) - totalLakeArea = reductions(23) - totalGLMeltFlux = reductions(24) - totalTerrestrialMeltFlux = reductions(25) - totalChannelGLMeltFlux = reductions(26) - totalChannelTerrestrialMeltFlux = reductions(27) - totalFlotationFraction = reductions(28) - + if (config_SGH) then + groundingLineFlux = reductions(16) + groundingLineMigrationFlux = reductions(17) + totalSubglacialWaterVolume = reductions(18) + totalBasalMeltInput = reductions(19) + totalExternalWaterInput = reductions(20) + totalChannelMelt = reductions(21) + totalLakevolume = reductions(22) + totalLakeArea = reductions(23) + totalGLMeltFlux = reductions(24) + totalTerrestrialMeltFlux = reductions(25) + totalChannelGLMeltFlux = reductions(26) + totalChannelTerrestrialMeltFlux = reductions(27) + totalFlotationFraction = reductions(28) + endif if (totalIceArea > 0.0_RKIND) then iceThicknessMean = totalIceVolume / totalIceArea @@ -626,11 +640,12 @@ subroutine li_compute_global_stats(domain, memberName, timeLevel, err) else avgSubshelfMelt = 0.0_RKIND endif - - if (groundedIceArea > 0.0_RKIND) then - avgFlotationFraction = totalFlotationFraction / groundedIceArea - else - avgFlotationFraction = 0.0_RKIND + if (config_SGH) then + if (groundedIceArea > 0.0_RKIND) then + avgFlotationFraction = totalFlotationFraction / groundedIceArea + else + avgFlotationFraction = 0.0_RKIND + endif endif block => block % next From d31ecb0dddd700b18134ed0d81e1bdc0bcaa472a Mon Sep 17 00:00:00 2001 From: Courtney Shafer Date: Tue, 11 Jul 2023 13:53:38 -0600 Subject: [PATCH 037/451] Add grounded ice mask to BasalMeltInput term The basalMeltInput term was including non-grounded ice in the calculation of the totalBasalMeltInput and giving wrong answers. The mask ensures that only basal melt occurring under grounded ice is considered. --- .../src/analysis_members/mpas_li_global_stats.F | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/components/mpas-albany-landice/src/analysis_members/mpas_li_global_stats.F b/components/mpas-albany-landice/src/analysis_members/mpas_li_global_stats.F index 2f9b75440ac4..0579ebe7cde7 100755 --- a/components/mpas-albany-landice/src/analysis_members/mpas_li_global_stats.F +++ b/components/mpas-albany-landice/src/analysis_members/mpas_li_global_stats.F @@ -436,7 +436,8 @@ subroutine li_compute_global_stats(domain, memberName, timeLevel, err) blockSumSubglacialWaterVolume = blockSumSubglacialWaterVolume + waterThickness(iCell) * areaCell(iCell) ! Basal melt input - blockSumBasalMeltInput = blockSumBasalMeltInput + basalMeltInput(iCell) * areaCell(iCell) + blockSumBasalMeltInput = blockSumBasalMeltInput + real(li_mask_is_grounded_ice_int(cellMask(iCell)),RKIND) * & + basalMeltInput(iCell) * areaCell(iCell) ! External water input blockSumExternalWaterInput = blockSumExternalWaterInput + externalWaterInput(iCell) * areaCell(iCell) @@ -648,6 +649,8 @@ subroutine li_compute_global_stats(domain, memberName, timeLevel, err) endif endif + + block => block % next end do From 48b1edb27c1a489d991b55ff4c8d78b68ded1bbe Mon Sep 17 00:00:00 2001 From: Matthew Hoffman Date: Sat, 17 Feb 2024 12:49:20 -0700 Subject: [PATCH 038/451] Update variable names and other code review edits --- .../Registry_global_stats.xml | 32 +++++------ .../analysis_members/mpas_li_global_stats.F | 55 +++++++++---------- 2 files changed, 42 insertions(+), 45 deletions(-) diff --git a/components/mpas-albany-landice/src/analysis_members/Registry_global_stats.xml b/components/mpas-albany-landice/src/analysis_members/Registry_global_stats.xml index 74e5875d4dde..50ad79158354 100755 --- a/components/mpas-albany-landice/src/analysis_members/Registry_global_stats.xml +++ b/components/mpas-albany-landice/src/analysis_members/Registry_global_stats.xml @@ -100,14 +100,15 @@ + - - - - - - - - + bedBumpMax) then blockSumLakeVolume = blockSumLakeVolume + (waterThickness(iCell) - bedBumpMax) * areaCell(iCell) endif - + ! Lake Area if (waterThickness(iCell) > bedBumpMax) then blockSumLakeArea = blockSumLakeArea + areaCell(iCell) @@ -581,13 +581,12 @@ subroutine li_compute_global_stats(domain, memberName, timeLevel, err) call mpas_pool_get_array(globalStatsAMPool, 'totalBasalMeltInput', totalBasalMeltInput) call mpas_pool_get_array(globalStatsAMPool, 'totalExternalWaterInput', totalExternalWaterInput) call mpas_pool_get_array(globalStatsAMPool, 'totalChannelMelt', totalChannelMelt) - call mpas_pool_get_array(globalStatsAMPool, 'totalLakeVolume', totalLakeVolume) - call mpas_pool_get_array(globalStatsAMPool, 'totalLakeArea', totalLakeArea) - call mpas_pool_get_array(globalStatsAMPool, 'totalGLMeltFlux',totalGLMeltFlux) - call mpas_pool_get_array(globalStatsAMPool, 'totalTerrestrialMeltFlux', totalTerrestrialMeltFlux) - call mpas_pool_get_array(globalStatsAMPool, 'totalChannelGLMeltFlux',totalChannelGLMeltFlux) - call mpas_pool_get_array(globalStatsAMPool, 'totalChannelTerrestrialMeltFlux', totalChannelTerrestrialMeltFlux) - call mpas_pool_get_array(globalStatsAMPool, 'totalFlotationFraction', totalFlotationFraction) + call mpas_pool_get_array(globalStatsAMPool, 'totalSubglacialLakeVolume', totalSubglacialLakeVolume) + call mpas_pool_get_array(globalStatsAMPool, 'totalSubglacialLakeArea', totalSubglacialLakeArea) + call mpas_pool_get_array(globalStatsAMPool, 'totalDistWaterFluxMarineMargin',totalDistWaterFluxMarineMargin) + call mpas_pool_get_array(globalStatsAMPool, 'totalDistWaterFluxTerrestrialMargin', totalDistWaterFluxTerrestrialMargin) + call mpas_pool_get_array(globalStatsAMPool, 'totalChnlWaterFluxMarineMargin',totalChnlWaterFluxMarineMargin) + call mpas_pool_get_array(globalStatsAMPool, 'totalChnlWaterFluxTerrestrialMargin', totalChnlWaterFluxTerrestrialMargin) call mpas_pool_get_array(globalStatsAMPool, 'avgFlotationFraction', avgFlotationFraction) endif @@ -613,12 +612,12 @@ subroutine li_compute_global_stats(domain, memberName, timeLevel, err) totalBasalMeltInput = reductions(19) totalExternalWaterInput = reductions(20) totalChannelMelt = reductions(21) - totalLakevolume = reductions(22) - totalLakeArea = reductions(23) - totalGLMeltFlux = reductions(24) - totalTerrestrialMeltFlux = reductions(25) - totalChannelGLMeltFlux = reductions(26) - totalChannelTerrestrialMeltFlux = reductions(27) + totalSubglacialLakeVolume = reductions(22) + totalSubglacialLakeArea = reductions(23) + totalDistWaterFluxMarineMargin = reductions(24) + totalDistWaterFluxTerrestrialMargin = reductions(25) + totalChnlWaterFluxMarineMargin = reductions(26) + totalChnlWaterFluxTerrestrialMargin = reductions(27) totalFlotationFraction = reductions(28) endif From 32f22cf5dfd67807a3becdf43e550f17bb918fb0 Mon Sep 17 00:00:00 2001 From: Matthew Hoffman Date: Sat, 17 Feb 2024 13:13:39 -0700 Subject: [PATCH 039/451] Correct flotation fraction globalStat to use ice density --- .../src/analysis_members/mpas_li_global_stats.F | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/components/mpas-albany-landice/src/analysis_members/mpas_li_global_stats.F b/components/mpas-albany-landice/src/analysis_members/mpas_li_global_stats.F index fae830930175..2e1d05cbc390 100755 --- a/components/mpas-albany-landice/src/analysis_members/mpas_li_global_stats.F +++ b/components/mpas-albany-landice/src/analysis_members/mpas_li_global_stats.F @@ -454,7 +454,7 @@ subroutine li_compute_global_stats(domain, memberName, timeLevel, err) ! Area-weighted flotation fraction for grounded ice if (li_mask_is_grounded_ice(cellMask(iCell))) then - blockSumFlotationFraction = blockSumFlotationFraction + ( waterPressure(iCell) / rhow / gravity / thickness(iCell) ) * areaCell(iCell) + blockSumFlotationFraction = blockSumFlotationFraction + ( waterPressure(iCell) / rhoi / gravity / thickness(iCell) ) * areaCell(iCell) endif endif From 087aace29c8a941147fdedc76a6f00808a9ff06c Mon Sep 17 00:00:00 2001 From: Matthew Hoffman Date: Wed, 21 Feb 2024 10:22:35 -0700 Subject: [PATCH 040/451] Improve synchronization of timesteps between MALI and SLM This PR updates handling of timesteps between MALI and the SLM in a few ways: * switch config_slm_coupling_interval to be an integer in years because we only allow integer year values * On init, check that config_adaptive_timestep_force_interval divides evenly into config_slm_coupling_interval * On init, check that restart interval is an even multiple of config_slm_coupling_interval * On a restart, calculate which SLM time level to use based on the elapsed time from the start of the original simulation and config_slm_coupling_interval and make sure these divide cleanly --- .../mpas-albany-landice/src/Registry.xml | 10 +- .../src/mode_forward/mpas_li_bedtopo.F | 232 ++++++++++++++---- 2 files changed, 188 insertions(+), 54 deletions(-) diff --git a/components/mpas-albany-landice/src/Registry.xml b/components/mpas-albany-landice/src/Registry.xml index c4cd6df05bb9..1c6e0f632985 100644 --- a/components/mpas-albany-landice/src/Registry.xml +++ b/components/mpas-albany-landice/src/Registry.xml @@ -145,13 +145,9 @@ description="Selection of the method for bedrock uplift calculation." possible_values="'none', 'data', 'sealevelmodel'" /> - - \brief Perform various checks on the SLM coupling interval setting +!> \author Matt Hoffman +!> \date Feb 2024 +!> \details +!> This routine checks that the SLM coupling interval is an even multiple +!> of the adaptive timestep force inverval and divides evenly into the +!> restart interval. It also checks that the coupling interval in the MALI +!> matches the value in the SLM namelist. +! +!----------------------------------------------------------------------- + + subroutine check_SLM_coupling_interval(slm_dt1, streamManager, err) + + use mpas_timekeeping + use mpas_stream_manager + use mpas_derived_types, only : MPAS_STREAM_PROPERTY_RECORD_INTV + + integer, intent (in) :: slm_dt1 + type (MPAS_streamManager_type), intent(inout) :: streamManager + integer, intent(out) :: err + + ! local variables + integer, pointer :: config_slm_coupling_interval + character (len=StrKIND), pointer :: config_adaptive_timestep_force_interval + type (MPAS_Time_Type) :: force_interval, restart_interval + character(len=StrKIND) :: restart_interval_str + integer :: YYYY, MM, DD, H, M, S ! time components + type (MPAS_stream_list_type), pointer :: stream_cursor + integer :: err_tmp + + err = 0 + + ! First, check consistency in coupling interval set up in MALI and SLM + call mpas_pool_get_config(liConfigs, "config_slm_coupling_interval", config_slm_coupling_interval) + if (config_slm_coupling_interval /= slm_dt1) then + call mpas_log_write("The coupling interval in MALI and SLM settings are inconsistent", MPAS_LOG_ERR) + err = ior(err,1) + endif + + ! Check that config_adaptive_timestep_force_interval divides evenly into config_slm_coupling_interval + call mpas_pool_get_config(liConfigs, "config_adaptive_timestep_force_interval", config_adaptive_timestep_force_interval) + ! Note: Using mpas_set_time instead of mpas_set_time_interval, even though this is an interval + ! This is because mpas_get_time_interval requires a reference time, which is not relevant + ! to these checks, and mpas_get_time allows us to get the component pieces that we want to check. + call mpas_set_time(force_interval, dateTimeString=config_adaptive_timestep_force_interval, ierr=err_tmp) + err = ior(err, err_tmp) + call mpas_get_time(force_interval, YYYY=YYYY, MM=MM, DD=DD, H=H, M=M, S=S) + if ((MM /= 0) .or. (DD /= 0) .or. (H /= 0) .or. (M /= 0) .or. (S /= 0)) then + call mpas_log_write("config_adaptive_timestep_force_interval currently not supported " // & + "to have nonzero values for months, days, hours, minutes, or seconds when sea-level model " // & + "is coupled. config_adaptive_timestep_force_interval=" //trim(config_adaptive_timestep_force_interval), MPAS_LOG_ERR) + ! Note: the actual requirement is that adapt dt force interval divides evenly into coupling interval + ! but that is tricky to check, and wanting anything but even years for that option is a rare use case. + err = ior(err, 1) + endif + ! Next check the number of years divides evenly into SLM coupling interval + if (mod(config_slm_coupling_interval, YYYY) /= 0) then + call mpas_log_write("config_adaptive_timestep_force_interval does not divide evenly into config_slm_coupling_interval" // & + "config_adaptive_timestep_force_interval=" // trim(config_adaptive_timestep_force_interval) // & + "; config_slm_coupling_interval=$i", MPAS_LOG_ERR, intArgs=(/config_slm_coupling_interval/)) + err = ior(err, 1) + endif + + ! Now check that restart interval is an even multiple of coupling interval + stream_cursor => streamManager % streams % head + do while (associated(stream_cursor)) + if ( trim(stream_cursor % name) == 'restart' .and. (stream_cursor % valid) ) then + call MPAS_stream_mgr_get_property(streamManager, 'restart', MPAS_STREAM_PROPERTY_RECORD_INTV, & + restart_interval_str, ierr=err_tmp) + err = ior(err, err_tmp) + + call mpas_log_write('restart interval is: ' //trim(restart_interval_str)) + + call mpas_set_time(restart_interval, dateTimeString=restart_interval_str, ierr=err_tmp) + err = ior(err, err_tmp) + call mpas_get_time(restart_interval, YYYY=YYYY, MM=MM, DD=DD, H=H, M=M, S=S) + if ((MM /= 0) .or. (DD /= 0) .or. (H /= 0) .or. (M /= 0) .or. (S /= 0)) then + call mpas_log_write("If Sea Level Model is active, restart output_interval cannot include " // & + "nonzero months, days, hours, minutes or seconds. restart output_interval=" // & + trim(restart_interval_str), MPAS_LOG_ERR) + endif + err = ior(err, 1) + + if (mod(YYYY, config_slm_coupling_interval) /= 0) then + call mpas_log_write("restart output_interval must be a multiple of config_slm_coupling_interval", MPAS_LOG_ERR) + err = ior(err, 1) + endif + + endif + enddo + + !-------------------------------------------------------------------- + end subroutine check_SLM_coupling_interval + + +!*********************************************************************** +! +! routine find_slm_restart_timestep +! +!> \brief Perform various checks on the SLM coupling interval setting +!> \author Matt Hoffman +!> \date Feb 2024 +!> \details +!> This routine checks that the SLM coupling interval is an even multiple +!> of the adaptive timestep force inverval and divides evenly into the +!> restart interval. It also checks that the coupling interval in the MALI +!> matches the value in the SLM namelist. +! +!----------------------------------------------------------------------- + + subroutine find_slm_restart_timestep(meshPool, slmTimeStep, err) + + use mpas_timekeeping + + type (mpas_pool_type), intent(in) :: meshPool !< mesh information + integer, intent(out) :: slmTimeStep + integer, intent(out) :: err + + ! local vars + integer, pointer :: config_slm_coupling_interval + character (len=StrKIND), pointer :: xtime, simulationStartTime + character (len=StrKIND) :: elapsed_time_str + type (MPAS_Time_Type) :: start_time, curr_time + type (MPAS_Time_Type) :: elapsed_time ! should be a time interval but not possible to get years that way + integer :: YYYY, MM, DD, H, M, S ! time components + integer :: err_tmp + + err = 0 + + slmTimeStep = -999 ! initialize to bad number + + call mpas_pool_get_config(liConfigs, "config_slm_coupling_interval", config_slm_coupling_interval) + + call mpas_pool_get_array(meshPool, 'simulationStartTime', simulationStartTime) + call mpas_pool_get_array(meshPool, 'xtime', xtime) + call mpas_set_time(start_time, dateTimeString=simulationStartTime, ierr=err_tmp) + err = ior(err, err_tmp) + call mpas_set_time(curr_time, dateTimeString=xtime, ierr=err_tmp) + err = ior(err, err_tmp) + call mpas_get_timeInterval(curr_time - start_time, start_time, timeString=elapsed_time_str, ierr=err_tmp) + err = ior(err, err_tmp) + + ! convert elapsed time string to its units. Using the intermediate string format because mpas_get_timeInterval doesn't return + ! years, and figuring out years from days depends on the calendar + call mpas_set_time(elapsed_time, dateTimeString=elapsed_time_str, ierr=err_tmp) + err = ior(err, err_tmp) + call mpas_get_time(elapsed_time, YYYY=YYYY, MM=MM, DD=DD, H=H, M=M, S=S) + + ! make sure the elapsed time is an even year + if ((MM /= 0) .or. (DD /= 0) .or. (H /= 0) .or. (M /= 0) .or. (S /= 0)) then + call mpas_log_write("Elapsed time since simulationStartTime include nonzero months, days, hours, minutes, " // & + "or seconds.", MPAS_LOG_ERR) + err = ior(err, 1) + endif + + if (mod(YYYY, config_slm_coupling_interval) == 0) then + ! We can restart cleanly + slmTimeStep = YYYY / config_slm_coupling_interval + else + call mpas_log_write("Elapsed years since simulationStartTime is not evenly divisible by config_slm_coupling_interval." // & + " Unable to restart Sea Level Model cleanly.", MPAS_LOG_ERR) + err = ior(err, 1) + endif + + !-------------------------------------------------------------------- + end subroutine find_slm_restart_timestep + !*********************************************************************** end module li_bedtopo From 55e579bfe8ade495499de24aa3922bc3f4c59989 Mon Sep 17 00:00:00 2001 From: Matthew Hoffman Date: Wed, 21 Feb 2024 12:19:20 -0700 Subject: [PATCH 041/451] Improve error handling, correct other usage of config_uplift_method Also add missing =>next pointer assignment to keep code from hanging --- .../src/mode_forward/mpas_li_bedtopo.F | 42 +++++++++++++------ .../src/mode_forward/mpas_li_core.F | 11 ++--- 2 files changed, 35 insertions(+), 18 deletions(-) diff --git a/components/mpas-albany-landice/src/mode_forward/mpas_li_bedtopo.F b/components/mpas-albany-landice/src/mode_forward/mpas_li_bedtopo.F index 9a5cc0ad32aa..b9a09ed5f9ce 100644 --- a/components/mpas-albany-landice/src/mode_forward/mpas_li_bedtopo.F +++ b/components/mpas-albany-landice/src/mode_forward/mpas_li_bedtopo.F @@ -115,6 +115,7 @@ subroutine li_bedtopo_init(domain, err) !----------------------------------------------------------------- character (len=StrKIND), pointer :: config_uplift_method + integer :: err_tmp ! No init is needed. err = 0 @@ -122,7 +123,12 @@ subroutine li_bedtopo_init(domain, err) call mpas_pool_get_config(liConfigs, 'config_uplift_method', config_uplift_method) if (trim(config_uplift_method)=='sealevelmodel') then ! initialize the 1D sea-level model if fresh start - call slmodel_init(domain, err) + call slmodel_init(domain, err_tmp) + err = ior(err, err_tmp) + + if (err /= 0) then + call mpas_log_write('Error in li_bedtopo_init', MPAS_LOG_ERR) + endif endif !-------------------------------------------------------------------- @@ -445,7 +451,7 @@ subroutine slmodel_init(domain, err) call check_SLM_coupling_interval(dtime, domain % streamManager, err_tmp) err = ior(err, err_tmp) if (err /= 0) then - return + call mpas_log_write("Error occurred in check_SLM_coupling_interval.", MPAS_LOG_ERR) endif ! Set Displacement variable for GATHERV command @@ -473,8 +479,10 @@ subroutine slmodel_init(domain, err) call find_slm_restart_timestep(meshPool, slmTimeStep, err_tmp) err = ior(err, err_tmp) - call mpas_log_write("Calling the SLM. SLM timestep $i", intArgs=(/slmTimeStep/)) - call slmodel_solve(slmTimeStep, domain) + if (err == 0) then + call mpas_log_write("Calling the SLM. SLM timestep $i", intArgs=(/slmTimeStep/)) + call slmodel_solve(slmTimeStep, domain) + endif else @@ -532,11 +540,13 @@ subroutine slmodel_init(domain, err) slmTimeStep = 0 ! series of calling SLM routines - call sl_call_readnl - call sl_solver_checkpoint(itersl, dtime) - call sl_timewindow(slmTimeStep) - call sl_solver_init(itersl, starttime, ismIceload, ismBedtopo, ismMask) - call sl_deallocate_array + if (err == 0) then + call sl_call_readnl + call sl_solver_checkpoint(itersl, dtime) + call sl_timewindow(slmTimeStep) + call sl_solver_init(itersl, starttime, ismIceload, ismBedtopo, ismMask) + call sl_deallocate_array + endif endif deallocate(globalArrayThickness) @@ -995,12 +1005,14 @@ subroutine check_SLM_coupling_interval(slm_dt1, streamManager, err) integer :: err_tmp err = 0 + err_tmp = 0 ! First, check consistency in coupling interval set up in MALI and SLM call mpas_pool_get_config(liConfigs, "config_slm_coupling_interval", config_slm_coupling_interval) if (config_slm_coupling_interval /= slm_dt1) then - call mpas_log_write("The coupling interval in MALI and SLM settings are inconsistent", MPAS_LOG_ERR) - err = ior(err,1) + call mpas_log_write("The coupling interval in MALI ($i) and SLM ($i) are inconsistent", MPAS_LOG_ERR, & + intArgs=(/config_slm_coupling_interval, slm_dt1/)) + err = ior(err, 1) endif ! Check that config_adaptive_timestep_force_interval divides evenly into config_slm_coupling_interval @@ -1015,6 +1027,7 @@ subroutine check_SLM_coupling_interval(slm_dt1, streamManager, err) call mpas_log_write("config_adaptive_timestep_force_interval currently not supported " // & "to have nonzero values for months, days, hours, minutes, or seconds when sea-level model " // & "is coupled. config_adaptive_timestep_force_interval=" //trim(config_adaptive_timestep_force_interval), MPAS_LOG_ERR) + call mpas_log_write(" MM=$i, DD=$i, H=$i, M=$i, S=$i", intArgs=(/MM, DD, H, M, S/)) ! Note: the actual requirement is that adapt dt force interval divides evenly into coupling interval ! but that is tricky to check, and wanting anything but even years for that option is a rare use case. err = ior(err, 1) @@ -1030,7 +1043,8 @@ subroutine check_SLM_coupling_interval(slm_dt1, streamManager, err) ! Now check that restart interval is an even multiple of coupling interval stream_cursor => streamManager % streams % head do while (associated(stream_cursor)) - if ( trim(stream_cursor % name) == 'restart' .and. (stream_cursor % valid) ) then + if ( trim(stream_cursor % name) == 'restart' .and. (stream_cursor % active_stream) ) then + call mpas_log_write("Checking restart interval against SLM coulping interval") call MPAS_stream_mgr_get_property(streamManager, 'restart', MPAS_STREAM_PROPERTY_RECORD_INTV, & restart_interval_str, ierr=err_tmp) err = ior(err, err_tmp) @@ -1044,8 +1058,8 @@ subroutine check_SLM_coupling_interval(slm_dt1, streamManager, err) call mpas_log_write("If Sea Level Model is active, restart output_interval cannot include " // & "nonzero months, days, hours, minutes or seconds. restart output_interval=" // & trim(restart_interval_str), MPAS_LOG_ERR) + err = ior(err, 1) endif - err = ior(err, 1) if (mod(YYYY, config_slm_coupling_interval) /= 0) then call mpas_log_write("restart output_interval must be a multiple of config_slm_coupling_interval", MPAS_LOG_ERR) @@ -1053,6 +1067,8 @@ subroutine check_SLM_coupling_interval(slm_dt1, streamManager, err) endif endif + + stream_cursor => stream_cursor % next enddo !-------------------------------------------------------------------- diff --git a/components/mpas-albany-landice/src/mode_forward/mpas_li_core.F b/components/mpas-albany-landice/src/mode_forward/mpas_li_core.F index 10ee1e94b305..146b4e36d805 100644 --- a/components/mpas-albany-landice/src/mode_forward/mpas_li_core.F +++ b/components/mpas-albany-landice/src/mode_forward/mpas_li_core.F @@ -338,8 +338,8 @@ function li_core_init(domain, startTimeStamp) result(err) ! === call li_velocity_external_write_albany_mesh(domain) - call mpas_dmpar_max_int(domain % dminfo, err, globalErr) ! Find out if any blocks got an error - if (globalErr > 0) then + call mpas_dmpar_max_int(domain % dminfo, abs(err), globalErr) ! Find out if any blocks got an error + if (globalErr /= 0) then call mpas_log_write("An error has occurred in li_core_init. Aborting...", MPAS_LOG_CRIT) endif @@ -1111,7 +1111,8 @@ subroutine li_simulation_clock_init(core_clock, configs, ierr) character (len=StrKIND), pointer :: config_dt ! MPAS LI-specific config option character (len=StrKIND), pointer :: config_adaptive_timestep_force_interval ! MPAS LI-specific config option character (len=StrKIND), pointer :: config_restart_timestamp_name - character (len=StrKIND), pointer :: config_uplift_method, config_slm_coupling_interval + character (len=StrKIND), pointer :: config_uplift_method + integer, pointer :: config_slm_coupling_interval character (len=StrKIND) :: restartTimeStamp !< string to be read from file integer, pointer :: config_year_digits integer :: err_tmp @@ -1197,7 +1198,7 @@ subroutine li_simulation_clock_init(core_clock, configs, ierr) ! Set up the coupling time interval if MALI is coupled to sea-level model if (trim(config_uplift_method) == "sealevelmodel") then - call mpas_set_timeInterval(slm_coupling_interval, timeString=config_slm_coupling_interval, ierr=err_tmp) + call mpas_set_timeInterval(slm_coupling_interval, YY=config_slm_coupling_interval, ierr=err_tmp) ierr = ior(ierr,err_tmp) call mpas_add_clock_alarm(core_clock, 'slmCouplingInterval', alarmTime=startTime, & alarmTimeInterval=slm_coupling_interval, ierr=err_tmp) @@ -1210,7 +1211,7 @@ subroutine li_simulation_clock_init(core_clock, configs, ierr) endif ! === error check - if (ierr > 0) then + if (ierr /= 0) then call mpas_log_write("An error has occurred in li_simulation_clock_init.", MPAS_LOG_ERR) endif From 32ff9f8e24f32a2b4a768d526397751e41f25357 Mon Sep 17 00:00:00 2001 From: Matthew Hoffman Date: Wed, 21 Feb 2024 13:17:55 -0700 Subject: [PATCH 042/451] Update checks using interval division Trying to cast intervals into dateTimeStrings did not work. --- .../src/mode_forward/mpas_li_bedtopo.F | 75 ++++++++----------- 1 file changed, 33 insertions(+), 42 deletions(-) diff --git a/components/mpas-albany-landice/src/mode_forward/mpas_li_bedtopo.F b/components/mpas-albany-landice/src/mode_forward/mpas_li_bedtopo.F index b9a09ed5f9ce..dbdcb43d3aa5 100644 --- a/components/mpas-albany-landice/src/mode_forward/mpas_li_bedtopo.F +++ b/components/mpas-albany-landice/src/mode_forward/mpas_li_bedtopo.F @@ -448,7 +448,7 @@ subroutine slmodel_init(domain, err) call sl_drive_readnl(itersl, dtime, starttime) !SLM subroutine ! First, check consistency in coupling interval set up in MALI and SLM - call check_SLM_coupling_interval(dtime, domain % streamManager, err_tmp) + call check_SLM_coupling_interval(dtime, meshPool, domain % streamManager, err_tmp) err = ior(err, err_tmp) if (err /= 0) then call mpas_log_write("Error occurred in check_SLM_coupling_interval.", MPAS_LOG_ERR) @@ -985,23 +985,27 @@ end subroutine check ! !----------------------------------------------------------------------- - subroutine check_SLM_coupling_interval(slm_dt1, streamManager, err) + subroutine check_SLM_coupling_interval(slm_dt1, meshPool, streamManager, err) use mpas_timekeeping use mpas_stream_manager use mpas_derived_types, only : MPAS_STREAM_PROPERTY_RECORD_INTV integer, intent (in) :: slm_dt1 + type (mpas_pool_type), intent(in) :: meshPool !< mesh information type (MPAS_streamManager_type), intent(inout) :: streamManager integer, intent(out) :: err ! local variables integer, pointer :: config_slm_coupling_interval character (len=StrKIND), pointer :: config_adaptive_timestep_force_interval - type (MPAS_Time_Type) :: force_interval, restart_interval - character(len=StrKIND) :: restart_interval_str + type (MPAS_TimeInterval_Type) :: coupling_interval, force_interval, restart_interval, zero_interval + type (MPAS_Time_Type) :: start_time + character (len=StrKIND), pointer :: simulationStartTime integer :: YYYY, MM, DD, H, M, S ! time components type (MPAS_stream_list_type), pointer :: stream_cursor + integer (kind=I8KIND) :: n_intervals + type (MPAS_TimeInterval_type) :: remainder integer :: err_tmp err = 0 @@ -1015,28 +1019,26 @@ subroutine check_SLM_coupling_interval(slm_dt1, streamManager, err) err = ior(err, 1) endif + ! define zero interval for comparing against below + call mpas_set_timeInterval(zero_interval, dt = 0.0_RKIND) + ! get start time as a reference time + call mpas_pool_get_array(meshPool, 'simulationStartTime', simulationStartTime) + call mpas_set_time(start_time, dateTimeString=simulationStartTime) + ! define SLM coupling interval as a timeInterval type + call mpas_set_timeInterval(coupling_interval, YY=config_slm_coupling_interval, MM=0, DD=0, H=0, M=0, S=0, ierr=err_tmp) + err = ior(err, err_tmp) + ! Check that config_adaptive_timestep_force_interval divides evenly into config_slm_coupling_interval call mpas_pool_get_config(liConfigs, "config_adaptive_timestep_force_interval", config_adaptive_timestep_force_interval) - ! Note: Using mpas_set_time instead of mpas_set_time_interval, even though this is an interval - ! This is because mpas_get_time_interval requires a reference time, which is not relevant - ! to these checks, and mpas_get_time allows us to get the component pieces that we want to check. - call mpas_set_time(force_interval, dateTimeString=config_adaptive_timestep_force_interval, ierr=err_tmp) + call mpas_set_timeInterval(force_interval, timeString=config_adaptive_timestep_force_interval, ierr=err_tmp) err = ior(err, err_tmp) - call mpas_get_time(force_interval, YYYY=YYYY, MM=MM, DD=DD, H=H, M=M, S=S) - if ((MM /= 0) .or. (DD /= 0) .or. (H /= 0) .or. (M /= 0) .or. (S /= 0)) then - call mpas_log_write("config_adaptive_timestep_force_interval currently not supported " // & - "to have nonzero values for months, days, hours, minutes, or seconds when sea-level model " // & - "is coupled. config_adaptive_timestep_force_interval=" //trim(config_adaptive_timestep_force_interval), MPAS_LOG_ERR) - call mpas_log_write(" MM=$i, DD=$i, H=$i, M=$i, S=$i", intArgs=(/MM, DD, H, M, S/)) - ! Note: the actual requirement is that adapt dt force interval divides evenly into coupling interval - ! but that is tricky to check, and wanting anything but even years for that option is a rare use case. - err = ior(err, 1) - endif - ! Next check the number of years divides evenly into SLM coupling interval - if (mod(config_slm_coupling_interval, YYYY) /= 0) then - call mpas_log_write("config_adaptive_timestep_force_interval does not divide evenly into config_slm_coupling_interval" // & - "config_adaptive_timestep_force_interval=" // trim(config_adaptive_timestep_force_interval) // & - "; config_slm_coupling_interval=$i", MPAS_LOG_ERR, intArgs=(/config_slm_coupling_interval/)) + call mpas_interval_division(start_time, coupling_interval, force_interval, n_intervals, remainder) + if (remainder .EQ. zero_interval) then + call mpas_log_write("config_adaptive_timestep_force_interval divides into config_slm_coupling_interval $i times " // & + "with no remainder - check passes", intArgs=(/int(n_intervals)/)) + else + call mpas_log_write("config_adaptive_timestep_force_interval divides into config_slm_coupling_interval $i times " // & + "with nonzero remainder", MPAS_LOG_ERR, intArgs=(/int(n_intervals)/)) err = ior(err, 1) endif @@ -1045,27 +1047,16 @@ subroutine check_SLM_coupling_interval(slm_dt1, streamManager, err) do while (associated(stream_cursor)) if ( trim(stream_cursor % name) == 'restart' .and. (stream_cursor % active_stream) ) then call mpas_log_write("Checking restart interval against SLM coulping interval") - call MPAS_stream_mgr_get_property(streamManager, 'restart', MPAS_STREAM_PROPERTY_RECORD_INTV, & - restart_interval_str, ierr=err_tmp) - err = ior(err, err_tmp) - - call mpas_log_write('restart interval is: ' //trim(restart_interval_str)) - - call mpas_set_time(restart_interval, dateTimeString=restart_interval_str, ierr=err_tmp) + restart_interval = MPAS_stream_mgr_get_stream_interval(streamManager, 'restart', MPAS_STREAM_OUTPUT, ierr=err_tmp) err = ior(err, err_tmp) - call mpas_get_time(restart_interval, YYYY=YYYY, MM=MM, DD=DD, H=H, M=M, S=S) - if ((MM /= 0) .or. (DD /= 0) .or. (H /= 0) .or. (M /= 0) .or. (S /= 0)) then - call mpas_log_write("If Sea Level Model is active, restart output_interval cannot include " // & - "nonzero months, days, hours, minutes or seconds. restart output_interval=" // & - trim(restart_interval_str), MPAS_LOG_ERR) - err = ior(err, 1) + call mpas_interval_division(start_time, restart_interval, coupling_interval, n_intervals, remainder) + if (remainder .EQ. zero_interval) then + call mpas_log_write("config_slm_coupling_interval divides into restart interval $i times " // & + "with no remainder - check passes", intArgs=(/int(n_intervals)/)) + else + call mpas_log_write("config_slm_coupling_interval divides into restart interval $i times " // & + "with nonzero remainder", MPAS_LOG_ERR, intArgs=(/int(n_intervals)/)) endif - - if (mod(YYYY, config_slm_coupling_interval) /= 0) then - call mpas_log_write("restart output_interval must be a multiple of config_slm_coupling_interval", MPAS_LOG_ERR) - err = ior(err, 1) - endif - endif stream_cursor => stream_cursor % next From 869f944989932fb7b33822a2735fd70d5cf61cae Mon Sep 17 00:00:00 2001 From: Matthew Hoffman Date: Wed, 21 Feb 2024 13:35:41 -0700 Subject: [PATCH 043/451] Adjust check if adaptive dt is on or not --- .../src/mode_forward/mpas_li_bedtopo.F | 50 ++++++++++++++----- 1 file changed, 37 insertions(+), 13 deletions(-) diff --git a/components/mpas-albany-landice/src/mode_forward/mpas_li_bedtopo.F b/components/mpas-albany-landice/src/mode_forward/mpas_li_bedtopo.F index dbdcb43d3aa5..facbf8e9d6d7 100644 --- a/components/mpas-albany-landice/src/mode_forward/mpas_li_bedtopo.F +++ b/components/mpas-albany-landice/src/mode_forward/mpas_li_bedtopo.F @@ -998,8 +998,9 @@ subroutine check_SLM_coupling_interval(slm_dt1, meshPool, streamManager, err) ! local variables integer, pointer :: config_slm_coupling_interval - character (len=StrKIND), pointer :: config_adaptive_timestep_force_interval - type (MPAS_TimeInterval_Type) :: coupling_interval, force_interval, restart_interval, zero_interval + logical, pointer :: config_adaptive_timestep + character (len=StrKIND), pointer :: config_adaptive_timestep_force_interval, config_dt + type (MPAS_TimeInterval_Type) :: coupling_interval, force_interval, dt_interval, restart_interval, zero_interval type (MPAS_Time_Type) :: start_time character (len=StrKIND), pointer :: simulationStartTime integer :: YYYY, MM, DD, H, M, S ! time components @@ -1011,10 +1012,15 @@ subroutine check_SLM_coupling_interval(slm_dt1, meshPool, streamManager, err) err = 0 err_tmp = 0 + call mpas_log_write("") + call mpas_log_write("-- Checking consistency of config_slm_coupling_interval and other settings --") + ! First, check consistency in coupling interval set up in MALI and SLM call mpas_pool_get_config(liConfigs, "config_slm_coupling_interval", config_slm_coupling_interval) - if (config_slm_coupling_interval /= slm_dt1) then - call mpas_log_write("The coupling interval in MALI ($i) and SLM ($i) are inconsistent", MPAS_LOG_ERR, & + if (config_slm_coupling_interval == slm_dt1) then + call mpas_log_write("The coupling interval in MALI ($i yr) and SLM ($i yr) are consistent - check passes") + else + call mpas_log_write("The coupling interval in MALI ($i yr) and SLM ($i yr) are inconsistent", MPAS_LOG_ERR, & intArgs=(/config_slm_coupling_interval, slm_dt1/)) err = ior(err, 1) endif @@ -1028,18 +1034,35 @@ subroutine check_SLM_coupling_interval(slm_dt1, meshPool, streamManager, err) call mpas_set_timeInterval(coupling_interval, YY=config_slm_coupling_interval, MM=0, DD=0, H=0, M=0, S=0, ierr=err_tmp) err = ior(err, err_tmp) - ! Check that config_adaptive_timestep_force_interval divides evenly into config_slm_coupling_interval - call mpas_pool_get_config(liConfigs, "config_adaptive_timestep_force_interval", config_adaptive_timestep_force_interval) - call mpas_set_timeInterval(force_interval, timeString=config_adaptive_timestep_force_interval, ierr=err_tmp) - err = ior(err, err_tmp) - call mpas_interval_division(start_time, coupling_interval, force_interval, n_intervals, remainder) - if (remainder .EQ. zero_interval) then - call mpas_log_write("config_adaptive_timestep_force_interval divides into config_slm_coupling_interval $i times " // & + call mpas_pool_get_config(liConfigs, "config_adaptive_timestep", config_adaptive_timestep) + if (config_adaptive_timestep) then + ! for adaptive dt, check that config_adaptive_timestep_force_interval divides evenly into config_slm_coupling_interval + call mpas_pool_get_config(liConfigs, "config_adaptive_timestep_force_interval", config_adaptive_timestep_force_interval) + call mpas_set_timeInterval(force_interval, timeString=config_adaptive_timestep_force_interval, ierr=err_tmp) + err = ior(err, err_tmp) + call mpas_interval_division(start_time, coupling_interval, force_interval, n_intervals, remainder) + if (remainder .EQ. zero_interval) then + call mpas_log_write("config_adaptive_timestep_force_interval divides into config_slm_coupling_interval $i times " // & "with no remainder - check passes", intArgs=(/int(n_intervals)/)) + else + call mpas_log_write("config_adaptive_timestep_force_interval divides into config_slm_coupling_interval $i times " // & + "with nonzero remainder", MPAS_LOG_ERR, intArgs=(/int(n_intervals)/)) + err = ior(err, 1) + endif else - call mpas_log_write("config_adaptive_timestep_force_interval divides into config_slm_coupling_interval $i times " // & + ! For fixed dt, check that dt divides evenly into config_slm_coupling_interval + call mpas_pool_get_config(liConfigs, "config_dt", config_dt) + call mpas_set_timeInterval(dt_interval, timeString=config_dt, ierr=err_tmp) + err = ior(err, err_tmp) + call mpas_interval_division(start_time, coupling_interval, dt_interval, n_intervals, remainder) + if (remainder .EQ. zero_interval) then + call mpas_log_write("config_dt divides into config_slm_coupling_interval $i times " // & + "with no remainder - check passes", intArgs=(/int(n_intervals)/)) + else + call mpas_log_write("config_dt divides into config_slm_coupling_interval $i times " // & "with nonzero remainder", MPAS_LOG_ERR, intArgs=(/int(n_intervals)/)) - err = ior(err, 1) + err = ior(err, 1) + endif endif ! Now check that restart interval is an even multiple of coupling interval @@ -1061,6 +1084,7 @@ subroutine check_SLM_coupling_interval(slm_dt1, meshPool, streamManager, err) stream_cursor => stream_cursor % next enddo + call mpas_log_write("") !-------------------------------------------------------------------- end subroutine check_SLM_coupling_interval From a4d0d68995bcc4ca94d12c4b780640e874a3ad66 Mon Sep 17 00:00:00 2001 From: Matthew Hoffman Date: Wed, 21 Feb 2024 13:48:16 -0700 Subject: [PATCH 044/451] Update restart check to also use time interval division --- .../src/mode_forward/mpas_li_bedtopo.F | 43 ++++++++----------- 1 file changed, 18 insertions(+), 25 deletions(-) diff --git a/components/mpas-albany-landice/src/mode_forward/mpas_li_bedtopo.F b/components/mpas-albany-landice/src/mode_forward/mpas_li_bedtopo.F index facbf8e9d6d7..24fee4d71a22 100644 --- a/components/mpas-albany-landice/src/mode_forward/mpas_li_bedtopo.F +++ b/components/mpas-albany-landice/src/mode_forward/mpas_li_bedtopo.F @@ -1116,17 +1116,20 @@ subroutine find_slm_restart_timestep(meshPool, slmTimeStep, err) ! local vars integer, pointer :: config_slm_coupling_interval character (len=StrKIND), pointer :: xtime, simulationStartTime - character (len=StrKIND) :: elapsed_time_str + type (MPAS_TimeInterval_Type) :: coupling_interval, zero_interval type (MPAS_Time_Type) :: start_time, curr_time - type (MPAS_Time_Type) :: elapsed_time ! should be a time interval but not possible to get years that way - integer :: YYYY, MM, DD, H, M, S ! time components + integer (kind=I8KIND) :: n_intervals + type (MPAS_TimeInterval_type) :: remainder integer :: err_tmp err = 0 - - slmTimeStep = -999 ! initialize to bad number + err_tmp = 0 call mpas_pool_get_config(liConfigs, "config_slm_coupling_interval", config_slm_coupling_interval) + ! define SLM coupling interval as a timeInterval type + call mpas_set_timeInterval(coupling_interval, YY=config_slm_coupling_interval, MM=0, DD=0, H=0, M=0, S=0, ierr=err_tmp) + err = ior(err, err_tmp) + call mpas_pool_get_array(meshPool, 'simulationStartTime', simulationStartTime) call mpas_pool_get_array(meshPool, 'xtime', xtime) @@ -1134,30 +1137,20 @@ subroutine find_slm_restart_timestep(meshPool, slmTimeStep, err) err = ior(err, err_tmp) call mpas_set_time(curr_time, dateTimeString=xtime, ierr=err_tmp) err = ior(err, err_tmp) - call mpas_get_timeInterval(curr_time - start_time, start_time, timeString=elapsed_time_str, ierr=err_tmp) - err = ior(err, err_tmp) - - ! convert elapsed time string to its units. Using the intermediate string format because mpas_get_timeInterval doesn't return - ! years, and figuring out years from days depends on the calendar - call mpas_set_time(elapsed_time, dateTimeString=elapsed_time_str, ierr=err_tmp) - err = ior(err, err_tmp) - call mpas_get_time(elapsed_time, YYYY=YYYY, MM=MM, DD=DD, H=H, M=M, S=S) - - ! make sure the elapsed time is an even year - if ((MM /= 0) .or. (DD /= 0) .or. (H /= 0) .or. (M /= 0) .or. (S /= 0)) then - call mpas_log_write("Elapsed time since simulationStartTime include nonzero months, days, hours, minutes, " // & - "or seconds.", MPAS_LOG_ERR) - err = ior(err, 1) - endif - if (mod(YYYY, config_slm_coupling_interval) == 0) then - ! We can restart cleanly - slmTimeStep = YYYY / config_slm_coupling_interval + call mpas_interval_division(start_time, curr_time - start_time, coupling_interval, n_intervals, remainder) + call mpas_set_timeInterval(zero_interval, dt = 0.0_RKIND) + if (remainder .EQ. zero_interval) then + call mpas_log_write("SLM Restart check: config_slm_coupling_interval divides into elapsed time $i times " // & + "with no remainder - check passes", intArgs=(/int(n_intervals)/)) + slmTimeStep = int(n_intervals) else - call mpas_log_write("Elapsed years since simulationStartTime is not evenly divisible by config_slm_coupling_interval." // & - " Unable to restart Sea Level Model cleanly.", MPAS_LOG_ERR) + call mpas_log_write("SLM Restart check: config_slm_coupling_interval divides into elapsed time $i times " // & + "with nonzero remainder", MPAS_LOG_ERR, intArgs=(/int(n_intervals)/)) err = ior(err, 1) + slmTimeStep = -999 endif + call mpas_log_write("") !-------------------------------------------------------------------- end subroutine find_slm_restart_timestep From a3c43371b118fc9b14ad66e36a4aad1b7b06427a Mon Sep 17 00:00:00 2001 From: Matthew Hoffman Date: Wed, 21 Feb 2024 13:57:09 -0700 Subject: [PATCH 045/451] Add missing arguments to log write statement --- .../mpas-albany-landice/src/mode_forward/mpas_li_bedtopo.F | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/components/mpas-albany-landice/src/mode_forward/mpas_li_bedtopo.F b/components/mpas-albany-landice/src/mode_forward/mpas_li_bedtopo.F index 24fee4d71a22..aacfbed95ad3 100644 --- a/components/mpas-albany-landice/src/mode_forward/mpas_li_bedtopo.F +++ b/components/mpas-albany-landice/src/mode_forward/mpas_li_bedtopo.F @@ -1018,7 +1018,8 @@ subroutine check_SLM_coupling_interval(slm_dt1, meshPool, streamManager, err) ! First, check consistency in coupling interval set up in MALI and SLM call mpas_pool_get_config(liConfigs, "config_slm_coupling_interval", config_slm_coupling_interval) if (config_slm_coupling_interval == slm_dt1) then - call mpas_log_write("The coupling interval in MALI ($i yr) and SLM ($i yr) are consistent - check passes") + call mpas_log_write("The coupling interval in MALI ($i yr) and SLM ($i yr) are consistent - check passes", & + intArgs=(/config_slm_coupling_interval, slm_dt1/)) else call mpas_log_write("The coupling interval in MALI ($i yr) and SLM ($i yr) are inconsistent", MPAS_LOG_ERR, & intArgs=(/config_slm_coupling_interval, slm_dt1/)) From c692d660715f555fdb70014cb7febe138b8763ea Mon Sep 17 00:00:00 2001 From: Andrew Nolan Date: Wed, 21 Feb 2024 16:41:27 -0700 Subject: [PATCH 046/451] Add support for subglacial hydro quantities in regional stats. Following the recent addition of subglacial hydro quantities to the global stats analysis member, we've used those additions as template to add the quantitites to the regional stats analysis member. --- .../Registry_regional_stats.xml | 35 +++ .../analysis_members/mpas_li_regional_stats.F | 207 +++++++++++++++++- 2 files changed, 238 insertions(+), 4 deletions(-) diff --git a/components/mpas-albany-landice/src/analysis_members/Registry_regional_stats.xml b/components/mpas-albany-landice/src/analysis_members/Registry_regional_stats.xml index 7ae1f284d1de..8434ff36a818 100644 --- a/components/mpas-albany-landice/src/analysis_members/Registry_regional_stats.xml +++ b/components/mpas-albany-landice/src/analysis_members/Registry_regional_stats.xml @@ -103,6 +103,41 @@ description="maximum basal speed in the domain" /> + + + + + + + + + + + + + diff --git a/components/mpas-albany-landice/src/analysis_members/mpas_li_regional_stats.F b/components/mpas-albany-landice/src/analysis_members/mpas_li_regional_stats.F index 0f544b4b47a6..be9b5c8a2553 100644 --- a/components/mpas-albany-landice/src/analysis_members/mpas_li_regional_stats.F +++ b/components/mpas-albany-landice/src/analysis_members/mpas_li_regional_stats.F @@ -164,12 +164,14 @@ subroutine li_compute_regional_stats(domain, memberName, timeLevel, err) type (mpas_pool_type), pointer :: geometryPool type (mpas_pool_type), pointer :: regionsPool type (mpas_pool_type), pointer :: velocityPool + type (mpas_pool_type), pointer :: hydroPool ! arrays, vars needed from other pools for calculations here real (kind=RKIND), pointer :: config_ice_density real (kind=RKIND), pointer :: deltat real (kind=RKIND), dimension(:), pointer :: areaCell real (kind=RKIND), dimension(:), pointer :: dvEdge + real (kind=RKIND), dimension(:), pointer :: dcEdge real (kind=RKIND), dimension(:), pointer :: thickness real (kind=RKIND), dimension(:), pointer :: bedTopography real (kind=RKIND), dimension(:), pointer :: sfcMassBalApplied @@ -185,15 +187,27 @@ subroutine li_compute_regional_stats(domain, memberName, timeLevel, err) real (kind=RKIND), dimension(:), pointer :: groundedToFloatingThickness real (kind=RKIND), dimension(:,:), pointer :: normalVelocity + real (kind=RKIND), dimension(:), pointer :: waterThickness + real (kind=RKIND), dimension(:), pointer :: basalMeltInput + real (kind=RKIND), dimension(:), pointer :: externalWaterInput + real (kind=RKIND), dimension(:), pointer :: channelMelt + real (kind=RKIND), dimension(:), pointer :: waterFlux + real (kind=RKIND), dimension(:), pointer :: channelDischarge + real (kind=RKIND), dimension(:), pointer :: waterPressure + ! config options needed real (kind=RKIND), pointer :: config_sea_level real (kind=RKIND), pointer :: rhoi ! config_ice_density real (kind=RKIND), pointer :: rhow ! config_ocean_density + real (kind=RKIND), pointer :: bedBumpMax ! config_SGH_bed_roughness_max + logical, pointer :: config_SGH integer, dimension(:,:), pointer :: regionCellMasks integer, dimension(:), pointer :: cellMask integer, dimension(:), pointer :: edgeMask integer, dimension(:,:), pointer :: cellsOnEdge + integer, dimension(:), pointer :: hydroMarineMarginMask + integer, dimension(:), pointer :: hydroTerrestrialMarginMask integer, pointer :: nRegions, nRegionGroups !, maxRegionsInGroup !! maxRegionsInGroup not needed / used yet integer, pointer :: nCellsSolve, nEdgesSolve, nVertLevels integer :: k, iCell, iEdge @@ -218,6 +232,17 @@ subroutine li_compute_regional_stats(domain, memberName, timeLevel, err) real (kind=RKIND), dimension(:), pointer :: regionalAvgSubshelfMelt real (kind=RKIND), dimension(:), pointer :: regionalSurfaceSpeedMax real (kind=RKIND), dimension(:), pointer :: regionalBasalSpeedMax + real (kind=RKIND), dimension(:), pointer :: regionalSumSubglacialWaterVolume + real (kind=RKIND), dimension(:), pointer :: regionalSumBasalMeltInput + real (kind=RKIND), dimension(:), pointer :: regionalSumExternalWaterInput + real (kind=RKIND), dimension(:), pointer :: regionalSumChannelMelt + real (kind=RKIND), dimension(:), pointer :: regionalSumSubglacialLakeVolume + real (kind=RKIND), dimension(:), pointer :: regionalSumSubglacialLakeArea + real (kind=RKIND), dimension(:), pointer :: regionalSumDistWaterFluxMarineMargin + real (kind=RKIND), dimension(:), pointer :: regionalSumDistWaterFluxTerrestrialMargin + real (kind=RKIND), dimension(:), pointer :: regionalSumChnlWaterFluxMarineMargin + real (kind=RKIND), dimension(:), pointer :: regionalSumChnlWaterFluxTerrestrialMargin + real (kind=RKIND), dimension(:), pointer :: regionalAvgFlotationFraction ! storage for sums over blocks real (kind=RKIND), dimension(:), allocatable :: blockSumRegionIceArea, blockSumRegionIceVolume @@ -234,12 +259,25 @@ subroutine li_compute_regional_stats(domain, memberName, timeLevel, err) real (kind=RKIND), dimension(:), allocatable :: blockRegionGLMigrationFlux real (kind=RKIND), dimension(:), allocatable :: blockRegionMaxSurfaceSpeed real (kind=RKIND), dimension(:), allocatable :: blockRegionMaxBasalSpeed + real (kind=RKIND), dimension(:), allocatable :: blockSumRegionSubglacialWaterVolume + real (kind=RKIND), dimension(:), allocatable :: blockSumRegionBasalMeltInput + real (kind=RKIND), dimension(:), allocatable :: blockSumRegionExternalWaterInput + real (kind=RKIND), dimension(:), allocatable :: blockSumRegionChannelMelt + real (kind=RKIND), dimension(:), allocatable :: blockSumRegionLakeVolume + real (kind=RKIND), dimension(:), allocatable :: blockSumRegionLakeArea + real (kind=RKIND), dimension(:), allocatable :: blockSumRegionGLMeltFlux + real (kind=RKIND), dimension(:), allocatable :: blockSumRegionTerrestrialMeltFlux + real (kind=RKIND), dimension(:), allocatable :: blockSumRegionChannelGLMeltFlux + real (kind=RKIND), dimension(:), allocatable :: blockSumRegionChannelTerrestrialMeltFlux + real (kind=RKIND), dimension(:), allocatable :: blockSumRegionFlotationFraction + ! local variable needed calculating average floation fraction in a region + real (kind=RKIND), dimension(:), allocatable:: regionalSumFlotationFraction ! local variables real (kind=RKIND) :: fluxSign ! variables for processing stats - integer, parameter :: kMaxVariables = 32 ! Increase if number of stats increase + integer, parameter :: kMaxVariables = 43 ! Increase if number of stats increase integer :: nVars real (kind=RKIND), dimension(kMaxVariables) :: reductions, sums, mins, maxes @@ -251,6 +289,8 @@ subroutine li_compute_regional_stats(domain, memberName, timeLevel, err) call mpas_pool_get_config(liConfigs, 'config_sea_level', config_sea_level) call mpas_pool_get_config(liConfigs, 'config_ice_density', rhoi) call mpas_pool_get_config(liConfigs, 'config_ocean_density', rhow) + call mpas_pool_get_config(liConfigs, 'config_SGH_bed_roughness_max', bedBumpMax) + call mpas_pool_get_config(liConfigs, 'config_SGH', config_SGH) ! loop over blocks block => domain % blocklist @@ -265,7 +305,8 @@ subroutine li_compute_regional_stats(domain, memberName, timeLevel, err) call mpas_pool_get_subpool(block % structs, 'geometry', geometryPool) call mpas_pool_get_subpool(block % structs, 'velocity', velocityPool) call mpas_pool_get_subpool(block % structs, 'regions', regionsPool) -! call mpas_pool_get_subpool(block % structs, 'regionalStatsAM', regionalStatsAMPool) + call mpas_pool_get_subpool(block % structs, 'hydro', hydroPool) +! call mpas_pool_get_subpool(block % structs, 'regionalStatsAM', regionalStatsAMPool) ! get values and arrays from standard pools call mpas_pool_get_config(liConfigs, 'config_ice_density', config_ice_density) @@ -292,6 +333,18 @@ subroutine li_compute_regional_stats(domain, memberName, timeLevel, err) call mpas_pool_get_array(velocityPool, 'basalSpeed', basalSpeed) call mpas_pool_get_array(velocityPool, 'fluxAcrossGroundingLine', fluxAcrossGroundingLine) call mpas_pool_get_array(velocityPool, 'normalVelocity', normalVelocity) + if (config_SGH) then + call mpas_pool_get_array(meshPool, 'dcEdge', dcEdge) + call mpas_pool_get_array(hydroPool, 'waterThickness', waterThickness) + call mpas_pool_get_array(hydroPool, 'basalMeltInput', basalMeltInput) + call mpas_pool_get_array(hydroPool, 'externalWaterInput', externalWaterInput) + call mpas_pool_get_array(hydroPool, 'channelMelt', channelMelt) + call mpas_pool_get_array(hydroPool, 'hydroMarineMarginMask', hydroMarineMarginMask) + call mpas_pool_get_array(hydroPool, 'hydroTerrestrialMarginMask', hydroTerrestrialMarginMask) + call mpas_pool_get_array(hydroPool, 'waterFlux', waterFlux) + call mpas_pool_get_array(hydroPool, 'channelDischarge', channelDischarge) + call mpas_pool_get_array(hydroPool, 'waterPressure', waterPressure) + endif ! get region cell masks from regionMasks.nc input file call mpas_pool_get_array(regionsPool, 'regionCellMasks', regionCellMasks) @@ -310,6 +363,20 @@ subroutine li_compute_regional_stats(domain, memberName, timeLevel, err) allocate(blockSumRegionFaceMeltingFlux(nRegions)) allocate(blockSumRegionGLflux(nRegions)) allocate(blockRegionGLMigrationFlux(nRegions)) + if (config_SGH) then + allocate(blockSumRegionSubglacialWaterVolume(nRegions)) + allocate(blockSumRegionBasalMeltInput(nRegions)) + allocate(blockSumRegionExternalWaterInput(nRegions)) + allocate(blockSumRegionChannelMelt(nRegions)) + allocate(blockSumRegionLakeVolume(nRegions)) + allocate(blockSumRegionLakeArea(nRegions)) + allocate(blockSumRegionGLMeltFlux(nRegions)) + allocate(blockSumRegionTerrestrialMeltFlux(nRegions)) + allocate(blockSumRegionChannelGLMeltFlux(nRegions)) + allocate(blockSumRegionChannelTerrestrialMeltFlux(nRegions)) + allocate(blockSumRegionFlotationFraction(nRegions)) + allocate(regionalSumFlotationFraction(nRegions)) + endif blockSumRegionIceArea = 0.0_RKIND; blockSumRegionIceVolume = 0.0_RKIND blockSumRegionVAF = 0.0_RKIND @@ -324,6 +391,21 @@ subroutine li_compute_regional_stats(domain, memberName, timeLevel, err) blockSumRegionFaceMeltingFlux = 0.0_RKIND blockSumRegionGLflux = 0.0_RKIND blockRegionGLMigrationFlux = 0.0_RKIND + + if (config_SGH) then + blockSumRegionSubglacialWaterVolume = 0.0_RKIND + blockSumRegionBasalMeltInput = 0.0_RKIND + blockSumRegionExternalWaterInput = 0.0_RKIND + blockSumRegionChannelMelt = 0.0_RKIND + blockSumRegionLakeVolume = 0.0_RKIND + blockSumRegionLakeArea = 0.0_RKIND + blockSumRegionGLMeltFlux = 0.0_RKIND + blockSumRegionTerrestrialMeltFlux = 0.0_RKIND + blockSumRegionChannelGLMeltFlux = 0.0_RKIND + blockSumRegionChannelTerrestrialMeltFlux = 0.0_RKIND + blockSumRegionFlotationFraction = 0.0_RKIND + regionalSumFlotationFraction = 0.0_RKIND + endif do iCell = 1,nCellsSolve ! loop over cells ! do iGroup = 1,nRegionGroups ! loop over groups @@ -425,8 +507,39 @@ subroutine li_compute_regional_stats(domain, memberName, timeLevel, err) real(regionCellMasks(iRegion,iCell),RKIND) * & groundedToFloatingThickness(iCell) * areaCell(iCell) * rhoi / (deltat / scyr) + !! Subglacial Hydrology Calculations + if (config_SGH) then + + ! Subglacial Water Volume + blockSumRegionSubglacialWaterVolume(iRegion) = blockSumRegionSubglacialWaterVolume(iRegion) + & + waterThickness(iCell) * areaCell(iCell) + + ! Basal melt input + blockSumRegionBasalMeltInput(iRegion) = blockSumRegionBasalMeltInput(iRegion) + & + real(li_mask_is_grounded_ice_int(cellMask(iCell)),RKIND) * basalMeltInput(iCell) * areaCell(iCell) + + ! External water input + blockSumRegionExternalWaterInput(iRegion) = blockSumRegionExternalWaterInput(iRegion) + & + externalWaterInput(iCell) * areaCell(iCell) + + ! Lake Volume + if (waterThickness(iCell) > bedBumpMax) then + blockSumRegionLakeVolume(iRegion) = blockSumRegionLakeVolume(iRegion) + & + (waterThickness(iCell) - bedBumpMax) * areaCell(iCell) + endif + + ! Lake Area + if (waterThickness(iCell) > bedBumpMax) then + blockSumRegionLakeArea(iRegion) = blockSumRegionLakeArea(iRegion) + areaCell(iCell) + endif + + ! Area-weighted flotation fraction for grounded ice + if (li_mask_is_grounded_ice(cellMask(iCell))) then + blockSumRegionFlotationFraction(iRegion) = blockSumRegionFlotationFraction(iRegion) + & + ( waterPressure(iCell) / rhoi / gravity / thickness(iCell) ) * areaCell(iCell) + endif + endif end do ! end loop over regions - ! end do ! end loop over groups end do ! end loop over cells @@ -450,6 +563,29 @@ subroutine li_compute_regional_stats(domain, memberName, timeLevel, err) end if ! if edge is on cell in region of interest end do ! end loop over regions end if ! if GL + + if (config_SGH) then + ! Channel Melt + blockSumRegionChannelMelt(iRegion) = blockSumRegionChannelMelt(iRegion) + & + abs(channelMelt(iEdge) * dcEdge(iEdge)) + + ! Meltwater Flux across the grounding line + blockSumRegionGLMeltFlux(iRegion) = blockSumRegionGLMeltFlux(iRegion) + & + abs(hydroMarineMarginMask(iEdge) * waterFlux(iEdge) * dvEdge(iEdge) * rho_water) + + ! Meltwater Flux across terrestrial margins + blockSumRegionTerrestrialMeltFlux(iRegion) = blockSumRegionTerrestrialMeltFlux(iRegion) + & + abs(hydroTerrestrialMarginMask(iEdge) * waterFlux(iEdge) * dvEdge(iEdge) * rho_water) + + ! Meltwater Discharge in channels across grounding line + blockSumRegionChannelGLMeltFlux(iRegion) = blockSumRegionChannelGLMeltFlux(iRegion) + & + abs(hydroMarineMarginMask(iEdge) * channelDischarge(iEdge) * rho_water) + + ! Meltwater discharge in channels across terrestrial margin + blockSumRegionChannelTerrestrialMeltFlux(iRegion) = blockSumRegionChannelTerrestrialMeltFlux(iRegion) + & + abs( hydroTerrestrialMarginMask(iEdge) * channelDischarge(iEdge) * rho_water) + endif ! if SGH is on + end do ! end loop over edges block => block % next @@ -494,7 +630,22 @@ subroutine li_compute_regional_stats(domain, memberName, timeLevel, err) sums(15) = blockSumRegionVAF(iRegion) sums(16) = blockSumRegionGLflux(iRegion) sums(17) = blockRegionGLMigrationFlux(iRegion) - nVars = 17 + if (config_SGH) then + sums(18) = blockSumRegionSubglacialWaterVolume(iRegion) + sums(19) = blockSumRegionBasalMeltInput(iRegion) + sums(20) = blockSumRegionExternalWaterInput(iRegion) + sums(21) = blockSumRegionChannelMelt(iRegion) + sums(22) = blockSumRegionLakeVolume(iRegion) + sums(23) = blockSumRegionLakeArea(iRegion) + sums(24) = blockSumRegionGLMeltFlux(iRegion) + sums(25) = blockSumRegionTerrestrialMeltFlux(iRegion) + sums(26) = blockSumRegionChannelGLMeltFlux(iRegion) + sums(27) = blockSumRegionChannelTerrestrialMeltFlux(iRegion) + sums(28) = blockSumRegionFlotationFraction(iRegion) + nVars = 28 + else + nVars = 17 + endif call mpas_dmpar_sum_real_array(dminfo, nVars, sums(1:nVars), reductions(1:nVars)) @@ -526,6 +677,19 @@ subroutine li_compute_regional_stats(domain, memberName, timeLevel, err) call mpas_pool_get_array(regionalStatsAMPool, 'regionalSumGroundingLineFlux', regionalSumGroundingLineFlux) call mpas_pool_get_array(regionalStatsAMPool, 'regionalSumGroundingLineMigrationFlux', & regionalSumGroundingLineMigrationFlux) + if (config_SGH) then + call mpas_pool_get_array(regionalStatsAMPool, 'regionalSumSubglacialWaterVolume', regionalSumSubglacialWaterVolume) + call mpas_pool_get_array(regionalStatsAMPool, 'regionalSumBasalMeltInput', regionalSumBasalMeltInput) + call mpas_pool_get_array(regionalStatsAMPool, 'regionalSumExternalWaterInput', regionalSumExternalWaterInput) + call mpas_pool_get_array(regionalStatsAMPool, 'regionalSumChannelMelt', regionalSumChannelMelt) + call mpas_pool_get_array(regionalStatsAMPool, 'regionalSumSubglacialLakeVolume', regionalSumSubglacialLakeVolume) + call mpas_pool_get_array(regionalStatsAMPool, 'regionalSumSubglacialLakeArea', regionalSumSubglacialLakeArea) + call mpas_pool_get_array(regionalStatsAMPool, 'regionalSumDistWaterFluxMarineMargin',regionalSumDistWaterFluxMarineMargin) + call mpas_pool_get_array(regionalStatsAMPool, 'regionalSumDistWaterFluxTerrestrialMargin', regionalSumDistWaterFluxTerrestrialMargin) + call mpas_pool_get_array(regionalStatsAMPool, 'regionalSumChnlWaterFluxMarineMargin',regionalSumChnlWaterFluxMarineMargin) + call mpas_pool_get_array(regionalStatsAMPool, 'regionalSumChnlWaterFluxTerrestrialMargin', regionalSumChnlWaterFluxTerrestrialMargin) + call mpas_pool_get_array(regionalStatsAMPool, 'regionalAvgFlotationFraction', regionalAvgFlotationFraction) + endif regionalIceArea(iRegion) = reductions(1) regionalIceVolume(iRegion) = reductions(2) @@ -544,6 +708,19 @@ subroutine li_compute_regional_stats(domain, memberName, timeLevel, err) regionalVolumeAboveFloatation(iRegion) = reductions(15) regionalSumGroundingLineFlux(iRegion) = reductions(16) regionalSumGroundingLineMigrationFlux(iRegion) = reductions(17) + if (config_SGH) then + regionalSumSubglacialWaterVolume(iRegion) = reductions(18) + regionalSumBasalMeltInput(iRegion) = reductions(19) + regionalSumExternalWaterInput(iRegion) = reductions(20) + regionalSumChannelMelt(iRegion) = reductions(21) + regionalSumSubglacialLakeVolume(iRegion) = reductions(22) + regionalSumSubglacialLakeArea(iRegion) = reductions(23) + regionalSumDistWaterFluxMarineMargin(iRegion) = reductions(24) + regionalSumDistWaterFluxTerrestrialMargin(iRegion) = reductions(25) + regionalSumChnlWaterFluxMarineMargin(iRegion) = reductions(26) + regionalSumChnlWaterFluxTerrestrialMargin(iRegion) = reductions(27) + regionalSumFlotationFraction(iRegion) = reductions(28) + endif if (regionalIceArea(iRegion) > 0.0_RKIND) then regionalIceThicknessMean(iRegion) = regionalIceVolume(iRegion) / regionalIceArea(iRegion) @@ -565,6 +742,15 @@ subroutine li_compute_regional_stats(domain, memberName, timeLevel, err) regionalAvgSubshelfMelt(iRegion) = 0.0_RKIND endif + if (config_SGH) then + if (regionalIceArea(iRegion) > 0.0_RKIND) then + ! WHAT SHOULD totalFLoationFraction equivalent be? + regionalAvgFlotationFraction(iRegion) = regionalSumFlotationFraction(iRegion) / regionalIceArea(iRegion) + else + regionalAvgFlotationFraction(iRegion) = 0.0_RKIND + endif + endif + block => block % next end do @@ -624,6 +810,19 @@ subroutine li_compute_regional_stats(domain, memberName, timeLevel, err) deallocate(blockSumRegionFaceMeltingFlux) deallocate(blockSumRegionGLflux) deallocate(blockRegionGLMigrationflux) + if (config_SGH) then + deallocate(blockSumRegionSubglacialWaterVolume) + deallocate(blockSumRegionBasalMeltInput) + deallocate(blockSumRegionExternalWaterInput) + deallocate(blockSumRegionChannelMelt) + deallocate(blockSumRegionLakeVolume) + deallocate(blockSumRegionLakeArea) + deallocate(blockSumRegionGLMeltFlux) + deallocate(blockSumRegionTerrestrialMeltFlux) + deallocate(blockSumRegionChannelGLMeltFlux) + deallocate(blockSumRegionChannelTerrestrialMeltFlux) + deallocate(blockSumRegionFlotationFraction) + endif end subroutine li_compute_regional_stats From dd10e47bed3ac329fc89b6188f5f8958fd178e0b Mon Sep 17 00:00:00 2001 From: Andrew Nolan Date: Wed, 21 Feb 2024 16:53:27 -0700 Subject: [PATCH 047/451] Move reduction of `fluxAcrossGroundingLine` outside SGH condition. The reduction of `fluxAcrossGroundingLine` was accidently moved within a `config_SGH` condition, so that `groundingLineFlux` would only be calculated if `config_SGH` was turned on. Moved the reduction back to where it was to ensure it's calculated in all situations it's needed. --- .../analysis_members/mpas_li_global_stats.F | 32 ++++++++++--------- 1 file changed, 17 insertions(+), 15 deletions(-) diff --git a/components/mpas-albany-landice/src/analysis_members/mpas_li_global_stats.F b/components/mpas-albany-landice/src/analysis_members/mpas_li_global_stats.F index 2e1d05cbc390..c21b4a2cb861 100755 --- a/components/mpas-albany-landice/src/analysis_members/mpas_li_global_stats.F +++ b/components/mpas-albany-landice/src/analysis_members/mpas_li_global_stats.F @@ -461,13 +461,14 @@ subroutine li_compute_global_stats(domain, memberName, timeLevel, err) end do ! end loop over cells - if (config_SGH) then - ! Loop over edges - do iEdge = 1, nEdgesSolve + ! Loop over edges + do iEdge = 1, nEdgesSolve + + ! Flux across GL, units = kg/yr + blockGLflux = blockGLflux + fluxAcrossGroundingLine(iEdge) * dvEdge(iEdge) & + * scyr * rhoi ! convert from m^2/s to kg/yr - ! Flux across GL, units = kg/yr - blockGLflux = blockGLflux + fluxAcrossGroundingLine(iEdge) * dvEdge(iEdge) & - * scyr * rhoi ! convert from m^2/s to kg/yr + if (config_SGH) then ! Channel Melt blockSumChannelMelt = blockSumChannelMelt + abs(channelMelt(iEdge) * dcEdge(iEdge)) @@ -484,8 +485,9 @@ subroutine li_compute_global_stats(domain, memberName, timeLevel, err) ! Meltwater discharge in channels across terrestrial margin blockSumChannelTerrestrialMeltFlux = blockSumChannelTerrestrialMeltFlux + abs( hydroTerrestrialMarginMask(iEdge) * channelDischarge(iEdge) * rho_water) - end do ! end loop over edges - endif + endif ! is SGH is turned on + end do ! end loop over edges + block => block % next end do ! end loop over blocks @@ -530,9 +532,9 @@ subroutine li_compute_global_stats(domain, memberName, timeLevel, err) sums(13) = blockSumCalvingFlux sums(14) = blockSumFaceMeltingFlux sums(15) = blockSumVAF + sums(16) = blockGLflux + sums(17) = blockGLMigrationflux if (config_SGH) then - sums(16) = blockGLflux - sums(17) = blockGLMigrationflux sums(18) = blockSumSubglacialWaterVolume sums(19) = blockSumBasalMeltInput sums(20) = blockSumExternalWaterInput @@ -546,7 +548,7 @@ subroutine li_compute_global_stats(domain, memberName, timeLevel, err) sums(28) = blockSumFlotationFraction nVars = 28 else - nVars = 15 + nVars = 17 endif call mpas_dmpar_sum_real_array(dminfo, nVars, sums(1:nVars), reductions(1:nVars)) @@ -574,9 +576,9 @@ subroutine li_compute_global_stats(domain, memberName, timeLevel, err) call mpas_pool_get_array(globalStatsAMPool, 'avgSubshelfMelt', avgSubshelfMelt) call mpas_pool_get_array(globalStatsAMPool, 'totalCalvingFlux', totalCalvingFlux) call mpas_pool_get_array(globalStatsAMPool, 'totalFaceMeltingFlux', totalFaceMeltingFlux) + call mpas_pool_get_array(globalStatsAMPool, 'groundingLineFlux', groundingLineFlux) + call mpas_pool_get_array(globalStatsAMPool, 'groundingLineMigrationFlux', groundingLineMigrationFlux) if (config_SGH) then - call mpas_pool_get_array(globalStatsAMPool, 'groundingLineFlux', groundingLineFlux) - call mpas_pool_get_array(globalStatsAMPool, 'groundingLineMigrationFlux', groundingLineMigrationFlux) call mpas_pool_get_array(globalStatsAMPool, 'totalSubglacialWaterVolume', totalSubglacialWaterVolume) call mpas_pool_get_array(globalStatsAMPool, 'totalBasalMeltInput', totalBasalMeltInput) call mpas_pool_get_array(globalStatsAMPool, 'totalExternalWaterInput', totalExternalWaterInput) @@ -605,9 +607,9 @@ subroutine li_compute_global_stats(domain, memberName, timeLevel, err) totalCalvingFlux = reductions(13) totalFaceMeltingFlux = reductions(14) volumeAboveFloatation = reductions(15) + groundingLineFlux = reductions(16) + groundingLineMigrationFlux = reductions(17) if (config_SGH) then - groundingLineFlux = reductions(16) - groundingLineMigrationFlux = reductions(17) totalSubglacialWaterVolume = reductions(18) totalBasalMeltInput = reductions(19) totalExternalWaterInput = reductions(20) From 6df3ae38c9cbb25897ef9341639c8d7a220ef957 Mon Sep 17 00:00:00 2001 From: Walter Hannah Date: Thu, 22 Feb 2024 08:01:34 -0800 Subject: [PATCH 048/451] fix typo --- components/eam/src/physics/cam/phys_control.F90 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/components/eam/src/physics/cam/phys_control.F90 b/components/eam/src/physics/cam/phys_control.F90 index 543fd29753f2..b87ea442c4e7 100644 --- a/components/eam/src/physics/cam/phys_control.F90 +++ b/components/eam/src/physics/cam/phys_control.F90 @@ -745,7 +745,7 @@ subroutine phys_getopts(deep_scheme_out, shallow_scheme_out, eddy_scheme_out, & if ( present(use_crm_accel_out ) ) use_crm_accel_out = use_crm_accel if ( present(crm_accel_factor_out ) ) crm_accel_factor_out = crm_accel_factor if ( present(crm_accel_uv_out ) ) crm_accel_uv_out = crm_accel_uv - if ( present(MMF_PAM_dyn_per_phys ) ) MMF_PAM_dyn_per_phys_out = MMF_PAM_dyn_per_phys + if ( present(MMF_PAM_dyn_per_phys_out) ) MMF_PAM_dyn_per_phys_out = MMF_PAM_dyn_per_phys if ( present(use_subcol_microp_out ) ) use_subcol_microp_out = use_subcol_microp if ( present(macrop_scheme_out ) ) macrop_scheme_out = macrop_scheme From 18147b3b0fa4641e2464575386852cbec5f2302a Mon Sep 17 00:00:00 2001 From: Andrew Nolan Date: Thu, 22 Feb 2024 15:09:06 -0700 Subject: [PATCH 049/451] Add grounded ice mask to `externalWaterInput` term The grounded ice mask is used in the calculation of the `basalMeltInput` term but was excluded from `externalWaterInput`, which could cause problems in closing budgets. The grounded ice mask was not added to any of the calculations dependent on `waterThickness` b/c SGH model explicitly sets the `waterThickness` to zero outside of the grounded ice area. --- .../src/analysis_members/mpas_li_global_stats.F | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/components/mpas-albany-landice/src/analysis_members/mpas_li_global_stats.F b/components/mpas-albany-landice/src/analysis_members/mpas_li_global_stats.F index c21b4a2cb861..10350fa9d235 100755 --- a/components/mpas-albany-landice/src/analysis_members/mpas_li_global_stats.F +++ b/components/mpas-albany-landice/src/analysis_members/mpas_li_global_stats.F @@ -440,7 +440,8 @@ subroutine li_compute_global_stats(domain, memberName, timeLevel, err) basalMeltInput(iCell) * areaCell(iCell) ! External water input - blockSumExternalWaterInput = blockSumExternalWaterInput + externalWaterInput(iCell) * areaCell(iCell) + blockSumExternalWaterInput = blockSumExternalWaterInput + & + real(li_mask_is_grounded_ice_int(cellMask(iCell)),RKIND) * externalWaterInput(iCell) * areaCell(iCell) ! Lake Volume if (waterThickness(iCell) > bedBumpMax) then From 219b5ab9d58ef201dd052b274ee9369e1464b530 Mon Sep 17 00:00:00 2001 From: Andrew Nolan Date: Thu, 22 Feb 2024 15:17:16 -0700 Subject: [PATCH 050/451] Add missing `regionCellMasks` call from SGH regional stats terms Masking by `regionCellMasks` in SGH regional stats terms was missing, which meant all cell centered SGH values would have been uniform across the regions and match the global stats value. Still not determined how the edge centered SGH value should be mask by region (e.g. using upwind cells region or by the `regionEdgeMasks`), but once that is decided the matching region masking needs to be done for the SGH edge quantities. --- .../analysis_members/mpas_li_regional_stats.F | 33 ++++++++++++------- 1 file changed, 22 insertions(+), 11 deletions(-) diff --git a/components/mpas-albany-landice/src/analysis_members/mpas_li_regional_stats.F b/components/mpas-albany-landice/src/analysis_members/mpas_li_regional_stats.F index be9b5c8a2553..b93d9ad39c28 100644 --- a/components/mpas-albany-landice/src/analysis_members/mpas_li_regional_stats.F +++ b/components/mpas-albany-landice/src/analysis_members/mpas_li_regional_stats.F @@ -512,31 +512,37 @@ subroutine li_compute_regional_stats(domain, memberName, timeLevel, err) ! Subglacial Water Volume blockSumRegionSubglacialWaterVolume(iRegion) = blockSumRegionSubglacialWaterVolume(iRegion) + & - waterThickness(iCell) * areaCell(iCell) - - ! Basal melt input - blockSumRegionBasalMeltInput(iRegion) = blockSumRegionBasalMeltInput(iRegion) + & - real(li_mask_is_grounded_ice_int(cellMask(iCell)),RKIND) * basalMeltInput(iCell) * areaCell(iCell) + (real(regionCellMasks(iRegion,iCell),RKIND) * waterThickness(iCell) * areaCell(iCell)) + + if (li_mask_is_grounded_ice(cellMask(iCell))) then + ! Basal melt input + blockSumRegionBasalMeltInput(iRegion) = blockSumRegionBasalMeltInput(iRegion) + & + (real(regionCellMasks(iRegion,iCell),RKIND) * basalMeltInput(iCell) * areaCell(iCell)) + endif ! External water input blockSumRegionExternalWaterInput(iRegion) = blockSumRegionExternalWaterInput(iRegion) + & - externalWaterInput(iCell) * areaCell(iCell) + (real(regionCellMasks(iRegion,iCell),RKIND) * & + real(li_mask_is_grounded_ice_int(cellMask(iCell)),RKIND) * & + externalWaterInput(iCell) * areaCell(iCell)) ! Lake Volume if (waterThickness(iCell) > bedBumpMax) then blockSumRegionLakeVolume(iRegion) = blockSumRegionLakeVolume(iRegion) + & - (waterThickness(iCell) - bedBumpMax) * areaCell(iCell) + (real(regionCellMasks(iRegion,iCell),RKIND) * (waterThickness(iCell) - bedBumpMax) * areaCell(iCell)) endif ! Lake Area if (waterThickness(iCell) > bedBumpMax) then - blockSumRegionLakeArea(iRegion) = blockSumRegionLakeArea(iRegion) + areaCell(iCell) + blockSumRegionLakeArea(iRegion) = blockSumRegionLakeArea(iRegion) + & + (real(regionCellMasks(iRegion,iCell),RKIND) * areaCell(iCell)) endif ! Area-weighted flotation fraction for grounded ice if (li_mask_is_grounded_ice(cellMask(iCell))) then blockSumRegionFlotationFraction(iRegion) = blockSumRegionFlotationFraction(iRegion) + & - ( waterPressure(iCell) / rhoi / gravity / thickness(iCell) ) * areaCell(iCell) + (real(regionCellMasks(iRegion,iCell),RKIND) * & + ( waterPressure(iCell) / rhoi / gravity / thickness(iCell) ) * areaCell(iCell)) endif endif end do ! end loop over regions @@ -564,6 +570,12 @@ subroutine li_compute_regional_stats(domain, memberName, timeLevel, err) end do ! end loop over regions end if ! if GL + ! TO DO: Need to define our own condition on how to decide which region to put the edge quantities + ! TO DO: Make sure SGH terms are masked based on region (using regionEdgeMasks?) b/c calculations are + ! currently unmasked and therefore global values + + + ! assign the SGH stats this edge quantities to the region of the upwind cell if (config_SGH) then ! Channel Melt blockSumRegionChannelMelt(iRegion) = blockSumRegionChannelMelt(iRegion) + & @@ -584,8 +596,7 @@ subroutine li_compute_regional_stats(domain, memberName, timeLevel, err) ! Meltwater discharge in channels across terrestrial margin blockSumRegionChannelTerrestrialMeltFlux(iRegion) = blockSumRegionChannelTerrestrialMeltFlux(iRegion) + & abs( hydroTerrestrialMarginMask(iEdge) * channelDischarge(iEdge) * rho_water) - endif ! if SGH is on - + endif ! if SGH is on end do ! end loop over edges block => block % next From fae4e15379b7650f1c2d497b7d6f9119be89f90c Mon Sep 17 00:00:00 2001 From: Andrew Nolan Date: Thu, 22 Feb 2024 15:27:29 -0700 Subject: [PATCH 051/451] Deallocate `regionalSumFlotationFraction`. Was missing the deallocation of `regionalSumFlotationFraction`, which is a local variable needed for calculating the numerator of `regionalAvgFlotationFraction`. --- .../src/analysis_members/mpas_li_regional_stats.F | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/components/mpas-albany-landice/src/analysis_members/mpas_li_regional_stats.F b/components/mpas-albany-landice/src/analysis_members/mpas_li_regional_stats.F index b93d9ad39c28..912eca2a5024 100644 --- a/components/mpas-albany-landice/src/analysis_members/mpas_li_regional_stats.F +++ b/components/mpas-albany-landice/src/analysis_members/mpas_li_regional_stats.F @@ -270,7 +270,7 @@ subroutine li_compute_regional_stats(domain, memberName, timeLevel, err) real (kind=RKIND), dimension(:), allocatable :: blockSumRegionChannelGLMeltFlux real (kind=RKIND), dimension(:), allocatable :: blockSumRegionChannelTerrestrialMeltFlux real (kind=RKIND), dimension(:), allocatable :: blockSumRegionFlotationFraction - ! local variable needed calculating average floation fraction in a region + ! local variable needed calculating numerator of regionalAvgFlotationFraction real (kind=RKIND), dimension(:), allocatable:: regionalSumFlotationFraction ! local variables @@ -833,6 +833,8 @@ subroutine li_compute_regional_stats(domain, memberName, timeLevel, err) deallocate(blockSumRegionChannelGLMeltFlux) deallocate(blockSumRegionChannelTerrestrialMeltFlux) deallocate(blockSumRegionFlotationFraction) + ! local variable needed for calculating numerator of regionalAvgFlotationFraction + deallocate(regionalSumFlotationFraction) endif end subroutine li_compute_regional_stats From abaa6cae48047fb4d4759fbd8d25d66f096c0a18 Mon Sep 17 00:00:00 2001 From: Matthew Hoffman Date: Fri, 23 Feb 2024 19:34:45 -0700 Subject: [PATCH 052/451] Add missing error flag so model actually dies when error occurs --- .../mpas-albany-landice/src/mode_forward/mpas_li_bedtopo.F | 1 + 1 file changed, 1 insertion(+) diff --git a/components/mpas-albany-landice/src/mode_forward/mpas_li_bedtopo.F b/components/mpas-albany-landice/src/mode_forward/mpas_li_bedtopo.F index aacfbed95ad3..f1cc7aceed22 100644 --- a/components/mpas-albany-landice/src/mode_forward/mpas_li_bedtopo.F +++ b/components/mpas-albany-landice/src/mode_forward/mpas_li_bedtopo.F @@ -1080,6 +1080,7 @@ subroutine check_SLM_coupling_interval(slm_dt1, meshPool, streamManager, err) else call mpas_log_write("config_slm_coupling_interval divides into restart interval $i times " // & "with nonzero remainder", MPAS_LOG_ERR, intArgs=(/int(n_intervals)/)) + err = ior(err, 1) endif endif From 6bb3000ce6caa7769555b4f20bc6130f60d2fe1e Mon Sep 17 00:00:00 2001 From: Matthew Hoffman Date: Fri, 23 Feb 2024 19:59:03 -0700 Subject: [PATCH 053/451] Allow restarts at any interval when using SLM This commit changes how restarts are handled when the SLM is active to allow MALI to be restarted at any arbitrary restart interval and have the SLM restart correctly. This is done by changing the SLM coupling alarm to be based off of the original simulationStartTime (instead of the start time of the current execution). This required moving the creation of the coupling alarm to later in initialization so that the variable simulationStartTime is available. With this change, it was also necessary to change the way the SLM time level is calculated on a restart to take the floor of the elapsed time divided by the coupling interval, rather than requiring that there be no remainder. This adds a little fragility because there is no way to double check that is the correct SLM time level, but if this is set up correctly, it should be handled properly. Finally, as part of these changes, I also removed the check on init that the coupling interval divides evenly into the restart interval, because that's no longer a requirement. That's sort of too bad, because it was a lot of work to figure out how to make that check! But it's nicer to not have that restriction. --- .../src/mode_forward/mpas_li_bedtopo.F | 69 +++++++++---------- .../src/mode_forward/mpas_li_core.F | 17 ----- 2 files changed, 32 insertions(+), 54 deletions(-) diff --git a/components/mpas-albany-landice/src/mode_forward/mpas_li_bedtopo.F b/components/mpas-albany-landice/src/mode_forward/mpas_li_bedtopo.F index f1cc7aceed22..4ead2074546f 100644 --- a/components/mpas-albany-landice/src/mode_forward/mpas_li_bedtopo.F +++ b/components/mpas-albany-landice/src/mode_forward/mpas_li_bedtopo.F @@ -407,6 +407,10 @@ subroutine slmodel_init(domain, err) integer :: itersl, dtime ! SLM variable real :: starttime ! SLM variable integer, dimension(:), pointer :: cellMask ! integer bitmask for cells + integer, pointer :: config_slm_coupling_interval + type (MPAS_TimeInterval_type) :: slm_coupling_interval + character (len=StrKIND), pointer :: simulationStartTime + type (MPAS_Time_type) :: simulationStartTime_timeType ! MPI variables integer, dimension(:), pointer :: indexToCellID @@ -415,12 +419,30 @@ subroutine slmodel_init(domain, err) err = 0 err_tmp = 0 + + call mpas_pool_get_subpool(domain % blocklist % structs, 'mesh', meshPool) + + ! Set up the alarm for the coupling time interval + call mpas_pool_get_config(liConfigs, 'config_slm_coupling_interval', config_slm_coupling_interval) + call mpas_set_timeInterval(slm_coupling_interval, YY=config_slm_coupling_interval, ierr=err_tmp) + err = ior(err,err_tmp) + call mpas_pool_get_array(meshPool, 'simulationStartTime', simulationStartTime) + call mpas_set_time(simulationStartTime_timeType, dateTimeString=simulationStartTime, ierr=err_tmp) + err = ior(err,err_tmp) + call mpas_add_clock_alarm(domain%clock, 'slmCouplingInterval', alarmTime=simulationStartTime_timeType, & + alarmTimeInterval=slm_coupling_interval, ierr=err_tmp) + err = ior(err,err_tmp) + if (mpas_is_alarm_ringing(domain%clock, 'slmCouplingInterval', ierr=err_tmp)) then + err = ior(err, err_tmp) + call mpas_reset_clock_alarm(domain%clock, 'slmCouplingInterval', ierr=err_tmp) + err = ior(err, err_tmp) + endif + ! initialize interpolation call interpolate_init(domain, err_tmp) err = ior(err, err_tmp) ! Set needed variables for using MPI - call mpas_pool_get_subpool(domain % blocklist % structs, 'mesh', meshPool) call mpas_pool_get_dimension(meshPool, 'nCells', nCellsAll) call mpas_pool_get_dimension(meshPool, 'nCellsSolve', nCellsOwned) call mpas_pool_get_array(meshPool, 'indexToCellID', indexToCellID) @@ -448,7 +470,7 @@ subroutine slmodel_init(domain, err) call sl_drive_readnl(itersl, dtime, starttime) !SLM subroutine ! First, check consistency in coupling interval set up in MALI and SLM - call check_SLM_coupling_interval(dtime, meshPool, domain % streamManager, err_tmp) + call check_SLM_coupling_interval(dtime, meshPool, err_tmp) err = ior(err, err_tmp) if (err /= 0) then call mpas_log_write("Error occurred in check_SLM_coupling_interval.", MPAS_LOG_ERR) @@ -985,7 +1007,7 @@ end subroutine check ! !----------------------------------------------------------------------- - subroutine check_SLM_coupling_interval(slm_dt1, meshPool, streamManager, err) + subroutine check_SLM_coupling_interval(slm_dt1, meshPool, err) use mpas_timekeeping use mpas_stream_manager @@ -993,18 +1015,16 @@ subroutine check_SLM_coupling_interval(slm_dt1, meshPool, streamManager, err) integer, intent (in) :: slm_dt1 type (mpas_pool_type), intent(in) :: meshPool !< mesh information - type (MPAS_streamManager_type), intent(inout) :: streamManager integer, intent(out) :: err ! local variables integer, pointer :: config_slm_coupling_interval logical, pointer :: config_adaptive_timestep character (len=StrKIND), pointer :: config_adaptive_timestep_force_interval, config_dt - type (MPAS_TimeInterval_Type) :: coupling_interval, force_interval, dt_interval, restart_interval, zero_interval + type (MPAS_TimeInterval_Type) :: coupling_interval, force_interval, dt_interval, zero_interval type (MPAS_Time_Type) :: start_time character (len=StrKIND), pointer :: simulationStartTime integer :: YYYY, MM, DD, H, M, S ! time components - type (MPAS_stream_list_type), pointer :: stream_cursor integer (kind=I8KIND) :: n_intervals type (MPAS_TimeInterval_type) :: remainder integer :: err_tmp @@ -1066,26 +1086,9 @@ subroutine check_SLM_coupling_interval(slm_dt1, meshPool, streamManager, err) endif endif - ! Now check that restart interval is an even multiple of coupling interval - stream_cursor => streamManager % streams % head - do while (associated(stream_cursor)) - if ( trim(stream_cursor % name) == 'restart' .and. (stream_cursor % active_stream) ) then - call mpas_log_write("Checking restart interval against SLM coulping interval") - restart_interval = MPAS_stream_mgr_get_stream_interval(streamManager, 'restart', MPAS_STREAM_OUTPUT, ierr=err_tmp) - err = ior(err, err_tmp) - call mpas_interval_division(start_time, restart_interval, coupling_interval, n_intervals, remainder) - if (remainder .EQ. zero_interval) then - call mpas_log_write("config_slm_coupling_interval divides into restart interval $i times " // & - "with no remainder - check passes", intArgs=(/int(n_intervals)/)) - else - call mpas_log_write("config_slm_coupling_interval divides into restart interval $i times " // & - "with nonzero remainder", MPAS_LOG_ERR, intArgs=(/int(n_intervals)/)) - err = ior(err, 1) - endif - endif + ! No need to compare restart interval and coupling interval because restarts with SLM are supported for + ! any restart interval now - stream_cursor => stream_cursor % next - enddo call mpas_log_write("") !-------------------------------------------------------------------- @@ -1118,7 +1121,7 @@ subroutine find_slm_restart_timestep(meshPool, slmTimeStep, err) ! local vars integer, pointer :: config_slm_coupling_interval character (len=StrKIND), pointer :: xtime, simulationStartTime - type (MPAS_TimeInterval_Type) :: coupling_interval, zero_interval + type (MPAS_TimeInterval_Type) :: coupling_interval type (MPAS_Time_Type) :: start_time, curr_time integer (kind=I8KIND) :: n_intervals type (MPAS_TimeInterval_type) :: remainder @@ -1141,17 +1144,9 @@ subroutine find_slm_restart_timestep(meshPool, slmTimeStep, err) err = ior(err, err_tmp) call mpas_interval_division(start_time, curr_time - start_time, coupling_interval, n_intervals, remainder) - call mpas_set_timeInterval(zero_interval, dt = 0.0_RKIND) - if (remainder .EQ. zero_interval) then - call mpas_log_write("SLM Restart check: config_slm_coupling_interval divides into elapsed time $i times " // & - "with no remainder - check passes", intArgs=(/int(n_intervals)/)) - slmTimeStep = int(n_intervals) - else - call mpas_log_write("SLM Restart check: config_slm_coupling_interval divides into elapsed time $i times " // & - "with nonzero remainder", MPAS_LOG_ERR, intArgs=(/int(n_intervals)/)) - err = ior(err, 1) - slmTimeStep = -999 - endif + slmTimeStep = int(n_intervals) + call mpas_log_write("SLM Restart check: Using SLM time level $i because config_slm_coupling_interval divides into " // & + "elapsed time that many times ", intArgs=(/int(slmTimeStep)/)) call mpas_log_write("") !-------------------------------------------------------------------- diff --git a/components/mpas-albany-landice/src/mode_forward/mpas_li_core.F b/components/mpas-albany-landice/src/mode_forward/mpas_li_core.F index 146b4e36d805..16c7c7807200 100644 --- a/components/mpas-albany-landice/src/mode_forward/mpas_li_core.F +++ b/components/mpas-albany-landice/src/mode_forward/mpas_li_core.F @@ -1105,13 +1105,11 @@ subroutine li_simulation_clock_init(core_clock, configs, ierr) type (MPAS_Time_Type) :: startTime, stopTime, alarmStartTime type (MPAS_TimeInterval_type) :: runDuration, timeStep, alarmTimeStep type (MPAS_TimeInterval_type) :: adaptDtForceInterval - type (MPAS_TimeInterval_type) :: slm_coupling_interval character (len=StrKIND), pointer :: config_start_time, config_run_duration, config_stop_time, & config_output_interval, config_restart_interval ! MPAS standard configs character (len=StrKIND), pointer :: config_dt ! MPAS LI-specific config option character (len=StrKIND), pointer :: config_adaptive_timestep_force_interval ! MPAS LI-specific config option character (len=StrKIND), pointer :: config_restart_timestamp_name - character (len=StrKIND), pointer :: config_uplift_method integer, pointer :: config_slm_coupling_interval character (len=StrKIND) :: restartTimeStamp !< string to be read from file integer, pointer :: config_year_digits @@ -1131,7 +1129,6 @@ subroutine li_simulation_clock_init(core_clock, configs, ierr) call mpas_pool_get_config(configs, 'config_stop_time', config_stop_time) call mpas_pool_get_config(configs, 'config_restart_timestamp_name', config_restart_timestamp_name) call mpas_pool_get_config(configs, 'config_adaptive_timestep_force_interval', config_adaptive_timestep_force_interval) - call mpas_pool_get_config(configs, 'config_uplift_method', config_uplift_method) call mpas_pool_get_config(configs, 'config_slm_coupling_interval', config_slm_coupling_interval) @@ -1196,20 +1193,6 @@ subroutine li_simulation_clock_init(core_clock, configs, ierr) endif ierr = ior(ierr, err_tmp) - ! Set up the coupling time interval if MALI is coupled to sea-level model - if (trim(config_uplift_method) == "sealevelmodel") then - call mpas_set_timeInterval(slm_coupling_interval, YY=config_slm_coupling_interval, ierr=err_tmp) - ierr = ior(ierr,err_tmp) - call mpas_add_clock_alarm(core_clock, 'slmCouplingInterval', alarmTime=startTime, & - alarmTimeInterval=slm_coupling_interval, ierr=err_tmp) - ierr = ior(ierr,err_tmp) - if (mpas_is_alarm_ringing(core_clock, 'slmCouplingInterval', ierr=err_tmp)) then - ierr = ior(ierr, err_tmp) - call mpas_reset_clock_alarm(core_clock, 'slmCouplingInterval', ierr=err_tmp) - ierr = ior(ierr, err_tmp) - endif - endif - ! === error check if (ierr /= 0) then call mpas_log_write("An error has occurred in li_simulation_clock_init.", MPAS_LOG_ERR) From be5f341ce4d50beb4393df4f1dc386b4e6fb59df Mon Sep 17 00:00:00 2001 From: Matthew Hoffman Date: Fri, 23 Feb 2024 20:17:19 -0700 Subject: [PATCH 054/451] Add addl info on restart about the calculated time since last SLM call This doesn't serve any internal purpose, but it could help a user detect an error in their configuration. --- .../src/mode_forward/mpas_li_bedtopo.F | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/components/mpas-albany-landice/src/mode_forward/mpas_li_bedtopo.F b/components/mpas-albany-landice/src/mode_forward/mpas_li_bedtopo.F index 4ead2074546f..b3461a52ae41 100644 --- a/components/mpas-albany-landice/src/mode_forward/mpas_li_bedtopo.F +++ b/components/mpas-albany-landice/src/mode_forward/mpas_li_bedtopo.F @@ -1125,6 +1125,7 @@ subroutine find_slm_restart_timestep(meshPool, slmTimeStep, err) type (MPAS_Time_Type) :: start_time, curr_time integer (kind=I8KIND) :: n_intervals type (MPAS_TimeInterval_type) :: remainder + character (len=StrKIND) :: remainder_string integer :: err_tmp err = 0 @@ -1135,7 +1136,6 @@ subroutine find_slm_restart_timestep(meshPool, slmTimeStep, err) call mpas_set_timeInterval(coupling_interval, YY=config_slm_coupling_interval, MM=0, DD=0, H=0, M=0, S=0, ierr=err_tmp) err = ior(err, err_tmp) - call mpas_pool_get_array(meshPool, 'simulationStartTime', simulationStartTime) call mpas_pool_get_array(meshPool, 'xtime', xtime) call mpas_set_time(start_time, dateTimeString=simulationStartTime, ierr=err_tmp) @@ -1145,8 +1145,12 @@ subroutine find_slm_restart_timestep(meshPool, slmTimeStep, err) call mpas_interval_division(start_time, curr_time - start_time, coupling_interval, n_intervals, remainder) slmTimeStep = int(n_intervals) - call mpas_log_write("SLM Restart check: Using SLM time level $i because config_slm_coupling_interval divides into " // & + call mpas_get_timeInterval(remainder, start_time, timeString=remainder_string, ierr=err_tmp) + err = ior(err, err_tmp) + call mpas_log_write("SLM Restart: Using SLM time level $i because config_slm_coupling_interval divides into " // & "elapsed time that many times ", intArgs=(/int(slmTimeStep)/)) + call mpas_log_write(" That calculation implies it has been " // trim(remainder_string) // " since last SLM coupling. " // & + "If that interval seems wrong, there may be an error in your configuration.") call mpas_log_write("") !-------------------------------------------------------------------- From 052b15de927db57d213bdc8e4eeba57237e9a8e6 Mon Sep 17 00:00:00 2001 From: Matthew Hoffman Date: Fri, 23 Feb 2024 20:46:11 -0700 Subject: [PATCH 055/451] Don't call SLM on init of a restart It's not needed, and if the restart time is not a coupling interval, it will make the SLM get out of sync. --- .../src/mode_forward/mpas_li_bedtopo.F | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/components/mpas-albany-landice/src/mode_forward/mpas_li_bedtopo.F b/components/mpas-albany-landice/src/mode_forward/mpas_li_bedtopo.F index b3461a52ae41..d5aaf12672bd 100644 --- a/components/mpas-albany-landice/src/mode_forward/mpas_li_bedtopo.F +++ b/components/mpas-albany-landice/src/mode_forward/mpas_li_bedtopo.F @@ -501,10 +501,13 @@ subroutine slmodel_init(domain, err) call find_slm_restart_timestep(meshPool, slmTimeStep, err_tmp) err = ior(err, err_tmp) - if (err == 0) then - call mpas_log_write("Calling the SLM. SLM timestep $i", intArgs=(/slmTimeStep/)) - call slmodel_solve(slmTimeStep, domain) - endif + + ! Note: no need to call slmodel_solve on init of a restart. + ! If this time level happens to be a coupling interval, SLM would have been solved already + ! in the previous run that generated the restart file. + ! While it would not hurt (other than unneeded execution time) to call SLM again if the + ! restart time level happens to be a coupling interval, if the restart time is in between + ! coupling intervals calling SLM here will make things out of sync. else From 8b89b6fc87e9a0dbbd272d786e18f550b314a151 Mon Sep 17 00:00:00 2001 From: Walter Hannah Date: Mon, 26 Feb 2024 16:05:17 -0800 Subject: [PATCH 056/451] adjust default MMF2 configuration --- components/eam/cime_config/config_component.xml | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/components/eam/cime_config/config_component.xml b/components/eam/cime_config/config_component.xml index c7585072ac94..16ff080ae839 100755 --- a/components/eam/cime_config/config_component.xml +++ b/components/eam/cime_config/config_component.xml @@ -75,10 +75,11 @@ -crm pam -pam_dycor spam -crm_dt 8 -crm pam -pam_dycor awfl -crm_dt 8 -use_MMF -nlev 60 -crm_nz 50 - -crm_dx 2000 -crm_nx 64 -crm_ny 1 + -crm_dx 2000 -crm_nx 64 -crm_ny 1 -crm_nx_rad 4 -crm_ny_rad 1 + -crm_dx 2000 -crm_nx 45 -crm_ny 1 -crm_nx_rad 5 -crm_ny_rad 1 -MMF_microphysics_scheme sam1mom -chem none -MMF_microphysics_scheme p3 -chem none - -crm_nx_rad 4 -crm_ny_rad 1 -rad rrtmgp -rrtmgpxx + -rad rrtmgp -rrtmgpxx -use_MMF_VT -use_MMF_ESMT -aquaplanet From ef9d3281c9051dadc2627f6abcf9d4e0308647bd Mon Sep 17 00:00:00 2001 From: Walter Hannah Date: Tue, 27 Feb 2024 08:18:08 -0800 Subject: [PATCH 057/451] add PAM coupler options to override SPAM parameter defaults --- components/eam/src/physics/crm/pam/pam_driver.cpp | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/components/eam/src/physics/crm/pam/pam_driver.cpp b/components/eam/src/physics/crm/pam/pam_driver.cpp index 128974a856e4..c325945f8803 100644 --- a/components/eam/src/physics/crm/pam/pam_driver.cpp +++ b/components/eam/src/physics/crm/pam/pam_driver.cpp @@ -54,6 +54,14 @@ extern "C" void pam_driver() { coupler.set_option("sponge_time_scale",60); // minimum damping timescale at top coupler.set_option("crm_acceleration_ceaseflag",false); //------------------------------------------------------------------------------------------------ + // coupler options for SPAM dycor + coupler.set_option("spam_couple_wind_exact_inverse",true); + coupler.set_option("spam_clip_negative_densities",true); + coupler.set_option("spam_clip_vertical_velocities",true); + coupler.set_option("spam_adjust_crm_per_phys_using_vert_cfl",true); + coupler.set_option("spam_target_cfl",0.7); + coupler.set_option("spam_max_w",50.0); + //------------------------------------------------------------------------------------------------ // Allocate the coupler state and retrieve host/device data managers coupler.allocate_coupler_state( crm_nz , crm_ny , crm_nx , nens ); From 644bf4c00c6dc3295fc3996455318e0fdd6f9c51 Mon Sep 17 00:00:00 2001 From: Walter Hannah Date: Tue, 27 Feb 2024 08:24:59 -0800 Subject: [PATCH 058/451] update pam_state_recall_dry_density --- .../eam/src/physics/crm/pam/pam_state.h | 54 +++++++++++-------- 1 file changed, 31 insertions(+), 23 deletions(-) diff --git a/components/eam/src/physics/crm/pam/pam_state.h b/components/eam/src/physics/crm/pam/pam_state.h index 34cc42a4a788..3266899ba217 100644 --- a/components/eam/src/physics/crm/pam/pam_state.h +++ b/components/eam/src/physics/crm/pam/pam_state.h @@ -258,6 +258,13 @@ inline void pam_state_save_dry_density( pam::PamCoupler &coupler ) { // recall CRM dry density saved previously - only for anelastic case +// Note - The need for this arises because the SPAM dycor diagnoses the dry +// density in a way that preserves the total density to match the reference +// density. However, this is problematic in the presence of the GCM forcing +// which naturally changes the total density. Therefore, we can recall the +// previous dry density and use it to replace the horizontal mean returned from +// the dycor, which ensures that the impact of GCM forcing is preserved while +// also retaining the dry density perturbations created by the dycor. inline void pam_state_recall_dry_density( pam::PamCoupler &coupler ) { using yakl::c::parallel_for; using yakl::c::SimpleBounds; @@ -270,29 +277,30 @@ inline void pam_state_recall_dry_density( pam::PamCoupler &coupler ) { auto crm_rho_d = dm_device.get("density_dry"); auto tmp_rho_d = dm_device.get("density_dry_save"); //------------------------------------------------------------------------------------------------ - #ifdef MMF_ALT_DENSITY_RECALL - // initialize horizontal mean of previous CRM dry density - real2d old_hmean_rho_d("old_hmean_rho_d" ,nz,nens); - real2d new_hmean_rho_d("new_hmean_rho_d" ,nz,nens); - parallel_for(SimpleBounds<2>(nz,nens), YAKL_LAMBDA (int k, int iens) { - old_hmean_rho_d(k,iens) = 0; - new_hmean_rho_d(k,iens) = 0; - }); - real r_nx_ny = 1._fp/(nx*ny); // precompute reciprocal to avoid costly divisions - // calculate horizontal mean of previous CRM dry density - parallel_for(SimpleBounds<4>(nz,ny,nx,nens), YAKL_LAMBDA (int k, int j, int i, int iens) { - atomicAdd( old_hmean_rho_d(k,iens), tmp_rho_d(k,j,i,iens) * r_nx_ny ); - atomicAdd( new_hmean_rho_d(k,iens), crm_rho_d(k,j,i,iens) * r_nx_ny ); - }); - // replace horizontal mean dry density with prevoius value - parallel_for(SimpleBounds<4>(nz,ny,nx,nens), YAKL_LAMBDA (int k, int j, int i, int iens) { - crm_rho_d(k,j,i,iens) = crm_rho_d(k,j,i,iens) - new_hmean_rho_d(k,iens) + old_hmean_rho_d(k,iens); - }); - #else - parallel_for( "Recall CRM dry density",SimpleBounds<4>(nz,ny,nx,nens),YAKL_LAMBDA (int k_crm, int j, int i, int iens) { - crm_rho_d(k_crm,j,i,iens) = tmp_rho_d(k_crm,j,i,iens); - }); - #endif + // initialize horizontal mean of previous CRM dry density + real2d old_hmean_rho_d("old_hmean_rho_d" ,nz,nens); + real2d new_hmean_rho_d("new_hmean_rho_d" ,nz,nens); + parallel_for(SimpleBounds<2>(nz,nens), YAKL_LAMBDA (int k, int iens) { + old_hmean_rho_d(k,iens) = 0; + new_hmean_rho_d(k,iens) = 0; + }); + real r_nx_ny = 1._fp/(nx*ny); // precompute reciprocal to avoid costly divisions + // calculate horizontal mean of previous CRM dry density + parallel_for(SimpleBounds<4>(nz,ny,nx,nens), YAKL_LAMBDA (int k, int j, int i, int iens) { + atomicAdd( old_hmean_rho_d(k,iens), tmp_rho_d(k,j,i,iens) * r_nx_ny ); + atomicAdd( new_hmean_rho_d(k,iens), crm_rho_d(k,j,i,iens) * r_nx_ny ); + }); + // replace horizontal mean dry density with previous value + parallel_for(SimpleBounds<4>(nz,ny,nx,nens), YAKL_LAMBDA (int k, int j, int i, int iens) { + crm_rho_d(k,j,i,iens) = crm_rho_d(k,j,i,iens) - new_hmean_rho_d(k,iens) + old_hmean_rho_d(k,iens); + }); + //------------------------------------------------------------------------------------------------ + // Original simple appraoch to completely reinstate the previous dry density field + // (this was shown to negatively impact the model stability) + // This was used initially, but the above + // parallel_for( "Recall CRM dry density",SimpleBounds<4>(nz,ny,nx,nens),YAKL_LAMBDA (int k_crm, int j, int i, int iens) { + // crm_rho_d(k_crm,j,i,iens) = tmp_rho_d(k_crm,j,i,iens); + // }); //------------------------------------------------------------------------------------------------ } From 6b7dcbeae6ac486a59041eb78e882ae06e1a8ea0 Mon Sep 17 00:00:00 2001 From: Walter Hannah Date: Tue, 27 Feb 2024 08:37:57 -0800 Subject: [PATCH 059/451] update PAM submodule --- components/eam/src/physics/crm/pam/external | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/components/eam/src/physics/crm/pam/external b/components/eam/src/physics/crm/pam/external index 87731d56aeee..9d692dccdd67 160000 --- a/components/eam/src/physics/crm/pam/external +++ b/components/eam/src/physics/crm/pam/external @@ -1 +1 @@ -Subproject commit 87731d56aeee4bfae4750e17732828ba186367a7 +Subproject commit 9d692dccdd67d9c4dc278c76290504a2af8cd187 From 40a442cbb3a3a5ab4cf1c570be56dadaed2d66ea Mon Sep 17 00:00:00 2001 From: Andrew Nolan Date: Tue, 5 Mar 2024 08:47:11 -0800 Subject: [PATCH 060/451] Use `regionEdgeMask` to calculate SGH regional stats defined on edges. Addes `regionEdgeMask` and `regionVertexMask` to the registry so the additional mask variables can be included in the `regionsInput` stream. --- .../mpas-albany-landice/src/Registry.xml | 10 +++- .../analysis_members/mpas_li_regional_stats.F | 58 +++++++++++-------- 2 files changed, 42 insertions(+), 26 deletions(-) diff --git a/components/mpas-albany-landice/src/Registry.xml b/components/mpas-albany-landice/src/Registry.xml index a1ddaf744018..4fc54d8c2390 100644 --- a/components/mpas-albany-landice/src/Registry.xml +++ b/components/mpas-albany-landice/src/Registry.xml @@ -1,4 +1,4 @@ - +/?xml version="1.0"?> @@ -936,6 +936,8 @@ input_interval="initial_only" runtime_format="single_file"> + + @@ -937,10 +938,9 @@ runtime_format="single_file"> - 3x3min @@ -176,6 +177,8 @@ attributes from the config_cache.xml file (with keys converted to upper-case). 0.5x0.5 0.5x0.5 5x5min +0.1x0.1 + mksrf_flakwat @@ -203,6 +206,7 @@ attributes from the config_cache.xml file (with keys converted to upper-case). mksrf_fslp10 mksrf_fero mksrf_ffert +mksrf_ftoprad lnd/clm2/rawdata/mksrf_navyoro_20min.c010129.nc @@ -313,6 +317,9 @@ attributes from the config_cache.xml file (with keys converted to upper-case). lnd/clm2/rawdata/mksrf_fert.c220309.nc +lnd/clm2/rawdata/mksrf_toprad_0.1x0.1.c231218.nc + diff --git a/components/elm/bld/namelist_files/namelist_definition.xml b/components/elm/bld/namelist_files/namelist_definition.xml index 8182c6d90666..10a9f98ee8e5 100644 --- a/components/elm/bld/namelist_files/namelist_definition.xml +++ b/components/elm/bld/namelist_files/namelist_definition.xml @@ -772,7 +772,7 @@ in its attributes. (Only used if scripgriddata_src_type = UGRID.) + valid_values="mksrf_fsoitex,mksrf_forganic,mksrf_flakwat,mksrf_fwetlnd,mksrf_fmax,mksrf_fmax,mksrf_fglacier,mksrf_fvocef,mksrf_furbtopo,mksrf_flndtopo,firrig,mksrf_furban,mksrf_fvegtyp,mksrf_fsoicol,mksrf_fsoiord,mksrf_flai,mksrf_fgdp,mksrf_fpeat,mksrf_fabm,mksrf_ftopostats,mksrf_fvic,mksrf_fch4,mksrf_fgrvl,mksrf_fslp10,mksrf_fero,mksrf_ffert,mksrf_ftoprad" > Filename for mksurfdata_map to remap raw data into the output surface dataset @@ -931,10 +931,15 @@ ELM-Erosion parameters dataset + input_pathname="abs" group="elmexp" valid_values="" > ELM-Fertilizer dataset + +Topography parameters dataset for TOP solar radiation parameterization + + If TRUE, output variables in double precision for mksurfdata diff --git a/components/elm/tools/mksurfdata_map/mksurfdata.pl b/components/elm/tools/mksurfdata_map/mksurfdata.pl index 222a9c51bd15..05389d0d579d 100755 --- a/components/elm/tools/mksurfdata_map/mksurfdata.pl +++ b/components/elm/tools/mksurfdata_map/mksurfdata.pl @@ -421,8 +421,8 @@ ($) my $mkopts = "-csmdata $CSMDATA -silent -justvalue -namelist elmexp $usrnam"; foreach my $typ ( "lak", "veg", "voc", "top", "tex", "col","ord", "fmx", "lai", "urb", "org", "glc", "utp", "wet", - "gdp", "peat","abm", "topostats" , "vic", "ch4", - "pho", "grvl", "slp10", "ero", "fert") { + "gdp", "peat","abm", "topostats" , "vic", "ch4", + "pho", "grvl", "slp10", "ero", "fert", "toprad") { my $lmask = `$scrdir/../../bld/queryDefaultNamelist.pl $mopts -silent -options type=$typ,mergeGIS=$merge_gis,hirespft=$hirespft -var lmask`; $lmask = trim($lmask); my $hgrid = `$scrdir/../../bld/queryDefaultNamelist.pl $mopts -options type=$typ,hirespft=$hirespft -var hgrid`; @@ -539,6 +539,7 @@ ($) map_fslp10 = '$map{'slp10'}' map_fero = '$map{'ero'}' map_ffert = '$map{'fert'}' + map_ftoprad = '$map{'toprad'}' mksrf_fsoitex = '$datfil{'tex'}' mksrf_forganic = '$datfil{'org'}' mksrf_flakwat = '$datfil{'lak'}' @@ -563,6 +564,7 @@ ($) mksrf_fslp10 = '$datfil{'slp10'}' mksrf_fero = '$datfil{'ero'}' mksrf_ffert = '$datfil{'fert'}' + mksrf_ftoprad = '$datfil{'toprad'}' EOF my $urbdesc = "urb3den"; my $rcp_option= ""; diff --git a/components/elm/tools/mksurfdata_map/src/Srcfiles b/components/elm/tools/mksurfdata_map/src/Srcfiles index f8bda5dcf61b..96cec841a941 100644 --- a/components/elm/tools/mksurfdata_map/src/Srcfiles +++ b/components/elm/tools/mksurfdata_map/src/Srcfiles @@ -28,6 +28,7 @@ mkVICparamsMod.F90 mkCH4inversionMod.F90 mkSedMod.F90 mkFertMod.F90 +mktopradMod.F90 nanMod.F90 shr_file_mod.F90 shr_sys_mod.F90 diff --git a/components/elm/tools/mksurfdata_map/src/mkfileMod.F90 b/components/elm/tools/mksurfdata_map/src/mkfileMod.F90 index c3f67cc7a12c..50b029efc7d5 100644 --- a/components/elm/tools/mksurfdata_map/src/mkfileMod.F90 +++ b/components/elm/tools/mksurfdata_map/src/mkfileMod.F90 @@ -15,6 +15,7 @@ subroutine mkfile(domain, fname, dynlanduse) use mkpftMod , only : mkpftAtt use mksoilMod , only : mksoilAtt use mkSedMod , only : mksedAtt + use mktopradMod , only : mktopradAtt use mkharvestMod , only : mkharvest_fieldname, mkharvest_numtypes, mkharvest_longname use mkncdio , only : check_ret, ncd_defvar use mkdomainMod @@ -297,6 +298,10 @@ subroutine mkfile(domain, fname, dynlanduse) call check_ret(nf_put_att_text(ncid, NF_GLOBAL, & 'map_fertilizer_file', len_trim(str), trim(str)), subname) + str = get_filename(map_ftoprad) + call check_ret(nf_put_att_text(ncid, NF_GLOBAL, & + 'map_ftoprad_file', len_trim(str), trim(str)), subname) + ! ---------------------------------------------------------------------- ! Define variables ! ---------------------------------------------------------------------- @@ -313,6 +318,8 @@ subroutine mkfile(domain, fname, dynlanduse) call mksedAtt( ncid, dynlanduse, xtype ) + call mktopradAtt( ncid, dynlanduse, xtype ) + if (outnc_1d) then call ncd_defvar(ncid=ncid, varname='AREA' , xtype=nf_double, & dim1name='gridcell',& diff --git a/components/elm/tools/mksurfdata_map/src/mksurfdat.F90 b/components/elm/tools/mksurfdata_map/src/mksurfdat.F90 index d062907cdccf..a936c43052b9 100644 --- a/components/elm/tools/mksurfdata_map/src/mksurfdat.F90 +++ b/components/elm/tools/mksurfdata_map/src/mksurfdat.F90 @@ -44,7 +44,9 @@ program mksurfdat use mkCH4inversionMod , only : mkCH4inversion use mksoilphosphorusMod, only : mksoilphosphorus use mkSedMod , only : mkgrvl, mkslp10, mkEROparams - use mkFertMod , only : mkfert! + use mkFertMod , only : mkfert + use mktopradMod , only : mktoprad +! ! !ARGUMENTS: implicit none @@ -152,6 +154,10 @@ program mksurfdat real(r8), allocatable :: litho(:) ! lithology erodiblity index (unitless) real(r8), allocatable :: nfert(:,:) ! crop nitrogen fertilizer (g/m^2) real(r8), allocatable :: pfert(:,:) ! crop phosphorus fertilizer (g/m^2) + real(r8), allocatable :: sinsl_sinas(:) ! sin(slope)*sin(aspect) / cos(slope) + real(r8), allocatable :: sinsl_cosas(:) ! sin(slope)*cos(aspect) / cos(slope) + real(r8), allocatable :: sky_view(:) ! mean of (sky view factor / cos(slope)) + real(r8), allocatable :: terrain_config(:) ! mean of (terrain configuration factor / cos(slope)) type(domain_type) :: ldomain @@ -187,6 +193,7 @@ program mksurfdat mksrf_fslp10, & mksrf_fero, & mksrf_ffert, & + mksrf_ftoprad, & nglcec, & numpft, & soil_color, & @@ -224,6 +231,7 @@ program mksurfdat map_fslp10, & map_ffert, & map_fero, & + map_ftoprad, & outnc_large_files, & outnc_double, & outnc_dims, & @@ -264,8 +272,9 @@ program mksurfdat ! mksrf_fphosphorus Soil phosphorus dataset ! mksrf_fgrvl ---- Soil gravel content dataset ! mksrf_fslp10 --- Slope percentile dataset - ! mksrf_fero ----- ELM-Erosion parameters dataset + ! mksrf_fero ----- ELM-Erosion parameters dataset ! mksrf_ffert ---- Crop Fertilizer dataset + ! mksrf_ftoprad --- TOP parameters dataset for solar radiation parameterization ! ====================================== ! Must specify mapping file for the different datafiles above ! ====================================== @@ -295,6 +304,7 @@ program mksurfdat ! map_fslp10 ------ Mapping for mksrf_fslp10 ! map_fero -------- Mapping for mksrf_fero ! map_ffert ------- Mapping for mksrf_ffert + ! map_ftoprad_______ Mapping for mksrf_ftoprad ! ====================================== ! Optionally specify setting for: ! ====================================== @@ -464,7 +474,11 @@ program mksurfdat tillage(ns_o) , & litho(ns_o) , & nfert(ns_o,0:numpft) , & - pfert(ns_o,0:numpft) ) + pfert(ns_o,0:numpft) , & + sinsl_sinas(ns_o) , & + sinsl_cosas(ns_o) , & + sky_view(ns_o) , & + terrain_config(ns_o) ) landfrac_pft(:) = spval pctlnd_pft(:) = spval @@ -511,6 +525,10 @@ program mksurfdat litho(:) = spval nfert(:,:) = 0._r8 pfert(:,:) = 0._r8 + sinsl_sinas(:) = spval + sinsl_cosas(:) = spval + sky_view(:) = spval + terrain_config(:) = spval ! ---------------------------------------------------------------------- ! Open diagnostic output log file @@ -581,6 +599,7 @@ program mksurfdat write(ndiag,*)' mapping for slope percentile ',trim(map_fslp10) write(ndiag,*)' mapping for erosion params ',trim(map_fero) write(ndiag,*)' mapping for fertilizer ',trim(map_ffert) + write(ndiag,*)' mapping for TOP params ',trim(map_ftoprad) if (mksrf_fdynuse /= ' ') then write(6,*)'mksrf_fdynuse = ',trim(mksrf_fdynuse) @@ -768,6 +787,12 @@ program mksurfdat nfert_o=nfert, pfert_o=pfert) end if + call mktoprad(ldomain, mapfname=map_ftoprad, datfname=mksrf_ftoprad, varname = 'SINSL_SINAS', ndiag=ndiag, top_o=sinsl_sinas, nodata=0.0_r8) + call mktoprad(ldomain, mapfname=map_ftoprad, datfname=mksrf_ftoprad, varname = 'SINSL_COSAS', ndiag=ndiag, top_o=sinsl_cosas, nodata=0.0_r8) + call mktoprad(ldomain, mapfname=map_ftoprad, datfname=mksrf_ftoprad, varname = 'SKY_VIEW', ndiag=ndiag, top_o=sky_view, nodata=1.0_r8) + call mktoprad(ldomain, mapfname=map_ftoprad, datfname=mksrf_ftoprad, varname = 'TERRAIN_CONFIG', ndiag=ndiag, top_o=terrain_config, nodata=0.0_r8) + + do n = 1,ns_o ! Assume wetland and/or lake when dataset landmask implies ocean @@ -797,6 +822,10 @@ program mksurfdat litho(n) = 0._r8 nfert(n,:) = 0._r8 pfert(n,:) = 0._r8 + sinsl_sinas(n) = 0._r8 + sinsl_cosas(n) = 0._r8 + sky_view(n) = 1._r8 + terrain_config(n)= 0._r8 else pftdata_mask(n) = 1 end if @@ -1103,6 +1132,18 @@ program mksurfdat call check_ret(nf_inq_varid(ncid, 'Litho', varid), subname) call check_ret(nf_put_var_double(ncid, varid, litho), subname) + call check_ret(nf_inq_varid(ncid, 'SINSL_SINAS', varid), subname) + call check_ret(nf_put_var_double(ncid, varid, sinsl_sinas), subname) + + call check_ret(nf_inq_varid(ncid, 'SINSL_COSAS', varid), subname) + call check_ret(nf_put_var_double(ncid, varid, sinsl_cosas), subname) + + call check_ret(nf_inq_varid(ncid, 'SKY_VIEW', varid), subname) + call check_ret(nf_put_var_double(ncid, varid, sky_view), subname) + + call check_ret(nf_inq_varid(ncid, 'TERRAIN_CONFIG', varid), subname) + call check_ret(nf_put_var_double(ncid, varid, terrain_config), subname) + ! Deallocate arrays NOT needed for dynamic-pft section of code deallocate ( organic ) @@ -1123,6 +1164,7 @@ program mksurfdat deallocate ( grvl, slp10 ) deallocate ( ero_c1, ero_c2, ero_c3, tillage, litho ) deallocate ( nfert, pfert ) + deallocate ( sinsl_sinas, sinsl_cosas, sky_view, terrain_config ) ! Synchronize the disk copy of a netCDF dataset with in-memory buffers call check_ret(nf_sync(ncid), subname) diff --git a/components/elm/tools/mksurfdata_map/src/mktopradMod.F90 b/components/elm/tools/mksurfdata_map/src/mktopradMod.F90 new file mode 100644 index 000000000000..e8ea66f9de49 --- /dev/null +++ b/components/elm/tools/mksurfdata_map/src/mktopradMod.F90 @@ -0,0 +1,239 @@ +module mktopradMod +!----------------------------------------------------------------------- +!BOP +! +! !MODULE: mktopradMod +! +! !DESCRIPTION: +! Make topography data for TOP solar radiation parameterization +! +! !REVISION HISTORY: +! Author: Dalei Hao +! +!----------------------------------------------------------------------- +!!USES: + use shr_kind_mod, only : r8 => shr_kind_r8 + use shr_sys_mod , only : shr_sys_flush + implicit none + + SAVE + private ! By default make data private +! +! !PUBLIC MEMBER FUNCTIONS: +! + public mktopradAtt ! Add attributes to output file + + public mktoprad ! Set topography +! +! !PUBLIC DATA MEMBERS: +! +! +! !PRIVATE DATA MEMBERS: +! +! !PRIVATE MEMBER FUNCTIONS: + +!EOP +!=============================================================== +contains +!=============================================================== + +!----------------------------------------------------------------------- +!BOP +! +! !IROUTINE: mktoprad +! +! !INTERFACE: +subroutine mktoprad(ldomain, mapfname, datfname, varname, ndiag, top_o, nodata) +! +! !DESCRIPTION: +! Make topography data for TOP solar radiation parameterization +! +! !USES: + use mkdomainMod , only : domain_type, domain_clean, domain_read, domain_checksame + use mkgridmapMod + use mkvarpar + use mkvarctl + use mkncdio +! +! !ARGUMENTS: + implicit none + type(domain_type), intent(in) :: ldomain + character(len=*) , intent(in) :: mapfname ! input mapping file name + character(len=*) , intent(in) :: datfname ! input data file name + integer , intent(in) :: ndiag ! unit number for diag out + character(len=*) , intent(in) :: varname ! topo variable name + real(r8) , intent(out):: top_o(:) ! output topography data + real(r8) , intent(in) :: nodata ! default value +! +! +! !CALLED FROM: +! subroutine mksrfdat in module mksrfdatMod +! +! !REVISION HISTORY: +! Author: Dalei Hao +! +! +! !LOCAL VARIABLES: +!EOP + type(domain_type) :: tdomain ! local domain + type(gridmap_type) :: tgridmap ! local gridmap + + real(r8), allocatable :: top_i(:) ! input top variable + real(r8), allocatable :: mask_i(:) ! input grid: mask (0, 1) + integer :: ns_i,ns_o ! indices + integer :: k,l,n,m,ni ! indices + integer :: ncidi,dimid,varid ! input netCDF id's + integer :: ier ! error status + character(len=256) :: name ! name of attribute + character(len=256) :: unit ! units of attribute + character(len= 32) :: subname = 'mktop' +!----------------------------------------------------------------------- + + write (6,*) 'Attempting to make topography .....' + call shr_sys_flush(6) + + ns_o = ldomain%ns + + ! ----------------------------------------------------------------- + ! Read input file + ! ----------------------------------------------------------------- + + ! Obtain input grid info, read local fields + + call domain_read(tdomain,datfname) + + ns_i = tdomain%ns + allocate(top_i(ns_i), stat=ier) + if (ier /= 0) then + write(6,*)'mktoprad allocation error'; call abort() + end if + + write (6,*) 'Open topography file: ', trim(datfname) + call check_ret(nf_open(datfname, 0, ncidi), subname) + call check_ret(nf_inq_varid (ncidi, trim(varname), varid), subname) + call check_ret(nf_get_var_double (ncidi, varid, top_i), subname) + call check_ret(nf_close(ncidi), subname) + + ! Read topo dataset + call gridmap_mapread(tgridmap, mapfname) + + ! Error checks for domain and map consistencies + ! Note that the topo dataset has no landmask - so a unit landmask is assumed + + call domain_checksame( tdomain, ldomain, tgridmap ) + + ! Determine top_o on output grid + + top_o(:) = nodata + + call gridmap_areaave(tgridmap, top_i, top_o, nodata=nodata) + + ! Deallocate dynamic memory + + call domain_clean(tdomain) + call gridmap_clean(tgridmap) + deallocate (top_i) + + write (6,*) 'Successfully made topography parameters' + write (6,*) + call shr_sys_flush(6) + +end subroutine mktoprad + +!----------------------------------------------------------------------- + +!----------------------------------------------------------------------- +!BOP +! +! !IROUTINE: mktopradAtt +! +! !INTERFACE: +subroutine mktopradAtt( ncid, dynlanduse, xtype ) +! +! !DESCRIPTION: +! add atttributes to output file regarding the topography module +! +! !USES: + use fileutils , only : get_filename + use mkncdio , only : check_ret, ncd_defvar + use mkvarpar + use mkvarctl + +! !ARGUMENTS: + implicit none + include 'netcdf.inc' + integer, intent(in) :: ncid ! NetCDF file ID to write out to + logical, intent(in) :: dynlanduse ! if dynamic land-use file + integer, intent(in) :: xtype ! external type to output real data as +! +! !CALLED FROM: +! subroutine mkfile in module mkfileMod +! +! !REVISION HISTORY: +! Original Author: Dalei Hao +! +! +! !LOCAL VARIABLES: +!EOP + integer :: dimid ! temporary + character(len=256) :: str ! global attribute string + character(len=32) :: subname = 'mktopAtt' +!----------------------------------------------------------------------- + + if (.not. dynlanduse) then + + ! Add global attributes to file + + str = get_filename(mksrf_fgrvl) + call check_ret(nf_put_att_text(ncid, NF_GLOBAL, & + 'top_raw_data_file_name', len_trim(str), trim(str)), subname) + + ! Define variables + + if (outnc_1d) then + call ncd_defvar(ncid=ncid, varname='SINSL_COSAS', xtype=xtype, & + dim1name='gridcell',& + long_name='sin(slope) * cos(aspect)', units='unitless') + else + call ncd_defvar(ncid=ncid, varname='SINSL_COSAS', xtype=xtype, & + dim1name='lsmlon', dim2name='lsmlat', & + long_name='sin(slope) * cos(aspect)', units='unitless') + end if + + if (outnc_1d) then + call ncd_defvar(ncid=ncid, varname='SINSL_SINAS', xtype=xtype, & + dim1name='gridcell',& + long_name='sin(slope) * sin(aspect)', units='unitless') + else + call ncd_defvar(ncid=ncid, varname='SINSL_SINAS', xtype=xtype, & + dim1name='lsmlon', dim2name='lsmlat', & + long_name='sin(slope) * sin(aspect)', units='unitless') + end if + + if (outnc_1d) then + call ncd_defvar(ncid=ncid, varname='SKY_VIEW', xtype=xtype, & + dim1name='gridcell',& + long_name='sky view factor', units='unitless') + else + call ncd_defvar(ncid=ncid, varname='SKY_VIEW', xtype=xtype, & + dim1name='lsmlon', dim2name='lsmlat', & + long_name='sky view factor', units='unitless') + end if + + if (outnc_1d) then + call ncd_defvar(ncid=ncid, varname='TERRAIN_CONFIG', xtype=xtype, & + dim1name='gridcell',& + long_name='terrain configuration factor', units='unitless') + else + call ncd_defvar(ncid=ncid, varname='TERRAIN_CONFIG', xtype=xtype, & + dim1name='lsmlon', dim2name='lsmlat', & + long_name='terrain configuration factor', units='unitless') + end if + + end if + +end subroutine mktopradAtt + +!----------------------------------------------------------------------- + +end module mktopradMod diff --git a/components/elm/tools/mksurfdata_map/src/mkvarctl.F90 b/components/elm/tools/mksurfdata_map/src/mkvarctl.F90 index 48e745833749..127f0e83124b 100644 --- a/components/elm/tools/mksurfdata_map/src/mkvarctl.F90 +++ b/components/elm/tools/mksurfdata_map/src/mkvarctl.F90 @@ -52,7 +52,8 @@ module mkvarctl character(len=256), public :: mksrf_fslp10 = ' ' ! slope percentile file name character(len=256), public :: mksrf_fero = ' ' ! ELM-Erosion parameters data file name character(len=256), public :: mksrf_ffert = ' ' ! crop fertilizer data file name - integer , public :: numpft = 16 ! number of plant types + character(len=256), public :: mksrf_ftoprad = ' ' ! topography parameters data file name for TOP solar radiation parameterization + integer , public :: numpft = 16 ! number of plant types character(len=256), public :: map_fpft = ' ' ! Mapping file for PFT character(len=256), public :: map_flakwat = ' ' ! Mapping file for lake water @@ -80,6 +81,7 @@ module mkvarctl character(len=256), public :: map_fslp10 = ' ' ! Mapping file for slope percentile character(len=256), public :: map_fero = ' ' ! Mapping file for ELM-Erosion parameters character(len=256), public :: map_ffert = ' ' ! Mapping file for crop fertilizer! + character(len=256), public :: map_ftoprad = ' ' ! Mapping file for topography parameters in TOP solar radiation parameterization ! ! Variables to override data read in with ! (all_urban is mostly for single-point mode, but could be used for sensitivity studies) From e99b394cf5930683eda564255ae8841fb57a73c2 Mon Sep 17 00:00:00 2001 From: hollyhan Date: Tue, 12 Mar 2024 00:09:08 -0600 Subject: [PATCH 068/451] Move 'deallocate' statement out of error-check --- .../mpas-albany-landice/src/mode_forward/mpas_li_bedtopo.F | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/components/mpas-albany-landice/src/mode_forward/mpas_li_bedtopo.F b/components/mpas-albany-landice/src/mode_forward/mpas_li_bedtopo.F index f3bd15e57e83..51c9a8f69e23 100644 --- a/components/mpas-albany-landice/src/mode_forward/mpas_li_bedtopo.F +++ b/components/mpas-albany-landice/src/mode_forward/mpas_li_bedtopo.F @@ -578,11 +578,10 @@ subroutine slmodel_init(domain, err) call sl_solver_checkpoint(itersl, dtime) call sl_solver_init(itersl, starttime, ismIceload, ismBedtopo, ismMask) call sl_deallocate_array - - deallocate(ismIceload, ismBedtopo, ismMask) - deallocate(bedtopoSLgrid1D, thicknessSLgrid1D, maskSLgrid1D) endif + deallocate(ismIceload, ismBedtopo, ismMask) + deallocate(bedtopoSLgrid1D, thicknessSLgrid1D, maskSLgrid1D) endif deallocate(globalArrayThickness) deallocate(gatheredArrayThickness) From a90e0e6301ab194b2878b093f15c5834a837bd53 Mon Sep 17 00:00:00 2001 From: Nicole Jeffery Date: Wed, 13 Mar 2024 12:37:01 -0500 Subject: [PATCH 069/451] More changes for the icepack BGC interface Added flag to turn off BGC coupling between the ocean and sea ice: config_couple_bgc_fields=false Added black carbon conservation analysis member -track ocean black carbon flux Added carbon conservation check options in interfaces for both icepack and column Bugfixes to column package version: 1. Bugfixes to lateral melt BGC snow flux and ice flux 2. Bugfix to add_new_ice_bgc -replaces adjust_tracer_profile with simpler and more accurate version update_vertical_bio_tracers Define carbon molar mass in mpas constants Commented out problematic omp directives in icepack interface Corrections to some bgc Registry descriptions (still more to do) NOTE: Changed submodule path for Icepack to a branch that works with the BGC interface. nonBFB with BGC --- .gitmodules | 2 +- components/mpas-seaice/bld/build-namelist | 10 +- .../mpas-seaice/bld/build-namelist-section | 2 +- .../namelist_defaults_mpassi.xml | 2 +- .../namelist_definition_mpassi.xml | 16 +- components/mpas-seaice/cime_config/buildnml | 9 + components/mpas-seaice/driver/ice_comp_mct.F | 22 +- components/mpas-seaice/src/Registry.xml | 62 +- .../Registry_seaice_conservation_check.xml | 108 + .../mpas_seaice_conservation_check.F | 577 ++++- .../mpas-seaice/src/column/ice_algae.F90 | 9 +- .../mpas-seaice/src/column/ice_colpkg.F90 | 5 +- .../mpas-seaice/src/column/ice_therm_itd.F90 | 10 +- .../mpas-seaice/src/column/ice_zbgc.F90 | 214 +- .../src/shared/mpas_seaice_column.F | 342 ++- .../src/shared/mpas_seaice_constants.F | 2 +- .../src/shared/mpas_seaice_icepack.F | 2286 ++++------------- 17 files changed, 1607 insertions(+), 2071 deletions(-) diff --git a/.gitmodules b/.gitmodules index 2652b041ac83..84c10e97a8c1 100644 --- a/.gitmodules +++ b/.gitmodules @@ -76,7 +76,7 @@ [submodule "components/mpas-seaice/src/icepack"] path = components/mpas-seaice/src/icepack url = git@github.com:E3SM-Project/Icepack.git - branch = origin/njeffery/merge-fixes-to-bgc + branch = njeffery/merge-fixes-to-bgc [submodule "externals/haero"] path = externals/haero url = git@github.com:eagles-project/haero.git diff --git a/components/mpas-seaice/bld/build-namelist b/components/mpas-seaice/bld/build-namelist index 71f8a0e8c87f..d8bfcaa68c05 100755 --- a/components/mpas-seaice/bld/build-namelist +++ b/components/mpas-seaice/bld/build-namelist @@ -628,12 +628,7 @@ add_default($nl, 'config_recover_tracer_means_check'); ################################## # Namelist group: column_package # ################################## - -if ($ice_bgc eq 'ice_bgc') { - add_default($nl, 'config_column_physics_type', 'val'=>"column_package"); -} else { - add_default($nl, 'config_column_physics_type'); -} +add_default($nl, 'config_column_physics_type'); add_default($nl, 'config_use_column_shortwave'); add_default($nl, 'config_use_column_vertical_thermodynamics'); if ($ice_bgc eq 'ice_bgc') { @@ -681,6 +676,7 @@ if ($ice_bgc eq 'ice_bgc') { add_default($nl, 'config_use_humics', 'val'=>".true."); add_default($nl, 'config_use_DON', 'val'=>".true."); add_default($nl, 'config_use_iron', 'val'=>".true."); + add_default($nl, 'config_couple_biogeochemistry_fields'); } else { add_default($nl, 'config_use_vertical_biochemistry', 'val'=>".false."); add_default($nl, 'config_use_vertical_tracers', 'val'=>".false."); @@ -694,6 +690,7 @@ if ($ice_bgc eq 'ice_bgc') { add_default($nl, 'config_use_humics', 'val'=>".false."); add_default($nl, 'config_use_DON', 'val'=>".false."); add_default($nl, 'config_use_iron', 'val'=>".false."); + add_default($nl, 'config_couple_biogeochemistry_fields', 'val'=>".false."); } add_default($nl, 'config_use_chlorophyll'); add_default($nl, 'config_use_macromolecules'); @@ -943,7 +940,6 @@ if ($iceberg_mode eq 'data') { add_default($nl, 'config_use_data_icebergs', 'val'=>"false"); } add_default($nl, 'config_salt_flux_coupling_type'); -add_default($nl, 'config_couple_biogeochemistry_fields'); add_default($nl, 'config_ice_ocean_drag_coefficient'); ############################### diff --git a/components/mpas-seaice/bld/build-namelist-section b/components/mpas-seaice/bld/build-namelist-section index 28a6053f050a..8b6a06dd6740 100644 --- a/components/mpas-seaice/bld/build-namelist-section +++ b/components/mpas-seaice/bld/build-namelist-section @@ -193,6 +193,7 @@ add_default($nl, 'config_use_floe_size_distribution'); # Namelist group: biogeochemistry # ################################### +add_default($nl, 'config_couple_biogeochemistry_fields'); add_default($nl, 'config_use_brine'); add_default($nl, 'config_use_vertical_zsalinity'); add_default($nl, 'config_use_vertical_biochemistry'); @@ -447,7 +448,6 @@ add_default($nl, 'config_min_friction_velocity'); add_default($nl, 'config_ocean_heat_transfer_type'); add_default($nl, 'config_sea_freezing_temperature_type'); add_default($nl, 'config_ocean_surface_type'); -add_default($nl, 'config_couple_biogeochemistry_fields'); add_default($nl, 'config_use_data_icebergs'); add_default($nl, 'config_salt_flux_coupling_type'); add_default($nl, 'config_ice_ocean_drag_coefficient'); 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 e7abd738eb26..118cc1e2581e 100644 --- a/components/mpas-seaice/bld/namelist_files/namelist_defaults_mpassi.xml +++ b/components/mpas-seaice/bld/namelist_files/namelist_defaults_mpassi.xml @@ -203,6 +203,7 @@ false +false false false false @@ -430,7 +431,6 @@ 'constant' 'mushy' 'free' -false false 'constant' 0.00536 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 53649226f8eb..bee39c08070e 100644 --- a/components/mpas-seaice/bld/namelist_files/namelist_definition_mpassi.xml +++ b/components/mpas-seaice/bld/namelist_files/namelist_definition_mpassi.xml @@ -955,6 +955,14 @@ Default: Defined in namelist_defaults.xml + +Couple ocean and seaice biogeochemical fields + +Valid values: true or false +Default: Defined in namelist_defaults.xml + + Use the brine height tracer @@ -2654,14 +2662,6 @@ Valid values: 'free' or 'non-free' Default: Defined in namelist_defaults.xml - - - -Valid values: true or false -Default: Defined in namelist_defaults.xml - - Use data iceberg meltwater forcing diff --git a/components/mpas-seaice/cime_config/buildnml b/components/mpas-seaice/cime_config/buildnml index 8a890c9ce474..955a64144f72 100755 --- a/components/mpas-seaice/cime_config/buildnml +++ b/components/mpas-seaice/cime_config/buildnml @@ -688,6 +688,15 @@ def buildnml(case, caseroot, compname): lines.append(' ') lines.append(' ') lines.append(' ') + lines.append(' ') + lines.append(' ') + lines.append(' ') + lines.append(' ') + lines.append(' ') + lines.append(' ') + lines.append(' ') + lines.append(' ') + lines.append(' ') lines.append('') lines.append('') lines.append(' - + + - + + + @@ -5306,7 +5328,7 @@ type="real" dimensions="nZBGCTracers nCategories nCells Time" units="mmol m-2 s-1" - description="Tracers are ordered: diatom nitrogen, smallPlankton nitrogen, phaeocystis nitrogen, nitrate, polysaccarid carbon, lipid carbon, ammonium, silicate, DMSPp, DMSPd, DMS, Nonreactive nitrate, Protein nitrogen, dissolved iron in umol/m2/s, particulate iron in umol/m2/s, humic carbon, black carbon1 in mg/m2/s, black carbon2 in mg/m2/s, dust1 in mg/m2/s, dust2 in mg/m2/s, dust3 in mg/m2/s, dust4 in mg/m2/s" + description="Only bio tracers used in the order: diatom nitrogen, smallPlankton nitrogen, phaeocystis nitrogen, nitrate, polysaccarid carbon, lipid carbon, dissolved inorganic carbon,ammonium, silicate, DMSPp, DMSPd, DMS, Nonreactive nitrate, Protein nitrogen, dissolved iron in umol/m2/s, particulate iron in umol/m2/s, humic carbon, black carbon1 in mg/m2/s, black carbon2 in mg/m2/s, dust1 in mg/m2/s, dust2 in mg/m2/s, dust3 in mg/m2/s, dust4 in mg/m2/s" icepack_name="flux_bion" packages="pkgColumnBiogeochemistry;pkgColumnPackage" /> @@ -5314,7 +5336,23 @@ type="real" dimensions="nZBGCTracers nCells Time" units="mmol m-3" - description="Tracers are ordered: diatom nitrogen, smallPlankton nitrogen, phaeocystis nitrogen, nitrate, polysaccarid carbon, lipid carbon, ammonium, silicate, DMSPp, DMSPd, DMS, Nonreactive nitrate, Protein nitrogen, dissolved iron in umol/m3, particulate iron in umol/m3, humic carbon, black carbon1 in mg/m3, black carbon2 in mg/m3,dust1 in mg/m3, dust2 in mg/m3, dust3 in mg/m3, dust4 in mg/m3" + description="All bio tracers including those not used in the order: diatom nitrogen, smallPlankton nitrogen, phaeocystis nitrogen, nitrate, polysaccarid carbon, lipid carbon, dissolved inorganic carbon,ammonium, silicate, DMSPp, DMSPd, DMS, Nonreactive nitrate, Protein nitrogen, dissolved iron in umol/m3, particulate iron in umol/m3, humic carbon, black carbon1 in mg/m3, black carbon2 in mg/m3,dust1 in mg/m3, dust2 in mg/m3, dust3 in mg/m3, dust4 in mg/m3" + icepack_name="ocean_bio" + packages="pkgColumnBiogeochemistry;pkgColumnPackage" + /> + + @@ -5426,6 +5464,10 @@ type="real" dimensions="nCells Time" /> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \brief Compute MPAS-Seaice analysis member +!> \author Nicole Jeffery +!> \date 11 Mar 2024 +!> \details +!> This routine conducts all computations to verify black carbon conservation +! +!----------------------------------------------------------------------- + + subroutine black_carbon_conservation(domain, err) + + type (domain_type), intent(inout) :: & + domain + + integer, intent(out) :: & + err !< Output: error flag + + type(block_type), pointer :: & + blockPtr + + type(MPAS_pool_type), pointer :: & + conservationCheckBlackCarbonAMPool, & + conservationCheckAMPool, & + conservationCheckAreaAMPool + + real(kind=RKIND), dimension(:), pointer :: & + initialBlackCarbon, & + finalBlackCarbon, & + blackCarbonChange, & + blackCarbonChangeFlux, & + netBlackCarbonFlux, & + absoluteBlackCarbonError, & + relativeBlackCarbonError, & + iceAreaCell, & + iceAreaCellInitial, & + accumAbsoluteBlackCarbonError, & + accumRelativeBlackCarbonError + + real(kind=RKIND), dimension(:), pointer :: & + blackCarbonConsAtmBlackCarbonFlux, & + blackCarbonConsOceanBlackCarbonFlux, & + blackCarbonConsAtmBC1Flux, & + blackCarbonConsAtmBC2Flux + + real(kind=RKIND), dimension(:), allocatable :: & + sumArray, & + sumArrayOut + + type(MPAS_pool_type), pointer :: & + meshPool, & + tracersAggregatePool, & + biogeochemistryPool, & + icestatePool + + real(kind=RKIND), dimension(:), pointer :: & + areaCell, & + totalAtmBlackCarbonFlux, & + totalOceanBlackCarbonFlux, & + oceanBlackCarbonFlux + + real(kind=RKIND), dimension(:,:), pointer :: & + atmosBlackCarbonFlux + + integer, dimension(:,:), pointer :: & + cellInHemisphere + + real(kind=RKIND), pointer :: & + dt, & + earthArea + + logical, pointer :: & + config_AM_conservationCheck_write_to_logfile + + real(kind=RKIND) :: & + totalAtmBlackCarbonCell, & + totalAtmBC1Cell, & + totalAtmBC2Cell, & + totalOceanBlackCarbonCell + + integer, pointer :: & + nCellsSolve, & + nHemispheres, & + nAccumulate + + type (MPAS_Time_Type) :: & + currTime, & + startTime + + integer :: & + iCell, & + iHemisphere, & + iSumPrev, & + ierr + + integer :: & + nVars, & + nZBGC, & + nSums + + real(kind=RKIND) :: & + fluxScale + + character(len=strKIND) :: & + timeStr, & + timeStrStart + + character(len=16) :: & + valStr + + err = 0 + + call MPAS_pool_get_config(domain % configs, "config_dt", dt) + call MPAS_pool_get_config(domain % configs, "config_AM_conservationCheck_write_to_logfile", & + config_AM_conservationCheck_write_to_logfile) + + !------------------------------------------------------------- + ! Net carbon flux to ice + !------------------------------------------------------------- + + call MPAS_pool_get_dimension(domain % blocklist % dimensions, "nHemispheres", nHemispheres) + + nVars = 4 + + nSums = nHemispheres * nVars + + allocate(sumArray(nSums)) + allocate(sumArrayOut(nSums)) + + sumArray = 0.0_RKIND + + blockPtr => domain % blocklist + do while (associated(blockPtr)) + + call MPAS_pool_get_dimension(blockPtr % dimensions, "nCellsSolve", nCellsSolve) + + call MPAS_pool_get_subpool(blockPtr % structs, "mesh", meshPool) + call MPAS_pool_get_subpool(blockPtr % structs, "biogeochemistry", biogeochemistryPool) + call MPAS_pool_get_subpool(blockPtr % structs, "tracers_aggregate", tracersAggregatePool) + call MPAS_pool_get_subpool(blockPtr % structs, "icestate", icestatePool) + call MPAS_pool_get_subpool(blockPtr % structs, "conservationCheckAM", conservationCheckAMPool) + + + call MPAS_pool_get_array(tracersAggregatePool, "iceAreaCell", iceAreaCell) + call MPAS_pool_get_array(icestatePool, "iceAreaCellInitial", iceAreaCellInitial) + call MPAS_pool_get_array(meshPool, "areaCell", areaCell) + call MPAS_pool_get_array(biogeochemistryPool, "totalAtmBlackCarbonFlux", totalAtmBlackCarbonFlux) + call MPAS_pool_get_array(biogeochemistryPool, "totalOceanBlackCarbonFlux", totalOceanBlackCarbonFlux) + call MPAS_pool_get_array(biogeochemistryPool, "atmosBlackCarbonFlux", atmosBlackCarbonFlux) + call MPAS_pool_get_array(biogeochemistryPool, "oceanBlackCarbonFlux", oceanBlackCarbonFlux) + call MPAS_pool_get_array(conservationCheckAMPool, "cellInHemisphere", cellInHemisphere) + + do iCell = 1, nCellsSolve + + ! compute total black carbon flux to ocean from individual fluxes + + nZBGC = 1 + totalAtmBC1Cell = atmosBlackCarbonFlux(nZBGC,iCell) * areaCell(iCell)* & + iceAreaCellInitial(iCell) + nZBGC = nZBGC+1 + totalAtmBC2Cell = atmosBlackCarbonFlux(nZBGC,iCell) * areaCell(iCell)* & + iceAreaCellInitial(iCell) + totalOceanBlackCarbonCell = oceanBlackCarbonFlux(iCell) * areaCell(iCell)* & + iceAreaCell(iCell) + totalAtmBlackCarbonCell = totalAtmBC1Cell + totalAtmBC2Cell + + do iHemisphere = 1, nHemispheres + iSumPrev = (iHemisphere-1) * nVars + if (cellInHemisphere(iHemisphere,iCell) == 1) then + sumArray(iSumPrev+1) = sumArray(iSumPrev+1) + totalAtmBlackCarbonCell + sumArray(iSumPrev+2) = sumArray(iSumPrev+2) + totalAtmBC1Cell + sumArray(iSumPrev+3) = sumArray(iSumPrev+3) + totalAtmBC2Cell + sumArray(iSumPrev+4) = sumArray(iSumPrev+4) + totalOceanBlackCarbonCell + endif + enddo ! iHemisphere + + enddo ! iCell + + blockPtr => blockPtr % next + enddo + + ! perform the sums over processors + call MPAS_dmpar_sum_real_array(domain % dminfo, nSums, sumArray, sumArrayOut) + + ! accumulate fluxes + call MPAS_pool_get_subpool(domain % blocklist % structs, "conservationCheckBlackCarbonAM", conservationCheckBlackCarbonAMPool) + call MPAS_pool_get_array(conservationCheckBlackCarbonAMPool, "blackCarbonConsOceanBlackCarbonFlux", blackCarbonConsOceanBlackCarbonFlux) + call MPAS_pool_get_array(conservationCheckBlackCarbonAMPool, "blackCarbonConsAtmBlackCarbonFlux", blackCarbonConsAtmBlackCarbonFlux) + call MPAS_pool_get_array(conservationCheckBlackCarbonAMPool, "blackCarbonConsAtmBC1Flux", blackCarbonConsAtmBC1Flux) + call MPAS_pool_get_array(conservationCheckBlackCarbonAMPool, "blackCarbonConsAtmBC2Flux", blackCarbonConsAtmBC2Flux) + + do iHemisphere = 1, nHemispheres + iSumPrev = (iHemisphere-1) * nVars + blackCarbonConsAtmBlackCarbonFlux(iHemisphere) = blackCarbonConsAtmBlackCarbonFlux(iHemisphere) + sumArrayOut(iSumPrev+1) + blackCarbonConsAtmBC1Flux(iHemisphere) = blackCarbonConsAtmBC1Flux(iHemisphere) + sumArrayOut(iSumPrev+2) + blackCarbonConsAtmBC2Flux(iHemisphere) = blackCarbonConsAtmBC2Flux(iHemisphere) + sumArrayOut(iSumPrev+3) + blackCarbonConsOceanBlackCarbonFlux(iHemisphere) = blackCarbonConsOceanBlackCarbonFlux(iHemisphere) + sumArrayOut(iSumPrev+4) + enddo ! iHemisphere + + ! cleanup + deallocate(sumArray) + deallocate(sumArrayOut) + + !------------------------------------------------------------- + ! Black carbon conservation error + !------------------------------------------------------------- + + if (MPAS_stream_mgr_ringing_alarms(domain % streamManager, "conservationCheckOutput", ierr=ierr)) then + + ! convert fluxes to fluxes per m2 of whole earth and per second + call MPAS_pool_get_subpool(domain % blocklist % structs, "conservationCheckAM", conservationCheckAMPool) + call MPAS_pool_get_array(conservationCheckAMPool, "nAccumulate", nAccumulate) + call MPAS_pool_get_subpool(domain % blocklist % structs, "conservationCheckAreaAM", conservationCheckAreaAMPool) + call MPAS_pool_get_array(conservationCheckAreaAMPool, "earthArea", earthArea) + fluxScale = 1.0_RKIND / (earthArea * real(nAccumulate)) + + ! get initial black carbon content + call MPAS_pool_get_array(conservationCheckBlackCarbonAMPool, "initialBlackCarbon", initialBlackCarbon) + + ! get final black carbon content + call MPAS_pool_get_array(conservationCheckBlackCarbonAMPool, "finalBlackCarbon", finalBlackCarbon) + call compute_total_black_carbon(domain, finalBlackCarbon) + + ! compute the black carbon content change + call MPAS_pool_get_array(conservationCheckBlackCarbonAMPool, "blackCarbonChange", blackCarbonChange) + blackCarbonChange(:) = finalBlackCarbon(:) - initialBlackCarbon(:) + call MPAS_pool_get_array(conservationCheckBlackCarbonAMPool, "blackCarbonChangeFlux", blackCarbonChangeFlux) + blackCarbonChangeFlux(:) = blackCarbonChange(:) * (fluxScale / dt) + + ! calculate the final net black carbon flux to the ice + call MPAS_pool_get_array(conservationCheckBlackCarbonAMPool, "netBlackCarbonFlux", netBlackCarbonFlux) + netBlackCarbonFlux(:) = blackCarbonConsAtmBlackCarbonFlux(:) & + - blackCarbonConsOceanBlackCarbonFlux(:) + + ! absolute error + call MPAS_pool_get_array(conservationCheckBlackCarbonAMPool, "absoluteBlackCarbonError", absoluteBlackCarbonError) + call MPAS_pool_get_array(conservationCheckBlackCarbonAMPool, "accumAbsoluteBlackCarbonError", accumAbsoluteBlackCarbonError) + absoluteBlackCarbonError(:) = netBlackCarbonFlux(:) * dt - blackCarbonChange(:) + + ! rescale fluxes + blackCarbonConsOceanBlackCarbonFlux(:) = blackCarbonConsOceanBlackCarbonFlux(:) * fluxScale + blackCarbonConsAtmBlackCarbonFlux(:) = blackCarbonConsAtmBlackCarbonFlux(:) * fluxScale + blackCarbonConsAtmBC1Flux(:) = blackCarbonConsAtmBC1Flux(:) * fluxScale + blackCarbonConsAtmBC2Flux(:) = blackCarbonConsAtmBC2Flux(:) * fluxScale + netBlackCarbonFlux(:) = netBlackCarbonFlux(:) * fluxScale + + ! compute the final black carbon error + call MPAS_pool_get_array(conservationCheckBlackCarbonAMPool, "relativeBlackCarbonError", relativeBlackCarbonError) + call MPAS_pool_get_array(conservationCheckBlackCarbonAMPool, "accumRelativeBlackCarbonError", accumRelativeBlackCarbonError) + do iHemisphere = 1, nHemispheres + if (abs(finalBlackCarbon(iHemisphere)) > 0.0) then + relativeBlackCarbonError(iHemisphere) = absoluteBlackCarbonError(iHemisphere) / finalBlackCarbon(iHemisphere) + else + relativeBlackCarbonError(iHemisphere) = 0.0_RKIND + endif + enddo ! iHemisphere + + startTime = mpas_get_clock_time(domain % clock, MPAS_START_TIME, ierr=ierr) + currTime = mpas_get_clock_time(domain % clock, MPAS_NOW, ierr=ierr) + + call MPAS_get_time(currTime, dateTimeString=timeStr, ierr=ierr) + call MPAS_get_time(startTime, dateTimeString=timeStrStart, ierr=ierr) + + if (trim(timeStr) /= trim(timeStrStart)) then + accumRelativeBlackCarbonError(:) = accumRelativeBlackCarbonError(:) + relativeBlackCarbonError(:) + accumAbsoluteBlackCarbonError(:) = accumAbsoluteBlackCarbonError(:) + absoluteBlackCarbonError(:) + !------------------------------------------------------------- + ! Output to log file + !------------------------------------------------------------- + + if (config_AM_conservationCheck_write_to_logfile) then + + call mpas_log_write('-----------------------------------------------------------------------------') + call mpas_log_write(' Black carbon conservation check') + call mpas_log_write(' ') + call mpas_log_write(' Initial black carbon (kg) = '//trim(hemisphere_format(initialBlackCarbon))) + call mpas_log_write(' Final black carbon (kg) = '//trim(hemisphere_format(finalBlackCarbon))) + call mpas_log_write(' Black carbon change (kg) = '//trim(hemisphere_format(blackCarbonChange))) + call mpas_log_write(' Black carbon change flux (kg/m2s) = '//trim(hemisphere_format(blackCarbonChangeFlux))) + call mpas_log_write(' ') + call mpas_log_write(' Ocean black carbon flux (kg/m2s) = '//trim(hemisphere_format(blackCarbonConsOceanBlackCarbonFlux))) + call mpas_log_write(' Atmos black carbon flux (kg/m2s) = '//trim(hemisphere_format(blackCarbonConsAtmBlackCarbonFlux))) + call mpas_log_write(' Net black carbon flux (kg/m2s) = '//trim(hemisphere_format(netBlackCarbonFlux))) + call mpas_log_write(' ') + call mpas_log_write(' Individual atmosphere black carbon fluxes :') + call mpas_log_write(' Atmos BC1 flux (kg/m2s) = '//trim(hemisphere_format(blackCarbonConsAtmBC1Flux))) + call mpas_log_write(' Atmos BC2 flux (kg/m2s) = '//trim(hemisphere_format(blackCarbonConsAtmBC2Flux))) + call mpas_log_write(' ') + + call mpas_log_write(' Net black carbon change (kg) = '//trim(hemisphere_format((netBlackCarbonFlux * dt) / fluxScale))) + call mpas_log_write(' Net black carbon flux (kg/m2s) = '//trim(hemisphere_format(netBlackCarbonFlux))) + call mpas_log_write(' ') + call mpas_log_write(' Absolute black carbon error (kg) = '//trim(hemisphere_format(absoluteBlackCarbonError))) + call mpas_log_write(' Absolute BC error/s (kg/m2s) = '//trim(hemisphere_format((absoluteBlackCarbonError * fluxScale) / dt))) + call mpas_log_write(' Relative black carbon error = '//trim(hemisphere_format(relativeBlackCarbonError))) + + call mpas_log_write(' ') + call mpas_log_write(' Total run accumulated error ') + call mpas_log_write(' Accum. abs black carbon error(kg) = '//trim(hemisphere_format(accumAbsoluteBlackCarbonError))) + call mpas_log_write(' Accum. rel black carbon error = '//trim(hemisphere_format(accumRelativeBlackCarbonError))) + endif + endif + endif + + end subroutine black_carbon_conservation + !*********************************************************************** ! ! routine compute_total_energy @@ -2800,6 +3132,100 @@ subroutine compute_total_carbon(domain, totalCarbon) end subroutine compute_total_carbon +!*********************************************************************** +! +! routine compute_total_black_carbon +! +!> \brief Compute total black carbon +!> \author Nicole Jeffery +!> \date 11 Mar 2024 +!> \details +!> Calculate the total black carbon +! +!----------------------------------------------------------------------- + + subroutine compute_total_black_carbon(domain, totalBlackCarbon) + + type (domain_type), intent(inout) :: & + domain + + real(kind=RKIND), dimension(:), intent(out) :: & + totalBlackCarbon + + type(block_type), pointer :: & + blockPtr + + type(MPAS_pool_type), pointer :: & + meshPool, & + biogeochemistryPool, & + conservationCheckAMPool + + integer, pointer :: & + nCellsSolve, & + nHemispheres + + real(kind=RKIND), dimension(:), pointer :: & + totalBlackCarbonContentCell, & + areaCell + + integer, dimension(:,:), pointer :: & + cellInHemisphere + + integer :: & + iCell, & + iHemisphere + + real(kind=RKIND) :: & + blackCarbonCell + + real(kind=RKIND), dimension(:), allocatable :: & + blackCarbon + + call MPAS_pool_get_dimension(domain % blocklist % dimensions, "nHemispheres", nHemispheres) + + allocate(blackCarbon(nHemispheres)) + blackCarbon(:) = 0.0_RKIND + + blockPtr => domain % blocklist + do while (associated(blockPtr)) + + call MPAS_pool_get_subpool(blockPtr % structs, "mesh", meshPool) + call MPAS_pool_get_subpool(blockPtr % structs, "biogeochemistry", biogeochemistryPool) + call MPAS_pool_get_subpool(blockPtr % structs, "conservationCheckAM", conservationCheckAMPool) + + call MPAS_pool_get_dimension(blockPtr % dimensions, 'nCellsSolve', nCellsSolve) + call MPAS_pool_get_dimension(blockPtr % dimensions, 'nHemispheres', nHemispheres) + + call MPAS_pool_get_array(meshPool, "areaCell", areaCell) + call MPAS_pool_get_array(biogeochemistryPool, "totalBlackCarbonContentCell", totalBlackCarbonContentCell) + call MPAS_pool_get_array(conservationCheckAMPool, "cellInHemisphere", cellInHemisphere) + + call compute_black_carbon_cell(blockPtr,totalBlackCarbonContentCell) + + do iCell = 1, nCellsSolve + + ! black carbon mass (kg) + blackCarbonCell = totalBlackCarbonContentCell(iCell) * areaCell(iCell) + + do iHemisphere = 1, nHemispheres + if (cellInHemisphere(iHemisphere,iCell) == 1) then + blackCarbon(iHemisphere) = blackCarbon(iHemisphere) + blackCarbonCell + endif + enddo ! iHemisphere + + enddo ! iCell + + blockPtr => blockPtr % next + enddo + + ! sum across processors + call MPAS_dmpar_sum_real_array(domain % dminfo, nHemispheres, blackCarbon, totalBlackCarbon) + + ! clean up + deallocate(blackCarbon) + + end subroutine compute_total_black_carbon + !*********************************************************************** ! ! compute_carbon_cell @@ -3059,6 +3485,127 @@ subroutine compute_carbon_cell(blockPtr,totalCarbonContentCell) end subroutine compute_carbon_cell +!*********************************************************************** +! +! compute_black_carbon_cell +! +!> \brief +!> \author Nicole Jeffery, LANL +!> \date 11 Mar 2024 +!> \details Calculate the total carbon concentration in the sea ice cell +!> by summing the appropriate biogeochemical tracers in units of kg C +!> +!> Total black carbon = black carbon 1 + black carbon 2 +! +!----------------------------------------------------------------------- + + subroutine compute_black_carbon_cell(blockPtr,totalBlackCarbonContentCell) + + real(kind=RKIND), dimension(:), intent(out) :: & + totalBlackCarbonContentCell + + type(block_type), intent(in) :: & + blockPtr + + logical, pointer :: & + config_use_zaerosols + + integer, pointer :: & + nBioLayersP1, & + nBioLayersP3, & + nBioLayers, & + nzAerosols, & + maxBCType, & + TWO + + type(MPAS_pool_type), pointer :: & + mesh, & + biogeochemistry, & + tracers_aggregate + + real(kind=RKIND), dimension(:), pointer :: & + brineFractionCell, & + iceVolumeCell, & + snowVolumeCell + + real(kind=RKIND), dimension(:,:), pointer :: & + verticalAerosolsConcCell + + integer, pointer :: & + nCellsSolve, & + nSnowLayers + + real(kind=RKIND), dimension(:), allocatable :: & + verticalGridSpace + + real(kind=RKIND) :: & + snowleveltop, & + snowlevelint + + integer :: & + iBioTracers, & + iBioCount, & + iBioData, & + iCell, & + nBC + + call MPAS_pool_get_config(blockPtr % configs, "config_use_zaerosols",config_use_zaerosols) + + call MPAS_pool_get_dimension(blockPtr % dimensions, "nBioLayers", nBioLayers) + call MPAS_pool_get_dimension(blockPtr % dimensions, "nBioLayersP1", nBioLayersP1) + call MPAS_pool_get_dimension(blockPtr % dimensions, "nBioLayersP3", nBioLayersP3) + call MPAS_pool_get_dimension(blockPtr % dimensions, "nzAerosols", nzAerosols) + call MPAS_pool_get_dimension(blockPtr % dimensions, "maxBCType", maxBCType) + call MPAS_pool_get_dimension(blockPtr % dimensions, "TWO", TWO) + + call MPAS_pool_get_subpool(blockPtr % structs, "tracers_aggregate", tracers_aggregate) + call MPAS_pool_get_subpool(blockPtr % structs, "mesh", mesh) + call MPAS_pool_get_subpool(blockPtr % structs, "biogeochemistry", biogeochemistry) + + call MPAS_pool_get_dimension(mesh, "nCellsSolve", nCellsSolve) + call MPAS_pool_get_dimension(mesh, 'nSnowLayers', nSnowLayers) + + call MPAS_pool_get_array(tracers_aggregate, "verticalAerosolsConcCell", verticalAerosolsConcCell) + call MPAS_pool_get_array(tracers_aggregate, "brineFractionCell", brineFractionCell) + call MPAS_pool_get_array(tracers_aggregate, "iceVolumeCell", iceVolumeCell) + call MPAS_pool_get_array(tracers_aggregate, "snowVolumeCell", snowVolumeCell) + + allocate(verticalGridSpace(nBioLayersP1)) + + verticalGridSpace(:) = 1.0_RKIND/real(nBioLayers,kind=RKIND) + verticalGridSpace(1) = verticalGridSpace(1)/2.0_RKIND + verticalGridSpace(nBioLayersP1) = verticalGridSpace(1) + + totalBlackCarbonContentCell(:) = 0.0_RKIND + + if (config_use_zaerosols) then + nBC = min(nzAerosols,maxBCType) + do iCell = 1, nCellsSolve + iBioCount = 0 + + ! BC + snowleveltop = snowVolumeCell(iCell)/real(nSnowLayers,kind=RKIND)/2.0_RKIND + snowlevelint = snowVolumeCell(iCell) - snowleveltop + do iBioTracers = 1, nBC + iBioData = (iBioTracers-1)*nBioLayersP3 + ! ice BC + do iBioCount = 1, nBioLayersP1 + totalBlackCarbonContentCell(iCell) = totalBlackCarbonContentCell(iCell) + & + verticalAerosolsConcCell(iBioData + iBioCount,iCell) * verticalGridSpace(iBioCount) * & + iceVolumeCell(iCell) * brineFractionCell(iCell) + end do + ! snow BC + totalBlackCarbonContentCell(iCell) = totalBlackCarbonContentCell(iCell) + & + verticalAerosolsConcCell(iBioData+nBioLayersP1+1,iCell) * snowleveltop + & + verticalAerosolsConcCell(iBioData+nBioLayersP1+2,iCell) * snowlevelint + enddo + enddo + endif + + deallocate(verticalGridSpace) + + end subroutine compute_black_carbon_cell + !*********************************************************************** ! ! routine reset_accumulated_variables @@ -3082,7 +3629,8 @@ subroutine reset_accumulated_variables(domain) conservationCheckEnergyAMPool, & conservationCheckMassAMPool, & conservationCheckSaltAMPool, & - conservationCheckCarbonAMPool + conservationCheckCarbonAMPool, & + conservationCheckBlackCarbonAMPool integer, pointer :: & nAccumulate @@ -3125,6 +3673,12 @@ subroutine reset_accumulated_variables(domain) carbonConsHumicsFlux, & carbonConsSemiLabileDOCFlux + real(kind=RKIND), dimension(:), pointer :: & + blackCarbonConsOceanBlackCarbonFlux, & + blackCarbonConsAtmBlackCarbonFlux, & + blackCarbonConsAtmBC1Flux, & + blackCarbonConsAtmBC2Flux + ! number of accumulations call MPAS_pool_get_subpool(domain % blocklist % structs, "conservationCheckAM", conservationCheckAMPool) call MPAS_pool_get_array(conservationCheckAMPool, "nAccumulate", nAccumulate) @@ -3209,6 +3763,19 @@ subroutine reset_accumulated_variables(domain) carbonConsHumicsFlux(:) = 0.0_RKIND carbonConsSemiLabileDOCFlux(:) = 0.0_RKIND + ! black carbon + + call MPAS_pool_get_subpool(domain % blocklist % structs, "conservationCheckBlackCarbonAM", conservationCheckBlackCarbonAMPool) + call MPAS_pool_get_array(conservationCheckBlackCarbonAMPool, "blackCarbonConsOceanBlackCarbonFlux", blackCarbonConsOceanBlackCarbonFlux) + call MPAS_pool_get_array(conservationCheckBlackCarbonAMPool, "blackCarbonConsAtmBlackCarbonFlux", blackCarbonConsAtmBlackCarbonFlux) + call MPAS_pool_get_array(conservationCheckBlackCarbonAMPool, "blackCarbonConsAtmBC1Flux", blackCarbonConsAtmBC1Flux) + call MPAS_pool_get_array(conservationCheckBlackCarbonAMPool, "blackCarbonConsAtmBC2Flux", blackCarbonConsAtmBC2Flux) + + blackCarbonConsOceanBlackCarbonFlux(:) = 0.0_RKIND + blackCarbonConsAtmBlackCarbonFlux(:) = 0.0_RKIND + blackCarbonConsAtmBC1Flux(:) = 0.0_RKIND + blackCarbonConsAtmBC2Flux(:) = 0.0_RKIND + end subroutine reset_accumulated_variables !*********************************************************************** diff --git a/components/mpas-seaice/src/column/ice_algae.F90 b/components/mpas-seaice/src/column/ice_algae.F90 index 78dce86e2d31..e3fb475d72bf 100644 --- a/components/mpas-seaice/src/column/ice_algae.F90 +++ b/components/mpas-seaice/src/column/ice_algae.F90 @@ -1325,7 +1325,8 @@ subroutine z_biogeochemistry (n_cat, dt, & trcrn(nt_zbgc_frac+mm-1) = zbgc_frac_init(mm) if (sum_tot > c0) trcrn(nt_zbgc_frac+mm-1) = sum_new/sum_tot - if (abs(sum_initial-sum_tot-flux_bio(mm)*dt + source(mm)) > accuracy*max(sum_initial,sum_tot) .or. & + if (abs(sum_initial-sum_tot-flux_bio(mm)*dt + source(mm)) > accuracy*max(sum_initial,sum_tot) .\ +or. & ! if (abs(sum_new-sum_old) > accuracy*sum_old .or. & minval(biocons(:)) < c0 .or. minval(initcons_stationary(:)) < c0 & .or. l_stop) then @@ -2874,8 +2875,8 @@ subroutine check_conservation_FCT & C_low(k) = C_new(k) enddo - accuracy = 1.0e-14_dbl_kind*max(c1, C_init_tot, C_new_tot) - fluxbio = (C_init_tot - C_new_tot + source)/dt + accuracy = 1.0e-11_dbl_kind*max(c1, C_init_tot, C_new_tot) + fluxbio = fluxbio + (C_init_tot - C_new_tot + source)/dt diff_dt =C_new_tot - C_init_tot - (S_top+S_bot+L_bot*C_new(nblyr+1)+L_top*C_new(1))*dt if (minval(C_low) < c0) then @@ -2885,7 +2886,7 @@ subroutine check_conservation_FCT & endif if (abs(diff_dt) > accuracy ) then - !l_stop = .true. + l_stop = .true. write(warning,*) 'Conservation of zbgc low order solution failed: diff_dt:',& diff_dt call add_warning(warning) diff --git a/components/mpas-seaice/src/column/ice_colpkg.F90 b/components/mpas-seaice/src/column/ice_colpkg.F90 index ce21d8a69eab..ee140abdbf7f 100644 --- a/components/mpas-seaice/src/column/ice_colpkg.F90 +++ b/components/mpas-seaice/src/column/ice_colpkg.F90 @@ -5459,7 +5459,8 @@ subroutine colpkg_biogeochemistry(dt, & upNO, upNH, iDi, iki, zfswin, & zsal_tot, darcy_V, grow_net, & PP_net, hbri,dhbr_bot, dhbr_top, Zoo,& - fbio_snoice, fbio_atmice, ocean_bio, & + fbio_snoice, fbio_atmice, & + ocean_bio, & first_ice, fswpenln, bphi, bTiz, ice_bio_net, & snow_bio_net, totalChla, fswthrun, Rayleigh_criteria, & sice_rho, fzsal, fzsal_g, & @@ -5816,7 +5817,7 @@ subroutine colpkg_biogeochemistry(dt, & n_don, & n_fed, n_fep, & n_zaero, first_ice(n), & - hin_old(n), ocean_bio(:), & + hin_old(n), ocean_bio(1:nbtrcr), & bphi(:,n), iphin, & iDi(:,n), sss, & fswpenln(:,n), & diff --git a/components/mpas-seaice/src/column/ice_therm_itd.F90 b/components/mpas-seaice/src/column/ice_therm_itd.F90 index 81930d017e49..7adcbc9c1c66 100644 --- a/components/mpas-seaice/src/column/ice_therm_itd.F90 +++ b/components/mpas-seaice/src/column/ice_therm_itd.F90 @@ -913,7 +913,9 @@ subroutine lateral_melt (dt, ncat, & dvint ! snow interior layer real (kind=dbl_kind), dimension (ncat) :: & - vicen_init ! volume per unit area of ice (m) + vicen_init, & ! initial volume per unit area of ice (m) + aicen_init, & ! initial area + vsnon_init ! initial volume of snow (m) if (rside > c0) then ! grid cells with lateral melting. @@ -944,6 +946,8 @@ subroutine lateral_melt (dt, ncat, & ! state variables vicen_init(n) = vicen(n) + aicen_init(n) = aicen(n) + vsnon_init(n) = vsnon(n) aicen(n) = aicen(n) * (c1 - rside) vicen(n) = vicen(n) * (c1 - rside) vsnon(n) = vsnon(n) * (c1 - rside) @@ -980,8 +984,8 @@ subroutine lateral_melt (dt, ncat, & !----------------------------------------------------------------- if (z_tracers) then ! snow tracers - dvssl = min(p5*vsnon(n)/real(nslyr,kind=dbl_kind), hs_ssl*aicen(n)) !snow surface layer - dvint = vsnon(n)- dvssl !snow interior + dvssl = min(p5*vsnon_init(n)/real(nslyr,kind=dbl_kind), hs_ssl*aicen_init(n)) !snow surface layer + dvint = vsnon_init(n)- dvssl !snow interior do k = 1, nbtrcr flux_bio(k) = flux_bio(k) & + (trcrn(bio_index(k)+nblyr+1,n)*dvssl & diff --git a/components/mpas-seaice/src/column/ice_zbgc.F90 b/components/mpas-seaice/src/column/ice_zbgc.F90 index e8cef6dcad9f..de31fbf702f7 100644 --- a/components/mpas-seaice/src/column/ice_zbgc.F90 +++ b/components/mpas-seaice/src/column/ice_zbgc.F90 @@ -11,6 +11,7 @@ module ice_zbgc use ice_kinds_mod use ice_zbgc_shared ! everything + use ice_warnings, only: add_warning implicit none @@ -109,7 +110,8 @@ subroutine add_new_ice_bgc (dt, nblyr, & location , & ! 1 (add frazil to bottom), 0 (add frazil throughout) n , & ! ice category index k , & ! ice layer index - m + m , & + nbiolayer real (kind=dbl_kind) :: & vbri1 , & ! starting volume of existing brine @@ -119,12 +121,14 @@ subroutine add_new_ice_bgc (dt, nblyr, & real (kind=dbl_kind) :: & vsurp , & ! volume of new ice added to each cat vtmp ! total volume of new and old ice - + real (kind=dbl_kind), dimension (ncat) :: & - vbrin ! trcrn(nt_fbri,n)*vicen(n) + vbrin , & ! trcrn(nt_fbri,n)*vicen(n) + brine_frac_init ! initial trcrn(nt_fbri,n) real (kind=dbl_kind) :: & - vice_new ! vicen_init + vsurp + vice_new , & ! vicen_init + vsurp + bio0new ! ocean_bio * zbgc_init_fac real (kind=dbl_kind) :: & Tmlts ! melting temperature (oC) @@ -132,9 +136,8 @@ subroutine add_new_ice_bgc (dt, nblyr, & character (len=char_len) :: & fieldid ! field identifier - real (kind=dbl_kind), dimension (nbtrcr) :: & - total_bio_initial, & ! Initial column bio concentration (mmol/m2) - total_bio_final ! final column bio concentration (mmol/m2) + character(len=char_len_long) :: & + warning real (kind=dbl_kind), dimension (nblyr+1) :: & zspace ! vertical grid spacing @@ -152,19 +155,13 @@ subroutine add_new_ice_bgc (dt, nblyr, & if (tr_brine) vbrin(n) = trcrn(nt_fbri,n)*vicen_init(n) enddo - do m = 1, nbtrcr - total_bio_initial(m) = c0 - do n = 1, ncat - do k = 1, nblyr+1 - total_bio_initial(m) = total_bio_initial(m) + vbrin(n) * zspace(k)*trcrn(bio_index(m)+k-1,n) - enddo - enddo - enddo - call column_sum (ncat, vbrin, vbri_init) vbri_init = vbri_init + vi0_init + do k = 1, nbtrcr + flux_bio(k) = flux_bio(k) - vi0_init/dt*ocean_bio(k)*zbgc_init_frac(k) + enddo !----------------------------------------------------------------- ! Distribute bgc in new ice volume among all ice categories by ! increasing ice thickness, leaving ice area unchanged. @@ -178,34 +175,27 @@ subroutine add_new_ice_bgc (dt, nblyr, & vtmp = c0 do n = 1,ncat - - if (hsurp > c0) then + brine_frac_init(n) = c1 + if (hsurp > c0) then ! add ice to all categories vtmp = vbrin(n) - vsurp = hsurp * aicen_init(n) + vsurp = hsurp * aicen_init(n) vbrin(n) = vbrin(n) + vsurp vice_new = vicen_init(n) + vsurp - if (tr_brine .and. vicen(n) > c0) then - trcrn(nt_fbri,n) = vbrin(n)/vicen(n) + if (tr_brine .and. vice_new > c0) then ! NJvicen(n) > c0) then + brine_frac_init(n) = trcrn(nt_fbri,n) !NJ + trcrn(nt_fbri,n) = vbrin(n)/vice_new !NJ vicen(n) elseif (tr_brine .and. vicen(n) <= c0) then trcrn(nt_fbri,n) = c1 endif - if (nbtrcr > 0) then - location = 1 - call adjust_tracer_profile(nbtrcr, dt, ntrcr, & - aicen_init(n), & - vbrin(n), & - vice_new, & - trcrn(:,n), & - vtmp, & - vsurp, sss, & - nilyr, nblyr, & - solve_zsal, bgrid, & - cgrid, & - ocean_bio, igrid, & - location, & - l_stop, stop_label) + if (nbtrcr > 0) then + do m = 1, nbtrcr + bio0new = ocean_bio(m)*zbgc_init_frac(m) + nbiolayer = nblyr+1 + call update_vertical_bio_tracers(nbiolayer, trcrn(bio_index(m):bio_index(m) + nblyr,n), & + vtmp, vbrin(n), bio0new,zspace(:)) + enddo !nbtrcr if (l_stop) return endif ! nbtrcr endif ! hsurp > 0 @@ -214,36 +204,30 @@ subroutine add_new_ice_bgc (dt, nblyr, & !----------------------------------------------------------------- ! Combine bgc in new ice grown in open water with category 1 ice. !----------------------------------------------------------------- - + if (vi0new > c0) then - vbri1 = vbrin(1) + vbri1 = vbrin(1) vbrin(1) = vbrin(1) + vi0new if (tr_brine .and. vicen(1) > c0) then trcrn(nt_fbri,1) = vbrin(1)/vicen(1) elseif (tr_brine .and. vicen(1) <= c0) then trcrn(nt_fbri,1) = c1 endif - + ! Diffuse_bio handles concentration changes from ice growth/melt ! ice area changes ! add salt throughout, location = 0 - if (nbtrcr > 0) then - location = 0 - call adjust_tracer_profile(nbtrcr, dt, ntrcr, & - aicen(1), & - vbrin(1), & - vicen(1), & - trcrn(:,1), & - vbri1, & - vi0new, sss, & - nilyr, nblyr, & - solve_zsal, bgrid, & - cgrid, & - ocean_bio, igrid, & - location, & - l_stop, stop_label) + if (nbtrcr > 0 .and. vbrin(1) > c0) then + do m = 1, nbtrcr + bio0new = ocean_bio(m)*zbgc_init_frac(m) + do k = 1, nblyr+1 + trcrn(bio_index(m) + k-1,1) = & + (trcrn(bio_index(m) + k-1,1)*vbri1 + bio0new * vi0new)/vbrin(1) + enddo + enddo + if (l_stop) return if (solve_zsal .and. vsnon1 .le. c0) then @@ -253,16 +237,6 @@ subroutine add_new_ice_bgc (dt, nblyr, & endif ! nbtrcr > 0 endif ! vi0new > 0 - do m = 1, nbtrcr - total_bio_final(m) = c0 - do n = 1, ncat - do k = 1, nblyr+1 - total_bio_final(m) = total_bio_final(m) + trcrn(nt_fbri,n) * vicen(n) *zspace(k)*trcrn(bio_index(m)+k-1,n) - enddo - enddo - flux_bio(m) = flux_bio(m) + (total_bio_initial(m) - total_bio_final(m))/dt - enddo - if (tr_brine .and. l_conservation_check) then call column_sum (ncat, vbrin, vbri_final) @@ -320,10 +294,6 @@ subroutine lateral_melt_bgc (dt, & ! local variables - real (kind=dbl_kind) :: & - total_bio_initial, & ! initial column tracer concentration (mmol/m2) - total_bio_final ! final column tracer concentration (mmol/m20 - integer (kind=int_kind) :: & k , & ! layer index m , & ! @@ -332,9 +302,12 @@ subroutine lateral_melt_bgc (dt, & real (kind=dbl_kind), dimension (nblyr+1) :: & zspace ! vertical grid spacing + character(len=char_len_long) :: & + warning + zspace(:) = c1/real(nblyr,kind=dbl_kind) - zspace(1) = p5*zspace(1) - zspace(nblyr+1) = p5*zspace(nblyr+1) + zspace(1) = p5*zspace(2) + zspace(nblyr+1) = p5*zspace(nblyr) if (solve_zsal) then do n = 1, ncat @@ -347,15 +320,13 @@ subroutine lateral_melt_bgc (dt, & endif do m = 1, nbtrcr - total_bio_initial = c0 - total_bio_final = c0 do n = 1, ncat do k = 1, nblyr+1 - total_bio_initial = total_bio_initial + trcrn(nt_fbri,n) * vicen_init(n) *zspace(k)*trcrn(bio_index(m)+k-1,n) - total_bio_final = total_bio_final + trcrn(nt_fbri,n) * vicen(n) *zspace(k)*trcrn(bio_index(m)+k-1,n) + flux_bio(m) = flux_bio(m) + trcrn(nt_fbri,n) & + * vicen_init(n)*zspace(k)*trcrn(bio_index(m)+k-1,n) & + * rside/dt enddo - enddo - flux_bio(m) = flux_bio(m) + (total_bio_initial - total_bio_final)/dt + enddo enddo end subroutine lateral_melt_bgc @@ -462,7 +433,7 @@ subroutine adjust_tracer_profile (nbtrcr, dt, ntrcr, & hbri_old = vtmp if (solve_zsal) then top_conc = sss * salt_loss - do k = 1, nblyr + do k = 1, nblyr S_stationary(k) = trcrn(nt_bgc_S+k-1)* hbri_old enddo call regrid_stationary (S_stationary, hbri_old, & @@ -472,7 +443,7 @@ subroutine adjust_tracer_profile (nbtrcr, dt, ntrcr, & bgrid(2:nblyr+1), fluxb,& l_stop, stop_label) if (l_stop) return - do k = 1, nblyr + do k = 1, nblyr trcrn(nt_bgc_S+k-1) = S_stationary(k)/hbri trtmp0(nt_sice+k-1) = trcrn(nt_bgc_S+k-1) enddo @@ -480,7 +451,7 @@ subroutine adjust_tracer_profile (nbtrcr, dt, ntrcr, & do m = 1, nbtrcr top_conc = ocean_bio(m)*zbgc_init_frac(m) - do k = 1, nblyr+1 + do k = 1, nblyr+1 C_stationary(k) = trcrn(bio_index(m) + k-1)* hbri_old enddo !k call regrid_stationary (C_stationary, hbri_old, & @@ -789,6 +760,91 @@ subroutine merge_bgc_fluxes_skl (ntrcr, & enddo end subroutine merge_bgc_fluxes_skl +!======================================================================= +! +! Given some added new ice to the base of the existing ice, recalculate +! vertical bio tracer so that new grid cells are all the same size. +! +! author: N. Jeffery, LANL +! + subroutine update_vertical_bio_tracers(nbiolyr, trc, h1, h2, trc0, zspace) + + use ice_constants_colpkg, only: c0 + + integer (kind=int_kind), intent(in) :: & + nbiolyr ! number of bio layers nblyr+1 + + real (kind=dbl_kind), dimension(:), intent(inout) :: & + trc ! vertical tracer + + real (kind=dbl_kind), intent(in) :: & + h1, & ! old thickness + h2, & ! new thickness + trc0 ! tracer value of added ice on ice bottom + + real (kind=dbl_kind), dimension(nbiolyr), intent(in) :: & + zspace + + ! local variables + + real(kind=dbl_kind), dimension(nbiolyr) :: trc2 ! updated tracer temporary + + ! vertical indices for old and new grid + integer :: k1, k2 + + real (kind=dbl_kind) :: & + z1a, z1b, & ! upper, lower boundary of old cell/added new ice at bottom + z2a, z2b, & ! upper, lower boundary of new cell + overlap , & ! overlap between old and new cell + rnilyr + + !rnilyr = real(nilyr,dbl_kind) + z2a = c0 + z2b = c0 + ! loop over new grid cells + do k2 = 1, nbiolyr + + ! initialize new tracer + trc2(k2) = c0 + + ! calculate upper and lower boundary of new cell + z2a = z2b !((k2 - 1) * h2) * zspace(k2)+z2b ! / rnilyr + z2b = z2b + h2 * zspace(k2) !(k2 * h2) * zspace(k2)+z2a !/ rnilyr + + z1a = c0 + z1b = c0 + ! loop over old grid cells + do k1 = 1, nbiolyr + + ! calculate upper and lower boundary of old cell + z1a = z1b !((k1 - 1) * h1) * zspace(k1)+z1b !/ rnilyr + z1b = z1b + h1 * zspace(k1) !(k1 * h1) * zspace(k1)+z1a !/ rnilyr + + ! calculate overlap between old and new cell + overlap = max(min(z1b, z2b) - max(z1a, z2a), c0) + + ! aggregate old grid cell contribution to new cell + trc2(k2) = trc2(k2) + overlap * trc(k1) + + enddo ! k1 + + ! calculate upper and lower boundary of added new ice at bottom + z1a = h1 + z1b = h2 + + ! calculate overlap between added ice and new cell + overlap = max(min(z1b, z2b) - max(z1a, z2a), c0) + ! aggregate added ice contribution to new cell + trc2(k2) = trc2(k2) + overlap * trc0 + ! renormalize new grid cell + trc2(k2) = trc2(k2)/zspace(k2)/h2 !(rnilyr * trc2(k2)) / h2 + + enddo ! k2 + + ! update vertical tracer array with the adjusted tracer + trc = trc2 + + end subroutine update_vertical_bio_tracers !======================================================================= diff --git a/components/mpas-seaice/src/shared/mpas_seaice_column.F b/components/mpas-seaice/src/shared/mpas_seaice_column.F index cfebdab2e200..1b736c4b0ccb 100644 --- a/components/mpas-seaice/src/shared/mpas_seaice_column.F +++ b/components/mpas-seaice/src/shared/mpas_seaice_column.F @@ -2110,6 +2110,9 @@ subroutine column_itd_thermodynamics(domain, clock) colpkg_step_therm2, & colpkg_clear_warnings + use seaice_constants, only: & + seaicePuny + type(domain_type), intent(inout) :: domain type(MPAS_clock_type), intent(in) :: clock @@ -2202,13 +2205,13 @@ subroutine column_itd_thermodynamics(domain, clock) iBioLayers ! test carbon conservation - real(kind=RKIND), dimension(:), allocatable :: & + real(kind=RKIND), dimension(:,:), allocatable :: & totalCarbonCatFinal, & totalCarbonCatInitial, & - oceanBioFluxesTemp, & - verticalGridSpace + oceanBioFluxesTemp - real(kind=RKIND) :: & + real(kind=RKIND), dimension(:), allocatable :: & + verticalGridSpace, & oceanCarbonFlux, & totalCarbonFinal, & totalCarbonInitial, & @@ -2317,11 +2320,22 @@ subroutine column_itd_thermodynamics(domain, clock) ! newly formed ice allocate(newlyFormedIceLogical(nCategories)) allocate(oceanBioConcentrationsUsed(ciceTracerObject % nBioTracers)) - allocate(oceanBioFluxesTemp(ciceTracerObject % nBioTracers)) + allocate(oceanBioFluxesTemp(ciceTracerObject % nBioTracers,nCellsSolve)) allocate(verticalGridSpace(nBioLayersP1)) if (checkCarbon) then - allocate(totalCarbonCatFinal(nCategories)) - allocate(totalCarbonCatInitial(nCategories)) + allocate(totalCarbonCatFinal(nCategories,nCellsSolve)) + allocate(totalCarbonCatInitial(nCategories,nCellsSolve)) + allocate(totalCarbonInitial(nCellsSolve)) + allocate(totalCarbonFinal(nCellsSolve)) + allocate(oceanCarbonFlux(nCellsSolve)) + allocate(carbonError(nCellsSolve)) + else + allocate(totalCarbonCatFinal(1,1)) + allocate(totalCarbonCatInitial(1,1)) + allocate(totalCarbonInitial(1)) + allocate(totalCarbonFinal(1)) + allocate(oceanCarbonFlux(1)) + allocate(carbonError(1)) endif verticalGridSpace(:) = 1.0_RKIND/real(nBioLayers,kind=RKIND) @@ -2337,8 +2351,10 @@ subroutine column_itd_thermodynamics(domain, clock) anyAbort = .false. !$omp parallel do default(shared) private(iCategory,iBioTracers,iBioData,& - !$omp& totalCarbonInitial,abortMessage,oceanBioFluxesTemp,totalCarbonFinal,& - !$omp& carbonError) firstprivate(newlyFormedIceLogical,oceanBioConcentrationsUsed) & + !$omp& totalCarbonInitial,totalCarbonCatInitial,totalCarbonCatFinal,& + !$omp& abortMessage,oceanBioFluxesTemp,totalCarbonFinal,& + !$omp& oceanCarbonFlux, carbonError) & + !$omp& firstprivate(newlyFormedIceLogical,oceanBioConcentrationsUsed) & !$omp& reduction(.or.:abortFlag) do iCell = 1, nCellsSolve @@ -2358,14 +2374,14 @@ subroutine column_itd_thermodynamics(domain, clock) tracerArrayCategory, iCell, setGetPhysicsTracers, setGetBGCTracers) if (checkCarbon) then - totalCarbonInitial = 0.0_RKIND - call seaice_total_carbon_content_category(block,totalCarbonCatInitial,iceAreaCategory(1,:,:),iceVolumeCategory(1,:,:),iCell) + totalCarbonInitial(iCell) = 0.0_RKIND + call seaice_total_carbon_content_category(block,totalCarbonCatInitial(:,iCell),iceAreaCategory(1,:,:),iceVolumeCategory(1,:,:),iCell) do iCategory = 1,nCategories - totalCarbonInitial = totalCarbonInitial + totalCarbonCatInitial(iCategory)*iceAreaCategory(1,iCategory,iCell) + totalCarbonInitial(iCell) = totalCarbonInitial(iCell) + totalCarbonCatInitial(iCategory,iCell)*iceAreaCategory(1,iCategory,iCell) enddo endif - oceanBioFluxesTemp(:) = 0.0_RKIND + oceanBioFluxesTemp(:,iCell) = 0.0_RKIND call colpkg_clear_warnings() call colpkg_step_therm2(& @@ -2408,7 +2424,7 @@ subroutine column_itd_thermodynamics(domain, clock) oceanAerosolFlux(:,iCell), & newlyFormedIceLogical(:), & !first_ice, intent(inout) zSalinityFlux(iCell), & - oceanBioFluxesTemp(:), & + oceanBioFluxesTemp(:,iCell), & oceanBioConcentrationsUsed(:), & !ocean_bio, intent(in) abortFlag, & abortMessage, & @@ -2417,7 +2433,7 @@ subroutine column_itd_thermodynamics(domain, clock) dayOfYear) do iBioTracers = 1, ciceTracerObject % nBioTracers - oceanBioFluxes(iBioTracers,iCell) = oceanBioFluxes(iBioTracers,iCell) + oceanBioFluxesTemp(iBioTracers) + oceanBioFluxes(iBioTracers,iCell) = oceanBioFluxes(iBioTracers,iCell) + oceanBioFluxesTemp(iBioTracers,iCell) enddo call column_write_warnings(abortFlag) @@ -2433,26 +2449,26 @@ subroutine column_itd_thermodynamics(domain, clock) tracerArrayCategory, iCell, setGetPhysicsTracers, setGetBGCTracers) if (checkCarbon) then - totalCarbonFinal = 0.0_RKIND - call seaice_total_carbon_content_category(block,totalCarbonCatFinal,iceAreaCategory(1,:,:),iceVolumeCategory(1,:,:),iCell) - call seaice_ocean_carbon_flux_cell(block,oceanCarbonFlux,oceanBioFluxesTemp,iCell) + totalCarbonFinal(iCell) = 0.0_RKIND + call seaice_total_carbon_content_category(block,totalCarbonCatFinal(:,iCell),iceAreaCategory(1,:,:),iceVolumeCategory(1,:,:),iCell) + call seaice_ocean_carbon_flux_cell(block,oceanCarbonFlux(iCell),oceanBioFluxesTemp(:,iCell),iCell) do iCategory = 1,nCategories - totalCarbonFinal = totalCarbonFinal + totalCarbonCatFinal(iCategory)*iceAreaCategory(1,iCategory,iCell) + totalCarbonFinal(iCell) = totalCarbonFinal(iCell) + totalCarbonCatFinal(iCategory,iCell)*iceAreaCategory(1,iCategory,iCell) enddo - carbonError = totalCarbonInitial - oceanCarbonFlux*config_dt - totalCarbonFinal + carbonError(iCell) = (totalCarbonFinal(iCell) - totalCarbonInitial(iCell))/config_dt + oceanCarbonFlux(iCell) - if (abs(carbonError) > 1.0e-14_RKIND*MAXVAL((/totalCarbonInitial,totalCarbonFinal/))) then + if (abs(carbonError(iCell)) > max(seaicePuny,1.0e-14_RKIND*abs(oceanCarbonFlux(iCell)))) then call mpas_log_write("column_step_therm2, carbon conservation error", messageType=MPAS_LOG_ERR) call mpas_log_write("iCell: $i", messageType=MPAS_LOG_ERR, intArgs=(/indexToCellID(iCell)/)) - call mpas_log_write("carbonError: $r", messageType=MPAS_LOG_ERR, realArgs=(/carbonError/)) - call mpas_log_write("totalCarbonInitial: $r", messageType=MPAS_LOG_ERR, realArgs=(/totalCarbonInitial/)) - call mpas_log_write("totalCarbonFinal: $r", messageType=MPAS_LOG_ERR, realArgs=(/totalCarbonFinal/)) - call mpas_log_write("oceanCarbonFlux: $r", messageType=MPAS_LOG_ERR, realArgs=(/oceanCarbonFlux/)) + call mpas_log_write("carbonError: $r", messageType=MPAS_LOG_ERR, realArgs=(/carbonError(iCell)/)) + call mpas_log_write("totalCarbonInitial: $r", messageType=MPAS_LOG_ERR, realArgs=(/totalCarbonInitial(iCell)/)) + call mpas_log_write("totalCarbonFinal: $r", messageType=MPAS_LOG_ERR, realArgs=(/totalCarbonFinal(iCell)/)) + call mpas_log_write("oceanCarbonFlux: $r", messageType=MPAS_LOG_ERR, realArgs=(/oceanCarbonFlux(iCell)/)) do iCategory = 1, nCategories call mpas_log_write("iCategory: $i", messageType=MPAS_LOG_ERR, intArgs=(/iCategory/)) - call mpas_log_write("totalCarbonCatFinal(iCategory): $r", messageType=MPAS_LOG_ERR, realArgs=(/totalCarbonCatFinal(iCategory)/)) - call mpas_log_write("totalCarbonCatInitial(iCategory): $r", messageType=MPAS_LOG_ERR, realArgs=(/totalCarbonCatFinal(iCategory)/)) + call mpas_log_write("totalCarbonCatFinal(iCategory,iCell): $r", messageType=MPAS_LOG_ERR, realArgs=(/totalCarbonCatFinal(iCategory,iCell)/)) + call mpas_log_write("totalCarbonCatInitial(iCategory,iCell): $r", messageType=MPAS_LOG_ERR, realArgs=(/totalCarbonCatFinal(iCategory,iCell)/)) enddo endif endif @@ -2472,10 +2488,12 @@ subroutine column_itd_thermodynamics(domain, clock) call seaice_critical_error_write_block(domain, block, anyAbort) call seaice_check_critical_error(domain, anyAbort) - if (checkCarbon) then - deallocate(totalCarbonCatFinal) - deallocate(totalCarbonCatInitial) - endif + deallocate(totalCarbonCatFinal) + deallocate(totalCarbonCatInitial) + deallocate(totalCarbonInitial) + deallocate(totalCarbonFinal) + deallocate(oceanCarbonFlux) + deallocate(carbonError) ! newly formed ice deallocate(newlyFormedIceLogical) @@ -3372,6 +3390,9 @@ subroutine column_ridging(domain) colpkg_step_ridge, & colpkg_clear_warnings + use seaice_constants, only: & + seaicePuny + type(domain_type), intent(inout) :: domain type(block_type), pointer :: block @@ -3408,7 +3429,8 @@ subroutine column_ridging(domain) nIceLayers, & nSnowLayers, & nAerosols, & - nBioLayers + nBioLayers, & + nBioLayersP1 ! variables real(kind=RKIND), dimension(:), pointer :: & @@ -3458,7 +3480,24 @@ subroutine column_ridging(domain) ! local integer :: & iCell, & - iCategory + iCategory, & + iBioTracers, & + iBioData, & + iBioLayers + + ! test carbon conservation + real(kind=RKIND), dimension(:,:), allocatable :: & + totalCarbonCatFinal, & + totalCarbonCatInitial, & + oceanBioFluxesTemp + + real(kind=RKIND), dimension(:), allocatable :: & + verticalGridSpace, & + oceanCarbonFlux, & + totalCarbonFinal, & + totalCarbonInitial, & + carbonError, & + iceAreaCategoryInitial logical, dimension(:), allocatable :: & newlyFormedIceLogical @@ -3466,12 +3505,15 @@ subroutine column_ridging(domain) logical :: & abortFlag, & setGetPhysicsTracers, & - setGetBGCTracers + setGetBGCTracers, & + checkCarbon character(len=strKIND) :: & abortMessage, & abortLocation + checkCarbon = .false. + block => domain % blocklist do while (associated(block)) @@ -3491,6 +3533,7 @@ subroutine column_ridging(domain) call MPAS_pool_get_config(block % configs, "config_dynamics_subcycle_number", config_dynamics_subcycle_number) call MPAS_pool_get_config(block % configs, "config_use_column_biogeochemistry", config_use_column_biogeochemistry) call MPAS_pool_get_config(block % configs, "config_use_zaerosols", config_use_zaerosols) + call MPAS_pool_get_config(block % configs, "config_dt", config_dt) call MPAS_pool_get_array(velocity_solver, "dynamicsTimeStep", dynamicsTimeStep) @@ -3500,6 +3543,7 @@ subroutine column_ridging(domain) call MPAS_pool_get_dimension(mesh, "nSnowLayers", nSnowLayers) call MPAS_pool_get_dimension(mesh, "nAerosols", nAerosols) call MPAS_pool_get_dimension(block % dimensions, "nBioLayers", nBioLayers) + call MPAS_pool_get_dimension(block % dimensions, "nBioLayersP1", nBioLayersP1) call MPAS_pool_get_array(mesh, "indexToCellID", indexToCellID) @@ -3546,6 +3590,30 @@ subroutine column_ridging(domain) ! newly formed ice allocate(newlyFormedIceLogical(nCategories)) + allocate(oceanBioFluxesTemp(ciceTracerObject % nBioTracers,nCellsSolve)) + allocate(verticalGridSpace(nBioLayersP1)) + if (checkCarbon) then + allocate(totalCarbonCatFinal(nCategories,nCellsSolve)) + allocate(totalCarbonCatInitial(nCategories,nCellsSolve)) + allocate(totalCarbonInitial(nCellsSolve)) + allocate(totalCarbonFinal(nCellsSolve)) + allocate(oceanCarbonFlux(nCellsSolve)) + allocate(carbonError(nCellsSolve)) + allocate(iceAreaCategoryInitial(nCategories)) + else + allocate(totalCarbonCatFinal(1,1)) + allocate(totalCarbonCatInitial(1,1)) + allocate(totalCarbonInitial(1)) + allocate(totalCarbonFinal(1)) + allocate(oceanCarbonFlux(1)) + allocate(carbonError(1)) + allocate(iceAreaCategoryInitial(1)) + endif + + verticalGridSpace(:) = 1.0_RKIND/real(nBioLayers,kind=RKIND) + verticalGridSpace(1) = verticalGridSpace(2)/2.0_RKIND + verticalGridSpace(nBioLayersP1) = verticalGridSpace(1) + setGetPhysicsTracers = .true. setGetBGCTracers = (config_use_column_biogeochemistry .or. config_use_zaerosols) @@ -3564,6 +3632,17 @@ subroutine column_ridging(domain) call set_cice_tracer_array_category(block, ciceTracerObject, & tracerArrayCategory, iCell, setGetPhysicsTracers, setGetBGCTracers) + if (checkCarbon) then + totalCarbonInitial(iCell) = 0.0_RKIND + call seaice_total_carbon_content_category(block,totalCarbonCatInitial(:,iCell),iceAreaCategory(1,:,:),iceVolumeCategory(1,:,:),iCell) + do iCategory = 1,nCategories + iceAreaCategoryInitial(iCategory) = iceAreaCategory(1,iCategory,iCell) + totalCarbonInitial(iCell) = totalCarbonInitial(iCell) + totalCarbonCatInitial(iCategory,iCell)*iceAreaCategory(1,iCategory,iCell) + enddo + endif + + oceanBioFluxesTemp(:,iCell) = 0.0_RKIND + call colpkg_clear_warnings() call colpkg_step_ridge(& dynamicsTimeStep, & @@ -3607,11 +3686,15 @@ subroutine column_ridging(domain) oceanSaltFlux(iCell), & newlyFormedIceLogical(:), & zSalinityFlux(iCell), & - oceanBioFluxes(:,iCell), & + oceanBioFluxesTemp(:,iCell), & abortFlag, & abortMessage) call column_write_warnings(abortFlag) + do iBioTracers = 1, ciceTracerObject % nBioTracers + oceanBioFluxes(iBioTracers,iCell) = oceanBioFluxes(iBioTracers,iCell) + oceanBioFluxesTemp(iBioTracers,iCell) + enddo + ! update do iCategory = 1, nCategories newlyFormedIce(iCategory,iCell) = 0 @@ -3622,6 +3705,35 @@ subroutine column_ridging(domain) call get_cice_tracer_array_category(block, ciceTracerObject, & tracerArrayCategory, iCell, setGetPhysicsTracers, setGetBGCTracers) + if (checkCarbon) then + totalCarbonFinal(iCell) = 0.0_RKIND + call seaice_total_carbon_content_category(block,totalCarbonCatFinal(:,iCell),iceAreaCategory(1,:,:),iceVolumeCategory(1,:,:),iCell) + call seaice_ocean_carbon_flux_cell(block,oceanCarbonFlux(iCell),oceanBioFluxesTemp(:,iCell),iCell) + do iCategory = 1,nCategories + totalCarbonFinal(iCell) = totalCarbonFinal(iCell) + totalCarbonCatFinal(iCategory,iCell)*iceAreaCategory(1,iCategory,iCell) + enddo + carbonError(iCell) = (totalCarbonFinal(iCell) - totalCarbonInitial(iCell))/config_dt + oceanCarbonFlux(iCell) + + if (abs(carbonError(iCell)) > max(10.0_RKIND*seaicePuny,1.0e-14_RKIND*abs(oceanCarbonFlux(iCell))) .and. & + MAXVAL(iceAreaCategory(1,:,iCell)) > seaicePuny .and. & + MAXVAL(iceAreaCategoryInitial(:)) > seaicePuny) then + call mpas_log_write("column_step_ridge, carbon conservation error", messageType=MPAS_LOG_ERR) + call mpas_log_write("iCell: $i", messageType=MPAS_LOG_ERR, intArgs=(/indexToCellID(iCell)/)) + call mpas_log_write("carbonError: $r", messageType=MPAS_LOG_ERR, realArgs=(/carbonError(iCell)/)) + call mpas_log_write("totalCarbonInitial: $r", messageType=MPAS_LOG_ERR, realArgs=(/totalCarbonInitial(iCell)/)) + call mpas_log_write("totalCarbonFinal: $r", messageType=MPAS_LOG_ERR, realArgs=(/totalCarbonFinal(iCell)/)) + call mpas_log_write("oceanCarbonFlux: $r", messageType=MPAS_LOG_ERR, realArgs=(/oceanCarbonFlux(iCell)/)) + + do iCategory = 1, nCategories + call mpas_log_write("iCategory: $i", messageType=MPAS_LOG_ERR, intArgs=(/iCategory/)) + call mpas_log_write("totalCarbonCatFinal(iCategory,iCell): $r", messageType=MPAS_LOG_ERR, realArgs=(/totalCarbonCatFinal(iCategory,iCell)/)) + call mpas_log_write("totalCarbonCatInitial(iCategory,iCell): $r", messageType=MPAS_LOG_ERR, realArgs=(/totalCarbonCatFinal(iCategory,iCell)/)) + call mpas_log_write("iceAreaCategory(1,iCategory,iCell): $r", messageType=MPAS_LOG_ERR, realArgs=(/iceAreaCategory(1,iCategory,iCell)/)) + call mpas_log_write("iceAreaCategoryInitial(iCategory): $r", messageType=MPAS_LOG_ERR, realArgs=(/iceAreaCategoryInitial(iCategory)/)) + enddo + endif + endif + ! code abort if (abortFlag) then call mpas_log_write("column_ridging: "//trim(abortMessage) , messageType=MPAS_LOG_ERR) @@ -3635,6 +3747,16 @@ subroutine column_ridging(domain) call seaice_critical_error_write_block(domain, block, abortFlag) call seaice_check_critical_error(domain, abortFlag) + deallocate(oceanBioFluxesTemp) + deallocate(verticalGridSpace) + deallocate(totalCarbonCatFinal) + deallocate(totalCarbonCatInitial) + deallocate(totalCarbonInitial) + deallocate(totalCarbonFinal) + deallocate(oceanCarbonFlux) + deallocate(carbonError) + deallocate(iceAreaCategoryInitial) + ! newly formed ice deallocate(newlyFormedIceLogical) @@ -3759,6 +3881,7 @@ subroutine column_biogeochemistry(domain) snowIceBioFluxes, & atmosIceBioFluxes, & oceanBioConcentrations, & + oceanBioConcentrationsInUse, & totalVerticalBiologyIce, & totalVerticalBiologySnow, & penetratingShortwaveFlux, & @@ -3823,7 +3946,7 @@ subroutine column_biogeochemistry(domain) iBioLayers ! test carbon conservation - real(kind=RKIND), dimension(:), allocatable :: & + real(kind=RKIND), dimension(:,:), allocatable :: & totalCarbonCatFinal, & totalCarbonCatInitial, & totalCarbonCatFlux, & @@ -3831,12 +3954,13 @@ subroutine column_biogeochemistry(domain) brineHeightCatFinal real(kind=RKIND), dimension(:), allocatable :: & - oceanBioConcentrationsUsed, & - iceCarbonInitialCategory, & - iceCarbonFinalCategory, & - iceCarbonFluxCategory, & - iceBrineInitialCategory, & - iceBrineFinalCategory + totalCarbonFinal, & + totalCarbonInitial, & + totalCarbonFlux, & + carbonError + + real(kind=RKIND):: & + errorCheck logical, dimension(:), allocatable :: & newlyFormedIceLogical @@ -3852,12 +3976,8 @@ subroutine column_biogeochemistry(domain) abortMessage, & abortLocation - real(kind=RKIND) :: & - carbonErrorCat, & - carbonErrorColumnPackage - real(kind=RKIND), parameter :: & - accuracy = 1.0e-14_RKIND + accuracy = 1.0e-13_RKIND ! test carbon conservation checkCarbon = .false. @@ -3932,6 +4052,7 @@ subroutine column_biogeochemistry(domain) call MPAS_pool_get_array(biogeochemistry, "snowIceBioFluxes", snowIceBioFluxes) call MPAS_pool_get_array(biogeochemistry, "atmosIceBioFluxes", atmosIceBioFluxes) call MPAS_pool_get_array(biogeochemistry, "oceanBioConcentrations", oceanBioConcentrations) + call MPAS_pool_get_array(biogeochemistry, "oceanBioConcentrationsInUse", oceanBioConcentrationsInUse) call MPAS_pool_get_array(biogeochemistry, "totalVerticalBiologyIce", totalVerticalBiologyIce) call MPAS_pool_get_array(biogeochemistry, "totalVerticalBiologySnow", totalVerticalBiologySnow) call MPAS_pool_get_array(biogeochemistry, "zSalinityIceDensity", zSalinityIceDensity) @@ -3995,16 +4116,37 @@ subroutine column_biogeochemistry(domain) ! newly formed ice allocate(newlyFormedIceLogical(nCategories)) - allocate(oceanBioConcentrationsUsed(ciceTracerObject % nBioTracers)) - allocate(brineHeightCatInitial(nCategories)) + allocate(brineHeightCatInitial(nCategories,nCellsSolve)) + allocate(carbonError(nCellsSolve)) if (checkCarbon) then - allocate(totalCarbonCatFinal(nCategories)) - allocate(totalCarbonCatInitial(nCategories)) - allocate(totalCarbonCatFlux(nCategories)) - allocate(brineHeightCatFinal(nCategories)) + allocate(totalCarbonCatFinal(nCategories,nCellsSolve)) + allocate(totalCarbonCatInitial(nCategories,nCellsSolve)) + allocate(totalCarbonCatFlux(nCategories,nCellsSolve)) + allocate(brineHeightCatFinal(nCategories,nCellsSolve)) + allocate(totalCarbonFinal(nCellsSolve)) + allocate(totalCarbonInitial(nCellsSolve)) + allocate(totalCarbonFlux(nCellsSolve)) + else + allocate(totalCarbonCatFinal(1,1)) + allocate(totalCarbonCatInitial(1,1)) + allocate(totalCarbonCatFlux(1,1)) + allocate(brineHeightCatFinal(1,1)) + allocate(totalCarbonFinal(1)) + allocate(totalCarbonInitial(1)) + allocate(totalCarbonFlux(1)) endif + brineHeightCatInitial(:,:) = 0.0_RKIND + carbonError(:) = 0.0_RKIND + totalCarbonCatFinal(:,:) = 0.0_RKIND + totalCarbonCatInitial(:,:) = 0.0_RKIND + totalCarbonCatFlux(:,:) = 0.0_RKIND + brineHeightCatFinal(:,:) = 0.0_RKIND + totalCarbonFinal(:) = 0.0_RKIND + totalCarbonInitial(:) = 0.0_RKIND + totalCarbonFlux(:) = 0.0_RKIND + setGetPhysicsTracers = .true. setGetBGCTracers = (config_use_column_biogeochemistry .or. config_use_zaerosols) @@ -4013,12 +4155,19 @@ subroutine column_biogeochemistry(domain) abortMessage = "" atmosBioFluxes(:,:) = 0.0_RKIND - + oceanBioConcentrationsInUse(:,:) = 0.0_RKIND + + !$offomp parallel do default(shared) private(iCategory,iBioTracers,iAlgae, iBioLayers) & + !$offomp& firstprivate(atmosBioFluxes,atmosBlackCarbonFlux, & + !$offomp& totalCarbonCatInitial, totalCarbonCatFinal, & + !$offomp& totalCarbonInitial, totalCarbonFinal, totalCarbonFlux, & + !$offomp& atmosDustFlux, bioShortwaveFluxCell, newlyFormedIce) + ! do iCell = 1, nCellsSolve ! newly formed ice do iCategory = 1, nCategories newlyFormedIceLogical(iCategory) = (newlyFormedIce(iCategory,iCell) == 1) - brineHeightCatInitial(iCategory) = brineFraction(1,iCategory,iCell) * & + brineHeightCatInitial(iCategory,iCell) = brineFraction(1,iCategory,iCell) * & iceVolumeCategoryInitial(iCategory,iCell)/(iceAreaCategoryInitial(iCategory,iCell) + seaicePuny) enddo ! iCategory rayleighCriteria = (rayleighCriteriaReal(iCell) > 0.5_RKIND) @@ -4067,14 +4216,20 @@ subroutine column_biogeochemistry(domain) do iBioTracers = 1, ciceTracerObject % nBioTracers iBioData = ciceTracerObject % index_LayerIndexToDataArray(iBioTracers) - oceanBioConcentrationsUsed(iBioTracers) = oceanBioConcentrations(iBioData,iCell) + oceanBioConcentrationsInUse(iBioTracers,iCell) = oceanBioConcentrations(iBioData,iCell) enddo ! iBioTracers call set_cice_tracer_array_category(block, ciceTracerObject, & tracerArrayCategory, iCell, setGetPhysicsTracers, setGetBGCTracers) - if (checkCarbon) call seaice_total_carbon_content_category(block,& - totalCarbonCatInitial,iceAreaCategoryInitial,iceVolumeCategoryInitial,iCell) + if (checkCarbon) then + call seaice_total_carbon_content_category(block,& + totalCarbonCatInitial(:,iCell),iceAreaCategoryInitial(:,:),iceVolumeCategoryInitial(:,:),iCell) + totalCarbonInitial(iCell) = 0.0_RKIND + do iCategory = 1, nCategories + totalCarbonInitial(iCell) = totalCarbonInitial(iCell) + totalCarbonCatInitial(iCategory,iCell)*iceAreaCategoryInitial(iCategory,iCell) + enddo + endif call colpkg_clear_warnings() call colpkg_biogeochemistry(& @@ -4096,7 +4251,7 @@ subroutine column_biogeochemistry(domain) verticalNitrogenLosses(:,:,iCell), & snowIceBioFluxes(:,iCell), & atmosIceBioFluxes(:,iCell), & - oceanBioConcentrationsUsed(:), & + oceanBioConcentrationsInUse(:,iCell), & newlyFormedIceLogical(:), & shortwaveLayerPenetration(:,:,iCell), & bioPorosity(:,:,iCell), & @@ -4161,35 +4316,43 @@ subroutine column_biogeochemistry(domain) tracerArrayCategory, iCell, setGetPhysicsTracers, setGetBGCTracers) if (checkCarbon) then - call seaice_total_carbon_content_category(block,totalCarbonCatFinal,iceAreaCategory(1,:,:),iceVolumeCategory(1,:,:),iCell) - call seaice_ocean_carbon_flux(block,totalCarbonCatFlux,oceanBioFluxesCategory(:,:,:),iCell) - do iCategory = 1,nCategories - brineHeightCatFinal(iCategory) = brineFraction(1,iCategory,iCell) * & + call seaice_total_carbon_content_category(block,totalCarbonCatFinal(:,iCell),iceAreaCategory(1,:,:),iceVolumeCategory(1,:,:),iCell) + call seaice_ocean_carbon_flux(block,totalCarbonCatFlux(:,iCell),oceanBioFluxesCategory(:,:,:),iCell) + totalCarbonFinal(iCell) = 0.0_RKIND + totalCarbonFlux(iCell) = 0.0_RKIND + do iCategory = 1, nCategories + totalCarbonFinal(iCell) = totalCarbonFinal(iCell) + totalCarbonCatFinal(iCategory,iCell)*iceAreaCategory(1,iCategory,iCell) + totalCarbonFlux(iCell) = totalCarbonFlux(iCell) + totalCarbonCatFlux(iCategory,iCell) * iceAreaCategory(1,iCategory,iCell) + enddo + carbonError(iCell) = (totalCarbonFinal(iCell) - totalCarbonInitial(iCell))/config_dt + totalCarbonFlux(iCell) + errorCheck = MAX(accuracy,accuracy*abs(totalCarbonFlux(iCell))) + + if (abs(carbonError(iCell)) > errorCheck) then + do iCategory = 1,nCategories + if (iceAreaCategory(1,iCategory,iCell) > seaicePuny) then + brineHeightCatFinal(iCategory,iCell) = brineFraction(1,iCategory,iCell) * & iceVolumeCategory(1,iCategory,iCell)/(iceAreaCategory(1,iCategory,iCell) + seaicePuny) - carbonErrorCat = totalCarbonCatInitial(iCategory) - totalCarbonCatFlux(iCategory)*config_dt - & - totalCarbonCatFinal(iCategory) - if (abs(carbonErrorCat) > accuracy*MAXVAL((/totalCarbonCatInitial(iCategory),totalCarbonCatFinal(iCategory)/))) then -! abortFlag = .true. -! abortMessage = "carbon conservation errror after column bgc" - call mpas_log_write("column_biogeochemistry, carbon conservation error", messageType=MPAS_LOG_ERR) - call mpas_log_write("iCell: $i", messageType=MPAS_LOG_ERR, intArgs=(/indexToCellID(iCell)/)) - call mpas_log_write("iCategory: $i", messageType=MPAS_LOG_ERR, intArgs=(/iCategory/)) - call mpas_log_write("carbonErrorCat: $r", messageType=MPAS_LOG_ERR, realArgs=(/carbonErrorCat/)) - call mpas_log_write("carbonErrorCat*iceAreaCategory: $r", messageType=MPAS_LOG_ERR, realArgs=(/carbonErrorCat*iceAreaCategory(1,iCategory,iCell)/)) - call mpas_log_write("totalCarbonCatInitial(iCategory): $r", messageType=MPAS_LOG_ERR, realArgs=(/totalCarbonCatInitial(iCategory)/)) - call mpas_log_write("totalCarbonCatFinal(iCategory): $r", messageType=MPAS_LOG_ERR, realArgs=(/totalCarbonCatFinal(iCategory)/)) - call mpas_log_write("totalCarbonCatFlux(iCategory): $r", messageType=MPAS_LOG_ERR, realArgs=(/totalCarbonCatFlux(iCategory)/)) - call mpas_log_write("brineHeightCatInitial(iCategory): $r", messageType=MPAS_LOG_ERR, realArgs=(/brineHeightCatInitial(iCategory)/)) - call mpas_log_write("brineHeightCatFinal(iCategory): $r", messageType=MPAS_LOG_ERR, realArgs=(/brineHeightCatFinal(iCategory)/)) - endif - enddo - endif + call mpas_log_write("column_biogeochemistry, carbon conservation error", messageType=MPAS_LOG_ERR) + call mpas_log_write("iCell: $i", messageType=MPAS_LOG_ERR, intArgs=(/indexToCellID(iCell)/)) + call mpas_log_write("iCategory: $i", messageType=MPAS_LOG_ERR, intArgs=(/iCategory/)) + call mpas_log_write("carbonError: $r", messageType=MPAS_LOG_ERR, realArgs=(/carbonError(iCell)/)) + call mpas_log_write("carbonError*iceAreaCategory: $r", messageType=MPAS_LOG_ERR, realArgs=(/carbonError(iCell)*iceAreaCategory(1,iCategory,iCell)/)) + call mpas_log_write("iceAreaCategory: $r", messageType=MPAS_LOG_ERR, realArgs=(/iceAreaCategory(1,iCategory,iCell)/)) + call mpas_log_write("iceAreaCategoryInitial: $r", messageType=MPAS_LOG_ERR, realArgs=(/iceAreaCategoryInitial(iCategory,iCell)/)) + call mpas_log_write("totalCarbonCatInitial(iCategory,iCell): $r", messageType=MPAS_LOG_ERR, realArgs=(/totalCarbonCatInitial(iCategory,iCell)/)) + call mpas_log_write("totalCarbonCatFinal(iCategory,iCell): $r", messageType=MPAS_LOG_ERR, realArgs=(/totalCarbonCatFinal(iCategory,iCell)/)) + call mpas_log_write("totalCarbonCatFlux(iCategory,iCell): $r", messageType=MPAS_LOG_ERR, realArgs=(/totalCarbonCatFlux(iCategory,iCell)/)) + call mpas_log_write("brineHeightCatInitial(iCategory,iCell): $r", messageType=MPAS_LOG_ERR, realArgs=(/brineHeightCatInitial(iCategory,iCell)/)) + call mpas_log_write("brineHeightCatFinal(iCategory,iCell): $r", messageType=MPAS_LOG_ERR, realArgs=(/brineHeightCatFinal(iCategory,iCell)/)) + endif + enddo + endif !carbonError + endif ! code abort if (abortFlag) then call mpas_log_write("column_biogeochemistry: "//trim(abortMessage) , messageType=MPAS_LOG_ERR) call mpas_log_write("iCell: $i", messageType=MPAS_LOG_ERR, intArgs=(/indexToCellID(iCell)/)) - exit endif totalSkeletalAlgae(iCell) = 0.0_RKIND @@ -4222,16 +4385,17 @@ subroutine column_biogeochemistry(domain) call seaice_critical_error_write_block(domain, block, abortFlag) call seaice_check_critical_error(domain, abortFlag) - if (checkCarbon) then - deallocate(totalCarbonCatFinal) - deallocate(totalCarbonCatInitial) - deallocate(totalCarbonCatFlux) - deallocate(brineHeightCatFinal) - endif + deallocate(totalCarbonCatFinal) + deallocate(totalCarbonCatInitial) + deallocate(totalCarbonCatFlux) + deallocate(brineHeightCatFinal) + deallocate(totalCarbonFinal) + deallocate(totalCarbonInitial) + deallocate(totalCarbonFlux) deallocate(brineHeightCatInitial) deallocate(newlyFormedIceLogical) - deallocate(oceanBioConcentrationsUsed) + deallocate(carbonError) block => block % next end do diff --git a/components/mpas-seaice/src/shared/mpas_seaice_constants.F b/components/mpas-seaice/src/shared/mpas_seaice_constants.F index 9a36d97b0919..5c6a270704b2 100644 --- a/components/mpas-seaice/src/shared/mpas_seaice_constants.F +++ b/components/mpas-seaice/src/shared/mpas_seaice_constants.F @@ -187,7 +187,7 @@ module seaice_constants ! biogeochemistry constants real(kind=RKIND), public :: & skeletalLayerThickness = 0.03_RKIND ,&! (m) skeletal layer thickness - gramsCarbonPerMolCarbon ! g carbon per mol carbon + gramsCarbonPerMolCarbon = 12.0107_RKIND ! g carbon per mol carbon ! ocean biogeochemistry ISPOL values real(kind=RKIND), parameter, public :: & diff --git a/components/mpas-seaice/src/shared/mpas_seaice_icepack.F b/components/mpas-seaice/src/shared/mpas_seaice_icepack.F index fe3b3d5e977e..05e6f98f3375 100644 --- a/components/mpas-seaice/src/shared/mpas_seaice_icepack.F +++ b/components/mpas-seaice/src/shared/mpas_seaice_icepack.F @@ -2092,6 +2092,9 @@ subroutine column_itd_thermodynamics(domain, clock) use icepack_intfc, only: & icepack_step_therm2 + use seaice_constants, only: & + seaicePuny + type(domain_type), intent(inout) :: domain type(MPAS_clock_type), intent(in) :: clock @@ -2171,6 +2174,7 @@ subroutine column_itd_thermodynamics(domain, clock) oceanAerosolFlux, & oceanBioFluxes, & oceanBioConcentrations, & + oceanBioConcentrationsInUse, & initialSalinityProfile ! WaveSpectra, & ! DFloeSizeNewIce, & @@ -2200,21 +2204,18 @@ subroutine column_itd_thermodynamics(domain, clock) iBioLayers ! test carbon conservation - real(kind=RKIND), dimension(:), allocatable :: & + real(kind=RKIND), dimension(:,:), allocatable :: & totalCarbonCatFinal, & totalCarbonCatInitial, & - oceanBioFluxesTemp, & - verticalGridSpace + oceanBioFluxesTemp - real(kind=RKIND) :: & - oceanCarbonFlux, & + real(kind=RKIND), dimension(:), allocatable :: & + verticalGridSpace, & totalCarbonFinal, & totalCarbonInitial, & + oceanCarbonFlux, & carbonError - real(kind=RKIND), dimension(:), allocatable :: & - oceanBioConcentrationsUsed - logical, dimension(:), allocatable :: & newlyFormedIceLogical @@ -2319,6 +2320,7 @@ subroutine column_itd_thermodynamics(domain, clock) call MPAS_pool_get_array(biogeochemistry, "newlyFormedIce", newlyFormedIce) call MPAS_pool_get_array(biogeochemistry, "oceanBioFluxes", oceanBioFluxes) call MPAS_pool_get_array(biogeochemistry, "oceanBioConcentrations", oceanBioConcentrations) + call MPAS_pool_get_array(biogeochemistry, "oceanBioConcentrationsInUse", oceanBioConcentrationsInUse) call MPAS_pool_get_array(biogeochemistry, "biologyGrid", biologyGrid) call MPAS_pool_get_array(biogeochemistry, "verticalGrid", verticalGrid) call MPAS_pool_get_array(biogeochemistry, "interfaceBiologyGrid", interfaceBiologyGrid) @@ -2330,12 +2332,22 @@ subroutine column_itd_thermodynamics(domain, clock) ! newly formed ice allocate(newlyFormedIceLogical(nCategories)) - allocate(oceanBioConcentrationsUsed(ciceTracerObject % nBioTracers)) - allocate(oceanBioFluxesTemp(ciceTracerObject % nBioTracers)) + allocate(oceanBioFluxesTemp(ciceTracerObject % nBioTracers,nCellsSolve)) allocate(verticalGridSpace(nBioLayersP1)) if (checkCarbon) then - allocate(totalCarbonCatFinal(nCategories)) - allocate(totalCarbonCatInitial(nCategories)) + allocate(totalCarbonCatFinal(nCategories,nCellsSolve)) + allocate(totalCarbonCatInitial(nCategories,nCellsSolve)) + allocate(totalCarbonInitial(nCellsSolve)) + allocate(totalCarbonFinal(nCellsSolve)) + allocate(oceanCarbonFlux(nCellsSolve)) + allocate(carbonError(nCellsSolve)) + else + allocate(totalCarbonCatFinal(1,1)) + allocate(totalCarbonCatInitial(1,1)) + allocate(totalCarbonInitial(1)) + allocate(totalCarbonFinal(1)) + allocate(oceanCarbonFlux(1)) + allocate(carbonError(1)) endif verticalGridSpace(:) = 1.0_RKIND/real(nBioLayers,kind=RKIND) @@ -2345,14 +2357,17 @@ subroutine column_itd_thermodynamics(domain, clock) setGetPhysicsTracers = .true. setGetBGCTracers = (config_use_column_biogeochemistry .or. config_use_zaerosols) + oceanBioConcentrationsInUse(:,:) = 0.0_RKIND ! code abort abortFlag = .false. abortMessage = "" - !$omp parallel do default(shared) private(iCategory,iBioTracers,iBioData,& - !$omp& totalCarbonInitial,abortMessage,oceanBioFluxesTemp,totalCarbonFinal,& - !$omp& carbonError) firstprivate(newlyFormedIceLogical,oceanBioConcentrationsUsed) & - !$omp& reduction(.or.:abortFlag) + !$offomp parallel do default(shared) private(iCategory,iBioTracers,iBioData,& + !$offomp& totalCarbonInitial,abortMessage,oceanBioFluxesTemp,totalCarbonFinal,& + !$offomp& totalCarbonCatInitial, totalCarbonCatFinal, & + !$offomp& oceanCarbonFlux, carbonError) & + !$offomp& firstprivate(newlyFormedIceLogical) & + !$offomp& reduction(.or.:abortFlag) do iCell = 1, nCellsSolve ! newly formed ice @@ -2363,7 +2378,7 @@ subroutine column_itd_thermodynamics(domain, clock) ! read the required ocean concentration fields into the allocated array do iBioTracers = 1, ciceTracerObject % nBioTracers iBioData = ciceTracerObject % index_LayerIndexToDataArray(iBioTracers) - oceanBioConcentrationsUsed(iBioTracers) = oceanBioConcentrations(iBioData, iCell) + oceanBioConcentrationsInUse(iBioTracers, iCell) = oceanBioConcentrations(iBioData, iCell) enddo ! iBioTracers ! set the category tracer array @@ -2371,14 +2386,14 @@ subroutine column_itd_thermodynamics(domain, clock) tracerArrayCategory, iCell, setGetPhysicsTracers, setGetBGCTracers) if (checkCarbon) then - totalCarbonInitial = 0.0_RKIND - call seaice_total_carbon_content_category(block,totalCarbonCatInitial,iceAreaCategory(1,:,:),iceVolumeCategory(1,:,:),iCell) + totalCarbonInitial(iCell) = 0.0_RKIND + call seaice_total_carbon_content_category(block,totalCarbonCatInitial(:,iCell),iceAreaCategory(1,:,:),iceVolumeCategory(1,:,:),iCell) do iCategory = 1,nCategories - totalCarbonInitial = totalCarbonInitial + totalCarbonCatInitial(iCategory)*iceAreaCategory(1,iCategory,iCell) + totalCarbonInitial(iCell) = totalCarbonInitial(iCell) + totalCarbonCatInitial(iCategory,iCell)*iceAreaCategory(1,iCategory,iCell) enddo endif - oceanBioFluxesTemp(:) = 0.0_RKIND + oceanBioFluxesTemp(:,iCell) = 0.0_RKIND ! CICE calculates the Sig Wave Height from the wave spectrum as follows before step therm2: ! we will use the Sig Wave Height from WW3, but could use this for testing without WW3 @@ -2387,10 +2402,10 @@ subroutine column_itd_thermodynamics(domain, clock) call icepack_step_therm2(& dt=config_dt, & ncat=nCategories, & - nltrcr=ciceTracerObject % nBioTracers, & ! CHECK/FIX for BGC nilyr=nIcelayers, & nslyr=nSnowLayers, & hin_max=categoryThicknessLimits(:), & + nbtrcr=ciceTracerObject % nBioTracers, & nblyr=nBioLayers, & aicen=iceAreaCategory(1,:,iCell), & vicen=iceVolumeCategory(1,:,iCell), & @@ -2423,8 +2438,8 @@ subroutine column_itd_thermodynamics(domain, clock) igrid=interfaceBiologyGrid(:), & faero_ocn=oceanAerosolFlux(:,iCell), & first_ice=newlyFormedIceLogical(:), & - flux_bio=oceanBioFluxesTemp(:), & - ocean_bio=oceanBioConcentrationsUsed(:), & + flux_bio=oceanBioFluxesTemp(:,iCell), & + ocean_bio=oceanBioConcentrationsInUse(:,iCell), & frazil_diag=frazilGrowthDiagnostic(iCell), & frz_onset=freezeOnset(iCell), & ! optional yday=dayOfYear) ! optional @@ -2442,9 +2457,13 @@ subroutine column_itd_thermodynamics(domain, clock) ! d_afsd_newi=DFloeSizeNewIce(:,iCell), & ! d_afsd_latm=DFloeSizeLateralMelt(:,iCell), & ! d_afsd_weld=DFloeSizeWeld(:,iCell), & -! floe_rad_c=FloeSizeBinCenter(:), & +! floe_rad_c=FloeSizeBinCenter(:), & ! floe_binwidth=FloeSizeBinWidth(:)) + do iBioTracers = 1, ciceTracerObject % nBioTracers + oceanBioFluxes(iBioTracers,iCell) = oceanBioFluxes(iBioTracers,iCell) + oceanBioFluxesTemp(iBioTracers,iCell) + enddo + abortFlag = icepack_warnings_aborted() call seaice_icepack_write_warnings(abortFlag) @@ -2459,26 +2478,31 @@ subroutine column_itd_thermodynamics(domain, clock) tracerArrayCategory, iCell, setGetPhysicsTracers, setGetBGCTracers) if (checkCarbon) then - totalCarbonFinal = 0.0_RKIND - call seaice_total_carbon_content_category(block,totalCarbonCatFinal,iceAreaCategory(1,:,:),iceVolumeCategory(1,:,:),iCell) - call seaice_ocean_carbon_flux_cell(block,oceanCarbonFlux,oceanBioFluxesTemp,iCell) + totalCarbonFinal(iCell) = 0.0_RKIND + call seaice_total_carbon_content_category(block,totalCarbonCatFinal(:,iCell),iceAreaCategory(1,:,:),iceVolumeCategory(1,:,:),iCell) + call seaice_ocean_carbon_flux_cell(block,oceanCarbonFlux(iCell),oceanBioFluxesTemp(:,iCell)) do iCategory = 1,nCategories - totalCarbonFinal = totalCarbonFinal + totalCarbonCatFinal(iCategory)*iceAreaCategory(1,iCategory,iCell) + totalCarbonFinal(iCell) = totalCarbonFinal(iCell) + totalCarbonCatFinal(iCategory,iCell)*iceAreaCategory(1,iCategory,iCell) enddo - carbonError = totalCarbonInitial - oceanCarbonFlux*config_dt - totalCarbonFinal + carbonError(iCell) = (totalCarbonFinal(iCell) - totalCarbonInitial(iCell))/config_dt + oceanCarbonFlux(iCell) - if (abs(carbonError) > 1.0e-14_RKIND*MAXVAL((/totalCarbonInitial,totalCarbonFinal/))) then + if (abs(carbonError(iCell)) > max(seaicePuny,1.0e-14_RKIND*abs(oceanCarbonFlux(iCell)))) then call mpas_log_write("column_step_therm2, carbon conservation error", messageType=MPAS_LOG_ERR) call mpas_log_write("iCell: $i", messageType=MPAS_LOG_ERR, intArgs=(/indexToCellID(iCell)/)) - call mpas_log_write("carbonError: $r", messageType=MPAS_LOG_ERR, realArgs=(/carbonError/)) - call mpas_log_write("totalCarbonInitial: $r", messageType=MPAS_LOG_ERR, realArgs=(/totalCarbonInitial/)) - call mpas_log_write("totalCarbonFinal: $r", messageType=MPAS_LOG_ERR, realArgs=(/totalCarbonFinal/)) - call mpas_log_write("oceanCarbonFlux: $r", messageType=MPAS_LOG_ERR, realArgs=(/oceanCarbonFlux/)) + call mpas_log_write("carbonError: $r", messageType=MPAS_LOG_ERR, realArgs=(/carbonError(iCell)/)) + call mpas_log_write("totalCarbonInitial: $r", messageType=MPAS_LOG_ERR, realArgs=(/totalCarbonInitial(iCell)/)) + call mpas_log_write("totalCarbonFinal: $r", messageType=MPAS_LOG_ERR, realArgs=(/totalCarbonFinal(iCell)/)) + call mpas_log_write("oceanCarbonFlux: $r", messageType=MPAS_LOG_ERR, realArgs=(/oceanCarbonFlux(iCell)/)) + call mpas_log_write("config_dt: $r", messageType=MPAS_LOG_ERR, realArgs=(/config_dt/)) do iCategory = 1, nCategories call mpas_log_write("iCategory: $i", messageType=MPAS_LOG_ERR, intArgs=(/iCategory/)) - call mpas_log_write("totalCarbonCatFinal(iCategory): $r", messageType=MPAS_LOG_ERR, realArgs=(/totalCarbonCatFinal(iCategory)/)) - call mpas_log_write("totalCarbonCatInitial(iCategory): $r", messageType=MPAS_LOG_ERR, realArgs=(/totalCarbonCatFinal(iCategory)/)) + call mpas_log_write("totalCarbonCatFinal(iCategory,iCell): $r", messageType=MPAS_LOG_ERR, realArgs=(/totalCarbonCatFinal(iCategory,iCell)/)) + call mpas_log_write("totalCarbonCatInitial(iCategory,iCell): $r", messageType=MPAS_LOG_ERR, realArgs=(/totalCarbonCatInitial(iCategory,iCell)/)) + call mpas_log_write("iceAreaCategoryInitial(iCategory,iCell): $r", messageType=MPAS_LOG_ERR, realArgs=(/iceAreaCategoryInitial(iCategory,iCell)/)) + call mpas_log_write("iceVolumeCategoryInitial(iCategory,iCell): $r", messageType=MPAS_LOG_ERR, realArgs=(/iceVolumeCategoryInitial(iCategory,iCell)/)) + call mpas_log_write("iceAreaCategory(1,iCategory,iCell): $r", messageType=MPAS_LOG_ERR, realArgs=(/iceAreaCategory(1,iCategory,iCell)/)) + call mpas_log_write("iceVolumeCategory(1,iCategory,iCell): $r", messageType=MPAS_LOG_ERR, realArgs=(/iceVolumeCategory(1,iCategory,iCell)/)) enddo endif endif @@ -2495,14 +2519,15 @@ subroutine column_itd_thermodynamics(domain, clock) call seaice_critical_error_write_block(domain, block, abortFlag) call seaice_check_critical_error(domain, abortFlag) - if (checkCarbon) then - deallocate(totalCarbonCatFinal) - deallocate(totalCarbonCatInitial) - endif + deallocate(totalCarbonCatFinal) + deallocate(totalCarbonCatInitial) + deallocate(totalCarbonInitial) + deallocate(totalCarbonFinal) + deallocate(oceanCarbonFlux) + deallocate(carbonError) ! newly formed ice deallocate(newlyFormedIceLogical) - deallocate(oceanBioConcentrationsUsed) deallocate(oceanBioFluxesTemp) deallocate(verticalGridSpace) @@ -3285,6 +3310,9 @@ subroutine column_ridging(domain) use icepack_intfc, only: & icepack_step_ridge + use seaice_constants, only: & + seaicePuny + type(domain_type), intent(inout) :: domain type(block_type), pointer :: block @@ -3321,7 +3349,8 @@ subroutine column_ridging(domain) nIceLayers, & nSnowLayers, & nAerosols, & - nBioLayers + nBioLayers, & + nBioLayersP1 ! variables real(kind=RKIND), dimension(:), pointer :: & @@ -3370,14 +3399,34 @@ subroutine column_ridging(domain) ! local integer :: & iCell, & - iCategory + iCategory, & + iBioTracers, & + iBioData, & + iBioLayers + + ! test carbon conservation + real(kind=RKIND), dimension(:,:), allocatable :: & + totalCarbonCatFinal, & + totalCarbonCatInitial, & + oceanBioFluxesTemp + + real(kind=RKIND), dimension(:), allocatable :: & + verticalGridSpace, & + totalCarbonFinal, & + totalCarbonInitial, & + oceanCarbonFlux, & + carbonError, & + iceAreaCategoryInitial logical, dimension(:), allocatable :: & newlyFormedIceLogical logical :: & setGetPhysicsTracers, & - setGetBGCTracers + setGetBGCTracers, & + checkCarbon + + checkCarbon = .false. block => domain % blocklist do while (associated(block)) @@ -3398,6 +3447,7 @@ subroutine column_ridging(domain) call MPAS_pool_get_config(block % configs, "config_dynamics_subcycle_number", config_dynamics_subcycle_number) call MPAS_pool_get_config(block % configs, "config_use_column_biogeochemistry", config_use_column_biogeochemistry) call MPAS_pool_get_config(block % configs, "config_use_zaerosols", config_use_zaerosols) + call MPAS_pool_get_config(block % configs, "config_dt", config_dt) call MPAS_pool_get_array(velocity_solver, "dynamicsTimeStep", dynamicsTimeStep) @@ -3407,6 +3457,7 @@ subroutine column_ridging(domain) call MPAS_pool_get_dimension(mesh, "nSnowLayers", nSnowLayers) call MPAS_pool_get_dimension(mesh, "nAerosols", nAerosols) call MPAS_pool_get_dimension(block % dimensions, "nBioLayers", nBioLayers) + call MPAS_pool_get_dimension(block % dimensions, "nBioLayersP1", nBioLayersP1) call MPAS_pool_get_array(mesh, "indexToCellID", indexToCellID) @@ -3455,6 +3506,30 @@ subroutine column_ridging(domain) setGetPhysicsTracers = .true. setGetBGCTracers = (config_use_column_biogeochemistry .or. config_use_zaerosols) + allocate(oceanBioFluxesTemp(ciceTracerObject % nBioTracers,nCellsSolve)) + allocate(verticalGridSpace(nBioLayersP1)) + if (checkCarbon) then + allocate(totalCarbonCatFinal(nCategories,nCellsSolve)) + allocate(totalCarbonCatInitial(nCategories,nCellsSolve)) + allocate(totalCarbonInitial(nCellsSolve)) + allocate(totalCarbonFinal(nCellsSolve)) + allocate(oceanCarbonFlux(nCellsSolve)) + allocate(carbonError(nCellsSolve)) + allocate(iceAreaCategoryInitial(nCategories)) + else + allocate(totalCarbonCatFinal(1,1)) + allocate(totalCarbonCatInitial(1,1)) + allocate(totalCarbonInitial(1)) + allocate(totalCarbonFinal(1)) + allocate(oceanCarbonFlux(1)) + allocate(carbonError(1)) + allocate(iceAreaCategoryInitial(1)) + endif + + verticalGridSpace(:) = 1.0_RKIND/real(nBioLayers,kind=RKIND) + verticalGridSpace(1) = verticalGridSpace(1)/2.0_RKIND + verticalGridSpace(nBioLayersP1) = verticalGridSpace(1) + do iCell = 1, nCellsSolve ! newly formed ice @@ -3466,6 +3541,17 @@ subroutine column_ridging(domain) call set_cice_tracer_array_category(block, ciceTracerObject, & tracerArrayCategory, iCell, setGetPhysicsTracers, setGetBGCTracers) + if (checkCarbon) then + totalCarbonInitial(iCell) = 0.0_RKIND + call seaice_total_carbon_content_category(block,totalCarbonCatInitial(:,iCell),iceAreaCategory(1,:,:),iceVolumeCategory(1,:,:),iCell) + do iCategory = 1,nCategories + iceAreaCategoryInitial(iCategory) = iceAreaCategory(1,iCategory,iCell) + totalCarbonInitial(iCell) = totalCarbonInitial(iCell) + totalCarbonCatInitial(iCategory,iCell)*iceAreaCategory(1,iCategory,iCell) + enddo + endif + + oceanBioFluxesTemp(:,iCell) = 0.0_RKIND + call icepack_step_ridge(& dt=dynamicsTimeStep, & ndtd=config_dynamics_subcycle_number, & @@ -3506,7 +3592,7 @@ subroutine column_ridging(domain) aice=iceAreaCell(iCell), & fsalt=oceanSaltFlux(iCell), & first_ice=newlyFormedIceLogical(:), & - flux_bio=oceanBioFluxes(:,iCell), & ! DC no closing argument + flux_bio=oceanBioFluxesTemp(:,iCell), & Tf=seaFreezingTemperature(iCell)) ! update @@ -3515,13 +3601,58 @@ subroutine column_ridging(domain) if (newlyFormedIceLogical(iCategory)) newlyFormedIce(iCategory,iCell) = 1 enddo ! iCategory + do iBioTracers = 1, ciceTracerObject % nBioTracers + oceanBioFluxes(iBioTracers,iCell) = oceanBioFluxes(iBioTracers,iCell) + oceanBioFluxesTemp(iBioTracers,iCell) + enddo + ! get category tracer array call get_cice_tracer_array_category(block, ciceTracerObject, & tracerArrayCategory, iCell, setGetPhysicsTracers, setGetBGCTracers) + if (checkCarbon) then + totalCarbonFinal(iCell) = 0.0_RKIND + call seaice_total_carbon_content_category(block,totalCarbonCatFinal(:,iCell),iceAreaCategory(1,:,:),iceVolumeCategory(1,:,:),iCell) + call seaice_ocean_carbon_flux_cell(block,oceanCarbonFlux(iCell),oceanBioFluxesTemp(:,iCell)) + do iCategory = 1,nCategories + totalCarbonFinal(iCell) = totalCarbonFinal(iCell) + totalCarbonCatFinal(iCategory,iCell)*iceAreaCategory(1,iCategory,iCell) + enddo + carbonError(iCell) = (totalCarbonFinal(iCell) - totalCarbonInitial(iCell))/config_dt + oceanCarbonFlux(iCell) + + if (abs(carbonError(iCell)) > max(10.0_RKIND*seaicePuny,1.0e-14_RKIND*abs(oceanCarbonFlux(iCell))) .and. & + MAXVAL(iceAreaCategory(1,:,iCell)) > seaicePuny .and. & + MAXVAL(iceAreaCategoryInitial(:)) > seaicePuny) then + call mpas_log_write("icepack_step_ridge, carbon conservation error", messageType=MPAS_LOG_ERR) + call mpas_log_write("iCell: $i", messageType=MPAS_LOG_ERR, intArgs=(/indexToCellID(iCell)/)) + call mpas_log_write("carbonError: $r", messageType=MPAS_LOG_ERR, realArgs=(/carbonError(iCell)/)) + call mpas_log_write("totalCarbonInitial: $r", messageType=MPAS_LOG_ERR, realArgs=(/totalCarbonInitial(iCell)/)) + call mpas_log_write("totalCarbonFinal: $r", messageType=MPAS_LOG_ERR, realArgs=(/totalCarbonFinal(iCell)/)) + call mpas_log_write("oceanCarbonFlux: $r", messageType=MPAS_LOG_ERR, realArgs=(/oceanCarbonFlux(iCell)/)) + call mpas_log_write("config_dt: $r", messageType=MPAS_LOG_ERR, realArgs=(/config_dt/)) + + do iCategory = 1, nCategories + call mpas_log_write("iCategory: $i", messageType=MPAS_LOG_ERR, intArgs=(/iCategory/)) + call mpas_log_write("totalCarbonCatFinal(iCategory,iCell): $r", messageType=MPAS_LOG_ERR, realArgs=(/totalCarbonCatFinal(iCategory,iCell)/)) + call mpas_log_write("totalCarbonCatInitial(iCategory,iCell): $r", messageType=MPAS_LOG_ERR, realArgs=(/totalCarbonCatInitial(iCategory,iCell)/)) + call mpas_log_write("iceAreaCategory(1,iCategory,iCell): $r", messageType=MPAS_LOG_ERR, realArgs=(/iceAreaCategory(1,iCategory,iCell)/)) + call mpas_log_write("iceAreaCategoryInitial(iCategory): $r", messageType=MPAS_LOG_ERR, realArgs=(/iceAreaCategoryInitial(iCategory)/)) + call mpas_log_write("iceVolumeCategory(1,iCategory,iCell): $r", messageType=MPAS_LOG_ERR, realArgs=(/iceVolumeCategory(1,iCategory,iCell)/)) + enddo + endif + endif + enddo ! iCell call seaice_icepack_write_warnings(icepack_warnings_aborted()) +! check carbon + deallocate(oceanBioFluxesTemp) + deallocate(verticalGridSpace) + deallocate(totalCarbonCatFinal) + deallocate(totalCarbonCatInitial) + deallocate(totalCarbonInitial) + deallocate(totalCarbonFinal) + deallocate(oceanCarbonFlux) + deallocate(carbonError) + deallocate(iceAreaCategoryInitial) ! newly formed ice deallocate(newlyFormedIceLogical) @@ -3591,7 +3722,8 @@ subroutine column_biogeochemistry(domain) nBioLayersP1, & nAlgae, & maxBCType, & - maxDustType + maxDustType, & + maxAerosolType ! variables @@ -3630,6 +3762,8 @@ subroutine column_biogeochemistry(domain) snowIceBioFluxes, & atmosIceBioFluxes, & oceanBioConcentrations, & + oceanBioConcentrationsInUse, & + oceanBioToIceInUse, & totalVerticalBiologyIce, & totalVerticalBiologySnow, & penetratingShortwaveFlux, & @@ -3690,10 +3824,12 @@ subroutine column_biogeochemistry(domain) iSnowCount, & iIceCount, & indexj, & - iBioLayers + iBioLayers, & + iWarning, & + nWarnings ! test carbon conservation - real(kind=RKIND), dimension(:), allocatable :: & + real(kind=RKIND), dimension(:,:), allocatable :: & totalCarbonCatFinal, & totalCarbonCatInitial, & totalCarbonCatFlux, & @@ -3701,12 +3837,12 @@ subroutine column_biogeochemistry(domain) brineHeightCatFinal real(kind=RKIND), dimension(:), allocatable :: & - oceanBioConcentrationsUsed, & - iceCarbonInitialCategory, & - iceCarbonFinalCategory, & - iceCarbonFluxCategory, & - iceBrineInitialCategory, & - iceBrineFinalCategory + totalCarbonFinal, & + totalCarbonInitial, & + totalCarbonFlux + + real(kind=RKIND) :: & + errorCheck logical, dimension(:), allocatable :: & newlyFormedIceLogical @@ -3721,12 +3857,11 @@ subroutine column_biogeochemistry(domain) abortMessage, & abortLocation - real(kind=RKIND) :: & - carbonErrorCat, & - carbonErrorColumnPackage + real(kind=RKIND), dimension(:), allocatable :: & + carbonError real(kind=RKIND), parameter :: & - accuracy = 1.0e-14_RKIND + accuracy = 1.0e-13_RKIND ! test carbon conservation checkCarbon = .false. @@ -3787,6 +3922,8 @@ subroutine column_biogeochemistry(domain) call MPAS_pool_get_array(biogeochemistry, "snowIceBioFluxes", snowIceBioFluxes) call MPAS_pool_get_array(biogeochemistry, "atmosIceBioFluxes", atmosIceBioFluxes) call MPAS_pool_get_array(biogeochemistry, "oceanBioConcentrations", oceanBioConcentrations) + call MPAS_pool_get_array(biogeochemistry, "oceanBioConcentrationsInUse", oceanBioConcentrationsInUse) + call MPAS_pool_get_array(biogeochemistry, "oceanBioToIceInUse", oceanBioToIceInUse) call MPAS_pool_get_array(biogeochemistry, "totalVerticalBiologyIce", totalVerticalBiologyIce) call MPAS_pool_get_array(biogeochemistry, "totalVerticalBiologySnow", totalVerticalBiologySnow) call MPAS_pool_get_array(biogeochemistry, "atmosBioFluxes", atmosBioFluxes) @@ -3846,36 +3983,61 @@ subroutine column_biogeochemistry(domain) ! newly formed ice allocate(newlyFormedIceLogical(nCategories)) - allocate(oceanBioConcentrationsUsed(ciceTracerObject % nBioTracers)) - allocate(brineHeightCatInitial(nCategories)) + allocate(brineHeightCatInitial(nCategories,nCellsSolve)) + allocate(carbonError(nCellsSolve)) if (checkCarbon) then - allocate(totalCarbonCatFinal(nCategories)) - allocate(totalCarbonCatInitial(nCategories)) - allocate(totalCarbonCatFlux(nCategories)) - allocate(brineHeightCatFinal(nCategories)) + allocate(totalCarbonCatFinal(nCategories,nCellsSolve)) + allocate(totalCarbonCatInitial(nCategories,nCellsSolve)) + allocate(totalCarbonCatFlux(nCategories,nCellsSolve)) + allocate(brineHeightCatFinal(nCategories,nCellsSolve)) + allocate(totalCarbonFinal(nCellsSolve)) + allocate(totalCarbonInitial(nCellsSolve)) + allocate(totalCarbonFlux(nCellsSolve)) + else + allocate(totalCarbonCatFinal(1,1)) + allocate(totalCarbonCatInitial(1,1)) + allocate(totalCarbonCatFlux(1,1)) + allocate(brineHeightCatFinal(1,1)) + allocate(totalCarbonFinal(1)) + allocate(totalCarbonInitial(1)) + allocate(totalCarbonFlux(1)) endif + brineHeightCatInitial(:,:) = 0.0_RKIND + carbonError(:) = 0.0_RKIND + totalCarbonCatFinal(:,:) = 0.0_RKIND + totalCarbonCatInitial(:,:) = 0.0_RKIND + totalCarbonCatFlux(:,:) = 0.0_RKIND + brineHeightCatFinal(:,:) = 0.0_RKIND + totalCarbonFinal(:) = 0.0_RKIND + totalCarbonInitial(:) = 0.0_RKIND + totalCarbonFlux(:) = 0.0_RKIND + setGetPhysicsTracers = .true. setGetBGCTracers = (config_use_column_biogeochemistry .or. config_use_zaerosols) atmosBioFluxes(:,:) = 0.0_RKIND - - !$omp parallel do default(shared) private(iCategory,iBioTracers,iAlgae) & - !$omp& firstprivate(atmosBioFluxes,atmosBlackCarbonFlux, & - !$omp& atmosDustFlux, bioShortwaveFluxCell, newlyFormedIce) + oceanBioConcentrationsInUse(:,:) = 0.0_RKIND + oceanBioToIceInUse(:,:) = 0.0_RKIND + + !$offomp parallel do default(shared) private(iCategory,iBioTracers,iAlgae, iBioLayers) & + !$offomp& firstprivate(atmosBioFluxes,atmosBlackCarbonFlux, & + !$offomp& totalCarbonCatInitial, totalCarbonCatFinal, & + !$offomp& totalCarbonInitial, totalCarbonFinal, totalCarbonFlux, & + !$offomp& atmosDustFlux, bioShortwaveFluxCell, newlyFormedIce) ! do iCell = 1, nCellsSolve ! newly formed ice do iCategory = 1, nCategories newlyFormedIceLogical(iCategory) = (newlyFormedIce(iCategory,iCell) == 1) - brineHeightCatInitial(iCategory) = brineFraction(1,iCategory,iCell) * & + brineHeightCatInitial(iCategory,iCell) = brineFraction(1,iCategory,iCell) * & iceVolumeCategoryInitial(iCategory,iCell)/(iceAreaCategoryInitial(iCategory,iCell) + seaicePuny) enddo ! iCategory !update ocean concentrations fields and atmospheric fluxes into allocated array -#ifdef coupled +#ifdef coupled call icepack_load_ocean_bio_array(& nit=oceanNitrateConc(iCell), & amm=oceanAmmoniumConc(iCell), & @@ -3891,7 +4053,6 @@ subroutine column_biogeochemistry(domain) zaeros=oceanZAerosolConc(:,iCell), & ocean_bio_all=oceanBioConcentrations(:,iCell), & hum=oceanHumicsConc(iCell)) - #else do iBioTracers = 1, maxBCType atmosBlackCarbonFlux(iBioTracers,iCell) = 1.e-12_RKIND @@ -3912,14 +4073,20 @@ subroutine column_biogeochemistry(domain) do iBioTracers = 1, ciceTracerObject % nBioTracers iBioData = ciceTracerObject % index_LayerIndexToDataArray(iBioTracers) - oceanBioConcentrationsUsed(iBioTracers) = oceanBioConcentrations(iBioData,iCell) + oceanBioConcentrationsInUse(iBioTracers,iCell) = oceanBioConcentrations(iBioData,iCell) enddo ! iBioTracers call set_cice_tracer_array_category(block, ciceTracerObject, & tracerArrayCategory, iCell, setGetPhysicsTracers, setGetBGCTracers) - if (checkCarbon) call seaice_total_carbon_content_category(block,& - totalCarbonCatInitial,iceAreaCategoryInitial,iceVolumeCategoryInitial,iCell) + if (checkCarbon) then + call seaice_total_carbon_content_category(block,& + totalCarbonCatInitial(:,iCell),iceAreaCategoryInitial(:,:),iceVolumeCategoryInitial(:,:),iCell) + totalCarbonInitial(iCell) = 0.0_RKIND + do iCategory = 1, nCategories + totalCarbonInitial(iCell) = totalCarbonInitial(iCell) + totalCarbonCatInitial(iCategory,iCell)*iceAreaCategoryInitial(iCategory,iCell) + enddo + endif ! code abort abortFlag = .false. @@ -3942,7 +4109,8 @@ subroutine column_biogeochemistry(domain) Zoo=verticalNitrogenLosses(:,:,iCell), & fbio_snoice=snowIceBioFluxes(:,iCell), & fbio_atmice=atmosIceBioFluxes(:,iCell), & - ocean_bio=oceanBioConcentrationsUsed(:), & + ocean_bio_dh=oceanBioToIceInUse(:,iCell), & + ocean_bio=oceanBioConcentrationsInUse(:,iCell), & first_ice=newlyFormedIceLogical(:), & fswpenln=shortwaveLayerPenetration(:,:,iCell), & bphi=bioPorosity(:,:,iCell), & @@ -3991,29 +4159,39 @@ subroutine column_biogeochemistry(domain) tracerArrayCategory, iCell, setGetPhysicsTracers, setGetBGCTracers) if (checkCarbon) then - call seaice_total_carbon_content_category(block,totalCarbonCatFinal,iceAreaCategory(1,:,:),iceVolumeCategory(1,:,:),iCell) - call seaice_ocean_carbon_flux(block,totalCarbonCatFlux,oceanBioFluxesCategory(:,:,:),iCell) - do iCategory = 1,nCategories - brineHeightCatFinal(iCategory) = brineFraction(1,iCategory,iCell) * & - iceVolumeCategory(1,iCategory,iCell)/(iceAreaCategory(1,iCategory,iCell) + seaicePuny) - carbonErrorCat = totalCarbonCatInitial(iCategory) - totalCarbonCatFlux(iCategory)*config_dt - & - totalCarbonCatFinal(iCategory) - if (abs(carbonErrorCat) > accuracy*MAXVAL((/totalCarbonCatInitial(iCategory),totalCarbonCatFinal(iCategory)/))) then -! abortFlag = .true. -! abortMessage = "carbon conservation errror after column bgc" - call mpas_log_write("column_biogeochemistry, carbon conservation error", messageType=MPAS_LOG_ERR) - call mpas_log_write("iCell: $i", messageType=MPAS_LOG_ERR, intArgs=(/indexToCellID(iCell)/)) - call mpas_log_write("iCategory: $i", messageType=MPAS_LOG_ERR, intArgs=(/iCategory/)) - call mpas_log_write("carbonErrorCat: $r", messageType=MPAS_LOG_ERR, realArgs=(/carbonErrorCat/)) - call mpas_log_write("carbonErrorCat*iceAreaCategory: $r", messageType=MPAS_LOG_ERR, realArgs=(/carbonErrorCat*iceAreaCategory(1,iCategory,iCell)/)) - call mpas_log_write("totalCarbonCatInitial(iCategory): $r", messageType=MPAS_LOG_ERR, realArgs=(/totalCarbonCatInitial(iCategory)/)) - call mpas_log_write("totalCarbonCatFinal(iCategory): $r", messageType=MPAS_LOG_ERR, realArgs=(/totalCarbonCatFinal(iCategory)/)) - call mpas_log_write("totalCarbonCatFlux(iCategory): $r", messageType=MPAS_LOG_ERR, realArgs=(/totalCarbonCatFlux(iCategory)/)) - call mpas_log_write("brineHeightCatInitial(iCategory): $r", messageType=MPAS_LOG_ERR, realArgs=(/brineHeightCatInitial(iCategory)/)) - call mpas_log_write("brineHeightCatFinal(iCategory): $r", messageType=MPAS_LOG_ERR, realArgs=(/brineHeightCatFinal(iCategory)/)) - endif + call seaice_total_carbon_content_category(block,totalCarbonCatFinal(:,iCell),iceAreaCategory(1,:,:),iceVolumeCategory(1,:,:),iCell) + call seaice_ocean_carbon_flux(block,totalCarbonCatFlux(:,iCell),oceanBioFluxesCategory(:,:,:),iCell) + totalCarbonFinal(iCell) = 0.0_RKIND + totalCarbonFlux(iCell) = 0.0_RKIND + do iCategory = 1, nCategories + totalCarbonFinal(iCell) = totalCarbonFinal(iCell) + totalCarbonCatFinal(iCategory,iCell)*iceAreaCategory(1,iCategory,iCell) + totalCarbonFlux(iCell) = totalCarbonFlux(iCell) + totalCarbonCatFlux(iCategory,iCell) * iceAreaCategory(1,iCategory,iCell) enddo - endif + carbonError(iCell) = (totalCarbonFinal(iCell) - totalCarbonInitial(iCell))/config_dt +totalCarbonFlux(iCell) + errorCheck = max(accuracy,accuracy*abs(totalCarbonFlux(iCell))) + + if (abs(carbonError(iCell)) > errorCheck) then + do iCategory = 1,nCategories + if (iceAreaCategory(1,iCategory,iCell) > seaicePuny) then + brineHeightCatFinal(iCategory,iCell) = brineFraction(1,iCategory,iCell) * & + iceVolumeCategory(1,iCategory,iCell)/(iceAreaCategory(1,iCategory,iCell) + seaicePuny) + call mpas_log_write("column_biogeochemistry, carbon conservation error", messageType=MPAS_LOG_ERR) + call mpas_log_write("iCell: $i", messageType=MPAS_LOG_ERR, intArgs=(/indexToCellID(iCell)/)) + call mpas_log_write("iCategory: $i", messageType=MPAS_LOG_ERR, intArgs=(/iCategory/)) + call mpas_log_write("carbonError: $r", messageType=MPAS_LOG_ERR, realArgs=(/carbonError(iCell)/)) + call mpas_log_write("carbonError*iceAreaCategory: $r", messageType=MPAS_LOG_ERR, realArgs=(/carbonError(iCell)*iceAreaCategory(1,iCategory,iCell)/)) + call mpas_log_write("iceAreaCategory: $r", messageType=MPAS_LOG_ERR, realArgs=(/iceAreaCategory(1,iCategory,iCell)/)) + call mpas_log_write("iceAreaCategoryInitial: $r", messageType=MPAS_LOG_ERR, realArgs=(/iceAreaCategoryInitial(iCategory,iCell)/)) + call mpas_log_write("totalCarbonCatInitial(iCategory): $r", messageType=MPAS_LOG_ERR, realArgs=(/totalCarbonCatInitial(iCategory,iCell)/)) + call mpas_log_write("totalCarbonCatFinal(iCategory,iCell): $r", messageType=MPAS_LOG_ERR, realArgs=(/totalCarbonCatFinal(iCategory,iCell)/)) + call mpas_log_write("totalCarbonCatFlux(iCategory,iCell): $r", messageType=MPAS_LOG_ERR, realArgs=(/totalCarbonCatFlux(iCategory,iCell)/)) + call mpas_log_write("brineHeightCatInitial(iCategory,iCell): $r", messageType=MPAS_LOG_ERR, realArgs=(/brineHeightCatInitial(iCategory,iCell)/)) + call mpas_log_write("brineHeightCatFinal(iCategory,iCell): $r", messageType=MPAS_LOG_ERR, realArgs=(/brineHeightCatFinal(iCategory,iCell)/)) + call mpas_log_write("iceAreaCategory(1,iCategory,iCell): $r", messageType=MPAS_LOG_ERR, realArgs=(/iceAreaCategory(1,iCategory,iCell)/)) + end if + enddo !categories + endif ! carbonError + endif ! checkCarbon totalSkeletalAlgae(iCell) = 0.0_RKIND bioShortwaveFluxCell(:,iCell) = 0.0_RKIND @@ -4047,16 +4225,17 @@ subroutine column_biogeochemistry(domain) call seaice_critical_error_write_block(domain, block, abortFlag) call seaice_check_critical_error(domain, abortFlag) - if (checkCarbon) then - deallocate(totalCarbonCatFinal) - deallocate(totalCarbonCatInitial) - deallocate(totalCarbonCatFlux) - deallocate(brineHeightCatFinal) - endif + deallocate(totalCarbonCatFinal) + deallocate(totalCarbonCatInitial) + deallocate(totalCarbonCatFlux) + deallocate(brineHeightCatFinal) + deallocate(totalCarbonFinal) + deallocate(totalCarbonInitial) + deallocate(totalCarbonFlux) deallocate(brineHeightCatInitial) deallocate(newlyFormedIceLogical) - deallocate(oceanBioConcentrationsUsed) + deallocate(carbonError) block => block % next end do @@ -4585,6 +4764,7 @@ subroutine seaice_icepack_coupling_prep(domain) oceanDMSPdFlux, & oceanHumicsFlux, & oceanDustIronFlux, & + oceanBlackCarbonFlux, & totalOceanCarbonFlux real(kind=RKIND), dimension(:,:), pointer :: & @@ -4725,6 +4905,7 @@ subroutine seaice_icepack_coupling_prep(domain) call MPAS_pool_get_array(biogeochemistry, "oceanDMSPdFlux", oceanDMSPdFlux) call MPAS_pool_get_array(biogeochemistry, "oceanHumicsFlux", oceanHumicsFlux) call MPAS_pool_get_array(biogeochemistry, "oceanDustIronFlux", oceanDustIronFlux) + call MPAS_pool_get_array(biogeochemistry, "oceanBlackCarbonFlux", oceanBlackCarbonFlux) call MPAS_pool_get_array(biogeochemistry, "oceanBioFluxes", oceanBioFluxes) call MPAS_pool_get_array(biogeochemistry, "oceanAlgaeFlux", oceanAlgaeFlux) call MPAS_pool_get_array(biogeochemistry, "oceanDOCFlux", oceanDOCFlux) @@ -4857,6 +5038,7 @@ subroutine seaice_icepack_coupling_prep(domain) oceanDMSPdFlux(iCell) = 0.0_RKIND oceanDMSFlux(iCell) = 0.0_RKIND oceanDustIronFlux(iCell) = 0.0_RKIND + oceanBlackCarbonFlux(iCell) = 0.0_RKIND oceanHumicsFlux(iCell) = 0.0_RKIND do iBioTracers = 1, ciceTracerObject % nBioTracers @@ -4939,8 +5121,11 @@ subroutine seaice_icepack_coupling_prep(domain) oceanParticulateIronFlux(iBioTracers,iCell) = oceanBioFluxesAll(iBioData) enddo - ! Black Carbon (not saved) - iBioData = iBioData + maxBCType + ! Black Carbon (combined; saved for conservation) + do iBioTracers = 1, maxBCType + iBioData = iBioData + 1 + oceanBlackCarbonFlux(iCell) = oceanBlackCarbonFlux(iCell) + oceanBioFluxesAll(iBioData) + enddo ! Dust (combined) do iBioTracers = 1, maxDustType @@ -5034,6 +5219,7 @@ subroutine seaice_column_scale_fluxes(domain) oceanDMSPpFlux, & oceanDMSPdFlux, & oceanHumicsFlux, & + oceanBlackCarbonFlux, & oceanDustIronFlux real(kind=RKIND), dimension(:,:), pointer :: & @@ -5116,6 +5302,7 @@ subroutine seaice_column_scale_fluxes(domain) call MPAS_pool_get_array(biogeochemistry, "oceanDMSPdFlux", oceanDMSPdFlux) call MPAS_pool_get_array(biogeochemistry, "oceanHumicsFlux", oceanHumicsFlux) call MPAS_pool_get_array(biogeochemistry, "oceanDustIronFlux", oceanDustIronFlux) + call MPAS_pool_get_array(biogeochemistry, "oceanBlackCarbonFlux", oceanBlackCarbonFlux) call MPAS_pool_get_array(biogeochemistry, "oceanAlgaeFlux", oceanAlgaeFlux) call MPAS_pool_get_array(biogeochemistry, "oceanDOCFlux", oceanDOCFlux) call MPAS_pool_get_array(biogeochemistry, "oceanDICFlux", oceanDICFlux) @@ -5156,8 +5343,10 @@ subroutine seaice_column_scale_fluxes(domain) albedoVisibleDiffuseCell(iCell) = albedoVisibleDiffuseCell(iCell) * iceAreaInverse albedoIRDiffuseCell(iCell) = albedoIRDiffuseCell(iCell) * iceAreaInverse - if (config_use_zaerosols) & + if (config_use_zaerosols) then oceanDustIronFlux(iCell) = oceanDustIronFlux(iCell) * iceAreaInverse + oceanBlackCarbonFlux(iCell) = oceanBlackCarbonFlux(iCell) * iceAreaInverse + end if if (config_use_column_biogeochemistry) then @@ -5210,8 +5399,10 @@ subroutine seaice_column_scale_fluxes(domain) albedoVisibleDiffuseCell(iCell) = 0.0_RKIND albedoIRDiffuseCell(iCell) = 0.0_RKIND - if (config_use_zaerosols) & - oceanDustIronFlux(iCell) = 0.0_RKIND + if (config_use_zaerosols) then + oceanDustIronFlux(iCell) = 0.0_RKIND + oceanBlackCarbonFlux(iCell) = 0.0_RKIND + end if if (config_use_column_biogeochemistry) then @@ -9125,7 +9316,6 @@ subroutine init_icepack_package_parameters(domain, tracerObject) call init_icepack_package_tracer_indices(tracerObject) ! set the column parameters - call init_column_package_configs(domain) !echmod - temporary until colpkg_constants are moved call init_icepack_package_configs(domain) end subroutine init_icepack_package_parameters @@ -9654,7 +9844,7 @@ subroutine init_icepack_package_tracer_flags(domain) tr_pond_in = use_meltponds, & tr_pond_lvl_in = config_use_level_meltponds, & tr_pond_topo_in = config_use_topo_meltponds, & - !tr_fsd_in = , & + !tr_fsd_in = config_use_floe_size_distribution, & tr_aero_in = config_use_aerosols, & !tr_iso_in = , & tr_brine_in = config_use_brine, & @@ -9837,203 +10027,84 @@ end subroutine init_icepack_package_tracer_indices !||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||| ! -! init_column_package_configs +! init_icepack_package_configs ! !> \brief -!> \author Adrian K. Turner, LANL -!> \date 2nd Feburary 2015 +!> \author Adrian K. Turner, Elizabeth Hunke, Darin Comeau, Nicole Jeffery, Andrew Roberts, Erin Thomas, Jon Wolfe, LANL, Anthony Craig, NOAA (cntr), David Bailey, NCAR +!> \date 2022-2023 !> \details !> ! !----------------------------------------------------------------------- - subroutine init_column_package_configs(domain) !colpkg routine - remove - - !use ice_colpkg_shared, only: & - ! ktherm, & - ! conduct, & - ! fbot_xfer_type, & - ! heat_capacity, & - ! calc_Tsfc, & - ! ustar_min, & - ! a_rapid_mode, & - ! Rac_rapid_mode, & - ! aspect_rapid_mode, & - ! dSdt_slow_mode, & - ! phi_c_slow_mode, & - ! phi_i_mushy, & - ! shortwave, & - ! albedo_type, & - ! albicev, & - ! albicei, & - ! albsnowv, & - ! albsnowi, & - ! ahmax, & - ! R_ice, & - ! R_pnd, & - ! R_snw, & - ! dT_mlt, & - ! rsnw_mlt, & - ! kalg, & - ! kstrength, & - ! krdg_partic, & - ! krdg_redist, & - ! mu_rdg, & - ! Cf, & - ! atmbndy, & - ! calc_strair, & - ! formdrag, & - ! highfreq, & - ! natmiter, & - ! oceanmixed_ice, & - ! tfrz_option, & - ! kitd, & - ! kcatbound, & - ! hs0, & - ! frzpnd, & - ! dpscale, & - ! rfracmin, & - ! rfracmax, & - ! pndaspect, & - ! hs1, & - ! hp1 - ! bgc_flux_type, & - ! z_tracers, & - ! scale_bgc, & - ! solve_zbgc, & - ! dEdd_algae, & - ! modal_aero, & - ! skl_bgc, & - ! solve_zsal, & - ! grid_o, & - ! l_sk, & - ! grid_o_t, & - ! initbio_frac, & - ! frazil_scav, & - ! grid_oS, & - ! l_skS, & - ! phi_snow, & - ! ratio_Si2N_diatoms, & - ! ratio_Si2N_sp , & - ! ratio_Si2N_phaeo , & - ! ratio_S2N_diatoms , & - ! ratio_S2N_sp , & - ! ratio_S2N_phaeo , & - ! ratio_Fe2C_diatoms, & - ! ratio_Fe2C_sp , & - ! ratio_Fe2C_phaeo , & - ! ratio_Fe2N_diatoms, & - ! ratio_Fe2N_sp , & - ! ratio_Fe2N_phaeo , & - ! ratio_Fe2DON , & - ! ratio_Fe2DOC_s , & - ! ratio_Fe2DOC_l , & - ! fr_resp , & - ! tau_min , & - ! tau_max , & - ! algal_vel , & - ! R_dFe2dust , & - ! dustFe_sol , & - ! chlabs_diatoms , & - ! chlabs_sp , & - ! chlabs_phaeo , & - ! alpha2max_low_diatoms , & - ! alpha2max_low_sp , & - ! alpha2max_low_phaeo , & - ! beta2max_diatoms , & - ! beta2max_sp , & - ! beta2max_phaeo , & - ! mu_max_diatoms , & - ! mu_max_sp , & - ! mu_max_phaeo , & - ! grow_Tdep_diatoms, & - ! grow_Tdep_sp , & - ! grow_Tdep_phaeo , & - ! fr_graze_diatoms , & - ! fr_graze_sp , & - ! fr_graze_phaeo , & - ! mort_pre_diatoms , & - ! mort_pre_sp , & - ! mort_pre_phaeo , & - ! mort_Tdep_diatoms, & - ! mort_Tdep_sp , & - ! mort_Tdep_phaeo , & - ! k_exude_diatoms , & - ! k_exude_sp , & - ! k_exude_phaeo , & - ! K_Nit_diatoms , & - ! K_Nit_sp , & - ! K_Nit_phaeo , & - ! K_Am_diatoms , & - ! K_Am_sp , & - ! K_Am_phaeo , & - ! K_Sil_diatoms , & - ! K_Sil_sp , & - ! K_Sil_phaeo , & - ! K_Fe_diatoms , & - ! K_Fe_sp , & - ! K_Fe_phaeo , & - ! f_don_protein , & - ! kn_bac_protein , & - ! f_don_Am_protein , & - ! f_doc_s , & - ! f_doc_l , & - ! f_exude_s , & - ! f_exude_l , & - ! k_bac_s , & - ! k_bac_l , & - ! T_max , & - ! fsal , & - ! op_dep_min , & - ! fr_graze_s , & - ! fr_graze_e , & - ! fr_mort2min , & - ! fr_dFe , & - ! k_nitrif , & - ! t_iron_conv , & - ! max_loss , & - ! max_dfe_doc1 , & - ! fr_resp_s , & - ! y_sk_DMS , & - ! t_sk_conv , & - ! t_sk_ox , & - ! algaltype_diatoms , & - ! algaltype_sp , & - ! algaltype_phaeo , & - ! nitratetype , & - ! ammoniumtype , & - ! silicatetype , & - ! dmspptype , & - ! dmspdtype , & - ! humtype , & - ! doctype_s , & - ! doctype_l , & - ! dontype_protein , & - ! fedtype_1 , & - ! feptype_1 , & - ! zaerotype_bc1 , & - ! zaerotype_bc2 , & - ! zaerotype_dust1 , & - ! zaerotype_dust2 , & - ! zaerotype_dust3 , & - ! zaerotype_dust4 , & - ! ratio_C2N_diatoms , & - ! ratio_C2N_sp , & - ! ratio_C2N_phaeo , & - ! ratio_chl2N_diatoms, & - ! ratio_chl2N_sp , & - ! ratio_chl2N_phaeo , & - ! F_abs_chl_diatoms , & - ! F_abs_chl_sp , & - ! F_abs_chl_phaeo , & - ! ratio_C2N_proteins - - use ice_colpkg, only: & - colpkg_init_parameters + subroutine init_icepack_package_configs(domain) + + use icepack_intfc, only: & + icepack_init_parameters, & + icepack_write_parameters, & + icepack_configure, & + icepack_query_parameters ! debugging + + use seaice_constants, only: & + seaicePuny, & ! a small number + seaiceBigNumber, & ! a large number + seaiceSecondsPerDay, & ! number of seconds in 1 day + seaiceDensityIce, & ! density of ice (kg/m^3) + seaiceDensitySnow, & ! density of snow (kg/m^3) + seaiceDensitySeaWater, & ! density of seawater (kg/m^3) + seaiceDensityFreshwater, & ! density of freshwater (kg/m^3) + seaiceFreshIceSpecificHeat, & ! specific heat of fresh ice (J/kg/K) + seaiceWaterVaporSpecificHeat, & ! specific heat of water vapor (J/kg/K) + seaiceAirSpecificHeat, & ! specific heat of air (J/kg/K) + seaiceSeaWaterSpecificHeat, & ! specific heat of ocn (J/kg/K) + seaiceLatentHeatVaporization, & ! latent heat, vaporization freshwater (J/kg) + seaiceZvir, & ! rh2o/rair - 1.0 + seaiceLatentHeatSublimation, & ! latent heat, sublimation freshwater (J/kg) + seaiceLatentHeatMelting, & ! latent heat of melting of fresh ice (J/kg) + seaiceIceSurfaceMeltingTemperature, & ! melting temp. ice top surface (C) + seaiceSnowSurfaceMeltingTemperature, & ! melting temp. snow top surface (C) + seaiceStefanBoltzmann, & ! J m-2 K-4 s-1 + seaiceIceSnowEmissivity, & ! emissivity of snow and ice + seaiceSnowSurfaceScatteringLayer, & ! snow surface scattering layer thickness (m) + seaiceStabilityReferenceHeight, & ! stability reference height (m) + seaiceFreshWaterFreezingPoint, & ! freezing temp of fresh ice (K) + seaiceIceSurfaceRoughness, & ! ice surface roughness (m) + seaiceVonKarmanConstant, & ! Von Karman constant + seaiceOceanAlbedo, & ! Ocean albedo + seaiceReferenceSalinity, & ! ice reference salinity (ppt) + seaiceMaximumSalinity, & ! ice maximum salinity (ppt) + seaiceMeltingTemperatureDepression, & ! melting temperature depression factor (C/ppt) + seaiceFrazilSalinityReduction, & ! bulk salinity reduction of newly formed frazil (ppt) + seaiceFrazilIcePorosity, & ! initial liquid fraction of frazil + seaicePi, & ! pi + seaiceGravity, & ! gravitational acceleration (m/s^2) + seaiceSnowPatchiness, & ! snow patchiness parameter + seaiceIceStrengthConstantHiblerP, & ! P* constant in Hibler strength formulation + seaiceIceStrengthConstantHiblerC, & ! C* constant in Hibler strength formulation + skeletalLayerThickness, & ! skeletal layer thickness + gramsCarbonPerMolCarbon, & ! grams carbon per mol carbon + seaiceSnowMinimumDensity, & ! minimum snow density (kg/m^3) + seaiceBrineDynamicViscosity, & ! dynamic viscosity of brine (kg/m/s) + seaiceFreezingTemperatureConstant, &! constant freezing temp of seawater (C) + seaiceExtinctionCoef, & ! vis extnctn coef in ice, wvlngth<700nm (1/m) + seaiceFreshIceConductivity, & ! thermal conductivity of fresh ice(W/m/deg) + seaiceSnowMinimumThickness, & ! min snow thickness for computing zTsn (m) + seaiceFrazilMinimumThickness, & ! min thickness of new frazil ice + seaiceAlbedoWtVisibleDirect, & ! visible, direct + seaiceAlbedoWtNearIRDirect, & ! near IR, direct + seaiceAlbedoWtVisibleDiffuse, & ! visible, diffuse + seaiceAlbedoWtNearIRDiffuse, & ! near IR, diffuse + seaiceQsatQiceConstant, & ! constant for saturation humidity over ice + seaiceQsatTiceConstant, & ! constant for saturation humidity over ice + seaiceQsatQocnConstant, & ! constant for saturation humidity over ocean + seaiceQsatTocnConstant ! constant for saturation humidity over ocean type(domain_type), intent(inout) :: & domain + type(MPAS_pool_type), pointer :: & + snow + character(len=strKIND), pointer :: & config_thermodynamics_type, & config_heat_conductivity_type, & @@ -10046,13 +10117,17 @@ subroutine init_column_package_configs(domain) !colpkg routine - remove config_itd_conversion_type, & config_category_bounds_type, & config_pond_refreezing_type, & + config_salt_flux_coupling_type, & config_ocean_heat_transfer_type, & + config_frazil_coupling_type, & config_sea_freezing_temperature_type, & config_skeletal_bgc_flux_type, & config_snow_redistribution_scheme logical, pointer :: & + config_use_snicar_ad, & config_calc_surface_temperature, & + config_update_ocean_fluxes, & config_use_form_drag, & config_use_high_frequency_coupling, & config_use_ocean_mixed_layer, & @@ -10062,10 +10137,12 @@ subroutine init_column_package_configs(domain) !colpkg routine - remove config_use_vertical_biochemistry, & config_use_shortwave_bioabsorption, & config_use_skeletal_biochemistry, & - config_use_vertical_zsalinity, & config_use_modal_aerosols, & - config_use_snicar_ad, & - config_use_snow_liquid_ponds + config_use_macromolecules, & + config_do_restart_bgc, & + config_use_snow_liquid_ponds, & + config_use_snow_grain_radius, & + config_use_shortwave_redistribution real(kind=RKIND), pointer :: & config_min_friction_velocity, & @@ -10076,15 +10153,21 @@ subroutine init_column_package_configs(domain) !colpkg routine - remove config_rapid_mode_aspect_ratio, & config_slow_mode_drainage_strength, & config_slow_mode_critical_porosity, & + config_macro_drainage_timescale, & config_congelation_ice_porosity, & +! config_frazil_ice_porosity, & +! config_frazil_salinity_reduction, & config_visible_ice_albedo, & config_infrared_ice_albedo, & config_visible_snow_albedo, & config_infrared_snow_albedo, & config_variable_albedo_thickness_limit, & +! config_snow_surface_scattering_layer_depth, & config_ice_shortwave_tuning_parameter, & config_pond_shortwave_tuning_parameter, & config_snow_shortwave_tuning_parameter, & + config_shortwave_redistribution_fraction, & + config_shortwave_redistribution_threshold, & config_temp_change_snow_grain_radius_change, & config_max_melting_snow_grain_radius, & config_algae_absorption_coefficient, & @@ -10102,8 +10185,6 @@ subroutine init_column_package_configs(domain) !colpkg routine - remove config_biogrid_top_molecular_sublayer, & config_new_ice_fraction_biotracer, & config_fraction_biotracer_in_frazil, & - config_zsalinity_molecular_sublayer, & - config_zsalinity_gravity_drainage_scale, & config_snow_porosity_at_ice_surface, & config_ratio_Si_to_N_diatoms, & config_ratio_Si_to_N_small_plankton, & @@ -10228,13 +10309,40 @@ subroutine init_column_package_configs(domain) !colpkg routine - remove config_snow_redistribution_factor, & config_max_dry_snow_radius + real(kind=RKIND), dimension(:,:,:), pointer :: & + snowEmpiricalGrowthParameterTau, & + snowEmpiricalGrowthParameterKappa, & + snowPropertyRate + integer, pointer :: & - config_boundary_layer_iteration_number + config_boundary_layer_iteration_number, & + nGrainAgingTemperature, & + nGrainAgingTempGradient, & + nGrainAgingSnowDensity + + integer :: & + config_thermodynamics_type_int, & + config_ice_strength_formulation_int, & + config_ridging_participation_function_int, & + config_ridging_redistribution_function_int, & + config_itd_conversion_type_int, & + config_category_bounds_type_int + + character(len=strKIND) :: tmp_config_shortwave_type + character(len=strKIND) :: tmp_config_snw_ssp_table + character(len=strKIND) :: snw_aging_table = 'snicar' + + ! debugging + integer :: itmp1, itmp2 + real(kind=RKIND) :: rtmp1, rtmp2 + character(len=strKIND) :: ctmp1, ctmp2 call MPAS_pool_get_config(domain % configs, "config_thermodynamics_type", config_thermodynamics_type) call MPAS_pool_get_config(domain % configs, "config_heat_conductivity_type", config_heat_conductivity_type) call MPAS_pool_get_config(domain % configs, "config_ocean_heat_transfer_type", config_ocean_heat_transfer_type) call MPAS_pool_get_config(domain % configs, "config_calc_surface_temperature", config_calc_surface_temperature) + call MPAS_pool_get_config(domain % configs, "config_update_ocean_fluxes", config_update_ocean_fluxes) + call MPAS_pool_get_config(domain % configs, "config_frazil_coupling_type", config_frazil_coupling_type) call MPAS_pool_get_config(domain % configs, "config_min_friction_velocity", config_min_friction_velocity) call MPAS_pool_get_config(domain % configs, "config_ice_ocean_drag_coefficient", config_ice_ocean_drag_coefficient) call MPAS_pool_get_config(domain % configs, "config_snow_thermal_conductivity", config_snow_thermal_conductivity) @@ -10243,7 +10351,10 @@ subroutine init_column_package_configs(domain) !colpkg routine - remove call MPAS_pool_get_config(domain % configs, "config_rapid_mode_aspect_ratio", config_rapid_mode_aspect_ratio) call MPAS_pool_get_config(domain % configs, "config_slow_mode_drainage_strength", config_slow_mode_drainage_strength) call MPAS_pool_get_config(domain % configs, "config_slow_mode_critical_porosity", config_slow_mode_critical_porosity) + call MPAS_pool_get_config(domain % configs, "config_macro_drainage_timescale", config_macro_drainage_timescale) call MPAS_pool_get_config(domain % configs, "config_congelation_ice_porosity", config_congelation_ice_porosity) +! call MPAS_pool_get_config(domain % configs, "config_frazil_ice_porosity", config_frazil_ice_porosity) +! call MPAS_pool_get_config(domain % configs, "config_frazil_salinity_reduction", config_frazil_salinity_reduction) call MPAS_pool_get_config(domain % configs, "config_shortwave_type", config_shortwave_type) call MPAS_pool_get_config(domain % configs, "config_use_snicar_ad", config_use_snicar_ad) call MPAS_pool_get_config(domain % configs, "config_albedo_type", config_albedo_type) @@ -10252,9 +10363,13 @@ subroutine init_column_package_configs(domain) !colpkg routine - remove call MPAS_pool_get_config(domain % configs, "config_visible_snow_albedo", config_visible_snow_albedo) call MPAS_pool_get_config(domain % configs, "config_infrared_snow_albedo", config_infrared_snow_albedo) call MPAS_pool_get_config(domain % configs, "config_variable_albedo_thickness_limit", config_variable_albedo_thickness_limit) +! call MPAS_pool_get_config(domain % configs, "config_snow_surface_scattering_layer_depth", config_snow_surface_scattering_layer_depth) call MPAS_pool_get_config(domain % configs, "config_ice_shortwave_tuning_parameter", config_ice_shortwave_tuning_parameter) call MPAS_pool_get_config(domain % configs, "config_pond_shortwave_tuning_parameter", config_pond_shortwave_tuning_parameter) call MPAS_pool_get_config(domain % configs, "config_snow_shortwave_tuning_parameter", config_snow_shortwave_tuning_parameter) + call MPAS_pool_get_config(domain % configs, "config_use_shortwave_redistribution", config_use_shortwave_redistribution) + call MPAS_pool_get_config(domain % configs, "config_shortwave_redistribution_fraction", config_shortwave_redistribution_fraction) + call MPAS_pool_get_config(domain % configs, "config_shortwave_redistribution_threshold", config_shortwave_redistribution_threshold) call MPAS_pool_get_config(domain % configs, "config_temp_change_snow_grain_radius_change", & config_temp_change_snow_grain_radius_change) call MPAS_pool_get_config(domain % configs, "config_max_melting_snow_grain_radius", config_max_melting_snow_grain_radius) @@ -10275,6 +10390,7 @@ subroutine init_column_package_configs(domain) !colpkg routine - remove call MPAS_pool_get_config(domain % configs, "config_category_bounds_type", config_category_bounds_type) call MPAS_pool_get_config(domain % configs, "config_snow_to_ice_transition_depth", config_snow_to_ice_transition_depth) call MPAS_pool_get_config(domain % configs, "config_pond_refreezing_type", config_pond_refreezing_type) + call MPAS_pool_get_config(domain % configs, "config_salt_flux_coupling_type", config_salt_flux_coupling_type) call MPAS_pool_get_config(domain % configs, "config_pond_flushing_factor", config_pond_flushing_factor) call MPAS_pool_get_config(domain % configs, "config_min_meltwater_retained_fraction", config_min_meltwater_retained_fraction) call MPAS_pool_get_config(domain % configs, "config_max_meltwater_retained_fraction", config_max_meltwater_retained_fraction) @@ -10288,17 +10404,16 @@ subroutine init_column_package_configs(domain) !colpkg routine - remove call MPAS_pool_get_config(domain % configs, "config_use_vertical_biochemistry", config_use_vertical_biochemistry) call MPAS_pool_get_config(domain % configs, "config_use_shortwave_bioabsorption", config_use_shortwave_bioabsorption) call MPAS_pool_get_config(domain % configs, "config_use_modal_aerosols", config_use_modal_aerosols) + call MPAS_pool_get_config(domain % configs, "config_use_macromolecules", config_use_macromolecules) + call MPAS_pool_get_config(domain % configs, "config_do_restart_bgc", config_do_restart_bgc) call MPAS_pool_get_config(domain % configs, "config_use_skeletal_biochemistry", config_use_skeletal_biochemistry) - call MPAS_pool_get_config(domain % configs, "config_use_vertical_zsalinity", config_use_vertical_zsalinity) call MPAS_pool_get_config(domain % configs, "config_biogrid_bottom_molecular_sublayer", & config_biogrid_bottom_molecular_sublayer) call MPAS_pool_get_config(domain % configs, "config_bio_gravity_drainage_length_scale", & config_bio_gravity_drainage_length_scale) call MPAS_pool_get_config(domain % configs, "config_biogrid_top_molecular_sublayer", config_biogrid_top_molecular_sublayer) - call MPAS_pool_get_config(domain % configs, "config_zsalinity_gravity_drainage_scale", config_zsalinity_gravity_drainage_scale) call MPAS_pool_get_config(domain % configs, "config_new_ice_fraction_biotracer", config_new_ice_fraction_biotracer) call MPAS_pool_get_config(domain % configs, "config_fraction_biotracer_in_frazil", config_fraction_biotracer_in_frazil) - call MPAS_pool_get_config(domain % configs, "config_zsalinity_molecular_sublayer", config_zsalinity_molecular_sublayer) call MPAS_pool_get_config(domain % configs, "config_snow_porosity_at_ice_surface", config_snow_porosity_at_ice_surface) call MPAS_pool_get_config(domain % configs, "config_ratio_Si_to_N_diatoms", config_ratio_Si_to_N_diatoms) call MPAS_pool_get_config(domain % configs, "config_ratio_Si_to_N_small_plankton", config_ratio_Si_to_N_small_plankton) @@ -10433,1534 +10548,14 @@ subroutine init_column_package_configs(domain) !colpkg routine - remove call MPAS_pool_get_config(domain % configs, "config_wind_compaction_factor", config_wind_compaction_factor) call MPAS_pool_get_config(domain % configs, "config_snow_redistribution_factor", config_snow_redistribution_factor) call MPAS_pool_get_config(domain % configs, "config_max_dry_snow_radius", config_max_dry_snow_radius) - - call colpkg_init_parameters(& - config_cice_int("config_thermodynamics_type", config_thermodynamics_type), & - config_heat_conductivity_type, & - config_ocean_heat_transfer_type, & - config_calc_surface_temperature, & - config_min_friction_velocity, & - config_ice_ocean_drag_coefficient, & - config_snow_thermal_conductivity, & - config_rapid_mode_channel_radius, & - config_rapid_model_critical_Ra, & - config_rapid_mode_aspect_ratio, & - config_slow_mode_drainage_strength, & - config_slow_mode_critical_porosity, & - config_congelation_ice_porosity, & - config_shortwave_type, & - config_use_snicar_ad, & - config_albedo_type, & - config_visible_ice_albedo, & - config_infrared_ice_albedo, & - config_visible_snow_albedo, & - config_infrared_snow_albedo, & - config_variable_albedo_thickness_limit, & - config_ice_shortwave_tuning_parameter, & - config_pond_shortwave_tuning_parameter, & - config_snow_shortwave_tuning_parameter, & - config_temp_change_snow_grain_radius_change, & - config_max_melting_snow_grain_radius, & - config_algae_absorption_coefficient, & - config_cice_int("config_ice_strength_formulation", config_ice_strength_formulation), & - config_cice_int("config_ridging_participation_function", config_ridging_participation_function), & - config_cice_int("config_ridging_redistribution_function", config_ridging_redistribution_function), & - config_ridging_efolding_scale, & - config_ratio_ridging_work_to_PE, & - config_atmos_boundary_method, & - config_calc_surface_stresses, & - config_use_form_drag, & - config_use_high_frequency_coupling, & - config_boundary_layer_iteration_number, & - config_use_ocean_mixed_layer, & - config_sea_freezing_temperature_type, & - config_cice_int("config_itd_conversion_type", config_itd_conversion_type), & - config_cice_int("config_category_bounds_type", config_category_bounds_type), & - config_snow_to_ice_transition_depth, & - config_pond_refreezing_type, & - config_pond_flushing_factor, & - config_min_meltwater_retained_fraction, & - config_max_meltwater_retained_fraction, & - config_pond_depth_to_fraction_ratio, & - config_snow_on_pond_ice_tapering_parameter, & - config_critical_pond_ice_thickness, & - config_skeletal_bgc_flux_type, & - config_use_vertical_tracers, & - config_scale_initial_vertical_bgc, & - config_use_vertical_biochemistry, & - config_use_shortwave_bioabsorption, & - config_use_modal_aerosols, & - config_use_skeletal_biochemistry, & - config_use_vertical_zsalinity, & - config_biogrid_bottom_molecular_sublayer, & - config_bio_gravity_drainage_length_scale, & - config_biogrid_top_molecular_sublayer, & - config_new_ice_fraction_biotracer, & - config_fraction_biotracer_in_frazil, & - config_zsalinity_molecular_sublayer, & - config_zsalinity_gravity_drainage_scale, & - config_snow_porosity_at_ice_surface, & - config_ratio_Si_to_N_diatoms, & - config_ratio_Si_to_N_small_plankton, & - config_ratio_Si_to_N_phaeocystis, & - config_ratio_S_to_N_diatoms, & - config_ratio_S_to_N_small_plankton, & - config_ratio_S_to_N_phaeocystis, & - config_ratio_Fe_to_C_diatoms, & - config_ratio_Fe_to_C_small_plankton, & - config_ratio_Fe_to_C_phaeocystis, & - config_ratio_Fe_to_N_diatoms, & - config_ratio_Fe_to_N_small_plankton, & - config_ratio_Fe_to_N_phaeocystis, & - config_ratio_Fe_to_DON, & - config_ratio_Fe_to_DOC_saccharids, & - config_ratio_Fe_to_DOC_lipids, & - config_respiration_fraction_of_growth, & - config_rapid_mobile_to_stationary_time, & - config_long_mobile_to_stationary_time, & - config_algal_maximum_velocity, & - config_ratio_Fe_to_dust, & - config_solubility_of_Fe_in_dust, & - config_chla_absorptivity_of_diatoms, & - config_chla_absorptivity_of_small_plankton, & - config_chla_absorptivity_of_phaeocystis, & - config_light_attenuation_diatoms, & - config_light_attenuation_small_plankton, & - config_light_attenuation_phaeocystis, & - config_light_inhibition_diatoms, & - config_light_inhibition_small_plankton, & - config_light_inhibition_phaeocystis, & - config_maximum_growth_rate_diatoms, & - config_maximum_growth_rate_small_plankton, & - config_maximum_growth_rate_phaeocystis, & - config_temperature_growth_diatoms, & - config_temperature_growth_small_plankton, & - config_temperature_growth_phaeocystis, & - config_grazed_fraction_diatoms, & - config_grazed_fraction_small_plankton, & - config_grazed_fraction_phaeocystis, & - config_mortality_diatoms, & - config_mortality_small_plankton, & - config_mortality_phaeocystis, & - config_temperature_mortality_diatoms, & - config_temperature_mortality_small_plankton, & - config_temperature_mortality_phaeocystis, & - config_exudation_diatoms, & - config_exudation_small_plankton, & - config_exudation_phaeocystis, & - config_nitrate_saturation_diatoms, & - config_nitrate_saturation_small_plankton, & - config_nitrate_saturation_phaeocystis, & - config_ammonium_saturation_diatoms, & - config_ammonium_saturation_small_plankton, & - config_ammonium_saturation_phaeocystis, & - config_silicate_saturation_diatoms, & - config_silicate_saturation_small_plankton, & - config_silicate_saturation_phaeocystis, & - config_iron_saturation_diatoms, & - config_iron_saturation_small_plankton, & - config_iron_saturation_phaeocystis, & - config_fraction_spilled_to_DON, & - config_degredation_of_DON, & - config_fraction_DON_ammonium, & - config_fraction_loss_to_saccharids, & - config_fraction_loss_to_lipids, & - config_fraction_exudation_to_saccharids, & - config_fraction_exudation_to_lipids, & - config_remineralization_saccharids, & - config_remineralization_lipids, & - config_maximum_brine_temperature, & - config_salinity_dependence_of_growth, & - config_minimum_optical_depth, & - config_slopped_grazing_fraction, & - config_excreted_fraction, & - config_fraction_mortality_to_ammonium, & - config_fraction_iron_remineralized, & - config_nitrification_rate, & - config_desorption_loss_particulate_iron, & - config_maximum_loss_fraction, & - config_maximum_ratio_iron_to_saccharids, & - config_respiration_loss_to_DMSPd, & - config_DMSP_to_DMS_conversion_fraction, & - config_DMSP_to_DMS_conversion_time, & - config_DMS_oxidation_time, & - config_mobility_type_diatoms, & - config_mobility_type_small_plankton, & - config_mobility_type_phaeocystis, & - config_mobility_type_nitrate, & - config_mobility_type_ammonium, & - config_mobility_type_silicate, & - config_mobility_type_DMSPp, & - config_mobility_type_DMSPd, & - config_mobility_type_humics, & - config_mobility_type_saccharids, & - config_mobility_type_lipids, & - config_mobility_type_inorganic_carbon, & - config_mobility_type_proteins, & - config_mobility_type_dissolved_iron, & - config_mobility_type_particulate_iron, & - config_mobility_type_black_carbon1, & - config_mobility_type_black_carbon2, & - config_mobility_type_dust1, & - config_mobility_type_dust2, & - config_mobility_type_dust3, & - config_mobility_type_dust4, & - config_ratio_C_to_N_diatoms, & - config_ratio_C_to_N_small_plankton, & - config_ratio_C_to_N_phaeocystis, & - config_ratio_chla_to_N_diatoms, & - config_ratio_chla_to_N_small_plankton, & - config_ratio_chla_to_N_phaeocystis, & - config_scales_absorption_diatoms, & - config_scales_absorption_small_plankton, & - config_scales_absorption_phaeocystis, & - config_ratio_C_to_N_proteins, & - config_snow_redistribution_scheme, & - config_use_snow_liquid_ponds, & - config_fallen_snow_radius, & - config_max_dry_snow_radius, & - config_new_snow_density, & - config_max_snow_density, & - config_minimum_wind_compaction, & - config_wind_compaction_factor, & - config_snow_redistribution_factor) - - !----------------------------------------------------------------------- - ! Parameters for thermodynamics - !----------------------------------------------------------------------- - - ! ktherm: - ! type of thermodynamics - ! 1 = Bitz and Lipscomb 1999 - ! 2 = mushy layer theory - !ktherm = config_cice_int("config_thermodynamics_type", config_thermodynamics_type) - - ! conduct: - ! 'MU71' or 'bubbly' - !conduct = config_heat_conductivity_type - - ! calc_Tsfc: - ! if true, calculate surface temperature - ! if false, Tsfc is computed elsewhere and - ! atmos-ice fluxes are provided to CICE - !calc_Tsfc = config_calc_surface_temperature - - ! ustar_min: - ! minimum friction velocity for ice-ocean heat flux - !ustar_min = config_min_friction_velocity - - ! mushy thermodynamics: - - ! a_rapid_mode: - ! channel radius for rapid drainage mode (m) - !a_rapid_mode = config_rapid_mode_channel_radius - - ! Rac_rapid_mode: - ! critical rayleigh number for rapid drainage mode - !Rac_rapid_mode = config_rapid_model_critical_Ra - - ! aspect_rapid_mode: - ! aspect ratio for rapid drainage mode (larger=wider) - !aspect_rapid_mode = config_rapid_mode_aspect_ratio - - ! dSdt_slow_mode: - ! slow mode drainage strength (m s-1 K-1) - !dSdt_slow_mode = config_slow_mode_drainage_strength - - ! phi_c_slow_mode: - ! liquid fraction porosity cutoff for slow mode - !phi_c_slow_mode = config_slow_mode_critical_porosity - - ! phi_i_mushy: - ! liquid fraction of congelation ice - !phi_i_mushy = config_congelation_ice_porosity - - !----------------------------------------------------------------------- - ! Parameters for radiation - !----------------------------------------------------------------------- - - ! shortwave: - ! shortwave method, 'default' ('ccsm3') or 'dEdd' - !shortwave = config_shortwave_type - - ! albedo_type: - ! albedo parameterization, 'default' ('ccsm3') or 'constant' - ! shortwave='dEdd' overrides this parameter - !albedo_type = config_albedo_type - - ! baseline albedos for ccsm3 shortwave, set in namelist - - ! albicev: - ! visible ice albedo for h > ahmax - !albicev = config_visible_ice_albedo - - ! albicei: - ! near-ir ice albedo for h > ahmax - !albicei = config_infrared_ice_albedo - - ! albsnowv: - ! cold snow albedo, visible - !albsnowv = config_visible_snow_albedo - - ! albsnowi: - ! cold snow albedo, near IR - !albsnowi = config_infrared_snow_albedo - - ! ahmax: - ! thickness above which ice albedo is constant (m) - !ahmax = config_variable_albedo_thickness_limit - - ! dEdd tuning parameters, set in namelist - - ! R_ice: - ! sea ice tuning parameter; +1 > 1sig increase in albedo - !R_ice = config_ice_shortwave_tuning_parameter - - ! R_pnd: - ! ponded ice tuning parameter; +1 > 1sig increase in albedo - !R_pnd = config_pond_shortwave_tuning_parameter - - ! R_snw: - ! snow tuning parameter; +1 > ~.01 change in broadband albedo - !R_snw = config_snow_shortwave_tuning_parameter - - ! dT_mlt: - ! change in temp for non-melt to melt snow grain radius change (C) - !dT_mlt = config_temp_change_snow_grain_radius_change - - ! rsnw_mlt: - ! maximum melting snow grain radius (10^-6 m) - !rsnw_mlt = config_max_melting_snow_grain_radius - - ! kalg: - ! algae absorption coefficient for 0.5 m thick layer - !kalg = config_algae_absorption_coefficient - - !----------------------------------------------------------------------- - ! Parameters for ridging and strength - !----------------------------------------------------------------------- - - ! kstrength: - ! 0 for simple Hibler (1979) formulation - ! 1 for Rothrock (1975) pressure formulation - !kstrength = config_cice_int("config_ice_strength_formulation", config_ice_strength_formulation) - - ! krdg_partic: - ! 0 for Thorndike et al. (1975) formulation - ! 1 for exponential participation function - !krdg_partic = config_cice_int("config_ridging_participation_function", config_ridging_participation_function) - - ! krdg_redist: - ! 0 for Hibler (1980) formulation - ! 1 for exponential redistribution function - !krdg_redist = config_cice_int("config_ridging_redistribution_function", config_ridging_redistribution_function) - - ! mu_rdg: - ! gives e-folding scale of ridged ice (m^.5) - ! (krdg_redist = 1) - !mu_rdg = config_ridging_efolding_scale - - ! Cf - ! ratio of ridging work to PE change in ridging (kstrength = 1) - !Cf = config_ratio_ridging_work_to_PE - - !----------------------------------------------------------------------- - ! Parameters for atmosphere - !----------------------------------------------------------------------- - - ! atmbndy: - ! atmo boundary method, 'default' ('ccsm3') or 'constant' - !atmbndy = config_atmos_boundary_method - - ! calc_strair: - ! if true, calculate wind stress components - !calc_strair = config_calc_surface_stresses - - ! formdrag: - ! if true, calculate form drag - !formdrag = config_use_form_drag - - ! highfreq: - ! if true, use high frequency coupling - !highfreq = config_use_high_frequency_coupling - - ! natmiter: - ! number of iterations for boundary layer calculations - !natmiter = config_boundary_layer_iteration_number - - !----------------------------------------------------------------------- - ! Parameters for ocean - !----------------------------------------------------------------------- - - ! oceanmixed_ice: - ! if true, use ocean mixed layer - !oceanmixed_ice = config_use_ocean_mixed_layer - - ! fbot_xfer_type: - ! transfer coefficient type for ice-ocean heat flux - !fbot_xfer_type = config_ocean_heat_transfer_type - - ! tfrz_option: - ! form of ocean freezing temperature - ! 'minus1p8' = -1.8 C - ! 'linear_salt' = -depressT * sss - ! 'mushy' conforms with ktherm=2 - !tfrz_option = config_sea_freezing_temperature_type - - !----------------------------------------------------------------------- - ! Parameters for the ice thickness distribution - !----------------------------------------------------------------------- - - ! kitd: - ! type of itd conversions - ! 0 = delta function - ! 1 = linear remap - !kitd = config_cice_int("config_itd_conversion_type", config_itd_conversion_type) - - ! kcatbound: - ! 0 = old category boundary formula - ! 1 = new formula giving round numbers - ! 2 = WMO standard - ! 3 = asymptotic formula - !kcatbound = config_cice_int("config_category_bounds_type", config_category_bounds_type) - - !----------------------------------------------------------------------- - ! Parameters for melt ponds - !----------------------------------------------------------------------- - - ! hs0: - ! snow depth for transition to bare sea ice (m) - !hs0 = config_snow_to_ice_transition_depth - - ! level-ice ponds - - ! frzpnd: - ! pond refreezing parameterization - !frzpnd = config_pond_refreezing_type - - ! dpscale: - ! alters e-folding time scale for flushing with BL99 thermodynamics - !dpscale = config_pond_flushing_factor - - ! rfracmin: - ! minimum retained fraction of meltwater - !rfracmin = config_min_meltwater_retained_fraction - - ! rfracmax: - ! maximum retained fraction of meltwater - !rfracmax = config_max_meltwater_retained_fraction - - ! pndaspect: - ! ratio of pond depth to pond fraction - !pndaspect = config_pond_depth_to_fraction_ratio - - ! hs1: - ! tapering parameter for snow on pond ice - !hs1 = config_snow_on_pond_ice_tapering_parameter - - ! topo ponds - - ! hp1 - ! critical parameter for pond ice thickness - !hp1 = config_critical_pond_ice_thickness - - !----------------------------------------------------------------------- - ! Parameters for biogeochemistry - !----------------------------------------------------------------------- - - ! bgc_flux_type: - ! bgc_flux_type = config_skeletal_bgc_flux_type - - ! z_tracers: - ! if .true., bgc or aerosol tracers are vertically resolved - !z_tracers = config_use_vertical_tracers - - ! scale_bgc: - ! if .true., initialize bgc tracers proportionally with salinity - !scale_bgc = config_scale_initial_vertical_bgc - - ! solve_zbgc: - ! if .true., solve vertical biochemistry portion of code - !solve_zbgc = config_use_vertical_biochemistry - - ! dEdd_algae: - ! if .true., algal absorption of Shortwave is computed in the - !dEdd_algae = config_use_shortwave_bioabsorption - - ! skl_bgc: - ! if true, solve skeletal biochemistry - !skl_bgc = config_use_skeletal_biochemistry - -! zsalinity has been deprecated -! ! solve_zsal: -! ! if true, update salinity profile from solve_S_dt -! !solve_zsal = config_use_vertical_zsalinity - - ! modal_aero: - ! if true, use modal aerosal optical properties - ! only for use with tr_aero or tr_zaero - !modal_aero = config_use_shortwave_bioabsorption - - ! grid_o: - ! for bottom flux - !grid_o = config_biogrid_bottom_molecular_sublayer - - ! l_sk: - ! characteristic diffusive scale (zsalinity) (m) - !l_sk =config_bio_gravity_drainage_length_scale - - ! grid_o_t: - ! top grid point length scale - !grid_o_t = config_biogrid_top_molecular_sublayer - - ! phi_snow: - ! porosity of snow - !phi_snow = config_snow_porosity_at_ice_surface - - ! initbio_frac: - ! fraction of ocean tracer concentration used to initialize tracer - !initbio_frac = config_new_ice_fraction_biotracer - - ! frazil_scav: - ! multiple of ocean tracer concentration due to frazil scavenging - !frazil_scav = config_fraction_biotracer_in_frazil - - ! ratio_Si2N_diatoms: - ! ratio of algal Silicate to Nitrate (mol/mol) - ! ratio_Si2N_diatoms = config_ratio_Si_to_N_diatoms - - ! ratio_Si2N_sp: - ! ratio of algal Silicate to Nitrogen (mol/mol) - ! ratio_Si2N_sp = config_ratio_Si_to_N_small_plankton - - ! ratio_Si2N_phaeo: - ! ratio of algal Silicate to Nitrogen (mol/mol) - ! ratio_Si2N_phaeo = config_ratio_Si_to_N_phaeocystis - - ! ratio_S2N_diatoms: - ! ratio of algal Sulphur to Nitrogen (mol/mol) - ! ratio_S2N_diatoms = config_ratio_S_to_N_diatoms - - ! ratio_S2N_sp: - ! ratio of algal Sulphur to Nitrogen (mol/mol) - ! ratio_S2N_sp = config_ratio_S_to_N_small_plankton - - ! ratio_S2N_phaeo: - ! ratio of algal Sulphur to Nitrogen (mol/mol) - ! ratio_S2N_phaeo = config_ratio_S_to_N_phaeocystis - - ! ratio_Fe2C_diatoms: - ! ratio of algal iron to carbon (umol/mol) - ! ratio_Fe2C_diatoms = config_ratio_Fe_to_C_diatoms - - ! ratio_Fe2C_sp: - ! ratio of algal iron to carbon (umol/mol) - ! ratio_Fe2C_sp = config_ratio_Fe_to_C_small_plankton - - ! ratio_Fe2C_phaeo: - ! ratio of algal iron to carbon (umol/mol) - ! ratio_Fe2C_phaeo = config_ratio_Fe_to_C_phaeocystis - - ! ratio_Fe2N_diatoms: - ! ratio of algal iron to nitrogen (umol/mol) - ! ratio_Fe2N_diatoms = config_ratio_Fe_to_N_diatoms - - ! ratio_Fe2N_sp: - ! ratio of algal iron to nitrogen (umol/mol) - ! ratio_Fe2N_sp = config_ratio_Fe_to_N_small_plankton - - ! ratio_Fe2N_phaeo: - ! ratio of algal iron to nitrogen (umol/mol) - ! ratio_Fe2N_phaeo = config_ratio_Fe_to_N_phaeocystis - - ! ratio_Fe2DON: - ! ratio of iron to nitrogen of DON (nmol/umol) - ! ratio_Fe2DON = config_ratio_Fe_to_DON - - ! ratio_Fe2DOC_s: - ! ratio of iron to carbon of DOC (nmol/umol) saccharids - ! ratio_Fe2DOC_s = config_ratio_Fe_to_DOC_saccharids - - ! ratio_Fe2DOC_l: - ! ratio of iron to carbon of DOC (nmol/umol) lipids - ! ratio_Fe2DOC_l = config_ratio_Fe_to_DOC_lipids - - ! fr_resp: - ! fraction of algal growth lost due to respiration - ! fr_resp = config_respiration_fraction_of_growth - - ! tau_min: - ! rapid mobile to stationary exchanges (s) = 1.5 hours - ! tau_min = config_rapid_mobile_to_stationary_time - - ! tau_max: - ! long time mobile to stationary exchanges (s) = 2 days - ! tau_max = config_long_mobile_to_stationary_time - - ! algal_vel: - ! 0.5 cm/d(m/s) Lavoie 2005 1.5 cm/day - ! algal_vel = config_algal_maximum_velocity - - ! R_dFe2dust: - ! g/g (3.5% content) Tagliabue 2009 - ! R_dFe2dust = config_ratio_Fe_to_dust - - ! dustFe_sol; - ! solubility fraction - ! dustFe_sol = config_solubility_of_Fe_in_dust - - ! chlabs_diatoms: - ! chl absorption (1/m/(mg/m^3)) - ! chlabs_diatoms = config_chla_absorptivity_of_diatoms - - ! chlabs_sp: - ! chl absorption (1/m/(mg/m^3)) - ! chlabs_sp = config_chla_absorptivity_of_small_plankton - - ! chlabs_phaeo: - ! chl absorption (1/m/(mg/m^3)) - ! chlabs_phaeo = config_chla_absorptivity_of_phaeocystis - - ! alpha2max_low_diatoms: - ! light limitation diatoms (1/(W/m^2)) - ! alpha2max_low_diatoms = config_light_attenuation_diatoms - - ! alpha2max_low_sp: - ! light limitation small plankton (1/(W/m^2)) - ! alpha2max_low_sp = config_light_attenuation_small_plankton - - ! alpha2max_low_phaeo: - ! light limitation phaeocystis (1/(W/m^2)) - ! alpha2max_low_phaeo = config_light_attenuation_phaeocystis - - ! beta2max_diatoms: - ! light inhibition diatoms(1/(W/m^2)) - ! beta2max_diatoms = config_light_inhibition_diatoms - - ! beta2max_sp: - ! light inhibition small plankton(1/(W/m^2)) - ! beta2max_sp = config_light_inhibition_small_plankton - - ! beta2max_phaeo: - ! light inhibition phaeocystis (1/(W/m^2)) - ! beta2max_phaeo = config_light_inhibition_phaeocystis - - ! mu_max_diatoms: - ! maximum growth rate diatoms (1/day) - ! mu_max_diatoms = config_maximum_growth_rate_diatoms - - ! mu_max_sp: - ! maximum growth rate small plankton (1/day) - ! mu_max_sp = config_maximum_growth_rate_small plankton - - ! mu_max_phaeo: - ! maximum growth rate phaeocystis (1/day) - ! mu_max_phaeo = config_maximum_growth_rate_phaeocystis - - ! grow_Tdep_sp: - ! Temperature dependence of growth small plankton (1/C) - ! grow_Tdep_sp = config_temperature_growth_small_plankton - - ! grow_Tdep_phaeo: - ! Temperature dependence of growth phaeocystis (1/C) - ! grow_Tdep_phaeo = config_temperature_growth_phaeocystis - - ! fr_graze_diatoms: - ! Fraction grazed diatoms - ! fr_graze_diatoms = config_grazed_fraction_diatoms - - ! fr_graze_sp: - ! Fraction grazed small_plankton - ! fr_graze_sp = config_grazed_fraction_small_plankton - - ! fr_graze_phaeo: - ! Fraction grazed phaeocystis - ! fr_graze_phaeo = config_grazed_fraction_phaeocystis - - ! mort_pre_diatoms: - ! Mortality diatoms (1/day) - ! mort_pre_diatoms = config_mortality_diatoms - - ! mort_pre_sp: - ! Mortality small_plankton (1/day) - ! mort_pre_sp = config_mortality_small_plankton - - ! mort_pre_phaeo: - ! Mortality phaeocystis (1/day) - ! mort_pre_phaeo = config_mortality_phaeocystis - - ! mort_Tdep_diatoms: - ! T dependence of mortality diatoms (1/C) - ! mort_Tdep_diatoms = config_temperature_mortality_diatoms - - ! mort_Tdep_sp: - ! T dependence of mortality small plankton (1/C) - ! mort_Tdep_sp = config_temperature_mortality_small_plankton - - ! mort_Tdep_phaeo: - ! T dependence of mortality phaeocystis (1/C) - ! mort_Tdep_phaeo = config_temperature_mortality_phaeocystis - - ! k_exude_diatoms: - ! algal exudation diatoms (1/d) - ! k_exude_diatoms = config_exudation_diatoms - - ! k_exude_sp: - ! algal exudation small_plankton (1/d) - ! k_exude_sp = config_exudation_small_plankton - - ! k_exude_phaeo: - ! algal exudation phaeocystis (1/d) - ! k_exude_phaeo = config_exudation_phaeocystis - - ! K_Nit_diatoms: - ! nitrate half saturation diatoms (mmol/m^3) - ! K_Nit_diatoms = config_nitrate_saturation_diatoms - - ! K_Nit_sp: - ! nitrate half saturation small_plankton (mmol/m^3) - ! K_Nit_sp = config_nitrate_saturation_small_plankton - - ! K_Nit_phaeo: - ! nitrate half saturation phaeocystis (mmol/m^3) - ! K_Nit_phaeocystis = config_nitrate_saturation_phaeocystis - - ! K_Am_diatoms: - ! ammonium half saturation diatoms (mmol/m^3) - ! K_Am_diatoms = config_ammonium_saturation_diatoms - - ! K_Am_sp: - ! ammonium half saturation small_plankton (mmol/m^3) - ! K_Am_sp = config_ammonium_saturation_small_plankton - - ! K_Am_phaeo: - ! ammonium half saturation phaeocystis (mmol/m^3) - ! K_Am_phaeocystis = config_ammonium_saturation_phaeocystis - - ! K_Sil_diatoms: - ! silicate half saturation diatoms (mmol/m^3) - ! K_Sil_diatoms = config_silicate_saturation_diatoms - - ! K_Sil_sp: - ! silicate half saturation small_plankton (mmol/m^3) - ! K_Sil_sp = config_silicate_saturation_small_plankton - - ! K_Sil_phaeo: - ! silicate half saturation phaeocystis (mmol/m^3) - ! K_Sil_phaeocystis = config_silicate_saturation_phaeocystis - - ! K_Fe_diatoms: - ! iron half saturation diatoms (nM) - ! K_Fe_diatoms = config_iron_saturation_diatoms - - ! K_Fe_sp: - ! iron half saturation small_plankton (nM) - ! K_Fe_sp = config_iron_saturation_small_plankton - - ! K_Fe_phaeo: - ! iron half saturation phaeocystis (nM) - ! K_Fe_phaeocystis = config_iron_saturation_phaeocystis - - ! f_don_protein: - ! fraction of spilled grazing to proteins ! - ! f_don_protein = config_fraction_spilled_to_DON - - ! kn_bac_protein: - ! Bacterial degredation of DON (1/d) ! ! - ! kn_bac_protein = config_degredation_of_DON - - ! f_don_Am_protein: - ! fraction of remineralized DON to ammonium ! - ! f_don_Am_protein = config_fraction_DON_ammonium - - ! f_doc_s: - ! fraction of mortality to DOC saccharids - ! f_doc_s = config_fraction_loss_to_saccharids - - ! f_doc_l: - ! fraction of mortality to DOC lipids - ! f_doc_l = config_fraction_loss_to_lipids - - ! f_exude_s: - ! fraction of exudation to DOC saccharids - ! f_exude_s = config_fraction_exudation_to_saccharids - - ! f_exude_l: - ! fraction of exudation to DOC lipids - ! f_exude_l = config_fraction_exudation_to_lipids - - ! k_bac_s: - ! Bacterial degredation of DOC (1/d) saccharids - ! k_bac_s = config_remineralization_saccharids - - ! k_bac_l: - ! Bacterial degredation of DOC (1/d) lipids - ! k_bac_l = config_remineralization_lipids - - ! T_max: - ! maximum temperature (C) - ! T_max = config_maximum_brine_temperature - - ! fsal: - ! Salinity limitation (ppt) - ! fsal = config_salinity_dependence_of_growth - - ! op_dep_min: - ! Light attenuates for optical depths exceeding min - ! op_dep_min = config_minimum_optical_depth - - ! fr_graze_s: - ! fraction of grazing spilled or slopped - ! fr_graze_s = config_slopped_grazing_fraction - - ! fr_graze_e: - ! fraction of assimilation excreted - ! fr_graze_e = config_excreted_fraction - - ! fr_mort2min: - ! fractionation of mortality to Am - ! fr_mort2min = config_fraction_mortality_to_ammonium - - ! fr_dFe: - ! remineralized nitrogen (in units of algal iron) - ! fr_dFe = config_fraction_iron_remineralized - - ! k_nitrif: - ! nitrification rate (1/day) - ! k_nitrif = config_nitrification_rate - - ! t_iron_conv: - ! desorption loss pFe to dFe (day) - ! t_iron_conv = config_desorption_loss_particulate_iron - - ! max_loss: - ! restrict uptake to % of remaining value - ! max_loss = config_maximum_loss_fraction - - ! max_dfe_doc1: - ! max ratio of dFe to saccharides in the ice (nM Fe/muM C) - ! max_dfe_doc1 = config_maximum_ratio_iron_to_saccharids - - ! fr_resp_s: - ! DMSPd fraction of respiration loss as DMSPd - ! fr_resp_s = config_respiration_loss_to_DMSPd - - ! y_sk_DMS: - ! fraction conversion given high yield - ! y_sk_DMS = config_DMSP_to_DMS_conversion_fraction - - ! t_sk_conv: - ! Stefels conversion time (d) - ! t_sk_conv = config_DMSP_to_DMS_conversion_time - - ! t_sk_ox: - ! DMS oxidation time (d) - ! t_sk_ox = config_DMS_oxidation_time - - ! algaltype_diatoms: - ! mobility type diatoms - ! algaltype_diatoms = config_mobility_type_diatoms - - ! algaltype_sp: - ! mobility type small_plankton - ! algaltype_sp = config_mobility_type_small_plankton - - ! algaltype_phaeo: - ! mobility type phaeocystis - ! algaltype_phaeo = config_mobility_type_phaeocystis - - ! nitratetype: - ! mobility type nitrate - ! nitratetype = config_mobility_type_nitrate - - ! ammoniumtype: - ! mobility type ammonium - ! ammoniumtype = config_mobility_type_ammonium - - ! silicatetype: - ! mobility type silicate - ! silicatetype = config_mobility_type_silicate - - ! dmspptype: - ! mobility type DMSPp - ! dmspptype = config_mobility_type_DMSPp - - ! dmspdtype: - ! mobility type DMSPd - ! dmspdtype = config_mobility_type_DMSPd - - ! humicstype: - ! mobility type humics - ! humicstype = config_mobility_type_humics - - ! doctype_s: - ! mobility type sachharids - ! doctype_s = config_mobility_type_saccharids - - ! doctype_l: - ! mobility type lipids - ! doctype_l = config_mobility_type_lipids - - ! dictype_1: - ! mobility type dissolved inorganic carbon - ! dictype_1 = config_mobility_type_inorganic_carbon - - ! dontype_protein: - ! mobility type proteins - ! dontype_protein = config_mobility_type_proteins - - ! fedtype_1: - ! mobility type dissolved iron - ! fedtype_1 = config_mobility_type_dissolved_iron - - ! feptype_1: - ! mobility type particulate iron - ! feptype_1 = config_mobility_type_particulate_iron - - ! zaerotype_bc1: - ! mobility type for black carbon 1 - ! zaerotype_bc1 = config_mobility_type_black_carbon1 - - ! zaerotype_bc2: - ! mobility type for black carbon 2 - ! zaerotype_bc2 = config_mobility_type_black_carbon2 - - ! zaerotype_dust1: - ! mobility type for dust 1 - ! zaerotype_dust1 = config_mobility_type_dust1 - - ! zaerotype_dust2: - ! mobility type for dust 2 - ! zaerotype_dust2 = config_mobility_type_dust2 - - ! zaerotype_dust3: - ! mobility type for dust 3 - ! zaerotype_dust3 = config_mobility_type_dust3 - - ! zaerotype_dust4: - ! mobility type for dust 4 - ! zaerotype_dust4 = config_mobility_type_dust4 - - ! ratio_C2N_diatoms: - ! algal C to N ratio (mol/mol) diatoms - ! ratio_C2N_diatoms = config_ratio_C_to_N_diatoms - - ! ratio_C2N_sp: - ! algal C to N ratio (mol/mol) small_plankton - ! ratio_C2N_sp = config_ratio_C_to_N_small_plankton - - ! ratio_C2N_phaeo: - ! algal C to N ratio (mol/mol) phaeocystis - ! ratio_C2N_phaeo = config_ratio_C_to_N_phaeocystis - - ! ratio_chl2N_diatoms: - ! algal chla to N ratio (mol/mol) diatoms - ! ratio_chl2N_diatoms = config_ratio_chla_to_N_diatoms - - ! ratio_chl2N_sp: - ! algal chla to N ratio (mol/mol) small_plankton - ! ratio_chl2N_sp = config_ratio_chla_to_N_small_plankton - - ! ratio_chl2N_phaeo: - ! algal chla to N ratio (mol/mol) phaeocystis - ! ratio_chl2N_phaeo = config_ratio_chla_to_N_phaeocystis - - ! F_abs_chl_diatoms: - ! scales absorbed radiation for dEdd diatoms - ! F_abs_chl_diatoms = config_scales_absorption_diatoms - - ! F_abs_chl_sp: - ! scales absorbed radiation for dEdd small_plankton - ! F_abs_chl_sp = config_scales_absorption_small_plankton - - ! F_abs_chl_phaeo: - ! scales absorbed radiation for dEdd phaeocystis - ! F_abs_chl_phaeo = config_scales_absorption_phaeocystis - - ! ratio_C2N_proteins: - ! ratio of C to N in proteins (mol/mol) - ! ratio_C2N_proteins = config_ratio_C_to_N_proteins - -! ! grid_oS: -! ! for bottom flux (zsalinity) -! !grid_oS = config_zsalinity_molecular_sublayer - - ! l_skS: -! ! 0.02 characteristic skeletal layer thickness (m) (zsalinity) -! !l_skS = config_zsalinity_gravity_drainage_scale - - !----------------------------------------------------------------------- - ! Parameters for snow - !----------------------------------------------------------------------- - - ! snwredist: - ! snow redistribution type - ! snwredist = config_snow_redistribution_scheme - - ! use_smliq_pnd: - ! convert excess snow liquid to ponds - ! use_smliq_pnd = config_use_snow_liquid_ponds - - ! rsnw_fall: - ! fallen snow grain radius (um) - ! rsnw_fall = config_fallen_snow_radius - - ! rsnw_tmax: - ! maximum dry metamorphism snow grain radius (um) - ! rsnw_tmax = config_max_dry_snow_radius - - ! rhosnew: - ! new snow density (kg/m^3) - ! rhosnew = config_new_snow_density - - ! rhosmax: - ! maximum snow density (kg/m^3) - ! rhosmax = config_max_snow_density - - ! windmin: - ! minimum wind speed to compact snow (m/s) - ! windmin = config_minimum_wind_compaction - - ! snwlvlfac: - ! snow loss factor for wind redistribution - ! snwlvlfac = config_snow_redistribution_factor - - ! drhosdwind: - ! wind compaction factor (kg s/m^4) - ! drhosdwind = config_wind_compaction_factor - - end subroutine init_column_package_configs - -!||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||| -! -! init_icepack_package_configs -! -!> \brief -!> \author Adrian K. Turner, Elizabeth Hunke, Darin Comeau, Nicole Jeffery, Andrew Roberts, Erin Thomas, Jon Wolfe, LANL, Anthony Craig, NOAA (cntr), David Bailey, NCAR -!> \date 2022-2023 -!> \details -!> -! -!----------------------------------------------------------------------- - - subroutine init_icepack_package_configs(domain) - - use icepack_intfc, only: & - icepack_init_parameters, & - icepack_write_parameters, & - icepack_configure, & - icepack_query_parameters ! debugging - - use seaice_constants, only: & - seaicePuny, & ! a small number - seaiceBigNumber, & ! a large number - seaiceSecondsPerDay, & ! number of seconds in 1 day - seaiceDensityIce, & ! density of ice (kg/m^3) - seaiceDensitySnow, & ! density of snow (kg/m^3) - seaiceDensitySeaWater, & ! density of seawater (kg/m^3) - seaiceDensityFreshwater, & ! density of freshwater (kg/m^3) - seaiceFreshIceSpecificHeat, & ! specific heat of fresh ice (J/kg/K) - seaiceWaterVaporSpecificHeat, & ! specific heat of water vapor (J/kg/K) - seaiceAirSpecificHeat, & ! specific heat of air (J/kg/K) - seaiceSeaWaterSpecificHeat, & ! specific heat of ocn (J/kg/K) - seaiceLatentHeatVaporization, & ! latent heat, vaporization freshwater (J/kg) - seaiceZvir, & ! rh2o/rair - 1.0 - seaiceLatentHeatSublimation, & ! latent heat, sublimation freshwater (J/kg) - seaiceLatentHeatMelting, & ! latent heat of melting of fresh ice (J/kg) - seaiceIceSurfaceMeltingTemperature, & ! melting temp. ice top surface (C) - seaiceSnowSurfaceMeltingTemperature, & ! melting temp. snow top surface (C) - seaiceStefanBoltzmann, & ! J m-2 K-4 s-1 - seaiceIceSnowEmissivity, & ! emissivity of snow and ice - seaiceSnowSurfaceScatteringLayer, & ! snow surface scattering layer thickness (m) - seaiceStabilityReferenceHeight, & ! stability reference height (m) - seaiceFreshWaterFreezingPoint, & ! freezing temp of fresh ice (K) - seaiceIceSurfaceRoughness, & ! ice surface roughness (m) - seaiceVonKarmanConstant, & ! Von Karman constant - seaiceOceanAlbedo, & ! Ocean albedo - seaiceReferenceSalinity, & ! ice reference salinity (ppt) - seaiceMaximumSalinity, & ! ice maximum salinity (ppt) - seaiceMeltingTemperatureDepression, & ! melting temperature depression factor (C/ppt) - seaiceFrazilSalinityReduction, & ! bulk salinity reduction of newly formed frazil (ppt) - seaiceFrazilIcePorosity, & ! initial liquid fraction of frazil - seaicePi, & ! pi - seaiceGravity, & ! gravitational acceleration (m/s^2) - seaiceSnowPatchiness, & ! snow patchiness parameter - seaiceIceStrengthConstantHiblerP, & ! P* constant in Hibler strength formulation - seaiceIceStrengthConstantHiblerC, & ! C* constant in Hibler strength formulation - skeletalLayerThickness, & ! skeletal layer thickness - seaiceSnowMinimumDensity, & ! minimum snow density (kg/m^3) - seaiceBrineDynamicViscosity, & ! dynamic viscosity of brine (kg/m/s) - seaiceFreezingTemperatureConstant, &! constant freezing temp of seawater (C) - seaiceExtinctionCoef, & ! vis extnctn coef in ice, wvlngth<700nm (1/m) - seaiceFreshIceConductivity, & ! thermal conductivity of fresh ice(W/m/deg) - seaiceSnowMinimumThickness, & ! min snow thickness for computing zTsn (m) - seaiceFrazilMinimumThickness, & ! min thickness of new frazil ice - seaiceAlbedoWtVisibleDirect, & ! visible, direct - seaiceAlbedoWtNearIRDirect, & ! near IR, direct - seaiceAlbedoWtVisibleDiffuse, & ! visible, diffuse - seaiceAlbedoWtNearIRDiffuse, & ! near IR, diffuse - seaiceQsatQiceConstant, & ! constant for saturation humidity over ice - seaiceQsatTiceConstant, & ! constant for saturation humidity over ice - seaiceQsatQocnConstant, & ! constant for saturation humidity over ocean - seaiceQsatTocnConstant ! constant for saturation humidity over ocean - - type(domain_type), intent(inout) :: & - domain - - type(MPAS_pool_type), pointer :: & - snow - - character(len=strKIND), pointer :: & - config_thermodynamics_type, & - config_heat_conductivity_type, & - config_shortwave_type, & - config_albedo_type, & - config_ice_strength_formulation, & - config_ridging_participation_function, & - config_ridging_redistribution_function, & - config_atmos_boundary_method, & - config_itd_conversion_type, & - config_category_bounds_type, & - config_pond_refreezing_type, & - config_salt_flux_coupling_type, & - config_ocean_heat_transfer_type, & - config_frazil_coupling_type, & - config_sea_freezing_temperature_type, & - config_skeletal_bgc_flux_type, & - config_snow_redistribution_scheme - - logical, pointer :: & - config_use_snicar_ad, & - config_calc_surface_temperature, & - config_update_ocean_fluxes, & - config_use_form_drag, & - config_use_high_frequency_coupling, & - config_use_ocean_mixed_layer, & - config_calc_surface_stresses, & - config_use_vertical_tracers, & - config_scale_initial_vertical_bgc, & - config_use_vertical_biochemistry, & - config_use_shortwave_bioabsorption, & - config_use_skeletal_biochemistry, & - config_use_modal_aerosols, & - config_use_macromolecules, & - config_do_restart_bgc, & - config_use_snow_liquid_ponds, & - config_use_snow_grain_radius, & - config_use_shortwave_redistribution - - real(kind=RKIND), pointer :: & - config_min_friction_velocity, & - config_ice_ocean_drag_coefficient, & - config_snow_thermal_conductivity, & - config_rapid_mode_channel_radius, & - config_rapid_model_critical_Ra, & - config_rapid_mode_aspect_ratio, & - config_slow_mode_drainage_strength, & - config_slow_mode_critical_porosity, & - config_macro_drainage_timescale, & - config_congelation_ice_porosity, & -! config_frazil_ice_porosity, & -! config_frazil_salinity_reduction, & - config_visible_ice_albedo, & - config_infrared_ice_albedo, & - config_visible_snow_albedo, & - config_infrared_snow_albedo, & - config_variable_albedo_thickness_limit, & -! config_snow_surface_scattering_layer_depth, & - config_ice_shortwave_tuning_parameter, & - config_pond_shortwave_tuning_parameter, & - config_snow_shortwave_tuning_parameter, & - config_shortwave_redistribution_fraction, & - config_shortwave_redistribution_threshold, & - config_temp_change_snow_grain_radius_change, & - config_max_melting_snow_grain_radius, & - config_algae_absorption_coefficient, & - config_ridging_efolding_scale, & - config_ratio_ridging_work_to_PE, & - config_snow_to_ice_transition_depth, & - config_pond_flushing_factor, & - config_min_meltwater_retained_fraction, & - config_max_meltwater_retained_fraction, & - config_pond_depth_to_fraction_ratio, & - config_snow_on_pond_ice_tapering_parameter, & - config_critical_pond_ice_thickness, & - config_biogrid_bottom_molecular_sublayer, & - config_bio_gravity_drainage_length_scale, & - config_biogrid_top_molecular_sublayer, & - config_new_ice_fraction_biotracer, & - config_fraction_biotracer_in_frazil, & - config_snow_porosity_at_ice_surface, & - config_ratio_Si_to_N_diatoms, & - config_ratio_Si_to_N_small_plankton, & - config_ratio_Si_to_N_phaeocystis, & - config_ratio_S_to_N_diatoms, & - config_ratio_S_to_N_small_plankton, & - config_ratio_S_to_N_phaeocystis, & - config_ratio_Fe_to_C_diatoms, & - config_ratio_Fe_to_C_small_plankton, & - config_ratio_Fe_to_C_phaeocystis, & - config_ratio_Fe_to_N_diatoms, & - config_ratio_Fe_to_N_small_plankton, & - config_ratio_Fe_to_N_phaeocystis, & - config_ratio_Fe_to_DON, & - config_ratio_Fe_to_DOC_saccharids, & - config_ratio_Fe_to_DOC_lipids, & - config_respiration_fraction_of_growth, & - config_rapid_mobile_to_stationary_time, & - config_long_mobile_to_stationary_time, & - config_algal_maximum_velocity, & - config_ratio_Fe_to_dust, & - config_solubility_of_Fe_in_dust, & - config_chla_absorptivity_of_diatoms, & - config_chla_absorptivity_of_small_plankton, & - config_chla_absorptivity_of_phaeocystis, & - config_light_attenuation_diatoms, & - config_light_attenuation_small_plankton, & - config_light_attenuation_phaeocystis, & - config_light_inhibition_diatoms, & - config_light_inhibition_small_plankton, & - config_light_inhibition_phaeocystis, & - config_maximum_growth_rate_diatoms, & - config_maximum_growth_rate_small_plankton, & - config_maximum_growth_rate_phaeocystis, & - config_temperature_growth_diatoms, & - config_temperature_growth_small_plankton, & - config_temperature_growth_phaeocystis, & - config_grazed_fraction_diatoms, & - config_grazed_fraction_small_plankton, & - config_grazed_fraction_phaeocystis, & - config_mortality_diatoms, & - config_mortality_small_plankton, & - config_mortality_phaeocystis, & - config_temperature_mortality_diatoms, & - config_temperature_mortality_small_plankton, & - config_temperature_mortality_phaeocystis, & - config_exudation_diatoms, & - config_exudation_small_plankton, & - config_exudation_phaeocystis, & - config_nitrate_saturation_diatoms, & - config_nitrate_saturation_small_plankton, & - config_nitrate_saturation_phaeocystis, & - config_ammonium_saturation_diatoms, & - config_ammonium_saturation_small_plankton, & - config_ammonium_saturation_phaeocystis, & - config_silicate_saturation_diatoms, & - config_silicate_saturation_small_plankton, & - config_silicate_saturation_phaeocystis, & - config_iron_saturation_diatoms, & - config_iron_saturation_small_plankton, & - config_iron_saturation_phaeocystis, & - config_fraction_spilled_to_DON, & - config_degredation_of_DON, & - config_fraction_DON_ammonium, & - config_fraction_loss_to_saccharids, & - config_fraction_loss_to_lipids, & - config_fraction_exudation_to_saccharids, & - config_fraction_exudation_to_lipids, & - config_remineralization_saccharids, & - config_remineralization_lipids, & - config_maximum_brine_temperature, & - config_salinity_dependence_of_growth, & - config_minimum_optical_depth, & - config_slopped_grazing_fraction, & - config_excreted_fraction, & - config_fraction_mortality_to_ammonium, & - config_fraction_iron_remineralized, & - config_nitrification_rate, & - config_desorption_loss_particulate_iron, & - config_maximum_loss_fraction, & - config_maximum_ratio_iron_to_saccharids, & - config_respiration_loss_to_DMSPd, & - config_DMSP_to_DMS_conversion_fraction, & - config_DMSP_to_DMS_conversion_time, & - config_DMS_oxidation_time, & - config_mobility_type_diatoms, & - config_mobility_type_small_plankton, & - config_mobility_type_phaeocystis, & - config_mobility_type_nitrate, & - config_mobility_type_ammonium, & - config_mobility_type_silicate, & - config_mobility_type_DMSPp, & - config_mobility_type_DMSPd, & - config_mobility_type_humics, & - config_mobility_type_saccharids, & - config_mobility_type_lipids, & - config_mobility_type_inorganic_carbon, & - config_mobility_type_proteins, & - config_mobility_type_dissolved_iron, & - config_mobility_type_particulate_iron, & - config_mobility_type_black_carbon1, & - config_mobility_type_black_carbon2, & - config_mobility_type_dust1, & - config_mobility_type_dust2, & - config_mobility_type_dust3, & - config_mobility_type_dust4, & - config_ratio_C_to_N_diatoms, & - config_ratio_C_to_N_small_plankton, & - config_ratio_C_to_N_phaeocystis, & - config_ratio_chla_to_N_diatoms, & - config_ratio_chla_to_N_small_plankton, & - config_ratio_chla_to_N_phaeocystis, & - config_scales_absorption_diatoms, & - config_scales_absorption_small_plankton, & - config_scales_absorption_phaeocystis, & - config_ratio_C_to_N_proteins, & - config_fallen_snow_radius, & - config_new_snow_density, & - config_max_snow_density, & - config_minimum_wind_compaction, & - config_wind_compaction_factor, & - config_snow_redistribution_factor, & - config_max_dry_snow_radius - - real(kind=RKIND), dimension(:,:,:), pointer :: & - snowEmpiricalGrowthParameterTau, & - snowEmpiricalGrowthParameterKappa, & - snowPropertyRate - - integer, pointer :: & - config_boundary_layer_iteration_number, & - nGrainAgingTemperature, & - nGrainAgingTempGradient, & - nGrainAgingSnowDensity - - integer :: & - config_thermodynamics_type_int, & - config_ice_strength_formulation_int, & - config_ridging_participation_function_int, & - config_ridging_redistribution_function_int, & - config_itd_conversion_type_int, & - config_category_bounds_type_int - - character(len=strKIND) :: tmp_config_shortwave_type - character(len=strKIND) :: tmp_config_snw_ssp_table - character(len=strKIND) :: snw_aging_table = 'snicar' - - ! debugging - integer :: itmp1, itmp2 - real(kind=RKIND) :: rtmp1, rtmp2 - character(len=strKIND) :: ctmp1, ctmp2 - - call MPAS_pool_get_config(domain % configs, "config_thermodynamics_type", config_thermodynamics_type) - call MPAS_pool_get_config(domain % configs, "config_heat_conductivity_type", config_heat_conductivity_type) - call MPAS_pool_get_config(domain % configs, "config_ocean_heat_transfer_type", config_ocean_heat_transfer_type) - call MPAS_pool_get_config(domain % configs, "config_calc_surface_temperature", config_calc_surface_temperature) - call MPAS_pool_get_config(domain % configs, "config_update_ocean_fluxes", config_update_ocean_fluxes) - call MPAS_pool_get_config(domain % configs, "config_frazil_coupling_type", config_frazil_coupling_type) - call MPAS_pool_get_config(domain % configs, "config_min_friction_velocity", config_min_friction_velocity) - call MPAS_pool_get_config(domain % configs, "config_ice_ocean_drag_coefficient", config_ice_ocean_drag_coefficient) - call MPAS_pool_get_config(domain % configs, "config_snow_thermal_conductivity", config_snow_thermal_conductivity) - call MPAS_pool_get_config(domain % configs, "config_rapid_mode_channel_radius", config_rapid_mode_channel_radius) - call MPAS_pool_get_config(domain % configs, "config_rapid_model_critical_Ra", config_rapid_model_critical_Ra) - call MPAS_pool_get_config(domain % configs, "config_rapid_mode_aspect_ratio", config_rapid_mode_aspect_ratio) - call MPAS_pool_get_config(domain % configs, "config_slow_mode_drainage_strength", config_slow_mode_drainage_strength) - call MPAS_pool_get_config(domain % configs, "config_slow_mode_critical_porosity", config_slow_mode_critical_porosity) - call MPAS_pool_get_config(domain % configs, "config_macro_drainage_timescale", config_macro_drainage_timescale) - call MPAS_pool_get_config(domain % configs, "config_congelation_ice_porosity", config_congelation_ice_porosity) -! call MPAS_pool_get_config(domain % configs, "config_frazil_ice_porosity", config_frazil_ice_porosity) -! call MPAS_pool_get_config(domain % configs, "config_frazil_salinity_reduction", config_frazil_salinity_reduction) - call MPAS_pool_get_config(domain % configs, "config_shortwave_type", config_shortwave_type) - call MPAS_pool_get_config(domain % configs, "config_use_snicar_ad", config_use_snicar_ad) - call MPAS_pool_get_config(domain % configs, "config_albedo_type", config_albedo_type) - call MPAS_pool_get_config(domain % configs, "config_visible_ice_albedo", config_visible_ice_albedo) - call MPAS_pool_get_config(domain % configs, "config_infrared_ice_albedo", config_infrared_ice_albedo) - call MPAS_pool_get_config(domain % configs, "config_visible_snow_albedo", config_visible_snow_albedo) - call MPAS_pool_get_config(domain % configs, "config_infrared_snow_albedo", config_infrared_snow_albedo) - call MPAS_pool_get_config(domain % configs, "config_variable_albedo_thickness_limit", config_variable_albedo_thickness_limit) -! call MPAS_pool_get_config(domain % configs, "config_snow_surface_scattering_layer_depth", config_snow_surface_scattering_layer_depth) - call MPAS_pool_get_config(domain % configs, "config_ice_shortwave_tuning_parameter", config_ice_shortwave_tuning_parameter) - call MPAS_pool_get_config(domain % configs, "config_pond_shortwave_tuning_parameter", config_pond_shortwave_tuning_parameter) - call MPAS_pool_get_config(domain % configs, "config_snow_shortwave_tuning_parameter", config_snow_shortwave_tuning_parameter) - call MPAS_pool_get_config(domain % configs, "config_use_shortwave_redistribution", config_use_shortwave_redistribution) - call MPAS_pool_get_config(domain % configs, "config_shortwave_redistribution_fraction", config_shortwave_redistribution_fraction) - call MPAS_pool_get_config(domain % configs, "config_shortwave_redistribution_threshold", config_shortwave_redistribution_threshold) - call MPAS_pool_get_config(domain % configs, "config_temp_change_snow_grain_radius_change", & - config_temp_change_snow_grain_radius_change) - call MPAS_pool_get_config(domain % configs, "config_max_melting_snow_grain_radius", config_max_melting_snow_grain_radius) - call MPAS_pool_get_config(domain % configs, "config_algae_absorption_coefficient", config_algae_absorption_coefficient) - call MPAS_pool_get_config(domain % configs, "config_ice_strength_formulation", config_ice_strength_formulation) - call MPAS_pool_get_config(domain % configs, "config_ridging_participation_function", config_ridging_participation_function) - call MPAS_pool_get_config(domain % configs, "config_ridging_redistribution_function", config_ridging_redistribution_function) - call MPAS_pool_get_config(domain % configs, "config_ridging_efolding_scale", config_ridging_efolding_scale) - call MPAS_pool_get_config(domain % configs, "config_ratio_ridging_work_to_PE", config_ratio_ridging_work_to_PE) - call MPAS_pool_get_config(domain % configs, "config_atmos_boundary_method", config_atmos_boundary_method) - call MPAS_pool_get_config(domain % configs, "config_calc_surface_stresses", config_calc_surface_stresses) - call MPAS_pool_get_config(domain % configs, "config_use_form_drag", config_use_form_drag) - call MPAS_pool_get_config(domain % configs, "config_use_high_frequency_coupling", config_use_high_frequency_coupling) - call MPAS_pool_get_config(domain % configs, "config_boundary_layer_iteration_number", config_boundary_layer_iteration_number) - call MPAS_pool_get_config(domain % configs, "config_use_ocean_mixed_layer", config_use_ocean_mixed_layer) - call MPAS_pool_get_config(domain % configs, "config_sea_freezing_temperature_type", config_sea_freezing_temperature_type) - call MPAS_pool_get_config(domain % configs, "config_itd_conversion_type", config_itd_conversion_type) - call MPAS_pool_get_config(domain % configs, "config_category_bounds_type", config_category_bounds_type) - call MPAS_pool_get_config(domain % configs, "config_snow_to_ice_transition_depth", config_snow_to_ice_transition_depth) - call MPAS_pool_get_config(domain % configs, "config_pond_refreezing_type", config_pond_refreezing_type) - call MPAS_pool_get_config(domain % configs, "config_salt_flux_coupling_type", config_salt_flux_coupling_type) - call MPAS_pool_get_config(domain % configs, "config_pond_flushing_factor", config_pond_flushing_factor) - call MPAS_pool_get_config(domain % configs, "config_min_meltwater_retained_fraction", config_min_meltwater_retained_fraction) - call MPAS_pool_get_config(domain % configs, "config_max_meltwater_retained_fraction", config_max_meltwater_retained_fraction) - call MPAS_pool_get_config(domain % configs, "config_pond_depth_to_fraction_ratio", config_pond_depth_to_fraction_ratio) - call MPAS_pool_get_config(domain % configs, "config_snow_on_pond_ice_tapering_parameter", & - config_snow_on_pond_ice_tapering_parameter) - call MPAS_pool_get_config(domain % configs, "config_critical_pond_ice_thickness", config_critical_pond_ice_thickness) - call MPAS_pool_get_config(domain % configs, "config_skeletal_bgc_flux_type", config_skeletal_bgc_flux_type) - call MPAS_pool_get_config(domain % configs, "config_use_vertical_tracers", config_use_vertical_tracers) - call MPAS_pool_get_config(domain % configs, "config_scale_initial_vertical_bgc", config_scale_initial_vertical_bgc) - call MPAS_pool_get_config(domain % configs, "config_use_vertical_biochemistry", config_use_vertical_biochemistry) - call MPAS_pool_get_config(domain % configs, "config_use_shortwave_bioabsorption", config_use_shortwave_bioabsorption) - call MPAS_pool_get_config(domain % configs, "config_use_modal_aerosols", config_use_modal_aerosols) - call MPAS_pool_get_config(domain % configs, "config_use_macromolecules", config_use_macromolecules) - call MPAS_pool_get_config(domain % configs, "config_do_restart_bgc", config_do_restart_bgc) - call MPAS_pool_get_config(domain % configs, "config_use_skeletal_biochemistry", config_use_skeletal_biochemistry) - call MPAS_pool_get_config(domain % configs, "config_biogrid_bottom_molecular_sublayer", & - config_biogrid_bottom_molecular_sublayer) - call MPAS_pool_get_config(domain % configs, "config_bio_gravity_drainage_length_scale", & - config_bio_gravity_drainage_length_scale) - call MPAS_pool_get_config(domain % configs, "config_biogrid_top_molecular_sublayer", config_biogrid_top_molecular_sublayer) - call MPAS_pool_get_config(domain % configs, "config_new_ice_fraction_biotracer", config_new_ice_fraction_biotracer) - call MPAS_pool_get_config(domain % configs, "config_fraction_biotracer_in_frazil", config_fraction_biotracer_in_frazil) - call MPAS_pool_get_config(domain % configs, "config_snow_porosity_at_ice_surface", config_snow_porosity_at_ice_surface) - call MPAS_pool_get_config(domain % configs, "config_ratio_Si_to_N_diatoms", config_ratio_Si_to_N_diatoms) - call MPAS_pool_get_config(domain % configs, "config_ratio_Si_to_N_small_plankton", config_ratio_Si_to_N_small_plankton) - call MPAS_pool_get_config(domain % configs, "config_ratio_Si_to_N_phaeocystis", config_ratio_Si_to_N_phaeocystis) - call MPAS_pool_get_config(domain % configs, "config_ratio_S_to_N_diatoms", config_ratio_S_to_N_diatoms) - call MPAS_pool_get_config(domain % configs, "config_ratio_S_to_N_small_plankton", config_ratio_S_to_N_small_plankton) - call MPAS_pool_get_config(domain % configs, "config_ratio_S_to_N_phaeocystis", config_ratio_S_to_N_phaeocystis) - call MPAS_pool_get_config(domain % configs, "config_ratio_Fe_to_C_diatoms", config_ratio_Fe_to_C_diatoms) - call MPAS_pool_get_config(domain % configs, "config_ratio_Fe_to_C_small_plankton", config_ratio_Fe_to_C_small_plankton) - call MPAS_pool_get_config(domain % configs, "config_ratio_Fe_to_C_phaeocystis", config_ratio_Fe_to_C_phaeocystis) - call MPAS_pool_get_config(domain % configs, "config_ratio_Fe_to_N_diatoms", config_ratio_Fe_to_N_diatoms) - call MPAS_pool_get_config(domain % configs, "config_ratio_Fe_to_N_small_plankton", config_ratio_Fe_to_N_small_plankton) - call MPAS_pool_get_config(domain % configs, "config_ratio_Fe_to_N_phaeocystis", config_ratio_Fe_to_N_phaeocystis) - call MPAS_pool_get_config(domain % configs, "config_ratio_Fe_to_DON", config_ratio_Fe_to_DON) - call MPAS_pool_get_config(domain % configs, "config_ratio_Fe_to_DOC_saccharids", config_ratio_Fe_to_DOC_saccharids) - call MPAS_pool_get_config(domain % configs, "config_ratio_Fe_to_DOC_lipids", config_ratio_Fe_to_DOC_lipids) - call MPAS_pool_get_config(domain % configs, "config_respiration_fraction_of_growth", config_respiration_fraction_of_growth) - call MPAS_pool_get_config(domain % configs, "config_rapid_mobile_to_stationary_time", config_rapid_mobile_to_stationary_time) - call MPAS_pool_get_config(domain % configs, "config_long_mobile_to_stationary_time", config_long_mobile_to_stationary_time) - call MPAS_pool_get_config(domain % configs, "config_algal_maximum_velocity", config_algal_maximum_velocity) - call MPAS_pool_get_config(domain % configs, "config_ratio_Fe_to_dust", config_ratio_Fe_to_dust) - call MPAS_pool_get_config(domain % configs, "config_solubility_of_Fe_in_dust", config_solubility_of_Fe_in_dust) - call MPAS_pool_get_config(domain % configs, "config_chla_absorptivity_of_diatoms", config_chla_absorptivity_of_diatoms) - call MPAS_pool_get_config(domain % configs, "config_chla_absorptivity_of_small_plankton", & - config_chla_absorptivity_of_small_plankton) - call MPAS_pool_get_config(domain % configs, "config_chla_absorptivity_of_phaeocystis", config_chla_absorptivity_of_phaeocystis) - call MPAS_pool_get_config(domain % configs, "config_light_attenuation_diatoms", config_light_attenuation_diatoms) - call MPAS_pool_get_config(domain % configs, "config_light_attenuation_small_plankton", config_light_attenuation_small_plankton) - call MPAS_pool_get_config(domain % configs, "config_light_attenuation_phaeocystis", config_light_attenuation_phaeocystis) - call MPAS_pool_get_config(domain % configs, "config_light_inhibition_diatoms", config_light_inhibition_diatoms) - call MPAS_pool_get_config(domain % configs, "config_light_inhibition_small_plankton", config_light_inhibition_small_plankton) - call MPAS_pool_get_config(domain % configs, "config_light_inhibition_phaeocystis", config_light_inhibition_phaeocystis) - call MPAS_pool_get_config(domain % configs, "config_maximum_growth_rate_diatoms", config_maximum_growth_rate_diatoms) - call MPAS_pool_get_config(domain % configs, "config_maximum_growth_rate_small_plankton", & - config_maximum_growth_rate_small_plankton) - call MPAS_pool_get_config(domain % configs, "config_maximum_growth_rate_phaeocystis", config_maximum_growth_rate_phaeocystis) - call MPAS_pool_get_config(domain % configs, "config_temperature_growth_diatoms", config_temperature_growth_diatoms) - call MPAS_pool_get_config(domain % configs, "config_temperature_growth_small_plankton", & - config_temperature_growth_small_plankton) - call MPAS_pool_get_config(domain % configs, "config_temperature_growth_phaeocystis", config_temperature_growth_phaeocystis) - call MPAS_pool_get_config(domain % configs, "config_grazed_fraction_diatoms", config_grazed_fraction_diatoms) - call MPAS_pool_get_config(domain % configs, "config_grazed_fraction_small_plankton", config_grazed_fraction_small_plankton) - call MPAS_pool_get_config(domain % configs, "config_grazed_fraction_phaeocystis", config_grazed_fraction_phaeocystis) - call MPAS_pool_get_config(domain % configs, "config_mortality_diatoms", config_mortality_diatoms) - call MPAS_pool_get_config(domain % configs, "config_mortality_small_plankton", config_mortality_small_plankton) - call MPAS_pool_get_config(domain % configs, "config_mortality_phaeocystis", config_mortality_phaeocystis) - call MPAS_pool_get_config(domain % configs, "config_temperature_mortality_diatoms", config_temperature_mortality_diatoms) - call MPAS_pool_get_config(domain % configs, "config_temperature_mortality_small_plankton", & - config_temperature_mortality_small_plankton) - call MPAS_pool_get_config(domain % configs, "config_temperature_mortality_phaeocystis", & - config_temperature_mortality_phaeocystis) - call MPAS_pool_get_config(domain % configs, "config_exudation_diatoms", config_exudation_diatoms) - call MPAS_pool_get_config(domain % configs, "config_exudation_small_plankton", config_exudation_small_plankton) - call MPAS_pool_get_config(domain % configs, "config_exudation_phaeocystis", config_exudation_phaeocystis) - call MPAS_pool_get_config(domain % configs, "config_nitrate_saturation_diatoms", config_nitrate_saturation_diatoms) - call MPAS_pool_get_config(domain % configs, "config_nitrate_saturation_small_plankton", & - config_nitrate_saturation_small_plankton) - call MPAS_pool_get_config(domain % configs, "config_nitrate_saturation_phaeocystis", config_nitrate_saturation_phaeocystis) - call MPAS_pool_get_config(domain % configs, "config_ammonium_saturation_diatoms", config_ammonium_saturation_diatoms) - call MPAS_pool_get_config(domain % configs, "config_ammonium_saturation_small_plankton", & - config_ammonium_saturation_small_plankton) - call MPAS_pool_get_config(domain % configs, "config_ammonium_saturation_phaeocystis", & - config_ammonium_saturation_phaeocystis) - call MPAS_pool_get_config(domain % configs, "config_silicate_saturation_diatoms", config_silicate_saturation_diatoms) - call MPAS_pool_get_config(domain % configs, "config_silicate_saturation_small_plankton", & - config_silicate_saturation_small_plankton) - call MPAS_pool_get_config(domain % configs, "config_silicate_saturation_phaeocystis", config_silicate_saturation_phaeocystis) - call MPAS_pool_get_config(domain % configs, "config_iron_saturation_diatoms", config_iron_saturation_diatoms) - call MPAS_pool_get_config(domain % configs, "config_iron_saturation_small_plankton", config_iron_saturation_small_plankton) - call MPAS_pool_get_config(domain % configs, "config_iron_saturation_phaeocystis", config_iron_saturation_phaeocystis) - call MPAS_pool_get_config(domain % configs, "config_fraction_spilled_to_DON", config_fraction_spilled_to_DON) - call MPAS_pool_get_config(domain % configs, "config_degredation_of_DON", config_degredation_of_DON) - call MPAS_pool_get_config(domain % configs, "config_fraction_DON_ammonium", config_fraction_DON_ammonium) - call MPAS_pool_get_config(domain % configs, "config_fraction_loss_to_saccharids", config_fraction_loss_to_saccharids) - call MPAS_pool_get_config(domain % configs, "config_fraction_loss_to_lipids", config_fraction_loss_to_lipids) - call MPAS_pool_get_config(domain % configs, "config_fraction_exudation_to_saccharids", config_fraction_exudation_to_saccharids) - call MPAS_pool_get_config(domain % configs, "config_fraction_exudation_to_lipids", config_fraction_exudation_to_lipids) - call MPAS_pool_get_config(domain % configs, "config_remineralization_saccharids", config_remineralization_saccharids) - call MPAS_pool_get_config(domain % configs, "config_remineralization_lipids", config_remineralization_lipids) - call MPAS_pool_get_config(domain % configs, "config_maximum_brine_temperature", config_maximum_brine_temperature) - call MPAS_pool_get_config(domain % configs, "config_salinity_dependence_of_growth", config_salinity_dependence_of_growth) - call MPAS_pool_get_config(domain % configs, "config_minimum_optical_depth", config_minimum_optical_depth) - call MPAS_pool_get_config(domain % configs, "config_slopped_grazing_fraction", config_slopped_grazing_fraction) - call MPAS_pool_get_config(domain % configs, "config_excreted_fraction", config_excreted_fraction) - call MPAS_pool_get_config(domain % configs, "config_fraction_mortality_to_ammonium", config_fraction_mortality_to_ammonium) - call MPAS_pool_get_config(domain % configs, "config_fraction_iron_remineralized", config_fraction_iron_remineralized) - call MPAS_pool_get_config(domain % configs, "config_nitrification_rate", config_nitrification_rate) - call MPAS_pool_get_config(domain % configs, "config_desorption_loss_particulate_iron", config_desorption_loss_particulate_iron) - call MPAS_pool_get_config(domain % configs, "config_maximum_loss_fraction", config_maximum_loss_fraction) - call MPAS_pool_get_config(domain % configs, "config_maximum_ratio_iron_to_saccharids", config_maximum_ratio_iron_to_saccharids) - call MPAS_pool_get_config(domain % configs, "config_respiration_loss_to_DMSPd", config_respiration_loss_to_DMSPd) - call MPAS_pool_get_config(domain % configs, "config_DMSP_to_DMS_conversion_fraction", config_DMSP_to_DMS_conversion_fraction) - call MPAS_pool_get_config(domain % configs, "config_DMSP_to_DMS_conversion_time", config_DMSP_to_DMS_conversion_time) - call MPAS_pool_get_config(domain % configs, "config_DMS_oxidation_time", config_DMS_oxidation_time) - call MPAS_pool_get_config(domain % configs, "config_mobility_type_diatoms", config_mobility_type_diatoms) - call MPAS_pool_get_config(domain % configs, "config_mobility_type_small_plankton", config_mobility_type_small_plankton) - call MPAS_pool_get_config(domain % configs, "config_mobility_type_phaeocystis", config_mobility_type_phaeocystis) - call MPAS_pool_get_config(domain % configs, "config_mobility_type_nitrate", config_mobility_type_nitrate) - call MPAS_pool_get_config(domain % configs, "config_mobility_type_ammonium", config_mobility_type_ammonium) - call MPAS_pool_get_config(domain % configs, "config_mobility_type_silicate", config_mobility_type_silicate) - call MPAS_pool_get_config(domain % configs, "config_mobility_type_DMSPp", config_mobility_type_DMSPp) - call MPAS_pool_get_config(domain % configs, "config_mobility_type_DMSPd", config_mobility_type_DMSPd) - call MPAS_pool_get_config(domain % configs, "config_mobility_type_humics", config_mobility_type_humics) - call MPAS_pool_get_config(domain % configs, "config_mobility_type_saccharids", config_mobility_type_saccharids) - call MPAS_pool_get_config(domain % configs, "config_mobility_type_lipids", config_mobility_type_lipids) - call MPAS_pool_get_config(domain % configs, "config_mobility_type_inorganic_carbon", config_mobility_type_inorganic_carbon) - call MPAS_pool_get_config(domain % configs, "config_mobility_type_proteins", config_mobility_type_proteins) - call MPAS_pool_get_config(domain % configs, "config_mobility_type_dissolved_iron", config_mobility_type_dissolved_iron) - call MPAS_pool_get_config(domain % configs, "config_mobility_type_particulate_iron", config_mobility_type_particulate_iron) - call MPAS_pool_get_config(domain % configs, "config_mobility_type_black_carbon1", config_mobility_type_black_carbon1) - call MPAS_pool_get_config(domain % configs, "config_mobility_type_black_carbon2", config_mobility_type_black_carbon2) - call MPAS_pool_get_config(domain % configs, "config_mobility_type_dust1", config_mobility_type_dust1) - call MPAS_pool_get_config(domain % configs, "config_mobility_type_dust2", config_mobility_type_dust2) - call MPAS_pool_get_config(domain % configs, "config_mobility_type_dust3", config_mobility_type_dust3) - call MPAS_pool_get_config(domain % configs, "config_mobility_type_dust4", config_mobility_type_dust4) - call MPAS_pool_get_config(domain % configs, "config_ratio_C_to_N_diatoms", config_ratio_C_to_N_diatoms) - call MPAS_pool_get_config(domain % configs, "config_ratio_C_to_N_small_plankton", config_ratio_C_to_N_small_plankton) - call MPAS_pool_get_config(domain % configs, "config_ratio_C_to_N_phaeocystis", config_ratio_C_to_N_phaeocystis) - call MPAS_pool_get_config(domain % configs, "config_ratio_chla_to_N_diatoms", config_ratio_chla_to_N_diatoms) - call MPAS_pool_get_config(domain % configs, "config_ratio_chla_to_N_small_plankton", config_ratio_chla_to_N_small_plankton) - call MPAS_pool_get_config(domain % configs, "config_ratio_chla_to_N_phaeocystis", config_ratio_chla_to_N_phaeocystis) - call MPAS_pool_get_config(domain % configs, "config_scales_absorption_diatoms", config_scales_absorption_diatoms) - call MPAS_pool_get_config(domain % configs, "config_scales_absorption_small_plankton", config_scales_absorption_small_plankton) - call MPAS_pool_get_config(domain % configs, "config_scales_absorption_phaeocystis", config_scales_absorption_phaeocystis) - call MPAS_pool_get_config(domain % configs, "config_ratio_C_to_N_proteins", config_ratio_C_to_N_proteins) - call MPAS_pool_get_config(domain % configs, "config_snow_redistribution_scheme", config_snow_redistribution_scheme) - call MPAS_pool_get_config(domain % configs, "config_fallen_snow_radius", config_fallen_snow_radius) - call MPAS_pool_get_config(domain % configs, "config_use_snow_liquid_ponds", config_use_snow_liquid_ponds) - call MPAS_pool_get_config(domain % configs, "config_new_snow_density", config_new_snow_density) - call MPAS_pool_get_config(domain % configs, "config_max_snow_density", config_max_snow_density) - call MPAS_pool_get_config(domain % configs, "config_minimum_wind_compaction", config_minimum_wind_compaction) - call MPAS_pool_get_config(domain % configs, "config_wind_compaction_factor", config_wind_compaction_factor) - call MPAS_pool_get_config(domain % configs, "config_snow_redistribution_factor", config_snow_redistribution_factor) - call MPAS_pool_get_config(domain % configs, "config_max_dry_snow_radius", config_max_dry_snow_radius) - call MPAS_pool_get_config(domain % configs, "config_use_snow_grain_radius", config_use_snow_grain_radius) - call MPAS_pool_get_dimension(domain % blocklist % dimensions, "nGrainAgingTemperature", nGrainAgingTemperature) - call MPAS_pool_get_dimension(domain % blocklist % dimensions, "nGrainAgingTempGradient", nGrainAgingTempGradient) - call MPAS_pool_get_dimension(domain % blocklist % dimensions, "nGrainAgingSnowDensity", nGrainAgingSnowDensity) - call MPAS_pool_get_subpool(domain % blocklist % structs, "snow", snow) - call MPAS_pool_get_array(snow, "snowEmpiricalGrowthParameterTau", snowEmpiricalGrowthParameterTau) - call MPAS_pool_get_array(snow, "snowEmpiricalGrowthParameterKappa", snowEmpiricalGrowthParameterKappa) - call MPAS_pool_get_array(snow, "snowPropertyRate", snowPropertyRate) + call MPAS_pool_get_config(domain % configs, "config_use_snow_grain_radius", config_use_snow_grain_radius) + call MPAS_pool_get_dimension(domain % blocklist % dimensions, "nGrainAgingTemperature", nGrainAgingTemperature) + call MPAS_pool_get_dimension(domain % blocklist % dimensions, "nGrainAgingTempGradient", nGrainAgingTempGradient) + call MPAS_pool_get_dimension(domain % blocklist % dimensions, "nGrainAgingSnowDensity", nGrainAgingSnowDensity) + call MPAS_pool_get_subpool(domain % blocklist % structs, "snow", snow) + call MPAS_pool_get_array(snow, "snowEmpiricalGrowthParameterTau", snowEmpiricalGrowthParameterTau) + call MPAS_pool_get_array(snow, "snowEmpiricalGrowthParameterKappa", snowEmpiricalGrowthParameterKappa) + call MPAS_pool_get_array(snow, "snowPropertyRate", snowPropertyRate) config_thermodynamics_type_int = config_cice_int("config_thermodynamics_type", config_thermodynamics_type) config_ice_strength_formulation_int = config_cice_int("config_ice_strength_formulation", config_ice_strength_formulation) @@ -12157,6 +10752,7 @@ subroutine init_icepack_package_configs(domain) snowpatch_in = seaiceSnowPatchiness, & ! ccsm3 radiation scheme !rhosi_in = , & ! brine, zbgc, zsalinity sk_l_in = skeletalLayerThickness, & ! + R_gC2molC_in = gramsCarbonPerMolCarbon, & saltmax_in = seaiceMaximumSalinity, & phi_init_in = seaiceFrazilIcePorosity, & !min_salin_in = , & ! ktherm=1, brine, zsalinity @@ -12391,9 +10987,9 @@ subroutine init_icepack_package_configs(domain) ! - make Lfresh optional for E3SM? ! tcraig, this will write out icepack parameters to fort.101, need to uncomment 3 lines -! if (mpas_log_info % taskID == 0) then -! call icepack_write_parameters(101) -! endif + if (mpas_log_info % taskID == 0) then + call icepack_write_parameters(101) + endif ! call seaice_icepack_write_warnings(icepack_warnings_aborted()) call mpas_log_write(" ----- compare values after icepack init -----") @@ -15726,15 +14322,6 @@ subroutine seaice_icepack_reinitialize_diagnostics_bgc(domain) end if -! if (config_use_vertical_zsalinity) then !echmod deprecate -! call MPAS_pool_get_array(biogeochemistryPool, "zSalinityFlux", zSalinityFlux) -! call MPAS_pool_get_array(biogeochemistryPool, "zSalinityGDFlux", zSalinityGDFlux) - -! zSalinityFlux = 0.0_RKIND -! zSalinityGDFlux = 0.0_RKIND - -! end if - call MPAS_pool_get_array(biogeochemistryPool, "netBrineHeight", netBrineHeight) call MPAS_pool_get_array(biogeochemistryPool, "oceanBioFluxes", oceanBioFluxes) call MPAS_pool_get_array(biogeochemistryPool, "atmosIceBioFluxes", atmosIceBioFluxes) @@ -16745,7 +15332,7 @@ end subroutine seaice_ocean_carbon_flux ! !----------------------------------------------------------------------- - subroutine seaice_ocean_carbon_flux_cell(block,oceanCarbonFlux,oceanBioFluxes,iCell) + subroutine seaice_ocean_carbon_flux_cell(block,oceanCarbonFlux,oceanBioFluxes) real(kind=RKIND), intent(out) :: & oceanCarbonFlux @@ -16753,9 +15340,6 @@ subroutine seaice_ocean_carbon_flux_cell(block,oceanCarbonFlux,oceanBioFluxes,iC real(kind=RKIND), dimension(:), intent(in) :: & oceanBioFluxes - integer, intent(in) :: & - iCell - type(block_type), intent(in) :: & block From 105526017a97d110f36f8ad9a7783ca520beb183 Mon Sep 17 00:00:00 2001 From: hollyhan Date: Mon, 18 Mar 2024 10:55:50 -0700 Subject: [PATCH 070/451] Update the SeaLevelModel submodule --- components/mpas-albany-landice/src/SeaLevelModel | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/components/mpas-albany-landice/src/SeaLevelModel b/components/mpas-albany-landice/src/SeaLevelModel index 26c156da2191..5bb102d6750b 160000 --- a/components/mpas-albany-landice/src/SeaLevelModel +++ b/components/mpas-albany-landice/src/SeaLevelModel @@ -1 +1 @@ -Subproject commit 26c156da2191df360e1040e0141534178674fc82 +Subproject commit 5bb102d6750b1437f6a5305cdd244cbd3776c32b From 95e7295b02636685be997f6d78eed2117890038b Mon Sep 17 00:00:00 2001 From: Matthew Hoffman Date: Tue, 19 Mar 2024 12:18:54 -0600 Subject: [PATCH 071/451] Revisions from code review --- .../mpas-albany-landice/src/mode_forward/mpas_li_thermal.F | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/components/mpas-albany-landice/src/mode_forward/mpas_li_thermal.F b/components/mpas-albany-landice/src/mode_forward/mpas_li_thermal.F index 65c300963529..acc5048e3a4e 100644 --- a/components/mpas-albany-landice/src/mode_forward/mpas_li_thermal.F +++ b/components/mpas-albany-landice/src/mode_forward/mpas_li_thermal.F @@ -70,7 +70,7 @@ module li_thermal ! Note: kelvin_to_celsius = 273.15 (perhaps it should be called celsius_to_kelvin?) real (kind=RKIND), parameter :: & - maxtempThreshold = 0.1_RKIND + kelvin_to_celsius, & + maxtempThreshold = 1e-6_RKIND + kelvin_to_celsius, & mintempThreshold = -100._RKIND + kelvin_to_celsius !*********************************************************************** @@ -2847,7 +2847,7 @@ subroutine basal_melt_grounded_ice(& ! Update basal water thickness based on melting or freezing (same for enthalpy or temperature) if (groundedBasalMassBal(iCell) > 0.0) then - ! for freezing conditions (+SMB), limit positive BMB to the available basal water + ! for freezing conditions, limit positive BMB to the available basal water groundedBasalMassBal(iCell) = min(groundedBasalMassBal(iCell), basalWaterThickness(iCell) / deltat) endif basalWaterThickness(iCell) = basalWaterThickness(iCell) - deltat*groundedBasalMassBal(iCell) From 0af5931b90c565976fdcf94472ab187903ae6d50 Mon Sep 17 00:00:00 2001 From: Walter Hannah Date: Tue, 26 Mar 2024 12:38:59 -0700 Subject: [PATCH 072/451] PAM VT update --- .../eam/src/physics/crm/pam/pam_driver.cpp | 14 ++++++------- .../physics/crm/pam/pam_variance_transport.h | 20 +++++++++++-------- 2 files changed, 19 insertions(+), 15 deletions(-) diff --git a/components/eam/src/physics/crm/pam/pam_driver.cpp b/components/eam/src/physics/crm/pam/pam_driver.cpp index 2453f2ad61b2..e6f85ed0d5ac 100644 --- a/components/eam/src/physics/crm/pam/pam_driver.cpp +++ b/components/eam/src/physics/crm/pam/pam_driver.cpp @@ -25,7 +25,7 @@ #include "p3_f90.hpp" #include "pam_debug.h" -bool constexpr enable_check_state = true; +bool constexpr enable_check_state = false; extern "C" void pam_driver() { //------------------------------------------------------------------------------------------------ @@ -180,10 +180,11 @@ extern "C" void pam_driver() { // Apply forcing tendencies if (use_MMF_VT) { pam_variance_transport_apply_forcing(coupler); } - coupler.run_module( "apply_gcm_forcing_tendencies" , modules::apply_gcm_forcing_tendencies ); if (enable_check_state) { pam_debug_check_state(coupler, 2, nstep); } - coupler.run_module( "radiation" , [&] (pam::PamCoupler &coupler) {rad .timeStep(coupler);} ); + coupler.run_module( "apply_gcm_forcing_tendencies" , modules::apply_gcm_forcing_tendencies ); if (enable_check_state) { pam_debug_check_state(coupler, 3, nstep); } + coupler.run_module( "radiation" , [&] (pam::PamCoupler &coupler) {rad .timeStep(coupler);} ); + if (enable_check_state) { pam_debug_check_state(coupler, 4, nstep); } // Dynamics if (enable_physics_tend_stats) { pam_statistics_save_state(coupler); } @@ -191,13 +192,12 @@ extern "C" void pam_driver() { coupler.run_module( "dycore", [&] (pam::PamCoupler &coupler) {dycore.timeStep(coupler);} ); if (do_density_save_recall) { pam_state_recall_dry_density(coupler); } if (enable_physics_tend_stats) { pam_statistics_aggregate_tendency(coupler,"dycor"); } - if (enable_check_state) { pam_debug_check_state(coupler, 4, nstep); } + if (enable_check_state) { pam_debug_check_state(coupler, 5, nstep); } // Sponge layer damping if (enable_physics_tend_stats) { pam_statistics_save_state(coupler); } coupler.run_module( "sponge_layer", modules::sponge_layer ); if (enable_physics_tend_stats) { pam_statistics_aggregate_tendency(coupler,"sponge"); } - // if (enable_check_state) { pam_debug_check_state(coupler, 4, nstep); } // Apply hyperdiffusion to account for lack of horizontal mixing in SHOC pam_hyperdiffusion(coupler); @@ -207,13 +207,13 @@ extern "C" void pam_driver() { if (enable_physics_tend_stats) { pam_statistics_save_state(coupler); } coupler.run_module( "sgs", [&] (pam::PamCoupler &coupler) {sgs .timeStep(coupler);} ); if (enable_physics_tend_stats) { pam_statistics_aggregate_tendency(coupler,"sgs"); } - if (enable_check_state) { pam_debug_check_state(coupler, 5, nstep); } + if (enable_check_state) { pam_debug_check_state(coupler, 6, nstep); } // Microphysics - P3 if (enable_physics_tend_stats) { pam_statistics_save_state(coupler); } coupler.run_module( "micro", [&] (pam::PamCoupler &coupler) {micro .timeStep(coupler);} ); if (enable_physics_tend_stats) { pam_statistics_aggregate_tendency(coupler,"micro"); } - if (enable_check_state) { pam_debug_check_state(coupler, 6, nstep); } + if (enable_check_state) { pam_debug_check_state(coupler, 7, nstep); } // CRM mean state acceleration if (use_crm_accel && !coupler.get_option("crm_acceleration_ceaseflag")) { diff --git a/components/eam/src/physics/crm/pam/pam_variance_transport.h b/components/eam/src/physics/crm/pam/pam_variance_transport.h index b7067631203f..1033df4280d4 100644 --- a/components/eam/src/physics/crm/pam/pam_variance_transport.h +++ b/components/eam/src/physics/crm/pam/pam_variance_transport.h @@ -2,6 +2,7 @@ #include "pam_coupler.h" + inline void pam_variance_transport_init( pam::PamCoupler &coupler ) { using yakl::c::parallel_for; using yakl::c::SimpleBounds; @@ -24,6 +25,7 @@ inline void pam_variance_transport_init( pam::PamCoupler &coupler ) { //------------------------------------------------------------------------------------------------ } + inline void pam_variance_transport_diagnose( pam::PamCoupler &coupler ) { using yakl::c::parallel_for; using yakl::c::SimpleBounds; @@ -83,6 +85,7 @@ inline void pam_variance_transport_diagnose( pam::PamCoupler &coupler ) { //------------------------------------------------------------------------------------------------ } + inline void pam_variance_transport_compute_forcing( pam::PamCoupler &coupler ) { using yakl::c::parallel_for; using yakl::c::SimpleBounds; @@ -135,9 +138,10 @@ inline void pam_variance_transport_apply_forcing( pam::PamCoupler &coupler ) { // large-scale forcing from variance transport. This is meant to // protect against creating unstable situations, although // problematic scenarios were extremely rare in testing. - // A scaling limit of +/- 10% was found to be adequate. - real constexpr pert_scale_min = 1.0 - 0.005; - real constexpr pert_scale_max = 1.0 + 0.005; + // A scaling limit of +/- 10% was found to be adequate in SAM, + // but PAM seems much more sensitive (not sure why), so we use 0.1% here + real constexpr pert_scale_min = 1.0 - 0.001; + real constexpr pert_scale_max = 1.0 + 0.001; //------------------------------------------------------------------------------------------------ auto temp = dm_device.get("temp" ); auto rhov = dm_device.get("water_vapor" ); @@ -162,14 +166,15 @@ inline void pam_variance_transport_apply_forcing( pam::PamCoupler &coupler ) { //------------------------------------------------------------------------------------------------ // calculate scaling factor for local perturbations parallel_for( SimpleBounds<2>(nz,nens) , YAKL_LAMBDA (int k, int n) { + real tmp; // initialize scaling factors to 1.0 temp_pert_scale(k,n) = 1.0; rhov_pert_scale(k,n) = 1.0; uvel_pert_scale(k,n) = 1.0; - // set scaling factors as long as there are perturbations to scale - if (vt_temp(k,n)>0.0) { temp_pert_scale(k,n) = sqrt( 1.0 + crm_dt * vt_temp_forcing_tend(k,n) / vt_temp(k,n) ); } - if (vt_rhov(k,n)>0.0) { rhov_pert_scale(k,n) = sqrt( 1.0 + crm_dt * vt_rhov_forcing_tend(k,n) / vt_rhov(k,n) ); } - if (vt_uvel(k,n)>0.0) { uvel_pert_scale(k,n) = sqrt( 1.0 + crm_dt * vt_uvel_forcing_tend(k,n) / vt_uvel(k,n) ); } + // calculate variance scaling factor + tmp = 1.+crm_dt*vt_temp_forcing_tend(k,n)/vt_temp(k,n); if (tmp>0){ temp_pert_scale(k,n) = sqrt(tmp); } + tmp = 1.+crm_dt*vt_rhov_forcing_tend(k,n)/vt_rhov(k,n); if (tmp>0){ rhov_pert_scale(k,n) = sqrt(tmp); } + tmp = 1.+crm_dt*vt_uvel_forcing_tend(k,n)/vt_uvel(k,n); if (tmp>0){ uvel_pert_scale(k,n) = sqrt(tmp); } // enforce minimum scaling temp_pert_scale(k,n) = std::max( temp_pert_scale(k,n), pert_scale_min ); rhov_pert_scale(k,n) = std::max( rhov_pert_scale(k,n), pert_scale_min ); @@ -261,7 +266,6 @@ inline void pam_variance_transport_copy_to_host( pam::PamCoupler &coupler ) { vt_temp_feedback_tend.deep_copy_to(output_vt_temp_tend_host); vt_rhov_feedback_tend.deep_copy_to(output_vt_rhov_tend_host); vt_uvel_feedback_tend.deep_copy_to(output_vt_uvel_tend_host); - yakl::fence(); //------------------------------------------------------------------------------------------------ } From 6fe86f61e08038fb95f964b0cfb5907d5a53423a Mon Sep 17 00:00:00 2001 From: Walter Hannah Date: Tue, 26 Mar 2024 12:47:40 -0700 Subject: [PATCH 073/451] update PAM submodule --- components/eam/src/physics/crm/pam/external | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/components/eam/src/physics/crm/pam/external b/components/eam/src/physics/crm/pam/external index 9d692dccdd67..ff652f3f2a6c 160000 --- a/components/eam/src/physics/crm/pam/external +++ b/components/eam/src/physics/crm/pam/external @@ -1 +1 @@ -Subproject commit 9d692dccdd67d9c4dc278c76290504a2af8cd187 +Subproject commit ff652f3f2a6c2d675cd957883245aa6c036ef110 From 59b9476bbc96ed060ff12e4a7ba3480795b67872 Mon Sep 17 00:00:00 2001 From: Walter Hannah Date: Tue, 26 Mar 2024 12:48:49 -0700 Subject: [PATCH 074/451] update PAM hyperdiffusion timescale default --- components/eam/src/physics/crm/pam/pam_hyperdiffusion.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/components/eam/src/physics/crm/pam/pam_hyperdiffusion.h b/components/eam/src/physics/crm/pam/pam_hyperdiffusion.h index 4452c583afe3..b632b0e49093 100644 --- a/components/eam/src/physics/crm/pam/pam_hyperdiffusion.h +++ b/components/eam/src/physics/crm/pam/pam_hyperdiffusion.h @@ -28,7 +28,7 @@ inline void pam_hyperdiffusion( pam::PamCoupler &coupler ) { #ifdef MMF_PAM_HDT real constexpr hd_timescale = MMF_PAM_HDT; // damping time scale [sec] #else - real constexpr hd_timescale = 10.0; // damping time scale [sec] + real constexpr hd_timescale = 60.0; // damping time scale [sec] #endif //------------------------------------------------------------------------------------------------ real4d hd_temp("hd_temp",nz,ny,nx,nens); From 1bc8307c0bd724847bc866b3c86d07d3f51c4dda Mon Sep 17 00:00:00 2001 From: Trevor Hillebrand Date: Wed, 27 Mar 2024 11:40:59 -0700 Subject: [PATCH 075/451] Always remove small islands Always remove small islands, even if calving is turned off. Previously, remove_small_islands was only called from within each calving routine, which caused issues with AIS simulations with only restore_calving_front. --- .../src/mode_forward/mpas_li_calving.F | 21 +++---------------- 1 file changed, 3 insertions(+), 18 deletions(-) diff --git a/components/mpas-albany-landice/src/mode_forward/mpas_li_calving.F b/components/mpas-albany-landice/src/mode_forward/mpas_li_calving.F index 304ed0b0349c..a86612ad00ea 100644 --- a/components/mpas-albany-landice/src/mode_forward/mpas_li_calving.F +++ b/components/mpas-albany-landice/src/mode_forward/mpas_li_calving.F @@ -315,7 +315,8 @@ subroutine li_calve_ice(domain, err, solveVeloAfterCalving) ! now also remove any icebergs call remove_icebergs(domain) - ! Final operations after calving has been applied. + ! Final operations after calving has been applied, including removal + ! of small islands block => domain % blocklist do while (associated(block)) call mpas_pool_get_subpool(block % structs, 'geometry', geometryPool) @@ -324,6 +325,7 @@ subroutine li_calve_ice(domain, err, solveVeloAfterCalving) call mpas_pool_get_array(geometryPool, 'calvingThickness', calvingThickness) call mpas_pool_get_dimension(meshPool, 'nCells', nCells) + call remove_small_islands(meshPool, geometryPool) ! In data calving mode we just calculate what should be calved but don't actually calve it. ! So set thickness back to original value. if (config_data_calving) then @@ -927,8 +929,6 @@ subroutine thickness_calving(domain, calvingFraction, err) ! === apply calving === thickness(:) = thickness(:) - calvingThickness(:) - call remove_small_islands(meshPool, geometryPool) - block => block % next enddo @@ -1003,8 +1003,6 @@ subroutine floating_calving(domain, calvingFraction, err) ! === apply calving === thickness(:) = thickness(:) - calvingThickness(:) - call remove_small_islands(meshPool, geometryPool) - block => block % next enddo @@ -1180,8 +1178,6 @@ subroutine topographic_calving(domain, calvingFraction, err) ! === apply calving === thickness(:) = thickness(:) - calvingThickness(:) - call remove_small_islands(meshPool, geometryPool) - block => block % next enddo @@ -1412,8 +1408,6 @@ subroutine eigencalving(domain, err) enddo ! TODO: global reduce & reporting on amount of calving generated in this step - call remove_small_islands(meshPool, geometryPool) - block => block % next enddo @@ -1596,8 +1590,6 @@ subroutine specified_calving_velocity(domain, err) enddo ! TODO: global reduce & reporting on amount of calving generated in this step - call remove_small_islands(meshPool, geometryPool) - block => block % next enddo @@ -1985,8 +1977,6 @@ subroutine von_Mises_calving(domain, err) call li_calculate_mask(meshPool, velocityPool, geometryPool, err_tmp) err = ior(err, err_tmp) - call remove_small_islands(meshPool, geometryPool) - block => block % next enddo ! associated(block) @@ -2256,7 +2246,6 @@ subroutine ismip6_retreat(domain, err) ! update mask call li_calculate_mask(meshPool, velocityPool, geometryPool, err_tmp) err = ior(err, err_tmp) - call remove_small_islands(meshPool, geometryPool) deallocate(submergedArea) @@ -3326,8 +3315,6 @@ subroutine damage_calving(domain, err) enddo ! TODO: global reduce & reporting on amount of calving generated in this step - call remove_small_islands(meshPool, geometryPool) - block => block % next enddo @@ -3986,8 +3973,6 @@ subroutine mask_calving(domain, err) call li_calculate_mask(meshPool, velocityPool, geometryPool, err_tmp) err = ior(err, err_tmp) - call remove_small_islands(meshPool, geometryPool) - block => block % next enddo From dc672a666686f36032e244e33e16c5b8ae16858b Mon Sep 17 00:00:00 2001 From: Nicole Jeffery Date: Thu, 28 Mar 2024 16:54:47 -0500 Subject: [PATCH 076/451] Avoids division by small number in update vertical bio tracers -Cleans up some missing bgc info in Registry (more to do) -Adds some additional info to carbon conservation analysis member -Saves bgc ocean fluxes weighted by ice area (for carbon conservation) -Comments out $omp statements around step therm1 (code was crashing -with seg fault) -Removes and cleans up unnecessary write statements for carbon debugging Tested with E3SM-Project/Icepack.git branch njeffery/merge-fixes-to-bgc commit c090b4b20e4ec0317d2c7d742c5ab291ec7a2240 BFB except correcting a seg fault --- components/mpas-seaice/src/Registry.xml | 163 ++++++++- .../Registry_seaice_conservation_check.xml | 6 + .../mpas_seaice_conservation_check.F | 77 ++--- .../mpas-seaice/src/column/ice_algae.F90 | 33 +- .../mpas-seaice/src/column/ice_colpkg.F90 | 2 +- .../mpas-seaice/src/column/ice_therm_itd.F90 | 2 +- .../mpas-seaice/src/column/ice_zbgc.F90 | 8 +- .../src/shared/mpas_seaice_column.F | 60 +++- .../src/shared/mpas_seaice_icepack.F | 314 +++++------------- 9 files changed, 376 insertions(+), 289 deletions(-) diff --git a/components/mpas-seaice/src/Registry.xml b/components/mpas-seaice/src/Registry.xml index ed39007ef723..6eb70ead768b 100644 --- a/components/mpas-seaice/src/Registry.xml +++ b/components/mpas-seaice/src/Registry.xml @@ -5312,7 +5312,9 @@ type="real" dimensions="nCells Time" units="mmol m-2 s-1" - description="Total ocean carbon flux (positive into the ocean)" + description="Total ocean carbon flux (positive + into the ocean) weighted bysea ice + area fraction" packages="pkgColumnBiogeochemistry;pkgColumnPackage" /> + + + + + + + + + + + + + + + + puny) then ! loop over new grid cells do k2 = 1, nbiolyr @@ -840,7 +842,9 @@ subroutine update_vertical_bio_tracers(nbiolyr, trc, h1, h2, trc0, zspace) trc2(k2) = trc2(k2)/zspace(k2)/h2 !(rnilyr * trc2(k2)) / h2 enddo ! k2 - + else + trc2 = trc + endif ! h2 > 0 ! update vertical tracer array with the adjusted tracer trc = trc2 diff --git a/components/mpas-seaice/src/shared/mpas_seaice_column.F b/components/mpas-seaice/src/shared/mpas_seaice_column.F index 1b736c4b0ccb..80a00a154d99 100644 --- a/components/mpas-seaice/src/shared/mpas_seaice_column.F +++ b/components/mpas-seaice/src/shared/mpas_seaice_column.F @@ -4922,7 +4922,17 @@ subroutine seaice_column_coupling_prep(domain) oceanDMSPdFlux, & oceanHumicsFlux, & oceanDustIronFlux, & - totalOceanCarbonFlux + oceanBlackCarbonFlux, & + totalOceanCarbonFlux, & + oceanNitrateFluxArea, & + oceanSilicateFluxArea, & + oceanAmmoniumFluxArea, & + oceanDMSFluxArea, & + oceanDMSPpFluxArea, & + oceanDMSPdFluxArea, & + oceanHumicsFluxArea, & + oceanDustIronFluxArea, & + oceanBlackCarbonFluxArea real(kind=RKIND), dimension(:,:), pointer :: & albedoVisibleDirectCategory, & @@ -4939,7 +4949,13 @@ subroutine seaice_column_coupling_prep(domain) oceanDICFlux, & oceanDONFlux, & oceanParticulateIronFlux, & - oceanDissolvedIronFlux + oceanDissolvedIronFlux, & + oceanAlgaeFluxArea, & + oceanDOCFluxArea, & + oceanDICFluxArea, & + oceanDONFluxArea, & + oceanParticulateIronFluxArea, & + oceanDissolvedIronFluxArea real(kind=RKIND), dimension(:,:,:), pointer :: & iceAreaCategory @@ -5062,6 +5078,7 @@ subroutine seaice_column_coupling_prep(domain) call MPAS_pool_get_array(biogeochemistry, "oceanDMSPdFlux", oceanDMSPdFlux) call MPAS_pool_get_array(biogeochemistry, "oceanHumicsFlux", oceanHumicsFlux) call MPAS_pool_get_array(biogeochemistry, "oceanDustIronFlux", oceanDustIronFlux) + call MPAS_pool_get_array(biogeochemistry, "oceanBlackCarbonFlux", oceanBlackCarbonFlux) call MPAS_pool_get_array(biogeochemistry, "oceanBioFluxes", oceanBioFluxes) call MPAS_pool_get_array(biogeochemistry, "oceanAlgaeFlux", oceanAlgaeFlux) call MPAS_pool_get_array(biogeochemistry, "oceanDOCFlux", oceanDOCFlux) @@ -5071,6 +5088,22 @@ subroutine seaice_column_coupling_prep(domain) call MPAS_pool_get_array(biogeochemistry, "oceanDissolvedIronFlux", oceanDissolvedIronFlux) call MPAS_pool_get_array(biogeochemistry, "totalOceanCarbonFlux", totalOceanCarbonFlux) + call MPAS_pool_get_array(biogeochemistry, "oceanNitrateFluxArea", oceanNitrateFluxArea) + call MPAS_pool_get_array(biogeochemistry, "oceanSilicateFluxArea", oceanSilicateFluxArea) + call MPAS_pool_get_array(biogeochemistry, "oceanAmmoniumFluxArea", oceanAmmoniumFluxArea) + call MPAS_pool_get_array(biogeochemistry, "oceanDMSFluxArea", oceanDMSFluxArea) + call MPAS_pool_get_array(biogeochemistry, "oceanDMSPpFluxArea", oceanDMSPpFluxArea) + call MPAS_pool_get_array(biogeochemistry, "oceanDMSPdFluxArea", oceanDMSPdFluxArea) + call MPAS_pool_get_array(biogeochemistry, "oceanHumicsFluxArea", oceanHumicsFluxArea) + call MPAS_pool_get_array(biogeochemistry, "oceanDustIronFluxArea", oceanDustIronFluxArea) + call MPAS_pool_get_array(biogeochemistry, "oceanBlackCarbonFluxArea", oceanBlackCarbonFluxArea) + call MPAS_pool_get_array(biogeochemistry, "oceanAlgaeFluxArea", oceanAlgaeFluxArea) + call MPAS_pool_get_array(biogeochemistry, "oceanDOCFluxArea", oceanDOCFluxArea) + call MPAS_pool_get_array(biogeochemistry, "oceanDICFluxArea", oceanDICFluxArea) + call MPAS_pool_get_array(biogeochemistry, "oceanDONFluxArea", oceanDONFluxArea) + call MPAS_pool_get_array(biogeochemistry, "oceanParticulateIronFluxArea", oceanParticulateIronFluxArea) + call MPAS_pool_get_array(biogeochemistry, "oceanDissolvedIronFluxArea", oceanDissolvedIronFluxArea) + call MPAS_pool_get_dimension(mesh, "nZBGCTracers", nZBGCTracers) call MPAS_pool_get_dimension(mesh, "maxAlgaeType", maxAlgaeType) call MPAS_pool_get_dimension(mesh, "maxDOCType", maxDOCType) @@ -5194,6 +5227,7 @@ subroutine seaice_column_coupling_prep(domain) oceanDMSPdFlux(iCell) = 0.0_RKIND oceanDMSFlux(iCell) = 0.0_RKIND oceanDustIronFlux(iCell) = 0.0_RKIND + oceanBlackCarbonFlux(iCell) = 0.0_RKIND oceanHumicsFlux(iCell) = 0.0_RKIND do iBioTracers = 1, ciceTracerObject % nBioTracers @@ -5206,6 +5240,7 @@ subroutine seaice_column_coupling_prep(domain) do iBioTracers = 1, maxAlgaeType iBioData = iBioData+1 oceanAlgaeFlux(iBioTracers,iCell) = oceanBioFluxesAll(iBioData) + oceanAlgaeFluxArea(iBioTracers,iCell) = oceanBioFluxesAll(iBioData) totalOceanCarbonFlux(iCell) = totalOceanCarbonFlux(iCell) + & oceanAlgaeFlux(iBioTracers,iCell) * ratio_C_to_N(iBioTracers) enddo @@ -5213,11 +5248,13 @@ subroutine seaice_column_coupling_prep(domain) ! Nitrate iBioData = iBioData+1 oceanNitrateFlux(iCell) = oceanBioFluxesAll(iBioData) + oceanNitrateFluxArea(iCell) = oceanBioFluxesAll(iBioData) ! Polysaccharids and Lipids do iBioTracers = 1, maxDOCType iBioData = iBioData+1 oceanDOCFlux(iBioTracers,iCell) = oceanBioFluxesAll(iBioData) + oceanDOCFluxArea(iBioTracers,iCell) = oceanBioFluxesAll(iBioData) totalOceanCarbonFlux(iCell) = totalOceanCarbonFlux(iCell) + & oceanDOCFlux(iBioTracers,iCell) enddo @@ -5226,6 +5263,7 @@ subroutine seaice_column_coupling_prep(domain) do iBioTracers = 1, maxDICType iBioData = iBioData+1 oceanDICFlux(iBioTracers,iCell) = oceanBioFluxesAll(iBioData) + oceanDICFluxArea(iBioTracers,iCell) = oceanBioFluxesAll(iBioData) totalOceanCarbonFlux(iCell) = totalOceanCarbonFlux(iCell) + & oceanDICFlux(iBioTracers,iCell) enddo @@ -5236,22 +5274,27 @@ subroutine seaice_column_coupling_prep(domain) ! Ammonium iBioData = iBioData+1 oceanAmmoniumFlux(iCell) = oceanBioFluxesAll(iBioData) + oceanAmmoniumFluxArea(iCell) = oceanBioFluxesAll(iBioData) ! Silicate iBioData = iBioData+1 oceanSilicateFlux(iCell) = oceanBioFluxesAll(iBioData) + oceanSilicateFluxArea(iCell) = oceanBioFluxesAll(iBioData) ! DMSPp iBioData = iBioData+1 oceanDMSPpFlux(iCell) = oceanBioFluxesAll(iBioData) + oceanDMSPpFluxArea(iCell) = oceanBioFluxesAll(iBioData) ! DMSPd iBioData = iBioData+1 oceanDMSPdFlux(iCell) = oceanBioFluxesAll(iBioData) + oceanDMSPdFluxArea(iCell) = oceanBioFluxesAll(iBioData) ! DMS iBioData = iBioData+1 oceanDMSFlux(iCell) = oceanBioFluxesAll(iBioData) + oceanDMSFluxArea(iCell) = oceanBioFluxesAll(iBioData) ! PON iBioData = iBioData+1 @@ -5260,6 +5303,7 @@ subroutine seaice_column_coupling_prep(domain) do iBioTracers = 1, maxDONType iBioData = iBioData+1 oceanDONFlux(iBioTracers,iCell) = oceanBioFluxesAll(iBioData) + oceanDONFluxArea(iBioTracers,iCell) = oceanBioFluxesAll(iBioData) totalOceanCarbonFlux(iCell) = totalOceanCarbonFlux(iCell) + & oceanDONFlux(iBioTracers,iCell) * config_ratio_C_to_N_proteins enddo @@ -5268,26 +5312,34 @@ subroutine seaice_column_coupling_prep(domain) do iBioTracers = 1, maxIronType iBioData = iBioData+1 oceanDissolvedIronFlux(iBioTracers,iCell) = oceanBioFluxesAll(iBioData) + oceanDissolvedIronFluxArea(iBioTracers,iCell) = oceanBioFluxesAll(iBioData) enddo ! Particulate Iron do iBioTracers = 1, maxIronType iBioData = iBioData+1 oceanParticulateIronFlux(iBioTracers,iCell) = oceanBioFluxesAll(iBioData) + oceanParticulateIronFluxArea(iBioTracers,iCell) = oceanBioFluxesAll(iBioData) enddo - ! Black Carbon (not saved) - iBioData = iBioData + maxBCType + ! Black Carbon (combined; saved for conservation) + do iBioTracers = 1, maxBCType + iBioData = iBioData + 1 + oceanBlackCarbonFlux(iCell) = oceanBlackCarbonFlux(iCell) + oceanBioFluxesAll(iBioData) + enddo + oceanBlackCarbonFluxArea(iCell) = oceanBlackCarbonFlux(iCell) ! Dust (combined) do iBioTracers = 1, maxDustType iBioData = iBioData+1 oceanDustIronFlux(iCell) = oceanDustIronFlux(iCell) + oceanBioFluxesAll(iBioData) enddo + oceanDustIronFluxArea(iCell) = oceanDustIronFlux(iCell) ! Humics iBioData = iBioData+1 oceanHumicsFlux(iCell) = oceanBioFluxesAll(iBioData) + oceanHumicsFluxArea(iCell) = oceanBioFluxesAll(iBioData) totalOceanCarbonFlux(iCell) = totalOceanCarbonFlux(iCell) + & oceanHumicsFlux(iCell) diff --git a/components/mpas-seaice/src/shared/mpas_seaice_icepack.F b/components/mpas-seaice/src/shared/mpas_seaice_icepack.F index 05e6f98f3375..8255e731586f 100644 --- a/components/mpas-seaice/src/shared/mpas_seaice_icepack.F +++ b/components/mpas-seaice/src/shared/mpas_seaice_icepack.F @@ -1256,7 +1256,8 @@ end subroutine seaice_icepack_postdynamics_time_integration subroutine column_vertical_thermodynamics(domain, clock) use icepack_intfc, only: & - icepack_step_therm1 + icepack_step_therm1, & + icepack_warnings_clear use seaice_constants, only: & seaicePuny @@ -1690,14 +1691,18 @@ subroutine column_vertical_thermodynamics(domain, clock) endif ! code abort - abortFlag = .false. - abortMessage = "" + !abortFlag = .false. + !abortMessage = "" - !$omp parallel do default(shared) private(iCategory,iAerosol,northernHemisphereMask,& - !$omp& abortMessage) firstprivate(specificSnowAerosol,specificIceAerosol) & - !$omp& reduction(.or.:abortFlag) + !$offomp parallel do default(shared) private(iCategory,iAerosol,northernHemisphereMask,& + !$offomp& abortMessage) firstprivate(specificSnowAerosol,specificIceAerosol) + !$offomp& reduction(.or.:abortFlag) do iCell = 1, nCellsSolve + ! code abort + abortFlag = .false. + abortMessage = "" + ! initial state values iceAreaCellInitial(iCell) = iceAreaCell(iCell) @@ -1737,6 +1742,7 @@ subroutine column_vertical_thermodynamics(domain, clock) northernHemisphereMask = .false. endif + call icepack_warnings_clear() call icepack_step_therm1(& dt=config_dt, & ncat=nCategories, & @@ -1871,6 +1877,7 @@ subroutine column_vertical_thermodynamics(domain, clock) frz_onset=freezeOnset(iCell), & yday=dayOfYear, & prescribed_ice=config_use_prescribed_ice) + abortFlag = icepack_warnings_aborted() call seaice_icepack_write_warnings(abortFlag) @@ -2059,7 +2066,6 @@ subroutine column_vertical_thermodynamics(domain, clock) enddo ! iCategory endif - enddo ! iCell ! error-checking @@ -2203,27 +2209,16 @@ subroutine column_itd_thermodynamics(domain, clock) iBioData, & iBioLayers - ! test carbon conservation real(kind=RKIND), dimension(:,:), allocatable :: & - totalCarbonCatFinal, & - totalCarbonCatInitial, & oceanBioFluxesTemp - real(kind=RKIND), dimension(:), allocatable :: & - verticalGridSpace, & - totalCarbonFinal, & - totalCarbonInitial, & - oceanCarbonFlux, & - carbonError - logical, dimension(:), allocatable :: & newlyFormedIceLogical logical :: & abortFlag, & setGetPhysicsTracers, & - setGetBGCTracers, & - checkCarbon + setGetBGCTracers character(len=strKIND) :: & abortMessage, & @@ -2235,8 +2230,6 @@ subroutine column_itd_thermodynamics(domain, clock) ! day of year call get_day_of_year(clock, dayOfYear) - checkCarbon = .false. - block => domain % blocklist do while (associated(block)) @@ -2333,27 +2326,6 @@ subroutine column_itd_thermodynamics(domain, clock) ! newly formed ice allocate(newlyFormedIceLogical(nCategories)) allocate(oceanBioFluxesTemp(ciceTracerObject % nBioTracers,nCellsSolve)) - allocate(verticalGridSpace(nBioLayersP1)) - if (checkCarbon) then - allocate(totalCarbonCatFinal(nCategories,nCellsSolve)) - allocate(totalCarbonCatInitial(nCategories,nCellsSolve)) - allocate(totalCarbonInitial(nCellsSolve)) - allocate(totalCarbonFinal(nCellsSolve)) - allocate(oceanCarbonFlux(nCellsSolve)) - allocate(carbonError(nCellsSolve)) - else - allocate(totalCarbonCatFinal(1,1)) - allocate(totalCarbonCatInitial(1,1)) - allocate(totalCarbonInitial(1)) - allocate(totalCarbonFinal(1)) - allocate(oceanCarbonFlux(1)) - allocate(carbonError(1)) - endif - - verticalGridSpace(:) = 1.0_RKIND/real(nBioLayers,kind=RKIND) - verticalGridSpace(1) = verticalGridSpace(1)/2.0_RKIND - verticalGridSpace(nBioLayersP1) = verticalGridSpace(1) - setGetPhysicsTracers = .true. setGetBGCTracers = (config_use_column_biogeochemistry .or. config_use_zaerosols) @@ -2385,14 +2357,6 @@ subroutine column_itd_thermodynamics(domain, clock) call set_cice_tracer_array_category(block, ciceTracerObject,& tracerArrayCategory, iCell, setGetPhysicsTracers, setGetBGCTracers) - if (checkCarbon) then - totalCarbonInitial(iCell) = 0.0_RKIND - call seaice_total_carbon_content_category(block,totalCarbonCatInitial(:,iCell),iceAreaCategory(1,:,:),iceVolumeCategory(1,:,:),iCell) - do iCategory = 1,nCategories - totalCarbonInitial(iCell) = totalCarbonInitial(iCell) + totalCarbonCatInitial(iCategory,iCell)*iceAreaCategory(1,iCategory,iCell) - enddo - endif - oceanBioFluxesTemp(:,iCell) = 0.0_RKIND ! CICE calculates the Sig Wave Height from the wave spectrum as follows before step therm2: @@ -2464,9 +2428,6 @@ subroutine column_itd_thermodynamics(domain, clock) oceanBioFluxes(iBioTracers,iCell) = oceanBioFluxes(iBioTracers,iCell) + oceanBioFluxesTemp(iBioTracers,iCell) enddo - abortFlag = icepack_warnings_aborted() - call seaice_icepack_write_warnings(abortFlag) - ! update do iCategory = 1, nCategories newlyFormedIce(iCategory,iCell) = 0 @@ -2477,41 +2438,13 @@ subroutine column_itd_thermodynamics(domain, clock) call get_cice_tracer_array_category(block, ciceTracerObject, & tracerArrayCategory, iCell, setGetPhysicsTracers, setGetBGCTracers) - if (checkCarbon) then - totalCarbonFinal(iCell) = 0.0_RKIND - call seaice_total_carbon_content_category(block,totalCarbonCatFinal(:,iCell),iceAreaCategory(1,:,:),iceVolumeCategory(1,:,:),iCell) - call seaice_ocean_carbon_flux_cell(block,oceanCarbonFlux(iCell),oceanBioFluxesTemp(:,iCell)) - do iCategory = 1,nCategories - totalCarbonFinal(iCell) = totalCarbonFinal(iCell) + totalCarbonCatFinal(iCategory,iCell)*iceAreaCategory(1,iCategory,iCell) - enddo - carbonError(iCell) = (totalCarbonFinal(iCell) - totalCarbonInitial(iCell))/config_dt + oceanCarbonFlux(iCell) - - if (abs(carbonError(iCell)) > max(seaicePuny,1.0e-14_RKIND*abs(oceanCarbonFlux(iCell)))) then - call mpas_log_write("column_step_therm2, carbon conservation error", messageType=MPAS_LOG_ERR) - call mpas_log_write("iCell: $i", messageType=MPAS_LOG_ERR, intArgs=(/indexToCellID(iCell)/)) - call mpas_log_write("carbonError: $r", messageType=MPAS_LOG_ERR, realArgs=(/carbonError(iCell)/)) - call mpas_log_write("totalCarbonInitial: $r", messageType=MPAS_LOG_ERR, realArgs=(/totalCarbonInitial(iCell)/)) - call mpas_log_write("totalCarbonFinal: $r", messageType=MPAS_LOG_ERR, realArgs=(/totalCarbonFinal(iCell)/)) - call mpas_log_write("oceanCarbonFlux: $r", messageType=MPAS_LOG_ERR, realArgs=(/oceanCarbonFlux(iCell)/)) - call mpas_log_write("config_dt: $r", messageType=MPAS_LOG_ERR, realArgs=(/config_dt/)) - - do iCategory = 1, nCategories - call mpas_log_write("iCategory: $i", messageType=MPAS_LOG_ERR, intArgs=(/iCategory/)) - call mpas_log_write("totalCarbonCatFinal(iCategory,iCell): $r", messageType=MPAS_LOG_ERR, realArgs=(/totalCarbonCatFinal(iCategory,iCell)/)) - call mpas_log_write("totalCarbonCatInitial(iCategory,iCell): $r", messageType=MPAS_LOG_ERR, realArgs=(/totalCarbonCatInitial(iCategory,iCell)/)) - call mpas_log_write("iceAreaCategoryInitial(iCategory,iCell): $r", messageType=MPAS_LOG_ERR, realArgs=(/iceAreaCategoryInitial(iCategory,iCell)/)) - call mpas_log_write("iceVolumeCategoryInitial(iCategory,iCell): $r", messageType=MPAS_LOG_ERR, realArgs=(/iceVolumeCategoryInitial(iCategory,iCell)/)) - call mpas_log_write("iceAreaCategory(1,iCategory,iCell): $r", messageType=MPAS_LOG_ERR, realArgs=(/iceAreaCategory(1,iCategory,iCell)/)) - call mpas_log_write("iceVolumeCategory(1,iCategory,iCell): $r", messageType=MPAS_LOG_ERR, realArgs=(/iceVolumeCategory(1,iCategory,iCell)/)) - enddo - endif - endif - + abortFlag = icepack_warnings_aborted() ! cell-specific abort message if (abortFlag) then call mpas_log_write("column_itd_thermodynamics: "//trim(abortMessage) , messageType=MPAS_LOG_ERR) call mpas_log_write("iCell: $i", messageType=MPAS_LOG_ERR, intArgs=(/indexToCellID(iCell)/)) endif + call seaice_icepack_write_warnings(abortFlag) enddo ! iCell @@ -2519,17 +2452,9 @@ subroutine column_itd_thermodynamics(domain, clock) call seaice_critical_error_write_block(domain, block, abortFlag) call seaice_check_critical_error(domain, abortFlag) - deallocate(totalCarbonCatFinal) - deallocate(totalCarbonCatInitial) - deallocate(totalCarbonInitial) - deallocate(totalCarbonFinal) - deallocate(oceanCarbonFlux) - deallocate(carbonError) - ! newly formed ice deallocate(newlyFormedIceLogical) deallocate(oceanBioFluxesTemp) - deallocate(verticalGridSpace) block => block % next end do @@ -3041,11 +2966,6 @@ subroutine column_radiation(domain, clock, lInitialization) iAerosol, & iBioTracers - integer, dimension(:), allocatable :: & - index_shortwaveAerosol, & - index_verticalAerosolsConc, & - index_algaeConc - real(kind=RKIND) :: & dayOfYear, & lonCellColumn @@ -3163,28 +3083,6 @@ subroutine column_radiation(domain, clock, lInitialization) ! aerosols array allocate(aerosolsArray(4*nAerosols,nCategories)) - allocate(index_shortwaveAerosol(maxAerosolType)) - allocate(index_verticalAerosolsConc(maxAerosolType)) - allocate(index_algaeConc(nAlgae)) - - if (.not. config_use_zaerosols) then - index_shortwaveAerosol(1:maxAerosolType) = 1 - index_verticalAerosolsConc(1:maxAerosolType) = 1 - else - do iAerosol = 1, maxAerosolType - index_shortwaveAerosol(iAerosol) = ciceTracerObject % index_verticalAerosolsConcShortwave(iAerosol) - index_verticalAerosolsConc(iAerosol) = ciceTracerObject % index_verticalAerosolsConc(iAerosol) - enddo - endif - - if (.not. config_use_column_biogeochemistry) then - index_algaeConc(1:nAlgae) = 1 - else - do iBioTracers = 1, nAlgae - index_algaeConc(iBioTracers) = ciceTracerObject % index_algaeConc(iBioTracers) - enddo - endif - setGetPhysicsTracers = .true. setGetBGCTracers = (config_use_column_biogeochemistry .or. config_use_zaerosols) @@ -3192,7 +3090,7 @@ subroutine column_radiation(domain, clock, lInitialization) allocate(snow_grain_radius(nSnowLayers,nCategories)) !$omp parallel do default(shared) & - !$omp& firstprivate(aerosolsArray,index_shortwaveAerosol,snow_grain_radius) & + !$omp& firstprivate(aerosolsArray,snow_grain_radius) & !$omp& private(iCategory,iAerosol,lonCellColumn,iSnowLayer) do iCell = 1, nCellsSolve @@ -3282,9 +3180,6 @@ subroutine column_radiation(domain, clock, lInitialization) ! aerosols array deallocate(aerosolsArray) - deallocate(index_shortwaveAerosol) - deallocate(index_verticalAerosolsConc) - deallocate(index_algaeConc) block => block % next end do @@ -3404,29 +3299,15 @@ subroutine column_ridging(domain) iBioData, & iBioLayers - ! test carbon conservation real(kind=RKIND), dimension(:,:), allocatable :: & - totalCarbonCatFinal, & - totalCarbonCatInitial, & oceanBioFluxesTemp - real(kind=RKIND), dimension(:), allocatable :: & - verticalGridSpace, & - totalCarbonFinal, & - totalCarbonInitial, & - oceanCarbonFlux, & - carbonError, & - iceAreaCategoryInitial - logical, dimension(:), allocatable :: & newlyFormedIceLogical logical :: & setGetPhysicsTracers, & - setGetBGCTracers, & - checkCarbon - - checkCarbon = .false. + setGetBGCTracers block => domain % blocklist do while (associated(block)) @@ -3507,28 +3388,6 @@ subroutine column_ridging(domain) setGetBGCTracers = (config_use_column_biogeochemistry .or. config_use_zaerosols) allocate(oceanBioFluxesTemp(ciceTracerObject % nBioTracers,nCellsSolve)) - allocate(verticalGridSpace(nBioLayersP1)) - if (checkCarbon) then - allocate(totalCarbonCatFinal(nCategories,nCellsSolve)) - allocate(totalCarbonCatInitial(nCategories,nCellsSolve)) - allocate(totalCarbonInitial(nCellsSolve)) - allocate(totalCarbonFinal(nCellsSolve)) - allocate(oceanCarbonFlux(nCellsSolve)) - allocate(carbonError(nCellsSolve)) - allocate(iceAreaCategoryInitial(nCategories)) - else - allocate(totalCarbonCatFinal(1,1)) - allocate(totalCarbonCatInitial(1,1)) - allocate(totalCarbonInitial(1)) - allocate(totalCarbonFinal(1)) - allocate(oceanCarbonFlux(1)) - allocate(carbonError(1)) - allocate(iceAreaCategoryInitial(1)) - endif - - verticalGridSpace(:) = 1.0_RKIND/real(nBioLayers,kind=RKIND) - verticalGridSpace(1) = verticalGridSpace(1)/2.0_RKIND - verticalGridSpace(nBioLayersP1) = verticalGridSpace(1) do iCell = 1, nCellsSolve @@ -3541,15 +3400,6 @@ subroutine column_ridging(domain) call set_cice_tracer_array_category(block, ciceTracerObject, & tracerArrayCategory, iCell, setGetPhysicsTracers, setGetBGCTracers) - if (checkCarbon) then - totalCarbonInitial(iCell) = 0.0_RKIND - call seaice_total_carbon_content_category(block,totalCarbonCatInitial(:,iCell),iceAreaCategory(1,:,:),iceVolumeCategory(1,:,:),iCell) - do iCategory = 1,nCategories - iceAreaCategoryInitial(iCategory) = iceAreaCategory(1,iCategory,iCell) - totalCarbonInitial(iCell) = totalCarbonInitial(iCell) + totalCarbonCatInitial(iCategory,iCell)*iceAreaCategory(1,iCategory,iCell) - enddo - endif - oceanBioFluxesTemp(:,iCell) = 0.0_RKIND call icepack_step_ridge(& @@ -3609,53 +3459,12 @@ subroutine column_ridging(domain) call get_cice_tracer_array_category(block, ciceTracerObject, & tracerArrayCategory, iCell, setGetPhysicsTracers, setGetBGCTracers) - if (checkCarbon) then - totalCarbonFinal(iCell) = 0.0_RKIND - call seaice_total_carbon_content_category(block,totalCarbonCatFinal(:,iCell),iceAreaCategory(1,:,:),iceVolumeCategory(1,:,:),iCell) - call seaice_ocean_carbon_flux_cell(block,oceanCarbonFlux(iCell),oceanBioFluxesTemp(:,iCell)) - do iCategory = 1,nCategories - totalCarbonFinal(iCell) = totalCarbonFinal(iCell) + totalCarbonCatFinal(iCategory,iCell)*iceAreaCategory(1,iCategory,iCell) - enddo - carbonError(iCell) = (totalCarbonFinal(iCell) - totalCarbonInitial(iCell))/config_dt + oceanCarbonFlux(iCell) - - if (abs(carbonError(iCell)) > max(10.0_RKIND*seaicePuny,1.0e-14_RKIND*abs(oceanCarbonFlux(iCell))) .and. & - MAXVAL(iceAreaCategory(1,:,iCell)) > seaicePuny .and. & - MAXVAL(iceAreaCategoryInitial(:)) > seaicePuny) then - call mpas_log_write("icepack_step_ridge, carbon conservation error", messageType=MPAS_LOG_ERR) - call mpas_log_write("iCell: $i", messageType=MPAS_LOG_ERR, intArgs=(/indexToCellID(iCell)/)) - call mpas_log_write("carbonError: $r", messageType=MPAS_LOG_ERR, realArgs=(/carbonError(iCell)/)) - call mpas_log_write("totalCarbonInitial: $r", messageType=MPAS_LOG_ERR, realArgs=(/totalCarbonInitial(iCell)/)) - call mpas_log_write("totalCarbonFinal: $r", messageType=MPAS_LOG_ERR, realArgs=(/totalCarbonFinal(iCell)/)) - call mpas_log_write("oceanCarbonFlux: $r", messageType=MPAS_LOG_ERR, realArgs=(/oceanCarbonFlux(iCell)/)) - call mpas_log_write("config_dt: $r", messageType=MPAS_LOG_ERR, realArgs=(/config_dt/)) - - do iCategory = 1, nCategories - call mpas_log_write("iCategory: $i", messageType=MPAS_LOG_ERR, intArgs=(/iCategory/)) - call mpas_log_write("totalCarbonCatFinal(iCategory,iCell): $r", messageType=MPAS_LOG_ERR, realArgs=(/totalCarbonCatFinal(iCategory,iCell)/)) - call mpas_log_write("totalCarbonCatInitial(iCategory,iCell): $r", messageType=MPAS_LOG_ERR, realArgs=(/totalCarbonCatInitial(iCategory,iCell)/)) - call mpas_log_write("iceAreaCategory(1,iCategory,iCell): $r", messageType=MPAS_LOG_ERR, realArgs=(/iceAreaCategory(1,iCategory,iCell)/)) - call mpas_log_write("iceAreaCategoryInitial(iCategory): $r", messageType=MPAS_LOG_ERR, realArgs=(/iceAreaCategoryInitial(iCategory)/)) - call mpas_log_write("iceVolumeCategory(1,iCategory,iCell): $r", messageType=MPAS_LOG_ERR, realArgs=(/iceVolumeCategory(1,iCategory,iCell)/)) - enddo - endif - endif - + call seaice_icepack_write_warnings(icepack_warnings_aborted()) enddo ! iCell - call seaice_icepack_write_warnings(icepack_warnings_aborted()) -! check carbon - deallocate(oceanBioFluxesTemp) - deallocate(verticalGridSpace) - deallocate(totalCarbonCatFinal) - deallocate(totalCarbonCatInitial) - deallocate(totalCarbonInitial) - deallocate(totalCarbonFinal) - deallocate(oceanCarbonFlux) - deallocate(carbonError) - deallocate(iceAreaCategoryInitial) - ! newly formed ice deallocate(newlyFormedIceLogical) + deallocate(oceanBioFluxesTemp) block => block % next end do @@ -3984,9 +3793,9 @@ subroutine column_biogeochemistry(domain) ! newly formed ice allocate(newlyFormedIceLogical(nCategories)) allocate(brineHeightCatInitial(nCategories,nCellsSolve)) - allocate(carbonError(nCellsSolve)) if (checkCarbon) then + allocate(carbonError(nCellsSolve)) allocate(totalCarbonCatFinal(nCategories,nCellsSolve)) allocate(totalCarbonCatInitial(nCategories,nCellsSolve)) allocate(totalCarbonCatFlux(nCategories,nCellsSolve)) @@ -3995,6 +3804,7 @@ subroutine column_biogeochemistry(domain) allocate(totalCarbonInitial(nCellsSolve)) allocate(totalCarbonFlux(nCellsSolve)) else + allocate(carbonError(1)) allocate(totalCarbonCatFinal(1,1)) allocate(totalCarbonCatInitial(1,1)) allocate(totalCarbonCatFlux(1,1)) @@ -4153,7 +3963,6 @@ subroutine column_biogeochemistry(domain) bioTemperatureIceCell=bgridTemperatureIceCell(:,iCell)) abortFlag = icepack_warnings_aborted() - call seaice_icepack_write_warnings(abortFlag) call get_cice_tracer_array_category(block, ciceTracerObject, & tracerArrayCategory, iCell, setGetPhysicsTracers, setGetBGCTracers) @@ -4215,13 +4024,16 @@ subroutine column_biogeochemistry(domain) if (newlyFormedIceLogical(iCategory)) newlyFormedIce(iCategory,iCell) = 1 enddo ! iCategory + ! code abort + if (abortFlag) then + call mpas_log_write("column_biogeochemistry: "//trim(abortMessage) , messageType=MPAS_LOG_ERR) + call mpas_log_write("iCell: $i", messageType=MPAS_LOG_ERR, intArgs=(/indexToCellID(iCell)/)) + endif + + call seaice_icepack_write_warnings(abortFlag) + enddo ! iCell - ! code abort - if (abortFlag) then - call mpas_log_write("column_biogeochemistry: "//trim(abortMessage) , messageType=MPAS_LOG_ERR) - call mpas_log_write("iCell: $i", messageType=MPAS_LOG_ERR, intArgs=(/indexToCellID(iCell)/)) - endif call seaice_critical_error_write_block(domain, block, abortFlag) call seaice_check_critical_error(domain, abortFlag) @@ -4232,10 +4044,10 @@ subroutine column_biogeochemistry(domain) deallocate(totalCarbonFinal) deallocate(totalCarbonInitial) deallocate(totalCarbonFlux) + deallocate(carbonError) deallocate(brineHeightCatInitial) deallocate(newlyFormedIceLogical) - deallocate(carbonError) block => block % next end do @@ -4531,6 +4343,9 @@ subroutine seaice_icepack_aggregate(domain) nCellsSolve, & nCategories + integer, dimension(:), pointer :: & + indexToCellID + logical :: & setGetPhysicsTracers, & setGetBGCTracers @@ -4549,6 +4364,7 @@ subroutine seaice_icepack_aggregate(domain) call MPAS_pool_get_dimension(mesh, "nCellsSolve", nCellsSolve) call MPAS_pool_get_dimension(mesh, "nCategories", nCategories) + call MPAS_pool_get_array(mesh, "indexToCellID", indexToCellID) call MPAS_pool_get_array(tracers, "iceAreaCategory", iceAreaCategory, 1) call MPAS_pool_get_array(tracers, "iceVolumeCategory", iceVolumeCategory, 1) @@ -4765,7 +4581,16 @@ subroutine seaice_icepack_coupling_prep(domain) oceanHumicsFlux, & oceanDustIronFlux, & oceanBlackCarbonFlux, & - totalOceanCarbonFlux + totalOceanCarbonFlux, & + oceanNitrateFluxArea, & + oceanSilicateFluxArea, & + oceanAmmoniumFluxArea, & + oceanDMSFluxArea, & + oceanDMSPpFluxArea, & + oceanDMSPdFluxArea, & + oceanHumicsFluxArea, & + oceanDustIronFluxArea, & + oceanBlackCarbonFluxArea real(kind=RKIND), dimension(:,:), pointer :: & albedoVisibleDirectCategory, & @@ -4782,7 +4607,13 @@ subroutine seaice_icepack_coupling_prep(domain) oceanDICFlux, & oceanDONFlux, & oceanParticulateIronFlux, & - oceanDissolvedIronFlux + oceanDissolvedIronFlux, & + oceanAlgaeFluxArea, & + oceanDOCFluxArea, & + oceanDICFluxArea, & + oceanDONFluxArea, & + oceanParticulateIronFluxArea, & + oceanDissolvedIronFluxArea real(kind=RKIND), dimension(:,:,:), pointer :: & iceAreaCategory @@ -4915,6 +4746,22 @@ subroutine seaice_icepack_coupling_prep(domain) call MPAS_pool_get_array(biogeochemistry, "oceanDissolvedIronFlux", oceanDissolvedIronFlux) call MPAS_pool_get_array(biogeochemistry, "totalOceanCarbonFlux", totalOceanCarbonFlux) + call MPAS_pool_get_array(biogeochemistry, "oceanNitrateFluxArea", oceanNitrateFluxArea) + call MPAS_pool_get_array(biogeochemistry, "oceanSilicateFluxArea", oceanSilicateFluxArea) + call MPAS_pool_get_array(biogeochemistry, "oceanAmmoniumFluxArea", oceanAmmoniumFluxArea) + call MPAS_pool_get_array(biogeochemistry, "oceanDMSFluxArea", oceanDMSFluxArea) + call MPAS_pool_get_array(biogeochemistry, "oceanDMSPpFluxArea", oceanDMSPpFluxArea) + call MPAS_pool_get_array(biogeochemistry, "oceanDMSPdFluxArea", oceanDMSPdFluxArea) + call MPAS_pool_get_array(biogeochemistry, "oceanHumicsFluxArea", oceanHumicsFluxArea) + call MPAS_pool_get_array(biogeochemistry, "oceanDustIronFluxArea", oceanDustIronFluxArea) + call MPAS_pool_get_array(biogeochemistry, "oceanBlackCarbonFluxArea", oceanBlackCarbonFluxArea) + call MPAS_pool_get_array(biogeochemistry, "oceanAlgaeFluxArea", oceanAlgaeFluxArea) + call MPAS_pool_get_array(biogeochemistry, "oceanDOCFluxArea", oceanDOCFluxArea) + call MPAS_pool_get_array(biogeochemistry, "oceanDICFluxArea", oceanDICFluxArea) + call MPAS_pool_get_array(biogeochemistry, "oceanDONFluxArea", oceanDONFluxArea) + call MPAS_pool_get_array(biogeochemistry, "oceanParticulateIronFluxArea", oceanParticulateIronFluxArea) + call MPAS_pool_get_array(biogeochemistry, "oceanDissolvedIronFluxArea", oceanDissolvedIronFluxArea) + call MPAS_pool_get_dimension(mesh, "nZBGCTracers", nZBGCTracers) call MPAS_pool_get_dimension(mesh, "maxAlgaeType", maxAlgaeType) call MPAS_pool_get_dimension(mesh, "maxDOCType", maxDOCType) @@ -5051,6 +4898,7 @@ subroutine seaice_icepack_coupling_prep(domain) do iBioTracers = 1, maxAlgaeType iBioData = iBioData+1 oceanAlgaeFlux(iBioTracers,iCell) = oceanBioFluxesAll(iBioData) + oceanAlgaeFluxArea(iBioTracers,iCell) = oceanBioFluxesAll(iBioData) totalOceanCarbonFlux(iCell) = totalOceanCarbonFlux(iCell) + & oceanAlgaeFlux(iBioTracers,iCell) * ratio_C_to_N(iBioTracers) enddo @@ -5058,11 +4906,13 @@ subroutine seaice_icepack_coupling_prep(domain) ! Nitrate iBioData = iBioData+1 oceanNitrateFlux(iCell) = oceanBioFluxesAll(iBioData) + oceanNitrateFluxArea(iCell) = oceanBioFluxesAll(iBioData) ! Polysaccharids and Lipids do iBioTracers = 1, maxDOCType iBioData = iBioData+1 oceanDOCFlux(iBioTracers,iCell) = oceanBioFluxesAll(iBioData) + oceanDOCFluxArea(iBioTracers,iCell) = oceanBioFluxesAll(iBioData) totalOceanCarbonFlux(iCell) = totalOceanCarbonFlux(iCell) + & oceanDOCFlux(iBioTracers,iCell) enddo @@ -5071,6 +4921,7 @@ subroutine seaice_icepack_coupling_prep(domain) do iBioTracers = 1, maxDICType iBioData = iBioData+1 oceanDICFlux(iBioTracers,iCell) = oceanBioFluxesAll(iBioData) + oceanDICFluxArea(iBioTracers,iCell) = oceanBioFluxesAll(iBioData) totalOceanCarbonFlux(iCell) = totalOceanCarbonFlux(iCell) + & oceanDICFlux(iBioTracers,iCell) enddo @@ -5081,22 +4932,27 @@ subroutine seaice_icepack_coupling_prep(domain) ! Ammonium iBioData = iBioData+1 oceanAmmoniumFlux(iCell) = oceanBioFluxesAll(iBioData) + oceanAmmoniumFluxArea(iCell) = oceanBioFluxesAll(iBioData) ! Silicate iBioData = iBioData+1 oceanSilicateFlux(iCell) = oceanBioFluxesAll(iBioData) + oceanSilicateFluxArea(iCell) = oceanBioFluxesAll(iBioData) ! DMSPp iBioData = iBioData+1 oceanDMSPpFlux(iCell) = oceanBioFluxesAll(iBioData) + oceanDMSPpFluxArea(iCell) = oceanBioFluxesAll(iBioData) ! DMSPd iBioData = iBioData+1 oceanDMSPdFlux(iCell) = oceanBioFluxesAll(iBioData) + oceanDMSPdFluxArea(iCell) = oceanBioFluxesAll(iBioData) ! DMS iBioData = iBioData+1 oceanDMSFlux(iCell) = oceanBioFluxesAll(iBioData) + oceanDMSFluxArea(iCell) = oceanBioFluxesAll(iBioData) ! PON iBioData = iBioData+1 @@ -5105,6 +4961,7 @@ subroutine seaice_icepack_coupling_prep(domain) do iBioTracers = 1, maxDONType iBioData = iBioData+1 oceanDONFlux(iBioTracers,iCell) = oceanBioFluxesAll(iBioData) + oceanDONFluxArea(iBioTracers,iCell) = oceanBioFluxesAll(iBioData) totalOceanCarbonFlux(iCell) = totalOceanCarbonFlux(iCell) + & oceanDONFlux(iBioTracers,iCell) * config_ratio_C_to_N_proteins enddo @@ -5113,31 +4970,36 @@ subroutine seaice_icepack_coupling_prep(domain) do iBioTracers = 1, maxIronType iBioData = iBioData+1 oceanDissolvedIronFlux(iBioTracers,iCell) = oceanBioFluxesAll(iBioData) + oceanDissolvedIronFluxArea(iBioTracers,iCell) = oceanBioFluxesAll(iBioData) enddo ! Particulate Iron do iBioTracers = 1, maxIronType iBioData = iBioData+1 oceanParticulateIronFlux(iBioTracers,iCell) = oceanBioFluxesAll(iBioData) + oceanParticulateIronFluxArea(iBioTracers,iCell) = oceanBioFluxesAll(iBioData) enddo ! Black Carbon (combined; saved for conservation) do iBioTracers = 1, maxBCType iBioData = iBioData + 1 oceanBlackCarbonFlux(iCell) = oceanBlackCarbonFlux(iCell) + oceanBioFluxesAll(iBioData) - enddo + enddo + oceanBlackCarbonFluxArea(iCell) = oceanBlackCarbonFlux(iCell) ! Dust (combined) do iBioTracers = 1, maxDustType iBioData = iBioData+1 oceanDustIronFlux(iCell) = oceanDustIronFlux(iCell) + oceanBioFluxesAll(iBioData) - enddo + enddo + oceanDustIronFluxArea(iCell) = oceanDustIronFlux(iCell) ! Humics iBioData = iBioData+1 oceanHumicsFlux(iCell) = oceanBioFluxesAll(iBioData) + oceanHumicsFluxArea(iCell) = oceanBioFluxesAll(iBioData) totalOceanCarbonFlux(iCell) = totalOceanCarbonFlux(iCell) + & - oceanHumicsFlux(iCell) + oceanHumicsFlux(iCell) endif ! config_use_column_biogeochemistry .or. config_use_zaerosols @@ -15759,12 +15621,12 @@ subroutine seaice_icepack_write_warnings(logAsErrors) if (logAsErrors) then do iWarning = 1, size(warnings) call mpas_log_write(trim(warnings(iWarning)), messageType=MPAS_LOG_ERR) - enddo ! iWarning + enddo ! iWarning call mpas_log_write("icepack aborted", MPAS_LOG_CRIT) else do iWarning = 1, size(warnings) call mpas_log_write(trim(warnings(iWarning)), messageType=MPAS_LOG_WARN) - enddo ! iWarning + enddo ! iWarning endif call icepack_warnings_clear() From 2305a7dbfd1923929289274a7b9ceb5a582c89c5 Mon Sep 17 00:00:00 2001 From: Nicole Jeffery Date: Fri, 29 Mar 2024 14:29:01 -0500 Subject: [PATCH 077/451] Changed Icepack submodule url Now consistent with E3SM master BFB --- .gitmodules | 1 - 1 file changed, 1 deletion(-) diff --git a/.gitmodules b/.gitmodules index 84c10e97a8c1..69d56e140361 100644 --- a/.gitmodules +++ b/.gitmodules @@ -76,7 +76,6 @@ [submodule "components/mpas-seaice/src/icepack"] path = components/mpas-seaice/src/icepack url = git@github.com:E3SM-Project/Icepack.git - branch = njeffery/merge-fixes-to-bgc [submodule "externals/haero"] path = externals/haero url = git@github.com:eagles-project/haero.git From ebdb83028c0c026a227c038ffdf9279c575bab42 Mon Sep 17 00:00:00 2001 From: Walter Hannah Date: Fri, 29 Mar 2024 14:05:15 -0700 Subject: [PATCH 078/451] revert CRM timestep to 5 sec for MMF2 --- components/eam/cime_config/config_component.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/components/eam/cime_config/config_component.xml b/components/eam/cime_config/config_component.xml index 577c3256db42..784fe44195ed 100755 --- a/components/eam/cime_config/config_component.xml +++ b/components/eam/cime_config/config_component.xml @@ -72,8 +72,8 @@ -crm samxx -crm_dt 10 - -crm pam -pam_dycor spam -crm_dt 8 - -crm pam -pam_dycor awfl -crm_dt 8 + -crm pam -pam_dycor spam -crm_dt 5 + -crm pam -pam_dycor awfl -crm_dt 5 -use_MMF -nlev 60 -crm_nz 50 -crm_dx 2000 -crm_nx 64 -crm_ny 1 -crm_nx_rad 4 -crm_ny_rad 1 -crm_dx 2000 -crm_nx 45 -crm_ny 1 -crm_nx_rad 5 -crm_ny_rad 1 From 63570638abe7c46aa3b74e81dfc0dfb06cdf83a3 Mon Sep 17 00:00:00 2001 From: Nicole Jeffery Date: Sat, 30 Mar 2024 10:22:04 -0500 Subject: [PATCH 079/451] Corrects error in black carbon conservation member Small error introduced in last commit - broke compile BFB --- .../src/analysis_members/mpas_seaice_conservation_check.F | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/components/mpas-seaice/src/analysis_members/mpas_seaice_conservation_check.F b/components/mpas-seaice/src/analysis_members/mpas_seaice_conservation_check.F index ca7811a09679..0dac34ca2407 100644 --- a/components/mpas-seaice/src/analysis_members/mpas_seaice_conservation_check.F +++ b/components/mpas-seaice/src/analysis_members/mpas_seaice_conservation_check.F @@ -2391,7 +2391,7 @@ subroutine black_carbon_conservation(domain, err) nZBGC = nZBGC+1 totalAtmBC2Cell = atmosBlackCarbonFlux(nZBGC,iCell) * areaCell(iCell)* & iceAreaCellInitial(iCell) - totalOceanBlackCarbonCell = oceanBlackCarbonFlux(iCell) * areaCell(iCell) + totalOceanBlackCarbonCell = oceanBlackCarbonFluxArea(iCell) * areaCell(iCell) totalAtmBlackCarbonCell = totalAtmBC1Cell + totalAtmBC2Cell do iHemisphere = 1, nHemispheres From c8339245c735ffd25cd40aae6578f062c09d8a9f Mon Sep 17 00:00:00 2001 From: Alexander Hager Date: Mon, 25 Mar 2024 09:57:30 -0700 Subject: [PATCH 080/451] Enforce waterFluxMask = 2 at domain boundaries Adds requirement that waterFluxMask must equal 2 (no-flow conditions) at domain boundaries. Edges on domain boundaries will automatically have a waterFluxMask set to 2 if not done in input file (warning message will be issued in log file if this occurs). --- .../mode_forward/mpas_li_subglacial_hydro.F | 38 ++++++++++++++----- 1 file changed, 28 insertions(+), 10 deletions(-) diff --git a/components/mpas-albany-landice/src/mode_forward/mpas_li_subglacial_hydro.F b/components/mpas-albany-landice/src/mode_forward/mpas_li_subglacial_hydro.F index cffd631f00b5..25192502b8e1 100644 --- a/components/mpas-albany-landice/src/mode_forward/mpas_li_subglacial_hydro.F +++ b/components/mpas-albany-landice/src/mode_forward/mpas_li_subglacial_hydro.F @@ -2213,9 +2213,11 @@ subroutine calc_hydro_mask(domain) integer, dimension(:), pointer :: hydroTerrestrialMarginMask integer, dimension(:,:), pointer :: cellsOnEdge integer, dimension(:), pointer :: cellMask - integer, pointer :: nEdgesSolve + integer, dimension(:), pointer :: waterFluxMask + integer, pointer :: nEdgesSolve, nCells integer :: cell1, cell2, iEdge real (kind=RKIND), pointer :: config_sea_level + integer :: wfmWarning call mpas_pool_get_config(liConfigs, 'config_sea_level', config_sea_level) @@ -2228,14 +2230,29 @@ subroutine calc_hydro_mask(domain) call mpas_pool_get_array(geometryPool, 'cellMask', cellMask) call mpas_pool_get_array(hydroPool, 'hydroMarineMarginMask', hydroMarineMarginMask) call mpas_pool_get_array(hydroPool, 'hydroTerrestrialMarginMask', hydroTerrestrialMarginMask) + call mpas_pool_get_array(hydroPool, 'waterFluxMask', waterFluxMask) call mpas_pool_get_array(meshPool, 'cellsOnEdge', cellsOnEdge) call mpas_pool_get_dimension(meshPool, 'nEdgesSolve', nEdgesSolve) - + call mpas_pool_get_dimension(meshPool, 'nCells', nCells) + hydroMarineMarginMask(:) = 0 + hydroTerrestrialMarginMask(:) = 0 + wfmWarning = 0 + do iEdge = 1, nEdgesSolve cell1 = cellsOnEdge(1, iEdge) cell2 = cellsOnEdge(2, iEdge) - ! We are looking for edges with 1 edge grounded ice and the other edge floating ice or open ocean + + !ensure no-flow conditions on edges of domain if not set up + !in input file + if ( ((cell1 == nCells + 1) .or. (cell2 == nCells +1 )) & + .and. (waterFluxMask(iEdge) .ne. 2)) then + waterFluxMask(iEdge) = 2 + wfmWarning = 1 + endif + + ! hydroMarineMarginMask: We are looking for edges with 1 edge grounded ice and the other edge floating ice or open ocean + ! Exclude no-flow boundaries if ( (li_mask_is_grounded_ice(cellMask(cell1))) .and. & (li_mask_is_floating_ice(cellMask(cell2)) .or. & ((bedTopography(cell2) < config_sea_level) .and. (.not. li_mask_is_ice(cellMask(cell2)))) ) ) then @@ -2245,13 +2262,9 @@ subroutine calc_hydro_mask(domain) ((bedTopography(cell1) < config_sea_level) .and. (.not. li_mask_is_ice(cellMask(cell1)))) ) ) then hydroMarineMarginMask(iEdge) = 1 endif - enddo - - hydroTerrestrialMarginMask(:) = 0 - do iEdge = 1, nEdgesSolve - cell1 = cellsOnEdge(1, iEdge) - cell2 = cellsOnEdge(2, iEdge) - !Look for edges with 1 cell on grounding ice and the other cell on land without ice + + ! hydroTerrestrialMarginMask: Look for edges with 1 cell on grounding ice and the other cell on land without ice + ! Exclude no-flow boundaries if ((li_mask_is_grounded_ice(cellMask(cell1))) .and. ( .not. li_mask_is_ice(cellMask(cell2))) & .and. (bedTopography(cell2) >= config_sea_level)) then hydroTerrestrialMarginMask(iEdge) = 1 @@ -2264,8 +2277,13 @@ subroutine calc_hydro_mask(domain) block => block % next end do + if (wfmWarning == 1) then + call mpas_log_write('WARNING: Changing waterFluxMask to enforce no-flow conditions at domain boundaries') + endif call mpas_timer_start("halo updates") call mpas_dmpar_field_halo_exch(domain, 'hydroMarineMarginMask') + call mpas_dmpar_field_halo_exch(domain, 'hydroTerrestrialMarginMask') + call mpas_dmpar_field_halo_exch(domain, 'waterFluxMask') call mpas_timer_stop("halo updates") !-------------------------------------------------------------------- From 01a92b7f67beda8105c969b2940d3cc0e23dbbda Mon Sep 17 00:00:00 2001 From: Alexander Hager Date: Tue, 2 Apr 2024 09:15:31 -0600 Subject: [PATCH 081/451] Zero normal gradients at waterFluxMask = 2 Uses waterFluxMaskk=2 to zero out hydropotential and waterPressure normal slopes instead of using exterior domain boundary condition. --- .../src/mode_forward/mpas_li_subglacial_hydro.F | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/components/mpas-albany-landice/src/mode_forward/mpas_li_subglacial_hydro.F b/components/mpas-albany-landice/src/mode_forward/mpas_li_subglacial_hydro.F index 25192502b8e1..48ae15cf3faf 100644 --- a/components/mpas-albany-landice/src/mode_forward/mpas_li_subglacial_hydro.F +++ b/components/mpas-albany-landice/src/mode_forward/mpas_li_subglacial_hydro.F @@ -911,9 +911,7 @@ subroutine calc_edge_quantities(block, err) ! zero gradients at boundaries of the mesh do iEdge = 1, nEdges - cell1 = cellsOnEdge(1, iEdge) - cell2 = cellsOnEdge(2, iEdge) - if ((cell1 == nCells+1) .or. (cell2 == nCells+1)) then + if (waterFluxMask(iEdge) == 2) then hydropotentialBaseSlopeNormal(iEdge) = 0.0_RKIND hydropotentialSlopeNormal(iEdge) = 0.0_RKIND waterPressureSlopeNormal(iEdge) = 0.0_RKIND From a5856def8b5507fb1b54f6ad92ac8ac615aa21ed Mon Sep 17 00:00:00 2001 From: Alexander Hager Date: Tue, 2 Apr 2024 09:47:15 -0600 Subject: [PATCH 082/451] Zero tangent gradients at waterFluxMask = 2 Uses waterFlaskMask==2 as criteria for zeroing out hydropotential tangent slopes along domain boundaries. --- .../mode_forward/mpas_li_subglacial_hydro.F | 24 +++++++++---------- 1 file changed, 11 insertions(+), 13 deletions(-) diff --git a/components/mpas-albany-landice/src/mode_forward/mpas_li_subglacial_hydro.F b/components/mpas-albany-landice/src/mode_forward/mpas_li_subglacial_hydro.F index 48ae15cf3faf..ab4f427e2b1f 100644 --- a/components/mpas-albany-landice/src/mode_forward/mpas_li_subglacial_hydro.F +++ b/components/mpas-albany-landice/src/mode_forward/mpas_li_subglacial_hydro.F @@ -786,8 +786,8 @@ subroutine calc_edge_quantities(block, err) integer, pointer :: nEdges integer, pointer :: nCells integer, pointer :: nVertices - integer :: iEdge, cell1, cell2 integer :: i, j, iVertex, iCell + integer :: iEdge, cell1, cell2 real (kind=RKIND) :: velSign integer :: numGroundedCells integer :: err_tmp @@ -946,7 +946,6 @@ subroutine calc_edge_quantities(block, err) ! contaminated values. call mpas_pool_get_array(meshPool, 'dvEdge', dvEdge) call mpas_pool_get_array(meshPool, 'verticesOnEdge', verticesOnEdge) - call mpas_pool_get_array(meshPool, 'cellsOnVertex', cellsOnVertex) select case (trim(config_SGH_tangent_slope_calculation)) case ('from_vertex_barycentric', 'from_vertex_barycentric_kiteareas') do iEdge = 1, nEdges @@ -960,17 +959,11 @@ subroutine calc_edge_quantities(block, err) hydropotentialBaseSlopeTangent(iEdge) = 0.0_RKIND hydropotentialSlopeTangent(iEdge) = 0.0_RKIND endif - ! check for edges where a vertex is on the edge of the mesh and zero the tangent slope there - do i = 1, 2 - iVertex = verticesOnEdge(i, iEdge) - do j = 1, 3 - iCell = cellsOnVertex(j, iVertex) - if (iCell == nCells + 1) then - hydropotentialBaseSlopeTangent(iEdge) = 0.0_RKIND - hydropotentialSlopeTangent(iEdge) = 0.0_RKIND - endif - enddo - enddo + ! zero tangent slope at waterFluxMask==2 + if (waterFluxMask(iEdge) == 2) then + hydropotentialBaseSlopeTangent(iEdge) = 0.0_RKIND + hydropotentialSlopeTangent(iEdge) = 0.0_RKIND + endif end do ! edges case ('from_normal_slope') ! Do first with hydropotentialBase @@ -985,6 +978,11 @@ subroutine calc_edge_quantities(block, err) hydropotentialBaseSlopeTangent(iEdge) = 0.0_RKIND hydropotentialSlopeTangent(iEdge) = 0.0_RKIND endif + if (waterFluxMask(iEdge) == 2) then + hydropotentialBaseSlopeTangent(iEdge) = 0.0_RKIND + hydropotentialSlopeTangent(iEdge) = 0.0_RKIND + endif + end do ! edges case default call mpas_log_write('Invalid value for config_SGH_tangent_slope_calculation.', MPAS_LOG_ERR) From 684bd0fce66633ab9bd24365d89b6711cf8759f7 Mon Sep 17 00:00:00 2001 From: Alexander Hager Date: Tue, 2 Apr 2024 11:57:19 -0600 Subject: [PATCH 083/451] remove + 1e-30 to gradMagPhiBaseEdge in effectiveConducEdge Removes 1e-30 addition to gradMagPhiBaseEdge when calculating effectiveConducEdge. Allows gradMagPhiBaseEdge to actually be zero when hydropotential slopes are both zero, otherwise this line causes a blow up in effectiveConductEdge. This is now consistent with the way gradMagPhiEdge is used in the channel model --- .../mode_forward/mpas_li_subglacial_hydro.F | 27 +++++++++++++------ 1 file changed, 19 insertions(+), 8 deletions(-) diff --git a/components/mpas-albany-landice/src/mode_forward/mpas_li_subglacial_hydro.F b/components/mpas-albany-landice/src/mode_forward/mpas_li_subglacial_hydro.F index ab4f427e2b1f..a83a35c5d2ac 100644 --- a/components/mpas-albany-landice/src/mode_forward/mpas_li_subglacial_hydro.F +++ b/components/mpas-albany-landice/src/mode_forward/mpas_li_subglacial_hydro.F @@ -1000,16 +1000,27 @@ subroutine calc_edge_quantities(block, err) if (conduc_coeff_drowned > 0.0_RKIND) then ! Use a thickness weighted conductivity coeff. when water thickness exceeds bump height do iEdge = 1, nEdges - conduc_coeff_wtd = (conduc_coeff * min(waterThicknessEdge(iEdge), bedRoughMax) + & - conduc_coeff_drowned * max(waterThicknessEdge(iEdge) - bedRoughMax, 0.0_RKIND)) / & - (waterThicknessEdge(iEdge) + 1.0e-16_RKIND) ! Regularization only applies where value doesn't matter - effectiveConducEdge(iEdge) = conduc_coeff_wtd * waterThicknessEdge(iEdge)**(alpha-1.0_RKIND) * & - (gradMagPhiBaseEdge(iEdge)+1.0e-30_RKIND)**(beta - 2.0_RKIND) ! small value used for regularization + if (gradMagPhiBaseEdge(iEdge) < 0.01_RKIND) then + effectiveConducEdge(iEdge) = 0.0_RKIND + else + conduc_coeff_wtd = (conduc_coeff * min(waterThicknessEdge(iEdge), bedRoughMax) + & + conduc_coeff_drowned * max(waterThicknessEdge(iEdge) - bedRoughMax, 0.0_RKIND)) / & + (waterThicknessEdge(iEdge) + 1.0e-16_RKIND) ! Regularization only applies where value doesn't matter + + effectiveConducEdge(iEdge) = conduc_coeff_wtd * waterThicknessEdge(iEdge)**(alpha-1.0_RKIND) * & + gradMagPhiBaseEdge(iEdge)**(beta - 2.0_RKIND) + endif end do else - ! Just use a single conductivity coeff. - effectiveConducEdge(:) = conduc_coeff * waterThicknessEdge(:)**(alpha-1.0_RKIND) *& - (gradMagPhiBaseEdge(:)+1.0e-30_RKIND)**(beta - 2.0_RKIND) ! small value used for regularization + do iEdge = 1, nEdges + ! Just use a single conductivity coeff. + if (gradMagPhiBaseEdge(iEdge) < 0.01_RKIND) then + effectiveConducEdge(iEdge) = 0.0_RKIND + else + effectiveConducEdge(iEdge) = conduc_coeff * waterThicknessEdge(iEdge)**(alpha-1.0_RKIND) *& + gradMagPhiBaseEdge(iEdge)**(beta - 2.0_RKIND) + endif + enddo endif ! calculate diffusivity on edges From d43658b64f72c8956fae670945cac2244652fa14 Mon Sep 17 00:00:00 2001 From: Alexander Hager Date: Tue, 19 Mar 2024 15:09:15 -0600 Subject: [PATCH 084/451] no margin masks where waterFluxMask=2 Adds logic to calculations of hydroMarineMarginMask and hydroTerrestrialMarginMask so that they are not defined where waterFluxMask = 2. Allows interior of ice sheet to have zero thickness if desired without being counted to either mask. Important for restricting parts of domain to only thawed ice (masking out frozen bed). --- .../src/mode_forward/mpas_li_subglacial_hydro.F | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/components/mpas-albany-landice/src/mode_forward/mpas_li_subglacial_hydro.F b/components/mpas-albany-landice/src/mode_forward/mpas_li_subglacial_hydro.F index a83a35c5d2ac..ec55b53fa0b1 100644 --- a/components/mpas-albany-landice/src/mode_forward/mpas_li_subglacial_hydro.F +++ b/components/mpas-albany-landice/src/mode_forward/mpas_li_subglacial_hydro.F @@ -2221,7 +2221,8 @@ subroutine calc_hydro_mask(domain) integer, dimension(:,:), pointer :: cellsOnEdge integer, dimension(:), pointer :: cellMask integer, dimension(:), pointer :: waterFluxMask - integer, pointer :: nEdgesSolve, nCells + integer, pointer :: nEdgesSolve + integer, pointer :: nCells integer :: cell1, cell2, iEdge real (kind=RKIND), pointer :: config_sea_level integer :: wfmWarning @@ -2262,21 +2263,25 @@ subroutine calc_hydro_mask(domain) ! Exclude no-flow boundaries if ( (li_mask_is_grounded_ice(cellMask(cell1))) .and. & (li_mask_is_floating_ice(cellMask(cell2)) .or. & - ((bedTopography(cell2) < config_sea_level) .and. (.not. li_mask_is_ice(cellMask(cell2)))) ) ) then + ((bedTopography(cell2) < config_sea_level) .and. (.not. li_mask_is_ice(cellMask(cell2)))) ) & + .and. (waterFluxMask(iEdge) .ne. 2) ) then hydroMarineMarginMask(iEdge) = 1 elseif ( (li_mask_is_grounded_ice(cellMask(cell2))) .and. & (li_mask_is_floating_ice(cellMask(cell1)) .or. & - ((bedTopography(cell1) < config_sea_level) .and. (.not. li_mask_is_ice(cellMask(cell1)))) ) ) then + ((bedTopography(cell1) < config_sea_level) .and. (.not. li_mask_is_ice(cellMask(cell1)))) ) & + .and. (waterFluxMask(iEdge) .ne. 2) ) then hydroMarineMarginMask(iEdge) = 1 endif ! hydroTerrestrialMarginMask: Look for edges with 1 cell on grounding ice and the other cell on land without ice ! Exclude no-flow boundaries if ((li_mask_is_grounded_ice(cellMask(cell1))) .and. ( .not. li_mask_is_ice(cellMask(cell2))) & - .and. (bedTopography(cell2) >= config_sea_level)) then + .and. (bedTopography(cell2) >= config_sea_level) & + .and. (waterFluxMask(iEdge) .ne. 2) ) then hydroTerrestrialMarginMask(iEdge) = 1 elseif ((li_mask_is_grounded_ice(cellMask(cell2))) .and. ( .not. li_mask_is_ice(cellMask(cell1))) & - .and. (bedTopography(cell1) >= config_sea_level)) then + .and. (bedTopography(cell1) >= config_sea_level) & + .and. (waterFluxMask(iEdge) .ne. 2) ) then hydroTerrestrialMarginMask(iEdge) = 1 endif enddo From d367aa6536afaa81e7f9e18fe601ab1d54fdec4d Mon Sep 17 00:00:00 2001 From: Alexander Hager Date: Wed, 3 Apr 2024 10:55:18 -0600 Subject: [PATCH 085/451] clean up comment --- .../src/mode_forward/mpas_li_subglacial_hydro.F | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/components/mpas-albany-landice/src/mode_forward/mpas_li_subglacial_hydro.F b/components/mpas-albany-landice/src/mode_forward/mpas_li_subglacial_hydro.F index ec55b53fa0b1..42b76723ff68 100644 --- a/components/mpas-albany-landice/src/mode_forward/mpas_li_subglacial_hydro.F +++ b/components/mpas-albany-landice/src/mode_forward/mpas_li_subglacial_hydro.F @@ -909,7 +909,7 @@ subroutine calc_edge_quantities(block, err) endif ! if edge of grounded ice end do - ! zero gradients at boundaries of the mesh + ! zero gradients at edges that are marked as no flux. These should be applied at boundaries of the mesh. do iEdge = 1, nEdges if (waterFluxMask(iEdge) == 2) then hydropotentialBaseSlopeNormal(iEdge) = 0.0_RKIND From 304eb23b19460affc346625cc7bbf0d445de0ef2 Mon Sep 17 00:00:00 2001 From: Alexander Hager Date: Wed, 3 Apr 2024 11:19:23 -0600 Subject: [PATCH 086/451] Define SMALL_GRADPHI Define private module variable SMALL_GRADPHI, the minimum allowed gradMagPhiEdge or gradMagPhiBaseEdge allowed before all dependent variables are zeroed out. Replaces previous arbitrary threshold of 0.01 --- .../src/mode_forward/mpas_li_subglacial_hydro.F | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/components/mpas-albany-landice/src/mode_forward/mpas_li_subglacial_hydro.F b/components/mpas-albany-landice/src/mode_forward/mpas_li_subglacial_hydro.F index 42b76723ff68..4067e2951437 100644 --- a/components/mpas-albany-landice/src/mode_forward/mpas_li_subglacial_hydro.F +++ b/components/mpas-albany-landice/src/mode_forward/mpas_li_subglacial_hydro.F @@ -56,7 +56,8 @@ module li_subglacial_hydro ! Private module variables ! !-------------------------------------------------------------------- - +! Minimum gradMagPhiBaseEdge and gradMagPhiEdge allowed before all dependent variables are zeroed out +real(kind=RKIND), parameter :: SMALL_GRADPHI = 1.0e-6_RKIND !*********************************************************************** contains @@ -1000,7 +1001,7 @@ subroutine calc_edge_quantities(block, err) if (conduc_coeff_drowned > 0.0_RKIND) then ! Use a thickness weighted conductivity coeff. when water thickness exceeds bump height do iEdge = 1, nEdges - if (gradMagPhiBaseEdge(iEdge) < 0.01_RKIND) then + if (gradMagPhiBaseEdge(iEdge) < SMALL_GRADPHI) then effectiveConducEdge(iEdge) = 0.0_RKIND else conduc_coeff_wtd = (conduc_coeff * min(waterThicknessEdge(iEdge), bedRoughMax) + & @@ -1014,7 +1015,7 @@ subroutine calc_edge_quantities(block, err) else do iEdge = 1, nEdges ! Just use a single conductivity coeff. - if (gradMagPhiBaseEdge(iEdge) < 0.01_RKIND) then + if (gradMagPhiBaseEdge(iEdge) < SMALL_GRADPHI) then effectiveConducEdge(iEdge) = 0.0_RKIND else effectiveConducEdge(iEdge) = conduc_coeff * waterThicknessEdge(iEdge)**(alpha-1.0_RKIND) *& @@ -1809,7 +1810,7 @@ subroutine update_channel(block, err) ! Calculate terms needed for opening (melt) rate - where(gradMagPhiEdge < 0.01_RKIND) + where(gradMagPhiEdge < SMALL_GRADPHI) channelDischarge(:) = 0.0_RKIND elsewhere channelDischarge = -1.0_RKIND * Kc * channelArea**alpha_c * gradMagPhiEdge**(beta_c - 2.0_RKIND) * & @@ -1838,7 +1839,7 @@ subroutine update_channel(block, err) channelVelocity = channelDischarge / (channelArea + 1.0e-12_RKIND) ! diffusivity used only to limit channel dt right now - where(gradMagPhiEdge < 0.01_RKIND) + where(gradMagPhiEdge < SMALL_GRADPHI) channelDiffusivity = 0.0_RKIND elsewhere channelDiffusivity = abs(rho_water * gravity * channelArea * & From 5bb861056c5157d61ba695a2289bf4e586166cb7 Mon Sep 17 00:00:00 2001 From: Alexander Hager Date: Wed, 18 Oct 2023 15:43:31 -0700 Subject: [PATCH 087/451] totalGroundingLineDischargeCell/Edge MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Adds field totalGroundingLineDischargeCell – the total grounding line discharge, extrapolated from the grounding line edge to the adjacent ocean cell. Also introduces totalGroundingLineDischargeEdge – the total grounding line discharge at each edge. For use with MPAS-Ocean --- .../src/Registry_subglacial_hydro.xml | 8 ++- .../mode_forward/mpas_li_subglacial_hydro.F | 63 +++++++++++++++---- 2 files changed, 57 insertions(+), 14 deletions(-) diff --git a/components/mpas-albany-landice/src/Registry_subglacial_hydro.xml b/components/mpas-albany-landice/src/Registry_subglacial_hydro.xml index b70e885eb592..5aa5d66e7bb6 100644 --- a/components/mpas-albany-landice/src/Registry_subglacial_hydro.xml +++ b/components/mpas-albany-landice/src/Registry_subglacial_hydro.xml @@ -230,7 +230,11 @@ description="time step length limited by pressure equation scheme in subglacial hydrology system" /> - + + + - + diff --git a/components/mpas-albany-landice/src/mode_forward/mpas_li_subglacial_hydro.F b/components/mpas-albany-landice/src/mode_forward/mpas_li_subglacial_hydro.F index cffd631f00b5..88c2e4f4cd31 100644 --- a/components/mpas-albany-landice/src/mode_forward/mpas_li_subglacial_hydro.F +++ b/components/mpas-albany-landice/src/mode_forward/mpas_li_subglacial_hydro.F @@ -1718,7 +1718,6 @@ subroutine update_channel(block, err) ! local variables !----------------------------------------------------------------- ! Pools pointers -!! type (mpas_pool_type), pointer :: geometryPool type (mpas_pool_type), pointer :: hydroPool type (mpas_pool_type), pointer :: meshPool type (mpas_pool_type), pointer :: velocityPool @@ -1730,7 +1729,8 @@ subroutine update_channel(block, err) real (kind=RKIND), pointer :: rhoi real (kind=RKIND), pointer :: config_SGH_incipient_channel_width logical, pointer :: config_SGH_include_pressure_melt - + real (kind=RKIND), pointer :: config_SGH_bed_roughness_max + real (kind=RKIND), pointer :: config_sea_level real (kind=RKIND), dimension(:), pointer :: channelArea real (kind=RKIND), dimension(:), pointer :: channelMelt real (kind=RKIND), dimension(:), pointer :: channelPressureFreeze @@ -1747,26 +1747,37 @@ subroutine update_channel(block, err) real (kind=RKIND), dimension(:), pointer :: channelEffectivePressure real (kind=RKIND), dimension(:), pointer :: effectivePressure real (kind=RKIND), dimension(:), pointer :: channelDiffusivity + real (kind=RKIND), dimension(:), pointer :: waterThickness + real (kind=RKIND), dimension(:), pointer :: waterPressure + real (kind=RKIND), dimension(:), pointer :: iceThicknessHydro + real (kind=RKIND), dimension(:), pointer :: totalGroundingLineDischargeCell + real (kind=RKIND), dimension(:), pointer :: totalGroundingLineDischargeEdge + real (kind=RKIND), dimension(:), pointer :: dvEdge + real (kind=RKIND), dimension(:), pointer :: bedTopography integer, dimension(:), pointer :: waterFluxMask integer, dimension(:), pointer :: hydroMarineMarginMask integer, dimension(:), pointer :: edgeMask real (kind=RKIND), dimension(:,:), pointer :: flowParamA integer, dimension(:,:), pointer :: cellsOnEdge integer, pointer :: nVertLevels - - integer, pointer :: nEdgesSolve + real (kind=RKIND), pointer :: config_SGH_max_chnl_lake_depth + character (len=StrKIND), pointer :: config_SGH_inhibit_chnls_on_lakes + real (kind=RKIND), dimension(:), pointer :: xCell + real (kind=RKIND), dimension(:), pointer :: yCell + real (kind=RKIND), dimension(:), pointer :: xEdge + real (kind=RKIND), dimension(:), pointer :: yEdge + integer, dimension(:), pointer :: cellMask + integer, pointer :: nEdgesSolve, nEdges integer :: iEdge, cell1, cell2 - err = 0 ! Get pools things call mpas_pool_get_subpool(block % structs, 'hydro', hydroPool) -! call mpas_pool_get_subpool(block % structs, 'geometry', geometryPool) call mpas_pool_get_subpool(block % structs, 'mesh', meshPool) call mpas_pool_get_subpool(block % structs, 'velocity', velocityPool) call mpas_pool_get_subpool(block % structs, 'geometry', geometryPool) - + call mpas_pool_get_config(liConfigs, 'config_sea_level', config_sea_level) call mpas_pool_get_config(liConfigs, 'config_ice_density', rhoi) call mpas_pool_get_config(liConfigs, 'config_SGH_chnl_conduc_coeff', Kc) call mpas_pool_get_config(liConfigs, 'config_SGH_chnl_alpha', alpha_c) @@ -1774,10 +1785,8 @@ subroutine update_channel(block, err) call mpas_pool_get_config(liConfigs, 'config_SGH_chnl_creep_coefficient', creep_coeff) call mpas_pool_get_config(liConfigs, 'config_SGH_incipient_channel_width', config_SGH_incipient_channel_width) call mpas_pool_get_config(liConfigs, 'config_SGH_include_pressure_melt', config_SGH_include_pressure_melt) - call mpas_pool_get_dimension(meshPool, 'nEdgesSolve', nEdgesSolve) call mpas_pool_get_dimension(meshPool, 'nVertLevels', nVertLevels) - call mpas_pool_get_array(hydroPool, 'channelArea', channelArea) call mpas_pool_get_array(hydroPool, 'channelMelt', channelMelt) call mpas_pool_get_array(hydroPool, 'channelPressureFreeze', channelPressureFreeze) @@ -1799,7 +1808,15 @@ subroutine update_channel(block, err) call mpas_pool_get_array(hydroPool, 'hydroMarineMarginMask', hydroMarineMarginMask) call mpas_pool_get_array(hydroPool, 'channelDiffusivity', channelDiffusivity) call mpas_pool_get_array(geometryPool, 'edgeMask', edgeMask) - + call mpas_pool_get_array(meshPool, 'xCell', xCell) + call mpas_pool_get_array(meshPool, 'yCell', yCell) + call mpas_pool_get_array(meshPool, 'xEdge', xEdge) + call mpas_pool_get_array(meshPool, 'yEdge', yEdge) + call mpas_pool_get_array(meshPool, 'dvEdge', dvEdge) + call mpas_pool_get_array(geometryPool, 'bedTopography', bedTopography) + call mpas_pool_get_array(hydroPool, 'totalGroundingLineDischargeCell', totalGroundingLineDischargeCell) + call mpas_pool_get_array(hydroPool, 'totalGroundingLineDischargeEdge', totalGroundingLineDischargeEdge) + call mpas_pool_get_array(geometryPool, 'cellMask', cellMask) ! Calculate terms needed for opening (melt) rate where(gradMagPhiEdge < 0.01_RKIND) @@ -1867,9 +1884,31 @@ subroutine update_channel(block, err) channelOpeningRate = 0.0_RKIND channelClosingRate = 0.0_RKIND end where + channelChangeRate = channelOpeningRate - channelClosingRate - - + + totalGroundingLineDischargeCell(:) = 0.0_RKIND + totalGroundingLineDischargeEdge(:) = 0.0_RKIND + do iEdge = 1, nEdgesSolve + cell1 = cellsOnEdge(1, iEdge) + cell2 = cellsOnEdge(2, iEdge) + + if (hydroMarineMarginMask(iEdge) == 1) then + ! We are looking for edges with 1 cell grounded ice and the + ! other cell floating ice or open ocean + if ( (li_mask_is_grounded_ice(cellMask(cell1))) .and. & + (li_mask_is_floating_ice(cellMask(cell2)) .or. & + ((bedTopography(cell2) < config_sea_level) .and. (.not. li_mask_is_ice(cellMask(cell2)))) ) ) then + totalGroundingLineDischargeEdge(iEdge) = abs(channelDischarge(iEdge)) +abs( waterFlux(iEdge) * dvEdge(iEdge)) + totalGroundingLineDischargeCell(cell2) = totalGroundingLineDischargeCell(cell2) + totalGroundingLineDischargeEdge(iEdge) + elseif ( (li_mask_is_grounded_ice(cellMask(cell2))) .and. & + (li_mask_is_floating_ice(cellMask(cell1)) .or. & + ((bedTopography(cell1) < config_sea_level) .and. (.not. li_mask_is_ice(cellMask(cell1)))) ) ) then + totalGroundingLineDischargeEdge(iEdge) = abs(channelDischarge(iEdge)) + abs(waterFlux(iEdge) * dvEdge(iEdge)) + totalGroundingLineDischargeCell(cell1) = totalGroundingLineDischargeCell(cell1) + totalGroundingLineDischargeEdge(iEdge) + endif + endif + enddo !-------------------------------------------------------------------- end subroutine update_channel From 7cfb3dd7d6fc8d2b9b1c85f06d61c2481fa5b963 Mon Sep 17 00:00:00 2001 From: Trevor Hillebrand Date: Wed, 3 Apr 2024 19:06:13 -0700 Subject: [PATCH 088/451] Add mask updates between calving routines Update masks before mask calving, between mask calving and iceberg removal, and between iceberg removal and small island removal. --- .../src/mode_forward/mpas_li_calving.F | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/components/mpas-albany-landice/src/mode_forward/mpas_li_calving.F b/components/mpas-albany-landice/src/mode_forward/mpas_li_calving.F index a86612ad00ea..1df2391cdb2c 100644 --- a/components/mpas-albany-landice/src/mode_forward/mpas_li_calving.F +++ b/components/mpas-albany-landice/src/mode_forward/mpas_li_calving.F @@ -305,6 +305,12 @@ subroutine li_calve_ice(domain, err, solveVeloAfterCalving) endif + call mpas_pool_get_subpool(domain % blocklist % structs, 'geometry', geometryPool) + call mpas_pool_get_subpool(domain % blocklist % structs, 'mesh', meshPool) + call mpas_pool_get_subpool(domain % blocklist % structs, 'velocity', velocityPool) + + call li_calculate_mask(meshPool, velocityPool, geometryPool, err_tmp) + ! Consider mask calving as a possible additional step ! Mask calving can occur by itself or in conjunction with a physical calving law if (config_apply_calving_mask) then @@ -312,15 +318,20 @@ subroutine li_calve_ice(domain, err, solveVeloAfterCalving) err = ior(err, err_tmp) endif + call li_calculate_mask(meshPool, velocityPool, geometryPool, err_tmp) + ! now also remove any icebergs call remove_icebergs(domain) + call li_calculate_mask(meshPool, velocityPool, geometryPool, err_tmp) + ! Final operations after calving has been applied, including removal ! of small islands block => domain % blocklist do while (associated(block)) call mpas_pool_get_subpool(block % structs, 'geometry', geometryPool) call mpas_pool_get_subpool(block % structs, 'mesh', meshPool) + call mpas_pool_get_subpool(block % structs, 'velocity', velocityPool) call mpas_pool_get_array(geometryPool, 'thickness', thickness) call mpas_pool_get_array(geometryPool, 'calvingThickness', calvingThickness) call mpas_pool_get_dimension(meshPool, 'nCells', nCells) @@ -350,7 +361,6 @@ subroutine li_calve_ice(domain, err, solveVeloAfterCalving) endif ! config_print_calving_info ! Update mask and geometry - call mpas_pool_get_subpool(block % structs, 'velocity', velocityPool) call li_calculate_mask(meshPool, velocityPool, geometryPool, err_tmp) err = ior(err, err_tmp) call li_update_geometry(geometryPool) From 57a370e11206e87d7a27d5d253147fd58d61c4dd Mon Sep 17 00:00:00 2001 From: Alexander Hager Date: Wed, 27 Mar 2024 09:04:28 -0700 Subject: [PATCH 089/451] Move totalGroundingLineDischargeCell/Edge to subroutine This commit establishes a separate subroutine for calculating totalGroundingLineDischargeCell/Edge --- .../mode_forward/mpas_li_subglacial_hydro.F | 129 +++++++++++++++--- 1 file changed, 107 insertions(+), 22 deletions(-) diff --git a/components/mpas-albany-landice/src/mode_forward/mpas_li_subglacial_hydro.F b/components/mpas-albany-landice/src/mode_forward/mpas_li_subglacial_hydro.F index 88c2e4f4cd31..3da17bdcd986 100644 --- a/components/mpas-albany-landice/src/mode_forward/mpas_li_subglacial_hydro.F +++ b/components/mpas-albany-landice/src/mode_forward/mpas_li_subglacial_hydro.F @@ -551,6 +551,21 @@ subroutine li_SGH_solve(domain, err) call mpas_timer_stop("halo updates") endif + ! ============= + ! Calculate total grounding line discharges + ! ============= + block => domain % blocklist + do while (associated(block)) + + call calc_gl_totals(block, err_tmp) + err = ior(err, err_tmp) + + block => block % next + end do + call mpas_timer_start("halo updates") + call mpas_dmpar_field_halo_exch(domain, 'totalGroundingLineDischargeCell') + call mpas_dmpar_field_halo_exch(domain, 'totalGroundingLineDischargeEdge') + call mpas_timer_stop("halo updates") ! ============= ! Update water layer thickness @@ -1887,28 +1902,6 @@ subroutine update_channel(block, err) channelChangeRate = channelOpeningRate - channelClosingRate - totalGroundingLineDischargeCell(:) = 0.0_RKIND - totalGroundingLineDischargeEdge(:) = 0.0_RKIND - do iEdge = 1, nEdgesSolve - cell1 = cellsOnEdge(1, iEdge) - cell2 = cellsOnEdge(2, iEdge) - - if (hydroMarineMarginMask(iEdge) == 1) then - ! We are looking for edges with 1 cell grounded ice and the - ! other cell floating ice or open ocean - if ( (li_mask_is_grounded_ice(cellMask(cell1))) .and. & - (li_mask_is_floating_ice(cellMask(cell2)) .or. & - ((bedTopography(cell2) < config_sea_level) .and. (.not. li_mask_is_ice(cellMask(cell2)))) ) ) then - totalGroundingLineDischargeEdge(iEdge) = abs(channelDischarge(iEdge)) +abs( waterFlux(iEdge) * dvEdge(iEdge)) - totalGroundingLineDischargeCell(cell2) = totalGroundingLineDischargeCell(cell2) + totalGroundingLineDischargeEdge(iEdge) - elseif ( (li_mask_is_grounded_ice(cellMask(cell2))) .and. & - (li_mask_is_floating_ice(cellMask(cell1)) .or. & - ((bedTopography(cell1) < config_sea_level) .and. (.not. li_mask_is_ice(cellMask(cell1)))) ) ) then - totalGroundingLineDischargeEdge(iEdge) = abs(channelDischarge(iEdge)) + abs(waterFlux(iEdge) * dvEdge(iEdge)) - totalGroundingLineDischargeCell(cell1) = totalGroundingLineDischargeCell(cell1) + totalGroundingLineDischargeEdge(iEdge) - endif - endif - enddo !-------------------------------------------------------------------- end subroutine update_channel @@ -2310,4 +2303,96 @@ subroutine calc_hydro_mask(domain) !-------------------------------------------------------------------- end subroutine calc_hydro_mask +!*********************************************************************** +! +! routine calc_gl_total +! +!> \brief Calculate total grounding line discharge on edges and +! adjacent cells +!> \author Alex Hager +!> \date 27 March 2024 +!> \details +!----------------------------------------------------------------------- + subroutine calc_gl_totals(block, err) + + !----------------------------------------------------------------- + ! input variables + !----------------------------------------------------------------- + + !----------------------------------------------------------------- + ! input/output variables + !----------------------------------------------------------------- + type (block_type), intent(inout) :: block !< Input/Output: block object + + !----------------------------------------------------------------- + ! output variables + !----------------------------------------------------------------- + integer, intent(out) :: err !< Output: error flag + + !----------------------------------------------------------------- + !----------------------------------------------------------------- + ! output variables + !----------------------------------------------------------------- + + !----------------------------------------------------------------- + ! local variables + !----------------------------------------------------------------- + type (mpas_pool_type), pointer :: hydroPool + type (mpas_pool_type), pointer :: geometryPool + type (mpas_pool_type), pointer :: meshPool + + real (kind=RKIND), dimension(:), pointer :: totalGroundingLineDischargeCell + real (kind=RKIND), dimension(:), pointer :: totalGroundingLineDischargeEdge + real (kind=RKIND), dimension(:), pointer :: bedTopography + real (kind=RKIND), dimension(:), pointer :: channelDischarge + real (kind=RKIND), dimension(:), pointer :: waterFlux + real (kind=RKIND), dimension(:), pointer :: dvEdge + integer iEdge, cell1, cell2 + integer, pointer :: nEdgesSolve + integer, dimension(:,:), pointer :: cellsOnEdge + integer, dimension(:), pointer :: hydroMarineMarginMask + integer, dimension(:), pointer :: cellMask + real (kind=RKIND), pointer :: config_sea_level + + call mpas_pool_get_subpool(block % structs, 'hydro', hydroPool) + call mpas_pool_get_subpool(block % structs, 'geometry', geometryPool) + call mpas_pool_get_subpool(block % structs, 'mesh', meshPool) + + call mpas_pool_get_array(hydroPool, 'totalGroundingLineDischargeCell', totalGroundingLineDischargeCell) + call mpas_pool_get_array(hydroPool, 'totalGroundingLineDischargeEdge', totalGroundingLineDischargeEdge) + call mpas_pool_get_array(geometryPool, 'bedTopography', bedTopography) + call mpas_pool_get_array(hydroPool, 'channelDischarge', channelDischarge) + call mpas_pool_get_array(hydroPool, 'waterFlux', waterFlux) + call mpas_pool_get_array(meshPool, 'dvEdge', dvEdge) + call mpas_pool_get_dimension(meshPool, 'nEdgesSolve', nEdgesSolve) + call mpas_pool_get_array(meshPool, 'cellsOnEdge', cellsOnEdge) + call mpas_pool_get_array(hydroPool, 'hydroMarineMarginMask', hydroMarineMarginMask) + call mpas_pool_get_array(geometryPool, 'cellMask', cellMask) + call mpas_pool_get_config(liConfigs, 'config_sea_level', config_sea_level) + + totalGroundingLineDischargeCell(:) = 0.0_RKIND + totalGroundingLineDischargeEdge(:) = 0.0_RKIND + + do iEdge = 1, nEdgesSolve + cell1 = cellsOnEdge(1, iEdge) + cell2 = cellsOnEdge(2, iEdge) + + if (hydroMarineMarginMask(iEdge) == 1) then + ! We are looking for edges with 1 cell grounded ice and the + ! other cell floating ice or open ocean + if ( (li_mask_is_grounded_ice(cellMask(cell1))) .and. & + (li_mask_is_floating_ice(cellMask(cell2)) .or. & + ((bedTopography(cell2) < config_sea_level) .and. (.not. li_mask_is_ice(cellMask(cell2)))) ) ) then + totalGroundingLineDischargeEdge(iEdge) = abs(channelDischarge(iEdge)) +abs( waterFlux(iEdge) * dvEdge(iEdge)) + totalGroundingLineDischargeCell(cell2) = totalGroundingLineDischargeCell(cell2) + totalGroundingLineDischargeEdge(iEdge) + elseif ( (li_mask_is_grounded_ice(cellMask(cell2))) .and. & + (li_mask_is_floating_ice(cellMask(cell1)) .or. & + ((bedTopography(cell1) < config_sea_level) .and. (.not. li_mask_is_ice(cellMask(cell1)))) ) ) then + totalGroundingLineDischargeEdge(iEdge) = abs(channelDischarge(iEdge)) + abs(waterFlux(iEdge) * dvEdge(iEdge)) + totalGroundingLineDischargeCell(cell1) = totalGroundingLineDischargeCell(cell1) + totalGroundingLineDischargeEdge(iEdge) + endif + endif + enddo + end subroutine calc_gl_totals + end module li_subglacial_hydro From 0194a2b1ea565e95765fd741d95def019414c3b6 Mon Sep 17 00:00:00 2001 From: Walter Hannah Date: Fri, 5 Apr 2024 08:18:19 -0700 Subject: [PATCH 090/451] pam_debug update --- .../eam/src/physics/crm/pam/pam_debug.h | 41 +++++++++++++------ 1 file changed, 29 insertions(+), 12 deletions(-) diff --git a/components/eam/src/physics/crm/pam/pam_debug.h b/components/eam/src/physics/crm/pam/pam_debug.h index 937d18cf154e..2d3dc1efb894 100644 --- a/components/eam/src/physics/crm/pam/pam_debug.h +++ b/components/eam/src/physics/crm/pam/pam_debug.h @@ -27,28 +27,32 @@ inline void pam_debug_init( pam::PamCoupler &coupler ) { auto nens = coupler.get_option("ncrms"); //------------------------------------------------------------------------------------------------ dm_device.register_and_allocate("debug_save_temp", "saved temp for debug", {nz,ny,nx,nens}, {"z","y","x","nens"} ); + dm_device.register_and_allocate("debug_save_rhod", "saved rhod for debug", {nz,ny,nx,nens}, {"z","y","x","nens"} ); dm_device.register_and_allocate("debug_save_rhov", "saved rhov for debug", {nz,ny,nx,nens}, {"z","y","x","nens"} ); dm_device.register_and_allocate("debug_save_rhoc", "saved rhoc for debug", {nz,ny,nx,nens}, {"z","y","x","nens"} ); dm_device.register_and_allocate("debug_save_rhoi", "saved rhoi for debug", {nz,ny,nx,nens}, {"z","y","x","nens"} ); dm_device.register_and_allocate("debug_save_uvel", "saved uvel for debug", {nz,ny,nx,nens}, {"z","y","x","nens"} ); dm_device.register_and_allocate("debug_save_wvel", "saved wvel for debug", {nz,ny,nx,nens}, {"z","y","x","nens"} ); auto debug_save_temp = dm_device.get("debug_save_temp"); + auto debug_save_rhod = dm_device.get("debug_save_rhod"); auto debug_save_rhov = dm_device.get("debug_save_rhov"); auto debug_save_rhoc = dm_device.get("debug_save_rhoc"); auto debug_save_rhoi = dm_device.get("debug_save_rhoi"); auto debug_save_uvel = dm_device.get("debug_save_uvel"); auto debug_save_wvel = dm_device.get("debug_save_wvel"); //------------------------------------------------------------------------------------------------ - auto temp = dm_device.get("temp"); - auto rhov = dm_device.get("water_vapor"); - auto rhoc = dm_device.get("cloud_water"); - auto rhoi = dm_device.get("ice"); - auto uvel = dm_device.get("uvel"); - auto wvel = dm_device.get("wvel"); + auto temp = dm_device.get("temp"); + auto rhod = dm_device.get("density_dry"); + auto rhov = dm_device.get("water_vapor"); + auto rhoc = dm_device.get("cloud_water"); + auto rhoi = dm_device.get("ice"); + auto uvel = dm_device.get("uvel"); + auto wvel = dm_device.get("wvel"); //------------------------------------------------------------------------------------------------ parallel_for("copy data to saved debug variables", SimpleBounds<4>(nz,ny,nx,nens), YAKL_LAMBDA (int k, int j, int i, int iens) { debug_save_temp(k,j,i,iens) = temp(k,j,i,iens); + debug_save_rhod(k,j,i,iens) = rhod(k,j,i,iens); debug_save_rhov(k,j,i,iens) = rhov(k,j,i,iens); debug_save_rhoc(k,j,i,iens) = rhoc(k,j,i,iens); debug_save_rhoi(k,j,i,iens) = rhoi(k,j,i,iens); @@ -69,12 +73,14 @@ void pam_debug_check_state( pam::PamCoupler &coupler, int id, int nstep ) { auto nz = coupler.get_option("crm_nz"); auto nens = coupler.get_option("ncrms"); auto temp = dm_device.get("temp"); + auto rhod = dm_device.get("density_dry"); auto rhov = dm_device.get("water_vapor"); auto rhoc = dm_device.get("cloud_water"); auto rhoi = dm_device.get("ice"); auto uvel = dm_device.get("uvel"); auto wvel = dm_device.get("wvel"); auto debug_save_temp = dm_device.get("debug_save_temp"); + auto debug_save_rhod = dm_device.get("debug_save_rhod"); auto debug_save_rhov = dm_device.get("debug_save_rhov"); auto debug_save_rhoc = dm_device.get("debug_save_rhoc"); auto debug_save_rhoi = dm_device.get("debug_save_rhoi"); @@ -90,18 +96,21 @@ void pam_debug_check_state( pam::PamCoupler &coupler, int id, int nstep ) { auto phis = input_phis(iens)/grav; // Check for NaNs const auto is_nan_t_atm = isnan( temp(k,j,i,iens) ); + const auto is_nan_d_atm = isnan( rhod(k,j,i,iens) ); const auto is_nan_q_atm = isnan( rhov(k,j,i,iens) ); - if ( is_nan_t_atm || is_nan_q_atm ) { + if ( is_nan_t_atm || is_nan_q_atm || is_nan_d_atm ) { auto phis = input_phis(iens)/grav; - printf("PAM-DEBUG nan-found - st:%3.3d id:%2.2d k:%3.3d i:%3.3d n:%3.3d y:%5.1f x:%5.1f ph:%6.1f -- t:%8.2g rv:%8.2g rc:%8.2g ri:%8.2g u:%8.2g w:%8.2g -- t:%8.2g rv:%8.2g rc:%8.2g ri:%8.2g u:%8.2g w:%8.2g \n", + printf("PAM-DEBUG nan-found - st:%3.3d id:%2.2d k:%3.3d i:%3.3d n:%3.3d y:%5.1f x:%5.1f ph:%6.1f -- t:%8.2g rd:%8.2g rv:%8.2g rc:%8.2g ri:%8.2g u:%8.2g w:%8.2g -- t:%8.2g rd:%8.2g rv:%8.2g rc:%8.2g ri:%8.2g u:%8.2g w:%8.2g \n", nstep,id,k,i,iens,lat(iens),lon(iens),phis, temp(k,j,i,iens), + rhod(k,j,i,iens), rhov(k,j,i,iens), rhoc(k,j,i,iens), rhoi(k,j,i,iens), uvel(k,j,i,iens), wvel(k,j,i,iens), debug_save_temp(k,j,i,iens), + debug_save_rhod(k,j,i,iens), debug_save_rhov(k,j,i,iens), debug_save_rhoc(k,j,i,iens), debug_save_rhoi(k,j,i,iens), @@ -111,18 +120,21 @@ void pam_debug_check_state( pam::PamCoupler &coupler, int id, int nstep ) { } // Check for negative values const auto is_neg_t_atm = temp(k,j,i,iens)<0; + const auto is_neg_d_atm = rhod(k,j,i,iens)<0; const auto is_neg_q_atm = rhov(k,j,i,iens)<0; - if ( is_neg_t_atm || is_neg_q_atm ) { + if ( is_neg_t_atm || is_neg_q_atm || is_neg_d_atm ) { auto phis = input_phis(iens)/grav; - printf("PAM-DEBUG neg-found - st:%3.3d id:%2.2d k:%3.3d i:%3.3d n:%3.3d y:%5.1f x:%5.1f ph:%6.1f -- t:%8.2g rv:%8.2g rc:%8.2g ri:%8.2g u:%8.2g w:%8.2g -- t:%8.2g rv:%8.2g rc:%8.2g ri:%8.2g u:%8.2g w:%8.2g \n", + printf("PAM-DEBUG neg-found - st:%3.3d id:%2.2d k:%3.3d i:%3.3d n:%3.3d y:%5.1f x:%5.1f ph:%6.1f -- t:%8.2g rd:%8.2g rv:%8.2g rc:%8.2g ri:%8.2g u:%8.2g w:%8.2g -- t:%8.2g rd:%8.2g rv:%8.2g rc:%8.2g ri:%8.2g u:%8.2g w:%8.2g \n", nstep,id,k,i,iens,lat(iens),lon(iens),phis, temp(k,j,i,iens), + rhod(k,j,i,iens), rhov(k,j,i,iens), rhoc(k,j,i,iens), rhoi(k,j,i,iens), uvel(k,j,i,iens), wvel(k,j,i,iens), debug_save_temp(k,j,i,iens), + debug_save_rhod(k,j,i,iens), debug_save_rhov(k,j,i,iens), debug_save_rhoc(k,j,i,iens), debug_save_rhoi(k,j,i,iens), @@ -133,15 +145,17 @@ void pam_debug_check_state( pam::PamCoupler &coupler, int id, int nstep ) { // Check for low temperature const auto is_low_t = temp(k,j,i,iens)<100; if ( is_low_t ) { - printf("PAM-DEBUG low-T - st:%3.3d id:%2.2d k:%3.3d i:%3.3d n:%3.3d y:%5.1f x:%5.1f ph:%6.1f -- t:%8.2g rv:%8.2g rc:%8.2g ri:%8.2g u:%8.2g w:%8.2g -- t:%8.2g rv:%8.2g rc:%8.2g ri:%8.2g u:%8.2g w:%8.2g \n", + printf("PAM-DEBUG low-T - st:%3.3d id:%2.2d k:%3.3d i:%3.3d n:%3.3d y:%5.1f x:%5.1f ph:%6.1f -- t:%8.2g rd:%8.2g rv:%8.2g rc:%8.2g ri:%8.2g u:%8.2g w:%8.2g -- t:%8.2g rd:%8.2g rv:%8.2g rc:%8.2g ri:%8.2g u:%8.2g w:%8.2g \n", nstep,id,k,i,iens,lat(iens),lon(iens),phis, temp(k,j,i,iens), + rhod(k,j,i,iens), rhov(k,j,i,iens), rhoc(k,j,i,iens), rhoi(k,j,i,iens), uvel(k,j,i,iens), wvel(k,j,i,iens), debug_save_temp(k,j,i,iens), + debug_save_rhod(k,j,i,iens), debug_save_rhov(k,j,i,iens), debug_save_rhoc(k,j,i,iens), debug_save_rhoi(k,j,i,iens), @@ -153,15 +167,17 @@ void pam_debug_check_state( pam::PamCoupler &coupler, int id, int nstep ) { const auto is_large_pos_w = wvel(k,j,i,iens)> 40; const auto is_large_neg_w = wvel(k,j,i,iens)<-40; if ( is_large_pos_w || is_large_neg_w ) { - printf("PAM-DEBUG large-W - st:%3.3d id:%2.2d k:%3.3d i:%3.3d n:%3.3d y:%5.1f x:%5.1f ph:%6.1f -- t:%8.2g rv:%8.2g rc:%8.2g ri:%8.2g u:%8.2g w:%8.2g -- t:%8.2g rv:%8.2g rc:%8.2g ri:%8.2g u:%8.2g w:%8.2g \n", + printf("PAM-DEBUG large-W - st:%3.3d id:%2.2d k:%3.3d i:%3.3d n:%3.3d y:%5.1f x:%5.1f ph:%6.1f -- t:%8.2g rd:%8.2g rv:%8.2g rc:%8.2g ri:%8.2g u:%8.2g w:%8.2g -- t:%8.2g rd:%8.2g rv:%8.2g rc:%8.2g ri:%8.2g u:%8.2g w:%8.2g \n", nstep,id,k,i,iens,lat(iens),lon(iens),phis, temp(k,j,i,iens), + rhod(k,j,i,iens), rhov(k,j,i,iens), rhoc(k,j,i,iens), rhoi(k,j,i,iens), uvel(k,j,i,iens), wvel(k,j,i,iens), debug_save_temp(k,j,i,iens), + debug_save_rhod(k,j,i,iens), debug_save_rhov(k,j,i,iens), debug_save_rhoc(k,j,i,iens), debug_save_rhoi(k,j,i,iens), @@ -171,6 +187,7 @@ void pam_debug_check_state( pam::PamCoupler &coupler, int id, int nstep ) { } // update saved previous values debug_save_temp(k,j,i,iens) = temp(k,j,i,iens); + debug_save_rhod(k,j,i,iens) = rhod(k,j,i,iens); debug_save_rhov(k,j,i,iens) = rhov(k,j,i,iens); debug_save_rhoc(k,j,i,iens) = rhoc(k,j,i,iens); debug_save_rhoi(k,j,i,iens) = rhoi(k,j,i,iens); From 39da4a6344b42b04ab49036dfed78770f07b79b6 Mon Sep 17 00:00:00 2001 From: Alexander Hager Date: Fri, 5 Apr 2024 14:07:12 -0600 Subject: [PATCH 091/451] Cleanup PR This commit makes minor formatting adjustments to address comments in PR review. --- .../src/mode_forward/mpas_li_subglacial_hydro.F | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/components/mpas-albany-landice/src/mode_forward/mpas_li_subglacial_hydro.F b/components/mpas-albany-landice/src/mode_forward/mpas_li_subglacial_hydro.F index 4067e2951437..e8fa19ff51f8 100644 --- a/components/mpas-albany-landice/src/mode_forward/mpas_li_subglacial_hydro.F +++ b/components/mpas-albany-landice/src/mode_forward/mpas_li_subglacial_hydro.F @@ -56,8 +56,8 @@ module li_subglacial_hydro ! Private module variables ! !-------------------------------------------------------------------- -! Minimum gradMagPhiBaseEdge and gradMagPhiEdge allowed before all dependent variables are zeroed out -real(kind=RKIND), parameter :: SMALL_GRADPHI = 1.0e-6_RKIND + ! Minimum gradMagPhiBaseEdge and gradMagPhiEdge allowed before all dependent variables are zeroed out + real(kind=RKIND), parameter :: SMALL_GRADPHI = 1.0e-6_RKIND !*********************************************************************** contains @@ -773,7 +773,6 @@ subroutine calc_edge_quantities(block, err) integer, dimension(:), pointer :: edgeMask integer, dimension(:,:), pointer :: cellsOnEdge integer, dimension(:,:), pointer :: verticesOnEdge - integer, dimension(:,:), pointer :: cellsOnVertex integer, dimension(:,:), pointer :: baryCellsOnVertex real (kind=RKIND), dimension(:,:), pointer :: baryWeightsOnVertex real (kind=RKIND), pointer :: alpha, beta @@ -1019,7 +1018,7 @@ subroutine calc_edge_quantities(block, err) effectiveConducEdge(iEdge) = 0.0_RKIND else effectiveConducEdge(iEdge) = conduc_coeff * waterThicknessEdge(iEdge)**(alpha-1.0_RKIND) *& - gradMagPhiBaseEdge(iEdge)**(beta - 2.0_RKIND) + gradMagPhiBaseEdge(iEdge)**(beta - 2.0_RKIND) endif enddo endif @@ -2192,7 +2191,8 @@ end subroutine ocean_connection_N !> \author Matt Hoffman !> \date 24 October 2022 !> \details -!> This routine calculates a mask of the boundaries of the active hydrology domain +!> This routine calculates a mask of the boundaries of the active hydrology domain. +!> If there no waterFluxMask around domain boundaries, then calc_hydro_mask creates one. !----------------------------------------------------------------------- subroutine calc_hydro_mask(domain) @@ -2291,7 +2291,7 @@ subroutine calc_hydro_mask(domain) end do if (wfmWarning == 1) then - call mpas_log_write('WARNING: Changing waterFluxMask to enforce no-flow conditions at domain boundaries') + call mpas_log_write('Changing waterFluxMask to enforce no-flow conditions at domain boundaries', MPAS_LOG_WARN) endif call mpas_timer_start("halo updates") call mpas_dmpar_field_halo_exch(domain, 'hydroMarineMarginMask') From c3ad2365025dc7ff8f86b26bdda0ac9ce7a9374b Mon Sep 17 00:00:00 2001 From: Matt Hoffman Date: Fri, 5 Apr 2024 14:20:46 -0600 Subject: [PATCH 092/451] Update components/mpas-albany-landice/src/mode_forward/mpas_li_subglacial_hydro.F --- .../src/mode_forward/mpas_li_subglacial_hydro.F | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/components/mpas-albany-landice/src/mode_forward/mpas_li_subglacial_hydro.F b/components/mpas-albany-landice/src/mode_forward/mpas_li_subglacial_hydro.F index e8fa19ff51f8..76fdc8c0432c 100644 --- a/components/mpas-albany-landice/src/mode_forward/mpas_li_subglacial_hydro.F +++ b/components/mpas-albany-landice/src/mode_forward/mpas_li_subglacial_hydro.F @@ -2192,7 +2192,7 @@ end subroutine ocean_connection_N !> \date 24 October 2022 !> \details !> This routine calculates a mask of the boundaries of the active hydrology domain. -!> If there no waterFluxMask around domain boundaries, then calc_hydro_mask creates one. +!> If there is no waterFluxMask set around domain boundaries, then calc_hydro_mask creates one. !----------------------------------------------------------------------- subroutine calc_hydro_mask(domain) From 3ed937dfd495b81916fcdf391d77fa38c40b7f06 Mon Sep 17 00:00:00 2001 From: Alexander Hager Date: Fri, 5 Apr 2024 15:34:11 -0600 Subject: [PATCH 093/451] Clean up PR Makes a series of minor changes cleaning up the PR in accordance to review comments. Biggest change is the removal of superfluous variable totalGroundingLineDischargeEdge. --- .../src/Registry_subglacial_hydro.xml | 3 - .../mode_forward/mpas_li_subglacial_hydro.F | 60 ++++--------------- 2 files changed, 13 insertions(+), 50 deletions(-) diff --git a/components/mpas-albany-landice/src/Registry_subglacial_hydro.xml b/components/mpas-albany-landice/src/Registry_subglacial_hydro.xml index 5aa5d66e7bb6..9199facf7412 100644 --- a/components/mpas-albany-landice/src/Registry_subglacial_hydro.xml +++ b/components/mpas-albany-landice/src/Registry_subglacial_hydro.xml @@ -232,8 +232,6 @@ description="time step used for evolving subglacial hydrology system" /> - @@ -267,7 +265,6 @@ description="rate of channel melt production within each cell, averaged over cell area" /> - diff --git a/components/mpas-albany-landice/src/mode_forward/mpas_li_subglacial_hydro.F b/components/mpas-albany-landice/src/mode_forward/mpas_li_subglacial_hydro.F index 3da17bdcd986..3a6a36a698ed 100644 --- a/components/mpas-albany-landice/src/mode_forward/mpas_li_subglacial_hydro.F +++ b/components/mpas-albany-landice/src/mode_forward/mpas_li_subglacial_hydro.F @@ -1744,8 +1744,6 @@ subroutine update_channel(block, err) real (kind=RKIND), pointer :: rhoi real (kind=RKIND), pointer :: config_SGH_incipient_channel_width logical, pointer :: config_SGH_include_pressure_melt - real (kind=RKIND), pointer :: config_SGH_bed_roughness_max - real (kind=RKIND), pointer :: config_sea_level real (kind=RKIND), dimension(:), pointer :: channelArea real (kind=RKIND), dimension(:), pointer :: channelMelt real (kind=RKIND), dimension(:), pointer :: channelPressureFreeze @@ -1762,27 +1760,13 @@ subroutine update_channel(block, err) real (kind=RKIND), dimension(:), pointer :: channelEffectivePressure real (kind=RKIND), dimension(:), pointer :: effectivePressure real (kind=RKIND), dimension(:), pointer :: channelDiffusivity - real (kind=RKIND), dimension(:), pointer :: waterThickness - real (kind=RKIND), dimension(:), pointer :: waterPressure - real (kind=RKIND), dimension(:), pointer :: iceThicknessHydro - real (kind=RKIND), dimension(:), pointer :: totalGroundingLineDischargeCell - real (kind=RKIND), dimension(:), pointer :: totalGroundingLineDischargeEdge - real (kind=RKIND), dimension(:), pointer :: dvEdge - real (kind=RKIND), dimension(:), pointer :: bedTopography integer, dimension(:), pointer :: waterFluxMask integer, dimension(:), pointer :: hydroMarineMarginMask integer, dimension(:), pointer :: edgeMask real (kind=RKIND), dimension(:,:), pointer :: flowParamA integer, dimension(:,:), pointer :: cellsOnEdge integer, pointer :: nVertLevels - real (kind=RKIND), pointer :: config_SGH_max_chnl_lake_depth - character (len=StrKIND), pointer :: config_SGH_inhibit_chnls_on_lakes - real (kind=RKIND), dimension(:), pointer :: xCell - real (kind=RKIND), dimension(:), pointer :: yCell - real (kind=RKIND), dimension(:), pointer :: xEdge - real (kind=RKIND), dimension(:), pointer :: yEdge - integer, dimension(:), pointer :: cellMask - integer, pointer :: nEdgesSolve, nEdges + integer, pointer :: nEdgesSolve integer :: iEdge, cell1, cell2 err = 0 @@ -1792,7 +1776,6 @@ subroutine update_channel(block, err) call mpas_pool_get_subpool(block % structs, 'mesh', meshPool) call mpas_pool_get_subpool(block % structs, 'velocity', velocityPool) call mpas_pool_get_subpool(block % structs, 'geometry', geometryPool) - call mpas_pool_get_config(liConfigs, 'config_sea_level', config_sea_level) call mpas_pool_get_config(liConfigs, 'config_ice_density', rhoi) call mpas_pool_get_config(liConfigs, 'config_SGH_chnl_conduc_coeff', Kc) call mpas_pool_get_config(liConfigs, 'config_SGH_chnl_alpha', alpha_c) @@ -1800,8 +1783,8 @@ subroutine update_channel(block, err) call mpas_pool_get_config(liConfigs, 'config_SGH_chnl_creep_coefficient', creep_coeff) call mpas_pool_get_config(liConfigs, 'config_SGH_incipient_channel_width', config_SGH_incipient_channel_width) call mpas_pool_get_config(liConfigs, 'config_SGH_include_pressure_melt', config_SGH_include_pressure_melt) - call mpas_pool_get_dimension(meshPool, 'nEdgesSolve', nEdgesSolve) call mpas_pool_get_dimension(meshPool, 'nVertLevels', nVertLevels) + call mpas_pool_get_dimension(meshPool, 'nEdgesSolve', nEdgesSolve) call mpas_pool_get_array(hydroPool, 'channelArea', channelArea) call mpas_pool_get_array(hydroPool, 'channelMelt', channelMelt) call mpas_pool_get_array(hydroPool, 'channelPressureFreeze', channelPressureFreeze) @@ -1823,17 +1806,8 @@ subroutine update_channel(block, err) call mpas_pool_get_array(hydroPool, 'hydroMarineMarginMask', hydroMarineMarginMask) call mpas_pool_get_array(hydroPool, 'channelDiffusivity', channelDiffusivity) call mpas_pool_get_array(geometryPool, 'edgeMask', edgeMask) - call mpas_pool_get_array(meshPool, 'xCell', xCell) - call mpas_pool_get_array(meshPool, 'yCell', yCell) - call mpas_pool_get_array(meshPool, 'xEdge', xEdge) - call mpas_pool_get_array(meshPool, 'yEdge', yEdge) - call mpas_pool_get_array(meshPool, 'dvEdge', dvEdge) - call mpas_pool_get_array(geometryPool, 'bedTopography', bedTopography) - call mpas_pool_get_array(hydroPool, 'totalGroundingLineDischargeCell', totalGroundingLineDischargeCell) - call mpas_pool_get_array(hydroPool, 'totalGroundingLineDischargeEdge', totalGroundingLineDischargeEdge) - call mpas_pool_get_array(geometryPool, 'cellMask', cellMask) + ! Calculate terms needed for opening (melt) rate - where(gradMagPhiEdge < 0.01_RKIND) channelDischarge(:) = 0.0_RKIND elsewhere @@ -2307,11 +2281,11 @@ end subroutine calc_hydro_mask ! ! routine calc_gl_total ! -!> \brief Calculate total grounding line discharge on edges and -! adjacent cells +!> \brief Calculate total grounding line discharge on +! adjacent ocean cell !> \author Alex Hager !> \date 27 March 2024 -!> \details +!> \details Find the total amount of freshwater entering the first ocean cell from the grounding line. !----------------------------------------------------------------------- subroutine calc_gl_totals(block, err) @@ -2342,7 +2316,6 @@ subroutine calc_gl_totals(block, err) type (mpas_pool_type), pointer :: meshPool real (kind=RKIND), dimension(:), pointer :: totalGroundingLineDischargeCell - real (kind=RKIND), dimension(:), pointer :: totalGroundingLineDischargeEdge real (kind=RKIND), dimension(:), pointer :: bedTopography real (kind=RKIND), dimension(:), pointer :: channelDischarge real (kind=RKIND), dimension(:), pointer :: waterFlux @@ -2352,6 +2325,7 @@ subroutine calc_gl_totals(block, err) integer, dimension(:,:), pointer :: cellsOnEdge integer, dimension(:), pointer :: hydroMarineMarginMask integer, dimension(:), pointer :: cellMask + real (kind=RKIND) :: totalGroundingLineDischargeEdge real (kind=RKIND), pointer :: config_sea_level call mpas_pool_get_subpool(block % structs, 'hydro', hydroPool) @@ -2359,7 +2333,6 @@ subroutine calc_gl_totals(block, err) call mpas_pool_get_subpool(block % structs, 'mesh', meshPool) call mpas_pool_get_array(hydroPool, 'totalGroundingLineDischargeCell', totalGroundingLineDischargeCell) - call mpas_pool_get_array(hydroPool, 'totalGroundingLineDischargeEdge', totalGroundingLineDischargeEdge) call mpas_pool_get_array(geometryPool, 'bedTopography', bedTopography) call mpas_pool_get_array(hydroPool, 'channelDischarge', channelDischarge) call mpas_pool_get_array(hydroPool, 'waterFlux', waterFlux) @@ -2371,25 +2344,18 @@ subroutine calc_gl_totals(block, err) call mpas_pool_get_config(liConfigs, 'config_sea_level', config_sea_level) totalGroundingLineDischargeCell(:) = 0.0_RKIND - totalGroundingLineDischargeEdge(:) = 0.0_RKIND do iEdge = 1, nEdgesSolve cell1 = cellsOnEdge(1, iEdge) cell2 = cellsOnEdge(2, iEdge) if (hydroMarineMarginMask(iEdge) == 1) then - ! We are looking for edges with 1 cell grounded ice and the - ! other cell floating ice or open ocean - if ( (li_mask_is_grounded_ice(cellMask(cell1))) .and. & - (li_mask_is_floating_ice(cellMask(cell2)) .or. & - ((bedTopography(cell2) < config_sea_level) .and. (.not. li_mask_is_ice(cellMask(cell2)))) ) ) then - totalGroundingLineDischargeEdge(iEdge) = abs(channelDischarge(iEdge)) +abs( waterFlux(iEdge) * dvEdge(iEdge)) - totalGroundingLineDischargeCell(cell2) = totalGroundingLineDischargeCell(cell2) + totalGroundingLineDischargeEdge(iEdge) - elseif ( (li_mask_is_grounded_ice(cellMask(cell2))) .and. & - (li_mask_is_floating_ice(cellMask(cell1)) .or. & - ((bedTopography(cell1) < config_sea_level) .and. (.not. li_mask_is_ice(cellMask(cell1)))) ) ) then - totalGroundingLineDischargeEdge(iEdge) = abs(channelDischarge(iEdge)) + abs(waterFlux(iEdge) * dvEdge(iEdge)) - totalGroundingLineDischargeCell(cell1) = totalGroundingLineDischargeCell(cell1) + totalGroundingLineDischargeEdge(iEdge) + if (li_mask_is_grounded_ice(cellMask(cell1))) then + totalGroundingLineDischargeEdge = abs(channelDischarge(iEdge)) +abs( waterFlux(iEdge) * dvEdge(iEdge)) + totalGroundingLineDischargeCell(cell2) = totalGroundingLineDischargeCell(cell2) + totalGroundingLineDischargeEdge + elseif (li_mask_is_grounded_ice(cellMask(cell2))) then + totalGroundingLineDischargeEdge = abs(channelDischarge(iEdge)) + abs(waterFlux(iEdge) * dvEdge(iEdge)) + totalGroundingLineDischargeCell(cell1) = totalGroundingLineDischargeCell(cell1) + totalGroundingLineDischargeEdge endif endif enddo From f2325d3849b51cbc62715afcdcba3b10f7bb2b34 Mon Sep 17 00:00:00 2001 From: Alexander Hager Date: Fri, 5 Apr 2024 16:52:36 -0600 Subject: [PATCH 094/451] dist. and chnl. grounding line totals Calculates the distributed and channelized contributions to totalGroundingLineDischargeCell --- .../src/Registry_subglacial_hydro.xml | 8 +++++-- .../mode_forward/mpas_li_subglacial_hydro.F | 21 +++++++++++++++++-- 2 files changed, 25 insertions(+), 4 deletions(-) diff --git a/components/mpas-albany-landice/src/Registry_subglacial_hydro.xml b/components/mpas-albany-landice/src/Registry_subglacial_hydro.xml index 9199facf7412..61d8fa7f6812 100644 --- a/components/mpas-albany-landice/src/Registry_subglacial_hydro.xml +++ b/components/mpas-albany-landice/src/Registry_subglacial_hydro.xml @@ -229,10 +229,14 @@ + description="time step used for evolving subglacial hydrology system" /> + + description="total (channel + dist.) discharge across the grounding line, extrapolated from edge to adjacent ungrounded cell. Values from all edges are summed if multiple grounding line edges border a single ungrounded cell" /> + Date: Mon, 8 Apr 2024 14:41:54 -0700 Subject: [PATCH 095/451] Improve remove_small_islands Remove small islands that are one or two grounded cells with or without a one-cell-wide floating dynamic ice shelf. --- .../src/mode_forward/mpas_li_calving.F | 210 +++++++++++++----- 1 file changed, 158 insertions(+), 52 deletions(-) diff --git a/components/mpas-albany-landice/src/mode_forward/mpas_li_calving.F b/components/mpas-albany-landice/src/mode_forward/mpas_li_calving.F index 1df2391cdb2c..7d4b7799520e 100644 --- a/components/mpas-albany-landice/src/mode_forward/mpas_li_calving.F +++ b/components/mpas-albany-landice/src/mode_forward/mpas_li_calving.F @@ -320,6 +320,10 @@ subroutine li_calve_ice(domain, err, solveVeloAfterCalving) call li_calculate_mask(meshPool, velocityPool, geometryPool, err_tmp) + call remove_small_islands(meshPool, geometryPool, domain) + + call li_calculate_mask(meshPool, velocityPool, geometryPool, err_tmp) + ! now also remove any icebergs call remove_icebergs(domain) @@ -336,7 +340,6 @@ subroutine li_calve_ice(domain, err, solveVeloAfterCalving) call mpas_pool_get_array(geometryPool, 'calvingThickness', calvingThickness) call mpas_pool_get_dimension(meshPool, 'nCells', nCells) - call remove_small_islands(meshPool, geometryPool) ! In data calving mode we just calculate what should be calved but don't actually calve it. ! So set thickness back to original value. if (config_data_calving) then @@ -1023,20 +1026,23 @@ end subroutine floating_calving ! routine remove_small_islands ! !> \brief Remove very small islands that lead to velocity solver problems -!> \author Matthew Hoffman -!> \date Summer 2018 +!> \author Matthew Hoffman, Trevor Hillebrand +!> \date Summer 2018, re-written Apr 2024 !> \details This routine finds and eliminates very small islands that lead to !> unrealistic velocities in the Albany velocity solver. Specifically, this -!> finds one- and two-cell masses of ice that are surrounded by open ocean -!> and eliminates them by sending them to the calving flux. +!> finds one- and two-cell masses of grounded ice that are surrounded by dynamic +!> floating ice ice shelves ≥1 cell wide. It eliminates the dynamic cells +!> (both grounded and floating) in these islands by sending them to the +!> and then cleans up stranded non-dynamic cells using a flood-fill routine. !----------------------------------------------------------------------- - subroutine remove_small_islands(meshPool, geometryPool) + subroutine remove_small_islands(meshPool, geometryPool, domain) type (mpas_pool_type), pointer, intent(in) :: meshPool !< Input: Mesh pool type (mpas_pool_type), pointer, intent(inout) :: geometryPool !< Input: Geometry pool + type (domain_type), intent(inout) :: domain !< Input/Output: domain object + type (mpas_pool_type), pointer :: scratchPool logical, pointer :: config_remove_small_islands - real(kind=RKIND), pointer :: config_sea_level real (kind=RKIND), dimension(:), pointer :: calvingThickness ! thickness of ice that calves (computed in this subroutine) real (kind=RKIND), dimension(:), pointer :: calvingThicknessFromThreshold ! thickness of ice that calves (computed in this subroutine) real (kind=RKIND), dimension(:), pointer :: thickness @@ -1044,73 +1050,173 @@ subroutine remove_small_islands(meshPool, geometryPool) integer, dimension(:), pointer :: cellMask integer, dimension(:,:), pointer :: cellsOnCell ! list of cells that neighbor each cell integer, dimension(:), pointer :: nEdgesOnCell ! number of cells that border each cell - integer, pointer :: nCellsSolve - integer :: iCell, jCell, n, nIceNeighbors, nIceNeighbors2, neighborWithIce - integer :: nOpenOceanNeighbors, nOpenOceanNeighbors2 + integer, pointer :: nCells, maxEdges + logical :: removeIsland + integer :: iCell, jCell, kCell, m, n, count + integer :: nGroundedNeighbors, nGroundedNeighborsJCell + integer, dimension(:), allocatable :: connectedCellsList + integer, dimension(:), allocatable :: islandMask + type (field1dInteger), pointer :: seedMaskField + type (field1dInteger), pointer :: growMaskField + integer, dimension(:), pointer :: seedMask, growMask !masks to pass to flood-fill routine call mpas_pool_get_config(liConfigs, 'config_remove_small_islands', config_remove_small_islands) if (.not. config_remove_small_islands) then return ! skip this entire routine if disabled endif - call mpas_pool_get_config(liConfigs, 'config_sea_level', config_sea_level) - call mpas_pool_get_dimension(meshPool, 'nCellsSolve', nCellsSolve) + call mpas_pool_get_subpool(domain % blocklist % structs, 'scratch', scratchPool) + + call mpas_pool_get_dimension(meshPool, 'nCells', nCells) + call mpas_pool_get_dimension(meshPool, 'maxEdges', maxEdges) call mpas_pool_get_array(meshPool, 'cellsOnCell', cellsOnCell) call mpas_pool_get_array(meshPool, 'nEdgesOnCell', nEdgesOnCell) call mpas_pool_get_array(geometryPool, 'calvingThickness', calvingThickness) call mpas_pool_get_array(geometryPool, 'calvingThicknessFromThreshold', calvingThicknessFromThreshold) call mpas_pool_get_array(geometryPool, 'thickness', thickness) call mpas_pool_get_array(geometryPool, 'cellMask', cellMask) - call mpas_pool_get_array(geometryPool, 'bedTopography', bedTopography) - do iCell = 1, nCellsSolve - if (li_mask_is_ice(cellMask(iCell))) then ! might as well do for both grounded or floating - ! (1 or 2 cell floating masses are icebergs) - nIceNeighbors = 0 - nOpenOceanNeighbors = 0 + allocate(connectedCellsList((maxEdges+1)**2), & + islandMask(nCells+1)) + + islandMask(:) = 0 + + ! Allocate scratch fields for flood-fill + call mpas_pool_get_field(scratchPool, 'seedMask', seedMaskField) + call mpas_allocate_scratch_field(seedMaskField, single_block_in = .true.) + seedMask => seedMaskField % array + seedMask(:) = 0 + + call mpas_pool_get_field(scratchPool, 'growMask', growMaskField) + call mpas_allocate_scratch_field(growMaskField, single_block_in = .true.) + growMask => growMaskField % array + growMask(:) = 0 + + ! Loop over cells to find one- and two-cell regions of grounded ice, + ! which are potentially islands that need to be removed. + do iCell = 1, nCells + if (li_mask_is_grounded_ice(cellMask(iCell))) then + + nGroundedNeighbors = 0 + ! Count grounded neighbors do n = 1, nEdgesOnCell(iCell) jCell = cellsOnCell(n, iCell) - if (li_mask_is_ice(cellMask(jCell))) then - nIceNeighbors = nIceNeighbors + 1 - neighborWithIce = jCell + if (li_mask_is_grounded_ice(cellMask(jCell))) then + nGroundedNeighbors = nGroundedNeighbors + 1 endif - if (.not. li_mask_is_ice(cellMask(jCell)) .and. bedTopography(jCell) < config_sea_level) then - nOpenOceanNeighbors = nOpenOceanNeighbors + 1 + nGroundedNeighborsJCell = 0 + ! If the neighbor contains dynamic ice, check whether + ! it has other grounded neighbors. If it does, then we + ! will not consider this an island. + if (li_mask_is_dynamic_ice(cellMask(jCell))) then + do m = 1, nEdgesOnCell(jCell) + kCell = cellsOnCell(m, jCell) + if (li_mask_is_grounded_ice(cellMask(kCell))) then + nGroundedNeighborsJCell = nGroundedNeighborsJCell + 1 + endif + enddo + endif + ! If this grounded cell is dynamically connected to 1 or + ! fewer other grounded cells, then it should potentially + ! be removed. If its dynamic neighbors have other grounded + ! neighbors, then it is not an island. + if ( (nGroundedNeighborsJCell .le. 1) .and. & + (nGroundedNeighbors .le. 1) ) then + islandMask(iCell) = 1 + else + islandMask(iCell) = 0 endif enddo - if ((nIceNeighbors == 0) .and. (nOpenOceanNeighbors == nEdgesOnCell(iCell))) then - ! If this is a single cell of ice surrounded by open ocean, kill this location + endif + enddo + + ! Determine whether to remove each island. First, make a list of the + ! dynamic neighbors of the cells in islandMask. If the grounded island + ! cell has a grounded neighbour, add that neighbor's dynamic neighbors + ! to the list. Then, check that all the dynamic neighbors of the cells + ! in the list are also in the list. If so, then this is considered an + ! island and is removed. If not, then leave it alone. + do iCell = 1, nCells + connectedCellsList(:) = -1 + if (islandMask(iCell) == 1) then + removeIsland = .true. ! evalulated and updated below + ! Make a list of the grounded island cell and its + ! dynamic neighbors. + count = 1 + connectedCellsList(count) = iCell + do n = 1, nEdgesOnCell(iCell) + jCell = cellsOnCell(n, iCell) + if (li_mask_is_dynamic_ice(cellMask(jCell))) then + count = count + 1 + connectedCellsList(count) = jCell + endif + ! If there is a grounded neighbor, list its dynamic neighbors as well + if (li_mask_is_grounded_ice(cellMask(jCell))) then + do m = 1, nEdgesOnCell(jCell) + kCell = cellsOnCell(m, jCell) + if (li_mask_is_dynamic_ice(cellMask(kCell))) then + count = count + 1 + connectedCellsList(count) = kCell + endif + enddo + endif + enddo + ! Check that all the dynamic neighbors of neighbors are + ! in the list. If not, then do not remove the island. + do n = 1, (maxEdges+1)**2 + if (connectedCellsList(n) == -1) then + exit ! We've reached the end of the list. + else + jCell = connectedCellsList(n) + do m = 1, nEdgesOnCell(jCell) + kCell = cellsOnCell(m, jCell) + if ( li_mask_is_dynamic_ice(cellMask(kCell)) .and. & + (.not. any(connectedCellsList == kCell)) ) then + removeIsland = .false. + exit + endif + enddo + endif + enddo + ! Actually remove island + ! TODO: halo update needed? Would need to change logic. + if ( removeIsland ) then + do n = 1, count + calvingThickness(connectedCellsList(n)) = calvingThickness(connectedCellsList(n)) + & + thickness(connectedCellsList(n)) + calvingThicknessFromThreshold(connectedCellsList(n)) = & + calvingThicknessFromThreshold(connectedCellsList(n)) + thickness(connectedCellsList(n)) + thickness(connectedCellsList(n)) = 0.0_RKIND + enddo + endif + endif + enddo + + ! Clean up by removing non-dynamic ice that may have been left behind + ! after islands where removed. + where (li_mask_is_grounded_ice(cellMask)) + seedMask = 1 + end where + + where (li_mask_is_ice(cellMask)) + growMask = 1 + end where + + call mpas_log_write("***Cleaning up stranded cells after removing small islands***") + call li_flood_fill(seedMask, growMask, domain) + do iCell = 1, nCells + if (li_mask_is_floating_ice(cellMask(iCell)) .and. seedMask(iCell) == 0) then calvingThickness(iCell) = calvingThickness(iCell) + thickness(iCell) calvingThicknessFromThreshold(iCell) = calvingThicknessFromThreshold(iCell) + thickness(iCell) thickness(iCell) = 0.0_RKIND - elseif (nIceNeighbors == 1) then - ! check if this neighbor has any additional neighbors with ice - nIceNeighbors2 = 0 - nOpenOceanNeighbors2 = 0 - do n = 1, nEdgesOnCell(neighborWithIce) - jCell = cellsOnCell(n, neighborWithIce) - if (li_mask_is_ice(cellMask(jCell))) then - nIceNeighbors2 = nIceNeighbors2 + 1 - endif - if (.not. li_mask_is_ice(cellMask(jCell)) .and. bedTopography(jCell) < config_sea_level) then - nOpenOceanNeighbors2 = nOpenOceanNeighbors2 + 1 - endif - enddo - if ((nIceNeighbors2 == 1) .and. (nOpenOceanNeighbors2 == nEdgesOnCell(iCell)-1)) then - ! <- only neighbor with ice must have been iCell - ! kill both cells - calvingThickness(iCell) = calvingThickness(iCell) + thickness(iCell) - calvingThicknessFromThreshold(iCell) = calvingThicknessFromThreshold(iCell) + thickness(iCell) - thickness(iCell) = 0.0_RKIND - calvingThickness(neighborWithIce) = calvingThickness(neighborWithIce) + thickness(neighborWithIce) - calvingThicknessFromThreshold(neighborWithIce) = calvingThicknessFromThreshold(neighborWithIce) + thickness(neighborWithIce) - thickness(neighborWithIce) = 0.0_RKIND - endif - - endif ! check on nIceNeighbors + endif + enddo + call mpas_log_write("***Finished cleaning up after removing small islands***") - endif ! check if iCell has ice - end do ! loop over cells + deallocate(connectedCellsList, & + islandMask) + call mpas_deallocate_scratch_field(seedMaskField, single_block_in=.true.) + call mpas_deallocate_scratch_field(growMaskField, single_block_in=.true.) end subroutine remove_small_islands From 730931f76f3a17a9c2da0bad2407190707f377d3 Mon Sep 17 00:00:00 2001 From: Walter Hannah Date: Tue, 9 Apr 2024 11:17:12 -0700 Subject: [PATCH 096/451] bug fix in pam_state --- .../eam/src/physics/crm/pam/pam_state.h | 34 ++++++++++++++----- 1 file changed, 26 insertions(+), 8 deletions(-) diff --git a/components/eam/src/physics/crm/pam/pam_state.h b/components/eam/src/physics/crm/pam/pam_state.h index 3266899ba217..a34a867eb6e8 100644 --- a/components/eam/src/physics/crm/pam/pam_state.h +++ b/components/eam/src/physics/crm/pam/pam_state.h @@ -144,7 +144,7 @@ inline void pam_state_set_reference_state( pam::PamCoupler &coupler ) { real2d hmean_temp ("hmean_temp" ,nz ,nens); real r_nx_ny = 1._fp/(nx*ny); // precompute reciprocal to avoid costly divisions // initialize horizontal means - parallel_for(SimpleBounds<2>(nz,nens), YAKL_LAMBDA (int k, int iens) { + parallel_for(SimpleBounds<2>(nz+1,nens), YAKL_LAMBDA (int k, int iens) { hmean_pint(k,iens) = 0; if (k < nz) { hmean_pmid (k,iens) = 0; @@ -166,24 +166,42 @@ inline void pam_state_set_reference_state( pam::PamCoupler &coupler ) { atomicAdd( hmean_temp (k,iens), temp (k,j,i,iens) * r_nx_ny ); }); // calculate interface pressure from mid-level pressure - parallel_for(SimpleBounds<4>(nz+1,ny,nx,nens) , YAKL_LAMBDA (int k, int j, int i, int iens) { + // parallel_for(SimpleBounds<4>(nz+1,ny,nx,nens) , YAKL_LAMBDA (int k, int j, int i, int iens) { + parallel_for(SimpleBounds<2>(nz+1,nens) , YAKL_LAMBDA (int k, int iens) { if (k == 0 ) { - real rho = rho_d(k ,j,i,iens)+rho_v(k ,j,i,iens); - real dz = zint(k+1,iens)-zint(k ,iens); + real rho = hmean_rho_d(k,iens)+hmean_rho_v(k,iens); + real dz = zint(k+1,iens)-zint(k,iens); hmean_pint(k,iens) = hmean_pmid(k ,iens) + grav*rho*dz/2; } else if (k == nz) { - real rho = rho_d(k-1,j,i,iens)+rho_v(k-1,j,i,iens); - real dz = zint(k ,iens)-zint(k-1,iens); + real rho = hmean_rho_d(k-1,iens)+hmean_rho_v(k-1,iens); + real dz = zint(k,iens)-zint(k-1,iens); hmean_pint(k,iens) = hmean_pmid(k-1,iens) - grav*rho*dz/2; } else { - real rhokm1 = rho_d(k-1,j,i,iens)+rho_v(k-1,j,i,iens); - real rhokm0 = rho_d(k ,j,i,iens)+rho_v(k ,j,i,iens); + real rhokm1 = hmean_rho_d(k-1,iens)+hmean_rho_v(k-1,iens);; + real rhokm0 = hmean_rho_d(k ,iens)+hmean_rho_v(k ,iens); real dzkm1 = zint(k ,iens)-zint(k-1,iens); real dzkm0 = zint(k+1,iens)-zint(k ,iens); hmean_pint(k,iens) = 0.5_fp * ( hmean_pmid(k-1,iens) - grav*rhokm1*dzkm1/2 + hmean_pmid(k ,iens) + grav*rhokm0*dzkm0/2 ); } }); + + auto &dm_host = coupler.get_data_manager_host_readonly(); + auto lat = dm_host.get("latitude" ).createDeviceCopy(); + auto lon = dm_host.get("longitude" ).createDeviceCopy(); + auto input_phis = dm_host.get("input_phis").createDeviceCopy(); + // check that interface pressure is reasonable + parallel_for(SimpleBounds<2>(nz+1,nens) , YAKL_LAMBDA (int k, int iens) { + if ( hmean_pint(k,iens) < hmean_pmid(k,iens) ) { + auto phis = input_phis(iens)/grav; + printf("PAM-DEBUG bad-pint - k:%3.3d n:%3.3d y:%5.1f x:%5.1f ph:%6.1f -- pint:%8.2g pmid:%8.2g \n", + k,iens,lat(iens),lon(iens),phis, + hmean_pint(k,iens), + hmean_pmid(k,iens) + ); + } + }); + // set anelastic reference state from CRM horizontal mean parallel_for(SimpleBounds<2>(nz+1,nens) , YAKL_LAMBDA (int k, int iens) { ref_presi(k,iens) = hmean_pint(k,iens); From b094fc0db0534982a3f52aadd2ba5466e09be4e7 Mon Sep 17 00:00:00 2001 From: Walter Hannah Date: Tue, 9 Apr 2024 11:20:48 -0700 Subject: [PATCH 097/451] pam_debug updates --- .../eam/src/physics/crm/pam/pam_debug.h | 73 ++++++++++++------- 1 file changed, 47 insertions(+), 26 deletions(-) diff --git a/components/eam/src/physics/crm/pam/pam_debug.h b/components/eam/src/physics/crm/pam/pam_debug.h index 2d3dc1efb894..43d2b5bf4f5d 100644 --- a/components/eam/src/physics/crm/pam/pam_debug.h +++ b/components/eam/src/physics/crm/pam/pam_debug.h @@ -142,32 +142,31 @@ void pam_debug_check_state( pam::PamCoupler &coupler, int id, int nstep ) { debug_save_wvel(k,j,i,iens) ); } - // Check for low temperature - const auto is_low_t = temp(k,j,i,iens)<100; - if ( is_low_t ) { - printf("PAM-DEBUG low-T - st:%3.3d id:%2.2d k:%3.3d i:%3.3d n:%3.3d y:%5.1f x:%5.1f ph:%6.1f -- t:%8.2g rd:%8.2g rv:%8.2g rc:%8.2g ri:%8.2g u:%8.2g w:%8.2g -- t:%8.2g rd:%8.2g rv:%8.2g rc:%8.2g ri:%8.2g u:%8.2g w:%8.2g \n", - nstep,id,k,i,iens,lat(iens),lon(iens),phis, - temp(k,j,i,iens), - rhod(k,j,i,iens), - rhov(k,j,i,iens), - rhoc(k,j,i,iens), - rhoi(k,j,i,iens), - uvel(k,j,i,iens), - wvel(k,j,i,iens), - debug_save_temp(k,j,i,iens), - debug_save_rhod(k,j,i,iens), - debug_save_rhov(k,j,i,iens), - debug_save_rhoc(k,j,i,iens), - debug_save_rhoi(k,j,i,iens), - debug_save_uvel(k,j,i,iens), - debug_save_wvel(k,j,i,iens) - ); - } - // Check for large vertical velocity - const auto is_large_pos_w = wvel(k,j,i,iens)> 40; - const auto is_large_neg_w = wvel(k,j,i,iens)<-40; - if ( is_large_pos_w || is_large_neg_w ) { - printf("PAM-DEBUG large-W - st:%3.3d id:%2.2d k:%3.3d i:%3.3d n:%3.3d y:%5.1f x:%5.1f ph:%6.1f -- t:%8.2g rd:%8.2g rv:%8.2g rc:%8.2g ri:%8.2g u:%8.2g w:%8.2g -- t:%8.2g rd:%8.2g rv:%8.2g rc:%8.2g ri:%8.2g u:%8.2g w:%8.2g \n", + // // Check for low temperature + // const auto is_low_t = temp(k,j,i,iens)<100; + // if ( is_low_t ) { + // printf("PAM-DEBUG low-T - st:%3.3d id:%2.2d k:%3.3d i:%3.3d n:%3.3d y:%5.1f x:%5.1f ph:%6.1f -- t:%8.2g rd:%8.2g rv:%8.2g rc:%8.2g ri:%8.2g u:%8.2g w:%8.2g -- t:%8.2g rd:%8.2g rv:%8.2g rc:%8.2g ri:%8.2g u:%8.2g w:%8.2g \n", + // nstep,id,k,i,iens,lat(iens),lon(iens),phis, + // temp(k,j,i,iens), + // rhod(k,j,i,iens), + // rhov(k,j,i,iens), + // rhoc(k,j,i,iens), + // rhoi(k,j,i,iens), + // uvel(k,j,i,iens), + // wvel(k,j,i,iens), + // debug_save_temp(k,j,i,iens), + // debug_save_rhod(k,j,i,iens), + // debug_save_rhov(k,j,i,iens), + // debug_save_rhoc(k,j,i,iens), + // debug_save_rhoi(k,j,i,iens), + // debug_save_uvel(k,j,i,iens), + // debug_save_wvel(k,j,i,iens) + // ); + // } + // Check for large temperature drops + const auto is_drop_t = (temp(k,j,i,iens)-debug_save_temp(k,j,i,iens))<-50; + if ( is_drop_t ) { + printf("PAM-DEBUG drop-T - st:%3.3d id:%2.2d k:%3.3d i:%3.3d n:%3.3d y:%5.1f x:%5.1f ph:%6.1f -- t:%8.2g rd:%8.2g rv:%8.2g rc:%8.2g ri:%8.2g u:%8.2g w:%8.2g -- t:%8.2g rd:%8.2g rv:%8.2g rc:%8.2g ri:%8.2g u:%8.2g w:%8.2g \n", nstep,id,k,i,iens,lat(iens),lon(iens),phis, temp(k,j,i,iens), rhod(k,j,i,iens), @@ -185,6 +184,28 @@ void pam_debug_check_state( pam::PamCoupler &coupler, int id, int nstep ) { debug_save_wvel(k,j,i,iens) ); } + // // Check for large vertical velocity + // const auto is_large_pos_w = wvel(k,j,i,iens)> 40; + // const auto is_large_neg_w = wvel(k,j,i,iens)<-40; + // if ( is_large_pos_w || is_large_neg_w ) { + // printf("PAM-DEBUG large-W - st:%3.3d id:%2.2d k:%3.3d i:%3.3d n:%3.3d y:%5.1f x:%5.1f ph:%6.1f -- t:%8.2g rd:%8.2g rv:%8.2g rc:%8.2g ri:%8.2g u:%8.2g w:%8.2g -- t:%8.2g rd:%8.2g rv:%8.2g rc:%8.2g ri:%8.2g u:%8.2g w:%8.2g \n", + // nstep,id,k,i,iens,lat(iens),lon(iens),phis, + // temp(k,j,i,iens), + // rhod(k,j,i,iens), + // rhov(k,j,i,iens), + // rhoc(k,j,i,iens), + // rhoi(k,j,i,iens), + // uvel(k,j,i,iens), + // wvel(k,j,i,iens), + // debug_save_temp(k,j,i,iens), + // debug_save_rhod(k,j,i,iens), + // debug_save_rhov(k,j,i,iens), + // debug_save_rhoc(k,j,i,iens), + // debug_save_rhoi(k,j,i,iens), + // debug_save_uvel(k,j,i,iens), + // debug_save_wvel(k,j,i,iens) + // ); + // } // update saved previous values debug_save_temp(k,j,i,iens) = temp(k,j,i,iens); debug_save_rhod(k,j,i,iens) = rhod(k,j,i,iens); From 0720d0dca888c047638492a6c5312fb5932d88aa Mon Sep 17 00:00:00 2001 From: Walter Hannah Date: Tue, 9 Apr 2024 11:24:16 -0700 Subject: [PATCH 098/451] disable mean-state acceleration for dry density --- .../eam/src/physics/crm/pam/pam_accelerate.h | 26 +++++++++---------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/components/eam/src/physics/crm/pam/pam_accelerate.h b/components/eam/src/physics/crm/pam/pam_accelerate.h index a48ca628f691..a7b179a85c9d 100644 --- a/components/eam/src/physics/crm/pam/pam_accelerate.h +++ b/components/eam/src/physics/crm/pam/pam_accelerate.h @@ -25,7 +25,7 @@ inline void pam_accelerate_init( pam::PamCoupler &coupler ) { auto crm_accel_uv = coupler.get_option("crm_accel_uv"); //------------------------------------------------------------------------------------------------ dm_device.register_and_allocate("accel_save_t", "saved temperature for MSA", {nz,nens}, {"z","nens"} ); - dm_device.register_and_allocate("accel_save_r", "saved dry density for MSA", {nz,nens}, {"z","nens"} ); + // dm_device.register_and_allocate("accel_save_r", "saved dry density for MSA", {nz,nens}, {"z","nens"} ); dm_device.register_and_allocate("accel_save_q", "saved total water for MSA", {nz,nens}, {"z","nens"} ); dm_device.register_and_allocate("accel_save_u", "saved uvel for MSA", {nz,nens}, {"z","nens"} ); dm_device.register_and_allocate("accel_save_v", "saved vvel for MSA", {nz,nens}, {"z","nens"} ); @@ -45,14 +45,14 @@ inline void pam_accelerate_diagnose( pam::PamCoupler &coupler ) { auto crm_accel_uv = coupler.get_option("crm_accel_uv"); //------------------------------------------------------------------------------------------------ auto temp = dm_device.get("temp" ); - auto rhod = dm_device.get("density_dry"); + // auto rhod = dm_device.get("density_dry"); auto rhov = dm_device.get("water_vapor"); auto rhol = dm_device.get("cloud_water"); auto rhoi = dm_device.get("ice" ); auto uvel = dm_device.get("uvel" ); auto vvel = dm_device.get("vvel" ); auto accel_save_t = dm_device.get("accel_save_t"); - auto accel_save_r = dm_device.get("accel_save_r"); + // auto accel_save_r = dm_device.get("accel_save_r"); auto accel_save_q = dm_device.get("accel_save_q"); auto accel_save_u = dm_device.get("accel_save_u"); auto accel_save_v = dm_device.get("accel_save_v"); @@ -60,7 +60,7 @@ inline void pam_accelerate_diagnose( pam::PamCoupler &coupler ) { // compute horizontal means needed later for mean-state acceleration parallel_for( SimpleBounds<2>(nz,nens) , YAKL_LAMBDA (int k, int n) { accel_save_t(k,n) = 0.0; - accel_save_r(k,n) = 0.0; + // accel_save_r(k,n) = 0.0; accel_save_q(k,n) = 0.0; if (crm_accel_uv) { accel_save_u(k,n) = 0.0; @@ -70,7 +70,7 @@ inline void pam_accelerate_diagnose( pam::PamCoupler &coupler ) { real r_nx_ny = 1._fp/(nx*ny); // precompute reciprocal to avoid costly divisions parallel_for( SimpleBounds<4>(nz,ny,nx,nens) , YAKL_LAMBDA (int k, int j, int i, int n) { yakl::atomicAdd( accel_save_t(k,n), temp(k,j,i,n) * r_nx_ny ); - yakl::atomicAdd( accel_save_r(k,n), rhod(k,j,i,n) * r_nx_ny ); + // yakl::atomicAdd( accel_save_r(k,n), rhod(k,j,i,n) * r_nx_ny ); yakl::atomicAdd( accel_save_q(k,n), ( rhov(k,j,i,n) + rhol(k,j,i,n) + rhoi(k,j,i,n) ) * r_nx_ny ); if (crm_accel_uv) { yakl::atomicAdd( accel_save_u(k,n), uvel(k,j,i,n) * r_nx_ny ); @@ -93,14 +93,14 @@ inline void pam_accelerate( pam::PamCoupler &coupler, int nstep, int &nstop ) { auto nx = coupler.get_option("crm_nx"); //------------------------------------------------------------------------------------------------ auto temp = dm_device.get("temp" ); - auto rhod = dm_device.get("density_dry"); + // auto rhod = dm_device.get("density_dry"); auto rhov = dm_device.get("water_vapor"); auto rhol = dm_device.get("cloud_water"); auto rhoi = dm_device.get("ice" ); auto uvel = dm_device.get("uvel" ); auto vvel = dm_device.get("vvel" ); auto accel_save_t = dm_device.get("accel_save_t"); - auto accel_save_r = dm_device.get("accel_save_r"); + // auto accel_save_r = dm_device.get("accel_save_r"); auto accel_save_q = dm_device.get("accel_save_q"); auto accel_save_u = dm_device.get("accel_save_u"); auto accel_save_v = dm_device.get("accel_save_v"); @@ -109,12 +109,12 @@ inline void pam_accelerate( pam::PamCoupler &coupler, int nstep, int &nstop ) { real crm_accel_factor = coupler.get_option("crm_accel_factor"); //------------------------------------------------------------------------------------------------ real2d hmean_t ("hmean_t", nz,nens); - real2d hmean_r ("hmean_r", nz,nens); + // real2d hmean_r ("hmean_r", nz,nens); real2d hmean_q ("hmean_q", nz,nens); real2d hmean_u ("hmean_u", nz,nens); real2d hmean_v ("hmean_v", nz,nens); real2d ttend_acc("ttend_acc", nz,nens); - real2d rtend_acc("rtend_acc", nz,nens); + // real2d rtend_acc("rtend_acc", nz,nens); real2d qtend_acc("qtend_acc", nz,nens); real2d utend_acc("utend_acc", nz,nens); real2d vtend_acc("vtend_acc", nz,nens); @@ -127,7 +127,7 @@ inline void pam_accelerate( pam::PamCoupler &coupler, int nstep, int &nstop ) { // Compute the horizontal mean for each variable parallel_for( SimpleBounds<2>(nz,nens) , YAKL_LAMBDA (int k, int n) { hmean_t(k,n) = 0.0; - hmean_r(k,n) = 0.0; + // hmean_r(k,n) = 0.0; hmean_q(k,n) = 0.0; if (crm_accel_uv) { hmean_u(k,n) = 0.0; @@ -137,7 +137,7 @@ inline void pam_accelerate( pam::PamCoupler &coupler, int nstep, int &nstop ) { real r_nx_ny = 1._fp/(nx*ny); // precompute reciprocal to avoid costly divisions parallel_for( SimpleBounds<4>(nz,ny,nx,nens) , YAKL_LAMBDA (int k, int j, int i, int n) { yakl::atomicAdd( hmean_t(k,n), temp(k,j,i,n) * r_nx_ny ); - yakl::atomicAdd( hmean_r(k,n), rhod(k,j,i,n) * r_nx_ny ); + // yakl::atomicAdd( hmean_r(k,n), rhod(k,j,i,n) * r_nx_ny ); yakl::atomicAdd( hmean_q(k,n), ( rhov(k,j,i,n) + rhol(k,j,i,n) + rhoi(k,j,i,n) ) * r_nx_ny ); if (crm_accel_uv) { yakl::atomicAdd( hmean_u(k,n), uvel(k,j,i,n) * r_nx_ny ); @@ -150,7 +150,7 @@ inline void pam_accelerate( pam::PamCoupler &coupler, int nstep, int &nstop ) { ScalarLiveOut ceaseflag_liveout(false); parallel_for( SimpleBounds<2>(nz,nens) , YAKL_LAMBDA (int k, int n) { ttend_acc(k,n) = hmean_t(k,n) - accel_save_t(k,n); - rtend_acc(k,n) = hmean_r(k,n) - accel_save_r(k,n); + // rtend_acc(k,n) = hmean_r(k,n) - accel_save_r(k,n); qtend_acc(k,n) = hmean_q(k,n) - accel_save_q(k,n); if (crm_accel_uv) { utend_acc(k,n) = hmean_u(k,n) - accel_save_u(k,n); @@ -193,7 +193,7 @@ inline void pam_accelerate( pam::PamCoupler &coupler, int nstep, int &nstop ) { parallel_for( SimpleBounds<4>(nz,ny,nx,nens) , YAKL_LAMBDA (int k, int j, int i, int n) { temp(k,j,i,n) = temp(k,j,i,n) + crm_accel_factor * ttend_acc(k,n); - rhod(k,j,i,n) = rhod(k,j,i,n) + crm_accel_factor * rtend_acc(k,n); + // rhod(k,j,i,n) = rhod(k,j,i,n) + crm_accel_factor * rtend_acc(k,n); rhov(k,j,i,n) = rhov(k,j,i,n) + crm_accel_factor * qtend_acc(k,n); if (crm_accel_uv) { uvel(k,j,i,n) = uvel(k,j,i,n) + crm_accel_factor * utend_acc(k,n); From 081b18326623709d8f7019d4fcaedec551c51852 Mon Sep 17 00:00:00 2001 From: Walter Hannah Date: Tue, 9 Apr 2024 11:29:11 -0700 Subject: [PATCH 099/451] update pam_driver --- components/eam/src/physics/crm/pam/pam_driver.cpp | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/components/eam/src/physics/crm/pam/pam_driver.cpp b/components/eam/src/physics/crm/pam/pam_driver.cpp index e6f85ed0d5ac..69e67a90894c 100644 --- a/components/eam/src/physics/crm/pam/pam_driver.cpp +++ b/components/eam/src/physics/crm/pam/pam_driver.cpp @@ -25,7 +25,7 @@ #include "p3_f90.hpp" #include "pam_debug.h" -bool constexpr enable_check_state = false; +bool constexpr enable_check_state = true; extern "C" void pam_driver() { //------------------------------------------------------------------------------------------------ @@ -62,7 +62,7 @@ extern "C" void pam_driver() { coupler.set_option("spam_clip_vertical_velocities",true); coupler.set_option("spam_adjust_crm_per_phys_using_vert_cfl",true); coupler.set_option("spam_target_cfl",0.7); - coupler.set_option("spam_max_w",50.0); + coupler.set_option("spam_max_w",30.0); //------------------------------------------------------------------------------------------------ // Allocate the coupler state and retrieve host/device data managers coupler.allocate_coupler_state( crm_nz , crm_ny , crm_nx , nens ); @@ -91,8 +91,10 @@ extern "C" void pam_driver() { // Copy input CRM state (saved by the GCM) to coupler pam_state_copy_input_to_coupler(coupler); - // // update CRM dry density to match GCM and disable dry density forcing - // pam_state_update_dry_density(coupler); + #ifdef MMF_DISABLE_DENSITY_FORCING + // update CRM dry density to match GCM and disable dry density forcing + pam_state_update_dry_density(coupler); + #endif // if debugging - initialize saved state variables and check initial CRM state if (enable_check_state) { From 5e8b488dce3c4eab15346db343dcc8f92395c474 Mon Sep 17 00:00:00 2001 From: Trevor Hillebrand Date: Tue, 9 Apr 2024 14:18:12 -0700 Subject: [PATCH 100/451] Fix small bug in setting islandMask Fix small bug in setting islandMask. Also apply suggestions from code review. --- .../src/mode_forward/mpas_li_calving.F | 98 +++++++++++-------- 1 file changed, 55 insertions(+), 43 deletions(-) diff --git a/components/mpas-albany-landice/src/mode_forward/mpas_li_calving.F b/components/mpas-albany-landice/src/mode_forward/mpas_li_calving.F index 7d4b7799520e..6997af422493 100644 --- a/components/mpas-albany-landice/src/mode_forward/mpas_li_calving.F +++ b/components/mpas-albany-landice/src/mode_forward/mpas_li_calving.F @@ -320,7 +320,7 @@ subroutine li_calve_ice(domain, err, solveVeloAfterCalving) call li_calculate_mask(meshPool, velocityPool, geometryPool, err_tmp) - call remove_small_islands(meshPool, geometryPool, domain) + call remove_small_islands(domain, err_tmp) call li_calculate_mask(meshPool, velocityPool, geometryPool, err_tmp) @@ -1032,16 +1032,14 @@ end subroutine floating_calving !> unrealistic velocities in the Albany velocity solver. Specifically, this !> finds one- and two-cell masses of grounded ice that are surrounded by dynamic !> floating ice ice shelves ≥1 cell wide. It eliminates the dynamic cells -!> (both grounded and floating) in these islands by sending them to the -!> and then cleans up stranded non-dynamic cells using a flood-fill routine. +!> (both grounded and floating) in these islands by sending them to the calving +!> flux and then cleans up stranded non-dynamic cells using a flood-fill routine. !----------------------------------------------------------------------- - subroutine remove_small_islands(meshPool, geometryPool, domain) - type (mpas_pool_type), pointer, intent(in) :: meshPool !< Input: Mesh pool - type (mpas_pool_type), pointer, intent(inout) :: geometryPool !< Input: Geometry pool + subroutine remove_small_islands(domain, err) type (domain_type), intent(inout) :: domain !< Input/Output: domain object - - type (mpas_pool_type), pointer :: scratchPool + integer, intent(inout) :: err + type (mpas_pool_type), pointer :: scratchPool, meshPool, geometryPool, velocityPool logical, pointer :: config_remove_small_islands real (kind=RKIND), dimension(:), pointer :: calvingThickness ! thickness of ice that calves (computed in this subroutine) real (kind=RKIND), dimension(:), pointer :: calvingThicknessFromThreshold ! thickness of ice that calves (computed in this subroutine) @@ -1053,6 +1051,7 @@ subroutine remove_small_islands(meshPool, geometryPool, domain) integer, pointer :: nCells, maxEdges logical :: removeIsland integer :: iCell, jCell, kCell, m, n, count + integer :: nIslandCellsLocal, nIslandCellsGlobal integer :: nGroundedNeighbors, nGroundedNeighborsJCell integer, dimension(:), allocatable :: connectedCellsList integer, dimension(:), allocatable :: islandMask @@ -1066,6 +1065,9 @@ subroutine remove_small_islands(meshPool, geometryPool, domain) endif call mpas_pool_get_subpool(domain % blocklist % structs, 'scratch', scratchPool) + call mpas_pool_get_subpool(domain % blocklist % structs, 'mesh', meshPool) + call mpas_pool_get_subpool(domain % blocklist % structs, 'geometry', geometryPool) + call mpas_pool_get_subpool(domain % blocklist % structs, 'velocity', velocityPool) call mpas_pool_get_dimension(meshPool, 'nCells', nCells) call mpas_pool_get_dimension(meshPool, 'maxEdges', maxEdges) @@ -1080,7 +1082,8 @@ subroutine remove_small_islands(meshPool, geometryPool, domain) islandMask(nCells+1)) islandMask(:) = 0 - + nIslandCellsLocal = 0 + nIslandCellsGlobal = 0 ! Allocate scratch fields for flood-fill call mpas_pool_get_field(scratchPool, 'seedMask', seedMaskField) call mpas_allocate_scratch_field(seedMaskField, single_block_in = .true.) @@ -1096,7 +1099,7 @@ subroutine remove_small_islands(meshPool, geometryPool, domain) ! which are potentially islands that need to be removed. do iCell = 1, nCells if (li_mask_is_grounded_ice(cellMask(iCell))) then - + islandMask(iCell) = 1 ! Potentially an island. Further evaluated below. nGroundedNeighbors = 0 ! Count grounded neighbors do n = 1, nEdgesOnCell(iCell) @@ -1120,11 +1123,10 @@ subroutine remove_small_islands(meshPool, geometryPool, domain) ! fewer other grounded cells, then it should potentially ! be removed. If its dynamic neighbors have other grounded ! neighbors, then it is not an island. - if ( (nGroundedNeighborsJCell .le. 1) .and. & - (nGroundedNeighbors .le. 1) ) then - islandMask(iCell) = 1 - else + if ( (nGroundedNeighborsJCell > 1) .or. & + (nGroundedNeighbors > 1) ) then islandMask(iCell) = 0 + exit endif enddo endif @@ -1166,53 +1168,63 @@ subroutine remove_small_islands(meshPool, geometryPool, domain) do n = 1, (maxEdges+1)**2 if (connectedCellsList(n) == -1) then exit ! We've reached the end of the list. - else - jCell = connectedCellsList(n) - do m = 1, nEdgesOnCell(jCell) - kCell = cellsOnCell(m, jCell) - if ( li_mask_is_dynamic_ice(cellMask(kCell)) .and. & - (.not. any(connectedCellsList == kCell)) ) then - removeIsland = .false. - exit - endif - enddo endif + jCell = connectedCellsList(n) + do m = 1, nEdgesOnCell(jCell) + kCell = cellsOnCell(m, jCell) + if ( li_mask_is_dynamic_ice(cellMask(kCell)) .and. & + (.not. any(connectedCellsList == kCell)) ) then + removeIsland = .false. + exit + endif + enddo enddo ! Actually remove island - ! TODO: halo update needed? Would need to change logic. if ( removeIsland ) then + nIslandCellsLocal = nIslandCellsLocal + count do n = 1, count calvingThickness(connectedCellsList(n)) = calvingThickness(connectedCellsList(n)) + & thickness(connectedCellsList(n)) calvingThicknessFromThreshold(connectedCellsList(n)) = & calvingThicknessFromThreshold(connectedCellsList(n)) + thickness(connectedCellsList(n)) thickness(connectedCellsList(n)) = 0.0_RKIND + ! No need to evaluate any cells in this list again. + if (islandMask(connectedCellsList(n)) == 1) islandMask(connectedCellsList(n)) = 0 enddo endif endif enddo - ! Clean up by removing non-dynamic ice that may have been left behind - ! after islands where removed. - where (li_mask_is_grounded_ice(cellMask)) - seedMask = 1 - end where + call mpas_timer_start("halo updates") + call mpas_dmpar_field_halo_exch(domain, 'thickness') + call mpas_dmpar_field_halo_exch(domain, 'calvingThickness') + call mpas_timer_stop("halo updates") + call li_calculate_mask(meshPool, velocityPool, geometryPool, err) - where (li_mask_is_ice(cellMask)) - growMask = 1 - end where + call mpas_dmpar_sum_int(domain % dminfo, nIslandCellsLocal, nIslandCellsGlobal) - call mpas_log_write("***Cleaning up stranded cells after removing small islands***") - call li_flood_fill(seedMask, growMask, domain) - do iCell = 1, nCells - if (li_mask_is_floating_ice(cellMask(iCell)) .and. seedMask(iCell) == 0) then - calvingThickness(iCell) = calvingThickness(iCell) + thickness(iCell) - calvingThicknessFromThreshold(iCell) = calvingThicknessFromThreshold(iCell) + thickness(iCell) - thickness(iCell) = 0.0_RKIND - endif - enddo - call mpas_log_write("***Finished cleaning up after removing small islands***") + if ( nIslandCellsGlobal > 0 ) then + ! Clean up by removing non-dynamic ice that may have been left behind + ! after islands where removed. + where (li_mask_is_grounded_ice(cellMask)) + seedMask = 1 + end where + + where (li_mask_is_ice(cellMask)) + growMask = 1 + end where + call mpas_log_write("***Cleaning up stranded cells after removing small islands***") + call li_flood_fill(seedMask, growMask, domain) + do iCell = 1, nCells + if (li_mask_is_floating_ice(cellMask(iCell)) .and. seedMask(iCell) == 0) then + calvingThickness(iCell) = calvingThickness(iCell) + thickness(iCell) + calvingThicknessFromThreshold(iCell) = calvingThicknessFromThreshold(iCell) + thickness(iCell) + thickness(iCell) = 0.0_RKIND + endif + enddo + call mpas_log_write("***Finished cleaning up after removing small islands***") + endif deallocate(connectedCellsList, & islandMask) call mpas_deallocate_scratch_field(seedMaskField, single_block_in=.true.) From 338d3e693e8aeabbb0e6126941eb91ef8c4501a1 Mon Sep 17 00:00:00 2001 From: alexolinhager <131483939+alexolinhager@users.noreply.github.com> Date: Tue, 9 Apr 2024 17:10:36 -0700 Subject: [PATCH 101/451] Apply suggestions from code review Co-authored-by: Matt Hoffman --- .../mpas-albany-landice/src/Registry_subglacial_hydro.xml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/components/mpas-albany-landice/src/Registry_subglacial_hydro.xml b/components/mpas-albany-landice/src/Registry_subglacial_hydro.xml index 61d8fa7f6812..12c669d9093d 100644 --- a/components/mpas-albany-landice/src/Registry_subglacial_hydro.xml +++ b/components/mpas-albany-landice/src/Registry_subglacial_hydro.xml @@ -231,12 +231,12 @@ + description="distributed discharge across the grounding line, summed from grounding line edges to adjacent ungrounded cell. Values from all edges are summed if multiple grounding line edges border a single ungrounded cell" /> + description="total (channel + dist.) discharge across the grounding line, summed from grounding line edges to adjacent ungrounded cell. Values from all edges are summed if multiple grounding line edges border a single ungrounded cell" /> + description="channel discharge across the grounding line, summed from grounding line edges to adjacent ungrounded cell. Values from all edges are summed if multiple grounding line edges border a single ungrounded cell" /> Date: Tue, 9 Apr 2024 18:15:49 -0600 Subject: [PATCH 102/451] Minor PR Review Edits Minor edits to code following PR review --- .../src/mode_forward/mpas_li_subglacial_hydro.F | 13 +++---------- 1 file changed, 3 insertions(+), 10 deletions(-) diff --git a/components/mpas-albany-landice/src/mode_forward/mpas_li_subglacial_hydro.F b/components/mpas-albany-landice/src/mode_forward/mpas_li_subglacial_hydro.F index 009a4e4f2ec9..0028e75086eb 100644 --- a/components/mpas-albany-landice/src/mode_forward/mpas_li_subglacial_hydro.F +++ b/components/mpas-albany-landice/src/mode_forward/mpas_li_subglacial_hydro.F @@ -562,10 +562,6 @@ subroutine li_SGH_solve(domain, err) block => block % next end do - call mpas_timer_start("halo updates") - call mpas_dmpar_field_halo_exch(domain, 'totalGroundingLineDischargeCell') - call mpas_dmpar_field_halo_exch(domain, 'totalGroundingLineDischargeEdge') - call mpas_timer_stop("halo updates") ! ============= ! Update water layer thickness @@ -2318,7 +2314,6 @@ subroutine calc_gl_totals(block, err) real (kind=RKIND), dimension(:), pointer :: distGroundingLineDischargeCell real (kind=RKIND), dimension(:), pointer :: chnlGroundingLineDischargeCell real (kind=RKIND), dimension(:), pointer :: totalGroundingLineDischargeCell - real (kind=RKIND), dimension(:), pointer :: bedTopography real (kind=RKIND), dimension(:), pointer :: channelDischarge real (kind=RKIND), dimension(:), pointer :: waterFlux real (kind=RKIND), dimension(:), pointer :: dvEdge @@ -2330,7 +2325,6 @@ subroutine calc_gl_totals(block, err) real (kind=RKIND) :: distGroundingLineDischargeEdge real (kind=RKIND) :: chnlGroundingLineDischargeEdge real (kind=RKIND) :: totalGroundingLineDischargeEdge - real (kind=RKIND), pointer :: config_sea_level call mpas_pool_get_subpool(block % structs, 'hydro', hydroPool) call mpas_pool_get_subpool(block % structs, 'geometry', geometryPool) @@ -2339,7 +2333,6 @@ subroutine calc_gl_totals(block, err) call mpas_pool_get_array(hydroPool, 'distGroundingLineDischargeCell', distGroundingLineDischargeCell) call mpas_pool_get_array(hydroPool, 'chnlGroundingLineDischargeCell', chnlGroundingLineDischargeCell) call mpas_pool_get_array(hydroPool, 'totalGroundingLineDischargeCell', totalGroundingLineDischargeCell) - call mpas_pool_get_array(geometryPool, 'bedTopography', bedTopography) call mpas_pool_get_array(hydroPool, 'channelDischarge', channelDischarge) call mpas_pool_get_array(hydroPool, 'waterFlux', waterFlux) call mpas_pool_get_array(meshPool, 'dvEdge', dvEdge) @@ -2347,18 +2340,18 @@ subroutine calc_gl_totals(block, err) call mpas_pool_get_array(meshPool, 'cellsOnEdge', cellsOnEdge) call mpas_pool_get_array(hydroPool, 'hydroMarineMarginMask', hydroMarineMarginMask) call mpas_pool_get_array(geometryPool, 'cellMask', cellMask) - call mpas_pool_get_config(liConfigs, 'config_sea_level', config_sea_level) distGroundingLineDischargeCell(:) = 0.0_RKIND chnlGroundingLineDischargeCell(:) = 0.0_RKIND totalGroundingLineDischargeCell(:) = 0.0_RKIND do iEdge = 1, nEdgesSolve - cell1 = cellsOnEdge(1, iEdge) - cell2 = cellsOnEdge(2, iEdge) if (hydroMarineMarginMask(iEdge) == 1) then + cell1 = cellsOnEdge(1, iEdge) + cell2 = cellsOnEdge(2, iEdge) + !calculate totals at each grounding line edge distGroundingLineDischargeEdge = abs(waterFlux(iEdge) * dvEdge(iEdge)) chnlGroundingLineDischargeEdge = abs(channelDischarge(iEdge)) From 40c5a75790c972a0458ad73a2eabb4f14a7b03c5 Mon Sep 17 00:00:00 2001 From: Matt Hoffman Date: Tue, 9 Apr 2024 20:20:06 -0600 Subject: [PATCH 103/451] Remove whitespace addition --- .../src/mode_forward/mpas_li_subglacial_hydro.F | 1 - 1 file changed, 1 deletion(-) diff --git a/components/mpas-albany-landice/src/mode_forward/mpas_li_subglacial_hydro.F b/components/mpas-albany-landice/src/mode_forward/mpas_li_subglacial_hydro.F index 0028e75086eb..d54d87356c82 100644 --- a/components/mpas-albany-landice/src/mode_forward/mpas_li_subglacial_hydro.F +++ b/components/mpas-albany-landice/src/mode_forward/mpas_li_subglacial_hydro.F @@ -1802,7 +1802,6 @@ subroutine update_channel(block, err) call mpas_pool_get_array(hydroPool, 'hydroMarineMarginMask', hydroMarineMarginMask) call mpas_pool_get_array(hydroPool, 'channelDiffusivity', channelDiffusivity) call mpas_pool_get_array(geometryPool, 'edgeMask', edgeMask) - ! Calculate terms needed for opening (melt) rate where(gradMagPhiEdge < 0.01_RKIND) channelDischarge(:) = 0.0_RKIND From c7cbee480925f25e5a4945f2993eeaba806e99b6 Mon Sep 17 00:00:00 2001 From: Trevor Hillebrand Date: Wed, 10 Apr 2024 12:19:23 -0600 Subject: [PATCH 104/451] Apply suggestions from code review Add more descriptive comments. Co-authored-by: Matt Hoffman --- .../src/mode_forward/mpas_li_calving.F | 22 ++++++++++++++----- 1 file changed, 16 insertions(+), 6 deletions(-) diff --git a/components/mpas-albany-landice/src/mode_forward/mpas_li_calving.F b/components/mpas-albany-landice/src/mode_forward/mpas_li_calving.F index 6997af422493..5de1d6f5c7e3 100644 --- a/components/mpas-albany-landice/src/mode_forward/mpas_li_calving.F +++ b/components/mpas-albany-landice/src/mode_forward/mpas_li_calving.F @@ -1095,8 +1095,12 @@ subroutine remove_small_islands(domain, err) growMask => growMaskField % array growMask(:) = 0 - ! Loop over cells to find one- and two-cell regions of grounded ice, - ! which are potentially islands that need to be removed. + ! Loop over cells to find one- and two-cell regions of grounded ice + ! that are not dynamically connected to other grounded regions, + ! which are "islands" that potentially need to be removed. + ! In this first phase we identify islands that meet these + ! criteria. In phase 2 below we check if islands are dynamically + ! connected to floating ice, which will disqualify them for removal. do iCell = 1, nCells if (li_mask_is_grounded_ice(cellMask(iCell))) then islandMask(iCell) = 1 ! Potentially an island. Further evaluated below. @@ -1132,12 +1136,14 @@ subroutine remove_small_islands(domain, err) endif enddo - ! Determine whether to remove each island. First, make a list of the - ! dynamic neighbors of the cells in islandMask. If the grounded island - ! cell has a grounded neighbour, add that neighbor's dynamic neighbors + ! Determine whether to remove each island based on if it is dynamically + ! connected to other regions. For each cell in islandMask, + ! first make a list of its dynamic neighbors. If the grounded island + ! cell has a grounded neighbor, add that neighbor's dynamic neighbors ! to the list. Then, check that all the dynamic neighbors of the cells ! in the list are also in the list. If so, then this is considered an - ! island and is removed. If not, then leave it alone. + ! isolated island and is removed. If not, then it is dynamically connected + ! to other regions, so we leave it alone. do iCell = 1, nCells connectedCellsList(:) = -1 if (islandMask(iCell) == 1) then @@ -1182,6 +1188,10 @@ subroutine remove_small_islands(domain, err) ! Actually remove island if ( removeIsland ) then nIslandCellsLocal = nIslandCellsLocal + count + ! Note: nIslandCellsLocal may be inaccurate as neighbors or neighbors of neighbors to iCell + ! may get tallied multiple times from different members of islandMask. However, we only need + ! to know if nIslandCells>0, so this is ok. If we ever need an accurate value of nIslandCells, + ! some additional steps must be taken to avoid potential double counting. do n = 1, count calvingThickness(connectedCellsList(n)) = calvingThickness(connectedCellsList(n)) + & thickness(connectedCellsList(n)) From 0f9b78db2f4f77db99a0d43b889f65408bbb3394 Mon Sep 17 00:00:00 2001 From: Trevor Hillebrand Date: Wed, 10 Apr 2024 12:26:06 -0600 Subject: [PATCH 105/451] Apply more suggestions from code review Add another verbose comment. Co-authored-by: Matt Hoffman --- .../src/mode_forward/mpas_li_calving.F | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/components/mpas-albany-landice/src/mode_forward/mpas_li_calving.F b/components/mpas-albany-landice/src/mode_forward/mpas_li_calving.F index 5de1d6f5c7e3..054bc897574e 100644 --- a/components/mpas-albany-landice/src/mode_forward/mpas_li_calving.F +++ b/components/mpas-albany-landice/src/mode_forward/mpas_li_calving.F @@ -1123,10 +1123,15 @@ subroutine remove_small_islands(domain, err) endif enddo endif - ! If this grounded cell is dynamically connected to 1 or - ! fewer other grounded cells, then it should potentially - ! be removed. If its dynamic neighbors have other grounded - ! neighbors, then it is not an island. + ! Two checks that a grounded cell is NOT a 1 or 2 cell island: + ! 1. If a grounded cell has more than 1 grounded neighbor, it is not an island + ! This is the nGroundedNeighbors criterion. It gets re-evaluated with every + ! neighbor each time through the loop. It may not trigger on early checks + ! but it will trigger eventually if this cell has more than 1 grounded neighbor. + ! 2. If its dynamic neighbors have other grounded neighbors, then we do not + ! consider it an island. This is the nGroundedNeighborsJCell criterion. + ! Any grounded cells that survive these two checks are considered islands + ! and are further evaluated in the next phase. if ( (nGroundedNeighborsJCell > 1) .or. & (nGroundedNeighbors > 1) ) then islandMask(iCell) = 0 From e30be2d77f627c8fed81ffadf35a927cd430a5b2 Mon Sep 17 00:00:00 2001 From: Trevor Hillebrand Date: Wed, 10 Apr 2024 12:27:48 -0700 Subject: [PATCH 106/451] Add some further clarifying comments Add some further clarifying comments, and label phases 1 and 2. --- .../src/mode_forward/mpas_li_calving.F | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/components/mpas-albany-landice/src/mode_forward/mpas_li_calving.F b/components/mpas-albany-landice/src/mode_forward/mpas_li_calving.F index 054bc897574e..de2a523e9339 100644 --- a/components/mpas-albany-landice/src/mode_forward/mpas_li_calving.F +++ b/components/mpas-albany-landice/src/mode_forward/mpas_li_calving.F @@ -1095,12 +1095,14 @@ subroutine remove_small_islands(domain, err) growMask => growMaskField % array growMask(:) = 0 - ! Loop over cells to find one- and two-cell regions of grounded ice - ! that are not dynamically connected to other grounded regions, - ! which are "islands" that potentially need to be removed. + ! Phase 1: Loop over cells to find one- and two-cell regions of + ! grounded ice that are not dynamically connected to other grounded + ! regions, which are "islands" that potentially need to be removed. ! In this first phase we identify islands that meet these - ! criteria. In phase 2 below we check if islands are dynamically - ! connected to floating ice, which will disqualify them for removal. + ! criteria. In phase 2 below we check if islands are dynamically + ! connected to more extensive floating ice, which will disqualify + ! them for removal to avoid removing pinning points from ice + ! shelves, for example. do iCell = 1, nCells if (li_mask_is_grounded_ice(cellMask(iCell))) then islandMask(iCell) = 1 ! Potentially an island. Further evaluated below. @@ -1141,8 +1143,8 @@ subroutine remove_small_islands(domain, err) endif enddo - ! Determine whether to remove each island based on if it is dynamically - ! connected to other regions. For each cell in islandMask, + ! Phase 2: Determine whether to remove each island based on if it is + ! dynamically connected to other regions. For each cell in islandMask, ! first make a list of its dynamic neighbors. If the grounded island ! cell has a grounded neighbor, add that neighbor's dynamic neighbors ! to the list. Then, check that all the dynamic neighbors of the cells From fcb801bf90e7bd379b510e2c2ff3ee75e5992186 Mon Sep 17 00:00:00 2001 From: Walter Hannah Date: Fri, 12 Apr 2024 12:06:32 -0400 Subject: [PATCH 107/451] adjust white space --- components/eam/src/physics/crm/crm_physics.F90 | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/components/eam/src/physics/crm/crm_physics.F90 b/components/eam/src/physics/crm/crm_physics.F90 index 2beeded06bb3..51628d5ea74e 100644 --- a/components/eam/src/physics/crm/crm_physics.F90 +++ b/components/eam/src/physics/crm/crm_physics.F90 @@ -1384,8 +1384,8 @@ subroutine crm_physics_tend(ztodt, state, tend, ptend, pbuf2d, cam_in, cam_out, call pam_mirror_array_readwrite( 'output_ni_mean', crm_output%ni_mean, '' ) call pam_mirror_array_readwrite( 'output_qm_mean', crm_output%qm_mean, '' ) call pam_mirror_array_readwrite( 'output_bm_mean', crm_output%bm_mean, '' ) - call pam_mirror_array_readwrite( 'output_rho_d_mean', crm_output%rho_d_mean, '' ) - call pam_mirror_array_readwrite( 'output_rho_v_mean', crm_output%rho_v_mean, '' ) + call pam_mirror_array_readwrite( 'output_rho_d_mean', crm_output%rho_d_mean, '' ) + call pam_mirror_array_readwrite( 'output_rho_v_mean', crm_output%rho_v_mean, '' ) call pam_mirror_array_readwrite( 'output_qt_ls', crm_output%qt_ls, '' ) call pam_mirror_array_readwrite( 'output_t_ls', crm_output%t_ls, '' ) From 44ba5145df639f554be9e931740848f39a63464f Mon Sep 17 00:00:00 2001 From: Walter Hannah Date: Fri, 12 Apr 2024 12:13:13 -0400 Subject: [PATCH 108/451] change how PAM reference state pressure is set --- .../eam/src/physics/crm/pam/pam_state.h | 57 +++++++++---------- 1 file changed, 26 insertions(+), 31 deletions(-) diff --git a/components/eam/src/physics/crm/pam/pam_state.h b/components/eam/src/physics/crm/pam/pam_state.h index a34a867eb6e8..fb6553df07ef 100644 --- a/components/eam/src/physics/crm/pam/pam_state.h +++ b/components/eam/src/physics/crm/pam/pam_state.h @@ -108,6 +108,7 @@ inline void pam_state_set_reference_state( pam::PamCoupler &coupler ) { auto &dm_device = coupler.get_data_manager_device_readwrite(); auto nens = coupler.get_option("ncrms"); auto nz = coupler.get_option("crm_nz"); + auto gcm_nlev = coupler.get_option("gcm_nlev"); auto ref_presi = dm_device.get("ref_presi"); auto ref_pres = dm_device.get("ref_pres"); auto ref_rho_d = dm_device.get("ref_density_dry"); @@ -131,6 +132,14 @@ inline void pam_state_set_reference_state( pam::PamCoupler &coupler ) { auto rho_v = dm_device.get("water_vapor"); auto rho_c = dm_device.get("cloud_water"); auto rho_i = dm_device.get("ice"); + + auto &dm_host = coupler.get_data_manager_host_readonly(); + auto input_pmid = dm_host.get("input_pmid").createDeviceCopy(); + auto input_pint = dm_host.get("input_pint").createDeviceCopy(); + + auto lat = dm_host.get("latitude" ).createDeviceCopy(); + auto lon = dm_host.get("longitude" ).createDeviceCopy(); + auto input_phis = dm_host.get("input_phis").createDeviceCopy(); //------------------------------------------------------------------------------------------------ // Set anelastic reference state with current CRM mean state @@ -157,48 +166,34 @@ inline void pam_state_set_reference_state( pam::PamCoupler &coupler ) { }); // calculate horizontal means parallel_for(SimpleBounds<4>(nz,ny,nx,nens), YAKL_LAMBDA (int k, int j, int i, int iens) { - real pmid_tmp = rho_d(k,j,i,iens)*R_d*temp(k,j,i,iens) + rho_v(k,j,i,iens)*R_v*temp(k,j,i,iens); - atomicAdd( hmean_pmid (k,iens), pmid_tmp * r_nx_ny ); atomicAdd( hmean_rho_d(k,iens), rho_d (k,j,i,iens) * r_nx_ny ); atomicAdd( hmean_rho_v(k,iens), rho_v (k,j,i,iens) * r_nx_ny ); atomicAdd( hmean_rho_c(k,iens), rho_c (k,j,i,iens) * r_nx_ny ); atomicAdd( hmean_rho_i(k,iens), rho_i (k,j,i,iens) * r_nx_ny ); atomicAdd( hmean_temp (k,iens), temp (k,j,i,iens) * r_nx_ny ); }); - // calculate interface pressure from mid-level pressure - // parallel_for(SimpleBounds<4>(nz+1,ny,nx,nens) , YAKL_LAMBDA (int k, int j, int i, int iens) { - parallel_for(SimpleBounds<2>(nz+1,nens) , YAKL_LAMBDA (int k, int iens) { - if (k == 0 ) { - real rho = hmean_rho_d(k,iens)+hmean_rho_v(k,iens); - real dz = zint(k+1,iens)-zint(k,iens); - hmean_pint(k,iens) = hmean_pmid(k ,iens) + grav*rho*dz/2; - } else if (k == nz) { - real rho = hmean_rho_d(k-1,iens)+hmean_rho_v(k-1,iens); - real dz = zint(k,iens)-zint(k-1,iens); - hmean_pint(k,iens) = hmean_pmid(k-1,iens) - grav*rho*dz/2; - } else { - real rhokm1 = hmean_rho_d(k-1,iens)+hmean_rho_v(k-1,iens);; - real rhokm0 = hmean_rho_d(k ,iens)+hmean_rho_v(k ,iens); - real dzkm1 = zint(k ,iens)-zint(k-1,iens); - real dzkm0 = zint(k+1,iens)-zint(k ,iens); - hmean_pint(k,iens) = 0.5_fp * ( hmean_pmid(k-1,iens) - grav*rhokm1*dzkm1/2 + - hmean_pmid(k ,iens) + grav*rhokm0*dzkm0/2 ); - } + + // Use GCM state for reference pressure - previously, the current CRM pressure + // was used, but the way the interface pressure was calculated led to problems + // in edge cases (ex. over topography) - switching to GCM pressure works well + parallel_for( SimpleBounds<2>(nz+1,nens) , YAKL_LAMBDA (int k_crm, int iens) { + int k_gcm = (gcm_nlev+1)-1-k_crm; + hmean_pint(k_crm,iens) = input_pint(k_gcm,iens); + }); + parallel_for(SimpleBounds<2>(nz,nens), YAKL_LAMBDA (int k_crm, int iens) { + int k_gcm = gcm_nlev-1-k_crm; + hmean_pmid(k_crm,iens) = input_pmid(k_gcm,iens); }); - auto &dm_host = coupler.get_data_manager_host_readonly(); - auto lat = dm_host.get("latitude" ).createDeviceCopy(); - auto lon = dm_host.get("longitude" ).createDeviceCopy(); - auto input_phis = dm_host.get("input_phis").createDeviceCopy(); // check that interface pressure is reasonable - parallel_for(SimpleBounds<2>(nz+1,nens) , YAKL_LAMBDA (int k, int iens) { + parallel_for(SimpleBounds<2>(nz,nens) , YAKL_LAMBDA (int k, int iens) { if ( hmean_pint(k,iens) < hmean_pmid(k,iens) ) { auto phis = input_phis(iens)/grav; - printf("PAM-DEBUG bad-pint - k:%3.3d n:%3.3d y:%5.1f x:%5.1f ph:%6.1f -- pint:%8.2g pmid:%8.2g \n", - k,iens,lat(iens),lon(iens),phis, - hmean_pint(k,iens), - hmean_pmid(k,iens) - ); + printf("PAM-STATE - bad interface pressure for reference state - "+\ + "k:%3.3d n:%3.3d y:%5.1f x:%5.1f ph:%6.1f -- "+\ + "pint:%12.4f pmid:%12.4f \n", + k,iens,lat(iens),lon(iens),phis, + hmean_pint(k,iens),hmean_pmid(k,iens)); } }); From 8c8cb1c9e358119154f9ee4f974fc2d219a15c3b Mon Sep 17 00:00:00 2001 From: Walter Hannah Date: Fri, 12 Apr 2024 12:14:45 -0400 Subject: [PATCH 109/451] update PAM variance transport --- .../physics/crm/pam/pam_variance_transport.h | 39 ++++++++++--------- 1 file changed, 21 insertions(+), 18 deletions(-) diff --git a/components/eam/src/physics/crm/pam/pam_variance_transport.h b/components/eam/src/physics/crm/pam/pam_variance_transport.h index 1033df4280d4..ae9f0747ee31 100644 --- a/components/eam/src/physics/crm/pam/pam_variance_transport.h +++ b/components/eam/src/physics/crm/pam/pam_variance_transport.h @@ -38,6 +38,8 @@ inline void pam_variance_transport_diagnose( pam::PamCoupler &coupler ) { //------------------------------------------------------------------------------------------------ auto temp = dm_device.get("temp" ); auto rhov = dm_device.get("water_vapor"); + auto rhoc = dm_device.get("cloud_water"); + auto rhoi = dm_device.get("ice" ); auto uvel = dm_device.get("uvel" ); auto vt_temp = dm_device.get("vt_temp" ); auto vt_rhov = dm_device.get("vt_rhov" ); @@ -64,15 +66,17 @@ inline void pam_variance_transport_diagnose( pam::PamCoupler &coupler ) { // calculate horizontal mean real r_nx_ny = 1._fp/(nx*ny); // precompute reciprocal to avoid costly divisions parallel_for(SimpleBounds<4>(nz,ny,nx,nens), YAKL_LAMBDA (int k, int j, int i, int n) { + real rhot = rhov(k,j,i,n) + rhoc(k,j,i,n) + rhoi(k,j,i,n); yakl::atomicAdd( temp_mean(k,n), temp(k,j,i,n)*r_nx_ny ); - yakl::atomicAdd( rhov_mean(k,n), rhov(k,j,i,n)*r_nx_ny ); + yakl::atomicAdd( rhov_mean(k,n), rhot *r_nx_ny ); yakl::atomicAdd( uvel_mean(k,n), uvel(k,j,i,n)*r_nx_ny ); }); //------------------------------------------------------------------------------------------------ // calculate fluctuations from horz mean parallel_for(SimpleBounds<4>(nz,ny,nx,nens), YAKL_LAMBDA (int k, int j, int i, int n) { + real rhot = rhov(k,j,i,n) + rhoc(k,j,i,n) + rhoi(k,j,i,n); vt_temp_pert(k,j,i,n) = temp(k,j,i,n) - temp_mean(k,n); - vt_rhov_pert(k,j,i,n) = rhov(k,j,i,n) - rhov_mean(k,n); + vt_rhov_pert(k,j,i,n) = rhot - rhov_mean(k,n); vt_uvel_pert(k,j,i,n) = uvel(k,j,i,n) - uvel_mean(k,n); }); //------------------------------------------------------------------------------------------------ @@ -101,9 +105,6 @@ inline void pam_variance_transport_compute_forcing( pam::PamCoupler &coupler ) { // update CRM variance values pam_variance_transport_diagnose(coupler); //------------------------------------------------------------------------------------------------ - auto temp = dm_device.get("temp" ); - auto rhov = dm_device.get("water_vapor" ); - auto uvel = dm_device.get("uvel" ); auto vt_temp = dm_device.get("vt_temp" ); auto vt_rhov = dm_device.get("vt_rhov" ); auto vt_uvel = dm_device.get("vt_uvel" ); @@ -134,14 +135,16 @@ inline void pam_variance_transport_apply_forcing( pam::PamCoupler &coupler ) { auto nx = coupler.get_option("crm_nx"); auto crm_dt = coupler.get_option("crm_dt"); //------------------------------------------------------------------------------------------------ + // update CRM variance values + pam_variance_transport_diagnose(coupler); + //------------------------------------------------------------------------------------------------ // min and max perturbation scaling values are used to limit the // large-scale forcing from variance transport. This is meant to // protect against creating unstable situations, although // problematic scenarios were extremely rare in testing. - // A scaling limit of +/- 10% was found to be adequate in SAM, - // but PAM seems much more sensitive (not sure why), so we use 0.1% here - real constexpr pert_scale_min = 1.0 - 0.001; - real constexpr pert_scale_max = 1.0 + 0.001; + // A scaling limit of +/- 10% was found to be adequate. + real constexpr pert_scale_min = 1.0 - 0.1; + real constexpr pert_scale_max = 1.0 + 0.1; //------------------------------------------------------------------------------------------------ auto temp = dm_device.get("temp" ); auto rhov = dm_device.get("water_vapor" ); @@ -161,9 +164,6 @@ inline void pam_variance_transport_apply_forcing( pam::PamCoupler &coupler ) { real2d rhov_pert_scale("rhov_pert_scale", nz, nens); real2d uvel_pert_scale("uvel_pert_scale", nz, nens); //------------------------------------------------------------------------------------------------ - // update CRM variance values - pam_variance_transport_diagnose(coupler); - //------------------------------------------------------------------------------------------------ // calculate scaling factor for local perturbations parallel_for( SimpleBounds<2>(nz,nens) , YAKL_LAMBDA (int k, int n) { real tmp; @@ -172,9 +172,15 @@ inline void pam_variance_transport_apply_forcing( pam::PamCoupler &coupler ) { rhov_pert_scale(k,n) = 1.0; uvel_pert_scale(k,n) = 1.0; // calculate variance scaling factor - tmp = 1.+crm_dt*vt_temp_forcing_tend(k,n)/vt_temp(k,n); if (tmp>0){ temp_pert_scale(k,n) = sqrt(tmp); } - tmp = 1.+crm_dt*vt_rhov_forcing_tend(k,n)/vt_rhov(k,n); if (tmp>0){ rhov_pert_scale(k,n) = sqrt(tmp); } - tmp = 1.+crm_dt*vt_uvel_forcing_tend(k,n)/vt_uvel(k,n); if (tmp>0){ uvel_pert_scale(k,n) = sqrt(tmp); } + real tmp_t_scale = -1.0; + real tmp_q_scale = -1.0; + real tmp_u_scale = -1.0; + if (vt_temp(k,n)>0.0) { tmp_t_scale = 1. + crm_dt*vt_temp_forcing_tend(k,n) / vt_temp(k,n); } + if (vt_rhov(k,n)>0.0) { tmp_q_scale = 1. + crm_dt*vt_rhov_forcing_tend(k,n) / vt_rhov(k,n); } + if (vt_uvel(k,n)>0.0) { tmp_u_scale = 1. + crm_dt*vt_uvel_forcing_tend(k,n) / vt_uvel(k,n); } + if (tmp>0.0){ temp_pert_scale(k,n) = sqrt(tmp_t_scale); } + if (tmp>0.0){ rhov_pert_scale(k,n) = sqrt(tmp_q_scale); } + if (tmp>0.0){ uvel_pert_scale(k,n) = sqrt(tmp_u_scale); } // enforce minimum scaling temp_pert_scale(k,n) = std::max( temp_pert_scale(k,n), pert_scale_min ); rhov_pert_scale(k,n) = std::max( rhov_pert_scale(k,n), pert_scale_min ); @@ -213,9 +219,6 @@ inline void pam_variance_transport_compute_feedback( pam::PamCoupler &coupler ) // update CRM variance values pam_variance_transport_diagnose(coupler); //------------------------------------------------------------------------------------------------ - auto temp = dm_device.get("temp" ); - auto rhov = dm_device.get("water_vapor"); - auto uvel = dm_device.get("uvel" ); auto vt_temp = dm_device.get("vt_temp" ); auto vt_rhov = dm_device.get("vt_rhov" ); auto vt_uvel = dm_device.get("vt_uvel" ); From 98726502a74a6067dd2f4e96c04db227e5f3a790 Mon Sep 17 00:00:00 2001 From: Walter Hannah Date: Fri, 12 Apr 2024 12:16:11 -0400 Subject: [PATCH 110/451] update MMF2 default config --- components/eam/cime_config/config_component.xml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/components/eam/cime_config/config_component.xml b/components/eam/cime_config/config_component.xml index 784fe44195ed..056b607953f9 100755 --- a/components/eam/cime_config/config_component.xml +++ b/components/eam/cime_config/config_component.xml @@ -72,15 +72,15 @@ -crm samxx -crm_dt 10 - -crm pam -pam_dycor spam -crm_dt 5 - -crm pam -pam_dycor awfl -crm_dt 5 + -crm pam -pam_dycor spam -crm_dt 10 + -crm pam -pam_dycor awfl -crm_dt 10 -use_MMF -nlev 60 -crm_nz 50 -crm_dx 2000 -crm_nx 64 -crm_ny 1 -crm_nx_rad 4 -crm_ny_rad 1 -crm_dx 2000 -crm_nx 45 -crm_ny 1 -crm_nx_rad 5 -crm_ny_rad 1 -MMF_microphysics_scheme sam1mom -chem none -MMF_microphysics_scheme p3 -chem none -rad rrtmgp -rrtmgpxx - -use_MMF_VT + -use_MMF_VT -use_MMF_ESMT -aquaplanet -aquaplanet -rce From 2380d339ca04b8f6c878d2fcfdf76ecaa408663f Mon Sep 17 00:00:00 2001 From: Walter Hannah Date: Fri, 12 Apr 2024 12:29:53 -0400 Subject: [PATCH 111/451] bug fix in PAM variance transport --- .../eam/src/physics/crm/pam/pam_variance_transport.h | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/components/eam/src/physics/crm/pam/pam_variance_transport.h b/components/eam/src/physics/crm/pam/pam_variance_transport.h index ae9f0747ee31..e258b3b7f3ad 100644 --- a/components/eam/src/physics/crm/pam/pam_variance_transport.h +++ b/components/eam/src/physics/crm/pam/pam_variance_transport.h @@ -143,8 +143,8 @@ inline void pam_variance_transport_apply_forcing( pam::PamCoupler &coupler ) { // protect against creating unstable situations, although // problematic scenarios were extremely rare in testing. // A scaling limit of +/- 10% was found to be adequate. - real constexpr pert_scale_min = 1.0 - 0.1; - real constexpr pert_scale_max = 1.0 + 0.1; + real constexpr pert_scale_min = 1.0 - 0.05; + real constexpr pert_scale_max = 1.0 + 0.05; //------------------------------------------------------------------------------------------------ auto temp = dm_device.get("temp" ); auto rhov = dm_device.get("water_vapor" ); @@ -166,7 +166,6 @@ inline void pam_variance_transport_apply_forcing( pam::PamCoupler &coupler ) { //------------------------------------------------------------------------------------------------ // calculate scaling factor for local perturbations parallel_for( SimpleBounds<2>(nz,nens) , YAKL_LAMBDA (int k, int n) { - real tmp; // initialize scaling factors to 1.0 temp_pert_scale(k,n) = 1.0; rhov_pert_scale(k,n) = 1.0; @@ -178,9 +177,9 @@ inline void pam_variance_transport_apply_forcing( pam::PamCoupler &coupler ) { if (vt_temp(k,n)>0.0) { tmp_t_scale = 1. + crm_dt*vt_temp_forcing_tend(k,n) / vt_temp(k,n); } if (vt_rhov(k,n)>0.0) { tmp_q_scale = 1. + crm_dt*vt_rhov_forcing_tend(k,n) / vt_rhov(k,n); } if (vt_uvel(k,n)>0.0) { tmp_u_scale = 1. + crm_dt*vt_uvel_forcing_tend(k,n) / vt_uvel(k,n); } - if (tmp>0.0){ temp_pert_scale(k,n) = sqrt(tmp_t_scale); } - if (tmp>0.0){ rhov_pert_scale(k,n) = sqrt(tmp_q_scale); } - if (tmp>0.0){ uvel_pert_scale(k,n) = sqrt(tmp_u_scale); } + if (tmp_t_scale>0.0){ temp_pert_scale(k,n) = sqrt(tmp_t_scale); } + if (tmp_q_scale>0.0){ rhov_pert_scale(k,n) = sqrt(tmp_q_scale); } + if (tmp_u_scale>0.0){ uvel_pert_scale(k,n) = sqrt(tmp_u_scale); } // enforce minimum scaling temp_pert_scale(k,n) = std::max( temp_pert_scale(k,n), pert_scale_min ); rhov_pert_scale(k,n) = std::max( rhov_pert_scale(k,n), pert_scale_min ); From 63df74c0bb17552d825f55cb3b04edc5f5b83014 Mon Sep 17 00:00:00 2001 From: Walter Hannah Date: Fri, 12 Apr 2024 12:30:50 -0400 Subject: [PATCH 112/451] implement PAM driver subcycling --- .../eam/src/physics/crm/pam/pam_driver.cpp | 173 ++++++++++++------ 1 file changed, 122 insertions(+), 51 deletions(-) diff --git a/components/eam/src/physics/crm/pam/pam_driver.cpp b/components/eam/src/physics/crm/pam/pam_driver.cpp index 69e67a90894c..0833d2beff8d 100644 --- a/components/eam/src/physics/crm/pam/pam_driver.cpp +++ b/components/eam/src/physics/crm/pam/pam_driver.cpp @@ -1,5 +1,4 @@ #include "pam_coupler.h" -// #include "params.h" #include "Dycore.h" #include "Microphysics.h" #include "SGS.h" @@ -14,26 +13,90 @@ #include "pam_output.h" #include "pam_accelerate.h" #include "pam_variance_transport.h" +#include "pam_hyperdiffusion.h" #include "sponge_layer.h" #include "surface_friction.h" #include "scream_cxx_interface_finalize.h" -#include "pam_hyperdiffusion.h" - // Needed for p3_init #include "p3_functions.hpp" #include "p3_f90.hpp" #include "pam_debug.h" -bool constexpr enable_check_state = true; +bool constexpr enable_check_state = false; -extern "C" void pam_driver() { + +inline int pam_driver_set_subcycle_timestep( pam::PamCoupler &coupler, real crm_dt_fixed ) { + // calculate the CFL condition and adjust the PAM time loop subcylcing //------------------------------------------------------------------------------------------------ - using yakl::intrinsics::abs; - using yakl::intrinsics::maxval; - using yakl::atomicAdd; using yakl::c::parallel_for; using yakl::c::SimpleBounds; + using yakl::atomicMax; + //------------------------------------------------------------------------------------------------ + auto nens = coupler.get_option("ncrms"); + auto gcm_nlev = coupler.get_option("gcm_nlev"); + auto crm_nz = coupler.get_option("crm_nz"); + auto crm_nx = coupler.get_option("crm_nx"); + auto crm_ny = coupler.get_option("crm_ny"); + auto crm_dx = coupler.get_option("crm_dx"); + auto crm_dy = coupler.get_option("crm_dy"); + auto &dm_device = coupler.get_data_manager_device_readonly(); + auto &dm_host = coupler.get_data_manager_host_readonly(); + auto uvel = dm_device.get("uvel"); + auto wvel = dm_device.get("wvel"); + auto input_zint = dm_host.get("input_zint").createDeviceCopy(); + //------------------------------------------------------------------------------------------------ + yakl::ParallelMax pmax( crm_nz*nens ); + real cfl = 0; + int num_subcycle = 1; + int constexpr max_num_subcycle = 10; + real2d wvel_max("wvel_max",crm_nz,nens); + real2d uvel_max("uvel_max",crm_nz,nens); + real2d cfl_max("cfl_max", crm_nz,nens); + //------------------------------------------------------------------------------------------------ + // initialize max U and W arrays + parallel_for( SimpleBounds<2>(crm_nz,nens) , YAKL_LAMBDA (int k, int n) { + wvel_max(k,n) = 0.0; + uvel_max(k,n) = 0.0; + }); + // calculate max U and W + parallel_for( SimpleBounds<4>(crm_nz,crm_ny,crm_nx,nens) , YAKL_LAMBDA (int k, int j, int i, int n) { + yakl::atomicMax(uvel_max(k,n), sqrt(uvel(k,j,i,n)*uvel(k,j,i,n)) ); + yakl::atomicMax(wvel_max(k,n), fabs(wvel(k,j,i,n)) ); + }); + // find max CFL between horizontal and vertical CFL values + parallel_for( SimpleBounds<2>(crm_nz,nens) , YAKL_LAMBDA (int k, int n) { + int k_gcm = gcm_nlev-1-k; + real crm_dz = input_zint(k_gcm,n) - input_zint(k_gcm+1,n); + real cfl_u = uvel_max(k,n)*crm_dt_fixed/crm_dx; + real cfl_w = wvel_max(k,n)*crm_dt_fixed/crm_dz; + cfl_max(k,n) = max(cfl_u,cfl_w); + }); + // calculate final CFL across ensemble + real cfl_loc = pmax(cfl_max.data()); + cfl = max(cfl,cfl_loc); + // update number of subcycles and time step + num_subcycle = max(num_subcycle,max(1,static_cast(ceil(cfl/0.7)))); + real crm_dt_subcycle = crm_dt_fixed / num_subcycle; + coupler.set_option("crm_dt",crm_dt_subcycle); + // check for excessive subcylcing - don't exit, just print + if(num_subcycle > max_num_subcycle) { + real umax = pmax(uvel_max.data()); + real wmax = pmax(wvel_max.data()); + printf("PAM_DRIVER - WARNING: excessive subcycling!"+\ + " - num_subcycle: %3.3d dt: %8.4f cfl: %8.4f umax: %8.2f wmax: %8.2f \n", + num_subcycle,crm_dt_subcycle,cfl,umax,wmax); + // exit(-1); + } + + return num_subcycle; + //------------------------------------------------------------------------------------------------ +} + + +extern "C" void pam_driver() { + // This is the primary method for running the PAM CRM in E3SM-MMF. + //------------------------------------------------------------------------------------------------ auto &coupler = pam_interface::get_coupler(); //------------------------------------------------------------------------------------------------ // retreive coupler options @@ -42,8 +105,10 @@ extern "C" void pam_driver() { auto crm_nz = coupler.get_option("crm_nz"); auto crm_nx = coupler.get_option("crm_nx"); auto crm_ny = coupler.get_option("crm_ny"); + // auto crm_dx = coupler.get_option("crm_dx"); + // auto crm_dy = coupler.get_option("crm_dy"); auto gcm_dt = coupler.get_option("gcm_dt"); - auto crm_dt = coupler.get_option("crm_dt"); + auto crm_dt_fixed = coupler.get_option("crm_dt"); auto is_first_step = coupler.get_option("is_first_step"); auto is_restart = coupler.get_option("is_restart"); bool use_crm_accel = coupler.get_option("use_crm_accel"); @@ -162,7 +227,7 @@ extern "C" void pam_driver() { //------------------------------------------------------------------------------------------------ // set number of CRM steps - int nstop = int(gcm_dt/crm_dt); + int nstop = int(gcm_dt/crm_dt_fixed); // for mean-state acceleration adjust nstop and diagnose horizontal means if (use_crm_accel) { @@ -171,51 +236,58 @@ extern "C" void pam_driver() { }; // Run the CRM - real etime_crm = 0; int nstep = 0; - // while (etime_crm < gcm_dt) { while (nstep < nstop) { - if (crm_dt == 0.) { crm_dt = dycore.compute_time_step(coupler); } - if (etime_crm + crm_dt > gcm_dt) { crm_dt = gcm_dt - etime_crm; } + //-------------------------------------------------------------------------- + //-------------------------------------------------------------------------- + auto num_subcycle = pam_driver_set_subcycle_timestep(coupler,crm_dt_fixed); + #if defined(MMF_PAM_DYCOR_SPAM) + dycore.update_dt(coupler); + #endif if (enable_check_state) { pam_debug_check_state(coupler, 1, nstep); } - // Apply forcing tendencies - if (use_MMF_VT) { pam_variance_transport_apply_forcing(coupler); } - if (enable_check_state) { pam_debug_check_state(coupler, 2, nstep); } - coupler.run_module( "apply_gcm_forcing_tendencies" , modules::apply_gcm_forcing_tendencies ); - if (enable_check_state) { pam_debug_check_state(coupler, 3, nstep); } - coupler.run_module( "radiation" , [&] (pam::PamCoupler &coupler) {rad .timeStep(coupler);} ); - if (enable_check_state) { pam_debug_check_state(coupler, 4, nstep); } - - // Dynamics - if (enable_physics_tend_stats) { pam_statistics_save_state(coupler); } - if (do_density_save_recall) { pam_state_save_dry_density(coupler); } - coupler.run_module( "dycore", [&] (pam::PamCoupler &coupler) {dycore.timeStep(coupler);} ); - if (do_density_save_recall) { pam_state_recall_dry_density(coupler); } - if (enable_physics_tend_stats) { pam_statistics_aggregate_tendency(coupler,"dycor"); } - if (enable_check_state) { pam_debug_check_state(coupler, 5, nstep); } - - // Sponge layer damping - if (enable_physics_tend_stats) { pam_statistics_save_state(coupler); } - coupler.run_module( "sponge_layer", modules::sponge_layer ); - if (enable_physics_tend_stats) { pam_statistics_aggregate_tendency(coupler,"sponge"); } - - // Apply hyperdiffusion to account for lack of horizontal mixing in SHOC - pam_hyperdiffusion(coupler); - - // Turbulence - SHOC - coupler.run_module( "compute_surface_friction", modules::compute_surface_friction ); - if (enable_physics_tend_stats) { pam_statistics_save_state(coupler); } - coupler.run_module( "sgs", [&] (pam::PamCoupler &coupler) {sgs .timeStep(coupler);} ); - if (enable_physics_tend_stats) { pam_statistics_aggregate_tendency(coupler,"sgs"); } - if (enable_check_state) { pam_debug_check_state(coupler, 6, nstep); } - - // Microphysics - P3 - if (enable_physics_tend_stats) { pam_statistics_save_state(coupler); } - coupler.run_module( "micro", [&] (pam::PamCoupler &coupler) {micro .timeStep(coupler);} ); - if (enable_physics_tend_stats) { pam_statistics_aggregate_tendency(coupler,"micro"); } - if (enable_check_state) { pam_debug_check_state(coupler, 7, nstep); } + // loop for adaptive subcyling based on CFL + for(int icycle=1; icycle<=num_subcycle; icycle++) { + + // Apply forcing tendencies + if (use_MMF_VT) { pam_variance_transport_apply_forcing(coupler); } + if (enable_check_state) { pam_debug_check_state(coupler, 2, nstep); } + coupler.run_module( "apply_gcm_forcing_tendencies" , modules::apply_gcm_forcing_tendencies ); + if (enable_check_state) { pam_debug_check_state(coupler, 3, nstep); } + coupler.run_module( "radiation" , [&] (pam::PamCoupler &coupler) {rad .timeStep(coupler);} ); + if (enable_check_state) { pam_debug_check_state(coupler, 4, nstep); } + + // Dynamics + if (enable_physics_tend_stats) { pam_statistics_save_state(coupler); } + if (do_density_save_recall) { pam_state_save_dry_density(coupler); } + coupler.run_module( "dycore", [&] (pam::PamCoupler &coupler) {dycore.timeStep(coupler);} ); + if (do_density_save_recall) { pam_state_recall_dry_density(coupler); } + if (enable_physics_tend_stats) { pam_statistics_aggregate_tendency(coupler,"dycor"); } + if (enable_check_state) { pam_debug_check_state(coupler, 5, nstep); } + + // Sponge layer damping + if (enable_physics_tend_stats) { pam_statistics_save_state(coupler); } + coupler.run_module( "sponge_layer", modules::sponge_layer ); + if (enable_physics_tend_stats) { pam_statistics_aggregate_tendency(coupler,"sponge"); } + + // Apply hyperdiffusion to account for lack of horizontal mixing in SHOC + pam_hyperdiffusion(coupler); + + // Turbulence - SHOC + coupler.run_module( "compute_surface_friction", modules::compute_surface_friction ); + if (enable_physics_tend_stats) { pam_statistics_save_state(coupler); } + coupler.run_module( "sgs", [&] (pam::PamCoupler &coupler) {sgs .timeStep(coupler);} ); + if (enable_physics_tend_stats) { pam_statistics_aggregate_tendency(coupler,"sgs"); } + if (enable_check_state) { pam_debug_check_state(coupler, 6, nstep); } + + // Microphysics - P3 + if (enable_physics_tend_stats) { pam_statistics_save_state(coupler); } + coupler.run_module( "micro", [&] (pam::PamCoupler &coupler) {micro .timeStep(coupler);} ); + if (enable_physics_tend_stats) { pam_statistics_aggregate_tendency(coupler,"micro"); } + if (enable_check_state) { pam_debug_check_state(coupler, 7, nstep); } + + } // num_subcycle // CRM mean state acceleration if (use_crm_accel && !coupler.get_option("crm_acceleration_ceaseflag")) { @@ -227,7 +299,6 @@ extern "C" void pam_driver() { pam_radiation_timestep_aggregation(coupler); pam_statistics_timestep_aggregation(coupler); - etime_crm += crm_dt; nstep += 1; } //------------------------------------------------------------------------------------------------ From 7cc042a07306b2370931de60e03cc077f70f8454 Mon Sep 17 00:00:00 2001 From: Walter Hannah Date: Fri, 12 Apr 2024 13:47:26 -0400 Subject: [PATCH 113/451] bug fix --- components/eam/src/physics/crm/pam/pam_driver.cpp | 2 +- components/eam/src/physics/crm/pam/pam_state.h | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/components/eam/src/physics/crm/pam/pam_driver.cpp b/components/eam/src/physics/crm/pam/pam_driver.cpp index 0833d2beff8d..a05b5cf8b037 100644 --- a/components/eam/src/physics/crm/pam/pam_driver.cpp +++ b/components/eam/src/physics/crm/pam/pam_driver.cpp @@ -83,7 +83,7 @@ inline int pam_driver_set_subcycle_timestep( pam::PamCoupler &coupler, real crm_ if(num_subcycle > max_num_subcycle) { real umax = pmax(uvel_max.data()); real wmax = pmax(wvel_max.data()); - printf("PAM_DRIVER - WARNING: excessive subcycling!"+\ + printf("PAM_DRIVER - WARNING: excessive subcycling!" " - num_subcycle: %3.3d dt: %8.4f cfl: %8.4f umax: %8.2f wmax: %8.2f \n", num_subcycle,crm_dt_subcycle,cfl,umax,wmax); // exit(-1); diff --git a/components/eam/src/physics/crm/pam/pam_state.h b/components/eam/src/physics/crm/pam/pam_state.h index fb6553df07ef..270fef7f6c23 100644 --- a/components/eam/src/physics/crm/pam/pam_state.h +++ b/components/eam/src/physics/crm/pam/pam_state.h @@ -189,8 +189,8 @@ inline void pam_state_set_reference_state( pam::PamCoupler &coupler ) { parallel_for(SimpleBounds<2>(nz,nens) , YAKL_LAMBDA (int k, int iens) { if ( hmean_pint(k,iens) < hmean_pmid(k,iens) ) { auto phis = input_phis(iens)/grav; - printf("PAM-STATE - bad interface pressure for reference state - "+\ - "k:%3.3d n:%3.3d y:%5.1f x:%5.1f ph:%6.1f -- "+\ + printf("PAM-STATE - bad interface pressure for reference state - " + "k:%3.3d n:%3.3d y:%5.1f x:%5.1f ph:%6.1f -- " "pint:%12.4f pmid:%12.4f \n", k,iens,lat(iens),lon(iens),phis, hmean_pint(k,iens),hmean_pmid(k,iens)); From f714cf4e2d6612210692eecdf5b2e4eda3a82933 Mon Sep 17 00:00:00 2001 From: Walter Hannah Date: Fri, 12 Apr 2024 13:48:07 -0400 Subject: [PATCH 114/451] bug fix in PAM variance transport --- .../physics/crm/pam/pam_variance_transport.h | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/components/eam/src/physics/crm/pam/pam_variance_transport.h b/components/eam/src/physics/crm/pam/pam_variance_transport.h index e258b3b7f3ad..1eb7779f3469 100644 --- a/components/eam/src/physics/crm/pam/pam_variance_transport.h +++ b/components/eam/src/physics/crm/pam/pam_variance_transport.h @@ -118,9 +118,9 @@ inline void pam_variance_transport_compute_forcing( pam::PamCoupler &coupler ) { // calculate variance transport forcing parallel_for( SimpleBounds<2>(nz,nens) , YAKL_LAMBDA (int k_crm, int n) { int k_gcm = gcm_nlev-1-k_crm; - vt_temp_forcing_tend(k_crm,n) = ( gcm_vt_temp(k_gcm,n) - vt_temp(k_crm,n) ) * gcm_dt ; - vt_rhov_forcing_tend(k_crm,n) = ( gcm_vt_rhov(k_gcm,n) - vt_rhov(k_crm,n) ) * gcm_dt ; - vt_uvel_forcing_tend(k_crm,n) = ( gcm_vt_uvel(k_gcm,n) - vt_uvel(k_crm,n) ) * gcm_dt ; + vt_temp_forcing_tend(k_crm,n) = ( gcm_vt_temp(k_gcm,n) - vt_temp(k_crm,n) ) / gcm_dt ; + vt_rhov_forcing_tend(k_crm,n) = ( gcm_vt_rhov(k_gcm,n) - vt_rhov(k_crm,n) ) / gcm_dt ; + vt_uvel_forcing_tend(k_crm,n) = ( gcm_vt_uvel(k_gcm,n) - vt_uvel(k_crm,n) ) / gcm_dt ; }); //------------------------------------------------------------------------------------------------ } @@ -174,9 +174,9 @@ inline void pam_variance_transport_apply_forcing( pam::PamCoupler &coupler ) { real tmp_t_scale = -1.0; real tmp_q_scale = -1.0; real tmp_u_scale = -1.0; - if (vt_temp(k,n)>0.0) { tmp_t_scale = 1. + crm_dt*vt_temp_forcing_tend(k,n) / vt_temp(k,n); } - if (vt_rhov(k,n)>0.0) { tmp_q_scale = 1. + crm_dt*vt_rhov_forcing_tend(k,n) / vt_rhov(k,n); } - if (vt_uvel(k,n)>0.0) { tmp_u_scale = 1. + crm_dt*vt_uvel_forcing_tend(k,n) / vt_uvel(k,n); } + if (vt_temp(k,n)>0.0) { tmp_t_scale = 1. + crm_dt * vt_temp_forcing_tend(k,n) / vt_temp(k,n); } + if (vt_rhov(k,n)>0.0) { tmp_q_scale = 1. + crm_dt * vt_rhov_forcing_tend(k,n) / vt_rhov(k,n); } + if (vt_uvel(k,n)>0.0) { tmp_u_scale = 1. + crm_dt * vt_uvel_forcing_tend(k,n) / vt_uvel(k,n); } if (tmp_t_scale>0.0){ temp_pert_scale(k,n) = sqrt(tmp_t_scale); } if (tmp_q_scale>0.0){ rhov_pert_scale(k,n) = sqrt(tmp_q_scale); } if (tmp_u_scale>0.0){ uvel_pert_scale(k,n) = sqrt(tmp_u_scale); } @@ -236,9 +236,9 @@ inline void pam_variance_transport_compute_feedback( pam::PamCoupler &coupler ) parallel_for( SimpleBounds<2>(nz,nens) , YAKL_LAMBDA (int k_crm, int n) { int k_gcm = gcm_nlev-1-k_crm; if (k_crm Date: Fri, 12 Apr 2024 13:48:58 -0400 Subject: [PATCH 115/451] update default MMF_PAM_dyn_per_phys --- components/eam/bld/namelist_files/namelist_defaults_eam.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/components/eam/bld/namelist_files/namelist_defaults_eam.xml b/components/eam/bld/namelist_files/namelist_defaults_eam.xml index 74f2572ea040..d7e9afecf20e 100755 --- a/components/eam/bld/namelist_files/namelist_defaults_eam.xml +++ b/components/eam/bld/namelist_files/namelist_defaults_eam.xml @@ -871,7 +871,7 @@ 0 .false. .true. - 2 + 1 90.0 0.0 From 98a6e4025e9617bfdd0ba27699fa69bbbd959772 Mon Sep 17 00:00:00 2001 From: Walter Hannah Date: Fri, 12 Apr 2024 15:22:03 -0400 Subject: [PATCH 116/451] update default PAM hyperdiffusion timescale --- components/eam/src/physics/crm/pam/pam_hyperdiffusion.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/components/eam/src/physics/crm/pam/pam_hyperdiffusion.h b/components/eam/src/physics/crm/pam/pam_hyperdiffusion.h index b632b0e49093..e75d80265445 100644 --- a/components/eam/src/physics/crm/pam/pam_hyperdiffusion.h +++ b/components/eam/src/physics/crm/pam/pam_hyperdiffusion.h @@ -28,7 +28,7 @@ inline void pam_hyperdiffusion( pam::PamCoupler &coupler ) { #ifdef MMF_PAM_HDT real constexpr hd_timescale = MMF_PAM_HDT; // damping time scale [sec] #else - real constexpr hd_timescale = 60.0; // damping time scale [sec] + real constexpr hd_timescale = 120.0; // damping time scale [sec] #endif //------------------------------------------------------------------------------------------------ real4d hd_temp("hd_temp",nz,ny,nx,nens); From 2c54c4d9aa7db1659374433517d7a2636357c690 Mon Sep 17 00:00:00 2001 From: Walter Hannah Date: Fri, 12 Apr 2024 15:22:46 -0400 Subject: [PATCH 117/451] update PAM default crm_dx to 3km --- components/eam/cime_config/config_component.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/components/eam/cime_config/config_component.xml b/components/eam/cime_config/config_component.xml index 056b607953f9..ef9433ef9664 100755 --- a/components/eam/cime_config/config_component.xml +++ b/components/eam/cime_config/config_component.xml @@ -76,7 +76,7 @@ -crm pam -pam_dycor awfl -crm_dt 10 -use_MMF -nlev 60 -crm_nz 50 -crm_dx 2000 -crm_nx 64 -crm_ny 1 -crm_nx_rad 4 -crm_ny_rad 1 - -crm_dx 2000 -crm_nx 45 -crm_ny 1 -crm_nx_rad 5 -crm_ny_rad 1 + -crm_dx 3000 -crm_nx 45 -crm_ny 1 -crm_nx_rad 5 -crm_ny_rad 1 -MMF_microphysics_scheme sam1mom -chem none -MMF_microphysics_scheme p3 -chem none -rad rrtmgp -rrtmgpxx From 289951d1eb76f89b40a77fde44d1ea46ce153b61 Mon Sep 17 00:00:00 2001 From: Trevor Hillebrand Date: Sat, 13 Apr 2024 08:53:43 -0700 Subject: [PATCH 118/451] Remove icebergs in each RK stage Remove icebergs in each RK stage. When ice-shelves melt through in during an intermedite RK stage, they can leave behind icebergs that will cause the velocity solver to fail. So, we need to remove icebergs before each call to the velocity solver. --- .../src/mode_forward/mpas_li_calving.F | 9 +++++---- .../src/mode_forward/mpas_li_time_integration_fe_rk.F | 9 ++++++++- 2 files changed, 13 insertions(+), 5 deletions(-) diff --git a/components/mpas-albany-landice/src/mode_forward/mpas_li_calving.F b/components/mpas-albany-landice/src/mode_forward/mpas_li_calving.F index de2a523e9339..a460c3224a0e 100644 --- a/components/mpas-albany-landice/src/mode_forward/mpas_li_calving.F +++ b/components/mpas-albany-landice/src/mode_forward/mpas_li_calving.F @@ -45,7 +45,8 @@ module li_calving !-------------------------------------------------------------------- public :: li_calve_ice, li_restore_calving_front, li_apply_front_ablation_velocity, & - li_calculate_damage, li_finalize_damage_after_advection, li_flood_fill + li_calculate_damage, li_finalize_damage_after_advection, li_flood_fill, & + li_remove_icebergs !-------------------------------------------------------------------- ! @@ -325,7 +326,7 @@ subroutine li_calve_ice(domain, err, solveVeloAfterCalving) call li_calculate_mask(meshPool, velocityPool, geometryPool, err_tmp) ! now also remove any icebergs - call remove_icebergs(domain) + call li_remove_icebergs(domain) call li_calculate_mask(meshPool, velocityPool, geometryPool, err_tmp) @@ -4208,7 +4209,7 @@ subroutine calculate_calving_front_mask(meshPool, geometryPool, calvingFrontMask end subroutine calculate_calving_front_mask - subroutine remove_icebergs(domain) + subroutine li_remove_icebergs(domain) !----------------------------------------------------------------- ! input/output variables !----------------------------------------------------------------- @@ -4362,7 +4363,7 @@ subroutine remove_icebergs(domain) call mpas_deallocate_scratch_field(growMaskField, single_block_in=.false.) call mpas_log_write("Iceberg-detection flood-fill complete. Removed $i iceberg cells.", intArgs=(/globalIcebergCellCount/)) call mpas_timer_stop("iceberg detection") - end subroutine remove_icebergs + end subroutine li_remove_icebergs !||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||| ! diff --git a/components/mpas-albany-landice/src/mode_forward/mpas_li_time_integration_fe_rk.F b/components/mpas-albany-landice/src/mode_forward/mpas_li_time_integration_fe_rk.F index 6ca13f8deb0d..e4c58cc42b11 100644 --- a/components/mpas-albany-landice/src/mode_forward/mpas_li_time_integration_fe_rk.F +++ b/components/mpas-albany-landice/src/mode_forward/mpas_li_time_integration_fe_rk.F @@ -29,7 +29,9 @@ module li_time_integration_fe_rk use mpas_log use li_advection - use li_calving, only: li_calve_ice, li_restore_calving_front, li_calculate_damage, li_finalize_damage_after_advection + use li_calving, only: li_calve_ice, li_restore_calving_front, & + li_remove_icebergs, li_calculate_damage, & + li_finalize_damage_after_advection use li_thermal, only: li_thermal_solver, li_enthalpy_to_temperature_kelvin use li_iceshelf_melt use li_diagnostic_vars @@ -481,6 +483,11 @@ subroutine li_time_integrator_forwardeuler_rungekutta(domain, err) call li_restore_calving_front(domain, err_tmp) err = ior(err, err_tmp) endif + ! We need to remove icebergs between RK stages because the + ! main calving routine is not called until after the RK loop. + ! This frequently results in icebergs that causes intermediate + ! RK stage velocity solves to fail. + call li_remove_icebergs(domain) call li_velocity_solve(domain, solveVelo=.true., err=err_tmp) err = ior(err, err_tmp) From 748ad0a808b404ebb3cb43b5032c7f663c3cf177 Mon Sep 17 00:00:00 2001 From: Walter Hannah Date: Wed, 17 Apr 2024 18:58:56 -0400 Subject: [PATCH 119/451] reduce hd_timescale back to 60 sec fr PAM --- components/eam/src/physics/crm/pam/pam_hyperdiffusion.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/components/eam/src/physics/crm/pam/pam_hyperdiffusion.h b/components/eam/src/physics/crm/pam/pam_hyperdiffusion.h index e75d80265445..b632b0e49093 100644 --- a/components/eam/src/physics/crm/pam/pam_hyperdiffusion.h +++ b/components/eam/src/physics/crm/pam/pam_hyperdiffusion.h @@ -28,7 +28,7 @@ inline void pam_hyperdiffusion( pam::PamCoupler &coupler ) { #ifdef MMF_PAM_HDT real constexpr hd_timescale = MMF_PAM_HDT; // damping time scale [sec] #else - real constexpr hd_timescale = 120.0; // damping time scale [sec] + real constexpr hd_timescale = 60.0; // damping time scale [sec] #endif //------------------------------------------------------------------------------------------------ real4d hd_temp("hd_temp",nz,ny,nx,nens); From 6b92cabe43740e3a36df9c7aa718d9a5a4bc0301 Mon Sep 17 00:00:00 2001 From: Walter Hannah Date: Wed, 17 Apr 2024 18:59:54 -0400 Subject: [PATCH 120/451] update PAM submodule --- components/eam/src/physics/crm/pam/external | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/components/eam/src/physics/crm/pam/external b/components/eam/src/physics/crm/pam/external index ff652f3f2a6c..8f9538db7138 160000 --- a/components/eam/src/physics/crm/pam/external +++ b/components/eam/src/physics/crm/pam/external @@ -1 +1 @@ -Subproject commit ff652f3f2a6c2d675cd957883245aa6c036ef110 +Subproject commit 8f9538db7138baf26fa2b0f163fae3050d3fe29d From f750a1d9caca3e853a215fbf012888d07bba3176 Mon Sep 17 00:00:00 2001 From: Walter Hannah Date: Thu, 18 Apr 2024 16:23:30 -0400 Subject: [PATCH 121/451] make PAM dry density acceleration optional --- .../eam/src/physics/crm/pam/pam_accelerate.h | 89 +++++++++---------- 1 file changed, 41 insertions(+), 48 deletions(-) diff --git a/components/eam/src/physics/crm/pam/pam_accelerate.h b/components/eam/src/physics/crm/pam/pam_accelerate.h index a7b179a85c9d..5b277fdca966 100644 --- a/components/eam/src/physics/crm/pam/pam_accelerate.h +++ b/components/eam/src/physics/crm/pam/pam_accelerate.h @@ -17,16 +17,22 @@ inline void pam_accelerate_init( pam::PamCoupler &coupler ) { using yakl::c::parallel_for; using yakl::c::SimpleBounds; using yakl::atomicAdd; + //------------------------------------------------------------------------------------------------ + // The ability to accelerate dry density is implemented, but tests suggested + // that this was contributing to instabilities in PAM. Combined with the + // uncertainty of how to handle dry density in the anelastic case, we will + // disable dry density mean-state acceleration by default. + coupler.set_option("crm_accel_rd",false); + //------------------------------------------------------------------------------------------------ auto &dm_device = coupler.get_data_manager_device_readwrite(); auto nens = coupler.get_option("ncrms"); auto nz = coupler.get_option("crm_nz"); auto ny = coupler.get_option("crm_ny"); auto nx = coupler.get_option("crm_nx"); - auto crm_accel_uv = coupler.get_option("crm_accel_uv"); //------------------------------------------------------------------------------------------------ dm_device.register_and_allocate("accel_save_t", "saved temperature for MSA", {nz,nens}, {"z","nens"} ); - // dm_device.register_and_allocate("accel_save_r", "saved dry density for MSA", {nz,nens}, {"z","nens"} ); dm_device.register_and_allocate("accel_save_q", "saved total water for MSA", {nz,nens}, {"z","nens"} ); + dm_device.register_and_allocate("accel_save_r", "saved dry density for MSA", {nz,nens}, {"z","nens"} ); dm_device.register_and_allocate("accel_save_u", "saved uvel for MSA", {nz,nens}, {"z","nens"} ); dm_device.register_and_allocate("accel_save_v", "saved vvel for MSA", {nz,nens}, {"z","nens"} ); //------------------------------------------------------------------------------------------------ @@ -42,40 +48,37 @@ inline void pam_accelerate_diagnose( pam::PamCoupler &coupler ) { auto nz = coupler.get_option("crm_nz"); auto ny = coupler.get_option("crm_ny"); auto nx = coupler.get_option("crm_nx"); + auto crm_accel_rd = coupler.get_option("crm_accel_rd"); auto crm_accel_uv = coupler.get_option("crm_accel_uv"); //------------------------------------------------------------------------------------------------ auto temp = dm_device.get("temp" ); - // auto rhod = dm_device.get("density_dry"); auto rhov = dm_device.get("water_vapor"); auto rhol = dm_device.get("cloud_water"); auto rhoi = dm_device.get("ice" ); + auto rhod = dm_device.get("density_dry"); auto uvel = dm_device.get("uvel" ); auto vvel = dm_device.get("vvel" ); auto accel_save_t = dm_device.get("accel_save_t"); - // auto accel_save_r = dm_device.get("accel_save_r"); auto accel_save_q = dm_device.get("accel_save_q"); + auto accel_save_r = dm_device.get("accel_save_r"); auto accel_save_u = dm_device.get("accel_save_u"); auto accel_save_v = dm_device.get("accel_save_v"); //------------------------------------------------------------------------------------------------ // compute horizontal means needed later for mean-state acceleration parallel_for( SimpleBounds<2>(nz,nens) , YAKL_LAMBDA (int k, int n) { accel_save_t(k,n) = 0.0; - // accel_save_r(k,n) = 0.0; accel_save_q(k,n) = 0.0; - if (crm_accel_uv) { - accel_save_u(k,n) = 0.0; - accel_save_v(k,n) = 0.0; - } + if (crm_accel_rd) { accel_save_r(k,n) = 0.0; } + if (crm_accel_uv) { accel_save_u(k,n) = 0.0; } + if (crm_accel_uv) { accel_save_v(k,n) = 0.0; } }); real r_nx_ny = 1._fp/(nx*ny); // precompute reciprocal to avoid costly divisions parallel_for( SimpleBounds<4>(nz,ny,nx,nens) , YAKL_LAMBDA (int k, int j, int i, int n) { yakl::atomicAdd( accel_save_t(k,n), temp(k,j,i,n) * r_nx_ny ); - // yakl::atomicAdd( accel_save_r(k,n), rhod(k,j,i,n) * r_nx_ny ); yakl::atomicAdd( accel_save_q(k,n), ( rhov(k,j,i,n) + rhol(k,j,i,n) + rhoi(k,j,i,n) ) * r_nx_ny ); - if (crm_accel_uv) { - yakl::atomicAdd( accel_save_u(k,n), uvel(k,j,i,n) * r_nx_ny ); - yakl::atomicAdd( accel_save_v(k,n), vvel(k,j,i,n) * r_nx_ny ); - } + if (crm_accel_rd) { yakl::atomicAdd( accel_save_r(k,n), rhod(k,j,i,n) * r_nx_ny ); } + if (crm_accel_uv) { yakl::atomicAdd( accel_save_u(k,n), uvel(k,j,i,n) * r_nx_ny ); } + if (crm_accel_uv) { yakl::atomicAdd( accel_save_v(k,n), vvel(k,j,i,n) * r_nx_ny ); } }); //------------------------------------------------------------------------------------------------ } @@ -86,35 +89,35 @@ inline void pam_accelerate( pam::PamCoupler &coupler, int nstep, int &nstop ) { using yakl::c::SimpleBounds; using yakl::atomicAdd; using yakl::ScalarLiveOut; - auto &dm_device = coupler.get_data_manager_device_readwrite(); - auto nens = coupler.get_option("ncrms"); - auto nz = coupler.get_option("crm_nz"); - auto ny = coupler.get_option("crm_ny"); - auto nx = coupler.get_option("crm_nx"); + auto &dm_device = coupler.get_data_manager_device_readwrite(); + auto nens = coupler.get_option("ncrms"); + auto nz = coupler.get_option("crm_nz"); + auto ny = coupler.get_option("crm_ny"); + auto nx = coupler.get_option("crm_nx"); + auto crm_accel_rd = coupler.get_option("crm_accel_rd"); + auto crm_accel_uv = coupler.get_option("crm_accel_uv"); + real crm_accel_factor = coupler.get_option("crm_accel_factor"); //------------------------------------------------------------------------------------------------ auto temp = dm_device.get("temp" ); - // auto rhod = dm_device.get("density_dry"); auto rhov = dm_device.get("water_vapor"); auto rhol = dm_device.get("cloud_water"); auto rhoi = dm_device.get("ice" ); + auto rhod = dm_device.get("density_dry"); auto uvel = dm_device.get("uvel" ); auto vvel = dm_device.get("vvel" ); auto accel_save_t = dm_device.get("accel_save_t"); - // auto accel_save_r = dm_device.get("accel_save_r"); auto accel_save_q = dm_device.get("accel_save_q"); + auto accel_save_r = dm_device.get("accel_save_r"); auto accel_save_u = dm_device.get("accel_save_u"); auto accel_save_v = dm_device.get("accel_save_v"); //------------------------------------------------------------------------------------------------ - bool crm_accel_uv = coupler.get_option("crm_accel_uv"); - real crm_accel_factor = coupler.get_option("crm_accel_factor"); - //------------------------------------------------------------------------------------------------ real2d hmean_t ("hmean_t", nz,nens); - // real2d hmean_r ("hmean_r", nz,nens); + real2d hmean_r ("hmean_r", nz,nens); real2d hmean_q ("hmean_q", nz,nens); real2d hmean_u ("hmean_u", nz,nens); real2d hmean_v ("hmean_v", nz,nens); real2d ttend_acc("ttend_acc", nz,nens); - // real2d rtend_acc("rtend_acc", nz,nens); + real2d rtend_acc("rtend_acc", nz,nens); real2d qtend_acc("qtend_acc", nz,nens); real2d utend_acc("utend_acc", nz,nens); real2d vtend_acc("vtend_acc", nz,nens); @@ -127,22 +130,18 @@ inline void pam_accelerate( pam::PamCoupler &coupler, int nstep, int &nstop ) { // Compute the horizontal mean for each variable parallel_for( SimpleBounds<2>(nz,nens) , YAKL_LAMBDA (int k, int n) { hmean_t(k,n) = 0.0; - // hmean_r(k,n) = 0.0; hmean_q(k,n) = 0.0; - if (crm_accel_uv) { - hmean_u(k,n) = 0.0; - hmean_v(k,n) = 0.0; - } + if (crm_accel_rd) { hmean_r(k,n) = 0.0; } + if (crm_accel_uv) { hmean_u(k,n) = 0.0; } + if (crm_accel_uv) { hmean_v(k,n) = 0.0; } }); real r_nx_ny = 1._fp/(nx*ny); // precompute reciprocal to avoid costly divisions parallel_for( SimpleBounds<4>(nz,ny,nx,nens) , YAKL_LAMBDA (int k, int j, int i, int n) { yakl::atomicAdd( hmean_t(k,n), temp(k,j,i,n) * r_nx_ny ); - // yakl::atomicAdd( hmean_r(k,n), rhod(k,j,i,n) * r_nx_ny ); yakl::atomicAdd( hmean_q(k,n), ( rhov(k,j,i,n) + rhol(k,j,i,n) + rhoi(k,j,i,n) ) * r_nx_ny ); - if (crm_accel_uv) { - yakl::atomicAdd( hmean_u(k,n), uvel(k,j,i,n) * r_nx_ny ); - yakl::atomicAdd( hmean_v(k,n), vvel(k,j,i,n) * r_nx_ny ); - } + if (crm_accel_rd) { yakl::atomicAdd( hmean_r(k,n), rhod(k,j,i,n) * r_nx_ny ); } + if (crm_accel_uv) { yakl::atomicAdd( hmean_u(k,n), uvel(k,j,i,n) * r_nx_ny ); } + if (crm_accel_uv) { yakl::atomicAdd( hmean_v(k,n), vvel(k,j,i,n) * r_nx_ny ); } }); //------------------------------------------------------------------------------------------------ // Compute the accelerated tendencies @@ -150,12 +149,10 @@ inline void pam_accelerate( pam::PamCoupler &coupler, int nstep, int &nstop ) { ScalarLiveOut ceaseflag_liveout(false); parallel_for( SimpleBounds<2>(nz,nens) , YAKL_LAMBDA (int k, int n) { ttend_acc(k,n) = hmean_t(k,n) - accel_save_t(k,n); - // rtend_acc(k,n) = hmean_r(k,n) - accel_save_r(k,n); qtend_acc(k,n) = hmean_q(k,n) - accel_save_q(k,n); - if (crm_accel_uv) { - utend_acc(k,n) = hmean_u(k,n) - accel_save_u(k,n); - vtend_acc(k,n) = hmean_v(k,n) - accel_save_v(k,n); - } + if (crm_accel_rd) { rtend_acc(k,n) = hmean_r(k,n) - accel_save_r(k,n); } + if (crm_accel_uv) { utend_acc(k,n) = hmean_u(k,n) - accel_save_u(k,n); } + if (crm_accel_uv) { vtend_acc(k,n) = hmean_v(k,n) - accel_save_v(k,n); } if (abs(ttend_acc(k,n)) > dtemp_max) { ceaseflag_liveout = true; } @@ -191,14 +188,11 @@ inline void pam_accelerate( pam::PamCoupler &coupler, int nstep, int &nstop ) { //------------------------------------------------------------------------------------------------ // Apply the accelerated tendencies parallel_for( SimpleBounds<4>(nz,ny,nx,nens) , YAKL_LAMBDA (int k, int j, int i, int n) { - temp(k,j,i,n) = temp(k,j,i,n) + crm_accel_factor * ttend_acc(k,n); - // rhod(k,j,i,n) = rhod(k,j,i,n) + crm_accel_factor * rtend_acc(k,n); rhov(k,j,i,n) = rhov(k,j,i,n) + crm_accel_factor * qtend_acc(k,n); - if (crm_accel_uv) { - uvel(k,j,i,n) = uvel(k,j,i,n) + crm_accel_factor * utend_acc(k,n); - vvel(k,j,i,n) = vvel(k,j,i,n) + crm_accel_factor * vtend_acc(k,n); - } + if (crm_accel_rd) { rhod(k,j,i,n) = rhod(k,j,i,n) + crm_accel_factor * rtend_acc(k,n); } + if (crm_accel_uv) { uvel(k,j,i,n) = uvel(k,j,i,n) + crm_accel_factor * utend_acc(k,n); } + if (crm_accel_uv) { vvel(k,j,i,n) = vvel(k,j,i,n) + crm_accel_factor * vtend_acc(k,n); } // apply limiter on temperature temp(k,j,i,n) = std::max( temp_min, temp(k,j,i,n) ); }); @@ -231,4 +225,3 @@ inline void pam_accelerate( pam::PamCoupler &coupler, int nstep, int &nstop ) { }); //------------------------------------------------------------------------------------------------ } - From 8e65b050739206ac2490374af86e0721562194a8 Mon Sep 17 00:00:00 2001 From: Walter Hannah Date: Thu, 18 Apr 2024 16:24:38 -0400 Subject: [PATCH 122/451] remove MMF_PAM_dyn_per_phys namelist option --- components/eam/bld/build-namelist | 3 --- .../eam/bld/namelist_files/namelist_defaults_eam.xml | 1 - components/eam/bld/namelist_files/namelist_definition.xml | 6 ------ components/eam/src/physics/cam/phys_control.F90 | 8 ++------ components/eam/src/physics/crm/crm_physics.F90 | 7 ------- components/eam/src/physics/crm/pam/pam_driver.cpp | 1 + 6 files changed, 3 insertions(+), 23 deletions(-) diff --git a/components/eam/bld/build-namelist b/components/eam/bld/build-namelist index ac9001c3f7b1..8dc532b6a3df 100755 --- a/components/eam/bld/build-namelist +++ b/components/eam/bld/build-namelist @@ -3941,9 +3941,6 @@ if ($cfg->get('use_MMF')) { # MMF CRM domain orientation add_default($nl, 'MMF_orientation_angle'); - - # PAM dynamics sub-stepping parameter - add_default($nl, 'MMF_PAM_dyn_per_phys'); } add_default($nl, 'do_aerocom_ind3'); diff --git a/components/eam/bld/namelist_files/namelist_defaults_eam.xml b/components/eam/bld/namelist_files/namelist_defaults_eam.xml index d7e9afecf20e..fd7a91f19a1b 100755 --- a/components/eam/bld/namelist_files/namelist_defaults_eam.xml +++ b/components/eam/bld/namelist_files/namelist_defaults_eam.xml @@ -871,7 +871,6 @@ 0 .false. .true. - 1 90.0 0.0 diff --git a/components/eam/bld/namelist_files/namelist_definition.xml b/components/eam/bld/namelist_files/namelist_definition.xml index cc59697d5bbf..19e356ca6ccb 100644 --- a/components/eam/bld/namelist_files/namelist_definition.xml +++ b/components/eam/bld/namelist_files/namelist_definition.xml @@ -4824,12 +4824,6 @@ Defaults: 3D CRM: 0 - -Number of PAM dycor calls per physics time step. -Default: 2 - - Wavenumber cutoff for filtered MMF variance transport. diff --git a/components/eam/src/physics/cam/phys_control.F90 b/components/eam/src/physics/cam/phys_control.F90 index b87ea442c4e7..b7c9b37fa817 100644 --- a/components/eam/src/physics/cam/phys_control.F90 +++ b/components/eam/src/physics/cam/phys_control.F90 @@ -72,7 +72,6 @@ module phys_control logical :: use_crm_accel = .false. ! true => use MMF CRM mean-state acceleration (MSA) real(r8) :: crm_accel_factor = 2.D0 ! CRM acceleration factor logical :: crm_accel_uv = .true. ! true => apply MMF CRM MSA to momentum fields -integer :: MMF_PAM_dyn_per_phys = 2 ! PAM CRM dynamics steps per CRM physics steps logical :: use_subcol_microp = .false. ! if .true. then use sub-columns in microphysics @@ -229,7 +228,7 @@ subroutine phys_ctl_readnl(nlfile) eddy_scheme, microp_scheme, macrop_scheme, radiation_scheme, srf_flux_avg, & MMF_microphysics_scheme, MMF_orientation_angle, use_MMF, use_ECPP, & use_MMF_VT, MMF_VT_wn_max, use_MMF_ESMT, & - use_crm_accel, crm_accel_factor, crm_accel_uv, MMF_PAM_dyn_per_phys, & + use_crm_accel, crm_accel_factor, crm_accel_uv, & use_subcol_microp, atm_dep_flux, history_amwg, history_verbose, history_vdiag, & get_presc_aero_data,history_aerosol, history_aero_optics, & is_output_interactive_volc, & @@ -314,7 +313,6 @@ subroutine phys_ctl_readnl(nlfile) call mpibcast(use_crm_accel, 1 , mpilog, 0, mpicom) call mpibcast(crm_accel_factor, 1 , mpir8, 0, mpicom) call mpibcast(crm_accel_uv, 1 , mpilog, 0, mpicom) - call mpibcast(MMF_PAM_dyn_per_phys, 1 , mpiint, 0, mpicom) call mpibcast(use_subcol_microp, 1 , mpilog, 0, mpicom) call mpibcast(atm_dep_flux, 1 , mpilog, 0, mpicom) call mpibcast(history_amwg, 1 , mpilog, 0, mpicom) @@ -598,7 +596,7 @@ subroutine phys_getopts(deep_scheme_out, shallow_scheme_out, eddy_scheme_out, & prog_modal_aero_out, macrop_scheme_out, ideal_phys_option_out, & use_MMF_out, use_ECPP_out, MMF_microphysics_scheme_out, & MMF_orientation_angle_out, use_MMF_VT_out, MMF_VT_wn_max_out, use_MMF_ESMT_out, & - use_crm_accel_out, crm_accel_factor_out, crm_accel_uv_out, MMF_PAM_dyn_per_phys_out, & + use_crm_accel_out, crm_accel_factor_out, crm_accel_uv_out, & do_clubb_sgs_out, do_shoc_sgs_out, do_tms_out, state_debug_checks_out, & linearize_pbl_winds_out, & do_aerocom_ind3_out, & @@ -641,7 +639,6 @@ subroutine phys_getopts(deep_scheme_out, shallow_scheme_out, eddy_scheme_out, & logical, intent(out), optional :: use_crm_accel_out real(r8), intent(out), optional :: crm_accel_factor_out logical, intent(out), optional :: crm_accel_uv_out - integer, intent(out), optional :: MMF_PAM_dyn_per_phys_out logical, intent(out), optional :: use_subcol_microp_out logical, intent(out), optional :: atm_dep_flux_out logical, intent(out), optional :: history_amwg_out @@ -745,7 +742,6 @@ subroutine phys_getopts(deep_scheme_out, shallow_scheme_out, eddy_scheme_out, & if ( present(use_crm_accel_out ) ) use_crm_accel_out = use_crm_accel if ( present(crm_accel_factor_out ) ) crm_accel_factor_out = crm_accel_factor if ( present(crm_accel_uv_out ) ) crm_accel_uv_out = crm_accel_uv - if ( present(MMF_PAM_dyn_per_phys_out) ) MMF_PAM_dyn_per_phys_out = MMF_PAM_dyn_per_phys if ( present(use_subcol_microp_out ) ) use_subcol_microp_out = use_subcol_microp if ( present(macrop_scheme_out ) ) macrop_scheme_out = macrop_scheme diff --git a/components/eam/src/physics/crm/crm_physics.F90 b/components/eam/src/physics/crm/crm_physics.F90 index 51628d5ea74e..39ed6a0876c7 100644 --- a/components/eam/src/physics/crm/crm_physics.F90 +++ b/components/eam/src/physics/crm/crm_physics.F90 @@ -620,8 +620,6 @@ subroutine crm_physics_tend(ztodt, state, tend, ptend, pbuf2d, cam_in, cam_out, logical :: use_MMF_VT_tmp ! flag for MMF variance transport (for Fortran CRM) logical :: use_MMF_ESMT_tmp ! flag for MMF scalar momentum transport (for Fortran CRM) integer :: MMF_VT_wn_max ! wavenumber cutoff for filtered variance transport - - integer :: MMF_PAM_dyn_per_phys ! PAM CRM dynamics steps per CRM physics steps real(r8) :: tmp_e_sat ! temporary saturation vapor pressure real(r8) :: tmp_q_sat ! temporary saturation specific humidity @@ -734,9 +732,6 @@ subroutine crm_physics_tend(ztodt, state, tend, ptend, pbuf2d, cam_in, cam_out, use_crm_accel = use_crm_accel_tmp crm_accel_uv = crm_accel_uv_tmp - ! PAM namelist options - call phys_getopts(MMF_PAM_dyn_per_phys_out = MMF_PAM_dyn_per_phys) - nstep = get_nstep() itim = pbuf_old_tim_idx() ! "Old" pbuf time index (what does all this mean?) @@ -1466,8 +1461,6 @@ subroutine crm_physics_tend(ztodt, state, tend, ptend, pbuf2d, cam_in, cam_out, call pam_set_option('enable_physics_tend_stats', .false. ) - call pam_set_option('crm_dyn_per_phys', MMF_PAM_dyn_per_phys ) - call pam_set_option('is_first_step', (nstep<=1) ) call pam_set_option('is_restart', (nsrest>0) ) call pam_set_option('am_i_root', masterproc ) diff --git a/components/eam/src/physics/crm/pam/pam_driver.cpp b/components/eam/src/physics/crm/pam/pam_driver.cpp index a05b5cf8b037..f8f575ec8a1d 100644 --- a/components/eam/src/physics/crm/pam/pam_driver.cpp +++ b/components/eam/src/physics/crm/pam/pam_driver.cpp @@ -122,6 +122,7 @@ extern "C" void pam_driver() { coupler.set_option("crm_acceleration_ceaseflag",false); //------------------------------------------------------------------------------------------------ // coupler options for SPAM dycor + coupler.set_option("crm_dyn_per_phys",1); coupler.set_option("spam_couple_wind_exact_inverse",true); coupler.set_option("spam_clip_negative_densities",true); coupler.set_option("spam_clip_vertical_velocities",true); From 743b8ff2bdcc8a50672e5135ea3fa5c2e6a4ea4d Mon Sep 17 00:00:00 2001 From: Walter Hannah Date: Thu, 18 Apr 2024 16:26:14 -0400 Subject: [PATCH 123/451] fix white space --- components/eam/bld/namelist_files/namelist_defaults_eam.xml | 1 + 1 file changed, 1 insertion(+) diff --git a/components/eam/bld/namelist_files/namelist_defaults_eam.xml b/components/eam/bld/namelist_files/namelist_defaults_eam.xml index fd7a91f19a1b..56c816b1753c 100755 --- a/components/eam/bld/namelist_files/namelist_defaults_eam.xml +++ b/components/eam/bld/namelist_files/namelist_defaults_eam.xml @@ -871,6 +871,7 @@ 0 .false. .true. + 90.0 0.0 From 56c11f70c5137f887f204d00cd6bd7de9ed9e29a Mon Sep 17 00:00:00 2001 From: Walter Hannah Date: Thu, 18 Apr 2024 16:37:56 -0400 Subject: [PATCH 124/451] pam_debug.h clean-up --- .../eam/src/physics/crm/pam/pam_debug.h | 235 ++++++++++-------- 1 file changed, 129 insertions(+), 106 deletions(-) diff --git a/components/eam/src/physics/crm/pam/pam_debug.h b/components/eam/src/physics/crm/pam/pam_debug.h index 43d2b5bf4f5d..7e54f437f691 100644 --- a/components/eam/src/physics/crm/pam/pam_debug.h +++ b/components/eam/src/physics/crm/pam/pam_debug.h @@ -91,121 +91,144 @@ void pam_debug_check_state( pam::PamCoupler &coupler, int id, int nstep ) { auto input_phis = dm_host.get("input_phis").createDeviceCopy(); real grav = 9.80616; //------------------------------------------------------------------------------------------------ + // logical switches to set which checks are active + bool chk_nan = true; // check for NaN values in select fields + bool chk_neg = true; // check for negative values in select fields + bool chk_low_t = false; // check for low temperatures + bool chk_drop_t = true; // check for large drops in temperature + bool chk_wvel = false; // check for large vertical velocity + //------------------------------------------------------------------------------------------------ // Check for invalid values parallel_for("", SimpleBounds<4>(nz,ny,nx,nens), YAKL_LAMBDA (int k, int j, int i, int iens) { auto phis = input_phis(iens)/grav; + //-------------------------------------------------------------------------- // Check for NaNs - const auto is_nan_t_atm = isnan( temp(k,j,i,iens) ); - const auto is_nan_d_atm = isnan( rhod(k,j,i,iens) ); - const auto is_nan_q_atm = isnan( rhov(k,j,i,iens) ); - if ( is_nan_t_atm || is_nan_q_atm || is_nan_d_atm ) { - auto phis = input_phis(iens)/grav; - printf("PAM-DEBUG nan-found - st:%3.3d id:%2.2d k:%3.3d i:%3.3d n:%3.3d y:%5.1f x:%5.1f ph:%6.1f -- t:%8.2g rd:%8.2g rv:%8.2g rc:%8.2g ri:%8.2g u:%8.2g w:%8.2g -- t:%8.2g rd:%8.2g rv:%8.2g rc:%8.2g ri:%8.2g u:%8.2g w:%8.2g \n", - nstep,id,k,i,iens,lat(iens),lon(iens),phis, - temp(k,j,i,iens), - rhod(k,j,i,iens), - rhov(k,j,i,iens), - rhoc(k,j,i,iens), - rhoi(k,j,i,iens), - uvel(k,j,i,iens), - wvel(k,j,i,iens), - debug_save_temp(k,j,i,iens), - debug_save_rhod(k,j,i,iens), - debug_save_rhov(k,j,i,iens), - debug_save_rhoc(k,j,i,iens), - debug_save_rhoi(k,j,i,iens), - debug_save_uvel(k,j,i,iens), - debug_save_wvel(k,j,i,iens) - ); + if (chk_nan) { + const auto is_nan_t_atm = isnan( temp(k,j,i,iens) ); + const auto is_nan_d_atm = isnan( rhod(k,j,i,iens) ); + const auto is_nan_q_atm = isnan( rhov(k,j,i,iens) ); + if ( is_nan_t_atm || is_nan_q_atm || is_nan_d_atm ) { + auto phis = input_phis(iens)/grav; + printf("PAM-DEBUG nan-found - st:%3.3d id:%2.2d k:%3.3d i:%3.3d n:%3.3d y:%5.1f x:%5.1f ph:%6.1f -- t:%8.2g rd:%8.2g rv:%8.2g rc:%8.2g ri:%8.2g u:%8.2g w:%8.2g -- t:%8.2g rd:%8.2g rv:%8.2g rc:%8.2g ri:%8.2g u:%8.2g w:%8.2g \n", + nstep,id,k,i,iens,lat(iens),lon(iens),phis, + temp(k,j,i,iens), + rhod(k,j,i,iens), + rhov(k,j,i,iens), + rhoc(k,j,i,iens), + rhoi(k,j,i,iens), + uvel(k,j,i,iens), + wvel(k,j,i,iens), + debug_save_temp(k,j,i,iens), + debug_save_rhod(k,j,i,iens), + debug_save_rhov(k,j,i,iens), + debug_save_rhoc(k,j,i,iens), + debug_save_rhoi(k,j,i,iens), + debug_save_uvel(k,j,i,iens), + debug_save_wvel(k,j,i,iens) + ); + } } + //-------------------------------------------------------------------------- // Check for negative values - const auto is_neg_t_atm = temp(k,j,i,iens)<0; - const auto is_neg_d_atm = rhod(k,j,i,iens)<0; - const auto is_neg_q_atm = rhov(k,j,i,iens)<0; - if ( is_neg_t_atm || is_neg_q_atm || is_neg_d_atm ) { - auto phis = input_phis(iens)/grav; - printf("PAM-DEBUG neg-found - st:%3.3d id:%2.2d k:%3.3d i:%3.3d n:%3.3d y:%5.1f x:%5.1f ph:%6.1f -- t:%8.2g rd:%8.2g rv:%8.2g rc:%8.2g ri:%8.2g u:%8.2g w:%8.2g -- t:%8.2g rd:%8.2g rv:%8.2g rc:%8.2g ri:%8.2g u:%8.2g w:%8.2g \n", - nstep,id,k,i,iens,lat(iens),lon(iens),phis, - temp(k,j,i,iens), - rhod(k,j,i,iens), - rhov(k,j,i,iens), - rhoc(k,j,i,iens), - rhoi(k,j,i,iens), - uvel(k,j,i,iens), - wvel(k,j,i,iens), - debug_save_temp(k,j,i,iens), - debug_save_rhod(k,j,i,iens), - debug_save_rhov(k,j,i,iens), - debug_save_rhoc(k,j,i,iens), - debug_save_rhoi(k,j,i,iens), - debug_save_uvel(k,j,i,iens), - debug_save_wvel(k,j,i,iens) - ); + if (chk_neg) { + const auto is_neg_t_atm = temp(k,j,i,iens)<0; + const auto is_neg_d_atm = rhod(k,j,i,iens)<0; + const auto is_neg_q_atm = rhov(k,j,i,iens)<0; + if ( is_neg_t_atm || is_neg_q_atm || is_neg_d_atm ) { + auto phis = input_phis(iens)/grav; + printf("PAM-DEBUG neg-found - st:%3.3d id:%2.2d k:%3.3d i:%3.3d n:%3.3d y:%5.1f x:%5.1f ph:%6.1f -- t:%8.2g rd:%8.2g rv:%8.2g rc:%8.2g ri:%8.2g u:%8.2g w:%8.2g -- t:%8.2g rd:%8.2g rv:%8.2g rc:%8.2g ri:%8.2g u:%8.2g w:%8.2g \n", + nstep,id,k,i,iens,lat(iens),lon(iens),phis, + temp(k,j,i,iens), + rhod(k,j,i,iens), + rhov(k,j,i,iens), + rhoc(k,j,i,iens), + rhoi(k,j,i,iens), + uvel(k,j,i,iens), + wvel(k,j,i,iens), + debug_save_temp(k,j,i,iens), + debug_save_rhod(k,j,i,iens), + debug_save_rhov(k,j,i,iens), + debug_save_rhoc(k,j,i,iens), + debug_save_rhoi(k,j,i,iens), + debug_save_uvel(k,j,i,iens), + debug_save_wvel(k,j,i,iens) + ); + } + } + //-------------------------------------------------------------------------- + // Check for low temperature + if (chk_low_t) { + const auto is_low_t = temp(k,j,i,iens)<100; + if ( is_low_t ) { + printf("PAM-DEBUG low-T - st:%3.3d id:%2.2d k:%3.3d i:%3.3d n:%3.3d y:%5.1f x:%5.1f ph:%6.1f -- t:%8.2g rd:%8.2g rv:%8.2g rc:%8.2g ri:%8.2g u:%8.2g w:%8.2g -- t:%8.2g rd:%8.2g rv:%8.2g rc:%8.2g ri:%8.2g u:%8.2g w:%8.2g \n", + nstep,id,k,i,iens,lat(iens),lon(iens),phis, + temp(k,j,i,iens), + rhod(k,j,i,iens), + rhov(k,j,i,iens), + rhoc(k,j,i,iens), + rhoi(k,j,i,iens), + uvel(k,j,i,iens), + wvel(k,j,i,iens), + debug_save_temp(k,j,i,iens), + debug_save_rhod(k,j,i,iens), + debug_save_rhov(k,j,i,iens), + debug_save_rhoc(k,j,i,iens), + debug_save_rhoi(k,j,i,iens), + debug_save_uvel(k,j,i,iens), + debug_save_wvel(k,j,i,iens) + ); + } } - // // Check for low temperature - // const auto is_low_t = temp(k,j,i,iens)<100; - // if ( is_low_t ) { - // printf("PAM-DEBUG low-T - st:%3.3d id:%2.2d k:%3.3d i:%3.3d n:%3.3d y:%5.1f x:%5.1f ph:%6.1f -- t:%8.2g rd:%8.2g rv:%8.2g rc:%8.2g ri:%8.2g u:%8.2g w:%8.2g -- t:%8.2g rd:%8.2g rv:%8.2g rc:%8.2g ri:%8.2g u:%8.2g w:%8.2g \n", - // nstep,id,k,i,iens,lat(iens),lon(iens),phis, - // temp(k,j,i,iens), - // rhod(k,j,i,iens), - // rhov(k,j,i,iens), - // rhoc(k,j,i,iens), - // rhoi(k,j,i,iens), - // uvel(k,j,i,iens), - // wvel(k,j,i,iens), - // debug_save_temp(k,j,i,iens), - // debug_save_rhod(k,j,i,iens), - // debug_save_rhov(k,j,i,iens), - // debug_save_rhoc(k,j,i,iens), - // debug_save_rhoi(k,j,i,iens), - // debug_save_uvel(k,j,i,iens), - // debug_save_wvel(k,j,i,iens) - // ); - // } + //-------------------------------------------------------------------------- // Check for large temperature drops - const auto is_drop_t = (temp(k,j,i,iens)-debug_save_temp(k,j,i,iens))<-50; - if ( is_drop_t ) { - printf("PAM-DEBUG drop-T - st:%3.3d id:%2.2d k:%3.3d i:%3.3d n:%3.3d y:%5.1f x:%5.1f ph:%6.1f -- t:%8.2g rd:%8.2g rv:%8.2g rc:%8.2g ri:%8.2g u:%8.2g w:%8.2g -- t:%8.2g rd:%8.2g rv:%8.2g rc:%8.2g ri:%8.2g u:%8.2g w:%8.2g \n", - nstep,id,k,i,iens,lat(iens),lon(iens),phis, - temp(k,j,i,iens), - rhod(k,j,i,iens), - rhov(k,j,i,iens), - rhoc(k,j,i,iens), - rhoi(k,j,i,iens), - uvel(k,j,i,iens), - wvel(k,j,i,iens), - debug_save_temp(k,j,i,iens), - debug_save_rhod(k,j,i,iens), - debug_save_rhov(k,j,i,iens), - debug_save_rhoc(k,j,i,iens), - debug_save_rhoi(k,j,i,iens), - debug_save_uvel(k,j,i,iens), - debug_save_wvel(k,j,i,iens) - ); + if (chk_drop_t) { + const auto is_drop_t = (temp(k,j,i,iens)-debug_save_temp(k,j,i,iens))<-50; + if ( is_drop_t ) { + printf("PAM-DEBUG drop-T - st:%3.3d id:%2.2d k:%3.3d i:%3.3d n:%3.3d y:%5.1f x:%5.1f ph:%6.1f -- t:%8.2g rd:%8.2g rv:%8.2g rc:%8.2g ri:%8.2g u:%8.2g w:%8.2g -- t:%8.2g rd:%8.2g rv:%8.2g rc:%8.2g ri:%8.2g u:%8.2g w:%8.2g \n", + nstep,id,k,i,iens,lat(iens),lon(iens),phis, + temp(k,j,i,iens), + rhod(k,j,i,iens), + rhov(k,j,i,iens), + rhoc(k,j,i,iens), + rhoi(k,j,i,iens), + uvel(k,j,i,iens), + wvel(k,j,i,iens), + debug_save_temp(k,j,i,iens), + debug_save_rhod(k,j,i,iens), + debug_save_rhov(k,j,i,iens), + debug_save_rhoc(k,j,i,iens), + debug_save_rhoi(k,j,i,iens), + debug_save_uvel(k,j,i,iens), + debug_save_wvel(k,j,i,iens) + ); + } + } + //-------------------------------------------------------------------------- + // Check for large vertical velocity + if (chk_wvel) { + const auto is_large_pos_w = wvel(k,j,i,iens)> 40; + const auto is_large_neg_w = wvel(k,j,i,iens)<-40; + if ( is_large_pos_w || is_large_neg_w ) { + printf("PAM-DEBUG large-W - st:%3.3d id:%2.2d k:%3.3d i:%3.3d n:%3.3d y:%5.1f x:%5.1f ph:%6.1f -- t:%8.2g rd:%8.2g rv:%8.2g rc:%8.2g ri:%8.2g u:%8.2g w:%8.2g -- t:%8.2g rd:%8.2g rv:%8.2g rc:%8.2g ri:%8.2g u:%8.2g w:%8.2g \n", + nstep,id,k,i,iens,lat(iens),lon(iens),phis, + temp(k,j,i,iens), + rhod(k,j,i,iens), + rhov(k,j,i,iens), + rhoc(k,j,i,iens), + rhoi(k,j,i,iens), + uvel(k,j,i,iens), + wvel(k,j,i,iens), + debug_save_temp(k,j,i,iens), + debug_save_rhod(k,j,i,iens), + debug_save_rhov(k,j,i,iens), + debug_save_rhoc(k,j,i,iens), + debug_save_rhoi(k,j,i,iens), + debug_save_uvel(k,j,i,iens), + debug_save_wvel(k,j,i,iens) + ); + } } - // // Check for large vertical velocity - // const auto is_large_pos_w = wvel(k,j,i,iens)> 40; - // const auto is_large_neg_w = wvel(k,j,i,iens)<-40; - // if ( is_large_pos_w || is_large_neg_w ) { - // printf("PAM-DEBUG large-W - st:%3.3d id:%2.2d k:%3.3d i:%3.3d n:%3.3d y:%5.1f x:%5.1f ph:%6.1f -- t:%8.2g rd:%8.2g rv:%8.2g rc:%8.2g ri:%8.2g u:%8.2g w:%8.2g -- t:%8.2g rd:%8.2g rv:%8.2g rc:%8.2g ri:%8.2g u:%8.2g w:%8.2g \n", - // nstep,id,k,i,iens,lat(iens),lon(iens),phis, - // temp(k,j,i,iens), - // rhod(k,j,i,iens), - // rhov(k,j,i,iens), - // rhoc(k,j,i,iens), - // rhoi(k,j,i,iens), - // uvel(k,j,i,iens), - // wvel(k,j,i,iens), - // debug_save_temp(k,j,i,iens), - // debug_save_rhod(k,j,i,iens), - // debug_save_rhov(k,j,i,iens), - // debug_save_rhoc(k,j,i,iens), - // debug_save_rhoi(k,j,i,iens), - // debug_save_uvel(k,j,i,iens), - // debug_save_wvel(k,j,i,iens) - // ); - // } + //-------------------------------------------------------------------------- // update saved previous values debug_save_temp(k,j,i,iens) = temp(k,j,i,iens); debug_save_rhod(k,j,i,iens) = rhod(k,j,i,iens); From 8eae43e1a3df9f9ddde9a52d37ecad06ec77b199 Mon Sep 17 00:00:00 2001 From: Walter Hannah Date: Thu, 25 Apr 2024 15:13:25 -0400 Subject: [PATCH 125/451] update PAM submodule --- components/eam/src/physics/crm/pam/external | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/components/eam/src/physics/crm/pam/external b/components/eam/src/physics/crm/pam/external index 8f9538db7138..5931666c95a3 160000 --- a/components/eam/src/physics/crm/pam/external +++ b/components/eam/src/physics/crm/pam/external @@ -1 +1 @@ -Subproject commit 8f9538db7138baf26fa2b0f163fae3050d3fe29d +Subproject commit 5931666c95a3b75ae63fbe5bff6e743e74cb2c0a From 567fa1d665a2909266a3ee774e725e97b30a7f05 Mon Sep 17 00:00:00 2001 From: daleihao Date: Wed, 1 May 2024 11:56:37 -0700 Subject: [PATCH 126/451] change top_rad rawdate to 1km --- .../bld/namelist_files/namelist_defaults.xml | 9 ++++++++ .../namelist_defaults_tools.xml | 6 +++--- .../tools/mksurfdata_map/src/mktopradMod.F90 | 21 ++++++++++++++----- 3 files changed, 28 insertions(+), 8 deletions(-) diff --git a/components/elm/bld/namelist_files/namelist_defaults.xml b/components/elm/bld/namelist_files/namelist_defaults.xml index 8d7ad4fba900..0132320a2153 100644 --- a/components/elm/bld/namelist_files/namelist_defaults.xml +++ b/components/elm/bld/namelist_files/namelist_defaults.xml @@ -1657,6 +1657,13 @@ this mask will have smb calculated over the entire global land surface lnd/clm2/mappingdata/maps/2.5x3.33/map_1km-merge-10min_HYDRO1K-merge-nomask_to_2.5x3.33_nomask_aave_da_c130405.nc + + +lnd/clm2/mappingdata/maps/0.25x0.25/map_0.01x0.01_nomask_to_0.25x0.25_nomask_aave_da_c240424.nc + + + @@ -1704,6 +1711,8 @@ this mask will have smb calculated over the entire global land surface >lnd/clm2/mappingdata/maps/0.5x0.5/map_360x720cru_cruncep_to_0.5x0.5_nomask_aave_da_c190417.nc lnd/clm2/mappingdata/maps/0.5x0.5/map_1km-merge-10min_HYDRO1K-merge-nomask_to_0.5x0.5_nomask_aave_da_c190417.nc +lnd/clm2/mappingdata/maps/0.5x0.5/map_0.01x0.01_nomask_to_0.5x0.5_nomask_aave_da_c240424.nc diff --git a/components/elm/bld/namelist_files/namelist_defaults_tools.xml b/components/elm/bld/namelist_files/namelist_defaults_tools.xml index d948b16c95a5..f97a41314be0 100644 --- a/components/elm/bld/namelist_files/namelist_defaults_tools.xml +++ b/components/elm/bld/namelist_files/namelist_defaults_tools.xml @@ -177,7 +177,7 @@ attributes from the config_cache.xml file (with keys converted to upper-case). 0.5x0.5 0.5x0.5 5x5min -0.1x0.1 +0.01x0.01 @@ -317,8 +317,8 @@ attributes from the config_cache.xml file (with keys converted to upper-case). lnd/clm2/rawdata/mksrf_fert.c220309.nc -lnd/clm2/rawdata/mksrf_toprad_0.1x0.1.c231218.nc +lnd/clm2/rawdata/mksrf_toprad_0.01x0.01.c240422.nc diff --git a/components/elm/tools/mksurfdata_map/src/mktopradMod.F90 b/components/elm/tools/mksurfdata_map/src/mktopradMod.F90 index e8ea66f9de49..0325019706f7 100644 --- a/components/elm/tools/mksurfdata_map/src/mktopradMod.F90 +++ b/components/elm/tools/mksurfdata_map/src/mktopradMod.F90 @@ -114,25 +114,36 @@ subroutine mktoprad(ldomain, mapfname, datfname, varname, ndiag, top_o, nodata) call check_ret(nf_get_var_double (ncidi, varid, top_i), subname) call check_ret(nf_close(ncidi), subname) - ! Read topo dataset + ! set mask as 0 when topo data is filled value: -9999 + allocate(mask_i(ns_i), stat=ier) + if (ier /= 0) then + write(6,*)'mktoprad allocation error'; call abort() + end if + + mask_i(:) = 1._r8 + do ni = 1,ns_i + if (top_i(ni) < -1000._r8) then + mask_i(ni) = 0._r8 + end if + enddo + + ! Read mapping file call gridmap_mapread(tgridmap, mapfname) ! Error checks for domain and map consistencies - ! Note that the topo dataset has no landmask - so a unit landmask is assumed - call domain_checksame( tdomain, ldomain, tgridmap ) ! Determine top_o on output grid - top_o(:) = nodata - call gridmap_areaave(tgridmap, top_i, top_o, nodata=nodata) + call gridmap_areaave(tgridmap, top_i, top_o, nodata=nodata, mask_src=mask_i) ! Deallocate dynamic memory call domain_clean(tdomain) call gridmap_clean(tgridmap) deallocate (top_i) + deallocate (mask_i) write (6,*) 'Successfully made topography parameters' write (6,*) From cb43f07642f97625c9c3a66afda40b0322449326 Mon Sep 17 00:00:00 2001 From: daleihao Date: Thu, 2 May 2024 06:21:00 -0700 Subject: [PATCH 127/451] update mapping files --- components/elm/bld/namelist_files/namelist_defaults.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/components/elm/bld/namelist_files/namelist_defaults.xml b/components/elm/bld/namelist_files/namelist_defaults.xml index 0132320a2153..9a5294055647 100644 --- a/components/elm/bld/namelist_files/namelist_defaults.xml +++ b/components/elm/bld/namelist_files/namelist_defaults.xml @@ -1660,7 +1660,7 @@ this mask will have smb calculated over the entire global land surface lnd/clm2/mappingdata/maps/0.25x0.25/map_0.01x0.01_nomask_to_0.25x0.25_nomask_aave_da_c240424.nc +>lnd/clm2/mappingdata/maps/0.25x0.25/map_0.01x0.01_nomask_to_0.25x0.25_nomask_aave_da_c240501.nc @@ -1712,7 +1712,7 @@ this mask will have smb calculated over the entire global land surface lnd/clm2/mappingdata/maps/0.5x0.5/map_1km-merge-10min_HYDRO1K-merge-nomask_to_0.5x0.5_nomask_aave_da_c190417.nc lnd/clm2/mappingdata/maps/0.5x0.5/map_0.01x0.01_nomask_to_0.5x0.5_nomask_aave_da_c240424.nc +>lnd/clm2/mappingdata/maps/0.5x0.5/map_0.01x0.01_nomask_to_0.5x0.5_nomask_aave_da_c240501.nc From d6411d8d61d5171f14b977e75f12fa0aae94a83c Mon Sep 17 00:00:00 2001 From: Nicole Jeffery Date: Sat, 4 May 2024 11:05:52 -0500 Subject: [PATCH 128/451] Adds ^xpmem and grid TL319_r05_IcoswISC30E3r5 bfb --- cime_config/config_grids.xml | 10 ++++++++++ cime_config/machines/config_machines.xml | 1 + 2 files changed, 11 insertions(+) diff --git a/cime_config/config_grids.xml b/cime_config/config_grids.xml index b9ae00da0195..56a183886769 100755 --- a/cime_config/config_grids.xml +++ b/cime_config/config_grids.xml @@ -599,6 +599,16 @@ IcoswISC30E3r5 + + TL319 + r05 + IcoswISC30E3r5 + r05 + null + null + IcoswISC30E3r5 + + TL319 TL319 diff --git a/cime_config/machines/config_machines.xml b/cime_config/machines/config_machines.xml index 486948892aaf..00087a00a7da 100644 --- a/cime_config/machines/config_machines.xml +++ b/cime_config/machines/config_machines.xml @@ -2622,6 +2622,7 @@ $SHELL{dirname $(dirname $(which nf-config))} $SHELL{dirname $(dirname $(which pnetcdf_version))} ^lockedfile,individual + ^xpmem 128M From 2272b67514332b2ec98f413c4d8614d766c66df2 Mon Sep 17 00:00:00 2001 From: Nicole Jeffery Date: Mon, 6 May 2024 13:27:37 -0500 Subject: [PATCH 129/451] Split init_zbgc into three calls -First uses init_parameters to initialize bgc namelist parameters -Second (icepack_init_zbgc_tracer_indices) calls bgc indexing and array definitions. -Third defines parameter arrays for bgc (init_zbgc) bfb (round-off level in bgc) --- .../src/shared/mpas_seaice_icepack.F | 168 +++++++++--------- 1 file changed, 84 insertions(+), 84 deletions(-) diff --git a/components/mpas-seaice/src/shared/mpas_seaice_icepack.F b/components/mpas-seaice/src/shared/mpas_seaice_icepack.F index b08ed7c863c6..6c787048ad1d 100644 --- a/components/mpas-seaice/src/shared/mpas_seaice_icepack.F +++ b/components/mpas-seaice/src/shared/mpas_seaice_icepack.F @@ -12908,6 +12908,8 @@ end subroutine seaice_column_reinitialize_oceanic_fluxes subroutine init_column_tracer_object_for_biogeochemistry(domain, tracerObject) use icepack_intfc, only: icepack_init_zbgc + use icepack_intfc, only: icepack_init_zbgc_tracer_indices + use icepack_intfc, only: icepack_init_parameters use icepack_intfc, only: icepack_query_parameters type(domain_type), intent(in) :: & @@ -13252,90 +13254,7 @@ subroutine init_column_tracer_object_for_biogeochemistry(domain, tracerObject) allocate(tracerObject % index_dissolvedIronConcLayer(maxIronType)) tracerObject % nDissolvedIronIndex = nDissolvedIron - call icepack_init_zbgc(& - nblyr=nBioLayers, & - nilyr=nIceLayers, & - nslyr=nSnowLayers, & - n_algae_in=nAlgae, & - n_zaero_in=nzAerosols, & - n_doc_in=nDOC, & - n_dic_in=nDIC, & - n_don_in=nDON, & - n_fed_in=nDissolvedIron, & - n_fep_in=nParticulateIron, & - trcr_base=tracerObject % firstAncestorMask, & - trcr_depend=tracerObject % parentIndex, & - n_trcr_strata=tracerObject % ancestorNumber, & - nt_strata=tracerObject % ancestorIndices, & - nbtrcr_sw_out=tracerObject % nBioTracersShortwave, & - tr_brine_in=config_use_brine, & - nt_fbri_out=tracerObject % index_brineFraction,& - ntrcr_out=tracerObject % nTracers, & - nbtrcr_out=tracerObject % nBioTracers, & - ntrcr_o_out=tracerObject % nTracersNotBio, & - nt_bgc_Nit_out=tracerObject % index_nitrateConc, & - nt_bgc_Am_out=tracerObject % index_ammoniumConc, & - nt_bgc_Sil_out=tracerObject % index_silicateConc, & - nt_bgc_DMS_out=tracerObject % index_DMSConc, & - nt_bgc_PON_out=tracerObject % index_nonreactiveConc, & - nt_bgc_N_out=tracerObject % index_algaeConc, & - nt_bgc_C_out=tracerObject % index_algalCarbon, & - nt_bgc_chl_out=tracerObject % index_algalChlorophyll, & - nt_bgc_DOC_out=tracerObject % index_DOCConc, & - nt_bgc_DON_out=tracerObject % index_DONConc, & - nt_bgc_DIC_out=tracerObject % index_DICConc, & - nt_zaero_out=tracerObject % index_verticalAerosolsConc, & - nt_bgc_DMSPp_out=tracerObject % index_DMSPpConc, & - nt_bgc_DMSPd_out=tracerObject % index_DMSPdConc, & - nt_bgc_Fed_out=tracerObject % index_dissolvedIronConc, & - nt_bgc_Fep_out=tracerObject % index_particulateIronConc, & - nt_zbgc_frac_out=tracerObject % index_mobileFraction, & - tr_bgc_Nit_in=config_use_nitrate, & - tr_bgc_Am_in=config_use_ammonium, & - tr_bgc_Sil_in=config_use_silicate, & - tr_bgc_DMS_in=config_use_DMS, & - tr_bgc_PON_in=config_use_nonreactive, & - tr_bgc_N_in=use_nitrogen, & - tr_bgc_C_in=config_use_carbon, & - tr_bgc_chl_in=config_use_chlorophyll, & - tr_bgc_DON_in=config_use_DON, & - tr_bgc_Fe_in=config_use_iron,& - tr_zaero_in=config_use_zaerosols, & - nlt_zaero_sw_out=tracerObject % index_verticalAerosolsConcShortwave, & - nlt_chl_sw_out=tracerObject % index_chlorophyllShortwave, & - nlt_bgc_N_out=tracerObject % index_algaeConcLayer, & - nlt_bgc_Nit_out=tracerObject % index_nitrateConcLayer, & - nlt_bgc_Am_out=tracerObject % index_ammoniumConcLayer, & - nlt_bgc_Sil_out=tracerObject % index_silicateConcLayer, & - nlt_bgc_DMS_out=tracerObject % index_DMSConcLayer, & - nlt_bgc_DMSPp_out=tracerObject % index_DMSPpConcLayer, & - nlt_bgc_DMSPd_out=tracerObject % index_DMSPdConcLayer, & - nlt_bgc_C_out=tracerObject % index_algalCarbonLayer, & - nlt_bgc_chl_out=tracerObject % index_algalChlorophyllLayer, & - nlt_bgc_DIC_out=tracerObject % index_DICConcLayer, & - nlt_bgc_DOC_out=tracerObject % index_DOCConcLayer, & - nlt_bgc_PON_out=tracerObject % index_nonreactiveConcLayer, & - nlt_bgc_DON_out=tracerObject % index_DONConcLayer, & - nlt_bgc_Fed_out=tracerObject % index_dissolvedIronConcLayer, & - nlt_bgc_Fep_out=tracerObject % index_particulateIronConcLayer, & - nlt_zaero_out=tracerObject % index_verticalAerosolsConcLayer, & - nt_bgc_hum_out=tracerObject % index_humicsConc, & - nlt_bgc_hum_out=tracerObject % index_humicsConcLayer, & - tr_bgc_hum_in=config_use_humics, & - skl_bgc_in=config_use_skeletal_biochemistry, & - z_tracers_in=config_use_vertical_tracers, & - dEdd_algae_in=config_use_shortwave_bioabsorption, & - solve_zbgc_in=config_use_vertical_biochemistry, & - bio_index_o_out=tracerObject % index_LayerIndexToDataArray, & - bio_index_out=tracerObject % index_LayerIndexToBioIndex, & - frazil_scav_in=config_fraction_biotracer_in_frazil, & - initbio_frac_in=config_new_ice_fraction_biotracer, & - max_algae_in=maxAlgaeType, & - max_doc_in=maxDOCType, & - max_dic_in=maxDICType, & - max_don_in=maxDONType, & - max_fe_in=maxIronType, & - max_aero_in=maxAerosolType, & + call icepack_init_parameters(& ratio_Si2N_diatoms_in=config_ratio_Si_to_N_diatoms, & ratio_Si2N_sp_in=config_ratio_Si_to_N_small_plankton, & ratio_Si2N_phaeo_in=config_ratio_Si_to_N_phaeocystis, & @@ -13430,9 +13349,90 @@ subroutine init_column_tracer_object_for_biogeochemistry(domain, tracerObject) dmspdtype_in=config_mobility_type_DMSPd, & silicatetype_in=config_mobility_type_silicate, & humtype_in=config_mobility_type_humics, & + frazil_scav_in=config_fraction_biotracer_in_frazil, & + initbio_frac_in=config_new_ice_fraction_biotracer, & tau_min_in=config_rapid_mobile_to_stationary_time, & tau_max_in=config_long_mobile_to_stationary_time) + call icepack_init_zbgc_tracer_indices(& + nilyr_in=nIceLayers, & + nslyr_in=nSnowLayers, & + nblyr_in=nBioLayers, & + n_algae_in=nAlgae, & + n_zaero_in=nzAerosols, & + n_doc_in=nDOC, & + n_dic_in=nDIC, & + n_don_in=nDON, & + n_fed_in=nDissolvedIron, & + n_fep_in=nParticulateIron, & + trcr_base=tracerObject % firstAncestorMask, & + trcr_depend=tracerObject % parentIndex, & + n_trcr_strata=tracerObject % ancestorNumber, & + nt_strata=tracerObject % ancestorIndices, & + nbtrcr_sw_out=tracerObject % nBioTracersShortwave, & + tr_brine_in=config_use_brine, & + nt_fbri_out=tracerObject % index_brineFraction,& + ntrcr_out=tracerObject % nTracers, & + nbtrcr_out=tracerObject % nBioTracers, & + ntrcr_o_out=tracerObject % nTracersNotBio, & + nt_bgc_Nit_out=tracerObject % index_nitrateConc, & + nt_bgc_Am_out=tracerObject % index_ammoniumConc, & + nt_bgc_Sil_out=tracerObject % index_silicateConc, & + nt_bgc_DMS_out=tracerObject % index_DMSConc, & + nt_bgc_PON_out=tracerObject % index_nonreactiveConc, & + nt_bgc_N_out=tracerObject % index_algaeConc, & + nt_bgc_C_out=tracerObject % index_algalCarbon, & + nt_bgc_chl_out=tracerObject % index_algalChlorophyll, & + nt_bgc_DOC_out=tracerObject % index_DOCConc, & + nt_bgc_DON_out=tracerObject % index_DONConc, & + nt_bgc_DIC_out=tracerObject % index_DICConc, & + nt_zaero_out=tracerObject % index_verticalAerosolsConc, & + nt_bgc_DMSPp_out=tracerObject % index_DMSPpConc, & + nt_bgc_DMSPd_out=tracerObject % index_DMSPdConc, & + nt_bgc_Fed_out=tracerObject % index_dissolvedIronConc, & + nt_bgc_Fep_out=tracerObject % index_particulateIronConc, & + nt_zbgc_frac_out=tracerObject % index_mobileFraction, & + tr_bgc_Nit_in=config_use_nitrate, & + tr_bgc_Am_in=config_use_ammonium, & + tr_bgc_Sil_in=config_use_silicate, & + tr_bgc_DMS_in=config_use_DMS, & + tr_bgc_PON_in=config_use_nonreactive, & + tr_bgc_N_in=use_nitrogen, & + tr_bgc_C_in=config_use_carbon, & + tr_bgc_chl_in=config_use_chlorophyll, & + tr_bgc_DON_in=config_use_DON, & + tr_bgc_Fe_in=config_use_iron,& + tr_zaero_in=config_use_zaerosols, & + nlt_zaero_sw_out=tracerObject % index_verticalAerosolsConcShortwave, & + nlt_chl_sw_out=tracerObject % index_chlorophyllShortwave, & + nlt_bgc_N_out=tracerObject % index_algaeConcLayer, & + nlt_bgc_Nit_out=tracerObject % index_nitrateConcLayer, & + nlt_bgc_Am_out=tracerObject % index_ammoniumConcLayer, & + nlt_bgc_Sil_out=tracerObject % index_silicateConcLayer, & + nlt_bgc_DMS_out=tracerObject % index_DMSConcLayer, & + nlt_bgc_DMSPp_out=tracerObject % index_DMSPpConcLayer, & + nlt_bgc_DMSPd_out=tracerObject % index_DMSPdConcLayer, & + nlt_bgc_C_out=tracerObject % index_algalCarbonLayer, & + nlt_bgc_chl_out=tracerObject % index_algalChlorophyllLayer, & + nlt_bgc_DIC_out=tracerObject % index_DICConcLayer, & + nlt_bgc_DOC_out=tracerObject % index_DOCConcLayer, & + nlt_bgc_PON_out=tracerObject % index_nonreactiveConcLayer, & + nlt_bgc_DON_out=tracerObject % index_DONConcLayer, & + nlt_bgc_Fed_out=tracerObject % index_dissolvedIronConcLayer, & + nlt_bgc_Fep_out=tracerObject % index_particulateIronConcLayer, & + nlt_zaero_out=tracerObject % index_verticalAerosolsConcLayer, & + nt_bgc_hum_out=tracerObject % index_humicsConc, & + nlt_bgc_hum_out=tracerObject % index_humicsConcLayer, & + tr_bgc_hum_in=config_use_humics, & + skl_bgc_in=config_use_skeletal_biochemistry, & + z_tracers_in=config_use_vertical_tracers, & + dEdd_algae_in=config_use_shortwave_bioabsorption, & + solve_zbgc_in=config_use_vertical_biochemistry, & + bio_index_o_out=tracerObject % index_LayerIndexToDataArray, & + bio_index_out=tracerObject % index_LayerIndexToBioIndex) + + call icepack_init_zbgc() + ! check calculated tracer array size if (nTracers_temp /= tracerObject % nTracers) then call mpas_log_write(& From b5d1e12a94ccbf153f15b2a7ebdd249a3d4f7c9b Mon Sep 17 00:00:00 2001 From: Walter Hannah Date: Tue, 7 May 2024 16:07:39 -0700 Subject: [PATCH 130/451] update RCEMIP zenith angle --- components/eam/cime_config/usermods_dirs/rcemip/user_nl_cpl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/components/eam/cime_config/usermods_dirs/rcemip/user_nl_cpl b/components/eam/cime_config/usermods_dirs/rcemip/user_nl_cpl index 3ecd465f7a14..e3d4433d4a8d 100644 --- a/components/eam/cime_config/usermods_dirs/rcemip/user_nl_cpl +++ b/components/eam/cime_config/usermods_dirs/rcemip/user_nl_cpl @@ -31,4 +31,4 @@ seq_flux_mct_albdif = 0.07 seq_flux_mct_albdir = 0.07 seq_flux_atmocn_minwind = 1 -constant_zenith_deg = 42.05 \ No newline at end of file +constant_zenith_deg = 42.04 \ No newline at end of file From b33fa7dacce0a31f9552649dc14d0f774ead8780 Mon Sep 17 00:00:00 2001 From: Walter Hannah Date: Tue, 7 May 2024 16:08:06 -0700 Subject: [PATCH 131/451] update RCE use case comment --- components/eam/bld/namelist_files/use_cases/RCEMIP_EAMv1.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/components/eam/bld/namelist_files/use_cases/RCEMIP_EAMv1.xml b/components/eam/bld/namelist_files/use_cases/RCEMIP_EAMv1.xml index c1c8e9e027ad..146a9483b36f 100644 --- a/components/eam/bld/namelist_files/use_cases/RCEMIP_EAMv1.xml +++ b/components/eam/bld/namelist_files/use_cases/RCEMIP_EAMv1.xml @@ -35,7 +35,7 @@ 0.0 - + From f3278f20b89fe1ed80681e0c8d2935c911e70adb Mon Sep 17 00:00:00 2001 From: Walter Hannah Date: Tue, 14 May 2024 12:43:37 -0700 Subject: [PATCH 132/451] add RCEMIP2 compsets --- .../eam/cime_config/config_compsets.xml | 44 +++++++++++++++++++ 1 file changed, 44 insertions(+) diff --git a/components/eam/cime_config/config_compsets.xml b/components/eam/cime_config/config_compsets.xml index 39971fbb0945..01e99a9a1489 100644 --- a/components/eam/cime_config/config_compsets.xml +++ b/components/eam/cime_config/config_compsets.xml @@ -229,6 +229,50 @@ 2000_EAM%RCE-MMF2_SLND_SICE_DOCN%AQPCONST_SROF_SGLC_SWAV + + + FRCE-MW_295dT1p25 + 2000_EAM%RCE_SLND_SICE_DOCN%AQP11_SROF_SGLC_SWAV + + + FRCE-MW_300dT0p625 + 2000_EAM%RCE_SLND_SICE_DOCN%AQP12_SROF_SGLC_SWAV + + + FRCE-MW_300dT1p25 + 2000_EAM%RCE_SLND_SICE_DOCN%AQP13_SROF_SGLC_SWAV + + + FRCE-MW_300dT2p5 + 2000_EAM%RCE_SLND_SICE_DOCN%AQP14_SROF_SGLC_SWAV + + + FRCE-MW_305dT1p25 + 2000_EAM%RCE_SLND_SICE_DOCN%AQP15_SROF_SGLC_SWAV + + + + FRCE-MW-MMF1_295dT1p25 + 2000_EAM%RCE-MMF1_SLND_SICE_DOCN%AQP11_SROF_SGLC_SWAV + + + FRCE-MW-MMF1_300dT0p625 + 2000_EAM%RCE-MMF1_SLND_SICE_DOCN%AQP12_SROF_SGLC_SWAV + + + FRCE-MW-MMF1_300dT1p25 + 2000_EAM%RCE-MMF1_SLND_SICE_DOCN%AQP13_SROF_SGLC_SWAV + + + FRCE-MW-MMF1_300dT2p5 + 2000_EAM%RCE-MMF1_SLND_SICE_DOCN%AQP14_SROF_SGLC_SWAV + + + FRCE-MW-MMF1_305dT1p25 + 2000_EAM%RCE-MMF1_SLND_SICE_DOCN%AQP15_SROF_SGLC_SWAV + + + From b63cbcadde51a50160d1221a740d142d20ea5c0c Mon Sep 17 00:00:00 2001 From: Walter Hannah Date: Tue, 14 May 2024 12:44:11 -0700 Subject: [PATCH 133/451] add new data ocean SST patterns or RCEMIP2 --- .../docn/cime_config/config_component.xml | 10 +++- .../cime_config/namelist_definition_docn.xml | 7 ++- .../data_comps/docn/src/docn_comp_mod.F90 | 54 ++++++++++++++++++- 3 files changed, 66 insertions(+), 5 deletions(-) diff --git a/components/data_comps/docn/cime_config/config_component.xml b/components/data_comps/docn/cime_config/config_component.xml index 5a30c69df6cf..431d358f9951 100644 --- a/components/data_comps/docn/cime_config/config_component.xml +++ b/components/data_comps/docn/cime_config/config_component.xml @@ -13,7 +13,7 @@ This file may have ocn desc entries. --> - DOCN + DOCN null mode prescribed ocean mode slab ocean mode @@ -45,7 +45,7 @@ char - prescribed,sst_aquap1,sst_aquap2,sst_aquap3,sst_aquap4,sst_aquap5,sst_aquap6,sst_aquap7,sst_aquap8,sst_aquap9,sst_aquap10,sst_aquapfile,som,som_aquap,sst_aquap_constant,interannual,null + prescribed,sst_aquap1,sst_aquap2,sst_aquap3,sst_aquap4,sst_aquap5,sst_aquap6,sst_aquap7,sst_aquap8,sst_aquap9,sst_aquap10,sst_aquap11,sst_aquap12,sst_aquap13,sst_aquap14,sst_aquap15,sst_aquapfile,som,som_aquap,sst_aquap_constant,interannual,null prescribed null @@ -63,6 +63,12 @@ sst_aquap8 sst_aquap9 sst_aquap10 + + sst_aquap11 + sst_aquap12 + sst_aquap13 + sst_aquap14 + sst_aquap15 sst_aquapfile sst_aquap_constant diff --git a/components/data_comps/docn/cime_config/namelist_definition_docn.xml b/components/data_comps/docn/cime_config/namelist_definition_docn.xml index 948902e37324..a191d088d7f5 100644 --- a/components/data_comps/docn/cime_config/namelist_definition_docn.xml +++ b/components/data_comps/docn/cime_config/namelist_definition_docn.xml @@ -257,7 +257,7 @@ char streams shr_strdata_nml - SSTDATA,SST_AQUAP1,SST_AQUAP2,SST_AQUAP3,SST_AQUAP4,SST_AQUAP5,SST_AQUAP6,SST_AQUAP7,SST_AQUAP8,SST_AQUAP9,SST_AQUAP10,SST_AQUAPFILE,SST_AQUAP_CONSTANT,SOM,SOM_AQUAP,IAF,NULL,COPYALL + SSTDATA,SST_AQUAP1,SST_AQUAP2,SST_AQUAP3,SST_AQUAP4,SST_AQUAP5,SST_AQUAP6,SST_AQUAP7,SST_AQUAP8,SST_AQUAP9,SST_AQUAP10,SST_AQUAP11,SST_AQUAP12,SST_AQUAP13,SST_AQUAP14,SST_AQUAP15,SST_AQUAPFILE,SST_AQUAP_CONSTANT,SOM,SOM_AQUAP,IAF,NULL,COPYALL General method that operates on the data. This is generally implemented in the data models but is set in the strdata method for @@ -323,6 +323,11 @@ SST_AQUAP8 SST_AQUAP9 SST_AQUAP10 + SST_AQUAP11 + SST_AQUAP12 + SST_AQUAP13 + SST_AQUAP14 + SST_AQUAP15 SST_AQUAPFILE SST_AQUAP_CONSTANT SOM diff --git a/components/data_comps/docn/src/docn_comp_mod.F90 b/components/data_comps/docn/src/docn_comp_mod.F90 index e692882c9db1..002ed655b404 100644 --- a/components/data_comps/docn/src/docn_comp_mod.F90 +++ b/components/data_comps/docn/src/docn_comp_mod.F90 @@ -984,6 +984,7 @@ subroutine prescribed_sst(xc, yc, lsize, sst_option, sst) integer :: i real(r8) :: tmp, tmp1, pi real(r8) :: rlon(lsize), rlat(lsize) + real(r8) :: mean_SST, delta_SST real(r8), parameter :: pio180 = SHR_CONST_PI/180._r8 @@ -1013,8 +1014,8 @@ subroutine prescribed_sst(xc, yc, lsize, sst_option, sst) ! Control - if (sst_option < 1 .or. sst_option > 10) then - call shr_sys_abort ('prescribed_sst: ERROR: sst_option must be between 1 and 10') + if (sst_option < 1 .or. sst_option > 15) then + call shr_sys_abort ('prescribed_sst: ERROR: sst_option must be between 1 and 15') end if if (sst_option == 1 .or. sst_option == 6 .or. sst_option == 7 .or. sst_option == 8) then @@ -1174,6 +1175,55 @@ subroutine prescribed_sst(xc, yc, lsize, sst_option, sst) end do end if + !------------------------------------------------------------------------------- + ! RCEMIP phase 2 - Mock-Walker + + ! MW_295dT1p25 - mean SST = 295 / dSST = 1.25 K + + if (sst_option == 11) then + mean_SST = 295 + delta_SST = 1.25 + do i = 1, lsize + sst(i) = mean_SST + (delta_SST/2) * cos( rlat(i) * 360/54 ) + end do + end if + + ! MW_300dT0p625 - mean SST = 300 / dSST = 0.625 K + if (sst_option == 12) then + mean_SST = 300 + delta_SST = 0.625 + do i = 1, lsize + sst(i) = mean_SST + (delta_SST/2) * cos( rlat(i) * 360/54 ) + end do + end if + + ! MW_300dT1p25 - mean SST = 300 / dSST = 1.25 K + if (sst_option == 13) then + mean_SST = 300 + delta_SST = 1.25 + do i = 1, lsize + sst(i) = mean_SST + (delta_SST/2) * cos( rlat(i) * 360/54 ) + end do + end if + + ! MW_300dT2p5 - mean SST = 300 / dSST = 2.5 K + if (sst_option == 14) then + mean_SST = 300 + delta_SST = 2.5 + do i = 1, lsize + sst(i) = mean_SST + (delta_SST/2) * cos( rlat(i) * 360/54 ) + end do + end if + + ! MW_305dT1p25 - mean SST = 305 / dSST = 1.25 K + if (sst_option == 15) then + mean_SST = 305 + delta_SST = 1.25 + do i = 1, lsize + sst(i) = mean_SST + (delta_SST/2) * cos( rlat(i) * 360/54 ) + end do + end if + end subroutine prescribed_sst end module docn_comp_mod From 3803486652580fc8f983ec5af650c4399fa21870 Mon Sep 17 00:00:00 2001 From: Walter Hannah Date: Tue, 14 May 2024 12:45:03 -0700 Subject: [PATCH 134/451] add TMQS diagnostic for RCEMIP2 --- components/eam/src/physics/cam/cam_diagnostics.F90 | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/components/eam/src/physics/cam/cam_diagnostics.F90 b/components/eam/src/physics/cam/cam_diagnostics.F90 index ead4f558f05b..0b4abed44720 100644 --- a/components/eam/src/physics/cam/cam_diagnostics.F90 +++ b/components/eam/src/physics/cam/cam_diagnostics.F90 @@ -306,6 +306,7 @@ subroutine diag_init() call addfld ('MQ',(/ 'lev' /), 'A','kg/m2','Water vapor mass in layer') call addfld ('TMQ',horiz_only, 'A','kg/m2','Total (vertically integrated) precipitable water', & standard_name='atmosphere_mass_content_of_water_vapor') + call addfld ('TMQS',horiz_only, 'A','kg/m2','Total (vertically integrated) saturated precipitable water') call addfld ('TTQ',horiz_only, 'A', 'kg/m/s','Total (vertically integrated) vapor transport') call addfld ('TUQ',horiz_only, 'A','kg/m/s','Total (vertically integrated) zonal water flux') call addfld ('TVQ',horiz_only, 'A','kg/m/s','Total (vertically integrated) meridional water flux') @@ -1335,6 +1336,15 @@ subroutine diag_phys_writeout(state, psl) ftem(:ncol,1) = ftem(:ncol,1) + ftem(:ncol,k) end do call outfld ('TMQ ',ftem, pcols ,lchnk ) +! +! Mass of saturated q vertically integrated +! + call qsat(state%t(:ncol,:), state%pmid(:ncol,:), tem2(:ncol,:), ftem(:ncol,:)) + ftem(:ncol,:) = ftem(:ncol,:) * state%pdel(:ncol,:) * rga + do k=2,pver + ftem(:ncol,1) = ftem(:ncol,1) + ftem(:ncol,k) + end do + call outfld ('TMQS ',ftem, pcols ,lchnk ) ! ! Mass of vertically integrated water vapor flux ! From 4d9c01bb8483c053fa9bdd9fc7817872a65087f6 Mon Sep 17 00:00:00 2001 From: Alexander Hager Date: Thu, 8 Jun 2023 11:15:55 -0600 Subject: [PATCH 135/451] Add iceThicknessHydro to replace thickness thickness field is replaced by iceThicknessHydro, which makes changes along the boundaries where the surface evelation of a boundary cell is a local minimum. In this case the surface elevation of that cell is replaced by the minimum of its non-boundary neighbors, and the ice thickness is then recalculated from the updated surface elevation. The intent of this commit is to inhibit the formation of subglacial lakes forming on the domain boundaries, which causes instabilities in the channel model. Physically, lakes should not form at the boundary as it is intended to be a high in hydropotential (a watershed boundary). --- .../src/Registry_subglacial_hydro.xml | 4 +- .../mode_forward/mpas_li_subglacial_hydro.F | 116 ++++++++++++++++-- .../src/shared/mpas_li_mask.F | 66 +++++++++- 3 files changed, 174 insertions(+), 12 deletions(-) diff --git a/components/mpas-albany-landice/src/Registry_subglacial_hydro.xml b/components/mpas-albany-landice/src/Registry_subglacial_hydro.xml index 083c92bcfbe4..2fae65a0de14 100644 --- a/components/mpas-albany-landice/src/Registry_subglacial_hydro.xml +++ b/components/mpas-albany-landice/src/Registry_subglacial_hydro.xml @@ -140,7 +140,9 @@ - + diff --git a/components/mpas-albany-landice/src/mode_forward/mpas_li_subglacial_hydro.F b/components/mpas-albany-landice/src/mode_forward/mpas_li_subglacial_hydro.F index 60cd6e5ca795..53e2edc9ee9f 100644 --- a/components/mpas-albany-landice/src/mode_forward/mpas_li_subglacial_hydro.F +++ b/components/mpas-albany-landice/src/mode_forward/mpas_li_subglacial_hydro.F @@ -106,6 +106,7 @@ subroutine li_SGH_init(domain, err) real (kind=RKIND), dimension(:), pointer :: waterPressure real (kind=RKIND), dimension(:), pointer :: thickness real (kind=RKIND), dimension(:), pointer :: bedTopography + real (kind=RKIND), dimension(:), pointer :: iceThicknessHydro integer, dimension(:), pointer :: cellMask real (kind=RKIND), pointer :: tillMax real (kind=RKIND), pointer :: rhoi, rhoo @@ -182,8 +183,12 @@ subroutine li_SGH_init(domain, err) call mpas_pool_get_array(hydroPool, 'waterPressure', waterPressure) call mpas_pool_get_array(geometryPool, 'thickness', thickness) + call mpas_pool_get_array(hydroPool, 'iceThicknessHydro', iceThicknessHydro) + call calc_iceThicknessHydro(block, err_tmp) !adjust ice thickness along boundaries + err = ior(err,err_tmp) + waterPressure = max(0.0_RKIND, waterPressure) - waterPressure = min(waterPressure, rhoi * gravity * thickness) + waterPressure = min(waterPressure, rhoi * gravity * iceThicknessHydro) ! set pressure correctly under floating ice and open ocean call mpas_pool_get_array(geometryPool, 'cellMask', cellMask) call mpas_pool_get_array(geometryPool, 'bedTopography', bedTopography) @@ -325,6 +330,9 @@ subroutine li_SGH_solve(domain, err) call mpas_pool_get_array(velocityPool, 'flowParamA', flowParamA) call mpas_pool_get_array(geometryPool, 'thickness', thickness) + call calc_iceThicknessHydro(block, err_tmp) + err = ior(err, err_tmp) + call li_calculate_flowParamA(meshPool, temperature, thickness, flowParamA, err_tmp) err = ior(err, err_tmp) @@ -1480,6 +1488,7 @@ subroutine calc_pressure(block, err) real (kind=RKIND), dimension(:), pointer :: divergenceChannel real (kind=RKIND), dimension(:), pointer :: channelAreaChangeCell real (kind=RKIND), dimension(:), pointer :: bedTopography + real (kind=RKIND), dimension(:), pointer :: iceThicknessHydro integer, dimension(:), pointer :: hydroMarineMarginMask integer, dimension(:), pointer :: cellMask integer, dimension(:), pointer :: nEdgesOnCell @@ -1546,6 +1555,7 @@ subroutine calc_pressure(block, err) call mpas_pool_get_array(geometryPool, 'thickness', thickness) call mpas_pool_get_array(geometryPool, 'cellMask', cellMask) call mpas_pool_get_array(geometryPool, 'bedTopography', bedTopography) + call mpas_pool_get_array(hydroPool, 'iceThicknessHydro', iceThicknessHydro) openingRate(:) = bedRough * basalSpeed(:) * (bedRoughMax - waterThickness(:)) !openingRate(:) = bedRough * basalSpeed(:) * (bedRoughMax - waterThickness(:)) + & @@ -1566,7 +1576,7 @@ subroutine calc_pressure(block, err) case ('cavity') where (li_mask_is_floating_ice(cellMask)) - waterPressure = rhoi * gravity * thickness + waterPressure = rhoi * gravity * iceThicknessHydro elsewhere (.not. li_mask_is_ice(cellMask)) waterPressure = 0.0_RKIND elsewhere @@ -1576,11 +1586,11 @@ subroutine calc_pressure(block, err) case ('overburden') where (li_mask_is_floating_ice(cellMask)) - waterPressure = rhoi * gravity * thickness + waterPressure = rhoi * gravity * iceThicknessHydro elsewhere (.not. li_mask_is_ice(cellMask)) waterPressure = 0.0_RKIND elsewhere - waterPressure = rhoi * gravity * thickness + waterPressure = rhoi * gravity * iceThicknessHydro end where case default @@ -1589,7 +1599,7 @@ subroutine calc_pressure(block, err) end select waterPressure = max(0.0_RKIND, waterPressure) - waterPressure = min(waterPressure, rhoi * gravity * thickness) + waterPressure = min(waterPressure, rhoi * gravity * iceThicknessHydro) do iCell = 1, nCells if ( li_mask_is_floating_ice(cellMask(iCell)) .or. & @@ -1638,7 +1648,6 @@ subroutine calc_pressure_diag_vars(block, err) !----------------------------------------------------------------- ! input variables !----------------------------------------------------------------- - !----------------------------------------------------------------- ! input/output variables !----------------------------------------------------------------- @@ -1663,6 +1672,7 @@ subroutine calc_pressure_diag_vars(block, err) real (kind=RKIND), dimension(:), pointer :: waterThickness real (kind=RKIND), dimension(:), pointer :: hydropotential real (kind=RKIND), dimension(:), pointer :: effectivePressure + real (kind=RKIND), dimension(:), pointer :: iceThicknessHydro integer, dimension(:), pointer :: cellMask real (kind=RKIND), pointer :: config_sea_level @@ -1683,9 +1693,10 @@ subroutine calc_pressure_diag_vars(block, err) call mpas_pool_get_array(hydroPool, 'hydropotentialBase', hydropotentialBase) call mpas_pool_get_array(hydroPool, 'waterThickness', waterThickness) call mpas_pool_get_array(hydroPool, 'hydropotential', hydropotential) + call mpas_pool_get_array(hydroPool, 'iceThicknessHydro', iceThicknessHydro) call mpas_pool_get_array(geometryPool, 'cellMask', cellMask) - effectivePressure = rhoi * gravity * thickness - waterPressure + effectivePressure = rhoi * gravity * iceThicknessHydro - waterPressure ! < this should evalute to 0 for floating ice if Pw set correctly there. where (.not. li_mask_is_grounded_ice(cellmask)) effectivePressure = 0.0_RKIND ! zero effective pressure where no ice to avoid confusion @@ -2161,6 +2172,7 @@ subroutine ocean_connection_N(domain) real (kind=RKIND), dimension(:), pointer :: thickness real (kind=RKIND), dimension(:), pointer :: bedTopography real (kind=RKIND), dimension(:), pointer :: effectivePressure + real (kind=RKIND), dimension(:), pointer :: iceThicknessHydro real (kind=RKIND), pointer :: rhoi, rhoo ! Calculate N assuming perfect ocean connection @@ -2175,7 +2187,9 @@ subroutine ocean_connection_N(domain) call mpas_pool_get_array(geometryPool, 'thickness', thickness) call mpas_pool_get_array(geometryPool, 'bedTopography', bedTopography) call mpas_pool_get_array(hydroPool, 'effectivePressure', effectivePressure) - effectivePressure = rhoi * gravity * thickness - rhoi * gravity * max(0.0_RKIND, -1.0_RKIND * rhoo/rhoi * bedTopography) + call mpas_pool_get_array(hydroPool, 'iceThicknessHydro', iceThicknessHydro) + + effectivePressure = rhoi * gravity * iceThicknessHydro - rhoi * gravity * max(0.0_RKIND, -1.0_RKIND * rhoo/rhoi * bedTopography) effectivePressure = max(effectivePressure, 0.0_RKIND) ! This is just to zero out N in the open ocean to avoid confusion block => block % next @@ -2303,6 +2317,92 @@ subroutine calc_hydro_mask(domain) !-------------------------------------------------------------------- end subroutine calc_hydro_mask + + +!*********************************************************************** +! +! routine calc_iceThicknessHydro +! +!> \brief Calculate version of ice thickness used by hydrology model +!> \author Alex Hager +!> \date 7 June 2023 +!> \details +!> This routine calculates a modified ice thickness that is altered at +! the domain boundaries to avoid local minima in hydropotential +!----------------------------------------------------------------------- + subroutine calc_iceThicknessHydro(block, err) + + !----------------------------------------------------------------- + ! input variables + !----------------------------------------------------------------- + + !----------------------------------------------------------------- + ! input/output variables + !----------------------------------------------------------------- + type (block_type), intent(inout) :: block !< Input/Output: block object + + !----------------------------------------------------------------- + ! output variables + !----------------------------------------------------------------- + integer, intent(out) :: err !< Output: error flag + + !----------------------------------------------------------------- + ! local variables + !----------------------------------------------------------------- + ! Pools pointers + type (mpas_pool_type), pointer :: geometryPool + type (mpas_pool_type), pointer :: hydroPool + type (mpas_pool_type), pointer :: meshPool + real (kind=RKIND), dimension(:), pointer :: thickness + real (kind=RKIND), dimension(:), pointer :: bedTopography + real (kind=RKIND), dimension(:), pointer :: iceThicknessHydro + real (kind=RKIND), dimension(:), pointer :: upperSurface + integer, dimension(:,:), pointer :: cellsOnCell + integer, dimension(:), pointer :: cellMask + integer, pointer :: nCells + integer :: iCell + integer :: jCell + real (kind=RKIND) :: minNeighborHeight + real (kind=RKIND), parameter :: bigValue = 1.0_RKIND + integer, dimension(:), pointer :: nEdgesOnCell + err = 0 + + ! Get pools things + call mpas_pool_get_subpool(block % structs, 'hydro', hydroPool) + call mpas_pool_get_subpool(block % structs, 'geometry', geometryPool) + call mpas_pool_get_subpool(block % structs, 'mesh', meshPool) + + call mpas_pool_get_array(geometryPool, 'thickness', thickness) + call mpas_pool_get_array(geometryPool, 'bedTopography', bedTopography) + call mpas_pool_get_array(geometryPool, 'cellMask', cellMask) + call mpas_pool_get_array(hydroPool, 'iceThicknessHydro', iceThicknessHydro) + call mpas_pool_get_array(geometryPool, 'upperSurface', upperSurface) + call mpas_pool_get_array(meshPool, 'nEdgesOnCell', nEdgesOnCell) + call mpas_pool_get_dimension(meshPool, 'nCells', nCells) + call mpas_pool_get_array(meshPool, 'cellsOnCell', cellsOnCell) + + iceThicknessHydro = thickness + + do iCell = 1, nCells + if ((li_mask_is_boundary(cellMask(iCell))) .and. (li_mask_is_grounded_ice(cellMask(iCell)))) then !identify domain boundaries + minNeighborHeight = bigValue !allocate + + do jCell = 1, nEdgesOnCell(iCell) + if ( .not. li_mask_is_boundary(cellMask(cellsOnCell(jCell,iCell)))) then + minNeighborHeight = min(minNeighborHeight, upperSurface(cellsOnCell(jCell,iCell))) + endif + end do + + !only adjust surface elevation if cell is local minimum + if ((upperSurface(iCell) < minNeighborHeight) .and. (minNeighborHeight < bigValue)) then + iceThicknessHydro(iCell) = minNeighborHeight - bedTopography(iCell) + endif + + endif + enddo + +!------------------------------------------------------------------------- + end subroutine calc_iceThicknessHydro !*********************************************************************** ! diff --git a/components/mpas-albany-landice/src/shared/mpas_li_mask.F b/components/mpas-albany-landice/src/shared/mpas_li_mask.F index 673ed8186e47..64050cb83adf 100644 --- a/components/mpas-albany-landice/src/shared/mpas_li_mask.F +++ b/components/mpas-albany-landice/src/shared/mpas_li_mask.F @@ -45,6 +45,7 @@ module li_mask integer, parameter :: li_mask_ValueAlbanyMarginNeighbor = 128 ! This the first cell beyond the last active albany cell integer, parameter :: li_mask_ValueGroundingLine = 256 !< This is grounded cell that has a floating neighbor, or vertex/edge on that boundary + integer, parameter :: li_mask_ValueDomainBoundary = 512 !-------------------------------------------------------------------- ! @@ -143,7 +144,18 @@ module li_mask module procedure li_mask_is_grounding_line_logout_0d end interface - !-------------------------------------------------------------------- + + interface li_mask_is_boundary + module procedure li_mask_is_boundary_logout_1d + module procedure li_mask_is_boundary_logout_0d + end interface + + + interface li_mask_is_boundary_int + module procedure li_mask_is_boundary_intout_1d + module procedure li_mask_is_boundary_intout_0d + end interface +!-------------------------------------------------------------------- ! ! Private module variables ! @@ -294,10 +306,10 @@ subroutine li_calculate_mask(meshPool, velocityPool, geometryPool, err) logical :: isMargin logical :: isAlbanyMarginNeighbor logical :: aCellOnVertexHasIce, aCellOnVertexHasNoIce, aCellOnVertexHasDynamicIce, aCellOnVertexHasNoDynamicIce, & - aCellOnVertexIsFloating, aCellOnVertexIsFloatingAndDynamic, aCellOnVertexIsAlbanyActive + aCellOnVertexIsFloating, aCellOnVertexIsFloatingAndDynamic, aCellOnVertexIsAlbanyActive, aCellOnVertexIsDomainBoundary logical :: aCellOnVertexIsGrounded logical :: aCellOnEdgeHasIce, aCellOnEdgeHasNoIce, aCellOnEdgeHasDynamicIce, aCellOnEdgeHasNoDynamicIce, & - aCellOnEdgeIsFloating, aCellOnEdgeIsFloatingAndDynamic + aCellOnEdgeIsFloating, aCellOnEdgeIsFloatingAndDynamic, aCellOnEdgeIsDomainBoundary logical :: aCellOnEdgeIsGrounded logical :: aCellOnEdgeIsOpenOcean integer :: numCellsOnVertex @@ -473,6 +485,16 @@ subroutine li_calculate_mask(meshPool, velocityPool, geometryPool, err) endif enddo + !identify domain boundaries + do i=1,nCells + do j=1,nEdgesOnCell(i) + iCellNeighbor = cellsOnCell(j,i) + if (iCellNeighbor == nCells+1) then + cellMask(i) = ior(cellMask(i), li_mask_ValueDomainBoundary) + endif + enddo + enddo + !call mpas_timer_stop('calculate mask cell') ! ==== @@ -503,6 +525,7 @@ subroutine li_calculate_mask(meshPool, velocityPool, geometryPool, err) aCellOnVertexIsFloating = .false. aCellOnVertexIsGrounded = .false. aCellOnVertexIsFloatingAndDynamic = .false. + aCellOnVertexIsDomainBoundary = .false. do j = 1, vertexDegree ! vertexDegree is usually 3 (e.g. CVT mesh) but could be something else (e.g. 4 for quad mesh) iCell = cellsOnVertex(j,i) aCellOnVertexHasIce = (aCellOnVertexHasIce .or. li_mask_is_ice(cellMask(iCell))) @@ -514,7 +537,9 @@ subroutine li_calculate_mask(meshPool, velocityPool, geometryPool, err) (li_mask_is_floating_ice(cellMask(iCell)) .and. & li_mask_is_dynamic_ice(cellMask(iCell))) ) aCellOnVertexIsGrounded = (aCellOnVertexIsGrounded .or. li_mask_is_grounded_ice(cellMask(iCell))) + aCellOnVertexIsDomainBoundary = (aCellOnVertexIsDomainBoundary .or. li_mask_is_boundary(cellMask(iCell))) end do + if (aCellOnVertexHasIce) then vertexMask(i) = ior(vertexMask(i), li_mask_ValueIce) endif @@ -535,6 +560,9 @@ subroutine li_calculate_mask(meshPool, velocityPool, geometryPool, err) vertexMask(i) = ior(vertexMask(i), li_mask_ValueDynamicMargin) ! vertex with both 1+ dynamic ice cell(s) and 1+ non-dynamic cell(s) as neighbors endif + if (aCellOnVertexIsDomainBoundary) then + vertexMask(i) = ior(vertexMask(i), li_mask_ValueDomainBoundary) + endif end do @@ -607,6 +635,7 @@ subroutine li_calculate_mask(meshPool, velocityPool, geometryPool, err) aCellOnEdgeIsGrounded = .false. aCellOnEdgeIsOpenOcean = .false. aCellOnEdgeIsFloatingAndDynamic = .false. + aCellOnEdgeIsDomainBoundary = .false. do j = 1, 2 iCell = cellsOnEdge(j,i) aCellOnEdgeHasIce = (aCellOnEdgeHasIce .or. li_mask_is_ice(cellMask(iCell))) @@ -620,6 +649,7 @@ subroutine li_calculate_mask(meshPool, velocityPool, geometryPool, err) aCellOnEdgeIsGrounded = (aCellOnEdgeIsGrounded .or. li_mask_is_grounded_ice(cellMask(iCell))) aCellOnEdgeIsOpenOcean = aCellOnEdgeIsOpenOcean .or. & ((bedTopography(iCell) < config_sea_level) .and. (.not. li_mask_is_ice(cellMask(iCell)))) + aCellOnEdgeIsDomainBoundary = (aCellOnEdgeIsDomainBoundary .or. li_mask_is_boundary(cellMask(iCell))) end do if (aCellOnEdgeHasIce) then edgeMask(i) = ior(edgeMask(i), li_mask_ValueIce) @@ -641,6 +671,9 @@ subroutine li_calculate_mask(meshPool, velocityPool, geometryPool, err) if (aCellOnEdgeHasDynamicIce .and. aCellOnEdgeHasNoDynamicIce) then edgeMask(i) = ior(edgeMask(i), li_mask_ValueDynamicMargin) endif + if (aCellOnEdgeIsDomainBoundary) then + edgeMask(i) = ior(edgeMask(i), li_mask_ValueDomainBoundary) + endif end do !call mpas_timer_stop('calculate mask edge') @@ -905,8 +938,35 @@ function li_mask_is_initial_ice_logout_0d(mask) li_mask_is_initial_ice_logout_0d = (iand(mask, li_mask_ValueInitialIceExtent) == li_mask_ValueInitialIceExtent) end function li_mask_is_initial_ice_logout_0d + ! -- Functions that check for domain boundary -- + function li_mask_is_boundary_logout_1d(mask) + integer, dimension(:), intent(in) :: mask + logical, dimension(size(mask)) :: li_mask_is_boundary_logout_1d + + li_mask_is_boundary_logout_1d = (iand(mask, li_mask_ValueDomainBoundary) == li_mask_ValueDomainBoundary) + end function li_mask_is_boundary_logout_1d + + function li_mask_is_boundary_logout_0d(mask) + integer, intent(in) :: mask + logical :: li_mask_is_boundary_logout_0d + + li_mask_is_boundary_logout_0d = (iand(mask, li_mask_ValueDomainBoundary) == li_mask_ValueDomainBoundary) + end function li_mask_is_boundary_logout_0d + function li_mask_is_boundary_intout_1d(mask) + integer, dimension(:), intent(in) :: mask + integer, dimension(size(mask)) :: li_mask_is_boundary_intout_1d + + li_mask_is_boundary_intout_1d = iand(mask, li_mask_ValueDomainBoundary) / li_mask_ValueDomainBoundary + end function li_mask_is_boundary_intout_1d + + function li_mask_is_boundary_intout_0d(mask) + integer, intent(in) :: mask + integer :: li_mask_is_boundary_intout_0d + + li_mask_is_boundary_intout_0d = iand(mask, li_mask_ValueDomainBoundary) / li_mask_ValueDomainBoundary + end function li_mask_is_boundary_intout_0d !*********************************************************************** ! Private subroutines: !*********************************************************************** From dfa69eeeea3d08eeca86b090f07efc7c0f8f25c8 Mon Sep 17 00:00:00 2001 From: Alexander Hager Date: Wed, 14 Jun 2023 17:38:01 -0600 Subject: [PATCH 136/451] Fix bug in iceThicknessHydro Commit Fixes bug in previous commit that introduces iceThicknessHydro --- .../mode_forward/mpas_li_subglacial_hydro.F | 35 +++++++++++++++---- 1 file changed, 28 insertions(+), 7 deletions(-) diff --git a/components/mpas-albany-landice/src/mode_forward/mpas_li_subglacial_hydro.F b/components/mpas-albany-landice/src/mode_forward/mpas_li_subglacial_hydro.F index 53e2edc9ee9f..c67a3996f051 100644 --- a/components/mpas-albany-landice/src/mode_forward/mpas_li_subglacial_hydro.F +++ b/components/mpas-albany-landice/src/mode_forward/mpas_li_subglacial_hydro.F @@ -204,6 +204,11 @@ subroutine li_SGH_init(domain, err) block => block % next end do + !update halo for iceThicknessHydro + call mpas_timer_start("halo updates") + call mpas_dmpar_field_halo_exch(domain, 'iceThicknessHydro') + call mpas_timer_stop("halo updates") + ! === error check if (err > 0) then call mpas_log_write("An error has occurred in li_SGH_init.", MPAS_LOG_ERR) @@ -339,6 +344,11 @@ subroutine li_SGH_solve(domain, err) block => block % next end do + !update halo for iceThicknessHydro + call mpas_timer_start("halo updates") + call mpas_dmpar_field_halo_exch(domain, 'iceThicknessHydro') + call mpas_timer_stop("halo updates") + ! initialize while loop call mpas_pool_get_subpool(domain % blocklist % structs, 'mesh', meshPool) ! can get from any block call mpas_pool_get_array(meshPool, 'deltat', masterDeltat) @@ -2362,8 +2372,10 @@ subroutine calc_iceThicknessHydro(block, err) integer, pointer :: nCells integer :: iCell integer :: jCell + integer :: numCellsChanged + integer :: iNeighbor real (kind=RKIND) :: minNeighborHeight - real (kind=RKIND), parameter :: bigValue = 1.0_RKIND + real (kind=RKIND), parameter :: bigValue = 1.0e6_RKIND integer, dimension(:), pointer :: nEdgesOnCell err = 0 @@ -2382,27 +2394,36 @@ subroutine calc_iceThicknessHydro(block, err) call mpas_pool_get_array(meshPool, 'cellsOnCell', cellsOnCell) iceThicknessHydro = thickness + numCellsChanged = 0 do iCell = 1, nCells - if ((li_mask_is_boundary(cellMask(iCell))) .and. (li_mask_is_grounded_ice(cellMask(iCell)))) then !identify domain boundaries - minNeighborHeight = bigValue !allocate + if ((li_mask_is_boundary(cellMask(iCell))) .and. & + (li_mask_is_grounded_ice(cellMask(iCell)))) then !identify domain boundaries + + minNeighborHeight = bigValue !allocate do jCell = 1, nEdgesOnCell(iCell) - if ( .not. li_mask_is_boundary(cellMask(cellsOnCell(jCell,iCell)))) then - minNeighborHeight = min(minNeighborHeight, upperSurface(cellsOnCell(jCell,iCell))) + iNeighbor = cellsOnCell(jCell,iCell) + if ( .not. li_mask_is_boundary(cellMask(iNeighbor)) .and. & + (iNeighbor < nCells + 1)) then + minNeighborHeight = min(minNeighborHeight, upperSurface(iNeighbor)) endif end do !only adjust surface elevation if cell is local minimum if ((upperSurface(iCell) < minNeighborHeight) .and. (minNeighborHeight < bigValue)) then + call mpas_log_write("Changed ice thickness of cell $i", intArgs=(/iCell/)) + numCellsChanged = numCellsChanged + 1 iceThicknessHydro(iCell) = minNeighborHeight - bedTopography(iCell) endif endif enddo -!------------------------------------------------------------------------- - end subroutine calc_iceThicknessHydro + call mpas_log_write("Number of Cells Changed in iceThicknessHydro: $i", intArgs=(/numCellsChanged/)) + call mpas_log_write("Minimum Neighbor Height: $r", realArgs=(/minNeighborHeight/)) + + end subroutine calc_iceThicknessHydro !*********************************************************************** ! From c56a8a5cdea3a2db6f6820a499b6dcd69f58f561 Mon Sep 17 00:00:00 2001 From: Alexander Hager Date: Mon, 19 Jun 2023 17:20:30 -0600 Subject: [PATCH 137/451] iceThicknessHydro additionally adjusts elev. highs 'iceThicknessHydro' now adjusts the ice thicknesses of boundary cells so that there are also no local maxima in surface elevation on the boundaries (in addition to the previous removal of local minima). This will make the surface elevation of all boundary cells equal to either the minimum or maximum of their non-boundary neighbors. This is done to avoid diffusivity instabilities when using the 'from_vertex_barycentric' tangent slope calculation. Currently, this implementation will change *all* grounded boundary cells, so this commit also introduces a new namelist option, 'config_SGH_use_iceThicknessHydro' that enables the 'iceThicknessHydro' calculation if set to '.true.'. 'iceThicknessHydro' is equivalent to 'thickness' when 'config_SGH_use_iceThicknessHydro' is false. 'config_SGH_use_iceThicknessHydro' has a default value of '.true.' --- .../src/Registry_subglacial_hydro.xml | 8 ++- .../mode_forward/mpas_li_subglacial_hydro.F | 66 ++++++++++++------- 2 files changed, 48 insertions(+), 26 deletions(-) diff --git a/components/mpas-albany-landice/src/Registry_subglacial_hydro.xml b/components/mpas-albany-landice/src/Registry_subglacial_hydro.xml index 2fae65a0de14..ba9f0948d46f 100644 --- a/components/mpas-albany-landice/src/Registry_subglacial_hydro.xml +++ b/components/mpas-albany-landice/src/Registry_subglacial_hydro.xml @@ -77,7 +77,13 @@ description="notional englacial porosity" possible_values="positive real number" /> - + + + + maxNeighborHeight) .and. & + (maxNeighborHeight > bigNegativeValue)) then + numCellsChanged = numCellsChanged + 1 + iceThicknessHydro(iCell) = maxNeighborHeight - bedTopography(iCell) + endif - endif - enddo + endif + enddo - call mpas_log_write("Number of Cells Changed in iceThicknessHydro: $i", intArgs=(/numCellsChanged/)) - call mpas_log_write("Minimum Neighbor Height: $r", realArgs=(/minNeighborHeight/)) - + call mpas_log_write("Number of Cells Changed in iceThicknessHydro: $i", intArgs=(/numCellsChanged/)) + endif + end subroutine calc_iceThicknessHydro !*********************************************************************** From 45b1bf304e590c2b1a86fd3485756283eab9abb8 Mon Sep 17 00:00:00 2001 From: Alexander Hager Date: Wed, 5 Jul 2023 10:01:32 -0600 Subject: [PATCH 138/451] iceThicknessHydro as mean of neighboring cells iceThicknessHydro now smooths the entire ice thickness field used by the subglacial hydrology model, instead of only smoothing along the boundaries. In the subglacial hydrology model, each cell's surface elevation is now a mean of its neighbors. As done previously, an additional requirement prohibits the surface elevation used by the subglacial hydrology model from being a local minimum or maximum. The purpose of this commit is to address issues arising from single-cell subglacial lakes that form when the surface elevation of a cell is lower than all of its neighbors, particularly when coupling to ice dynamics. --- .../mode_forward/mpas_li_subglacial_hydro.F | 72 +++++++++++++------ 1 file changed, 50 insertions(+), 22 deletions(-) diff --git a/components/mpas-albany-landice/src/mode_forward/mpas_li_subglacial_hydro.F b/components/mpas-albany-landice/src/mode_forward/mpas_li_subglacial_hydro.F index bd94e2357afe..20da6bf73e99 100644 --- a/components/mpas-albany-landice/src/mode_forward/mpas_li_subglacial_hydro.F +++ b/components/mpas-albany-landice/src/mode_forward/mpas_li_subglacial_hydro.F @@ -2372,10 +2372,12 @@ subroutine calc_iceThicknessHydro(block, err) integer, pointer :: nCells integer :: iCell integer :: jCell - integer :: numCellsChanged integer :: iNeighbor real (kind=RKIND) :: minNeighborHeight real (kind=RKIND) :: maxNeighborHeight + real (kind=RKIND) :: meanNeighborHeight + real (kind=RKIND) :: totNeighborHeight + real (kind=RKIND) :: numCells real (kind=RKIND), parameter :: bigValue = 1.0e6_RKIND real (kind=RKIND), parameter :: bigNegativeValue = -1.0e6_RKIND integer, dimension(:), pointer :: nEdgesOnCell @@ -2396,6 +2398,7 @@ subroutine calc_iceThicknessHydro(block, err) call mpas_pool_get_dimension(meshPool, 'nCells', nCells) call mpas_pool_get_array(meshPool, 'cellsOnCell', cellsOnCell) call mpas_pool_get_config(liConfigs, 'config_SGH_use_iceThicknessHydro', config_SGH_use_iceThicknessHydro) + iceThicknessHydro = thickness !iceThicknessHydro is equivalent to thickness if @@ -2403,42 +2406,67 @@ subroutine calc_iceThicknessHydro(block, err) !ice thickness along boundaries. if (config_SGH_use_iceThicknessHydro) then - - numCellsChanged = 0 do iCell = 1, nCells - if ((li_mask_is_boundary(cellMask(iCell))) .and. & - (li_mask_is_grounded_ice(cellMask(iCell)))) then !identify domain boundaries - + if (li_mask_is_grounded_ice(cellMask(iCell))) then !identify domain boundaries + !Smooth by making each cell equal to the mean of its + !neighbors. + + do jCell = 1, nEdgesOnCell(iCell) + iNeighbor = cellsOnCell(jCell,iCell) + if (iNeighbor < nCells + 1) then + if (jCell == 1) then + totNeighborHeight = upperSurface(iNeighbor) + numCells = 1 + else + totNeighborHeight = totNeighborHeight + upperSurface(iNeighbor) + numCells = numCells + 1 + endif + endif + + meanNeighborHeight = totNeighborHeight / numCells + end do + + iceThicknessHydro(iCell) = meanNeighborHeight - bedTopography(iCell) + + !Above averaging is not sequential with respect to flow + !direction, so cells can still be local minima or maxima + !after smoothing. Find and correct cells where this is the case + minNeighborHeight = bigValue !allocate maxNeighborHeight = bigNegativeValue - + do jCell = 1, nEdgesOnCell(iCell) iNeighbor = cellsOnCell(jCell,iCell) - if (.not. li_mask_is_boundary(cellMask(iNeighbor)) .and. & - (iNeighbor < nCells + 1)) then - minNeighborHeight = min(minNeighborHeight, upperSurface(iNeighbor)) - maxNeighborHeight = max(maxNeighborHeight, upperSurface(iNeighbor)) - endif + if (iNeighbor < nCells + 1) then + + minNeighborHeight = min(minNeighborHeight, iceThicknessHydro(iNeighbor) + & + bedTopography(iNeighbor)) + + maxNeighborHeight = max(maxNeighborHeight, iceThicknessHydro(iNeighbor) + & + bedTopography(iNeighbor)) + + endif end do - + !only adjust surface elevation if cell is local minimum or !maximum - if ((upperSurface(iCell) < minNeighborHeight) .and. (minNeighborHeight < bigValue)) then - numCellsChanged = numCellsChanged + 1 - iceThicknessHydro(iCell) = minNeighborHeight - bedTopography(iCell) - elseif ((upperSurface(iCell) > maxNeighborHeight) .and. & - (maxNeighborHeight > bigNegativeValue)) then - numCellsChanged = numCellsChanged + 1 + if (((iceThicknessHydro(iCell) + bedTopography(iCell)) < minNeighborHeight) & + .and. (minNeighborHeight < bigValue)) then + + iceThicknessHydro(iCell) = minNeighborHeight - bedTopography(iCell) + + elseif (((iceThicknessHydro(iCell) + bedTopography(iCell)) > maxNeighborHeight) & + .and. (maxNeighborHeight > bigNegativeValue)) then + iceThicknessHydro(iCell) = maxNeighborHeight - bedTopography(iCell) + endif endif enddo - - call mpas_log_write("Number of Cells Changed in iceThicknessHydro: $i", intArgs=(/numCellsChanged/)) endif - + end subroutine calc_iceThicknessHydro !*********************************************************************** From 9407999931416f47b28d24070170031b2ef62508 Mon Sep 17 00:00:00 2001 From: Alexander Hager Date: Fri, 7 Jul 2023 15:46:23 -0600 Subject: [PATCH 139/451] Limit iceThicknessHydro to non-margin cells Disallow iceThicknessHydro modification at ice margins. Avoids bug where iceThicknessHydro can be negative at certain ice margin cells --- .../src/mode_forward/mpas_li_subglacial_hydro.F | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/components/mpas-albany-landice/src/mode_forward/mpas_li_subglacial_hydro.F b/components/mpas-albany-landice/src/mode_forward/mpas_li_subglacial_hydro.F index 20da6bf73e99..6c0c000dee19 100644 --- a/components/mpas-albany-landice/src/mode_forward/mpas_li_subglacial_hydro.F +++ b/components/mpas-albany-landice/src/mode_forward/mpas_li_subglacial_hydro.F @@ -1610,7 +1610,7 @@ subroutine calc_pressure(block, err) waterPressure = max(0.0_RKIND, waterPressure) waterPressure = min(waterPressure, rhoi * gravity * iceThicknessHydro) - + do iCell = 1, nCells if ( li_mask_is_floating_ice(cellMask(iCell)) .or. & ((.not. li_mask_is_ice(cellMask(iCell))) .and. (bedTopography(iCell) < config_sea_level) ) ) then @@ -1711,7 +1711,7 @@ subroutine calc_pressure_diag_vars(block, err) where (.not. li_mask_is_grounded_ice(cellmask)) effectivePressure = 0.0_RKIND ! zero effective pressure where no ice to avoid confusion end where - + hydropotentialBase = rho_water * gravity * bedTopography + waterPressure ! This is still correct under ice shelves/open ocean because waterPressure has been set appropriately there already. ! Note this leads to a nonuniform hydropotential at sea level that is a function of the ocean depth. @@ -2408,7 +2408,7 @@ subroutine calc_iceThicknessHydro(block, err) if (config_SGH_use_iceThicknessHydro) then do iCell = 1, nCells - if (li_mask_is_grounded_ice(cellMask(iCell))) then !identify domain boundaries + if ((li_mask_is_grounded_ice(cellMask(iCell))) .and. (.not. li_mask_is_margin(cellMask(iCell)))) then !identify domain boundaries !Smooth by making each cell equal to the mean of its !neighbors. From 0c3e53e62b13905a2b438db4a516a458d7e94dc9 Mon Sep 17 00:00:00 2001 From: Alexander Hager Date: Tue, 18 Jul 2023 14:34:26 -0600 Subject: [PATCH 140/451] iceThicknessHydro limited to local min/max Changes calculation of iceThicknessHydro and limits its affect to only local min/max. Previously iceThicknessHydro smoothed every cell by making it a mean of its neighbors, but this unrealistically flattened hydropotential gradients for ice sheet wide simulations. iceThicknessHydro is now adjusts the ice thickness of only local min/max so that their surface elevation is equal to the mean of their neighbors. This commit also introduces upperSurfaceHydro as an output variable in the hydro pool. --- .../src/Registry_subglacial_hydro.xml | 2 + .../mode_forward/mpas_li_subglacial_hydro.F | 57 ++++++++----------- 2 files changed, 25 insertions(+), 34 deletions(-) diff --git a/components/mpas-albany-landice/src/Registry_subglacial_hydro.xml b/components/mpas-albany-landice/src/Registry_subglacial_hydro.xml index ba9f0948d46f..32efc089c743 100644 --- a/components/mpas-albany-landice/src/Registry_subglacial_hydro.xml +++ b/components/mpas-albany-landice/src/Registry_subglacial_hydro.xml @@ -148,6 +148,8 @@ + maxNeighborHeight) & + elseif ((upperSurface(iCell) > maxNeighborHeight) & .and. (maxNeighborHeight > bigNegativeValue)) then - iceThicknessHydro(iCell) = maxNeighborHeight - bedTopography(iCell) + iceThicknessHydro(iCell) = meanNeighborHeight - bedTopography(iCell) endif @@ -2467,6 +2454,8 @@ subroutine calc_iceThicknessHydro(block, err) enddo endif + upperSurfaceHydro = iceThicknessHydro + bedTopography + end subroutine calc_iceThicknessHydro !*********************************************************************** From 2e1400f91edc4c63adf028ac63ce0b0fb3ea4928 Mon Sep 17 00:00:00 2001 From: Alexander Hager Date: Thu, 20 Jul 2023 16:21:26 -0600 Subject: [PATCH 141/451] Debug iceThicknessHydro Addresses a couple small bugs found in iceThicknessHydro. --- .../src/mode_forward/mpas_li_subglacial_hydro.F | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/components/mpas-albany-landice/src/mode_forward/mpas_li_subglacial_hydro.F b/components/mpas-albany-landice/src/mode_forward/mpas_li_subglacial_hydro.F index 97cc2d1ebfd0..c4912d9e0453 100644 --- a/components/mpas-albany-landice/src/mode_forward/mpas_li_subglacial_hydro.F +++ b/components/mpas-albany-landice/src/mode_forward/mpas_li_subglacial_hydro.F @@ -2412,19 +2412,19 @@ subroutine calc_iceThicknessHydro(block, err) do iCell = 1, nCells if ((li_mask_is_grounded_ice(cellMask(iCell))) .and. (.not. li_mask_is_margin(cellMask(iCell)))) then !identify domain boundaries - maxNeighborHeight = bigValue !allocate - minNeighborHeight = bigNegativeValue + maxNeighborHeight = bigNegativeValue !allocate + minNeighborHeight = bigValue do jCell = 1, nEdgesOnCell(iCell) iNeighbor = cellsOnCell(jCell,iCell) - if (jCell == 1) then - totNeighborHeight = upperSurface(iNeighbor) - numCells = 1 - endif - if (iNeighbor < nCells + 1) then + if (jCell == 1) then + totNeighborHeight = upperSurface(iNeighbor) + numCells = 1 + endif + minNeighborHeight = min(minNeighborHeight, upperSurface(iNeighbor)) maxNeighborHeight = max(maxNeighborHeight, upperSurface(iNeighbor)) From 0ad0388946f705192d723c2890b8c6398baca855 Mon Sep 17 00:00:00 2001 From: Alexander Hager Date: Fri, 8 Sep 2023 10:08:49 -0700 Subject: [PATCH 142/451] avoid negative iceThicknessHydro Defaults iceThicknessHydro to original thickness if below zero --- .../src/mode_forward/mpas_li_subglacial_hydro.F | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/components/mpas-albany-landice/src/mode_forward/mpas_li_subglacial_hydro.F b/components/mpas-albany-landice/src/mode_forward/mpas_li_subglacial_hydro.F index c4912d9e0453..3675f1185e1e 100644 --- a/components/mpas-albany-landice/src/mode_forward/mpas_li_subglacial_hydro.F +++ b/components/mpas-albany-landice/src/mode_forward/mpas_li_subglacial_hydro.F @@ -2450,6 +2450,11 @@ subroutine calc_iceThicknessHydro(block, err) endif + !avoid negatives, default to original thickness + if (iceThicknessHydro(iCell) < 0.0_RKIND) then + iceThicknessHydro(iCell) = thickness(iCell) + endif + endif enddo endif From 88beec159d3900b48336d3429919b57fc307f5af Mon Sep 17 00:00:00 2001 From: Alexander Hager Date: Tue, 26 Sep 2023 12:49:37 -0700 Subject: [PATCH 143/451] no iceThicknessHydro at GL Disables iceThicknessHydro at grounding line so not ocean properties are included in calculation --- .../mode_forward/mpas_li_subglacial_hydro.F | 88 ++++++++++++------- 1 file changed, 54 insertions(+), 34 deletions(-) diff --git a/components/mpas-albany-landice/src/mode_forward/mpas_li_subglacial_hydro.F b/components/mpas-albany-landice/src/mode_forward/mpas_li_subglacial_hydro.F index 3675f1185e1e..4e402062cc8e 100644 --- a/components/mpas-albany-landice/src/mode_forward/mpas_li_subglacial_hydro.F +++ b/components/mpas-albany-landice/src/mode_forward/mpas_li_subglacial_hydro.F @@ -2368,12 +2368,19 @@ subroutine calc_iceThicknessHydro(block, err) real (kind=RKIND), dimension(:), pointer :: iceThicknessHydro real (kind=RKIND), dimension(:), pointer :: upperSurfaceHydro real (kind=RKIND), dimension(:), pointer :: upperSurface + integer, dimension(:), pointer :: hydroMarineMarginMask integer, dimension(:,:), pointer :: cellsOnCell + integer, dimension(:,:), pointer :: edgesOnCell integer, dimension(:), pointer :: cellMask + integer, dimension(:), pointer :: edgeMask integer, pointer :: nCells + integer :: edgeNum + integer, dimension(:), pointer :: nEdgesOnCell + integer :: iEdge integer :: iCell integer :: jCell integer :: iNeighbor + integer :: isMarineMargin real (kind=RKIND) :: maxNeighborHeight real (kind=RKIND) :: minNeighborHeight real (kind=RKIND) :: meanNeighborHeight @@ -2381,7 +2388,6 @@ subroutine calc_iceThicknessHydro(block, err) real (kind=RKIND) :: numCells real (kind=RKIND), parameter :: bigValue = 1.0e6_RKIND real (kind=RKIND), parameter :: bigNegativeValue = -1.0e6_RKIND - integer, dimension(:), pointer :: nEdgesOnCell logical, pointer :: config_SGH_use_iceThicknessHydro err = 0 @@ -2393,12 +2399,16 @@ subroutine calc_iceThicknessHydro(block, err) call mpas_pool_get_array(geometryPool, 'thickness', thickness) call mpas_pool_get_array(geometryPool, 'bedTopography', bedTopography) call mpas_pool_get_array(geometryPool, 'cellMask', cellMask) + call mpas_pool_get_array(geometryPool, 'edgeMask', edgeMask) call mpas_pool_get_array(hydroPool, 'iceThicknessHydro', iceThicknessHydro) call mpas_pool_get_array(hydroPool, 'upperSurfaceHydro', upperSurfaceHydro) call mpas_pool_get_array(geometryPool, 'upperSurface', upperSurface) call mpas_pool_get_array(meshPool, 'nEdgesOnCell', nEdgesOnCell) call mpas_pool_get_dimension(meshPool, 'nCells', nCells) call mpas_pool_get_array(meshPool, 'cellsOnCell', cellsOnCell) + call mpas_pool_get_array(meshPool, 'edgesOnCell', edgesOnCell) + call mpas_pool_get_array(meshPool, 'nEdgesOnCell', nEdgesOnCell) + call mpas_pool_get_array(hydroPool, 'hydroMarineMarginMask', hydroMarineMarginMask) call mpas_pool_get_config(liConfigs, 'config_SGH_use_iceThicknessHydro', config_SGH_use_iceThicknessHydro) iceThicknessHydro = thickness @@ -2408,53 +2418,63 @@ subroutine calc_iceThicknessHydro(block, err) !ice thickness if (config_SGH_use_iceThicknessHydro) then - do iCell = 1, nCells - if ((li_mask_is_grounded_ice(cellMask(iCell))) .and. (.not. li_mask_is_margin(cellMask(iCell)))) then !identify domain boundaries - maxNeighborHeight = bigNegativeValue !allocate - minNeighborHeight = bigValue + if ((li_mask_is_grounded_ice(cellMask(iCell))) .and. (.not. li_mask_is_margin(cellMask(iCell)))) then !identify domain boundaries - do jCell = 1, nEdgesOnCell(iCell) - iNeighbor = cellsOnCell(jCell,iCell) + isMarineMargin = 0 + do edgeNum = 1, nEdgesOnCell(iCell) + iEdge = edgesOnCell(edgeNum,iCell) + if (hydroMarineMarginMask(iEdge) == 1) then + isMarineMargin = 1 + exit + endif + enddo - if (iNeighbor < nCells + 1) then + if (isMarineMargin == 0) then + maxNeighborHeight = bigNegativeValue !allocate + minNeighborHeight = bigValue + + do jCell = 1, nEdgesOnCell(iCell) + iNeighbor = cellsOnCell(jCell,iCell) - if (jCell == 1) then - totNeighborHeight = upperSurface(iNeighbor) - numCells = 1 - endif - - minNeighborHeight = min(minNeighborHeight, upperSurface(iNeighbor)) + if (iNeighbor < nCells + 1) then - maxNeighborHeight = max(maxNeighborHeight, upperSurface(iNeighbor)) + if (jCell == 1) then + totNeighborHeight = upperSurface(iNeighbor) + numCells = 1 + endif + + minNeighborHeight = min(minNeighborHeight, upperSurface(iNeighbor)) - totNeighborHeight = totNeighborHeight + upperSurface(iNeighbor) - numCells = numCells + 1 - endif - end do + maxNeighborHeight = max(maxNeighborHeight, upperSurface(iNeighbor)) - meanNeighborHeight = totNeighborHeight / numCells + totNeighborHeight = totNeighborHeight + upperSurface(iNeighbor) + numCells = numCells + 1 + endif + end do - !only adjust surface elevation if cell is local minimum or - !maximum - if ((upperSurface(iCell) < minNeighborHeight) & - .and. (minNeighborHeight < bigValue)) then + meanNeighborHeight = totNeighborHeight / numCells - iceThicknessHydro(iCell) = meanNeighborHeight - bedTopography(iCell) + !only adjust surface elevation if cell is local minimum or + !maximum + if ((upperSurface(iCell) < minNeighborHeight) & + .and. (minNeighborHeight < bigValue)) then - elseif ((upperSurface(iCell) > maxNeighborHeight) & - .and. (maxNeighborHeight > bigNegativeValue)) then + iceThicknessHydro(iCell) = meanNeighborHeight - bedTopography(iCell) - iceThicknessHydro(iCell) = meanNeighborHeight - bedTopography(iCell) + elseif ((upperSurface(iCell) > maxNeighborHeight) & + .and. (maxNeighborHeight > bigNegativeValue)) then - endif + iceThicknessHydro(iCell) = meanNeighborHeight - bedTopography(iCell) - !avoid negatives, default to original thickness - if (iceThicknessHydro(iCell) < 0.0_RKIND) then - iceThicknessHydro(iCell) = thickness(iCell) - endif - + endif + + !avoid negatives, default to original thickness + if (iceThicknessHydro(iCell) < 0.0_RKIND) then + iceThicknessHydro(iCell) = thickness(iCell) + endif + endif endif enddo endif From f728bb34c8c4ec468cfe16b381dda49fc329c1c6 Mon Sep 17 00:00:00 2001 From: Alexander Hager Date: Thu, 4 Jan 2024 15:05:04 -0800 Subject: [PATCH 144/451] Add waterPressureSmooth Adds smoothed water pressure field, waterPressureSmooth, that is used only for calculation of waterPressureSlopeNormal and channelPressureFreeze. Option config_SGH_iter_smooth_waterPressureSlopeNormal specifies number of times to smooth waterPressure over when calculating waterPressureSlopeNormal --- .../src/Registry_subglacial_hydro.xml | 13 ++- .../mode_forward/mpas_li_subglacial_hydro.F | 92 +++++++++++++++++-- 2 files changed, 95 insertions(+), 10 deletions(-) diff --git a/components/mpas-albany-landice/src/Registry_subglacial_hydro.xml b/components/mpas-albany-landice/src/Registry_subglacial_hydro.xml index 32efc089c743..ecbcb89a48bb 100644 --- a/components/mpas-albany-landice/src/Registry_subglacial_hydro.xml +++ b/components/mpas-albany-landice/src/Registry_subglacial_hydro.xml @@ -125,6 +125,10 @@ possible_values="'file', 'thermal', 'basal_heat'" /> + @@ -162,7 +166,9 @@ description="water layer thickness in subglacial till from previous time step" /> - + @@ -239,7 +245,7 @@ + description="time step used for evolving subglacial hydrology system" /> + + 0) then + do iter = 1, nTimesSmooth !May need to iterate to smooth properly + if (iter == 1) then + waterPressureSmooth = waterPressure + pressureField = waterPressure + else + pressureField = waterPressureSmooth + endif + + do iCell = 1, nCells + if ((li_mask_is_grounded_ice(cellMask(iCell))) .and. (.not. li_mask_is_margin(cellMask(iCell)))) then + + isMarineMargin = 0 + do edgeNum = 1, nEdgesOnCell(iCell) + iEdge = edgesOnCell(edgeNum,iCell) + if (hydroMarineMarginMask(iEdge) == 1) then + isMarineMargin = 1 + exit + endif + enddo + + if (isMarineMargin == 0) then + + totNeighborPressure = pressureField(iCell) + numCells = 1 + + do jCell = 1, nEdgesOnCell(iCell) + iNeighbor = cellsOnCell(jCell,iCell) + + if (iNeighbor < nCells + 1) then + totNeighborPressure = totNeighborPressure + pressureField(iNeighbor) + numCells = numCells + 1 + endif + end do + + !waterPressureSmooth is average of neighboring cells + waterPressureSmooth(iCell) = totNeighborPressure / numCells + endif + endif + end do + end do + elseif (nTimesSmooth == 0) then + waterPressureSmooth = waterPressure + endif + + do iEdge = 1, nEdges + cell1 = cellsOnEdge(1, iEdge) + cell2 = cellsOnEdge(2, iEdge) + + waterPressureSlopeNormal(iEdge) = (waterPressureSmooth(cell2) - waterPressureSmooth(cell1)) / dcEdge(iEdge) end do ! At boundaries of hydro domain, disallow inflow. Allow outflow if hydropotential gradient requires it. From e7fba6bdedb0a016846db8cef834543167678179 Mon Sep 17 00:00:00 2001 From: Alexander Hager Date: Wed, 28 Feb 2024 15:03:37 -0700 Subject: [PATCH 145/451] Adjust iceThicknessHydro logic + implementation Addresses comments in original PR about iceThicknessHydro. iceThickness hydro is now calculated for all grounded ice cells, including ice margins and the grounding line, but neighboring cells are only included in averaging calculation if they are also grounded cells. iceThicknessHydro is now an area-weighted average of neighboring cells that replaces local minima and maxima. --- .../src/Registry_subglacial_hydro.xml | 2 +- .../mode_forward/mpas_li_subglacial_hydro.F | 48 +++++++++---------- 2 files changed, 23 insertions(+), 27 deletions(-) diff --git a/components/mpas-albany-landice/src/Registry_subglacial_hydro.xml b/components/mpas-albany-landice/src/Registry_subglacial_hydro.xml index ecbcb89a48bb..143497036c10 100644 --- a/components/mpas-albany-landice/src/Registry_subglacial_hydro.xml +++ b/components/mpas-albany-landice/src/Registry_subglacial_hydro.xml @@ -79,7 +79,7 @@ /> diff --git a/components/mpas-albany-landice/src/mode_forward/mpas_li_subglacial_hydro.F b/components/mpas-albany-landice/src/mode_forward/mpas_li_subglacial_hydro.F index 2b0986249c1b..d708f79eca5e 100644 --- a/components/mpas-albany-landice/src/mode_forward/mpas_li_subglacial_hydro.F +++ b/components/mpas-albany-landice/src/mode_forward/mpas_li_subglacial_hydro.F @@ -2449,6 +2449,7 @@ subroutine calc_iceThicknessHydro(block, err) integer, dimension(:,:), pointer :: edgesOnCell integer, dimension(:), pointer :: cellMask integer, dimension(:), pointer :: edgeMask + real (kind=RKIND), dimension(:), pointer :: areaCell integer, pointer :: nCells integer :: edgeNum integer, dimension(:), pointer :: nEdgesOnCell @@ -2456,12 +2457,11 @@ subroutine calc_iceThicknessHydro(block, err) integer :: iCell integer :: jCell integer :: iNeighbor - integer :: isMarineMargin real (kind=RKIND) :: maxNeighborHeight real (kind=RKIND) :: minNeighborHeight real (kind=RKIND) :: meanNeighborHeight - real (kind=RKIND) :: totNeighborHeight - real (kind=RKIND) :: numCells + real (kind=RKIND) :: totalNeighborHeight + real (kind=RKIND) :: totalArea real (kind=RKIND), parameter :: bigValue = 1.0e6_RKIND real (kind=RKIND), parameter :: bigNegativeValue = -1.0e6_RKIND logical, pointer :: config_SGH_use_iceThicknessHydro @@ -2484,6 +2484,7 @@ subroutine calc_iceThicknessHydro(block, err) call mpas_pool_get_array(meshPool, 'cellsOnCell', cellsOnCell) call mpas_pool_get_array(meshPool, 'edgesOnCell', edgesOnCell) call mpas_pool_get_array(meshPool, 'nEdgesOnCell', nEdgesOnCell) + call mpas_pool_get_array(meshPool, 'areaCell', areaCell) call mpas_pool_get_array(hydroPool, 'hydroMarineMarginMask', hydroMarineMarginMask) call mpas_pool_get_config(liConfigs, 'config_SGH_use_iceThicknessHydro', config_SGH_use_iceThicknessHydro) @@ -2496,41 +2497,37 @@ subroutine calc_iceThicknessHydro(block, err) if (config_SGH_use_iceThicknessHydro) then do iCell = 1, nCells - if ((li_mask_is_grounded_ice(cellMask(iCell))) .and. (.not. li_mask_is_margin(cellMask(iCell)))) then !identify domain boundaries + if (li_mask_is_grounded_ice(cellMask(iCell))) then !identify domain boundaries - isMarineMargin = 0 - do edgeNum = 1, nEdgesOnCell(iCell) - iEdge = edgesOnCell(edgeNum,iCell) - if (hydroMarineMarginMask(iEdge) == 1) then - isMarineMargin = 1 - exit - endif - enddo - - if (isMarineMargin == 0) then - maxNeighborHeight = bigNegativeValue !allocate + maxNeighborHeight = bigNegativeValue !initialize minNeighborHeight = bigValue + totalNeighborHeight = 0.0_RKIND + totalArea = 0.0_RKIND + do jCell = 1, nEdgesOnCell(iCell) + iNeighbor = cellsOnCell(jCell,iCell) - if (iNeighbor < nCells + 1) then + !Only include neighbor cell in averaging if it contains grounded ice + if ((li_mask_is_grounded_ice(cellMask(iNeighbor)))) then - if (jCell == 1) then - totNeighborHeight = upperSurface(iNeighbor) - numCells = 1 - endif - minNeighborHeight = min(minNeighborHeight, upperSurface(iNeighbor)) maxNeighborHeight = max(maxNeighborHeight, upperSurface(iNeighbor)) - totNeighborHeight = totNeighborHeight + upperSurface(iNeighbor) - numCells = numCells + 1 + totalNeighborHeight = totalNeighborHeight + upperSurface(iNeighbor)*areaCell(iNeighbor) + + totalArea = totalArea + areaCell(iNeighbor) + endif end do - - meanNeighborHeight = totNeighborHeight / numCells + + if ((totalNeighborHeight == 0.0_RKIND) .or. (totalArea == 0.0_RKIND)) then + meanNeighborHeight = upperSurface(iCell) !no smoothing in single-cell islands + else + meanNeighborHeight = totalNeighborHeight / totalArea !area-weighted average height + endif !only adjust surface elevation if cell is local minimum or !maximum @@ -2550,7 +2547,6 @@ subroutine calc_iceThicknessHydro(block, err) if (iceThicknessHydro(iCell) < 0.0_RKIND) then iceThicknessHydro(iCell) = thickness(iCell) endif - endif endif enddo endif From e76d9a96abc804430fb78f8adf7fa625eebf6c98 Mon Sep 17 00:00:00 2001 From: Alexander Hager Date: Mon, 4 Mar 2024 10:17:42 -0700 Subject: [PATCH 146/451] waterPressure area-weighted mean subroutine Addresses PR comments regarding waterPressureSmooth, namely, moving waterPressureSmooth calculation to its own subroutine, making waterPressureSmooth an area-weighted mean of the current cell and its neighbors, and adding halo updates. Please enter the commit message for your changes. Lines starting --- .../src/Registry_subglacial_hydro.xml | 3 - .../mode_forward/mpas_li_subglacial_hydro.F | 200 +++++++++++------- 2 files changed, 123 insertions(+), 80 deletions(-) diff --git a/components/mpas-albany-landice/src/Registry_subglacial_hydro.xml b/components/mpas-albany-landice/src/Registry_subglacial_hydro.xml index 143497036c10..87af56eee82b 100644 --- a/components/mpas-albany-landice/src/Registry_subglacial_hydro.xml +++ b/components/mpas-albany-landice/src/Registry_subglacial_hydro.xml @@ -253,9 +253,6 @@ - - block % next end do @@ -302,8 +310,6 @@ subroutine li_SGH_solve(domain, err) integer :: numSubCycles ! number of subcycles integer :: err_tmp - - err = 0 err_tmp = 0 @@ -641,6 +647,14 @@ subroutine li_SGH_solve(domain, err) call calc_pressure(block, err_tmp) err = ior(err, err_tmp) + + call calc_waterPressureSmooth(block, err_tmp) !adjust ice thickness along boundaries + err = ior(err,err_tmp) + + !updates halos for waterPressure + call mpas_timer_start("halo updates") + call mpas_dmpar_field_halo_exch(domain, 'waterPressureSlopeNormal') + call mpas_timer_stop("halo updates") block => block % next end do @@ -777,7 +791,6 @@ subroutine calc_edge_quantities(block, err) real (kind=RKIND), dimension(:), pointer :: hydropotentialBaseVertex real (kind=RKIND), dimension(:), pointer :: hydropotentialVertex real (kind=RKIND), dimension(:), pointer :: waterPressure - real (kind=RKIND), dimension(:), pointer :: waterPressureSmooth real (kind=RKIND), dimension(:), pointer :: waterThicknessEdge real (kind=RKIND), dimension(:), pointer :: waterThicknessEdgeUpwind real (kind=RKIND), dimension(:), pointer :: waterThickness @@ -796,8 +809,7 @@ subroutine calc_edge_quantities(block, err) real (kind=RKIND), dimension(:), pointer :: waterFlux real (kind=RKIND), dimension(:), pointer :: waterFluxAdvec real (kind=RKIND), dimension(:), pointer :: waterFluxDiffu - real (kind=RKIND), dimension(:), pointer :: channelDebugMask - real (kind=RKIND), dimension(:), pointer :: pressureField + real (kind=RKIND), dimension(:), pointer :: waterPressureSmooth integer, dimension(:), pointer :: hydroMarineMarginMask integer, dimension(:), pointer :: waterFluxMask integer, dimension(:,:), pointer :: edgeSignOnCell @@ -832,7 +844,6 @@ subroutine calc_edge_quantities(block, err) integer :: iNeighbor integer :: numCells integer :: iter - real (kind=RKIND) :: totNeighborPressure err = 0 err_tmp = 0 @@ -858,7 +869,6 @@ subroutine calc_edge_quantities(block, err) call mpas_pool_get_array(hydroPool, 'waterThickness', waterThickness) call mpas_pool_get_array(hydroPool, 'waterPressure', waterPressure) - call mpas_pool_get_array(hydroPool, 'waterPressureSmooth', waterPressureSmooth) call mpas_pool_get_array(hydroPool, 'hydropotentialBase', hydropotentialBase) call mpas_pool_get_array(hydroPool, 'hydropotential', hydropotential) call mpas_pool_get_array(geometryPool, 'bedTopography', bedTopography) @@ -888,9 +898,8 @@ subroutine calc_edge_quantities(block, err) call mpas_pool_get_array(hydroPool, 'waterFluxMask', waterFluxMask) call mpas_pool_get_array(hydroPool, 'hydroMarineMarginMask', hydroMarineMarginMask) call mpas_pool_get_array(geometryPool, 'edgeMask', edgeMask) - call mpas_pool_get_array(hydroPool, 'channelDebugMask', channelDebugMask) call mpas_pool_get_array(hydroPool, 'hydroMarineMarginMask', hydroMarineMarginMask) - call mpas_pool_get_array(hydroPool, 'pressureField', pressureField) + call mpas_pool_get_array(hydroPool, 'waterPressureSmooth', waterPressureSmooth) do iEdge = 1, nEdges cell1 = cellsOnEdge(1, iEdge) @@ -908,63 +917,7 @@ subroutine calc_edge_quantities(block, err) hydropotentialBaseSlopeNormal(iEdge) = (hydropotentialBase(cell2) - hydropotentialBase(cell1)) / dcEdge(iEdge) hydropotentialSlopeNormal(iEdge) = (hydropotential(cell2) - hydropotential(cell1)) / dcEdge(iEdge) - !waterPressureSlopeNormal(iEdge) = (waterPressure(cell2) - waterPressure(cell1)) / dcEdge(iEdge) - end do - - ! Create a smoothed waterPressure product used only for - ! calculating waterPressureSlopeNormal - to avoid channelPressureFreeze - ! instabilities - - if (nTimesSmooth > 0) then - do iter = 1, nTimesSmooth !May need to iterate to smooth properly - if (iter == 1) then - waterPressureSmooth = waterPressure - pressureField = waterPressure - else - pressureField = waterPressureSmooth - endif - - do iCell = 1, nCells - if ((li_mask_is_grounded_ice(cellMask(iCell))) .and. (.not. li_mask_is_margin(cellMask(iCell)))) then - - isMarineMargin = 0 - do edgeNum = 1, nEdgesOnCell(iCell) - iEdge = edgesOnCell(edgeNum,iCell) - if (hydroMarineMarginMask(iEdge) == 1) then - isMarineMargin = 1 - exit - endif - enddo - - if (isMarineMargin == 0) then - - totNeighborPressure = pressureField(iCell) - numCells = 1 - - do jCell = 1, nEdgesOnCell(iCell) - iNeighbor = cellsOnCell(jCell,iCell) - - if (iNeighbor < nCells + 1) then - totNeighborPressure = totNeighborPressure + pressureField(iNeighbor) - numCells = numCells + 1 - endif - end do - - !waterPressureSmooth is average of neighboring cells - waterPressureSmooth(iCell) = totNeighborPressure / numCells - endif - endif - end do - end do - elseif (nTimesSmooth == 0) then - waterPressureSmooth = waterPressure - endif - - do iEdge = 1, nEdges - cell1 = cellsOnEdge(1, iEdge) - cell2 = cellsOnEdge(2, iEdge) - waterPressureSlopeNormal(iEdge) = (waterPressureSmooth(cell2) - waterPressureSmooth(cell1)) / dcEdge(iEdge) end do @@ -1751,7 +1704,6 @@ subroutine calc_pressure_diag_vars(block, err) type (mpas_pool_type), pointer :: geometryPool type (mpas_pool_type), pointer :: hydroPool real (kind=RKIND), pointer :: rhoi, rhoo - real (kind=RKIND), dimension(:), pointer :: thickness real (kind=RKIND), dimension(:), pointer :: waterPressure real (kind=RKIND), dimension(:), pointer :: bedTopography real (kind=RKIND), dimension(:), pointer :: hydropotentialBase @@ -1773,7 +1725,6 @@ subroutine calc_pressure_diag_vars(block, err) call mpas_pool_get_config(liConfigs, 'config_ocean_density', rhoo) call mpas_pool_get_array(hydroPool, 'effectivePressure', effectivePressure) - call mpas_pool_get_array(geometryPool, 'thickness', thickness) call mpas_pool_get_array(hydroPool, 'waterPressure', waterPressure) call mpas_pool_get_array(geometryPool, 'bedTopography', bedTopography) call mpas_pool_get_array(hydroPool, 'hydropotentialBase', hydropotentialBase) @@ -2255,7 +2206,6 @@ subroutine ocean_connection_N(domain) type (block_type), pointer :: block type (mpas_pool_type), pointer :: hydroPool type (mpas_pool_type), pointer :: geometryPool - real (kind=RKIND), dimension(:), pointer :: thickness real (kind=RKIND), dimension(:), pointer :: bedTopography real (kind=RKIND), dimension(:), pointer :: effectivePressure real (kind=RKIND), dimension(:), pointer :: iceThicknessHydro @@ -2270,7 +2220,6 @@ subroutine ocean_connection_N(domain) do while (associated(block)) call mpas_pool_get_subpool(block % structs, 'geometry', geometryPool) call mpas_pool_get_subpool(block % structs, 'hydro', hydroPool) - call mpas_pool_get_array(geometryPool, 'thickness', thickness) call mpas_pool_get_array(geometryPool, 'bedTopography', bedTopography) call mpas_pool_get_array(hydroPool, 'effectivePressure', effectivePressure) call mpas_pool_get_array(hydroPool, 'iceThicknessHydro', iceThicknessHydro) @@ -2413,8 +2362,8 @@ end subroutine calc_hydro_mask !> \author Alex Hager !> \date 7 June 2023 !> \details -!> This routine calculates a modified ice thickness that is altered at -! the domain boundaries to avoid local minima in hydropotential +!> This routine calculates a modified ice thickness that is altered to +!> avoid local minima in hydropotential !----------------------------------------------------------------------- subroutine calc_iceThicknessHydro(block, err) @@ -2566,7 +2515,6 @@ end subroutine calc_iceThicknessHydro !> \details Find the total amount of freshwater entering the first ocean cell from the grounding line. !----------------------------------------------------------------------- subroutine calc_gl_totals(block, err) - !----------------------------------------------------------------- ! input variables !----------------------------------------------------------------- @@ -2581,11 +2529,6 @@ subroutine calc_gl_totals(block, err) !----------------------------------------------------------------- integer, intent(out) :: err !< Output: error flag - !----------------------------------------------------------------- - !----------------------------------------------------------------- - ! output variables - !----------------------------------------------------------------- - !----------------------------------------------------------------- ! local variables !----------------------------------------------------------------- @@ -2653,4 +2596,107 @@ subroutine calc_gl_totals(block, err) enddo end subroutine calc_gl_totals +!*********************************************************************** +! +! routine calc_waterPressureSmooth +! +!> \brief Calculate smoothed version of waterPressure used for calculation +!> of waterPressureSlopeNormal +!> \author Alex Hager +!> \date 29 February 2024 +!> \details Creates a smoothed version of waterPressure, called waterPressureSmooth, +!> that is used for calculation of waterPressureSlopeNormal. +!> This is necessary to increase stability with channelPressureFreeze +!> with spatially variable bedTopography and upperSurface. waterPressureSmooth +!> an area-weighted average of the current cells and its neighbors. Possible to +!> perform multiple iterations of smoothing by adjusting +!> config_SGH_iter_smooth_waterPressureSlopeNormal +!----------------------------------------------------------------------- + subroutine calc_waterPressureSmooth(block,err) + !----------------------------------------------------------------- + ! input variables + !----------------------------------------------------------------- + + !----------------------------------------------------------------- + ! input/output variables + !----------------------------------------------------------------- + type (block_type), intent(inout) :: block !< Input/Output: block object + + !----------------------------------------------------------------- + ! output variables + !----------------------------------------------------------------- + integer, intent(out) :: err !< Output: error flag + + !----------------------------------------------------------------- + ! local variables + !----------------------------------------------------------------- + + type (mpas_pool_type), pointer :: meshPool + type (mpas_pool_type), pointer :: geometryPool + type (mpas_pool_type), pointer :: hydroPool + real (kind=RKIND), dimension(:), pointer :: bedTopography + real (kind=RKIND), dimension(:), pointer :: waterPressure + real (kind=RKIND), dimension(:), pointer :: waterPressureSmooth + real (kind=RKIND), dimension(:), pointer :: areaCell + real (kind=RKIND), dimension(:), allocatable :: pressureField + real(kind=RKIND) :: totalPressure + real(kind=RKIND) :: totalArea + integer, dimension(:), pointer :: cellMask + integer, dimension(:,:), pointer :: cellsOnCell + integer, dimension(:), pointer :: nEdgesOnCell + integer, pointer :: nTimesSmooth + integer, pointer :: nCells + integer :: iCell, jCell + integer :: iNeighbor + integer :: iter + + err = 0 + + ! Get pools things + call mpas_pool_get_subpool(block % structs, 'mesh', meshPool) + call mpas_pool_get_subpool(block % structs, 'hydro', hydroPool) + call mpas_pool_get_subpool(block % structs, 'geometry', geometryPool) + call mpas_pool_get_dimension(meshPool, 'nCells', nCells) + call mpas_pool_get_config(liConfigs, 'config_SGH_iter_smooth_waterPressureSlopeNormal', nTimesSmooth) + call mpas_pool_get_array(hydroPool, 'waterPressure', waterPressure) + call mpas_pool_get_array(hydroPool, 'waterPressureSmooth', waterPressureSmooth) + call mpas_pool_get_array(geometryPool, 'cellMask', cellMask) + call mpas_pool_get_array(meshPool, 'cellsOnCell', cellsOnCell) + call mpas_pool_get_array(meshPool, 'nEdgesOnCell', nEdgesOnCell) + call mpas_pool_get_array(meshPool, 'areaCell', areaCell) + allocate(pressureField(nCells+1)) + + waterPressureSmooth = waterPressure + pressureField = waterPressure + + do iter = 1, nTimesSmooth !May need to iterate to smooth properly + + do iCell = 1, nCells + if (li_mask_is_grounded_ice(cellMask(iCell))) then !smooth over all grounded cells + + totalPressure = pressureField(iCell) + totalArea = areaCell(iCell) + + do jCell = 1, nEdgesOnCell(iCell) + iNeighbor = cellsOnCell(jCell,iCell) + + if ((li_mask_is_grounded_ice(cellMask(iNeighbor)))) then + + totalPressure = totalPressure + pressureField(iNeighbor)*areaCell(iNeighbor) + + totalArea = totalArea + areaCell(iNeighbor) + endif + end do + + waterPressureSmooth(iCell) = totalPressure / totalArea !area-weighted average height + endif + end do + + pressureField = waterPressureSmooth + + end do + + deallocate(pressureField) + end subroutine calc_waterPressureSmooth + end module li_subglacial_hydro From 1f94eb5e39f32f136c6b4e0579817d3fdde2e10b Mon Sep 17 00:00:00 2001 From: Alexander Hager Date: Mon, 4 Mar 2024 11:00:18 -0700 Subject: [PATCH 147/451] Debug waterPressureSmooth fixes minor bug in waterPRessureSmooth calculation --- .../src/mode_forward/mpas_li_subglacial_hydro.F | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/components/mpas-albany-landice/src/mode_forward/mpas_li_subglacial_hydro.F b/components/mpas-albany-landice/src/mode_forward/mpas_li_subglacial_hydro.F index f74351f14ae8..a7f39e2c8308 100644 --- a/components/mpas-albany-landice/src/mode_forward/mpas_li_subglacial_hydro.F +++ b/components/mpas-albany-landice/src/mode_forward/mpas_li_subglacial_hydro.F @@ -2674,7 +2674,7 @@ subroutine calc_waterPressureSmooth(block,err) do iCell = 1, nCells if (li_mask_is_grounded_ice(cellMask(iCell))) then !smooth over all grounded cells - totalPressure = pressureField(iCell) + totalPressure = pressureField(iCell)*areaCell(iCell) totalArea = areaCell(iCell) do jCell = 1, nEdgesOnCell(iCell) @@ -2688,7 +2688,7 @@ subroutine calc_waterPressureSmooth(block,err) endif end do - waterPressureSmooth(iCell) = totalPressure / totalArea !area-weighted average height + waterPressureSmooth(iCell) = totalPressure / totalArea !area-weighted average pressure endif end do From 435acd54def3fe98bbc8d714058859bc0841f34f Mon Sep 17 00:00:00 2001 From: Alexander Hager Date: Fri, 8 Mar 2024 11:39:42 -0700 Subject: [PATCH 148/451] PR cleanup Implements minor edits to PR to clean up code and debug halo updates --- .../mode_forward/mpas_li_subglacial_hydro.F | 77 +++++++++---------- 1 file changed, 37 insertions(+), 40 deletions(-) diff --git a/components/mpas-albany-landice/src/mode_forward/mpas_li_subglacial_hydro.F b/components/mpas-albany-landice/src/mode_forward/mpas_li_subglacial_hydro.F index a7f39e2c8308..2724921170d4 100644 --- a/components/mpas-albany-landice/src/mode_forward/mpas_li_subglacial_hydro.F +++ b/components/mpas-albany-landice/src/mode_forward/mpas_li_subglacial_hydro.F @@ -181,12 +181,29 @@ subroutine li_SGH_init(domain, err) tillWaterThickness = max(0.0_RKIND, tillWaterThickness) tillWaterThickness = min(tillMax, tillWaterThickness) - call mpas_pool_get_array(hydroPool, 'waterPressure', waterPressure) call mpas_pool_get_array(geometryPool, 'thickness', thickness) call mpas_pool_get_array(hydroPool, 'iceThicknessHydro', iceThicknessHydro) call calc_iceThicknessHydro(block, err_tmp) !adjust ice thickness along boundaries err = ior(err,err_tmp) + block => block % next + end do + + !update halo for iceThicknessHydro + call mpas_timer_start("halo updates") + call mpas_dmpar_field_halo_exch(domain, 'iceThicknessHydro') + call mpas_timer_stop("halo updates") + + block => domain % blocklist + do while (associated(block)) + call mpas_pool_get_subpool(block % structs, 'mesh', meshPool) + call mpas_pool_get_subpool(block % structs, 'hydro', hydroPool) + call mpas_pool_get_subpool(block % structs, 'geometry', geometryPool) + call mpas_pool_get_subpool(block % structs, 'velocity', velocityPool) + call mpas_pool_get_array(hydroPool, 'waterPressure', waterPressure) + call mpas_pool_get_array(hydroPool, 'deltatSGH', deltatSGH) + call mpas_pool_get_array(hydroPool, 'iceThicknessHydro', iceThicknessHydro) + waterPressure = max(0.0_RKIND, waterPressure) waterPressure = min(waterPressure, rhoi * gravity * iceThicknessHydro) ! set pressure correctly under floating ice and open ocean @@ -201,22 +218,18 @@ subroutine li_SGH_init(domain, err) call calc_pressure_diag_vars(block, err_tmp) err = ior(err, err_tmp) - call calc_waterPressureSmooth(block, err_tmp) !adjust ice thickness along boundaries + !smooth water pressure for calculation of waterPressureSlopeNormal + call calc_waterPressureSmooth(block, err_tmp) err = ior(err,err_tmp) - !updates halos for waterPressure - call mpas_timer_start("halo updates") - call mpas_dmpar_field_halo_exch(domain, 'waterPressureSlopeNormal') - call mpas_timer_stop("halo updates") - block => block % next end do - !update halo for iceThicknessHydro + !updates halos for waterPressure call mpas_timer_start("halo updates") - call mpas_dmpar_field_halo_exch(domain, 'iceThicknessHydro') + call mpas_dmpar_field_halo_exch(domain, 'waterPressureSmooth') call mpas_timer_stop("halo updates") - + ! === error check if (err > 0) then call mpas_log_write("An error has occurred in li_SGH_init.", MPAS_LOG_ERR) @@ -651,14 +664,14 @@ subroutine li_SGH_solve(domain, err) call calc_waterPressureSmooth(block, err_tmp) !adjust ice thickness along boundaries err = ior(err,err_tmp) - !updates halos for waterPressure - call mpas_timer_start("halo updates") - call mpas_dmpar_field_halo_exch(domain, 'waterPressureSlopeNormal') - call mpas_timer_stop("halo updates") - block => block % next end do + !updates halos for waterPressure + call mpas_timer_start("halo updates") + call mpas_dmpar_field_halo_exch(domain, 'waterPressureSmooth') + call mpas_timer_stop("halo updates") + ! ============= ! ============= @@ -818,7 +831,6 @@ subroutine calc_edge_quantities(block, err) integer, dimension(:,:), pointer :: cellsOnEdge integer, dimension(:,:), pointer :: edgesOnCell integer, dimension(:,:), pointer :: cellsOnCell - integer, dimension(:), pointer :: nEdgesOnCell integer, dimension(:,:), pointer :: verticesOnEdge integer, dimension(:,:), pointer :: baryCellsOnVertex real (kind=RKIND), dimension(:,:), pointer :: baryWeightsOnVertex @@ -830,12 +842,11 @@ subroutine calc_edge_quantities(block, err) character (len=StrKIND), pointer :: config_SGH_tangent_slope_calculation real (kind=RKIND), pointer :: config_sea_level real (kind=RKIND), pointer :: rhoo - integer, pointer :: nTimesSmooth integer, pointer :: nEdges integer, pointer :: nCells integer, pointer :: nVertices integer :: iEdge, cell1, cell2 - integer :: i, j, iVertex, iCell, jCell + integer :: i, j, iVertex, iCell real (kind=RKIND) :: velSign integer :: numGroundedCells integer :: err_tmp @@ -843,7 +854,6 @@ subroutine calc_edge_quantities(block, err) integer :: edgeNum integer :: iNeighbor integer :: numCells - integer :: iter err = 0 err_tmp = 0 @@ -865,7 +875,6 @@ subroutine calc_edge_quantities(block, err) call mpas_pool_get_config(liConfigs, 'config_SGH_tangent_slope_calculation', config_SGH_tangent_slope_calculation) call mpas_pool_get_config(liConfigs, 'config_sea_level', config_sea_level) call mpas_pool_get_config(liConfigs, 'config_ocean_density', rhoo) - call mpas_pool_get_config(liConfigs, 'config_SGH_iter_smooth_waterPressureSlopeNormal', nTimesSmooth) call mpas_pool_get_array(hydroPool, 'waterThickness', waterThickness) call mpas_pool_get_array(hydroPool, 'waterPressure', waterPressure) @@ -883,7 +892,6 @@ subroutine calc_edge_quantities(block, err) call mpas_pool_get_array(meshPool, 'cellsOnEdge', cellsOnEdge) call mpas_pool_get_array(meshPool, 'edgesOnCell', edgesOnCell) call mpas_pool_get_array(meshPool, 'cellsOnCell', cellsOnCell) - call mpas_pool_get_array(meshPool, 'nEdgesOnCell', nEdgesOnCell) call mpas_pool_get_array(meshPool, 'edgeSignOnCell', edgeSignOnCell) call mpas_pool_get_array(hydroPool, 'hydropotentialBaseSlopeTangent', hydropotentialBaseSlopeTangent) call mpas_pool_get_array(hydroPool, 'hydropotentialSlopeTangent', hydropotentialSlopeTangent) @@ -898,7 +906,6 @@ subroutine calc_edge_quantities(block, err) call mpas_pool_get_array(hydroPool, 'waterFluxMask', waterFluxMask) call mpas_pool_get_array(hydroPool, 'hydroMarineMarginMask', hydroMarineMarginMask) call mpas_pool_get_array(geometryPool, 'edgeMask', edgeMask) - call mpas_pool_get_array(hydroPool, 'hydroMarineMarginMask', hydroMarineMarginMask) call mpas_pool_get_array(hydroPool, 'waterPressureSmooth', waterPressureSmooth) do iEdge = 1, nEdges @@ -2393,16 +2400,11 @@ subroutine calc_iceThicknessHydro(block, err) real (kind=RKIND), dimension(:), pointer :: iceThicknessHydro real (kind=RKIND), dimension(:), pointer :: upperSurfaceHydro real (kind=RKIND), dimension(:), pointer :: upperSurface - integer, dimension(:), pointer :: hydroMarineMarginMask integer, dimension(:,:), pointer :: cellsOnCell - integer, dimension(:,:), pointer :: edgesOnCell integer, dimension(:), pointer :: cellMask - integer, dimension(:), pointer :: edgeMask real (kind=RKIND), dimension(:), pointer :: areaCell integer, pointer :: nCells - integer :: edgeNum integer, dimension(:), pointer :: nEdgesOnCell - integer :: iEdge integer :: iCell integer :: jCell integer :: iNeighbor @@ -2424,17 +2426,14 @@ subroutine calc_iceThicknessHydro(block, err) call mpas_pool_get_array(geometryPool, 'thickness', thickness) call mpas_pool_get_array(geometryPool, 'bedTopography', bedTopography) call mpas_pool_get_array(geometryPool, 'cellMask', cellMask) - call mpas_pool_get_array(geometryPool, 'edgeMask', edgeMask) call mpas_pool_get_array(hydroPool, 'iceThicknessHydro', iceThicknessHydro) call mpas_pool_get_array(hydroPool, 'upperSurfaceHydro', upperSurfaceHydro) call mpas_pool_get_array(geometryPool, 'upperSurface', upperSurface) call mpas_pool_get_array(meshPool, 'nEdgesOnCell', nEdgesOnCell) call mpas_pool_get_dimension(meshPool, 'nCells', nCells) call mpas_pool_get_array(meshPool, 'cellsOnCell', cellsOnCell) - call mpas_pool_get_array(meshPool, 'edgesOnCell', edgesOnCell) call mpas_pool_get_array(meshPool, 'nEdgesOnCell', nEdgesOnCell) call mpas_pool_get_array(meshPool, 'areaCell', areaCell) - call mpas_pool_get_array(hydroPool, 'hydroMarineMarginMask', hydroMarineMarginMask) call mpas_pool_get_config(liConfigs, 'config_SGH_use_iceThicknessHydro', config_SGH_use_iceThicknessHydro) iceThicknessHydro = thickness @@ -2446,7 +2445,7 @@ subroutine calc_iceThicknessHydro(block, err) if (config_SGH_use_iceThicknessHydro) then do iCell = 1, nCells - if (li_mask_is_grounded_ice(cellMask(iCell))) then !identify domain boundaries + if (li_mask_is_grounded_ice(cellMask(iCell))) then !identify grounded ice maxNeighborHeight = bigNegativeValue !initialize minNeighborHeight = bigValue @@ -2646,7 +2645,7 @@ subroutine calc_waterPressureSmooth(block,err) integer, dimension(:), pointer :: nEdgesOnCell integer, pointer :: nTimesSmooth integer, pointer :: nCells - integer :: iCell, jCell + integer :: iCell, jEdge integer :: iNeighbor integer :: iter @@ -2677,8 +2676,8 @@ subroutine calc_waterPressureSmooth(block,err) totalPressure = pressureField(iCell)*areaCell(iCell) totalArea = areaCell(iCell) - do jCell = 1, nEdgesOnCell(iCell) - iNeighbor = cellsOnCell(jCell,iCell) + do jEdge = 1, nEdgesOnCell(iCell) + iNeighbor = cellsOnCell(jEdge,iCell) if ((li_mask_is_grounded_ice(cellMask(iNeighbor)))) then @@ -2690,13 +2689,11 @@ subroutine calc_waterPressureSmooth(block,err) waterPressureSmooth(iCell) = totalPressure / totalArea !area-weighted average pressure endif + end do + pressureField = waterPressureSmooth end do - - pressureField = waterPressureSmooth - - end do - - deallocate(pressureField) + + deallocate(pressureField) end subroutine calc_waterPressureSmooth end module li_subglacial_hydro From b352169bf19a940ffce621608505249c0a6f4340 Mon Sep 17 00:00:00 2001 From: Alexander Hager Date: Wed, 22 May 2024 14:07:20 -0600 Subject: [PATCH 149/451] PR Cleanup #2 Addresses minor cleaning edits following second round of review --- .../src/Registry_subglacial_hydro.xml | 2 -- .../mode_forward/mpas_li_subglacial_hydro.F | 25 +++++-------------- 2 files changed, 6 insertions(+), 21 deletions(-) diff --git a/components/mpas-albany-landice/src/Registry_subglacial_hydro.xml b/components/mpas-albany-landice/src/Registry_subglacial_hydro.xml index 87af56eee82b..fdc4cd0b3878 100644 --- a/components/mpas-albany-landice/src/Registry_subglacial_hydro.xml +++ b/components/mpas-albany-landice/src/Registry_subglacial_hydro.xml @@ -152,8 +152,6 @@ - domain % blocklist do while (associated(block)) - call mpas_pool_get_subpool(block % structs, 'mesh', meshPool) call mpas_pool_get_subpool(block % structs, 'hydro', hydroPool) call mpas_pool_get_subpool(block % structs, 'geometry', geometryPool) - call mpas_pool_get_subpool(block % structs, 'velocity', velocityPool) call mpas_pool_get_array(hydroPool, 'waterPressure', waterPressure) - call mpas_pool_get_array(hydroPool, 'deltatSGH', deltatSGH) call mpas_pool_get_array(hydroPool, 'iceThicknessHydro', iceThicknessHydro) waterPressure = max(0.0_RKIND, waterPressure) @@ -225,7 +222,7 @@ subroutine li_SGH_init(domain, err) block => block % next end do - !updates halos for waterPressure + !updates halos for waterPressureSmooth call mpas_timer_start("halo updates") call mpas_dmpar_field_halo_exch(domain, 'waterPressureSmooth') call mpas_timer_stop("halo updates") @@ -661,7 +658,7 @@ subroutine li_SGH_solve(domain, err) call calc_pressure(block, err_tmp) err = ior(err, err_tmp) - call calc_waterPressureSmooth(block, err_tmp) !adjust ice thickness along boundaries + call calc_waterPressureSmooth(block, err_tmp) !compute smoothed version of waterPressure err = ior(err,err_tmp) block => block % next @@ -830,7 +827,6 @@ subroutine calc_edge_quantities(block, err) integer, dimension(:), pointer :: edgeMask integer, dimension(:,:), pointer :: cellsOnEdge integer, dimension(:,:), pointer :: edgesOnCell - integer, dimension(:,:), pointer :: cellsOnCell integer, dimension(:,:), pointer :: verticesOnEdge integer, dimension(:,:), pointer :: baryCellsOnVertex real (kind=RKIND), dimension(:,:), pointer :: baryWeightsOnVertex @@ -850,10 +846,6 @@ subroutine calc_edge_quantities(block, err) real (kind=RKIND) :: velSign integer :: numGroundedCells integer :: err_tmp - integer :: isMarineMargin - integer :: edgeNum - integer :: iNeighbor - integer :: numCells err = 0 err_tmp = 0 @@ -891,7 +883,6 @@ subroutine calc_edge_quantities(block, err) call mpas_pool_get_array(geometryPool, 'cellMask', cellMask) call mpas_pool_get_array(meshPool, 'cellsOnEdge', cellsOnEdge) call mpas_pool_get_array(meshPool, 'edgesOnCell', edgesOnCell) - call mpas_pool_get_array(meshPool, 'cellsOnCell', cellsOnCell) call mpas_pool_get_array(meshPool, 'edgeSignOnCell', edgeSignOnCell) call mpas_pool_get_array(hydroPool, 'hydropotentialBaseSlopeTangent', hydropotentialBaseSlopeTangent) call mpas_pool_get_array(hydroPool, 'hydropotentialSlopeTangent', hydropotentialSlopeTangent) @@ -2215,7 +2206,7 @@ subroutine ocean_connection_N(domain) type (mpas_pool_type), pointer :: geometryPool real (kind=RKIND), dimension(:), pointer :: bedTopography real (kind=RKIND), dimension(:), pointer :: effectivePressure - real (kind=RKIND), dimension(:), pointer :: iceThicknessHydro + real (kind=RKIND), dimension(:), pointer :: thickness real (kind=RKIND), pointer :: rhoi, rhoo ! Calculate N assuming perfect ocean connection @@ -2229,9 +2220,9 @@ subroutine ocean_connection_N(domain) call mpas_pool_get_subpool(block % structs, 'hydro', hydroPool) call mpas_pool_get_array(geometryPool, 'bedTopography', bedTopography) call mpas_pool_get_array(hydroPool, 'effectivePressure', effectivePressure) - call mpas_pool_get_array(hydroPool, 'iceThicknessHydro', iceThicknessHydro) + call mpas_pool_get_array(hydroPool, 'iceThicknessHydro', thickness) - effectivePressure = rhoi * gravity * iceThicknessHydro - rhoi * gravity * max(0.0_RKIND, -1.0_RKIND * rhoo/rhoi * bedTopography) + effectivePressure = rhoi * gravity * thickness - rhoi * gravity * max(0.0_RKIND, -1.0_RKIND * rhoo/rhoi * bedTopography) effectivePressure = max(effectivePressure, 0.0_RKIND) ! This is just to zero out N in the open ocean to avoid confusion block => block % next @@ -2398,7 +2389,6 @@ subroutine calc_iceThicknessHydro(block, err) real (kind=RKIND), dimension(:), pointer :: thickness real (kind=RKIND), dimension(:), pointer :: bedTopography real (kind=RKIND), dimension(:), pointer :: iceThicknessHydro - real (kind=RKIND), dimension(:), pointer :: upperSurfaceHydro real (kind=RKIND), dimension(:), pointer :: upperSurface integer, dimension(:,:), pointer :: cellsOnCell integer, dimension(:), pointer :: cellMask @@ -2427,7 +2417,6 @@ subroutine calc_iceThicknessHydro(block, err) call mpas_pool_get_array(geometryPool, 'bedTopography', bedTopography) call mpas_pool_get_array(geometryPool, 'cellMask', cellMask) call mpas_pool_get_array(hydroPool, 'iceThicknessHydro', iceThicknessHydro) - call mpas_pool_get_array(hydroPool, 'upperSurfaceHydro', upperSurfaceHydro) call mpas_pool_get_array(geometryPool, 'upperSurface', upperSurface) call mpas_pool_get_array(meshPool, 'nEdgesOnCell', nEdgesOnCell) call mpas_pool_get_dimension(meshPool, 'nCells', nCells) @@ -2499,8 +2488,6 @@ subroutine calc_iceThicknessHydro(block, err) enddo endif - upperSurfaceHydro = iceThicknessHydro + bedTopography - end subroutine calc_iceThicknessHydro !*********************************************************************** @@ -2679,7 +2666,7 @@ subroutine calc_waterPressureSmooth(block,err) do jEdge = 1, nEdgesOnCell(iCell) iNeighbor = cellsOnCell(jEdge,iCell) - if ((li_mask_is_grounded_ice(cellMask(iNeighbor)))) then + if ((li_mask_is_grounded_ice(cellMask(iNeighbor)))) then !only include GROUNDED neighboring cells in smoothing totalPressure = totalPressure + pressureField(iNeighbor)*areaCell(iNeighbor) From 455ed3946fa6394b2fc92e8490342a9bff129d6b Mon Sep 17 00:00:00 2001 From: Nicole Jeffery Date: Thu, 23 May 2024 14:49:34 -0500 Subject: [PATCH 150/451] Add atm dust forcing and iron solubility map Adds 2 namelist fields: config_use_atm_dust_file - true, use monthly dust climatology config_use_iron_solubility_file -- true, use dust-iron solubility map from file (in icepack: use_atm_dust_sol = .not.config_use_iron_solubility_file) New fields track atmospheric wet and dry dust separately from the coupler to compute the iron contribution. Fraction of iron in dust is also generalized and read from a file. Dust/iron file is identical to the one used by mpas-o. Corrects some units in Registry. BFB with new namelist parameters = false and for all runs without zaerosols or without iron. --- components/mpas-seaice/bld/build-namelist | 2 + .../mpas-seaice/bld/build-namelist-section | 2 + .../namelist_defaults_mpassi.xml | 2 + .../namelist_definition_mpassi.xml | 16 + components/mpas-seaice/cime_config/buildnml | 9 +- components/mpas-seaice/driver/ice_comp_mct.F | 83 ++++- components/mpas-seaice/src/Registry.xml | 102 ++++-- .../mpas_seaice_core_interface.F | 16 +- .../src/shared/mpas_seaice_constants.F | 6 +- .../src/shared/mpas_seaice_forcing.F | 295 +++++++++++++++++- .../src/shared/mpas_seaice_icepack.F | 54 +++- 11 files changed, 537 insertions(+), 50 deletions(-) diff --git a/components/mpas-seaice/bld/build-namelist b/components/mpas-seaice/bld/build-namelist index d8bfcaa68c05..b5faa4ceeb2d 100755 --- a/components/mpas-seaice/bld/build-namelist +++ b/components/mpas-seaice/bld/build-namelist @@ -696,6 +696,8 @@ add_default($nl, 'config_use_chlorophyll'); add_default($nl, 'config_use_macromolecules'); add_default($nl, 'config_use_modal_aerosols'); add_default($nl, 'config_use_zaerosols'); +add_default($nl, 'config_use_atm_dust_file'); +add_default($nl, 'config_use_iron_solubility_file'); add_default($nl, 'config_skeletal_bgc_flux_type'); add_default($nl, 'config_scale_initial_vertical_bgc'); add_default($nl, 'config_biogrid_bottom_molecular_sublayer'); diff --git a/components/mpas-seaice/bld/build-namelist-section b/components/mpas-seaice/bld/build-namelist-section index 8b6a06dd6740..d2866ee4c813 100644 --- a/components/mpas-seaice/bld/build-namelist-section +++ b/components/mpas-seaice/bld/build-namelist-section @@ -213,6 +213,8 @@ add_default($nl, 'config_use_DON'); add_default($nl, 'config_use_iron'); add_default($nl, 'config_use_modal_aerosols'); add_default($nl, 'config_use_zaerosols'); +add_default($nl, 'config_use_atm_dust_file'); +add_default($nl, 'config_use_iron_solubility_file'); add_default($nl, 'config_skeletal_bgc_flux_type'); add_default($nl, 'config_scale_initial_vertical_bgc'); add_default($nl, 'config_biogrid_bottom_molecular_sublayer'); 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 f4f9bfa1ec3d..1ac5bfe8a04b 100644 --- a/components/mpas-seaice/bld/namelist_files/namelist_defaults_mpassi.xml +++ b/components/mpas-seaice/bld/namelist_files/namelist_defaults_mpassi.xml @@ -239,6 +239,8 @@ false false false +false +false 'Jin2006' false 0.006 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 5f56625f8d97..548004a78dcf 100644 --- a/components/mpas-seaice/bld/namelist_files/namelist_definition_mpassi.xml +++ b/components/mpas-seaice/bld/namelist_files/namelist_definition_mpassi.xml @@ -1115,6 +1115,22 @@ Valid values: true or false Default: Defined in namelist_defaults.xml + +Read atmospheric dust fluxes from a file + +Valid values: true or false +Default: Defined in namelist_defaults.xml + + + +Read atmospheric dust-iron solubility from a file + +Valid values: true or false +Default: Defined in namelist_defaults.xml + + Determines the ocean-ice fluxes of biogeochemistry for the bottom1-layer model: in Jin2006, the piston velocity is a function of ice growth/melt rate, in default, the piston velocity is constant diff --git a/components/mpas-seaice/cime_config/buildnml b/components/mpas-seaice/cime_config/buildnml index e29def8a31f8..5aa44cf06b9b 100755 --- a/components/mpas-seaice/cime_config/buildnml +++ b/components/mpas-seaice/cime_config/buildnml @@ -587,7 +587,14 @@ def buildnml(case, caseroot, compname): lines.append('') + lines.append('') + lines.append('') lines.append('') diff --git a/components/mpas-seaice/driver/ice_comp_mct.F b/components/mpas-seaice/driver/ice_comp_mct.F index 1dac3749056d..5c1bc715518e 100644 --- a/components/mpas-seaice/driver/ice_comp_mct.F +++ b/components/mpas-seaice/driver/ice_comp_mct.F @@ -1222,7 +1222,6 @@ subroutine ice_run_mct( EClock, cdata_i, x2i_i, i2x_i)!{{{ #endif call ice_import_moab(Eclock) #endif - ! Post coupling calls block => domain % blocklist @@ -1999,7 +1998,9 @@ subroutine ice_import_mct(x2i_i, errorCode)!{{{ oceanZAerosolConcField, & atmosAerosolFluxField, & atmosBlackCarbonFluxField, & - atmosDustFluxField + atmosDustFluxField, & + atmosWetDustFluxField, & + atmosDryDustFluxField real (kind=RKIND), dimension(:), pointer :: & seaSurfaceTemperature, & @@ -2045,7 +2046,9 @@ subroutine ice_import_mct(x2i_i, errorCode)!{{{ oceanZAerosolConc, & atmosAerosolFlux, & atmosBlackCarbonFlux, & - atmosDustFlux + atmosDustFlux, & + atmosWetDustFlux, & + atmosDryDustFlux !----------------------------------------------------------------------- ! @@ -2116,6 +2119,8 @@ subroutine ice_import_mct(x2i_i, errorCode)!{{{ call mpas_pool_get_array(biogeochemistry, 'oceanZAerosolConc', oceanZAerosolConc) call mpas_pool_get_array(biogeochemistry, 'atmosBlackCarbonFlux', atmosBlackCarbonFlux) call mpas_pool_get_array(biogeochemistry, 'atmosDustFlux', atmosDustFlux) + call mpas_pool_get_array(biogeochemistry, "atmosWetDustFlux", atmosWetDustFlux) + call mpas_pool_get_array(biogeochemistry, "atmosDryDustFlux", atmosDryDustFlux) endif if (config_use_column_biogeochemistry .and. config_couple_biogeochemistry_fields) then @@ -2247,6 +2252,16 @@ subroutine ice_import_mct(x2i_i, errorCode)!{{{ + x2i_i % rAttr(index_x2i_Faxa_dstdry3, n) atmosDustFlux(4,i) = x2i_i % rAttr(index_x2i_Faxa_dstwet4, n) & + x2i_i % rAttr(index_x2i_Faxa_dstdry4, n) + + atmosWetDustFlux(1,i) = x2i_i % rAttr(index_x2i_Faxa_dstwet1, n) + atmosWetDustFlux(2,i) = x2i_i % rAttr(index_x2i_Faxa_dstwet2, n) + atmosWetDustFlux(3,i) = x2i_i % rAttr(index_x2i_Faxa_dstwet3, n) + atmosWetDustFlux(4,i) = x2i_i % rAttr(index_x2i_Faxa_dstwet4, n) + + atmosDryDustFlux(1,i) = x2i_i % rAttr(index_x2i_Faxa_dstdry1, n) + atmosDryDustFlux(2,i) = x2i_i % rAttr(index_x2i_Faxa_dstdry2, n) + atmosDryDustFlux(3,i) = x2i_i % rAttr(index_x2i_Faxa_dstdry3, n) + atmosDryDustFlux(4,i) = x2i_i % rAttr(index_x2i_Faxa_dstdry4, n) else atmosBlackCarbonFlux(1,i) = x2i_i % rAttr(index_x2i_Faxa_bcphodry, n) atmosBlackCarbonFlux(2,i) = x2i_i % rAttr(index_x2i_Faxa_bcphidry, n) & @@ -2260,6 +2275,16 @@ subroutine ice_import_mct(x2i_i, errorCode)!{{{ + x2i_i % rAttr(index_x2i_Faxa_dstdry3, n) atmosDustFlux(4,i) = x2i_i % rAttr(index_x2i_Faxa_dstwet4, n) & + x2i_i % rAttr(index_x2i_Faxa_dstdry4, n) + + atmosDryDustFlux(1,i) = x2i_i % rAttr(index_x2i_Faxa_dstdry1, n) + atmosDryDustFlux(2,i) = x2i_i % rAttr(index_x2i_Faxa_dstdry2, n) + atmosDryDustFlux(3,i) = x2i_i % rAttr(index_x2i_Faxa_dstdry3, n) + atmosDryDustFlux(4,i) = x2i_i % rAttr(index_x2i_Faxa_dstdry4, n) + + atmosWetDustFlux(1,i) = x2i_i % rAttr(index_x2i_Faxa_dstwet1, n) + atmosWetDustFlux(2,i) = x2i_i % rAttr(index_x2i_Faxa_dstwet2, n) + atmosWetDustFlux(3,i) = x2i_i % rAttr(index_x2i_Faxa_dstwet3, n) + atmosWetDustFlux(4,i) = x2i_i % rAttr(index_x2i_Faxa_dstwet4, n) endif endif ! import biogeochemistry fields, if configured @@ -2348,6 +2373,8 @@ subroutine ice_import_mct(x2i_i, errorCode)!{{{ if (config_use_zaerosols) then call mpas_pool_get_field(biogeochemistry, "atmosBlackCarbonFlux", atmosBlackCarbonFluxField) call mpas_pool_get_field(biogeochemistry, "atmosDustFlux", atmosDustFluxField) + call mpas_pool_get_field(biogeochemistry, "atmosWetDustFlux", atmosWetDustFluxField) + call mpas_pool_get_field(biogeochemistry, "atmosDryDustFlux", atmosDryDustFluxField) call mpas_pool_get_field(biogeochemistry, 'oceanZAerosolConc', oceanZAerosolConcField) endif if (config_use_column_biogeochemistry .and. config_couple_biogeochemistry_fields) then @@ -2398,6 +2425,8 @@ subroutine ice_import_mct(x2i_i, errorCode)!{{{ if (config_use_zaerosols) then call mpas_dmpar_exch_halo_field(atmosBlackCarbonFluxField) call mpas_dmpar_exch_halo_field(atmosDustFluxField) + call mpas_dmpar_exch_halo_field(atmosDryDustFluxField) + call mpas_dmpar_exch_halo_field(atmosWetDustFluxField) call mpas_dmpar_exch_halo_field(oceanZAerosolConcField) endif if (config_use_column_biogeochemistry .and. config_couple_biogeochemistry_fields) then @@ -3567,7 +3596,9 @@ subroutine ice_import_moab(Eclock)!{{{ oceanZAerosolConcField, & atmosAerosolFluxField, & atmosBlackCarbonFluxField, & - atmosDustFluxField + atmosDustFluxField, & + atmosWetDustFluxField, & + atmosDryDustFluxField real (kind=RKIND), dimension(:), pointer :: & seaSurfaceTemperature, & @@ -3612,7 +3643,9 @@ subroutine ice_import_moab(Eclock)!{{{ oceanZAerosolConc, & atmosAerosolFlux, & atmosBlackCarbonFlux, & - atmosDustFlux + atmosDustFlux, & + atmosWetDustFlux, & + atmosDryDustFlux character(CXX) :: tagname integer :: ierr, ent_type integer :: cur_ice_stepno @@ -3721,6 +3754,8 @@ subroutine ice_import_moab(Eclock)!{{{ if (config_use_zaerosols) then call mpas_pool_get_array(biogeochemistry, "atmosBlackCarbonFlux", atmosBlackCarbonFlux) call mpas_pool_get_array(biogeochemistry, "atmosDustFlux", atmosDustFlux) + call mpas_pool_get_array(biogeochemistry, "atmosWetDustFlux", atmosWetDustFlux) + call mpas_pool_get_array(biogeochemistry, "atmosDryDustFlux", atmosDryDustFlux) endif endif @@ -3737,8 +3772,8 @@ subroutine ice_import_moab(Eclock)!{{{ seaSurfaceTiltV(i) = x2i_im(n,index_x2i_So_dhdy) if (trim(config_ocean_surface_type) == "free") then ! free surface (MPAS-O) - - ! freezingMeltingPotential(i) is the ocean energy associated with frazil formation + + ! freezingMeltingPotential(i) is the ocean energy associated with frazil formation ! when it is positive and frazilMassFlux is positive. Conversely, freezingMeltingPotential(i) ! is negative when there is the melting potential in which case frazilMassFlux is zero. @@ -3747,7 +3782,7 @@ subroutine ice_import_moab(Eclock)!{{{ frazilMassFlux = x2i_im(n,index_x2i_Fioo_frazil) ! Now determine the sea ice mass associated with the frazil heat flux given when - ! freezingMeltingPotential(i) is positive. This produces a revised mass flux, given + ! freezingMeltingPotential(i) is positive. This produces a revised mass flux, given ! in frazilMassFluxRev for the given sea surface salinity. The resulting difference ! is assigned to frazilMassAdjust(i) which is exported to the ocean in the subsequent ! coupling step as a freshwater and salt flux. This step is required to balance mass @@ -3755,7 +3790,7 @@ subroutine ice_import_moab(Eclock)!{{{ call frazil_mass(freezingMeltingPotential(i), frazilMassFluxRev, seaSurfaceSalinity(i)) - frazilMassAdjust(i) = frazilMassFlux-frazilMassFluxRev + frazilMassAdjust(i) = frazilMassFlux-frazilMassFluxRev else ! non-free surface (SOM) @@ -3850,6 +3885,18 @@ subroutine ice_import_moab(Eclock)!{{{ + x2i_im(n,index_x2i_Faxa_dstdry3) atmosDustFlux(4,i) = x2i_im(n,index_x2i_Faxa_dstwet4) & + x2i_im(n,index_x2i_Faxa_dstdry4) + + ! wet dust + atmosWetDustFlux(1,i) = x2i_im(n,index_x2i_Faxa_dstwet1) + atmosWetDustFlux(2,i) = x2i_im(n,index_x2i_Faxa_dstwet2) + atmosWetDustFlux(3,i) = x2i_im(n,index_x2i_Faxa_dstwet3) + atmosWetDustFlux(4,i) = x2i_im(n,index_x2i_Faxa_dstwet4) + + ! dry dust + atmosDryDustFlux(1,i) = x2i_im(n,index_x2i_Faxa_dstdry1) + atmosDryDustFlux(2,i) = x2i_im(n,index_x2i_Faxa_dstdry2) + atmosDryDustFlux(3,i) = x2i_im(n,index_x2i_Faxa_dstdry3) + atmosDryDustFlux(4,i) = x2i_im(n,index_x2i_Faxa_dstdry4) else atmosBlackCarbonFlux(1,i) = x2i_im(n,index_x2i_Faxa_bcphodry) atmosBlackCarbonFlux(2,i) = x2i_im(n,index_x2i_Faxa_bcphidry) & @@ -3863,12 +3910,24 @@ subroutine ice_import_moab(Eclock)!{{{ + x2i_im(n,index_x2i_Faxa_dstdry3) atmosDustFlux(4,i) = x2i_im(n,index_x2i_Faxa_dstwet4) & + x2i_im(n,index_x2i_Faxa_dstdry4) + + ! wet dust + atmosWetDustFlux(1,i) = x2i_im(n,index_x2i_Faxa_dstwet1) + atmosWetDustFlux(2,i) = x2i_im(n,index_x2i_Faxa_dstwet2) + atmosWetDustFlux(3,i) = x2i_im(n,index_x2i_Faxa_dstwet3) + atmosWetDustFlux(4,i) = x2i_im(n,index_x2i_Faxa_dstwet4) + + ! dry dust + atmosDryDustFlux(1,i) = x2i_im(n,index_x2i_Faxa_dstdry1) + atmosDryDustFlux(2,i) = x2i_im(n,index_x2i_Faxa_dstdry2) + atmosDryDustFlux(3,i) = x2i_im(n,index_x2i_Faxa_dstdry3) + atmosDryDustFlux(4,i) = x2i_im(n,index_x2i_Faxa_dstdry4) endif endif endif end do -!----------------------------------------------------------------------- +!----------------------------------------------------------------------- ! ! unit conversions and any manipulation of coupled fields ! @@ -3946,6 +4005,8 @@ subroutine ice_import_moab(Eclock)!{{{ if (config_use_zaerosols) then call mpas_pool_get_field(biogeochemistry, "atmosBlackCarbonFlux", atmosBlackCarbonFluxField) call mpas_pool_get_field(biogeochemistry, "atmosDustFlux", atmosDustFluxField) + call mpas_pool_get_field(biogeochemistry, "atmosWetDustFlux", atmosWetDustFluxField) + call mpas_pool_get_field(biogeochemistry, "atmosDryDustFlux", atmosDryDustFluxField) endif endif @@ -3995,6 +4056,8 @@ subroutine ice_import_moab(Eclock)!{{{ if (config_use_zaerosols) then call mpas_dmpar_exch_halo_field(atmosBlackCarbonFluxField) call mpas_dmpar_exch_halo_field(atmosDustFluxField) + call mpas_dmpar_exch_halo_field(atmosWetDustFluxField) + call mpas_dmpar_exch_halo_field(atmosDryDustFluxField) endif endif diff --git a/components/mpas-seaice/src/Registry.xml b/components/mpas-seaice/src/Registry.xml index 7a5d18c3dc5f..b4ffd634bd28 100644 --- a/components/mpas-seaice/src/Registry.xml +++ b/components/mpas-seaice/src/Registry.xml @@ -889,6 +889,14 @@ description="Aerosols in the ice use the z-aerosol scheme" possible_values="true or false" icepack_name="tr_zaero" + /> + + + + + + + + + + + + + + @@ -5278,7 +5328,21 @@ /> + + @@ -5330,7 +5394,7 @@ type="real" dimensions="nZBGCTracers nCategories nCells Time" units="mmol m-2 s-1" - description="Only bio tracers used in the order: diatom nitrogen, smallPlankton nitrogen, phaeocystis nitrogen, nitrate, polysaccarid carbon, lipid carbon, dissolved inorganic carbon,ammonium, silicate, DMSPp, DMSPd, DMS, Nonreactive nitrate, Protein nitrogen, dissolved iron in umol/m2/s, particulate iron in umol/m2/s, humic carbon, black carbon1 in mg/m2/s, black carbon2 in mg/m2/s, dust1 in mg/m2/s, dust2 in mg/m2/s, dust3 in mg/m2/s, dust4 in mg/m2/s" + description="Only bio tracers used in the order: diatom nitrogen, smallPlankton nitrogen, phaeocystis nitrogen, nitrate, polysaccarid carbon, lipid carbon, dissolved inorganic carbon,ammonium, silicate, DMSPp, DMSPd, DMS, Nonreactive nitrate, Protein nitrogen, dissolved iron in umol/m2/s, particulate iron in umol/m2/s, humic carbon, black carbon1 in kg/m2/s, black carbon2 in kg/m2/s, dust1 in kg/m2/s, dust2 in kg/m2/s, dust3 in kg/m2/s, dust4 in kg/m2/s" icepack_name="flux_bion" packages="pkgColumnBiogeochemistry;pkgColumnPackage" /> @@ -5518,104 +5582,104 @@ \brief +!> \author Nicole Jeffery, LANL +!> \date +!> \details: reads data file for dust fluxes and dust-iron solubility +!> +! +!----------------------------------------------------------------------- + + subroutine atmospheric_aerosols_forcing(& + streamManager, & + domain, & + simulationClock, & + firstTimeStep) + + type (MPAS_streamManager_type), intent(inout) :: streamManager + + type (domain_type) :: domain + + type (MPAS_clock_type) :: simulationClock + + logical, intent(in) :: & + firstTimeStep + + type (block_type), pointer :: block + + real(kind=RKIND), pointer :: & + config_dt + + ! configurations + call mpas_pool_get_config(domain % configs, 'config_dt', config_dt) + + call MPAS_forcing_get_forcing(seaiceForcingGroups, & + 'seaice_atm_bgc_forcing_monthly', streamManager, config_dt) + + block => domain % blocklist + do while (associated(block)) + + ! convert the input forcing variables to the coupling variables + call prepare_atmospheric_dust_coupling_variables(block) + + block => block % next + end do + + end subroutine atmospheric_aerosols_forcing + !||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||| ! ! prepare_atmospheric_coupling_variables_CORE @@ -1044,6 +1117,74 @@ subroutine prepare_atmospheric_coupling_variables_ISPOL(block) end subroutine prepare_atmospheric_coupling_variables_ISPOL +!||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||| +! +! prepare_atmospheric_dust_coupling_variables +! +!> \brief +!> \author Nicole Jeffery, LANL +!> \date +!> \details +!> Defines the atm flux fields for dust if reading from a file +! +!----------------------------------------------------------------------- + + subroutine prepare_atmospheric_dust_coupling_variables(block) + + type (block_type), pointer :: block + + type (mpas_pool_type), pointer :: & + mesh, & + atmosCoupling, & + atmosForcing, & + biogeochemistry + + real(kind=RKIND), dimension(:,:), pointer :: & + atmosDustFlux, & + atmosWetDustFlux, & + atmosDryDustFlux + + real(kind=RKIND), dimension(:), pointer :: & + dust_FLUZ_WET, & + dust_FLUZ_DRY + + integer, pointer :: & + nCellsSolve, & + maxBCType, & + nzAerosols + + integer :: & + iCell, & + iBioTracers, & + nDust + + call MPAS_pool_get_subpool(block % structs, "mesh", mesh) + call MPAS_pool_get_subpool(block % structs, "atmos_forcing", atmosForcing) + + call MPAS_pool_get_dimension(mesh, "nCellsSolve", nCellsSolve) + + ! zaerosols + + call MPAS_pool_get_subpool(block % structs, "biogeochemistry", biogeochemistry) + call MPAS_pool_get_dimension(mesh, "maxBCType", maxBCType) + call MPAS_pool_get_dimension(mesh, "nzAerosols", nzAerosols) + call MPAS_pool_get_array(biogeochemistry, "atmosDustFlux", atmosDustFlux) + call MPAS_pool_get_array(biogeochemistry, "atmosWetDustFlux", atmosWetDustFlux) + call MPAS_pool_get_array(biogeochemistry, "atmosDryDustFlux", atmosDryDustFlux) + call MPAS_pool_get_array(atmosForcing, "dust_FLUZ_WET", dust_FLUZ_WET) + call MPAS_pool_get_array(atmosForcing, "dust_FLUZ_DRY", dust_FLUZ_DRY) + + nDust = MAX(1,nzAerosols - maxBCType) + do iCell = 1, nCellsSolve + do iBioTracers = maxBCType + 1, nzAerosols + atmosDustFlux(iBioTracers,iCell) = (dust_FLUZ_WET(iCell) + dust_FLUZ_DRY(iCell))/nDust + atmosWetDustFlux(iBioTracers,iCell) = dust_FLUZ_WET(iCell)/nDust + atmosDryDustFlux(iBiotracers,iCell) = dust_FLUZ_DRY(iCell)/nDust + enddo + end do + + end subroutine prepare_atmospheric_dust_coupling_variables + !||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||| ! ! post_atmospheric_coupling @@ -1675,6 +1816,129 @@ subroutine init_oceanic_bgc_forcing(domain) end subroutine init_oceanic_bgc_forcing +!||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||| +! +! init_atm_iron_bgc_forcing +! +!> \brief +!> \author Nicole Jeffery, LANL +!> \date 5th April 2024 +!> \details +!> Uses monthly iron solubility maps from CAM6-MIMI (Yan Feng) +! to convert dust to dissolved iron for bgc. +!----------------------------------------------------------------------- + + subroutine init_atm_iron_bgc_forcing(domain, clock) + + type (domain_type) :: domain + + type (MPAS_Clock_type) :: clock + + logical, pointer :: & + config_do_restart + + character(len=strKIND) :: & + forcingIntervalMonthly, & + forcingReferenceTimeMonthly + + type (MPAS_Time_Type) :: currTime + character(len=strKIND) :: timeStamp + integer :: ierr + ! get forcing configuration options + call MPAS_pool_get_config(domain % configs, "config_do_restart", config_do_restart) + + ! create the dust iron solubility forcing group + + currTime = mpas_get_clock_time(clock, MPAS_NOW, ierr) + call mpas_get_time(curr_time=currTime, dateTimeString=timeStamp, ierr=ierr) + timeStamp = '0000'//trim(timeStamp(5:)) + + call MPAS_forcing_init_group(& + seaiceForcingGroups, & + "seaice_atm_bgc_forcing_monthly", & + domain, & + '0000-01-01_00:00:00', & + '0000-01-01_00:00:00', & + '0001-00-00_00:00:00', & + config_do_restart) + + forcingIntervalMonthly = "00-01-00_00:00:00" + forcingReferenceTimeMonthly = "0001-01-15_00:00:00" + + ! iron solubility fraction of wet dust iron + call MPAS_forcing_init_field(& + domain % streamManager, & + seaiceForcingGroups, & + 'seaice_atm_bgc_forcing_monthly', & + 'IRON_Zolubility_wet', & + 'DustIronMonthlyForcing', & + 'atmos_forcing', & + 'IRON_Zolubility_wet', & + 'linear', & + forcingReferenceTimeMonthly, & + forcingIntervalMonthly) + + ! iron solubility fraction of dry dust iron + call MPAS_forcing_init_field(& + domain % streamManager, & + seaiceForcingGroups, & + 'seaice_atm_bgc_forcing_monthly', & + 'IRON_Zolubility_dry', & + 'DustIronMonthlyForcing', & + 'atmos_forcing', & + 'IRON_Zolubility_dry', & + 'linear', & + forcingReferenceTimeMonthly, & + forcingIntervalMonthly) + + ! atmospheric wet dust flux + call MPAS_forcing_init_field(& + domain % streamManager, & + seaiceForcingGroups, & + 'seaice_atm_bgc_forcing_monthly', & + 'dust_FLUZ_WET', & + 'DustIronMonthlyForcing', & + 'atmos_forcing', & + 'dust_FLUZ_WET', & + 'linear', & + forcingReferenceTimeMonthly, & + forcingIntervalMonthly) + + ! atmospheric dry dust flux + call MPAS_forcing_init_field(& + domain % streamManager, & + seaiceForcingGroups, & + 'seaice_atm_bgc_forcing_monthly', & + 'dust_FLUZ_DRY', & + 'DustIronMonthlyForcing', & + 'atmos_forcing', & + 'dust_FLUZ_DRY', & + 'linear', & + forcingReferenceTimeMonthly, & + forcingIntervalMonthly) + + ! iron fraction in dust + call MPAS_forcing_init_field(& + domain % streamManager, & + seaiceForcingGroups, & + 'seaice_atm_bgc_forcing_monthly', & + 'IRON_in_duzt_fraction', & + 'DustIronMonthlyForcing', & + 'atmos_forcing', & + 'IRON_in_duzt_fraction', & + 'linear', & + forcingReferenceTimeMonthly, & + forcingIntervalMonthly) + + call MPAS_forcing_init_field_data(& + seaiceForcingGroups, & + 'seaice_atm_bgc_forcing_monthly', & + domain % streamManager, & + config_do_restart, & + .false.) + + end subroutine init_atm_iron_bgc_forcing + !||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||| ! ! init_oceanic_forcing_ncar @@ -3177,10 +3441,12 @@ subroutine reset_atmospheric_coupler_fluxes(domain) real(kind=RKIND), dimension(:,:), pointer :: & atmosBioFluxes, & atmosBlackCarbonFlux, & - atmosDustFlux + atmosDustFlux, & + atmosWetDustFlux, & + atmosDryDustFlux logical, pointer :: & - config_use_column_biogeochemistry + config_use_zaerosols block => domain % blocklist do while (associated(block)) @@ -3219,20 +3485,24 @@ subroutine reset_atmospheric_coupler_fluxes(domain) atmosReferenceTemperature2m = 0.0_RKIND atmosReferenceHumidity2m = 0.0_RKIND - ! biogeochemistry - call MPAS_pool_get_config(block % configs, "config_use_column_biogeochemistry", config_use_column_biogeochemistry) + ! zaerosols + call MPAS_pool_get_config(block % configs, "config_use_zaerosols", config_use_zaerosols) - if (config_use_column_biogeochemistry) then + if (config_use_zaerosols) then call MPAS_pool_get_subpool(block % structs, "biogeochemistry", biogeochemistry) call MPAS_pool_get_array(biogeochemistry, "atmosBioFluxes", atmosBioFluxes) call MPAS_pool_get_array(biogeochemistry, "atmosBlackCarbonFlux", atmosBlackCarbonFlux) call MPAS_pool_get_array(biogeochemistry, "atmosDustFlux", atmosDustFlux) + call MPAS_pool_get_array(biogeochemistry, "atmosWetDustFlux", atmosWetDustFlux) + call MPAS_pool_get_array(biogeochemistry, "atmosDryDustFlux", atmosDryDustFlux) atmosBioFluxes = 0.0_RKIND atmosBlackCarbonFlux = 0.0_RKIND atmosDustFlux = 0.0_RKIND + atmosWetDustFlux = 0.0_RKIND + atmosDryDustFlux = 0.0_RKIND endif @@ -3396,16 +3666,21 @@ subroutine seaice_forcing_write_restart_times(domain) config_use_forcing, & config_use_prescribed_ice, & config_use_prescribed_ice_forcing, & - config_use_data_icebergs + config_use_data_icebergs, & + config_use_atm_dust_file, & + config_use_iron_solubility_file call MPAS_pool_get_config(domain % configs, "config_use_forcing", config_use_forcing) call MPAS_pool_get_config(domain % configs, "config_use_prescribed_ice", config_use_prescribed_ice) call MPAS_pool_get_config(domain % configs, "config_use_prescribed_ice_forcing", config_use_prescribed_ice_forcing) call MPAS_pool_get_config(domain % configs, "config_use_data_icebergs", config_use_data_icebergs) + call MPAS_pool_get_config(domain % configs, "config_use_atm_dust_file", config_use_atm_dust_file) + call MPAS_pool_get_config(domain % configs, "config_use_iron_solubility_file", config_use_iron_solubility_file) if (config_use_forcing .or. & (config_use_prescribed_ice .and. config_use_prescribed_ice_forcing) .or. & - config_use_data_icebergs) then + config_use_data_icebergs .or. & + config_use_atm_dust_file .or. config_use_iron_solubility_file) then call MPAS_forcing_write_restart_times(seaiceForcingGroups) diff --git a/components/mpas-seaice/src/shared/mpas_seaice_icepack.F b/components/mpas-seaice/src/shared/mpas_seaice_icepack.F index 6c787048ad1d..f32d8e1d1dd8 100644 --- a/components/mpas-seaice/src/shared/mpas_seaice_icepack.F +++ b/components/mpas-seaice/src/shared/mpas_seaice_icepack.F @@ -3487,7 +3487,9 @@ subroutine column_biogeochemistry(domain) icepack_warnings_clear use seaice_constants, only: & - seaicePuny + seaicePuny, & + kilogramsToMicrograms, & + gramsIronPerMolIron type(domain_type), intent(inout) :: domain @@ -3503,6 +3505,7 @@ subroutine column_biogeochemistry(domain) melt_growth_rates, & ocean_coupling, & atmos_coupling, & + atmos_forcing, & initial ! configs @@ -3514,7 +3517,9 @@ subroutine column_biogeochemistry(domain) config_use_skeletal_biochemistry, & config_use_column_biogeochemistry, & config_use_zaerosols, & - config_use_vertical_tracers + config_use_vertical_tracers, & + config_use_atm_dust_file, & + config_use_iron_solubility_file ! dimensions integer, pointer :: & @@ -3554,7 +3559,10 @@ subroutine column_biogeochemistry(domain) oceanDMSPConc, & oceanHumicsConc, & openWaterArea, & - totalChlorophyll + totalChlorophyll, & + IRON_Zolubility_wet, & + IRON_Zolubility_dry, & + IRON_in_duzt_fraction real(kind=RKIND), dimension(:,:), pointer :: & iceAreaCategoryInitial, & @@ -3581,6 +3589,8 @@ subroutine column_biogeochemistry(domain) atmosBioFluxes, & atmosBlackCarbonFlux, & atmosDustFlux, & + atmosWetDustFlux, & + atmosDryDustFlux, & oceanBioFluxes, & oceanAlgaeConc, & oceanDOCConc, & @@ -3681,6 +3691,7 @@ subroutine column_biogeochemistry(domain) call MPAS_pool_get_subpool(block % structs, "diagnostics_biogeochemistry", diagnostics_biogeochemistry) call MPAS_pool_get_subpool(block % structs, "shortwave", shortwave) call MPAS_pool_get_subpool(block % structs, "atmos_coupling", atmos_coupling) + call MPAS_pool_get_subpool(block % structs, "atmos_forcing", atmos_forcing) call MPAS_pool_get_subpool(block % structs, "melt_growth_rates", melt_growth_rates) call MPAS_pool_get_subpool(block % structs, "ocean_coupling", ocean_coupling) call MPAS_pool_get_subpool(block % structs, "initial", initial) @@ -3704,6 +3715,8 @@ subroutine column_biogeochemistry(domain) call MPAS_pool_get_config(block % configs, "config_use_column_biogeochemistry", config_use_column_biogeochemistry) call MPAS_pool_get_config(block % configs, "config_use_zaerosols",config_use_zaerosols) call MPAS_pool_get_config(block % configs, "config_use_vertical_tracers",config_use_vertical_tracers) + call MPAS_pool_get_config(block % configs, "config_use_atm_dust_file", config_use_atm_dust_file) + call MPAS_pool_get_config(block % configs, "config_use_iron_solubility_file", config_use_iron_solubility_file) call MPAS_pool_get_array(biogeochemistry, "newlyFormedIce", newlyFormedIce) call MPAS_pool_get_array(biogeochemistry, "netNitrateUptake", netNitrateUptake) @@ -3734,6 +3747,8 @@ subroutine column_biogeochemistry(domain) call MPAS_pool_get_array(biogeochemistry, "atmosBioFluxes", atmosBioFluxes) call MPAS_pool_get_array(biogeochemistry, "atmosBlackCarbonFlux", atmosBlackCarbonFlux) call MPAS_pool_get_array(biogeochemistry, "atmosDustFlux", atmosDustFlux) + call MPAS_pool_get_array(biogeochemistry, "atmosWetDustFlux", atmosWetDustFlux) + call MPAS_pool_get_array(biogeochemistry, "atmosDryDustFlux", atmosDryDustFlux) call MPAS_pool_get_array(biogeochemistry, "oceanBioFluxes", oceanBioFluxes) call MPAS_pool_get_array(biogeochemistry, "oceanBioFluxesCategory", oceanBioFluxesCategory) call MPAS_pool_get_array(biogeochemistry, "verticalNitrogenLosses", verticalNitrogenLosses) @@ -3763,6 +3778,10 @@ subroutine column_biogeochemistry(domain) call MPAS_pool_get_array(atmos_coupling, "snowfallRate", snowfallRate) + call MPAS_pool_get_array(atmos_forcing, "IRON_Zolubility_wet", IRON_Zolubility_wet) + call MPAS_pool_get_array(atmos_forcing, "IRON_Zolubility_dry", IRON_Zolubility_dry) + call MPAS_pool_get_array(atmos_forcing, "IRON_in_duzt_fraction", IRON_in_duzt_fraction) + call MPAS_pool_get_array(icestate, "iceAreaCategoryInitial", iceAreaCategoryInitial) call MPAS_pool_get_array(icestate, "iceVolumeCategoryInitial", iceVolumeCategoryInitial) call MPAS_pool_get_array(icestate, "snowVolumeCategoryInitial", snowVolumeCategoryInitial) @@ -3863,9 +3882,13 @@ subroutine column_biogeochemistry(domain) do iBioTracers = 1, maxBCType atmosBlackCarbonFlux(iBioTracers,iCell) = 1.e-12_RKIND enddo - do iBioTracers = 1, maxDustType - atmosDustFlux(iBioTracers,iCell) = 1.e-13_RKIND - enddo + if (.not. config_use_atm_dust_file) then + do iBioTracers = 1, maxDustType + atmosDustFlux(iBioTracers,iCell) = 1.e-13_RKIND + atmosWetDustFlux(iBioTracers,iCell) = 1.e-13_RKIND * 0.5_RKIND + atmosDryDustFlux(iBioTracers,iCell) = 1.e-13_RKIND * 0.5_RKIND + enddo + endif #endif if (config_use_zaerosols) then indexj = ciceTracerObject % index_verticalAerosolsConcLayer(1) @@ -3875,6 +3898,16 @@ subroutine column_biogeochemistry(domain) do iBioTracers = maxBCType + 1, nzAerosols atmosBioFluxes(indexj -1 + iBioTracers, iCell) = atmosDustFlux(iBioTracers-maxBCType,iCell) enddo + indexj = ciceTracerObject % index_dissolvedIronConcLayer(1) + if (config_use_iron_solubility_file) then + atmosBioFluxes(indexj,iCell) = 0.0_RKIND + do iBioTracers = maxBCType + 1, nzAerosols + atmosBioFluxes(indexj,iCell) = atmosBioFluxes(indexj,iCell) + & + (atmosWetDustFlux(iBioTracers-maxBCType,iCell) * IRON_Zolubility_wet(iCell) + & + atmosDryDustFlux(iBioTracers-maxBCType,iCell) * IRON_Zolubility_dry(iCell) ) * & + IRON_in_duzt_fraction(iCell) * kilogramsToMicrograms * gramsIronPerMolIron + end do + end if endif do iBioTracers = 1, ciceTracerObject % nBioTracers @@ -10028,7 +10061,8 @@ subroutine init_icepack_package_configs(domain) config_do_restart_bgc, & config_use_snow_liquid_ponds, & config_use_snow_grain_radius, & - config_use_shortwave_redistribution + config_use_shortwave_redistribution, & + config_use_iron_solubility_file real(kind=RKIND), pointer :: & config_min_friction_velocity, & @@ -10293,6 +10327,7 @@ subroutine init_icepack_package_configs(domain) call MPAS_pool_get_config(domain % configs, "config_use_shortwave_bioabsorption", config_use_shortwave_bioabsorption) call MPAS_pool_get_config(domain % configs, "config_use_modal_aerosols", config_use_modal_aerosols) call MPAS_pool_get_config(domain % configs, "config_use_macromolecules", config_use_macromolecules) + call MPAS_pool_get_config(domain % configs, "config_use_iron_solubility_file", config_use_iron_solubility_file) call MPAS_pool_get_config(domain % configs, "config_do_restart_bgc", config_do_restart_bgc) call MPAS_pool_get_config(domain % configs, "config_use_skeletal_biochemistry", config_use_skeletal_biochemistry) call MPAS_pool_get_config(domain % configs, "config_biogrid_bottom_molecular_sublayer", & @@ -10754,6 +10789,7 @@ subroutine init_icepack_package_configs(domain) algal_vel_in = config_algal_maximum_velocity, & R_dFe2dust_in = config_ratio_Fe_to_dust, & dustFe_sol_in = config_solubility_of_Fe_in_dust, & + use_atm_dust_iron_in = .not.config_use_iron_solubility_file, & !chlabs_diatoms_in = config_chla_absorptivity_of_diatoms, & !chlabs_sp_in = config_chla_absorptivity_of_small_plankton, & !chlabs_phaeo_in = config_chla_absorptivity_of_phaeocystis, & @@ -11369,6 +11405,10 @@ subroutine init_icepack_package_configs(domain) ! solubility fraction ! dustFe_sol = config_solubility_of_Fe_in_dust + ! use_atm_dust_sol; + ! compute dust iron contribution in icepack + ! use_atm_dust_sol = .not.config_use_iron_solubility_file + ! chlabs_diatoms: ! chl absorption (1/m/(mg/m^3)) ! chlabs_diatoms = config_chla_absorptivity_of_diatoms From 8659988a4f6dd3abc95da8f9a0789b34cc2ca3bc Mon Sep 17 00:00:00 2001 From: Nicole Jeffery Date: Fri, 24 May 2024 15:56:59 -0500 Subject: [PATCH 151/451] Adds the sea ice-ocean dust flux field for coupling This field oceanDustIronFlux will be used by the ocean for dust-iron consistency across the coupled system Also corrects a bug in the calculation of iron from dust introduced in the last commit Works with E3SM-Project/Icepack.git origin/fixes-to-zaerosols-take3 BFB with zaerosols off --- components/mpas-seaice/driver/ice_comp_mct.F | 99 +++++++++++-------- .../src/shared/mpas_seaice_icepack.F | 2 +- 2 files changed, 60 insertions(+), 41 deletions(-) diff --git a/components/mpas-seaice/driver/ice_comp_mct.F b/components/mpas-seaice/driver/ice_comp_mct.F index 5c1bc715518e..50bf12ece375 100644 --- a/components/mpas-seaice/driver/ice_comp_mct.F +++ b/components/mpas-seaice/driver/ice_comp_mct.F @@ -2516,6 +2516,7 @@ subroutine ice_export_mct(i2x_i, errorCode) !{{{ config_rotate_cartesian_grid, & config_use_topo_meltponds, & config_use_column_biogeochemistry, & + config_use_zaerosols, & config_couple_biogeochemistry_fields, & config_use_column_shortwave, & config_use_data_icebergs @@ -2566,6 +2567,7 @@ subroutine ice_export_mct(i2x_i, errorCode) !{{{ oceanDMSPpFlux, & oceanDMSPdFlux, & oceanHumicsFlux, & + oceanDustIronFlux, & carbonToNitrogenRatioAlgae, & carbonToNitrogenRatioDON @@ -2588,6 +2590,7 @@ subroutine ice_export_mct(i2x_i, errorCode) !{{{ configs => block_ptr % configs call MPAS_pool_get_config(configs, "config_rotate_cartesian_grid", config_rotate_cartesian_grid) call MPAS_pool_get_config(configs, "config_use_topo_meltponds", config_use_topo_meltponds) + call MPAS_pool_get_config(configs, "config_use_zaerosols", config_use_zaerosols) call MPAS_pool_get_config(configs, "config_use_column_biogeochemistry", config_use_column_biogeochemistry) call mpas_pool_get_config(configs, "config_couple_biogeochemistry_fields", config_couple_biogeochemistry_fields) call MPAS_pool_get_config(configs, "config_use_column_shortwave", config_use_column_shortwave) @@ -2672,6 +2675,9 @@ subroutine ice_export_mct(i2x_i, errorCode) !{{{ call mpas_pool_get_array(biogeochemistry, 'carbonToNitrogenRatioDON', carbonToNitrogenRatioDON) endif + if (config_use_zaerosols .and. config_couple_biogeochemistry_fields) & + call mpas_pool_get_array(biogeochemistry, 'oceanDustIronFlux', oceanDustIronFlux) + do i = 1, nCellsSolve n = n + 1 @@ -2796,6 +2802,9 @@ subroutine ice_export_mct(i2x_i, errorCode) !{{{ i2x_i % rAttr(index_i2x_Fioi_fed1 ,n) = oceanDissolvedIronFlux(1,i) / 1000._RKIND i2x_i % rAttr(index_i2x_Fioi_fed2 ,n) = oceanDissolvedIronFlux(2,i) / 1000._RKIND endif + ! export dust, if configured kg/m2/s of dust + if (config_use_zaerosols .and. config_couple_biogeochemistry_fields) & + i2x_i % rAttr(index_i2x_Fioi_dust1 ,n) = oceanDustIronFlux(i) endif enddo @@ -3124,8 +3133,10 @@ subroutine ice_export_moab(EClock) config_rotate_cartesian_grid, & config_use_topo_meltponds, & config_use_column_biogeochemistry, & + config_use_zaerosols, & config_use_column_shortwave, & - config_use_data_icebergs + config_use_data_icebergs, & + config_couple_biogeochemistry_fields real(kind=RKIND), pointer :: & sphere_radius @@ -3173,6 +3184,7 @@ subroutine ice_export_moab(EClock) oceanDMSPpFlux, & oceanDMSPdFlux, & oceanHumicsFlux, & + oceanDustIronFlux, & carbonToNitrogenRatioAlgae, & carbonToNitrogenRatioDON @@ -3186,23 +3198,25 @@ subroutine ice_export_moab(EClock) integer :: ent_type, ierr, cur_ice_stepno character(len=32), parameter :: sub = 'ice_export_moab' - + character(len=100) :: outfile, wopts, localmeshfile, lnum character(CXX) :: tagname - !----------------------------------------------------------------------- + !----------------------------------------------------------------------- call shr_file_setLogUnit (iceLogUnit) n = 0 i2x_im(: ,:) = 0.0_RKIND block_ptr => domain % blocklist do while(associated(block_ptr)) - + configs => block_ptr % configs call MPAS_pool_get_config(configs, "config_rotate_cartesian_grid", config_rotate_cartesian_grid) call MPAS_pool_get_config(configs, "config_use_topo_meltponds", config_use_topo_meltponds) + call MPAS_pool_get_config(configs, "config_use_zaerosols", config_use_zaerosols) call MPAS_pool_get_config(configs, "config_use_column_biogeochemistry", config_use_column_biogeochemistry) + call mpas_pool_get_config(configs, "config_couple_biogeochemistry_fields", config_couple_biogeochemistry_fields) call MPAS_pool_get_config(configs, "config_use_column_shortwave", config_use_column_shortwave) call MPAS_pool_get_config(configs, "config_use_data_icebergs", config_use_data_icebergs) - + call MPAS_pool_get_subpool(block_ptr % structs, 'mesh', meshPool) call MPAS_pool_get_subpool(block_ptr % structs, "tracers_aggregate", tracersAggregate) call MPAS_pool_get_subpool(block_ptr % structs, "velocity_solver", velocitySolver) @@ -3211,7 +3225,7 @@ subroutine ice_export_moab(EClock) call MPAS_pool_get_subpool(block_ptr % structs, 'ocean_coupling', oceanCoupling) call MPAS_pool_get_subpool(block_ptr % structs, "atmos_fluxes", atmosFluxes) call MPAS_pool_get_subpool(block_ptr % structs, "ocean_fluxes", oceanFluxes) - + call MPAS_pool_get_dimension(meshPool, 'nCellsSolve', nCellsSolve) call MPAS_pool_get_config(meshPool, "sphere_radius", sphere_radius) call MPAS_pool_get_array(meshPool, "latCell", latCell) @@ -3219,7 +3233,7 @@ subroutine ice_export_moab(EClock) call MPAS_pool_get_array(meshPool, "xCell", xCell) call MPAS_pool_get_array(meshPool, "yCell", yCell) call MPAS_pool_get_array(meshPool, "zCell", zCell) - + call MPAS_pool_get_array(tracersAggregate, 'iceAreaCell', iceAreaCell) call MPAS_pool_get_array(tracersAggregate, 'iceVolumeCell', iceVolumeCell) call MPAS_pool_get_array(tracersAggregate, 'snowVolumeCell', snowVolumeCell) @@ -3227,44 +3241,44 @@ subroutine ice_export_moab(EClock) call MPAS_pool_get_array(tracersAggregate, 'pondLidThicknessCell', pondLidThicknessCell) call MPAS_pool_get_array(tracersAggregate, 'pondAreaCell', pondAreaCell) call MPAS_pool_get_array(tracersAggregate, 'surfaceTemperatureCell', surfaceTemperatureCell) - + call MPAS_pool_get_array(velocitySolver, 'airStressCellU', airStressCellU) call MPAS_pool_get_array(velocitySolver, 'airStressCellV', airStressCellV) call MPAS_pool_get_array(velocitySolver, 'oceanStressCellU', oceanStressCellU) call MPAS_pool_get_array(velocitySolver, 'oceanStressCellV', oceanStressCellV) - + call MPAS_pool_get_array(shortwave, 'albedoVisibleDirectCell', albedoVisibleDirectCell) call MPAS_pool_get_array(shortwave, 'albedoIRDirectCell', albedoIRDirectCell) call MPAS_pool_get_array(shortwave, 'albedoVisibleDiffuseCell', albedoVisibleDiffuseCell) call MPAS_pool_get_array(shortwave, 'albedoIRDiffuseCell', albedoIRDiffuseCell) call MPAS_pool_get_array(shortwave, 'absorbedShortwaveFlux', absorbedShortwaveFlux) - + call MPAS_pool_get_array(atmosCoupling, 'atmosReferenceSpeed10m', atmosReferenceSpeed10m) call MPAS_pool_get_array(atmosCoupling, 'atmosReferenceTemperature2m', atmosReferenceTemperature2m) call MPAS_pool_get_array(atmosCoupling, 'atmosReferenceHumidity2m', atmosReferenceHumidity2m) - + call MPAS_pool_get_array(oceanCoupling, 'frazilMassAdjust', frazilMassAdjust) - + call MPAS_pool_get_array(atmosFluxes, 'latentHeatFlux', latentHeatFlux) call MPAS_pool_get_array(atmosFluxes, 'sensibleHeatFlux', sensibleHeatFlux) call MPAS_pool_get_array(atmosFluxes, 'longwaveUp', longwaveUp) call MPAS_pool_get_array(atmosFluxes, 'evaporativeWaterFlux', evaporativeWaterFlux) - + call MPAS_pool_get_array(oceanFluxes, 'oceanHeatFlux', oceanHeatFlux) call MPAS_pool_get_array(oceanFluxes, 'oceanShortwaveFlux', oceanShortwaveFlux) call MPAS_pool_get_array(oceanFluxes, 'oceanFreshWaterFlux', oceanFreshWaterFlux) call MPAS_pool_get_array(oceanFluxes, 'oceanSaltFlux', oceanSaltFlux) - + if (config_use_data_icebergs) then call MPAS_pool_get_subpool(block_ptr % structs, "berg_fluxes", icebergFluxes) - + call MPAS_pool_get_array(icebergFluxes, "bergFreshwaterFlux", bergFreshwaterFlux) call MPAS_pool_get_array(icebergFluxes, "bergLatentHeatFlux", bergLatentHeatFlux) endif - - if (config_use_column_biogeochemistry) then + + if (config_use_column_biogeochemistry .and. config_couple_biogeochemistry_fields) then call mpas_pool_get_subpool(block_ptr % structs, 'biogeochemistry', biogeochemistry) - + call mpas_pool_get_array(biogeochemistry, 'oceanAlgaeFlux', oceanAlgaeFlux) call mpas_pool_get_array(biogeochemistry, 'oceanDOCFlux', oceanDOCFlux) call mpas_pool_get_array(biogeochemistry, 'oceanDICFlux', oceanDICFlux) @@ -3281,18 +3295,20 @@ subroutine ice_export_moab(EClock) call mpas_pool_get_array(biogeochemistry, 'carbonToNitrogenRatioAlgae', carbonToNitrogenRatioAlgae) call mpas_pool_get_array(biogeochemistry, 'carbonToNitrogenRatioDON', carbonToNitrogenRatioDON) endif - + if (config_use_zaerosols .and. config_couple_biogeochemistry_fields) & + call mpas_pool_get_array(biogeochemistry, 'oceanDustIronFlux', oceanDustIronFlux) + do i = 1, nCellsSolve n = n + 1 - + ! ice fraction ailohi = min(iceAreaCell(i), 1.0_RKIND) - + !TODO: CICE has a check for ailohi < 0 - + ! surface temperature Tsrf = seaiceFreshWaterFreezingPoint + surfaceTemperatureCell(i) - + ! basal pressure if ( ailohi > 0.0_RKIND ) then call basal_pressure(& @@ -3304,7 +3320,7 @@ subroutine ice_export_moab(EClock) pondAreaCell(i), & config_use_topo_meltponds) endif - + ! wind stress (on T-grid: convert to lat-lon) call seaice_latlon_vector_rotation_backward(& tauxa, & @@ -3318,7 +3334,7 @@ subroutine ice_export_moab(EClock) zCell(i), & sphere_radius, & config_rotate_cartesian_grid) - + ! ice/ocean stress (on POP T-grid: convert to lat-lon) call seaice_latlon_vector_rotation_backward(& tauxo, & @@ -3332,25 +3348,25 @@ subroutine ice_export_moab(EClock) zCell(i), & sphere_radius, & config_rotate_cartesian_grid) - - !-------states-------------------- + + !-------states-------------------- i2x_im(n, index_i2x_Si_ifrac) = ailohi - + if (config_use_data_icebergs) then i2x_im(n, index_i2x_Fioi_bergw) = bergFreshwaterFlux(i) i2x_im(n, index_i2x_Fioi_bergh) = bergLatentHeatFlux(i) endif - + if ( ailohi > 0.0_RKIND ) then - - !-------states-------------------- + + !-------states-------------------- i2x_im(n, index_i2x_Si_t) = Tsrf i2x_im(n, index_i2x_Si_bpress) = basalPressure i2x_im(n, index_i2x_Si_u10) = atmosReferenceSpeed10m(i) i2x_im(n, index_i2x_Si_tref) = atmosReferenceTemperature2m(i) i2x_im(n, index_i2x_Si_qref) = atmosReferenceHumidity2m(i) i2x_im(n, index_i2x_Si_snowh) = snowVolumeCell(i) / ailohi - + !--- a/i fluxes computed by ice i2x_im(n, index_i2x_Faii_taux) = tauxa i2x_im(n, index_i2x_Faii_tauy) = tauya @@ -3360,17 +3376,17 @@ subroutine ice_export_moab(EClock) i2x_im(n, index_i2x_Faii_evap) = evaporativeWaterFlux(i) i2x_im(n, index_i2x_Faii_swnet) = absorbedShortwaveFlux(i) i2x_im(n, index_i2x_Faii_evap) = evaporativeWaterFlux(i) - + if (config_use_column_shortwave) then i2x_im(n, index_i2x_Si_avsdr) = albedoVisibleDirectCell(i) i2x_im(n, index_i2x_Si_anidr) = albedoIRDirectCell(i) i2x_im(n, index_i2x_Si_avsdf) = albedoVisibleDiffuseCell(i) i2x_im(n, index_i2x_Si_anidf) = albedoIRDiffuseCell(i) - + i2x_im(n, index_i2x_Faii_swnet) = absorbedShortwaveFlux(i) endif - - ! i/o fluxes computed by ice, as well as additional freshwater and salt calculated at the last + + ! i/o fluxes computed by ice, as well as additional freshwater and salt calculated at the last ! coupling import and needed to grow sea ice from frazil passed from the ocean model in the ! field frazilMassAdjust. i2x_im(n, index_i2x_Fioi_melth) = oceanHeatFlux(i) @@ -3379,9 +3395,9 @@ subroutine ice_export_moab(EClock) i2x_im(n, index_i2x_Fioi_salt ) = oceanSaltFlux(i) + seaiceReferenceSalinity*0.001_RKIND*frazilMassAdjust(i)/ailohi i2x_im(n, index_i2x_Fioi_taux ) = tauxo i2x_im(n, index_i2x_Fioi_tauy ) = tauyo - + ! export biogeochemistry fields, if configured - if (config_use_column_biogeochemistry) then + if (config_use_column_biogeochemistry .and. config_couple_biogeochemistry_fields) then ! convert from mmol N/m^3 to mmol C/m^3 i2x_im(n, index_i2x_Fioi_algae1) = oceanAlgaeFlux(1,i) * carbonToNitrogenRatioAlgae(1) i2x_im(n, index_i2x_Fioi_algae2) = oceanAlgaeFlux(2,i) * carbonToNitrogenRatioAlgae(2) @@ -3404,9 +3420,12 @@ subroutine ice_export_moab(EClock) i2x_im(n, index_i2x_Fioi_fed1 ) = oceanDissolvedIronFlux(1,i) / 1000._RKIND i2x_im(n, index_i2x_Fioi_fed2 ) = oceanDissolvedIronFlux(2,i) / 1000._RKIND endif + ! export dust, kg/m2/s + if (config_use_zaerosols .and. config_couple_biogeochemistry_fields) & + i2x_im(n, index_i2x_Fioi_dust1 ) = oceanDustIronFlux(i) endif enddo - + block_ptr => block_ptr % next enddo @@ -3417,7 +3436,7 @@ subroutine ice_export_moab(EClock) if ( ierr /= 0 ) then write(iceLogUnit,*) 'Fail to set MOAB fields ' endif - + call seq_timemgr_EClockGetData( EClock, stepno=cur_ice_stepno ) #ifdef MOABDEBUG write(lnum,"(I0.2)")cur_ice_stepno diff --git a/components/mpas-seaice/src/shared/mpas_seaice_icepack.F b/components/mpas-seaice/src/shared/mpas_seaice_icepack.F index f32d8e1d1dd8..adee0c072b42 100644 --- a/components/mpas-seaice/src/shared/mpas_seaice_icepack.F +++ b/components/mpas-seaice/src/shared/mpas_seaice_icepack.F @@ -3905,7 +3905,7 @@ subroutine column_biogeochemistry(domain) atmosBioFluxes(indexj,iCell) = atmosBioFluxes(indexj,iCell) + & (atmosWetDustFlux(iBioTracers-maxBCType,iCell) * IRON_Zolubility_wet(iCell) + & atmosDryDustFlux(iBioTracers-maxBCType,iCell) * IRON_Zolubility_dry(iCell) ) * & - IRON_in_duzt_fraction(iCell) * kilogramsToMicrograms * gramsIronPerMolIron + IRON_in_duzt_fraction(iCell) * kilogramsToMicrograms / gramsIronPerMolIron end do end if endif From 9535815fa5419e726d90c0fe1c7af27ce789ec4a Mon Sep 17 00:00:00 2001 From: Nicole Jeffery Date: Mon, 27 May 2024 15:20:59 -0500 Subject: [PATCH 152/451] Move bgc indexing definitions to the interface -adds subroutine in the icepack interface, init_zbgc_tracer_indices, to replace icepack_init_zbgc_tracer_indices. -moves icepack_init_bgc_trcr from icepack to init_bgc_tracer_indices in mpas_seaice_icepack Tested in GCASE with ice-ocean bgc and aerosols active works with njeffery/Icepack.git branch: fixes-to-bgc-indices --- components/mpas-seaice/cime_config/buildnml | 2 +- .../src/shared/mpas_seaice_forcing.F | 7 - .../src/shared/mpas_seaice_icepack.F | 935 ++++++++++++++++-- 3 files changed, 853 insertions(+), 91 deletions(-) diff --git a/components/mpas-seaice/cime_config/buildnml b/components/mpas-seaice/cime_config/buildnml index 5aa44cf06b9b..c79de6314b06 100755 --- a/components/mpas-seaice/cime_config/buildnml +++ b/components/mpas-seaice/cime_config/buildnml @@ -594,7 +594,7 @@ def buildnml(case, caseroot, compname): lines.append('') lines.append('') diff --git a/components/mpas-seaice/src/shared/mpas_seaice_forcing.F b/components/mpas-seaice/src/shared/mpas_seaice_forcing.F index 5fba5fa7d5ec..ca0c4c5a962f 100644 --- a/components/mpas-seaice/src/shared/mpas_seaice_forcing.F +++ b/components/mpas-seaice/src/shared/mpas_seaice_forcing.F @@ -1841,18 +1841,11 @@ subroutine init_atm_iron_bgc_forcing(domain, clock) forcingIntervalMonthly, & forcingReferenceTimeMonthly - type (MPAS_Time_Type) :: currTime - character(len=strKIND) :: timeStamp - integer :: ierr ! get forcing configuration options call MPAS_pool_get_config(domain % configs, "config_do_restart", config_do_restart) ! create the dust iron solubility forcing group - currTime = mpas_get_clock_time(clock, MPAS_NOW, ierr) - call mpas_get_time(curr_time=currTime, dateTimeString=timeStamp, ierr=ierr) - timeStamp = '0000'//trim(timeStamp(5:)) - call MPAS_forcing_init_group(& seaiceForcingGroups, & "seaice_atm_bgc_forcing_monthly", & diff --git a/components/mpas-seaice/src/shared/mpas_seaice_icepack.F b/components/mpas-seaice/src/shared/mpas_seaice_icepack.F index adee0c072b42..fd49a8c383a9 100644 --- a/components/mpas-seaice/src/shared/mpas_seaice_icepack.F +++ b/components/mpas-seaice/src/shared/mpas_seaice_icepack.F @@ -12948,7 +12948,6 @@ end subroutine seaice_column_reinitialize_oceanic_fluxes subroutine init_column_tracer_object_for_biogeochemistry(domain, tracerObject) use icepack_intfc, only: icepack_init_zbgc - use icepack_intfc, only: icepack_init_zbgc_tracer_indices use icepack_intfc, only: icepack_init_parameters use icepack_intfc, only: icepack_query_parameters @@ -13089,6 +13088,7 @@ subroutine init_column_tracer_object_for_biogeochemistry(domain, tracerObject) nParticulateIron, & nDissolvedIron, & nzAerosols, & + nZBGCTracers, & maxAerosolType, & maxAlgaeType, & maxDOCType, & @@ -13106,6 +13106,12 @@ subroutine init_column_tracer_object_for_biogeochemistry(domain, tracerObject) real(kind=RKIND) :: & rtmp1, & rtmp2 + real (kind=RKIND), dimension (:), allocatable :: & + BGCTracerType, & + initialMobileFraction, & + retentionTime, & + releaseTime, & + newIceBGCFraction ! save tracer array size nTracers_temp = tracerObject % nTracers @@ -13246,6 +13252,7 @@ subroutine init_column_tracer_object_for_biogeochemistry(domain, tracerObject) call MPAS_pool_get_dimension(domain % blocklist % dimensions, "nParticulateIron", nParticulateIron) call MPAS_pool_get_dimension(domain % blocklist % dimensions, "nDissolvedIron", nDissolvedIron) call MPAS_pool_get_dimension(domain % blocklist % dimensions, "nzAerosols", nzAerosols) + call MPAS_pool_get_dimension(domain % blocklist % dimensions, "nZBGCTracers", nZBGCTracers) call MPAS_pool_get_dimension(domain % blocklist % dimensions, "maxAerosolType", maxAerosolType) call MPAS_pool_get_dimension(domain % blocklist % dimensions, "maxAlgaeType", maxAlgaeType) call MPAS_pool_get_dimension(domain % blocklist % dimensions, "maxDOCType", maxDOCType) @@ -13253,6 +13260,18 @@ subroutine init_column_tracer_object_for_biogeochemistry(domain, tracerObject) call MPAS_pool_get_dimension(domain % blocklist % dimensions, "maxDONType", maxDONType) call MPAS_pool_get_dimension(domain % blocklist % dimensions, "maxIronType", maxIronType) + allocate(BGCTracerType(nZBGCTracers)) + allocate(initialMobileFraction(nZBGCTracers)) + allocate(retentionTime(nZBGCTracers)) + allocate(releaseTime(nZBGCTracers)) + allocate(newIceBGCFraction(nZBGCTracers)) + + retentionTime(:) = 0.0_RKIND + releaseTime(:) = 0.0_RKIND + initialMobileFraction(:) = 0.0_RKIND + BGCTracerType(:) = 0.0_RKIND + newIceBGCFraction(:) = 0.0_RKIND + use_nitrogen = .false. if (config_use_skeletal_biochemistry .or. config_use_vertical_biochemistry) & use_nitrogen = .true. @@ -13394,84 +13413,15 @@ subroutine init_column_tracer_object_for_biogeochemistry(domain, tracerObject) tau_min_in=config_rapid_mobile_to_stationary_time, & tau_max_in=config_long_mobile_to_stationary_time) - call icepack_init_zbgc_tracer_indices(& - nilyr_in=nIceLayers, & - nslyr_in=nSnowLayers, & - nblyr_in=nBioLayers, & - n_algae_in=nAlgae, & - n_zaero_in=nzAerosols, & - n_doc_in=nDOC, & - n_dic_in=nDIC, & - n_don_in=nDON, & - n_fed_in=nDissolvedIron, & - n_fep_in=nParticulateIron, & - trcr_base=tracerObject % firstAncestorMask, & - trcr_depend=tracerObject % parentIndex, & - n_trcr_strata=tracerObject % ancestorNumber, & - nt_strata=tracerObject % ancestorIndices, & - nbtrcr_sw_out=tracerObject % nBioTracersShortwave, & - tr_brine_in=config_use_brine, & - nt_fbri_out=tracerObject % index_brineFraction,& - ntrcr_out=tracerObject % nTracers, & - nbtrcr_out=tracerObject % nBioTracers, & - ntrcr_o_out=tracerObject % nTracersNotBio, & - nt_bgc_Nit_out=tracerObject % index_nitrateConc, & - nt_bgc_Am_out=tracerObject % index_ammoniumConc, & - nt_bgc_Sil_out=tracerObject % index_silicateConc, & - nt_bgc_DMS_out=tracerObject % index_DMSConc, & - nt_bgc_PON_out=tracerObject % index_nonreactiveConc, & - nt_bgc_N_out=tracerObject % index_algaeConc, & - nt_bgc_C_out=tracerObject % index_algalCarbon, & - nt_bgc_chl_out=tracerObject % index_algalChlorophyll, & - nt_bgc_DOC_out=tracerObject % index_DOCConc, & - nt_bgc_DON_out=tracerObject % index_DONConc, & - nt_bgc_DIC_out=tracerObject % index_DICConc, & - nt_zaero_out=tracerObject % index_verticalAerosolsConc, & - nt_bgc_DMSPp_out=tracerObject % index_DMSPpConc, & - nt_bgc_DMSPd_out=tracerObject % index_DMSPdConc, & - nt_bgc_Fed_out=tracerObject % index_dissolvedIronConc, & - nt_bgc_Fep_out=tracerObject % index_particulateIronConc, & - nt_zbgc_frac_out=tracerObject % index_mobileFraction, & - tr_bgc_Nit_in=config_use_nitrate, & - tr_bgc_Am_in=config_use_ammonium, & - tr_bgc_Sil_in=config_use_silicate, & - tr_bgc_DMS_in=config_use_DMS, & - tr_bgc_PON_in=config_use_nonreactive, & - tr_bgc_N_in=use_nitrogen, & - tr_bgc_C_in=config_use_carbon, & - tr_bgc_chl_in=config_use_chlorophyll, & - tr_bgc_DON_in=config_use_DON, & - tr_bgc_Fe_in=config_use_iron,& - tr_zaero_in=config_use_zaerosols, & - nlt_zaero_sw_out=tracerObject % index_verticalAerosolsConcShortwave, & - nlt_chl_sw_out=tracerObject % index_chlorophyllShortwave, & - nlt_bgc_N_out=tracerObject % index_algaeConcLayer, & - nlt_bgc_Nit_out=tracerObject % index_nitrateConcLayer, & - nlt_bgc_Am_out=tracerObject % index_ammoniumConcLayer, & - nlt_bgc_Sil_out=tracerObject % index_silicateConcLayer, & - nlt_bgc_DMS_out=tracerObject % index_DMSConcLayer, & - nlt_bgc_DMSPp_out=tracerObject % index_DMSPpConcLayer, & - nlt_bgc_DMSPd_out=tracerObject % index_DMSPdConcLayer, & - nlt_bgc_C_out=tracerObject % index_algalCarbonLayer, & - nlt_bgc_chl_out=tracerObject % index_algalChlorophyllLayer, & - nlt_bgc_DIC_out=tracerObject % index_DICConcLayer, & - nlt_bgc_DOC_out=tracerObject % index_DOCConcLayer, & - nlt_bgc_PON_out=tracerObject % index_nonreactiveConcLayer, & - nlt_bgc_DON_out=tracerObject % index_DONConcLayer, & - nlt_bgc_Fed_out=tracerObject % index_dissolvedIronConcLayer, & - nlt_bgc_Fep_out=tracerObject % index_particulateIronConcLayer, & - nlt_zaero_out=tracerObject % index_verticalAerosolsConcLayer, & - nt_bgc_hum_out=tracerObject % index_humicsConc, & - nlt_bgc_hum_out=tracerObject % index_humicsConcLayer, & - tr_bgc_hum_in=config_use_humics, & - skl_bgc_in=config_use_skeletal_biochemistry, & - z_tracers_in=config_use_vertical_tracers, & - dEdd_algae_in=config_use_shortwave_bioabsorption, & - solve_zbgc_in=config_use_vertical_biochemistry, & - bio_index_o_out=tracerObject % index_LayerIndexToDataArray, & - bio_index_out=tracerObject % index_LayerIndexToBioIndex) - - call icepack_init_zbgc() + call init_zbgc_tracer_indices(domain, tracerObject, use_nitrogen, nTracers_temp, & + BGCTracerType, initialMobileFraction, retentionTime, & + releaseTime, newIceBGCFraction) + + call icepack_init_zbgc(bgc_tracer_type_in=BGCTracerType, & + zbgc_frac_init_in=initialMobileFraction, & + tau_ret_in=retentionTime, & + tau_rel_in=releaseTime, & + zbgc_init_frac_in=newIceBGCFraction) ! check calculated tracer array size if (nTracers_temp /= tracerObject % nTracers) then @@ -13494,8 +13444,827 @@ subroutine init_column_tracer_object_for_biogeochemistry(domain, tracerObject) call icepack_query_parameters(tau_max_out=rtmp2) if (rtmp1 /= rtmp2) call mpas_log_write('tau_max differs $r $r',realArgs=(/rtmp1,rtmp2/)) + deallocate(BGCTracerType) + deallocate(initialMobileFraction) + deallocate(retentionTime) + deallocate(releaseTime) + deallocate(newIceBGCFraction) + end subroutine init_column_tracer_object_for_biogeochemistry +!||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||| +! +! init_zbgc_tracer_indices +! +!> \brief +!> \author Nicole Jeffery, LANL +!> \date 24 May 2024 +!> \details +!> Moves icepack_init_zbgc_tracer_indices to the interface +! +!----------------------------------------------------------------------- + + subroutine init_zbgc_tracer_indices(domain, tracerObject, use_nitrogen, nTracersTemp, & + BGCTracerType, initialMobileFraction, retentionTime, & + releaseTime, newIceBGCFraction) + + type(domain_type), intent(in) :: & + domain + + type(ciceTracerObjectType), intent(inout) :: & + tracerObject + + real(kind=RKIND), dimension(:), intent(inout) :: & + BGCTracerType, & + initialMobileFraction, & + retentionTime, & + releaseTime, & + newIceBGCFraction + + integer, intent(in) :: & + nTracersTemp + + logical, intent(in) :: & + use_nitrogen + + logical, pointer :: & + config_use_brine, & + config_use_vertical_zsalinity, & !echmod deprecate + config_use_vertical_biochemistry, & + config_use_vertical_tracers, & + config_use_skeletal_biochemistry, & + config_use_shortwave_bioabsorption, & + config_use_nitrate, & + config_use_carbon, & + config_use_chlorophyll, & + config_use_ammonium, & + config_use_silicate, & + config_use_DMS, & + config_use_nonreactive, & + config_use_humics, & + config_use_DON, & + config_use_iron, & + config_use_zaerosols + + real(kind=RKIND), pointer :: & + config_mobility_type_diatoms, & + config_mobility_type_small_plankton, & + config_mobility_type_phaeocystis, & + config_mobility_type_nitrate, & + config_mobility_type_ammonium, & + config_mobility_type_silicate, & + config_mobility_type_DMSPp, & + config_mobility_type_DMSPd, & + config_mobility_type_humics, & + config_mobility_type_saccharids, & + config_mobility_type_lipids, & + config_mobility_type_inorganic_carbon, & + config_mobility_type_proteins, & + config_mobility_type_dissolved_iron, & + config_mobility_type_particulate_iron, & + config_mobility_type_black_carbon1, & + config_mobility_type_black_carbon2, & + config_mobility_type_dust1, & + config_mobility_type_dust2, & + config_mobility_type_dust3, & + config_mobility_type_dust4, & + config_rapid_mobile_to_stationary_time, & + config_long_mobile_to_stationary_time, & + config_fraction_biotracer_in_frazil, & + config_new_ice_fraction_biotracer + + integer, pointer :: & + nIceLayers, & + nSnowLayers, & + nBioLayers, & + nAlgae, & + nDOC, & + nDIC, & + nDON, & + nParticulateIron, & + nDissolvedIron, & + nzAerosols, & + nZBGCTracers, & + maxAerosolType, & + maxAlgaeType, & + maxDOCType, & + maxDICType, & + maxDONType, & + maxIronType + + integer :: & + iAerosols, & + nTracerDependOption, & + nCount, & + nTracerDepend, & + iBioLayer, & + iBioTracer + + real(kind=RKIND) :: & + rtmp1, & + rtmp2 + + real (kind=RKIND), dimension (:), allocatable :: & + algalType, & + docType, & + dicType, & + donType, & + fedType, & + fepType, & + zAeroType + + call MPAS_pool_get_config(domain % configs, "config_use_brine", config_use_brine) + call MPAS_pool_get_config(domain % configs, "config_use_vertical_zsalinity", config_use_vertical_zsalinity) !echmod deprecate + call MPAS_pool_get_config(domain % configs, "config_use_shortwave_bioabsorption", config_use_shortwave_bioabsorption) + call MPAS_pool_get_config(domain % configs, "config_use_vertical_tracers", config_use_vertical_tracers) + call MPAS_pool_get_config(domain % configs, "config_use_skeletal_biochemistry", config_use_skeletal_biochemistry) + call MPAS_pool_get_config(domain % configs, "config_use_vertical_biochemistry", config_use_vertical_biochemistry) + call MPAS_pool_get_config(domain % configs, "config_use_nitrate", config_use_nitrate) + call MPAS_pool_get_config(domain % configs, "config_use_carbon", config_use_carbon) + call MPAS_pool_get_config(domain % configs, "config_use_chlorophyll", config_use_chlorophyll) + call MPAS_pool_get_config(domain % configs, "config_use_ammonium", config_use_ammonium) + call MPAS_pool_get_config(domain % configs, "config_use_silicate", config_use_silicate) + call MPAS_pool_get_config(domain % configs, "config_use_DMS", config_use_DMS) + call MPAS_pool_get_config(domain % configs, "config_use_nonreactive", config_use_nonreactive) + call MPAS_pool_get_config(domain % configs, "config_use_humics", config_use_humics) + call MPAS_pool_get_config(domain % configs, "config_use_DON", config_use_DON) + call MPAS_pool_get_config(domain % configs, "config_use_iron", config_use_iron) + call MPAS_pool_get_config(domain % configs, "config_use_zaerosols", config_use_zaerosols) + + call MPAS_pool_get_config(domain % configs, "config_mobility_type_diatoms", config_mobility_type_diatoms) + call MPAS_pool_get_config(domain % configs, "config_mobility_type_small_plankton", config_mobility_type_small_plankton) + call MPAS_pool_get_config(domain % configs, "config_mobility_type_phaeocystis", config_mobility_type_phaeocystis) + call MPAS_pool_get_config(domain % configs, "config_mobility_type_nitrate", config_mobility_type_nitrate) + call MPAS_pool_get_config(domain % configs, "config_mobility_type_ammonium", config_mobility_type_ammonium) + call MPAS_pool_get_config(domain % configs, "config_mobility_type_silicate", config_mobility_type_silicate) + call MPAS_pool_get_config(domain % configs, "config_mobility_type_DMSPp", config_mobility_type_DMSPp) + call MPAS_pool_get_config(domain % configs, "config_mobility_type_DMSPd", config_mobility_type_DMSPd) + call MPAS_pool_get_config(domain % configs, "config_mobility_type_humics", config_mobility_type_humics) + call MPAS_pool_get_config(domain % configs, "config_mobility_type_saccharids", config_mobility_type_saccharids) + call MPAS_pool_get_config(domain % configs, "config_mobility_type_lipids", config_mobility_type_lipids) + call MPAS_pool_get_config(domain % configs, "config_mobility_type_inorganic_carbon", config_mobility_type_inorganic_carbon) + call MPAS_pool_get_config(domain % configs, "config_mobility_type_proteins", config_mobility_type_proteins) + call MPAS_pool_get_config(domain % configs, "config_mobility_type_dissolved_iron", config_mobility_type_dissolved_iron) + call MPAS_pool_get_config(domain % configs, "config_mobility_type_particulate_iron", config_mobility_type_particulate_iron) + call MPAS_pool_get_config(domain % configs, "config_mobility_type_black_carbon1", config_mobility_type_black_carbon1) + call MPAS_pool_get_config(domain % configs, "config_mobility_type_black_carbon2", config_mobility_type_black_carbon2) + call MPAS_pool_get_config(domain % configs, "config_mobility_type_dust1", config_mobility_type_dust1) + call MPAS_pool_get_config(domain % configs, "config_mobility_type_dust2", config_mobility_type_dust2) + call MPAS_pool_get_config(domain % configs, "config_mobility_type_dust3", config_mobility_type_dust3) + call MPAS_pool_get_config(domain % configs, "config_mobility_type_dust4", config_mobility_type_dust4) + call MPAS_pool_get_config(domain % configs, "config_rapid_mobile_to_stationary_time", & + config_rapid_mobile_to_stationary_time) + call MPAS_pool_get_config(domain % configs, "config_long_mobile_to_stationary_time", & + config_long_mobile_to_stationary_time) + call MPAS_pool_get_config(domain % configs, "config_fraction_biotracer_in_frazil", & + config_fraction_biotracer_in_frazil) + call MPAS_pool_get_config(domain % configs, "config_new_ice_fraction_biotracer", & + config_new_ice_fraction_biotracer) + + call MPAS_pool_get_dimension(domain % blocklist % dimensions, "nIceLayers", nIceLayers) + call MPAS_pool_get_dimension(domain % blocklist % dimensions, "nSnowLayers", nSnowLayers) + call MPAS_pool_get_dimension(domain % blocklist % dimensions, "nBioLayers",nBioLayers) + call MPAS_pool_get_dimension(domain % blocklist % dimensions, "nAlgae", nAlgae) + call MPAS_pool_get_dimension(domain % blocklist % dimensions, "nDOC", nDOC) + call MPAS_pool_get_dimension(domain % blocklist % dimensions, "nDIC", nDIC) + call MPAS_pool_get_dimension(domain % blocklist % dimensions, "nDON", nDON) + call MPAS_pool_get_dimension(domain % blocklist % dimensions, "nParticulateIron", nParticulateIron) + call MPAS_pool_get_dimension(domain % blocklist % dimensions, "nDissolvedIron", nDissolvedIron) + call MPAS_pool_get_dimension(domain % blocklist % dimensions, "nzAerosols", nzAerosols) + call MPAS_pool_get_dimension(domain % blocklist % dimensions, "nZBGCTracers", nZBGCTracers) + call MPAS_pool_get_dimension(domain % blocklist % dimensions, "maxAerosolType", maxAerosolType) + call MPAS_pool_get_dimension(domain % blocklist % dimensions, "maxAlgaeType", maxAlgaeType) + call MPAS_pool_get_dimension(domain % blocklist % dimensions, "maxDOCType", maxDOCType) + call MPAS_pool_get_dimension(domain % blocklist % dimensions, "maxDICType", maxDICType) + call MPAS_pool_get_dimension(domain % blocklist % dimensions, "maxDONType", maxDONType) + call MPAS_pool_get_dimension(domain % blocklist % dimensions, "maxIronType", maxIronType) + + tracerObject % nTracersNotBio = tracerObject % nTracers + tracerObject % index_brineFraction = 0 + if (config_use_brine) then + tracerObject % index_brineFraction = tracerObject % nTracers + 1 ! ice volume fraction with salt + tracerObject % nTracers = tracerObject % nTracers + 1 + tracerObject % parentIndex(tracerObject % index_brineFraction) = 1 ! volume-weighted + tracerObject % firstAncestorMask (tracerObject % index_brineFraction,1) = 0.0_RKIND ! volume-weighted + tracerObject % firstAncestorMask (tracerObject % index_brineFraction,2) = 1.0_RKIND ! volume-weighted + tracerObject % firstAncestorMask (tracerObject % index_brineFraction,3) = 0.0_RKIND ! volume-weighted + tracerObject % ancestorNumber(tracerObject % index_brineFraction) = 0 + tracerObject % ancestorIndices (tracerObject % index_brineFraction,1) = 0 + tracerObject % ancestorIndices (tracerObject % index_brineFraction,2) = 0 + endif + + nTracerDependOption = 0 ! if tracerObject % index_brineFraction /= 0 then use fbri dependency + if (tracerObject % index_brineFraction == 0) nTracerDependOption = -1 ! otherwise make tracers depend on ice volume + + !----------------------------------------------------------------- + ! biogeochemistry + !----------------------------------------------------------------- + + tracerObject % nBioTracers = 0 + tracerObject % nBioTracersShortwave = 0 + + ! vectors of size maxAlgaeType + tracerObject % index_algaeConcLayer(:) = 0 + tracerObject % index_algalCarbonLayer(:) = 0 + tracerObject % index_algalChlorophyllLayer(:) = 0 + tracerObject % index_algaeConc(:) = 0 + tracerObject % index_algalCarbon(:) = 0 + tracerObject % index_algalChlorophyll(:) = 0 + + ! vectors of size maxDICType + tracerObject % index_DICConcLayer(:) = 0 + tracerObject % index_DICConc(:) = 0 + + ! vectors of size maxDOCType + tracerObject % index_DOCConcLayer(:) = 0 + tracerObject % index_DOCConc(:) = 0 + + ! vectors of size maxDONType + tracerObject % index_DONConcLayer(:) = 0 + tracerObject % index_DONConc(:) = 0 + + ! vectors of size maxIronType + tracerObject % index_dissolvedIronConcLayer(:) = 0 + tracerObject % index_particulateIronConcLayer(:) = 0 + tracerObject % index_dissolvedIronConc(:) = 0 + tracerObject % index_particulateIronConc(:) = 0 + + ! vectors of size maxAerosolType + tracerObject % index_verticalAerosolsConcLayer(:) = 0 + tracerObject % index_verticalAerosolsConcShortwave(:) = 0 + tracerObject % index_verticalAerosolsConc(:) = 0 + + tracerObject % index_nitrateConcLayer = 0 + tracerObject % index_ammoniumConcLayer = 0 + tracerObject % index_silicateConcLayer = 0 + tracerObject % index_DMSPpConcLayer = 0 + tracerObject % index_DMSPdConcLayer = 0 + tracerObject % index_DMSConcLayer = 0 + tracerObject % index_nonreactiveConcLayer = 0 + tracerObject % index_humicsConcLayer = 0 + tracerObject % index_chlorophyllShortwave = 0 + tracerObject % index_LayerIndexToBioIndex(:) = 0 + tracerObject % index_LayerIndexToDataArray(:) = 0 + + tracerObject % index_nitrateConc = 0 + tracerObject % index_ammoniumConc = 0 + tracerObject % index_silicateConc = 0 + tracerObject % index_DMSPpConc = 0 + tracerObject % index_DMSPdConc = 0 + tracerObject % index_DMSConc = 0 + tracerObject % index_nonreactiveConc = 0 + tracerObject % index_humicsConc = 0 + + allocate(algalType(maxAlgaeType)) + allocate(docType(maxDOCType)) + allocate(dicType(maxDICType)) + allocate(donType(maxDONType)) + allocate(fedType(maxIronType)) + allocate(fepType(maxIronType)) + allocate(zAeroType(maxAerosolType)) + + algalType(1) = config_mobility_type_diatoms + algalType(2) = config_mobility_type_small_plankton + algalType(3) = config_mobility_type_phaeocystis + + docType(1) = config_mobility_type_saccharids + docType(2) = config_mobility_type_lipids + + dicType(1) = config_mobility_type_inorganic_carbon + + donType(1) = config_mobility_type_proteins + + fedType(1) = config_mobility_type_dissolved_iron + fepType(1) = config_mobility_type_particulate_iron + + zAeroType(1) = config_mobility_type_black_carbon1 + zAeroType(2) = config_mobility_type_black_carbon2 + zAeroType(3) = config_mobility_type_dust1 + zAeroType(4) = config_mobility_type_dust2 + zAeroType(5) = config_mobility_type_dust3 + zAeroType(6) = config_mobility_type_dust4 + + if (config_use_skeletal_biochemistry) then + + nCount = 1 + nTracerDepend = 0 + + if (config_use_shortwave_bioabsorption) then + tracerObject % index_chlorophyllShortwave = 1 + tracerObject % nBioTracersShortwave = nIceLayers+nSnowLayers+2 ! only the bottom layer + ! will be nonzero + endif + elseif (config_use_vertical_tracers) then ! defined on nBioLayers+1 in ice + ! and 2 snow layers (snow surface + interior) + nCount = nBioLayers + 1 + nTracerDepend = 2 + tracerObject % index_brineFraction + nTracerDependOption + + if (use_nitrogen) then + if (config_use_shortwave_bioabsorption) then + tracerObject % index_chlorophyllShortwave = 1 + tracerObject % nBioTracersShortwave = nIceLayers+nSnowLayers+2 + endif + endif ! use_nitrogen + + endif ! config_use_skeletal_biochemistry or config_use_vertical_tracers + + if (config_use_skeletal_biochemistry .or. config_use_vertical_tracers) then + + !----------------------------------------------------------------- + ! assign tracer indices and dependencies + ! BGCTracerType: < 0 purely mobile , >= 0 stationary + !------------------------------------------------------------------ + + if (use_nitrogen) then + do iBioTracer = 1, nAlgae + call init_bgc_tracer_indices(nCount, tracerObject % index_brineFraction, & + tracerObject % index_algaeConc(iBioTracer), & + tracerObject % index_algaeConcLayer(iBioTracer),& + algalType(iBioTracer), nTracerDepend, & + tracerObject % nTracers, & + tracerObject % nBioTracers, & + BGCTracerType, & + tracerObject % parentIndex, & + tracerObject % firstAncestorMask, & + tracerObject % ancestorNumber, & + tracerObject % ancestorIndices, & + tracerObject % index_LayerIndexToBioIndex) + tracerObject % index_LayerIndexToDataArray(tracerObject % index_algaeConcLayer(iBioTracer)) & + = iBioTracer + enddo ! iBioTracer + endif ! use_nitrogen + + if (config_use_nitrate) then + call init_bgc_tracer_indices(& + nCount, tracerObject % index_brineFraction, & + tracerObject % index_nitrateConc, & + tracerObject % index_nitrateConcLayer, & + config_mobility_type_nitrate, nTracerDepend, & + tracerObject % nTracers, & + tracerObject % nBioTracers, & + BGCTracerType, & + tracerObject % parentIndex, & + tracerObject % firstAncestorMask, & + tracerObject % ancestorNumber, & + tracerObject % ancestorIndices, & + tracerObject % index_LayerIndexToBioIndex) + tracerObject % index_LayerIndexToDataArray(tracerObject % index_nitrateConcLayer) & + = maxAlgaeType + 1 + endif ! config_use_nitrate + + if (config_use_carbon) then + ! + ! Algal C is not yet distinct from algal N + ! * Reqires exudation and/or changing C:N ratios + ! for implementation + ! + ! do iBioTracer = 1,nAlgae + ! call init_bgc_tracer_indices(nCount,tracerObject % index_brineFraction, & + ! tracerObject % index_algalCarbon(iBioTracer), & + ! tracerObject % index_algalCarbonLayer(iBioTracer), & + ! algalType(iBioTracer), nTracerDepend, & + ! tracerObject % nTracers, & + ! tracerObject % nBioTracers, & + ! BGCTracerType, & + ! tracerObject % parentIndex, & + ! tracerObject % firstAncestorMask, & + ! tracerObject % ancestorNumber, & + ! tracerObject % ancestorIndices, & + ! tracerObject % index_LayerIndexToBioIndex) + ! tracerObject % index_LayerIndexToDataArray(tracerObject % index_algalCarbonLayer(iBioTracer)) & + ! = maxAlgaeType + 1 + iBioTracer + ! enddo ! iBioTracer + + do iBioTracer = 1, nDOC + call init_bgc_tracer_indices(& + nCount, tracerObject % index_brineFraction, & + tracerObject % index_DOCConc(iBioTracer), & + tracerObject % index_DOCConcLayer(iBioTracer), & + docType(iBioTracer), nTracerDepend, & + tracerObject % nTracers, & + tracerObject % nBioTracers, & + BGCTracerType, & + tracerObject % parentIndex, & + tracerObject % firstAncestorMask, & + tracerObject % ancestorNumber, & + tracerObject % ancestorIndices, & + tracerObject % index_LayerIndexToBioIndex) + tracerObject % index_LayerIndexToDataArray(tracerObject % index_DOCConcLayer(iBioTracer)) & + = maxAlgaeType + 1 + iBioTracer + enddo ! iBioTracer + do iBioTracer = 1, nDIC + call init_bgc_tracer_indices(nCount, tracerObject % index_brineFraction, & + tracerObject % index_DICConc(iBioTracer), & + tracerObject % index_DICConcLayer(iBioTracer), & + dicType(iBioTracer), nTracerDepend, & + tracerObject % nTracers, & + tracerObject % nBioTracers, & + BGCTracerType, & + tracerObject % parentIndex, & + tracerObject % firstAncestorMask, & + tracerObject % ancestorNumber, & + tracerObject % ancestorIndices, & + tracerObject % index_LayerIndexToBioIndex) + tracerObject % index_LayerIndexToDataArray(tracerObject % index_DICConcLayer(iBioTracer)) & + = maxAlgaeType + maxDOCType + 1 + iBioTracer + enddo ! iBioTracer + endif ! config_use_carbon + + if (config_use_chlorophyll) then + do iBioTracer = 1, nAlgae + call init_bgc_tracer_indices(nCount, tracerObject % index_brineFraction, & + tracerObject % index_algalChlorophyll(iBioTracer), & + tracerObject % index_algalChlorophyllLayer(iBioTracer), & + algalType(iBioTracer), nTracerDepend, & + tracerObject % nTracers, & + tracerObject % nBioTracers, & + BGCTracerType, & + tracerObject % parentIndex, & + tracerObject % firstAncestorMask, & + tracerObject % ancestorNumber, & + tracerObject % ancestorIndices, & + tracerObject % index_LayerIndexToBioIndex) + tracerObject % index_LayerIndexToDataArray(tracerObject % index_algalChlorophyllLayer(iBioTracer)) & + = maxAlgaeType + 1 + maxDOCType + maxDICType + iBioTracer + enddo ! iBioTracer + endif ! config_use_chlorophyll + + if (config_use_ammonium) then + call init_bgc_tracer_indices(nCount, tracerObject % index_brineFraction, & + tracerObject % index_ammoniumConc, & + tracerObject % index_ammoniumConcLayer, & + config_mobility_type_ammonium, & + nTracerDepend, & + tracerObject % nTracers, & + tracerObject % nBioTracers, & + BGCTracerType, & + tracerObject % parentIndex, & + tracerObject % firstAncestorMask, & + tracerObject % ancestorNumber, & + tracerObject % ancestorIndices, & + tracerObject % index_LayerIndexToBioIndex) + tracerObject % index_LayerIndexToDataArray(tracerObject % index_ammoniumConcLayer) & + = 2*maxAlgaeType + maxDOCType + maxDICType + 2 + endif + if (config_use_silicate) then + call init_bgc_tracer_indices(nCount, tracerObject % index_brineFraction, & + tracerObject % index_silicateConc, & + tracerObject % index_silicateConcLayer, & + config_mobility_type_silicate, & + nTracerDepend, & + tracerObject % nTracers, & + tracerObject % nBioTracers, & + BGCTracerType, & + tracerObject % parentIndex, & + tracerObject % firstAncestorMask, & + tracerObject % ancestorNumber, & + tracerObject % ancestorIndices, & + tracerObject % index_LayerIndexToBioIndex) + tracerObject % index_LayerIndexToDataArray(tracerObject % index_silicateConcLayer) & + = 2*maxAlgaeType + maxDOCType + maxDICType + 3 + endif + if (config_use_DMS) then ! all together + call init_bgc_tracer_indices(nCount, tracerObject % index_brineFraction, & + tracerObject % index_DMSPpConc, & + tracerObject % index_DMSPpConcLayer, & + config_mobility_type_DMSPp, nTracerDepend, & + tracerObject % nTracers, & + tracerObject % nBioTracers, & + BGCTracerType, & + tracerObject % parentIndex, & + tracerObject % firstAncestorMask, & + tracerObject % ancestorNumber, & + tracerObject % ancestorIndices, & + tracerObject % index_LayerIndexToBioIndex) + tracerObject % index_LayerIndexToDataArray(tracerObject % index_DMSPpConcLayer) & + = 2*maxAlgaeType + maxDOCType + maxDICType + 4 + + call init_bgc_tracer_indices(nCount, tracerObject % index_brineFraction, & + tracerObject % index_DMSPdConc, & + tracerObject % index_DMSPdConcLayer, & + config_mobility_type_DMSPd, nTracerDepend, & + tracerObject % nTracers, & + tracerObject % nBioTracers, & + BGCTracerType, & + tracerObject % parentIndex, & + tracerObject % firstAncestorMask, & + tracerObject % ancestorNumber, & + tracerObject % ancestorIndices, & + tracerObject % index_LayerIndexToBioIndex) + tracerObject % index_LayerIndexToDataArray(tracerObject % index_DMSPdConcLayer) & + = 2*maxAlgaeType + maxDOCType + maxDICType + 5 + + call init_bgc_tracer_indices(nCount, tracerObject % index_brineFraction, & + tracerObject % index_DMSConc, & + tracerObject % index_DMSConcLayer, & + config_mobility_type_DMSPd, nTracerDepend, & + tracerObject % nTracers, & + tracerObject % nBioTracers, & + BGCTracerType, & + tracerObject % parentIndex, & + tracerObject % firstAncestorMask, & + tracerObject % ancestorNumber, & + tracerObject % ancestorIndices, & + tracerObject % index_LayerIndexToBioIndex) + tracerObject % index_LayerIndexToDataArray(tracerObject % index_DMSConcLayer) & + = 2*maxAlgaeType + maxDOCType + maxDICType + 6 + endif + if (config_use_nonreactive) then + call init_bgc_tracer_indices(nCount, tracerObject % index_brineFraction, & + tracerObject % index_nonreactiveConc, & + tracerObject % index_nonreactiveConcLayer, & + config_mobility_type_nitrate, nTracerDepend,& + tracerObject % nTracers, & + tracerObject % nBioTracers, & + BGCTracerType, & + tracerObject % parentIndex, & + tracerObject % firstAncestorMask, & + tracerObject % ancestorNumber, & + tracerObject % ancestorIndices, & + tracerObject % index_LayerIndexToBioIndex) + tracerObject % index_LayerIndexToDataArray(tracerObject % index_nonreactiveConcLayer) & + = 2*maxAlgaeType + maxDOCType + maxDICType + 7 + endif + if (config_use_DON) then + do iBioTracer = 1, nDON + call init_bgc_tracer_indices(nCount, tracerObject % index_brineFraction, & + tracerObject % index_DONConc(iBioTracer), & + tracerObject % index_DONConcLayer(iBioTracer), & + donType(iBioTracer), nTracerDepend, & + tracerObject % nTracers, & + tracerObject % nBioTracers, & + BGCTracerType, & + tracerObject % parentIndex, & + tracerObject % firstAncestorMask, & + tracerObject % ancestorNumber, & + tracerObject % ancestorIndices, & + tracerObject % index_LayerIndexToBioIndex) + tracerObject % index_LayerIndexToDataArray(tracerObject % index_DONConcLayer(iBioTracer)) & + = 2*maxAlgaeType + maxDOCType + maxDICType + 7 + iBioTracer + enddo ! iBioTracer + endif ! config_use_DON + if (config_use_iron) then + do iBioTracer = 1, nDissolvedIron + call init_bgc_tracer_indices(nCount, tracerObject % index_brineFraction, & + tracerObject % index_dissolvedIronConc(iBioTracer), & + tracerObject % index_dissolvedIronConcLayer(iBioTracer),& + fedType(iBioTracer), nTracerDepend, & + tracerObject % nTracers, & + tracerObject % nBioTracers, & + BGCTracerType, tracerObject % parentIndex, & + tracerObject % firstAncestorMask, & + tracerObject % ancestorNumber, & + tracerObject % ancestorIndices, & + tracerObject % index_LayerIndexToBioIndex) + tracerObject % index_LayerIndexToDataArray(tracerObject % index_dissolvedIronConcLayer(iBioTracer)) & + = 2*maxAlgaeType + maxDOCType + maxDICType + maxDONType + 7 + iBioTracer + enddo ! iBioTracer + do iBioTracer = 1, nParticulateIron + call init_bgc_tracer_indices(nCount, tracerObject % index_brineFraction, & + tracerObject % index_particulateIronConc(iBioTracer), & + tracerObject % index_particulateIronConcLayer(iBioTracer), & + fepType(iBioTracer), nTracerDepend, & + tracerObject % nTracers, & + tracerObject % nBioTracers, & + BGCTracerType, tracerObject % parentIndex, & + tracerObject % firstAncestorMask, & + tracerObject % ancestorNumber, & + tracerObject % ancestorIndices, & + tracerObject % index_LayerIndexToBioIndex) + tracerObject % index_LayerIndexToDataArray(tracerObject % index_particulateIronConcLayer(iBioTracer)) & + = 2*maxAlgaeType + maxDOCType + maxDICType + maxDONType + maxIronType + 7 + iBioTracer + enddo ! iBioTracer + endif ! config_use_iron + + if (config_use_humics) then + call init_bgc_tracer_indices(nCount, tracerObject % index_brineFraction, & + tracerObject % index_humicsConc, & + tracerObject % index_humicsConcLayer, & + config_mobility_type_humics, nTracerDepend, & + tracerObject % nTracers, & + tracerObject % nBioTracers, & + BGCTracerType, & + tracerObject % parentIndex, & + tracerObject % firstAncestorMask, & + tracerObject % ancestorNumber, & + tracerObject % ancestorIndices, & + tracerObject % index_LayerIndexToBioIndex) + tracerObject % index_LayerIndexToDataArray(tracerObject % index_humicsConcLayer) & + = 2*maxAlgaeType + maxDOCType + 8 + maxDICType + maxDONType + 2*maxIronType + maxAerosolType + endif + endif ! config_use_skeletal_biochemistry or config_use_vertical_tracers + + if (config_use_vertical_tracers) then ! defined on nBioLayers+1 in ice + ! and 2 snow layers (snow surface + interior) + nCount = nBioLayers + 1 + nTracerDepend = 2 + tracerObject % index_brineFraction + nTracerDependOption + + ! z layer aerosols + if (config_use_zaerosols) then + do iBioTracer = 1, nzAerosols + if (config_use_shortwave_bioabsorption) then + tracerObject % index_verticalAerosolsConcShortwave(iBioTracer) = & + tracerObject % nBioTracersShortwave + 1 + tracerObject % nBioTracersShortwave = & + tracerObject % nBioTracersShortwave + nIceLayers + nSnowLayers+2 + endif + call init_bgc_tracer_indices(nCount, tracerObject % index_brineFraction, & + tracerObject % index_verticalAerosolsConc(iBioTracer), & + tracerObject % index_verticalAerosolsConcLayer(iBioTracer), & + zAeroType(iBioTracer), nTracerDepend, & + tracerObject % nTracers, & + tracerObject % nBioTracers, & + BGCTracerType, tracerObject % parentIndex, & + tracerObject % firstAncestorMask, & + tracerObject % ancestorNumber, & + tracerObject % ancestorIndices, & + tracerObject % index_LayerIndexToBioIndex) + tracerObject % index_LayerIndexToDataArray(tracerObject % index_verticalAerosolsConcLayer(iBioTracer)) & + = 2*maxAlgaeType + maxDOCType + maxDICType + maxDONType + 2*maxIronType + 7 + iBioTracer + enddo ! iBioTracer + endif ! config_use_zaerosols + + tracerObject % index_mobileFraction = 0 + if (tracerObject % nBioTracers > 0) then + tracerObject % index_mobileFraction = tracerObject % nTracers + 1 + tracerObject % nTracers = tracerObject % nTracers + tracerObject % nBioTracers + do iBioLayer = 1,tracerObject % nBioTracers + initialMobileFraction(iBioLayer) = 1.0_RKIND + tracerObject % parentIndex(tracerObject % index_mobileFraction+iBioLayer-1) & + = 2+tracerObject % index_brineFraction + tracerObject % firstAncestorMask(tracerObject % index_mobileFraction+ iBioLayer - 1,1) = 0.0_RKIND + tracerObject % firstAncestorMask(tracerObject % index_mobileFraction+ iBioLayer - 1,2) = 1.0_RKIND + tracerObject % firstAncestorMask(tracerObject % index_mobileFraction+ iBioLayer - 1,3) = 0.0_RKIND + tracerObject % ancestorNumber(tracerObject % index_mobileFraction+ iBioLayer - 1) = 1 + tracerObject % ancestorIndices(tracerObject % index_mobileFraction+ iBioLayer - 1,1) & + = tracerObject % index_brineFraction + tracerObject % ancestorIndices(tracerObject % index_mobileFraction+ iBioLayer - 1,2) = 0 + retentionTime(iBioLayer) = 1.0_RKIND + releaseTime(iBioLayer) = 1.0_RKIND + + if (BGCTracerType(iBioLayer) >= 0.0_RKIND .and. BGCTracerType(iBioLayer) < 0.5_RKIND) then + retentionTime(iBioLayer) = config_rapid_mobile_to_stationary_time + releaseTime(iBioLayer) = config_long_mobile_to_stationary_time + initialMobileFraction(iBioLayer) = 1.0_RKIND + elseif (BGCTracerType(iBioLayer) >= 0.5_RKIND .and. BGCTracerType(iBioLayer) < 1.0_RKIND) then + retentionTime(iBioLayer) = config_rapid_mobile_to_stationary_time + releaseTime(iBioLayer) = config_rapid_mobile_to_stationary_time + initialMobileFraction(iBioLayer) = 1.0_RKIND + elseif (BGCTracerType(iBioLayer) >= 1.0_RKIND .and. BGCTracerType(iBioLayer) < 2.0_RKIND) then + retentionTime(iBioLayer) = config_long_mobile_to_stationary_time + releaseTime(iBioLayer) = config_rapid_mobile_to_stationary_time + initialMobileFraction(iBioLayer) = 1.0_RKIND + elseif (BGCTracerType(iBioLayer) >= 2.0_RKIND ) then + retentionTime(iBioLayer) = config_long_mobile_to_stationary_time + releaseTime(iBioLayer) = config_long_mobile_to_stationary_time + initialMobileFraction(iBioLayer) = 1.0_RKIND + endif + enddo + endif + + endif ! config_use_vertical_tracers + + do iBioLayer = 1, tracerObject % nBioTracers + newIceBGCFraction(iBioLayer) = config_fraction_biotracer_in_frazil + if (BGCTracerType(iBioLayer) < 0.0_RKIND) & + newIceBGCFraction(iBioLayer) = config_new_ice_fraction_biotracer + enddo + + if (.NOT.config_use_shortwave_bioabsorption) tracerObject % nBioTracersShortwave = 1 + + !----------------------------------------------------------------- + ! final consistency checks + !----------------------------------------------------------------- + + if (tracerObject % nBioTracers > nZBGCTracers) then + call mpas_log_write(& + "init_zbgc_tracer_indices: nBioTracers $i, greater than max nZBGCTracers: $i", & + messageType=MPAS_LOG_CRIT, intArgs=(/tracerObject % nBioTracers, nZBGCTracers/)) + endif + + deallocate(algalType) + deallocate(docType) + deallocate(dicType) + deallocate(donType) + deallocate(fedType) + deallocate(fepType) + deallocate(zAeroType) + + end subroutine init_zbgc_tracer_indices + +!||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||| +! +! init_bgc_tracer_indices +! +!> \brief +!> \author Nicole Jeffery, LANL +!> \date 24 May 2024 +!> \details +!> +!> Moves icepack_init_bgc_trcr to the interface +! +!----------------------------------------------------------------------- + + subroutine init_bgc_tracer_indices( nCount, iBrineFraction, & + iBGCConc, iBGCConcLayer, & + BGCType, nTracerDepend, & + nTracers, nBioTracers, & + BGCTracerType, parentIndexBGC, & + firstAncestorMaskBGC, & + ancestorNumberBGC, & + ancestorIndicesBGC, & + layerIndexToBioIndex) + + integer, intent(in) :: & + nCount , & ! counter + nTracerDepend , & ! tracer dependency index + iBrineFraction + + integer, intent(inout) :: & + nTracers , & ! number of tracers + nBioTracers , & ! number of bio tracers + iBGCConc , & ! tracer index + iBGCConcLayer ! bio tracer index + + integer, dimension(:), intent(inout) :: & + parentIndexBGC , & ! tracer dependencies + ancestorNumberBGC, & ! number of underlying tracer layers + layerIndexToBioIndex + + integer, dimension(:,:), intent(inout) :: & + ancestorIndicesBGC ! indices of underlying tracer layers + + real (kind=RKIND), dimension(:,:), intent(inout) :: & + firstAncestorMaskBGC ! = 0 or 1 depending on tracer dependency + ! argument 2: (1) aice, (2) vice, (3) vsno + + real (kind=RKIND), intent(in) :: & + BGCType ! bio tracer transport type (mobile vs stationary) + + real (kind=RKIND), dimension(:), intent(inout) :: & + BGCTracerType ! bio tracer transport type array + + ! local variables + + integer :: & + iCount , & ! loop index + nTemp , & ! temporary values + ancestorIndicesBGC1, & ! temporary values + ancestorIndicesBGC2 + + real (kind=RKIND) :: & + firstAncestorMaskBGC1, & ! temporary values + firstAncestorMaskBGC2, & + firstAncestorMaskBGC3 + + iBGCConc = nTracers + 1 + nBioTracers = nBioTracers + 1 + iBGCConcLayer = nBioTracers + BGCTracerType(nBioTracers) = BGCType + + if (nCount > 1) then + ! include vertical bgc in snow + do iCount = nCount, nCount+1 + nTracers = nTracers + 1 + parentIndexBGC (iBGCConc + iCount ) = 2 ! snow volume + firstAncestorMaskBGC (iBGCConc + iCount,1) = 0.0_RKIND + firstAncestorMaskBGC (iBGCConc + iCount,2) = 0.0_RKIND + firstAncestorMaskBGC (iBGCConc + iCount,3) = 1.0_RKIND + ancestorNumberBGC(iBGCConc + iCount ) = 0 + ancestorIndicesBGC (iBGCConc + iCount,1) = 0 + ancestorIndicesBGC (iBGCConc + iCount,2) = 0 + enddo + + firstAncestorMaskBGC1 = 0.0_RKIND + firstAncestorMaskBGC2 = 1.0_RKIND + firstAncestorMaskBGC3 = 0.0_RKIND + nTemp = 1 + ancestorIndicesBGC1 = iBrineFraction + ancestorIndicesBGC2 = 0 + else ! nCount = 1 + firstAncestorMaskBGC1 = 1.0_RKIND + firstAncestorMaskBGC2 = 0.0_RKIND + firstAncestorMaskBGC3 = 0.0_RKIND + nTemp = 0 + ancestorIndicesBGC1 = 0 + ancestorIndicesBGC2 = 0 + endif ! nCount + + do iCount = 1, nCount !in ice + nTracers = nTracers + 1 + parentIndexBGC (iBGCConc + iCount - 1 ) = nTracerDepend + firstAncestorMaskBGC (iBGCConc + iCount - 1,1) = firstAncestorMaskBGC1 + firstAncestorMaskBGC (iBGCConc + iCount - 1,2) = firstAncestorMaskBGC2 + firstAncestorMaskBGC (iBGCConc + iCount - 1,3) = firstAncestorMaskBGC3 + ancestorNumberBGC(iBGCConc + iCount - 1 ) = nTemp + ancestorIndicesBGC (iBGCConc + iCount - 1,1) = ancestorIndicesBGC1 + ancestorIndicesBGC (iBGCConc + iCount - 1,2) = ancestorIndicesBGC2 + enddo + + layerIndexToBioIndex (iBGCConcLayer) = iBGCConc + + end subroutine init_bgc_tracer_indices + !||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||| ! ! init_column_biogeochemistry @@ -13917,10 +14686,10 @@ subroutine seaice_icepack_reinitialize_diagnostics_thermodynamics(domain) pondFreshWaterFlux(:) = 0.0_RKIND - !fresh_ai (:,:,:) = c0 - !fsalt_ai (:,:,:) = c0 - !fhocn_ai (:,:,:) = c0 - !fswthru_ai(:,:,:) = c0 + !fresh_ai (:,:,:) = 0.0_RKIND + !fsalt_ai (:,:,:) = 0.0_RKIND + !fhocn_ai (:,:,:) = 0.0_RKIND + !fswthru_ai(:,:,:) = 0.0_RKIND ! shortwave call MPAS_pool_get_subpool(block % structs, "shortwave", shortwavePool) From f835a2c3c157223b1299e93e04503dfa876e99f4 Mon Sep 17 00:00:00 2001 From: daleihao Date: Tue, 28 May 2024 12:31:54 -0700 Subject: [PATCH 153/451] use std_elev when stdev_elev is not available in fsurdata & remove latitude limit fix a small bug --- components/elm/src/biogeophys/SurfaceAlbedoMod.F90 | 2 +- components/elm/src/main/surfrdMod.F90 | 7 ++++++- 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/components/elm/src/biogeophys/SurfaceAlbedoMod.F90 b/components/elm/src/biogeophys/SurfaceAlbedoMod.F90 index 073c836c19bc..49c6d061d3d8 100644 --- a/components/elm/src/biogeophys/SurfaceAlbedoMod.F90 +++ b/components/elm/src/biogeophys/SurfaceAlbedoMod.F90 @@ -1811,7 +1811,7 @@ subroutine Albedo_TOP_Adjustment(bounds, num_pft, filter_pft, & lon_180 = lon(g) if (lon_180 > pi) lon_180 = lon_180-2._r8*pi - if (cosz > 0._r8 .and. abs(lat(g)) < 1.047_r8 .and. stdev_elev(g) > 0._r8) then + if (cosz > 0._r8 .and. stdev_elev(g) > 0._r8) then local_timeofday = next_tod + lon_180 / pi * 180._r8 * 240._r8 if (local_timeofday >= 86400._r8) then diff --git a/components/elm/src/main/surfrdMod.F90 b/components/elm/src/main/surfrdMod.F90 index 9cbcd4b2b8e0..31ce8cd5b5f6 100755 --- a/components/elm/src/main/surfrdMod.F90 +++ b/components/elm/src/main/surfrdMod.F90 @@ -1702,7 +1702,12 @@ subroutine surfrd_get_topo_for_solar_rad(domain,filename) call ncd_io(ncid=ncid, varname='STDEV_ELEV', flag='read', data=domain%stdev_elev, & dim1name=grlnd, readvar=readvar) - if (.not. readvar) call endrun( trim(subname)//' ERROR: STDEV_ELEV NOT on fsurdat file' ) + if (.not. readvar) then + write(iulog,*) trim(subname),' ERROR: STDEV_ELEV NOT on fsurdat file' + call ncd_io(ncid=ncid, varname='STD_ELEV', flag='read', data=domain%stdev_elev, & + dim1name=grlnd, readvar=readvar) + if (.not. readvar) call endrun( trim(subname)//' ERROR: BOTH STD_ELEV and STDEV_ELEV NOT on fsurdat file' ) + endif call ncd_io(ncid=ncid, varname='SKY_VIEW', flag='read', data=domain%sky_view, & dim1name=grlnd, readvar=readvar) if (.not. readvar) call endrun( trim(subname)//' ERROR: SKY_VIEW NOT on fsurdat file' ) From e4b362d0269854dd5537e935cf2d94fdf1ac8a1b Mon Sep 17 00:00:00 2001 From: Dalei Hao Date: Tue, 28 May 2024 14:48:55 -0700 Subject: [PATCH 154/451] modidy error message --- components/elm/src/main/surfrdMod.F90 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/components/elm/src/main/surfrdMod.F90 b/components/elm/src/main/surfrdMod.F90 index 31ce8cd5b5f6..43bb7965314a 100755 --- a/components/elm/src/main/surfrdMod.F90 +++ b/components/elm/src/main/surfrdMod.F90 @@ -1703,7 +1703,7 @@ subroutine surfrd_get_topo_for_solar_rad(domain,filename) call ncd_io(ncid=ncid, varname='STDEV_ELEV', flag='read', data=domain%stdev_elev, & dim1name=grlnd, readvar=readvar) if (.not. readvar) then - write(iulog,*) trim(subname),' ERROR: STDEV_ELEV NOT on fsurdat file' + write(iulog,*) trim(subname),' WARNING: STDEV_ELEV NOT on fsurdat file. Try to use STD_ELEV instead.' call ncd_io(ncid=ncid, varname='STD_ELEV', flag='read', data=domain%stdev_elev, & dim1name=grlnd, readvar=readvar) if (.not. readvar) call endrun( trim(subname)//' ERROR: BOTH STD_ELEV and STDEV_ELEV NOT on fsurdat file' ) From c54c6db758cf9e6cae0e25974c91f4c9335035c5 Mon Sep 17 00:00:00 2001 From: Alexander Hager Date: Tue, 21 May 2024 07:57:54 -0600 Subject: [PATCH 155/451] Default waterThickness/Min. effectConducEdge limit Establishes a default waterThickness to be imposed as an initial condition if no waterThickness variable exists. Forces effectiveConducEdge to zero if below 1e-30 to avoid too small of diffusivity/waterVelocity values. --- .../mpas-albany-landice/src/Registry_subglacial_hydro.xml | 2 +- .../src/mode_forward/mpas_li_subglacial_hydro.F | 5 +++++ 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/components/mpas-albany-landice/src/Registry_subglacial_hydro.xml b/components/mpas-albany-landice/src/Registry_subglacial_hydro.xml index fdc4cd0b3878..8b3f07d4750f 100644 --- a/components/mpas-albany-landice/src/Registry_subglacial_hydro.xml +++ b/components/mpas-albany-landice/src/Registry_subglacial_hydro.xml @@ -152,7 +152,7 @@ - diff --git a/components/mpas-albany-landice/src/mode_forward/mpas_li_subglacial_hydro.F b/components/mpas-albany-landice/src/mode_forward/mpas_li_subglacial_hydro.F index 344459dae958..26c33ea28498 100644 --- a/components/mpas-albany-landice/src/mode_forward/mpas_li_subglacial_hydro.F +++ b/components/mpas-albany-landice/src/mode_forward/mpas_li_subglacial_hydro.F @@ -845,6 +845,7 @@ subroutine calc_edge_quantities(block, err) integer :: i, j, iVertex, iCell real (kind=RKIND) :: velSign integer :: numGroundedCells + real(kind=RKIND), parameter :: SMALL_CONDUC = 1.0e-30_RKIND integer :: err_tmp err = 0 @@ -1079,6 +1080,10 @@ subroutine calc_edge_quantities(block, err) enddo endif + where (effectiveConducEdge < SMALL_CONDUC) + effectiveConducEdge = 0.0_RKIND + end where + ! calculate diffusivity on edges diffusivity(:) = rho_water * gravity * effectiveConducEdge(:) * waterThicknessEdge(:) From 8628e1a38c70fd5819b696c235e0bcc22fbc132a Mon Sep 17 00:00:00 2001 From: Alexander Hager Date: Tue, 28 May 2024 07:40:46 -0600 Subject: [PATCH 156/451] Fix typo in PR #106 Fixes typo in PR #106 that accidentally got merged. --- .../src/mode_forward/mpas_li_subglacial_hydro.F | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/components/mpas-albany-landice/src/mode_forward/mpas_li_subglacial_hydro.F b/components/mpas-albany-landice/src/mode_forward/mpas_li_subglacial_hydro.F index 26c33ea28498..b722459761eb 100644 --- a/components/mpas-albany-landice/src/mode_forward/mpas_li_subglacial_hydro.F +++ b/components/mpas-albany-landice/src/mode_forward/mpas_li_subglacial_hydro.F @@ -2225,7 +2225,7 @@ subroutine ocean_connection_N(domain) call mpas_pool_get_subpool(block % structs, 'hydro', hydroPool) call mpas_pool_get_array(geometryPool, 'bedTopography', bedTopography) call mpas_pool_get_array(hydroPool, 'effectivePressure', effectivePressure) - call mpas_pool_get_array(hydroPool, 'iceThicknessHydro', thickness) + call mpas_pool_get_array(hydroPool, 'thickness', thickness) effectivePressure = rhoi * gravity * thickness - rhoi * gravity * max(0.0_RKIND, -1.0_RKIND * rhoo/rhoi * bedTopography) effectivePressure = max(effectivePressure, 0.0_RKIND) ! This is just to zero out N in the open ocean to avoid confusion From 73788b9a9d07a6758eb2307ba007ed6f93b07981 Mon Sep 17 00:00:00 2001 From: Nicole Jeffery Date: Fri, 31 May 2024 10:48:15 -0500 Subject: [PATCH 157/451] Updates .gitmodules to zbgc-enabled icepack submodule branch --- .gitmodules | 1 + 1 file changed, 1 insertion(+) diff --git a/.gitmodules b/.gitmodules index 69d56e140361..c9d0b3dbad9f 100644 --- a/.gitmodules +++ b/.gitmodules @@ -76,6 +76,7 @@ [submodule "components/mpas-seaice/src/icepack"] path = components/mpas-seaice/src/icepack url = git@github.com:E3SM-Project/Icepack.git + branch = fixes-to-bgc-indices [submodule "externals/haero"] path = externals/haero url = git@github.com:eagles-project/haero.git From 393d0ed31f0ee64074949f47a137a03d88d510e4 Mon Sep 17 00:00:00 2001 From: Nicole Jeffery Date: Fri, 31 May 2024 11:09:38 -0500 Subject: [PATCH 158/451] Reverts the previous commit --- .gitmodules | 1 - 1 file changed, 1 deletion(-) diff --git a/.gitmodules b/.gitmodules index c9d0b3dbad9f..69d56e140361 100644 --- a/.gitmodules +++ b/.gitmodules @@ -76,7 +76,6 @@ [submodule "components/mpas-seaice/src/icepack"] path = components/mpas-seaice/src/icepack url = git@github.com:E3SM-Project/Icepack.git - branch = fixes-to-bgc-indices [submodule "externals/haero"] path = externals/haero url = git@github.com:eagles-project/haero.git From 4873471b6aba3aceff6c808433a5e0d72b71486b Mon Sep 17 00:00:00 2001 From: Nicole Jeffery Date: Fri, 31 May 2024 12:08:35 -0500 Subject: [PATCH 159/451] Updating Icepack to hash #2e5d5a27 For BGC --- components/mpas-seaice/src/icepack | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/components/mpas-seaice/src/icepack b/components/mpas-seaice/src/icepack index abdd3d4bbc06..2e5d5a271baf 160000 --- a/components/mpas-seaice/src/icepack +++ b/components/mpas-seaice/src/icepack @@ -1 +1 @@ -Subproject commit abdd3d4bbc06255a3cdcff2d5c04ede90050eb51 +Subproject commit 2e5d5a271baf5d0705be76ac56fa588c9d7e252c From e6e4fb7bb4d1bccfd65e096c31edc3a4b28500b1 Mon Sep 17 00:00:00 2001 From: Walter Hannah Date: Thu, 6 Jun 2024 15:39:18 -0400 Subject: [PATCH 160/451] remove line --- components/eam/src/physics/crm/pam/pam_state.h | 1 - 1 file changed, 1 deletion(-) diff --git a/components/eam/src/physics/crm/pam/pam_state.h b/components/eam/src/physics/crm/pam/pam_state.h index 270fef7f6c23..980fb7f4eb0a 100644 --- a/components/eam/src/physics/crm/pam/pam_state.h +++ b/components/eam/src/physics/crm/pam/pam_state.h @@ -156,7 +156,6 @@ inline void pam_state_set_reference_state( pam::PamCoupler &coupler ) { parallel_for(SimpleBounds<2>(nz+1,nens), YAKL_LAMBDA (int k, int iens) { hmean_pint(k,iens) = 0; if (k < nz) { - hmean_pmid (k,iens) = 0; hmean_rho_d(k,iens) = 0; hmean_rho_v(k,iens) = 0; hmean_rho_c(k,iens) = 0; From 30faaba50681d0821a80ccb9b5592c9d81b6074e Mon Sep 17 00:00:00 2001 From: Walter Hannah Date: Thu, 6 Jun 2024 15:39:41 -0400 Subject: [PATCH 161/451] make variables const --- .../eam/src/physics/crm/pam/pam_variance_transport.h | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/components/eam/src/physics/crm/pam/pam_variance_transport.h b/components/eam/src/physics/crm/pam/pam_variance_transport.h index 1eb7779f3469..70b985cc2b7b 100644 --- a/components/eam/src/physics/crm/pam/pam_variance_transport.h +++ b/components/eam/src/physics/crm/pam/pam_variance_transport.h @@ -36,11 +36,11 @@ inline void pam_variance_transport_diagnose( pam::PamCoupler &coupler ) { auto ny = coupler.get_option("crm_ny"); auto nx = coupler.get_option("crm_nx"); //------------------------------------------------------------------------------------------------ - auto temp = dm_device.get("temp" ); - auto rhov = dm_device.get("water_vapor"); - auto rhoc = dm_device.get("cloud_water"); - auto rhoi = dm_device.get("ice" ); - auto uvel = dm_device.get("uvel" ); + auto temp = dm_device.get("temp" ); + auto rhov = dm_device.get("water_vapor"); + auto rhoc = dm_device.get("cloud_water"); + auto rhoi = dm_device.get("ice" ); + auto uvel = dm_device.get("uvel" ); auto vt_temp = dm_device.get("vt_temp" ); auto vt_rhov = dm_device.get("vt_rhov" ); auto vt_uvel = dm_device.get("vt_uvel" ); From f9e6cc20fbe98699adcbae004932871bf198c943 Mon Sep 17 00:00:00 2001 From: Walter Hannah Date: Thu, 6 Jun 2024 15:40:13 -0400 Subject: [PATCH 162/451] switch to std::abs --- components/eam/src/physics/crm/pam/pam_driver.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/components/eam/src/physics/crm/pam/pam_driver.cpp b/components/eam/src/physics/crm/pam/pam_driver.cpp index f8f575ec8a1d..bed8980ea67d 100644 --- a/components/eam/src/physics/crm/pam/pam_driver.cpp +++ b/components/eam/src/physics/crm/pam/pam_driver.cpp @@ -61,8 +61,8 @@ inline int pam_driver_set_subcycle_timestep( pam::PamCoupler &coupler, real crm_ }); // calculate max U and W parallel_for( SimpleBounds<4>(crm_nz,crm_ny,crm_nx,nens) , YAKL_LAMBDA (int k, int j, int i, int n) { - yakl::atomicMax(uvel_max(k,n), sqrt(uvel(k,j,i,n)*uvel(k,j,i,n)) ); - yakl::atomicMax(wvel_max(k,n), fabs(wvel(k,j,i,n)) ); + yakl::atomicMax(uvel_max(k,n), std::abs(uvel(k,j,i,n)) ); + yakl::atomicMax(wvel_max(k,n), std::abs(wvel(k,j,i,n)) ); }); // find max CFL between horizontal and vertical CFL values parallel_for( SimpleBounds<2>(crm_nz,nens) , YAKL_LAMBDA (int k, int n) { From 2590f226f43c316ecb224649c00e597a7dce8b43 Mon Sep 17 00:00:00 2001 From: Walter Hannah Date: Thu, 6 Jun 2024 15:42:58 -0400 Subject: [PATCH 163/451] remove pmax --- components/eam/src/physics/crm/pam/pam_driver.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/components/eam/src/physics/crm/pam/pam_driver.cpp b/components/eam/src/physics/crm/pam/pam_driver.cpp index bed8980ea67d..5fd1c5071d16 100644 --- a/components/eam/src/physics/crm/pam/pam_driver.cpp +++ b/components/eam/src/physics/crm/pam/pam_driver.cpp @@ -73,7 +73,7 @@ inline int pam_driver_set_subcycle_timestep( pam::PamCoupler &coupler, real crm_ cfl_max(k,n) = max(cfl_u,cfl_w); }); // calculate final CFL across ensemble - real cfl_loc = pmax(cfl_max.data()); + real cfl_loc = yakl::intrinsics::maxval(cfl_max); cfl = max(cfl,cfl_loc); // update number of subcycles and time step num_subcycle = max(num_subcycle,max(1,static_cast(ceil(cfl/0.7)))); From 2bd7c2af49666895bef1cb804ea54d30c5c02c47 Mon Sep 17 00:00:00 2001 From: Nicole Jeffery Date: Mon, 10 Jun 2024 13:55:01 -0500 Subject: [PATCH 164/451] Fix to using zaerosols without bgc -Shortened registry description for ocean bgc concentrations -Corrected some unit descriptions -Clean-up in mpas_seaice_icepack bugfix (BFB without bgc/zaerosols) --- components/mpas-seaice/driver/ice_comp_mct.F | 150 ++++++++++-------- components/mpas-seaice/src/Registry.xml | 16 +- components/mpas-seaice/src/icepack | 2 +- .../src/shared/mpas_seaice_constants.F | 2 +- .../src/shared/mpas_seaice_icepack.F | 113 +++---------- .../src/shared/mpas_seaice_initialize.F | 8 +- 6 files changed, 117 insertions(+), 174 deletions(-) diff --git a/components/mpas-seaice/driver/ice_comp_mct.F b/components/mpas-seaice/driver/ice_comp_mct.F index 50bf12ece375..3c579aee77af 100644 --- a/components/mpas-seaice/driver/ice_comp_mct.F +++ b/components/mpas-seaice/driver/ice_comp_mct.F @@ -2116,7 +2116,6 @@ subroutine ice_import_mct(x2i_i, errorCode)!{{{ call mpas_pool_get_subpool(block_ptr % structs, 'biogeochemistry', biogeochemistry) if (config_use_zaerosols) then - call mpas_pool_get_array(biogeochemistry, 'oceanZAerosolConc', oceanZAerosolConc) call mpas_pool_get_array(biogeochemistry, 'atmosBlackCarbonFlux', atmosBlackCarbonFlux) call mpas_pool_get_array(biogeochemistry, 'atmosDustFlux', atmosDustFlux) call mpas_pool_get_array(biogeochemistry, "atmosWetDustFlux", atmosWetDustFlux) @@ -2232,13 +2231,16 @@ subroutine ice_import_mct(x2i_i, errorCode)!{{{ endif ! set aerosols, if configured - if (config_use_zaerosols) then + if (config_use_zaerosols .or. config_use_column_biogeochemistry) then + call mpas_pool_get_array(biogeochemistry, 'oceanZAerosolConc', oceanZAerosolConc) oceanZAerosolConc(1,i) = 0.0_RKIND !x2i_i % rAttr(index_x2i_So_zaer1, n) oceanZAerosolConc(2,i) = 0.0_RKIND !x2i_i % rAttr(index_x2i_So_zaer2, n) oceanZAerosolConc(3,i) = 0.0_RKIND !x2i_i % rAttr(index_x2i_So_zaer3, n) oceanZAerosolConc(4,i) = 0.0_RKIND !x2i_i % rAttr(index_x2i_So_zaer4, n) oceanZAerosolConc(5,i) = 0.0_RKIND !x2i_i % rAttr(index_x2i_So_zaer5, n) oceanZAerosolConc(6,i) = 0.0_RKIND !x2i_i % rAttr(index_x2i_So_zaer6, n) + end if + if (config_use_zaerosols) then if (config_use_modal_aerosols) then atmosBlackCarbonFlux(1,i) = x2i_i % rAttr(index_x2i_Faxa_bcphodry, n) & + x2i_i % rAttr(index_x2i_Faxa_bcphidry, n) @@ -2370,12 +2372,14 @@ subroutine ice_import_mct(x2i_i, errorCode)!{{{ call mpas_pool_get_field(aerosols, "atmosAerosolFlux", atmosAerosolFluxField) endif + if (config_use_zaerosols .or. config_use_column_biogeochemistry) & + call mpas_pool_get_field(biogeochemistry, 'oceanZAerosolConc', oceanZAerosolConcField) + if (config_use_zaerosols) then call mpas_pool_get_field(biogeochemistry, "atmosBlackCarbonFlux", atmosBlackCarbonFluxField) call mpas_pool_get_field(biogeochemistry, "atmosDustFlux", atmosDustFluxField) call mpas_pool_get_field(biogeochemistry, "atmosWetDustFlux", atmosWetDustFluxField) call mpas_pool_get_field(biogeochemistry, "atmosDryDustFlux", atmosDryDustFluxField) - call mpas_pool_get_field(biogeochemistry, 'oceanZAerosolConc', oceanZAerosolConcField) endif if (config_use_column_biogeochemistry .and. config_couple_biogeochemistry_fields) then call mpas_pool_get_subpool(domain % blocklist % structs, 'biogeochemistry', biogeochemistry) @@ -2422,12 +2426,14 @@ subroutine ice_import_mct(x2i_i, errorCode)!{{{ if (config_use_aerosols) then call mpas_dmpar_exch_halo_field(atmosAerosolFluxField) endif + if (config_use_zaerosols .or. config_use_column_biogeochemistry) & + call mpas_dmpar_exch_halo_field(oceanZAerosolConcField) + if (config_use_zaerosols) then call mpas_dmpar_exch_halo_field(atmosBlackCarbonFluxField) call mpas_dmpar_exch_halo_field(atmosDustFluxField) call mpas_dmpar_exch_halo_field(atmosDryDustFluxField) call mpas_dmpar_exch_halo_field(atmosWetDustFluxField) - call mpas_dmpar_exch_halo_field(oceanZAerosolConcField) endif if (config_use_column_biogeochemistry .and. config_couple_biogeochemistry_fields) then call mpas_dmpar_exch_halo_field(oceanAlgaeConcField) @@ -3752,9 +3758,7 @@ subroutine ice_import_moab(Eclock)!{{{ endif if (config_use_column_biogeochemistry) then - call mpas_pool_get_config(configs, "config_use_zaerosols", config_use_zaerosols) call mpas_pool_get_subpool(block_ptr % structs, 'biogeochemistry', biogeochemistry) - call mpas_pool_get_array(biogeochemistry, 'oceanAlgaeConc', oceanAlgaeConc) call mpas_pool_get_array(biogeochemistry, 'oceanDOCConc', oceanDOCConc) call mpas_pool_get_array(biogeochemistry, 'oceanDICConc', oceanDICConc) @@ -3767,16 +3771,19 @@ subroutine ice_import_moab(Eclock)!{{{ call mpas_pool_get_array(biogeochemistry, 'oceanHumicsConc', oceanHumicsConc) call mpas_pool_get_array(biogeochemistry, 'oceanParticulateIronConc', oceanParticulateIronConc) call mpas_pool_get_array(biogeochemistry, 'oceanDissolvedIronConc', oceanDissolvedIronConc) - call mpas_pool_get_array(biogeochemistry, 'oceanZAerosolConc', oceanZAerosolConc) call mpas_pool_get_array(biogeochemistry, 'carbonToNitrogenRatioAlgae', carbonToNitrogenRatioAlgae) call mpas_pool_get_array(biogeochemistry, 'carbonToNitrogenRatioDON', carbonToNitrogenRatioDON) + endif + + call mpas_pool_get_config(configs, "config_use_zaerosols", config_use_zaerosols) if (config_use_zaerosols) then call mpas_pool_get_array(biogeochemistry, "atmosBlackCarbonFlux", atmosBlackCarbonFlux) call mpas_pool_get_array(biogeochemistry, "atmosDustFlux", atmosDustFlux) call mpas_pool_get_array(biogeochemistry, "atmosWetDustFlux", atmosWetDustFlux) call mpas_pool_get_array(biogeochemistry, "atmosDryDustFlux", atmosDryDustFlux) endif - endif + if (config_use_column_biogeochemistry .or. config_use_zaerosols) & + call mpas_pool_get_array(biogeochemistry, 'oceanZAerosolConc', oceanZAerosolConc) do i = 1, nCellsSolve n = n + 1 @@ -3883,65 +3890,67 @@ subroutine ice_import_moab(Eclock)!{{{ oceanParticulateIronConc(2,i) = x2i_im(n,index_x2i_So_fep2) oceanDissolvedIronConc(1,i) = x2i_im(n,index_x2i_So_fed1) oceanDissolvedIronConc(2,i) = x2i_im(n,index_x2i_So_fed2) + endif + if (config_use_zaerosols .or. config_use_column_biogeochemistry) then oceanZAerosolConc(1,i) = 0.0_RKIND oceanZAerosolConc(2,i) = 0.0_RKIND oceanZAerosolConc(3,i) = 0.0_RKIND oceanZAerosolConc(4,i) = 0.0_RKIND oceanZAerosolConc(5,i) = 0.0_RKIND oceanZAerosolConc(6,i) = 0.0_RKIND - ! set aerosols, if configured - if (config_use_zaerosols) then - if (config_use_modal_aerosols) then - atmosBlackCarbonFlux(1,i) = x2i_im(n,index_x2i_Faxa_bcphodry) & - + x2i_im(n,index_x2i_Faxa_bcphidry) - atmosBlackCarbonFlux(2,i) = x2i_im(n,index_x2i_Faxa_bcphiwet) - ! combine wet and dry dust - atmosDustFlux(1,i) = x2i_im(n,index_x2i_Faxa_dstwet1) & - + x2i_im(n,index_x2i_Faxa_dstdry1) - atmosDustFlux(2,i) = x2i_im(n,index_x2i_Faxa_dstwet2) & - + x2i_im(n,index_x2i_Faxa_dstdry2) - atmosDustFlux(3,i) = x2i_im(n,index_x2i_Faxa_dstwet3) & - + x2i_im(n,index_x2i_Faxa_dstdry3) - atmosDustFlux(4,i) = x2i_im(n,index_x2i_Faxa_dstwet4) & - + x2i_im(n,index_x2i_Faxa_dstdry4) - - ! wet dust - atmosWetDustFlux(1,i) = x2i_im(n,index_x2i_Faxa_dstwet1) - atmosWetDustFlux(2,i) = x2i_im(n,index_x2i_Faxa_dstwet2) - atmosWetDustFlux(3,i) = x2i_im(n,index_x2i_Faxa_dstwet3) - atmosWetDustFlux(4,i) = x2i_im(n,index_x2i_Faxa_dstwet4) - - ! dry dust - atmosDryDustFlux(1,i) = x2i_im(n,index_x2i_Faxa_dstdry1) - atmosDryDustFlux(2,i) = x2i_im(n,index_x2i_Faxa_dstdry2) - atmosDryDustFlux(3,i) = x2i_im(n,index_x2i_Faxa_dstdry3) - atmosDryDustFlux(4,i) = x2i_im(n,index_x2i_Faxa_dstdry4) - else - atmosBlackCarbonFlux(1,i) = x2i_im(n,index_x2i_Faxa_bcphodry) - atmosBlackCarbonFlux(2,i) = x2i_im(n,index_x2i_Faxa_bcphidry) & - + x2i_im(n,index_x2i_Faxa_bcphiwet) - ! combine wet and dry dust - atmosDustFlux(1,i) = x2i_im(n,index_x2i_Faxa_dstwet1) & - + x2i_im(n,index_x2i_Faxa_dstdry1) - atmosDustFlux(2,i) = x2i_im(n,index_x2i_Faxa_dstwet2) & - + x2i_im(n,index_x2i_Faxa_dstdry2) - atmosDustFlux(3,i) = x2i_im(n,index_x2i_Faxa_dstwet3) & - + x2i_im(n,index_x2i_Faxa_dstdry3) - atmosDustFlux(4,i) = x2i_im(n,index_x2i_Faxa_dstwet4) & - + x2i_im(n,index_x2i_Faxa_dstdry4) - - ! wet dust - atmosWetDustFlux(1,i) = x2i_im(n,index_x2i_Faxa_dstwet1) - atmosWetDustFlux(2,i) = x2i_im(n,index_x2i_Faxa_dstwet2) - atmosWetDustFlux(3,i) = x2i_im(n,index_x2i_Faxa_dstwet3) - atmosWetDustFlux(4,i) = x2i_im(n,index_x2i_Faxa_dstwet4) - - ! dry dust - atmosDryDustFlux(1,i) = x2i_im(n,index_x2i_Faxa_dstdry1) - atmosDryDustFlux(2,i) = x2i_im(n,index_x2i_Faxa_dstdry2) - atmosDryDustFlux(3,i) = x2i_im(n,index_x2i_Faxa_dstdry3) - atmosDryDustFlux(4,i) = x2i_im(n,index_x2i_Faxa_dstdry4) - endif + end if + ! set zaerosols, if configured + if (config_use_zaerosols) then + if (config_use_modal_aerosols) then + atmosBlackCarbonFlux(1,i) = x2i_im(n,index_x2i_Faxa_bcphodry) & + + x2i_im(n,index_x2i_Faxa_bcphidry) + atmosBlackCarbonFlux(2,i) = x2i_im(n,index_x2i_Faxa_bcphiwet) + ! combine wet and dry dust + atmosDustFlux(1,i) = x2i_im(n,index_x2i_Faxa_dstwet1) & + + x2i_im(n,index_x2i_Faxa_dstdry1) + atmosDustFlux(2,i) = x2i_im(n,index_x2i_Faxa_dstwet2) & + + x2i_im(n,index_x2i_Faxa_dstdry2) + atmosDustFlux(3,i) = x2i_im(n,index_x2i_Faxa_dstwet3) & + + x2i_im(n,index_x2i_Faxa_dstdry3) + atmosDustFlux(4,i) = x2i_im(n,index_x2i_Faxa_dstwet4) & + + x2i_im(n,index_x2i_Faxa_dstdry4) + + ! wet dust + atmosWetDustFlux(1,i) = x2i_im(n,index_x2i_Faxa_dstwet1) + atmosWetDustFlux(2,i) = x2i_im(n,index_x2i_Faxa_dstwet2) + atmosWetDustFlux(3,i) = x2i_im(n,index_x2i_Faxa_dstwet3) + atmosWetDustFlux(4,i) = x2i_im(n,index_x2i_Faxa_dstwet4) + + ! dry dust + atmosDryDustFlux(1,i) = x2i_im(n,index_x2i_Faxa_dstdry1) + atmosDryDustFlux(2,i) = x2i_im(n,index_x2i_Faxa_dstdry2) + atmosDryDustFlux(3,i) = x2i_im(n,index_x2i_Faxa_dstdry3) + atmosDryDustFlux(4,i) = x2i_im(n,index_x2i_Faxa_dstdry4) + else + atmosBlackCarbonFlux(1,i) = x2i_im(n,index_x2i_Faxa_bcphodry) + atmosBlackCarbonFlux(2,i) = x2i_im(n,index_x2i_Faxa_bcphidry) & + + x2i_im(n,index_x2i_Faxa_bcphiwet) + ! combine wet and dry dust + atmosDustFlux(1,i) = x2i_im(n,index_x2i_Faxa_dstwet1) & + + x2i_im(n,index_x2i_Faxa_dstdry1) + atmosDustFlux(2,i) = x2i_im(n,index_x2i_Faxa_dstwet2) & + + x2i_im(n,index_x2i_Faxa_dstdry2) + atmosDustFlux(3,i) = x2i_im(n,index_x2i_Faxa_dstwet3) & + + x2i_im(n,index_x2i_Faxa_dstdry3) + atmosDustFlux(4,i) = x2i_im(n,index_x2i_Faxa_dstwet4) & + + x2i_im(n,index_x2i_Faxa_dstdry4) + + ! wet dust + atmosWetDustFlux(1,i) = x2i_im(n,index_x2i_Faxa_dstwet1) + atmosWetDustFlux(2,i) = x2i_im(n,index_x2i_Faxa_dstwet2) + atmosWetDustFlux(3,i) = x2i_im(n,index_x2i_Faxa_dstwet3) + atmosWetDustFlux(4,i) = x2i_im(n,index_x2i_Faxa_dstwet4) + + ! dry dust + atmosDryDustFlux(1,i) = x2i_im(n,index_x2i_Faxa_dstdry1) + atmosDryDustFlux(2,i) = x2i_im(n,index_x2i_Faxa_dstdry2) + atmosDryDustFlux(3,i) = x2i_im(n,index_x2i_Faxa_dstdry3) + atmosDryDustFlux(4,i) = x2i_im(n,index_x2i_Faxa_dstdry4) endif endif end do @@ -4020,15 +4029,15 @@ subroutine ice_import_moab(Eclock)!{{{ call mpas_pool_get_field(biogeochemistry, 'oceanHumicsConc', oceanHumicsConcField) call mpas_pool_get_field(biogeochemistry, 'oceanParticulateIronConc', oceanParticulateIronConcField) call mpas_pool_get_field(biogeochemistry, 'oceanDissolvedIronConc', oceanDissolvedIronConcField) + endif + if (config_use_zaerosols .or. config_use_column_biogeochemistry) & call mpas_pool_get_field(biogeochemistry, 'oceanZAerosolConc', oceanZAerosolConcField) - if (config_use_zaerosols) then - call mpas_pool_get_field(biogeochemistry, "atmosBlackCarbonFlux", atmosBlackCarbonFluxField) - call mpas_pool_get_field(biogeochemistry, "atmosDustFlux", atmosDustFluxField) - call mpas_pool_get_field(biogeochemistry, "atmosWetDustFlux", atmosWetDustFluxField) - call mpas_pool_get_field(biogeochemistry, "atmosDryDustFlux", atmosDryDustFluxField) - endif + if (config_use_zaerosols) then + call mpas_pool_get_field(biogeochemistry, "atmosBlackCarbonFlux", atmosBlackCarbonFluxField) + call mpas_pool_get_field(biogeochemistry, "atmosDustFlux", atmosDustFluxField) + call mpas_pool_get_field(biogeochemistry, "atmosWetDustFlux", atmosWetDustFluxField) + call mpas_pool_get_field(biogeochemistry, "atmosDryDustFlux", atmosDryDustFluxField) endif - call mpas_dmpar_exch_halo_field(seaSurfaceTemperatureField) call mpas_dmpar_exch_halo_field(seaSurfaceSalinityField) call mpas_dmpar_exch_halo_field(seaFreezingTemperatureField) @@ -4071,13 +4080,14 @@ subroutine ice_import_moab(Eclock)!{{{ call mpas_dmpar_exch_halo_field(oceanHumicsConcField) call mpas_dmpar_exch_halo_field(oceanParticulateIronConcField) call mpas_dmpar_exch_halo_field(oceanDissolvedIronConcField) + endif + if (config_use_zaerosols .or. config_use_column_biogeochemistry) & call mpas_dmpar_exch_halo_field(oceanZAerosolConcField) - if (config_use_zaerosols) then + if (config_use_zaerosols) then call mpas_dmpar_exch_halo_field(atmosBlackCarbonFluxField) call mpas_dmpar_exch_halo_field(atmosDustFluxField) call mpas_dmpar_exch_halo_field(atmosWetDustFluxField) call mpas_dmpar_exch_halo_field(atmosDryDustFluxField) - endif endif ! REVISION HISTORY: diff --git a/components/mpas-seaice/src/Registry.xml b/components/mpas-seaice/src/Registry.xml index b4ffd634bd28..22c11fe28f27 100644 --- a/components/mpas-seaice/src/Registry.xml +++ b/components/mpas-seaice/src/Registry.xml @@ -5402,7 +5402,7 @@ type="real" dimensions="nZBGCTracers nCells Time" units="mmol m-3" - description="All bio tracers including those not used in the order: diatom nitrogen, smallPlankton nitrogen, phaeocystis nitrogen, nitrate, polysaccarid carbon, lipid carbon, dissolved inorganic carbon,ammonium, silicate, DMSPp, DMSPd, DMS, Nonreactive nitrate, Protein nitrogen, dissolved iron in umol/m3, particulate iron in umol/m3, humic carbon, black carbon1 in mg/m3, black carbon2 in mg/m3,dust1 in mg/m3, dust2 in mg/m3, dust3 in mg/m3, dust4 in mg/m3" + description="All possible bio tracers in order: maxAlgaeType, nitrate, maxDOCType, maxDICType, chl (maxAlgaeType), ammonium, silicate, DMSPp, DMSPd, DMS, Nonreactive nitrate, maxDONType, dFe (maxFeType, umol/m3), pFe (maxFeType, umol/m3), maxBCType (kg/m3), maxDustType (kg/m3), humic carbon" icepack_name="ocean_bio" packages="pkgColumnBiogeochemistry;pkgColumnPackage" /> @@ -5410,7 +5410,7 @@ type="real" dimensions="nZBGCTracers nCells Time" units="mmol m-3" - description="Only bio tracers used in the order: diatom nitrogen, smallPlankton nitrogen, phaeocystis nitrogen, nitrate, polysaccarid carbon, lipid carbon,dissolved inorganic carbon, ammonium, silicate, DMSPp, DMSPd, DMS, Nonreactive nitrate, Protein nitrogen, dissolved iron in umol/m3, particulate iron in umol/m3, humic carbon, black carbon1 in mg/m3, black carbon2 in mg/m3,dust1 in mg/m3, dust2 in mg/m3, dust3 in mg/m3, dust4 in mg/m3" + description="Bio tracers used in the order of oceanBioConcentrations" icepack_name="ocean_bio" packages="pkgColumnBiogeochemistry;pkgColumnPackage" /> @@ -5418,7 +5418,7 @@ type="real" dimensions="nZBGCTracers nCells Time" units="mmol m-2" - description="Only bio tracers used and added to sea ice bottom in the order: diatom nitrogen, smallPlankton nitrogen, phaeocystis nitrogen, nitrate, polysaccarid carbon, lipid carbon, dissolved inorganic carbon,ammonium, silicate, DMSPp, DMSPd, DMS, Nonreactive nitrate, Protein nitrogen, dissolved iron in umol/m2, particulate iron in umol/m2, humic carbon, black carbon1 in mg/m2, black carbon2 in mg/m2,dust1 in mg/m2, dust2 in mg/m2, dust3 in mg/m2, dust4 in mg/m2" + description="Bio tracers used and added to sea ice bottom in the order of oceanBioConcentrations" icepack_name="ocean_bio" packages="pkgColumnBiogeochemistry;pkgColumnPackage" /> @@ -5498,7 +5498,7 @@ Date: Wed, 12 Jun 2024 16:47:00 -0500 Subject: [PATCH 165/451] Cleans redundant parameters in second call to parameter_init Also updates icepack hash to #c63f9e5 --- components/mpas-seaice/src/icepack | 2 +- .../src/shared/mpas_seaice_icepack.F | 105 ------------------ 2 files changed, 1 insertion(+), 106 deletions(-) diff --git a/components/mpas-seaice/src/icepack b/components/mpas-seaice/src/icepack index f459b0c5de3d..c63f9e5b710f 160000 --- a/components/mpas-seaice/src/icepack +++ b/components/mpas-seaice/src/icepack @@ -1 +1 @@ -Subproject commit f459b0c5de3d39b40e181ea2641ce4ac3039d329 +Subproject commit c63f9e5b710f87fd915ad0b77da19bd0a5ab6d12 diff --git a/components/mpas-seaice/src/shared/mpas_seaice_icepack.F b/components/mpas-seaice/src/shared/mpas_seaice_icepack.F index 9addef183781..933b669766c0 100644 --- a/components/mpas-seaice/src/shared/mpas_seaice_icepack.F +++ b/components/mpas-seaice/src/shared/mpas_seaice_icepack.F @@ -10103,8 +10103,6 @@ subroutine init_icepack_package_configs(domain) config_biogrid_bottom_molecular_sublayer, & config_bio_gravity_drainage_length_scale, & config_biogrid_top_molecular_sublayer, & - config_new_ice_fraction_biotracer, & - config_fraction_biotracer_in_frazil, & config_snow_porosity_at_ice_surface, & config_ratio_Si_to_N_diatoms, & config_ratio_Si_to_N_small_plankton, & @@ -10122,8 +10120,6 @@ subroutine init_icepack_package_configs(domain) config_ratio_Fe_to_DOC_saccharids, & config_ratio_Fe_to_DOC_lipids, & config_respiration_fraction_of_growth, & - config_rapid_mobile_to_stationary_time, & - config_long_mobile_to_stationary_time, & config_algal_maximum_velocity, & config_ratio_Fe_to_dust, & config_solubility_of_Fe_in_dust, & @@ -10190,37 +10186,6 @@ subroutine init_icepack_package_configs(domain) config_DMSP_to_DMS_conversion_fraction, & config_DMSP_to_DMS_conversion_time, & config_DMS_oxidation_time, & - config_mobility_type_diatoms, & - config_mobility_type_small_plankton, & - config_mobility_type_phaeocystis, & - config_mobility_type_nitrate, & - config_mobility_type_ammonium, & - config_mobility_type_silicate, & - config_mobility_type_DMSPp, & - config_mobility_type_DMSPd, & - config_mobility_type_humics, & - config_mobility_type_saccharids, & - config_mobility_type_lipids, & - config_mobility_type_inorganic_carbon, & - config_mobility_type_proteins, & - config_mobility_type_dissolved_iron, & - config_mobility_type_particulate_iron, & - config_mobility_type_black_carbon1, & - config_mobility_type_black_carbon2, & - config_mobility_type_dust1, & - config_mobility_type_dust2, & - config_mobility_type_dust3, & - config_mobility_type_dust4, & - config_ratio_C_to_N_diatoms, & - config_ratio_C_to_N_small_plankton, & - config_ratio_C_to_N_phaeocystis, & - config_ratio_chla_to_N_diatoms, & - config_ratio_chla_to_N_small_plankton, & - config_ratio_chla_to_N_phaeocystis, & - config_scales_absorption_diatoms, & - config_scales_absorption_small_plankton, & - config_scales_absorption_phaeocystis, & - config_ratio_C_to_N_proteins, & config_fallen_snow_radius, & config_new_snow_density, & config_max_snow_density, & @@ -10335,8 +10300,6 @@ subroutine init_icepack_package_configs(domain) call MPAS_pool_get_config(domain % configs, "config_bio_gravity_drainage_length_scale", & config_bio_gravity_drainage_length_scale) call MPAS_pool_get_config(domain % configs, "config_biogrid_top_molecular_sublayer", config_biogrid_top_molecular_sublayer) - call MPAS_pool_get_config(domain % configs, "config_new_ice_fraction_biotracer", config_new_ice_fraction_biotracer) - call MPAS_pool_get_config(domain % configs, "config_fraction_biotracer_in_frazil", config_fraction_biotracer_in_frazil) call MPAS_pool_get_config(domain % configs, "config_snow_porosity_at_ice_surface", config_snow_porosity_at_ice_surface) call MPAS_pool_get_config(domain % configs, "config_ratio_Si_to_N_diatoms", config_ratio_Si_to_N_diatoms) call MPAS_pool_get_config(domain % configs, "config_ratio_Si_to_N_small_plankton", config_ratio_Si_to_N_small_plankton) @@ -10354,8 +10317,6 @@ subroutine init_icepack_package_configs(domain) call MPAS_pool_get_config(domain % configs, "config_ratio_Fe_to_DOC_saccharids", config_ratio_Fe_to_DOC_saccharids) call MPAS_pool_get_config(domain % configs, "config_ratio_Fe_to_DOC_lipids", config_ratio_Fe_to_DOC_lipids) call MPAS_pool_get_config(domain % configs, "config_respiration_fraction_of_growth", config_respiration_fraction_of_growth) - call MPAS_pool_get_config(domain % configs, "config_rapid_mobile_to_stationary_time", config_rapid_mobile_to_stationary_time) - call MPAS_pool_get_config(domain % configs, "config_long_mobile_to_stationary_time", config_long_mobile_to_stationary_time) call MPAS_pool_get_config(domain % configs, "config_algal_maximum_velocity", config_algal_maximum_velocity) call MPAS_pool_get_config(domain % configs, "config_ratio_Fe_to_dust", config_ratio_Fe_to_dust) call MPAS_pool_get_config(domain % configs, "config_solubility_of_Fe_in_dust", config_solubility_of_Fe_in_dust) @@ -10431,37 +10392,6 @@ subroutine init_icepack_package_configs(domain) call MPAS_pool_get_config(domain % configs, "config_DMSP_to_DMS_conversion_fraction", config_DMSP_to_DMS_conversion_fraction) call MPAS_pool_get_config(domain % configs, "config_DMSP_to_DMS_conversion_time", config_DMSP_to_DMS_conversion_time) call MPAS_pool_get_config(domain % configs, "config_DMS_oxidation_time", config_DMS_oxidation_time) - call MPAS_pool_get_config(domain % configs, "config_mobility_type_diatoms", config_mobility_type_diatoms) - call MPAS_pool_get_config(domain % configs, "config_mobility_type_small_plankton", config_mobility_type_small_plankton) - call MPAS_pool_get_config(domain % configs, "config_mobility_type_phaeocystis", config_mobility_type_phaeocystis) - call MPAS_pool_get_config(domain % configs, "config_mobility_type_nitrate", config_mobility_type_nitrate) - call MPAS_pool_get_config(domain % configs, "config_mobility_type_ammonium", config_mobility_type_ammonium) - call MPAS_pool_get_config(domain % configs, "config_mobility_type_silicate", config_mobility_type_silicate) - call MPAS_pool_get_config(domain % configs, "config_mobility_type_DMSPp", config_mobility_type_DMSPp) - call MPAS_pool_get_config(domain % configs, "config_mobility_type_DMSPd", config_mobility_type_DMSPd) - call MPAS_pool_get_config(domain % configs, "config_mobility_type_humics", config_mobility_type_humics) - call MPAS_pool_get_config(domain % configs, "config_mobility_type_saccharids", config_mobility_type_saccharids) - call MPAS_pool_get_config(domain % configs, "config_mobility_type_lipids", config_mobility_type_lipids) - call MPAS_pool_get_config(domain % configs, "config_mobility_type_inorganic_carbon", config_mobility_type_inorganic_carbon) - call MPAS_pool_get_config(domain % configs, "config_mobility_type_proteins", config_mobility_type_proteins) - call MPAS_pool_get_config(domain % configs, "config_mobility_type_dissolved_iron", config_mobility_type_dissolved_iron) - call MPAS_pool_get_config(domain % configs, "config_mobility_type_particulate_iron", config_mobility_type_particulate_iron) - call MPAS_pool_get_config(domain % configs, "config_mobility_type_black_carbon1", config_mobility_type_black_carbon1) - call MPAS_pool_get_config(domain % configs, "config_mobility_type_black_carbon2", config_mobility_type_black_carbon2) - call MPAS_pool_get_config(domain % configs, "config_mobility_type_dust1", config_mobility_type_dust1) - call MPAS_pool_get_config(domain % configs, "config_mobility_type_dust2", config_mobility_type_dust2) - call MPAS_pool_get_config(domain % configs, "config_mobility_type_dust3", config_mobility_type_dust3) - call MPAS_pool_get_config(domain % configs, "config_mobility_type_dust4", config_mobility_type_dust4) - call MPAS_pool_get_config(domain % configs, "config_ratio_C_to_N_diatoms", config_ratio_C_to_N_diatoms) - call MPAS_pool_get_config(domain % configs, "config_ratio_C_to_N_small_plankton", config_ratio_C_to_N_small_plankton) - call MPAS_pool_get_config(domain % configs, "config_ratio_C_to_N_phaeocystis", config_ratio_C_to_N_phaeocystis) - call MPAS_pool_get_config(domain % configs, "config_ratio_chla_to_N_diatoms", config_ratio_chla_to_N_diatoms) - call MPAS_pool_get_config(domain % configs, "config_ratio_chla_to_N_small_plankton", config_ratio_chla_to_N_small_plankton) - call MPAS_pool_get_config(domain % configs, "config_ratio_chla_to_N_phaeocystis", config_ratio_chla_to_N_phaeocystis) - call MPAS_pool_get_config(domain % configs, "config_scales_absorption_diatoms", config_scales_absorption_diatoms) - call MPAS_pool_get_config(domain % configs, "config_scales_absorption_small_plankton", config_scales_absorption_small_plankton) - call MPAS_pool_get_config(domain % configs, "config_scales_absorption_phaeocystis", config_scales_absorption_phaeocystis) - call MPAS_pool_get_config(domain % configs, "config_ratio_C_to_N_proteins", config_ratio_C_to_N_proteins) call MPAS_pool_get_config(domain % configs, "config_snow_redistribution_scheme", config_snow_redistribution_scheme) call MPAS_pool_get_config(domain % configs, "config_fallen_snow_radius", config_fallen_snow_radius) call MPAS_pool_get_config(domain % configs, "config_use_snow_liquid_ponds", config_use_snow_liquid_ponds) @@ -10763,14 +10693,10 @@ subroutine init_icepack_package_configs(domain) grid_o_in = config_biogrid_bottom_molecular_sublayer, & l_sk_in = config_bio_gravity_drainage_length_scale, & grid_o_t_in = config_biogrid_top_molecular_sublayer, & - !initbio_frac_in = config_new_ice_fraction_biotracer, & - !frazil_scav_in = config_fraction_biotracer_in_frazil, & !grid_oS_in = config_zsalinity_molecular_sublayer, & !l_skS_in = config_zsalinity_gravity_drainage_scale, & phi_snow_in = config_snow_porosity_at_ice_surface, & fr_resp_in = config_respiration_fraction_of_growth, & - tau_min_in = config_rapid_mobile_to_stationary_time, & - tau_max_in = config_long_mobile_to_stationary_time, & algal_vel_in = config_algal_maximum_velocity, & R_dFe2dust_in = config_ratio_Fe_to_dust, & dustFe_sol_in = config_solubility_of_Fe_in_dust, & @@ -10790,37 +10716,6 @@ subroutine init_icepack_package_configs(domain) y_sk_DMS_in = config_DMSP_to_DMS_conversion_fraction, & t_sk_conv_in = config_DMSP_to_DMS_conversion_time, & t_sk_ox_in = config_DMS_oxidation_time, & - algaltype_diatoms_in = config_mobility_type_diatoms, & - algaltype_sp_in = config_mobility_type_small_plankton, & - algaltype_phaeo_in = config_mobility_type_phaeocystis, & - nitratetype_in = config_mobility_type_nitrate, & - ammoniumtype_in = config_mobility_type_ammonium, & - silicatetype_in = config_mobility_type_silicate, & - dmspptype_in = config_mobility_type_DMSPp, & - dmspdtype_in = config_mobility_type_DMSPd, & - humtype_in = config_mobility_type_humics, & - doctype_s_in = config_mobility_type_saccharids, & - doctype_l_in = config_mobility_type_lipids, & - dictype_1_in = config_mobility_type_inorganic_carbon, & - dontype_protein_in = config_mobility_type_proteins, & - fedtype_1_in = config_mobility_type_dissolved_iron, & - feptype_1_in = config_mobility_type_particulate_iron, & - zaerotype_bc1_in = config_mobility_type_black_carbon1, & - zaerotype_bc2_in = config_mobility_type_black_carbon2, & - zaerotype_dust1_in = config_mobility_type_dust1, & - zaerotype_dust2_in = config_mobility_type_dust2, & - zaerotype_dust3_in = config_mobility_type_dust3, & - zaerotype_dust4_in = config_mobility_type_dust4, & - ratio_C2N_diatoms_in = config_ratio_C_to_N_diatoms, & - ratio_C2N_sp_in = config_ratio_C_to_N_small_plankton, & - ratio_C2N_phaeo_in = config_ratio_C_to_N_phaeocystis, & - ratio_chl2N_diatoms_in = config_ratio_chla_to_N_diatoms, & - ratio_chl2N_sp_in = config_ratio_chla_to_N_small_plankton, & - ratio_chl2N_phaeo_in = config_ratio_chla_to_N_phaeocystis, & - F_abs_chl_diatoms_in = config_scales_absorption_diatoms, & - F_abs_chl_sp_in = config_scales_absorption_small_plankton, & - F_abs_chl_phaeo_in = config_scales_absorption_phaeocystis, & - ratio_C2N_proteins_in = config_ratio_C_to_N_proteins, & !conserv_check_in = , & snwgrain_in = config_use_snow_grain_radius, & snwredist_in = config_snow_redistribution_scheme, & From 2edf9b3c5649c798f7552e045416fd68b283b96c Mon Sep 17 00:00:00 2001 From: Dalei Hao Date: Thu, 13 Jun 2024 15:44:32 -0700 Subject: [PATCH 166/451] Undo the change related to latitude limits --- components/elm/src/biogeophys/SurfaceAlbedoMod.F90 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/components/elm/src/biogeophys/SurfaceAlbedoMod.F90 b/components/elm/src/biogeophys/SurfaceAlbedoMod.F90 index 49c6d061d3d8..073c836c19bc 100644 --- a/components/elm/src/biogeophys/SurfaceAlbedoMod.F90 +++ b/components/elm/src/biogeophys/SurfaceAlbedoMod.F90 @@ -1811,7 +1811,7 @@ subroutine Albedo_TOP_Adjustment(bounds, num_pft, filter_pft, & lon_180 = lon(g) if (lon_180 > pi) lon_180 = lon_180-2._r8*pi - if (cosz > 0._r8 .and. stdev_elev(g) > 0._r8) then + if (cosz > 0._r8 .and. abs(lat(g)) < 1.047_r8 .and. stdev_elev(g) > 0._r8) then local_timeofday = next_tod + lon_180 / pi * 180._r8 * 240._r8 if (local_timeofday >= 86400._r8) then From 047111c9358244b176cce8543119d727d7c3b7ef Mon Sep 17 00:00:00 2001 From: Walter Hannah Date: Fri, 21 Jun 2024 16:01:17 -0600 Subject: [PATCH 167/451] add new mkatmsrffile tool --- .../eam/tools/mkatmsrffile/mkatmsrffile.py | 295 ++++++++++++++++++ .../{ => old_mkatmsrffile}/Makefile | 0 .../{ => old_mkatmsrffile}/README | 0 .../{ => old_mkatmsrffile}/mkatmsrffile.F90 | 0 .../{ => old_mkatmsrffile}/nml_atmsrf | 0 .../test_mkatmsrffile.sh | 0 .../generate-dry-deposition.md | 38 ++- 7 files changed, 331 insertions(+), 2 deletions(-) create mode 100644 components/eam/tools/mkatmsrffile/mkatmsrffile.py rename components/eam/tools/mkatmsrffile/{ => old_mkatmsrffile}/Makefile (100%) rename components/eam/tools/mkatmsrffile/{ => old_mkatmsrffile}/README (100%) rename components/eam/tools/mkatmsrffile/{ => old_mkatmsrffile}/mkatmsrffile.F90 (100%) rename components/eam/tools/mkatmsrffile/{ => old_mkatmsrffile}/nml_atmsrf (100%) rename components/eam/tools/mkatmsrffile/{ => old_mkatmsrffile}/test_mkatmsrffile.sh (100%) diff --git a/components/eam/tools/mkatmsrffile/mkatmsrffile.py b/components/eam/tools/mkatmsrffile/mkatmsrffile.py new file mode 100644 index 000000000000..50999b6e945f --- /dev/null +++ b/components/eam/tools/mkatmsrffile/mkatmsrffile.py @@ -0,0 +1,295 @@ +#!/usr/bin/env python3 +#--------------------------------------------------------------------------------------------------- +''' +This is a replacement for the legacy gen_domain tool created for CESM. +Most legacy functionality is reproduced, with the notable exception of +the pole point latitude adjustment needed for the CESM FV grid. + +Created April, 2024 by Walter Hannah (LLNL) +''' +#--------------------------------------------------------------------------------------------------- +''' +The map file used to generate the atmsrf files can be created a few different ways. +For a typical E3SM configuration we recommend using a conservative, monotone map. +Here is an example command that can be used to generate one as of NCO version 5.2.2 + + SRC_GRID=${DIN_LOC_ROOT}/../mapping/grids/1x1d.nc + DST_GRID=${GRID_ROOT}/ne${NE}pg2_scrip.nc + MAP_FILE=${MAP_ROOT}/map_1x1_to_ne${NE}pg2_traave.nc + ncremap -a traave --src_grd=${SRC_GRID} --dst_grd=${DST_GRID} --map_file=${MAP_FILE} + +''' +#--------------------------------------------------------------------------------------------------- +import datetime, os, numpy as np, xarray as xr, numba, itertools, subprocess as sp +user, host = os.getenv('USER'), os.getenv('HOST') +source_code_meta = 'generate_domain_E3SM.py' +#--------------------------------------------------------------------------------------------------- +class clr:END,RED,GREEN,MAGENTA,CYAN = '\033[0m','\033[31m','\033[32m','\033[35m','\033[36m' +#--------------------------------------------------------------------------------------------------- +usage = ''' +python mkatmsrffile.py --map_file + --dst_grid + [--output-root ] + [--date-stamp ] + +Purpose: + This tool generates a file needed to prescribe atmospheric dry deposition of aerosols at the surface. + +Environment + + This tool requires a few special packages, such as xarray, numba, and itertools. + These are all included in the E3SM unified environment: + https://e3sm.org/resources/tools/other-tools/e3sm-unified-environment/ + + Otherwise a simple conda environment can be created: + conda create --name example_env --channel conda-forge xarray numpy numba scikit-learn netcdf4 + +The following output file is created: + + atmsrf__.nc + ???? + +''' +from optparse import OptionParser +parser = OptionParser(usage=usage) +parser.add_option('--map_file', + dest='map_file', + default=None, + help='Mapping file from a 1x1 degree grid to the target atmosphere grid') +parser.add_option('--vegetation_file', + dest='vegetation_file', + default=None, + help='Path to file containing area fractions of surface types and plant functional type (PFT) data (regrid_vegetation.nc)') +parser.add_option('--soil_water_file', + dest='soil_water_file', + default=None, + help='Path to file containing soil water data (clim_soilw.nc)') +parser.add_option('--dst_grid', + dest='dst_grid', + default=None, + help='destination atmosphere grid name') +parser.add_option('--output_root', + dest='output_root', + default='./', + help='Output path for domain files') +parser.add_option('--date-stamp', + dest='date_stamp', + default=None, + help='Creation date stamp for domain files') +(opts, args) = parser.parse_args() +#--------------------------------------------------------------------------------------------------- +def main(): + #----------------------------------------------------------------------------- + # check for valid input arguments + if opts.map_file is None: + raise ValueError(f'{clr.RED}map_file was not specified{clr.END}') + if opts.vegetation_file is None: + raise ValueError(f'{clr.RED}vegetation_file was not specified{clr.END}') + if opts.soil_water_file is None: + raise ValueError(f'{clr.RED}soil_water_file was not specified{clr.END}') + if opts.dst_grid is None: + raise ValueError(f'{clr.RED}dst_grid was not specified{clr.END}') + #----------------------------------------------------------------------------- + # check existence of input files and output path + if not os.path.exists(opts.vegetation_file) : + raise ValueError(f'{clr.RED}Vegetaion file does not exist:{clr.END} {opts.vegetation_file}') + if not os.path.exists(opts.soil_water_file) : + raise ValueError(f'{clr.RED}Soil water file does not exist:{clr.END} {opts.soil_water_file}') + if not os.path.exists(opts.output_root) : + raise ValueError(f'{clr.RED}Output root path does not exist:{clr.END} {opts.output_root}') + + #----------------------------------------------------------------------------- + # Set date stamp for file name + + if opts.date_stamp is None: + cdate = datetime.datetime.now().strftime('%Y%m%d') + else: + cdate = opts.date_stamp + + #----------------------------------------------------------------------------- + # specify output file name + + output_file = f'{opts.output_root}/atm_srf_{opts.dst_grid}_{cdate}.nc' + + #----------------------------------------------------------------------------- + # open input files as datasets + + ds_map = xr.open_dataset(opts.map_file) + ds_veg = xr.open_dataset(opts.vegetation_file) + ds_slw = xr.open_dataset(opts.soil_water_file) + + #----------------------------------------------------------------------------- + # check that dimension sizes are consistent + + nxy_veg = len(ds_veg.lat) * len(ds_veg.lon) + nxy_slw = len(ds_slw.lat) * len(ds_slw.lon) + n_a = len(ds_map.n_a) + n_b = len(ds_map.n_b) + + if nxy_veg!=nxy_slw or n_a!=nxy_veg or n_a!=nxy_slw: + err_msg = f'{clr.RED}Input file dimension sizes are inconsistent:{clr.END}' + err_msg += f' n_a: {n_a} nxy_veg: {nxy_veg} nxy_slw: {nxy_slw}' + raise ValueError(err_msg) + + ntime = 12 # expected length of time dimension + + if len(ds_veg.time)!=ntime: + err_msg = f'vegetation_file time record error:' + err_msg += f' expected length = {ntime}, actual length = {len(ds_veg.time)}' + raise ValueError(err_msg) + + if len(ds_slw.time)!=ntime: + err_msg = f'soil_water_file time record error:' + err_msg += f' expected length = {ntime}, actual length = {len(ds_slw.time)}' + raise ValueError(err_msg) + + if len(ds_veg.lat)!=len(ds_slw.lat): + err_msg = f'inconsistent latitude coordinate lengths:' + err_msg += f' ds_veg.lat = {len(ds_veg.lat)}' + err_msg += f' ds_slw.lat = {len(ds_slw.lat)}' + raise ValueError(err_msg) + + if len(ds_veg.lon)!=len(ds_slw.lon): + err_msg = f'inconsistent latitude coordinate lengths:' + err_msg += f' ds_veg.lon = {len(ds_veg.lon)}' + err_msg += f' ds_slw.lon = {len(ds_slw.lon)}' + raise ValueError(err_msg) + + #----------------------------------------------------------------------------- + # print some informative stuff + + print(f''' + File and parameter values: + {clr.GREEN}map_file {clr.END}: {opts.map_file} + {clr.GREEN}vegetation_file {clr.END}: {opts.vegetation_file} + {clr.GREEN}soil_water_file {clr.END}: {opts.soil_water_file} + {clr.GREEN}output_root {clr.END}: {opts.output_root} + {clr.GREEN}output_file {clr.END}: {output_file} + {clr.GREEN}dst_grid {clr.END}: {opts.dst_grid} + {clr.GREEN}map_file n_a {clr.END}: {n_a} + {clr.GREEN}map_file n_b {clr.END}: {n_b} + ''') + + #----------------------------------------------------------------------------- + # Load input data + # (also convert percentage to fraction [0,1]) + LANDMASK_in = ds_veg['LANDMASK' ].values + PCT_LAKE_in = ds_veg['PCT_LAKE' ].values/1e2 + PCT_URBAN_in = ds_veg['PCT_URBAN' ].values/1e2 + PCT_WETLAND_in = ds_veg['PCT_WETLAND'].values/1e2 + PCT_PFT_in = ds_veg['PCT_PFT' ].values/1e2 + SOILW_in = ds_slw['SOILW' ].values + #----------------------------------------------------------------------------- + # Adjust input data based on land fraction (for consistency with fortran tool) + nlat = len(ds_veg.lat) + nlon = len(ds_veg.lon) + adjust_inputs(ntime, nlat, nlon, LANDMASK_in, PCT_LAKE_in, PCT_URBAN_in, PCT_WETLAND_in, SOILW_in) + #----------------------------------------------------------------------------- + # Remap data to the atmosphere grid + + n_s = len(ds_map.n_s) + wgt = ds_map.S.values + row = ds_map.row.values-1 + col = ds_map.col.values-1 + + shp_1D = (n_b) + shp_2D = (ntime,n_b) + + SOILW = apply_map_2D( np.zeros(shp_2D), ntime, n_s, wgt, row, col, np.reshape(SOILW_in,(ntime,-1)) ) + + PCT_LAKE = apply_map_1D( np.zeros(shp_1D), n_s, wgt, row, col, np.reshape(PCT_LAKE_in ,-1) ) + PCT_URBAN = apply_map_1D( np.zeros(shp_1D), n_s, wgt, row, col, np.reshape(PCT_URBAN_in ,-1) ) + PCT_WETLAND = apply_map_1D( np.zeros(shp_1D), n_s, wgt, row, col, np.reshape(PCT_WETLAND_in,-1) ) + + npft = len(ds_veg.PCT_PFT[:,0,0]) + PCT_PFT = np.zeros((npft,n_b)) + for p in range(npft): + PCT_PFT[p,:] = apply_map_1D( np.zeros(shp_1D), n_s, wgt, row, col, np.reshape(PCT_PFT_in[p,:,:],-1) ) + + #----------------------------------------------------------------------------- + # Compute fields to output + + nclass_landuse = 11 + fraction_landuse = np.zeros([nclass_landuse,n_b]) + total_soilw = np.zeros([ntime,n_b]) + + for i in range(n_b): + # Calculate total_land as sum as all surface type fractions + total_land = PCT_LAKE[i] + PCT_URBAN[i] + PCT_WETLAND[i] + for p in range(npft): total_land += PCT_PFT[p,i] + # Adjust lake area fraction + if total_land<1.0: + PCT_LAKE[i] = PCT_LAKE[i] + (1.0 - total_land) + # Calculate total_soilw + fraction_soilw = total_land - ( PCT_LAKE[i] + PCT_WETLAND[i] ) + for t in range(ntime): + total_soilw[t,i] = total_soilw[t,i] + SOILW[t,i] * fraction_soilw + + # Calculate fraction_landuse - n-1 indexing is used to correspond to fortran indexing + fraction_landuse[ 1-1,i] = PCT_URBAN[i] + fraction_landuse[ 2-1,i] = np.sum( PCT_PFT[[n-1 for n in [16,17]] ,i], axis=0) + fraction_landuse[ 3-1,i] = np.sum( PCT_PFT[[n-1 for n in [13,14,15]] ,i], axis=0) + fraction_landuse[ 4-1,i] = np.sum( PCT_PFT[[n-1 for n in [5,6,7,8,9]],i], axis=0) + fraction_landuse[ 5-1,i] = np.sum( PCT_PFT[[n-1 for n in [2,3,4]] ,i], axis=0) + fraction_landuse[ 6-1,i] = PCT_WETLAND[i] + fraction_landuse[ 7-1,i] = PCT_LAKE[i] + fraction_landuse[ 8-1,i] = PCT_PFT[1-1,i] + fraction_landuse[11-1,i] = np.sum( PCT_PFT[[n-1 for n in [10,11,12]] ,i], axis=0) + + # Normalize fraction_landuse if it does not sum to 1 +/- tolerance + fraction_landuse_tolerance = 0.001 + fraction_landuse_sum = np.sum(fraction_landuse[:,i]) + fraction_landuse_error = fraction_landuse_sum - 1.0 + if np.absolute(fraction_landuse_error) > fraction_landuse_tolerance: + for c in range(nclass_landuse): + fraction_landuse[c,i] = fraction_landuse[c,i] / fraction_landuse_sum + + #----------------------------------------------------------------------------- + # Create output file and add fields + + ds_out = xr.Dataset() + ds_out['fraction_landuse'] = xr.DataArray(fraction_landuse,dims=['class','ncol']) + ds_out['soilw'] = xr.DataArray(SOILW ,dims=['month','ncol']) + ds_out['lon'] = ds_map.xc_b.rename({'n_b':'ncol'}) + ds_out['lat'] = ds_map.yc_b.rename({'n_b':'ncol'}) + ds_out.to_netcdf(path=output_file,mode='w') + + #----------------------------------------------------------------------------- + # convert to 64bit_data + + cmd = f'ncks -O --fl_fmt=64bit_data {output_file} {output_file} ' + sp.check_call(cmd,shell=True) + + #----------------------------------------------------------------------------- + # print status message + + print(f'\nsuccessfully created atmsrf file: {clr.MAGENTA}{output_file}{clr.END}') + print() + +#--------------------------------------------------------------------------------------------------- +@numba.njit() +def adjust_inputs(ntime, nlat, nlon, LANDMASK, PCT_LAKE, PCT_URBAN, PCT_WETLAND, SOILW): + for j in range(nlat): + for i in range(nlon): + if LANDMASK[j,i]==0: + PCT_LAKE[j,i] = 1.0 + PCT_URBAN[j,i] = 0.0 + PCT_WETLAND[j,i] = 0.0 + for t in range(ntime): SOILW[t,j,i] = 0.0 + +@numba.njit() +def apply_map_1D( data_out, n_s, wgt, row, col, data_in ): + for k in range(n_s): + data_out[row[k]] = data_out[row[k]] + data_in[col[k]] * wgt[k] + return data_out + +@numba.njit() +def apply_map_2D( data_out, ntime, n_s, wgt, row, col, data_in ): + for t in range(ntime): + for k in range(n_s): + data_out[t,row[k]] = data_out[t,row[k]] + data_in[t,col[k]] * wgt[k] + return data_out +#--------------------------------------------------------------------------------------------------- +if __name__ == '__main__': + main() +#--------------------------------------------------------------------------------------------------- \ No newline at end of file diff --git a/components/eam/tools/mkatmsrffile/Makefile b/components/eam/tools/mkatmsrffile/old_mkatmsrffile/Makefile similarity index 100% rename from components/eam/tools/mkatmsrffile/Makefile rename to components/eam/tools/mkatmsrffile/old_mkatmsrffile/Makefile diff --git a/components/eam/tools/mkatmsrffile/README b/components/eam/tools/mkatmsrffile/old_mkatmsrffile/README similarity index 100% rename from components/eam/tools/mkatmsrffile/README rename to components/eam/tools/mkatmsrffile/old_mkatmsrffile/README diff --git a/components/eam/tools/mkatmsrffile/mkatmsrffile.F90 b/components/eam/tools/mkatmsrffile/old_mkatmsrffile/mkatmsrffile.F90 similarity index 100% rename from components/eam/tools/mkatmsrffile/mkatmsrffile.F90 rename to components/eam/tools/mkatmsrffile/old_mkatmsrffile/mkatmsrffile.F90 diff --git a/components/eam/tools/mkatmsrffile/nml_atmsrf b/components/eam/tools/mkatmsrffile/old_mkatmsrffile/nml_atmsrf similarity index 100% rename from components/eam/tools/mkatmsrffile/nml_atmsrf rename to components/eam/tools/mkatmsrffile/old_mkatmsrffile/nml_atmsrf diff --git a/components/eam/tools/mkatmsrffile/test_mkatmsrffile.sh b/components/eam/tools/mkatmsrffile/old_mkatmsrffile/test_mkatmsrffile.sh similarity index 100% rename from components/eam/tools/mkatmsrffile/test_mkatmsrffile.sh rename to components/eam/tools/mkatmsrffile/old_mkatmsrffile/test_mkatmsrffile.sh diff --git a/docs/dev-guide/adding-grid-support/adding-grid-support-step-by-step-guide/generate-dry-deposition.md b/docs/dev-guide/adding-grid-support/adding-grid-support-step-by-step-guide/generate-dry-deposition.md index f9dc7ff9eda4..cf777c418a2b 100644 --- a/docs/dev-guide/adding-grid-support/adding-grid-support-step-by-step-guide/generate-dry-deposition.md +++ b/docs/dev-guide/adding-grid-support/adding-grid-support-step-by-step-guide/generate-dry-deposition.md @@ -1,6 +1,40 @@ # Generate a Dry Deposition File -!!!WARNING - This page is still under construction +Atmospheric dry deposition of aerosols at the surface depends on certain surface properties, such as soil type. In some cases these calculations can be handled in the land model and passed to the atmosphere through the coupler. However, with modal areosols this method is not adequate and we must recalculate these fields in the atmosphere (see subroutine `interp_map` in `components/eam/src/chemistry/mozart/mo_drydep.F90`). + +For unstructured grids it was determined to create this offline interpolation tool rather than generalize the subroutine interp_map. + +Be sure to activate the E3SM unified environment when performing the steps below. + +## Map File Generation + +The destination atmosphere grid file should be on the "pg2" grid. These grid files are easily generated with three TempestRemap commands as follows: + +```shell +NE=30 +GenerateCSMesh --alt --res ${NE} --file ${GRID_ROOT}/ne${NE}.g +GenerateVolumetricMesh --in ${GRID_ROOT}/ne${NE}.g --out ${GRID_ROOT}/ne${NE}pg2.g --np 2 --uniform +ConvertMeshToSCRIP --in ${GRID_ROOT}/ne${NE}pg2.g --out ${GRID_ROOT}/ne${NE}pg2_scrip.nc +``` + +The map file used to generate atmsrf files can be created a few different ways. For a typical E3SM configuration we recommend using a conservative, monotone map. Here is an example command that can be used to generate one (as of NCO version 5.2.2) + +```shell +SRC_GRID=${DIN_LOC_ROOT}/../mapping/grids/1x1d.nc +DST_GRID=${GRID_ROOT}/ne${NE}pg2_scrip.nc +MAP_FILE=${MAP_ROOT}/map_1x1_to_ne${NE}pg2_traave.nc +ncremap -5 -a traave --src_grd=${SRC_GRID} --dst_grd=${DST_GRID} --map_file=${MAP_FILE} +``` + +For RRM grids the last two commands would be used on the exodus file produced by [SQuadGen](https://github.com/ClimateGlobalChange/squadgen) (See the [Adding Support for New Grids](https://docs.e3sm.org/user-guides/adding-grid-support-overview.md) tutorial for more information.). + +## Generating a New Dry Desposition File (atmsrf) + +```shell +VEGE_FILE=${DIN_LOC_ROOT}/atm/cam/chem/trop_mozart/dvel/regrid_vegetation.nc +SOIL_FILE=${DIN_LOC_ROOT}/atm/cam/chem/trop_mozart/dvel/clim_soilw.nc + +python ~/E3SM/mkatmsrffile.py --map_file=${MAP_FILE} --vegetation_file=${VEGE_FILE} --soil_water_file=${SOIL_FILE} --output_root=${atmsrf_root} --dst_grid=ne${NE}pg2 --date-stamp=20240613 +``` Back to step-by-step guide for [Adding Support for New Grids](../adding-grid-support-step-by-step-guide.md) From 6853aee04a467f67d00985c506ed01771aebcf1f Mon Sep 17 00:00:00 2001 From: Nicole Jeffery Date: Sat, 22 Jun 2024 12:32:38 -0500 Subject: [PATCH 168/451] Removes redundant parameter and dimension passes to icepack More cleanup of the mpas-seaice icepack interface. Updates icepack hash #31ce4221 BFB --- components/mpas-seaice/src/icepack | 2 +- .../src/shared/mpas_seaice_icepack.F | 120 ++---------------- .../src/shared/mpas_seaice_initialize.F | 9 -- .../src/shared/mpas_seaice_velocity_solver.F | 1 - 4 files changed, 10 insertions(+), 122 deletions(-) diff --git a/components/mpas-seaice/src/icepack b/components/mpas-seaice/src/icepack index c63f9e5b710f..31ce42217717 160000 --- a/components/mpas-seaice/src/icepack +++ b/components/mpas-seaice/src/icepack @@ -1 +1 @@ -Subproject commit c63f9e5b710f87fd915ad0b77da19bd0a5ab6d12 +Subproject commit 31ce42217717dbbde87b73129d7a4ff3d052455d diff --git a/components/mpas-seaice/src/shared/mpas_seaice_icepack.F b/components/mpas-seaice/src/shared/mpas_seaice_icepack.F index 933b669766c0..c6386f2c1aa4 100644 --- a/components/mpas-seaice/src/shared/mpas_seaice_icepack.F +++ b/components/mpas-seaice/src/shared/mpas_seaice_icepack.F @@ -340,7 +340,6 @@ subroutine init_column_itd(domain) call MPAS_pool_get_array(initial, "categoryThicknessLimits", categoryThicknessLimits) call icepack_init_itd(& - nCategories, & categoryThicknessLimits) call seaice_icepack_write_warnings(icepack_warnings_aborted()) @@ -400,7 +399,6 @@ subroutine init_column_thermodynamic_profiles(domain) allocate(initialSalinityProfileVertical(1:nIceLayers+1)) call icepack_init_thermo(& - nIceLayers, & initialSalinityProfileVertical) call seaice_icepack_write_warnings(icepack_warnings_aborted()) @@ -864,8 +862,6 @@ subroutine init_column_thermodynamic_tracers(domain) integer, pointer :: & nCellsSolve, & - nIceLayers, & - nSnowLayers, & nCategories integer :: & @@ -883,8 +879,6 @@ subroutine init_column_thermodynamic_tracers(domain) call MPAS_pool_get_dimension(mesh, "nCellsSolve", nCellsSolve) call MPAS_pool_get_dimension(mesh, "nCategories", nCategories) - call MPAS_pool_get_dimension(mesh, "nIceLayers", nIceLayers) - call MPAS_pool_get_dimension(mesh, "nSnowLayers", nSnowLayers) call MPAS_pool_get_array(atmos_coupling, "airTemperature", airTemperature) @@ -906,8 +900,6 @@ subroutine init_column_thermodynamic_tracers(domain) initialSalinityProfile(:,iCell), & initialMeltingTemperatureProfile(:,iCell), & surfaceTemperature(1,iCategory,iCell), & - nIceLayers, & - nSnowLayers, & iceEnthalpy(:,iCategory,iCell), & snowEnthalpy(:,iCategory,iCell)) @@ -1745,9 +1737,6 @@ subroutine column_vertical_thermodynamics(domain, clock) call icepack_warnings_clear() call icepack_step_therm1(& dt=config_dt, & - ncat=nCategories, & - nilyr=nIceLayers, & - nslyr=nSnowLayers, & aicen_init=iceAreaCategoryInitial(:,iCell), & vicen_init=iceVolumeCategoryInitial(:,iCell), & vsnon_init=snowVolumeCategoryInitial(:,iCell), & @@ -2163,9 +2152,6 @@ subroutine column_itd_thermodynamics(domain, clock) oceanHeatFlux, & freezeOnset, & categoryThicknessLimits, & - biologyGrid, & - verticalGrid, & - interfaceBiologyGrid, & frazilGrowthDiagnostic ! frazilGrowthDiagnostic, & ! WaveFrequency, & @@ -2314,9 +2300,6 @@ subroutine column_itd_thermodynamics(domain, clock) call MPAS_pool_get_array(biogeochemistry, "oceanBioFluxes", oceanBioFluxes) call MPAS_pool_get_array(biogeochemistry, "oceanBioConcentrations", oceanBioConcentrations) call MPAS_pool_get_array(biogeochemistry, "oceanBioConcentrationsInUse", oceanBioConcentrationsInUse) - call MPAS_pool_get_array(biogeochemistry, "biologyGrid", biologyGrid) - call MPAS_pool_get_array(biogeochemistry, "verticalGrid", verticalGrid) - call MPAS_pool_get_array(biogeochemistry, "interfaceBiologyGrid", interfaceBiologyGrid) call MPAS_pool_get_array(initial, "initialSalinityProfile", initialSalinityProfile) call MPAS_pool_get_array(initial, "categoryThicknessLimits", categoryThicknessLimits) @@ -2365,12 +2348,7 @@ subroutine column_itd_thermodynamics(domain, clock) call icepack_step_therm2(& dt=config_dt, & - ncat=nCategories, & - nilyr=nIcelayers, & - nslyr=nSnowLayers, & hin_max=categoryThicknessLimits(:), & - nbtrcr=ciceTracerObject % nBioTracers, & - nblyr=nBioLayers, & aicen=iceAreaCategory(1,:,iCell), & vicen=iceVolumeCategory(1,:,iCell), & vsnon=snowVolumeCategory(1,:,iCell), & @@ -2397,9 +2375,6 @@ subroutine column_itd_thermodynamics(domain, clock) fresh=oceanFreshWaterFlux(iCell), & fsalt=oceanSaltFlux(iCell), & fhocn=oceanHeatFlux(iCell), & - bgrid=biologyGrid(:), & - cgrid=verticalGrid(:), & - igrid=interfaceBiologyGrid(:), & faero_ocn=oceanAerosolFlux(:,iCell), & first_ice=newlyFormedIceLogical(:), & flux_bio=oceanBioFluxesTemp(:,iCell), & @@ -2772,9 +2747,6 @@ subroutine column_snow(domain) call icepack_step_snow (& dt=config_dt, & wind=windSpeed(iCell), & - nilyr=nIceLayers, & - nslyr=nSnowLayers, & - ncat=nCategories, & aice=iceAreaCell(iCell), & aicen=iceAreaCategory(1,:,iCell), & vicen=iceVolumeCategory(1,:,iCell), & @@ -2895,9 +2867,7 @@ subroutine column_radiation(domain, clock, lInitialization) shortwaveIRDirectDown, & shortwaveIRDiffuseDown, & solarZenithAngleCosine, & - snowfallRate, & - verticalShortwaveGrid, & - verticalGrid + snowfallRate real(kind=RKIND), dimension(:,:), pointer :: & surfaceShortwaveFlux, & @@ -3065,8 +3035,6 @@ subroutine column_radiation(domain, clock, lInitialization) call MPAS_pool_get_array(ponds, "pondLidMeltFluxFraction", pondLidMeltFluxFraction) call MPAS_pool_get_array(biogeochemistry, "bioTracerShortwave", bioTracerShortwave) - call MPAS_pool_get_array(biogeochemistry, "verticalShortwaveGrid", verticalShortwaveGrid) - call MPAS_pool_get_array(biogeochemistry, "verticalGrid", verticalGrid) ! calendar type call MPAS_pool_get_config(block % configs, "config_calendar_type", config_calendar_type) @@ -3117,8 +3085,6 @@ subroutine column_radiation(domain, clock, lInitialization) call icepack_step_radiation(& dt=config_dt, & - swgrid=verticalShortwaveGrid(:), & - igrid=verticalGrid(:), & fbri=brineFraction(1,:,iCell), & aicen=iceAreaCategory(1,:,iCell), & vicen=iceVolumeCategory(1,:,iCell), & @@ -3236,12 +3202,7 @@ subroutine column_ridging(domain) ! dimensions integer, pointer :: & nCellsSolve, & - nCategories, & - nIceLayers, & - nSnowLayers, & - nAerosols, & - nBioLayers, & - nBioLayersP1 + nCategories ! variables real(kind=RKIND), dimension(:), pointer :: & @@ -3330,11 +3291,6 @@ subroutine column_ridging(domain) call MPAS_pool_get_dimension(mesh, "nCellsSolve", nCellsSolve) call MPAS_pool_get_dimension(mesh, "nCategories", nCategories) - call MPAS_pool_get_dimension(mesh, "nIceLayers", nIceLayers) - call MPAS_pool_get_dimension(mesh, "nSnowLayers", nSnowLayers) - call MPAS_pool_get_dimension(mesh, "nAerosols", nAerosols) - call MPAS_pool_get_dimension(block % dimensions, "nBioLayers", nBioLayers) - call MPAS_pool_get_dimension(block % dimensions, "nBioLayersP1", nBioLayersP1) call MPAS_pool_get_array(mesh, "indexToCellID", indexToCellID) @@ -3401,10 +3357,6 @@ subroutine column_ridging(domain) call icepack_step_ridge(& dt=dynamicsTimeStep, & ndtd=config_dynamics_subcycle_number, & - nilyr=nIceLayers, & - nslyr=nSnowLayers, & - nblyr=nBioLayers, & - ncat=nCategories, & hin_max=categoryThicknessLimits, & ! hin_max, dimension(0:ncat), intent(inout) rdg_conv=ridgeConvergence(iCell), & rdg_shear=ridgeShear(iCell), & @@ -3424,7 +3376,6 @@ subroutine column_ridging(domain) fpond=pondFreshWaterFlux(iCell), & fresh=oceanFreshWaterFlux(iCell), & fhocn=oceanHeatFlux(iCell), & - n_aero=nAerosols, & faero_ocn=oceanAerosolFlux(:,iCell), & ! DC no fiso_ocn argument aparticn=ridgeParticipationFunction(:,iCell), & krdgn=ratioRidgeThicknessToIce(:,iCell), & @@ -3525,10 +3476,7 @@ subroutine column_biogeochemistry(domain) integer, pointer :: & nCellsSolve, & nCategories, & - nIceLayers, & - nSnowLayers, & nzAerosols, & - nBioLayers, & nBioLayersP1, & nAlgae, & maxBCType, & @@ -3543,10 +3491,6 @@ subroutine column_biogeochemistry(domain) netSpecificAlgalGrowthRate, & primaryProduction, & netBrineHeight, & - biologyGrid, & - interfaceBiologyGrid, & - interfaceGrid, & - verticalGrid, & seaSurfaceTemperature, & seaSurfaceSalinity, & seaFreezingTemperature, & @@ -3698,10 +3642,7 @@ subroutine column_biogeochemistry(domain) call MPAS_pool_get_dimension(mesh, "nCellsSolve", nCellsSolve) call MPAS_pool_get_dimension(mesh, "nCategories", nCategories) - call MPAS_pool_get_dimension(mesh, "nIceLayers", nIceLayers) - call MPAS_pool_get_dimension(mesh, "nSnowLayers", nSnowLayers) call MPAS_pool_get_dimension(mesh, "nzAerosols", nzAerosols) - call MPAS_pool_get_dimension(mesh, "nBioLayers", nBioLayers) call MPAS_pool_get_dimension(mesh, "nBioLayersP1", nBioLayersP1) call MPAS_pool_get_dimension(mesh, "nAlgae", nAlgae) call MPAS_pool_get_dimension(mesh, "maxBCType", maxBCType) @@ -3728,10 +3669,6 @@ subroutine column_biogeochemistry(domain) call MPAS_pool_get_array(biogeochemistry, "brineBottomChange", brineBottomChange) call MPAS_pool_get_array(biogeochemistry, "brineTopChange", brineTopChange) call MPAS_pool_get_array(biogeochemistry, "bioPorosity", bioPorosity) - call MPAS_pool_get_array(biogeochemistry, "biologyGrid", biologyGrid) - call MPAS_pool_get_array(biogeochemistry, "interfaceBiologyGrid", interfaceBiologyGrid) - call MPAS_pool_get_array(biogeochemistry, "interfaceGrid", interfaceGrid) - call MPAS_pool_get_array(biogeochemistry, "verticalGrid", verticalGrid) call MPAS_pool_get_array(biogeochemistry, "bioDiffusivity", bioDiffusivity) call MPAS_pool_get_array(biogeochemistry, "bioPermeability", bioPermeability) call MPAS_pool_get_array(biogeochemistry, "bioShortwaveFlux", bioShortwaveFlux) @@ -3958,14 +3895,6 @@ subroutine column_biogeochemistry(domain) snow_bio_net=totalVerticalBiologySnow(:,iCell), & totalChla=totalChlorophyll(iCell), & fswthrun=penetratingShortwaveFlux(:,iCell), & - bgrid=biologyGrid, & - igrid=interfaceBiologyGrid, & - icgrid=interfaceGrid, & - cgrid=verticalGrid, & - nblyr=nBioLayers, & - nilyr=nIceLayers, & - nslyr=nSnowLayers, & - ncat=nCategories, & meltbn=basalIceMeltCategory(:,iCell), & melttn=surfaceIceMeltCategory(:,iCell), & congeln=congelationCategory(:,iCell), & @@ -4369,8 +4298,7 @@ subroutine seaice_icepack_aggregate(domain) iCell integer, pointer :: & - nCellsSolve, & - nCategories + nCellsSolve integer, dimension(:), pointer :: & indexToCellID @@ -4392,7 +4320,6 @@ subroutine seaice_icepack_aggregate(domain) call MPAS_pool_get_config(block % configs, "config_use_zaerosols", config_use_zaerosols) call MPAS_pool_get_dimension(mesh, "nCellsSolve", nCellsSolve) - call MPAS_pool_get_dimension(mesh, "nCategories", nCategories) call MPAS_pool_get_array(mesh, "indexToCellID", indexToCellID) call MPAS_pool_get_array(tracers, "iceAreaCategory", iceAreaCategory, 1) @@ -4417,7 +4344,6 @@ subroutine seaice_icepack_aggregate(domain) tracerArrayCategory, iCell, setGetPhysicsTracers, setGetBGCTracers) call icepack_aggregate( & - nCategories, & iceAreaCategory(1,:,iCell), & tracerArrayCategory, & ! trcrn iceVolumeCategory(1,:,iCell), & @@ -4427,7 +4353,6 @@ subroutine seaice_icepack_aggregate(domain) iceVolumeCell(iCell), & snowVolumeCell(iCell), & openWaterArea(iCell), & - ciceTracerObject % nTracers, & ciceTracerObject % parentIndex, & ! trcr_depend ciceTracerObject % firstAncestorMask, & ! trcr_base ciceTracerObject % ancestorNumber, & ! n_trcr_strata @@ -5570,18 +5495,12 @@ subroutine seaice_icepack_init_trcr(& initialSalinityProfile, & initialMeltingTemperatureProfile, & surfaceTemperature, & - nIceLayers, & - nSnowLayers, & iceEnthalpy, & snowEnthalpy) use icepack_intfc, only: & icepack_init_trcr - integer, intent(in) :: & - nIceLayers, & ! number of ice layers - nSnowLayers ! number of snow layers - real(kind=RKIND), intent(in) :: & airTemperature, & ! air temperature (C) seaFreezingTemperature ! freezing temperature (C) @@ -5602,8 +5521,6 @@ subroutine seaice_icepack_init_trcr(& initialSalinityProfile, & initialMeltingTemperatureProfile, & surfaceTemperature, & - nIceLayers, & - nSnowLayers, & iceEnthalpy, & snowEnthalpy) @@ -14177,13 +14094,7 @@ subroutine init_column_biogeochemistry_profiles(domain, tracerObject) brineFraction integer, pointer :: & - nCellsSolve, & - nIceLayers, & - nBioLayers, & - nBioLayersP1, & - nBioLayersP2, & - nCategories, & - nShortwaveBio + nCellsSolve integer :: & iCell @@ -14253,21 +14164,13 @@ subroutine init_column_biogeochemistry_profiles(domain, tracerObject) call MPAS_pool_get_array(tracers, "brineFraction", brineFraction, 1) call MPAS_pool_get_dimension(block % dimensions, "nCellsSolve", nCellsSolve) - call MPAS_pool_get_dimension(block % dimensions, "nCategories", nCategories) - call MPAS_pool_get_dimension(block % dimensions, "nIceLayers", nIceLayers) - call MPAS_pool_get_dimension(block % dimensions, "nBioLayers", nBioLayers) - call MPAS_pool_get_dimension(block % dimensions, "nBioLayersP1", nBioLayersP1) - call MPAS_pool_get_dimension(block % dimensions, "nBioLayersP2", nBioLayersP2) - call MPAS_pool_get_dimension(block % dimensions, "nShortwaveBio", nShortwaveBio) call icepack_init_hbrine(& - bgrid=biologyGrid, & - igrid=interfaceBiologyGrid, & - cgrid=verticalGrid, & - icgrid=interfaceGrid, & - swgrid=verticalShortwaveGrid, & - nblyr=nBioLayers, & - nilyr=nIceLayers, & + bgrid_out=biologyGrid, & + igrid_out=interfaceBiologyGrid, & + cgrid_out=verticalGrid, & + icgrid_out=interfaceGrid, & + swgrid_out=verticalShortwaveGrid, & phi_snow=config_snow_porosity_at_ice_surface) do iCell = 1, nCellsSolve @@ -14302,11 +14205,6 @@ subroutine init_column_biogeochemistry_profiles(domain, tracerObject) hum=oceanHumicsConc(iCell)) call icepack_init_bgc(& - ncat=nCategories, & - nblyr=nBioLayers, & - nilyr=nIceLayers, & - cgrid=verticalGrid, & - igrid=interfaceBiologyGrid, & sicen=iceSalinity(:,:,iCell), & trcrn=tracerArrayCategory(tracerObject % nTracersNotBio+1:tracerObject % nTracers,:), & sss=seaSurfaceSalinity(iCell), & diff --git a/components/mpas-seaice/src/shared/mpas_seaice_initialize.F b/components/mpas-seaice/src/shared/mpas_seaice_initialize.F index 12a843a5040c..69f145881758 100644 --- a/components/mpas-seaice/src/shared/mpas_seaice_initialize.F +++ b/components/mpas-seaice/src/shared/mpas_seaice_initialize.F @@ -784,8 +784,6 @@ subroutine init_ice_state_uniform_1D(& initialSalinityProfile(:,iCell), & initialMeltingTemperatureProfile(:,iCell), & surfaceTemperature(1,1,iCell), & - nIceLayers, & - nSnowLayers, & iceEnthalpy(:,1,iCell), & snowEnthalpy(:,1,iCell)) call seaice_icepack_write_warnings(icepack_warnings_aborted()) @@ -990,8 +988,6 @@ subroutine init_ice_cice_default(& initialSalinityProfile(:,iCell), & initialMeltingTemperatureProfile(:,iCell), & surfaceTemperature(1,iCategory,iCell), & - nIceLayers, & - nSnowLayers, & iceEnthalpy(:,iCategory,iCell), & snowEnthalpy(:,iCategory,iCell)) call seaice_icepack_write_warnings(icepack_warnings_aborted()) @@ -1148,7 +1144,6 @@ subroutine initial_category_areas_and_volumes(& if (trim(config_column_physics_type) == "icepack") then call icepack_init_itd(& - nCategories, & categoryThicknessLimits) call seaice_icepack_write_warnings(icepack_warnings_aborted()) else if (trim(config_column_physics_type) == "column_package") then @@ -1341,8 +1336,6 @@ subroutine init_ice_single_cell(& initialSalinityProfile(:,iCell), & initialMeltingTemperatureProfile(:,iCell), & surfaceTemperature(1,iCategory,iCell), & - nIceLayers, & - nSnowLayers, & iceEnthalpy(:,iCategory,iCell), & snowEnthalpy(:,iCategory,iCell)) call seaice_icepack_write_warnings(icepack_warnings_aborted()) @@ -1562,8 +1555,6 @@ subroutine init_ice_ridging(& initialSalinityProfile(:,iCell), & initialMeltingTemperatureProfile(:,iCell), & surfaceTemperature(1,iCategory,iCell), & - nIceLayers, & - nSnowLayers, & iceEnthalpy(:,iCategory,iCell), & snowEnthalpy(:,iCategory,iCell)) call seaice_icepack_write_warnings(icepack_warnings_aborted()) diff --git a/components/mpas-seaice/src/shared/mpas_seaice_velocity_solver.F b/components/mpas-seaice/src/shared/mpas_seaice_velocity_solver.F index f49ac45a9360..3009b618161b 100644 --- a/components/mpas-seaice/src/shared/mpas_seaice_velocity_solver.F +++ b/components/mpas-seaice/src/shared/mpas_seaice_velocity_solver.F @@ -1431,7 +1431,6 @@ subroutine ice_strength(domain) ! this routine doesnt reset icePressure call icepack_ice_strength(& - nCategories, & iceAreaCell(iCell), & iceVolumeCell(iCell), & openWaterArea(iCell), & From 51b8482f3ab1a7754471ef713e7bf0629a54cde3 Mon Sep 17 00:00:00 2001 From: mahf708 Date: Mon, 24 Jun 2024 21:38:42 -0400 Subject: [PATCH 169/451] workaround to point to md snippets outside of the docs dir --- components/eam/tools/mkatmsrffile/test.md | 3 +++ docs/dev-guide/adding-grid-support/index.md | 1 + docs/dev-guide/some-tools/mkatmsrffile.md | 2 ++ mkdocs.yaml | 2 ++ 4 files changed, 8 insertions(+) create mode 100644 components/eam/tools/mkatmsrffile/test.md create mode 100644 docs/dev-guide/some-tools/mkatmsrffile.md diff --git a/components/eam/tools/mkatmsrffile/test.md b/components/eam/tools/mkatmsrffile/test.md new file mode 100644 index 000000000000..bc0ef89536e0 --- /dev/null +++ b/components/eam/tools/mkatmsrffile/test.md @@ -0,0 +1,3 @@ +# test + +Some text goes here. diff --git a/docs/dev-guide/adding-grid-support/index.md b/docs/dev-guide/adding-grid-support/index.md index f7c25043747a..4decc3976d33 100644 --- a/docs/dev-guide/adding-grid-support/index.md +++ b/docs/dev-guide/adding-grid-support/index.md @@ -6,3 +6,4 @@ - [Atmosphere Grid Overview ](../../EAM/tech-guide/atmosphere-grid-overview.md) - [Grid Description File Overview ](adding-grid-support-grid-types.md) - [Step-by-Step Guide to Support a New Grid ](adding-grid-support-step-by-step-guide.md) +- [Some test ](../some-tools/mkatmsrffile.md) diff --git a/docs/dev-guide/some-tools/mkatmsrffile.md b/docs/dev-guide/some-tools/mkatmsrffile.md new file mode 100644 index 000000000000..1c0fec1cf2bd --- /dev/null +++ b/docs/dev-guide/some-tools/mkatmsrffile.md @@ -0,0 +1,2 @@ + +--8<-- 'components/eam/tools/mkatmsrffile/test.md' diff --git a/mkdocs.yaml b/mkdocs.yaml index 5c57a22993c3..66a694115b9c 100644 --- a/mkdocs.yaml +++ b/mkdocs.yaml @@ -9,6 +9,7 @@ nav: - Development: - Introduction: 'dev-guide/index.md' - Adding Support for New Grids: 'dev-guide/adding-grid-support/index.md' + - mkatmsrffile: 'dev-guide/some-tools/mkatmsrffile.md' - Components: '*include ./components/*/mkdocs.yml' - Tools: '*include ./tools/*/mkdocs.yml' - More Information: @@ -57,6 +58,7 @@ markdown_extensions: - pymdownx.details - pymdownx.highlight - pymdownx.superfences + - pymdownx.snippets - pymdownx.tabbed: alternate_style: true - pymdownx.arithmatex: From 52301555cba7c65f0c04d67011c1f73098105d55 Mon Sep 17 00:00:00 2001 From: Walter Hannah Date: Tue, 25 Jun 2024 16:18:02 -0600 Subject: [PATCH 170/451] cosmetic fix for consistency --- .../adding-grid-support-step-by-step-guide/add-grid-config.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/dev-guide/adding-grid-support/adding-grid-support-step-by-step-guide/add-grid-config.md b/docs/dev-guide/adding-grid-support/adding-grid-support-step-by-step-guide/add-grid-config.md index b872658db45e..f46a84afa767 100644 --- a/docs/dev-guide/adding-grid-support/adding-grid-support-step-by-step-guide/add-grid-config.md +++ b/docs/dev-guide/adding-grid-support/adding-grid-support-step-by-step-guide/add-grid-config.md @@ -1,3 +1,3 @@ # Add New Grid Configuration to E3SM -[Back to Adding Support for New Grids](../adding-grid-support-step-by-step-guide.md) +Back to step-by-step guide for [Adding Support for New Grids](../adding-grid-support-step-by-step-guide.md) From 7cd80e3d82d9748b9ef0a5df8c3760a4aa027976 Mon Sep 17 00:00:00 2001 From: Walter Hannah Date: Tue, 25 Jun 2024 16:18:33 -0600 Subject: [PATCH 171/451] add link to unified page --- .../generate-dry-deposition.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/dev-guide/adding-grid-support/adding-grid-support-step-by-step-guide/generate-dry-deposition.md b/docs/dev-guide/adding-grid-support/adding-grid-support-step-by-step-guide/generate-dry-deposition.md index cf777c418a2b..79e6fd017a40 100644 --- a/docs/dev-guide/adding-grid-support/adding-grid-support-step-by-step-guide/generate-dry-deposition.md +++ b/docs/dev-guide/adding-grid-support/adding-grid-support-step-by-step-guide/generate-dry-deposition.md @@ -4,7 +4,7 @@ Atmospheric dry deposition of aerosols at the surface depends on certain surface For unstructured grids it was determined to create this offline interpolation tool rather than generalize the subroutine interp_map. -Be sure to activate the E3SM unified environment when performing the steps below. +Be sure to activate the [E3SM unified environment](https://e3sm.org/resources/tools/other-tools/e3sm-unified-environment/) when performing the steps below. ## Map File Generation From 051837e179b50df38f4d499e10e7dd99a1e5ec4d Mon Sep 17 00:00:00 2001 From: Azamat Mametjanov Date: Tue, 25 Jun 2024 20:07:07 -0700 Subject: [PATCH 172/451] Update low-res perf-tests to match v3 configurations --- .../bench/wcycl/lores/user_nl_eam | 70 ++++++++++++++++--- .../bench/wcycl/lores/user_nl_elm | 46 ++++++++++-- cime_config/tests.py | 22 +++--- 3 files changed, 110 insertions(+), 28 deletions(-) diff --git a/cime_config/testmods_dirs/bench/wcycl/lores/user_nl_eam b/cime_config/testmods_dirs/bench/wcycl/lores/user_nl_eam index eeac1d647b1d..095c6946f5de 100644 --- a/cime_config/testmods_dirs/bench/wcycl/lores/user_nl_eam +++ b/cime_config/testmods_dirs/bench/wcycl/lores/user_nl_eam @@ -1,11 +1,59 @@ - nhtfrq = -24,-24,-6,-6,-3,-24,-24 - mfilt = 1,30,120,120,240,30,1 - avgflag_pertape = 'A','A','I','A','A','A','I' - fexcl1 = 'CFAD_SR532_CAL', 'LINOZ_DO3', 'LINOZ_DO3_PSC', 'LINOZ_O3CLIM', 'LINOZ_O3COL', 'LINOZ_SSO3', 'hstobie_linoz' - fincl1 = 'extinct_sw_inp','extinct_lw_bnd7','extinct_lw_inp','CLD_CAL', 'TREFMNAV', 'TREFMXAV' - fincl2 = 'FLUT','PRECT','U200','V200','U850','V850','Z500','OMEGA500','UBOT','VBOT','TREFHT','TREFHTMN:M','TREFHTMX:X','QREFHT','TS','PS','TMQ','TUQ','TVQ','TOZ', 'FLDS', 'FLNS', 'FSDS', 'FSNS', 'SHFLX', 'LHFLX', 'TGCLDCWP', 'TGCLDIWP', 'TGCLDLWP', 'CLDTOT', 'T250', 'T200', 'T150', 'T100', 'T050', 'T025', 'T010', 'T005', 'T002', 'T001', 'TTOP', 'U250', 'U150', 'U100', 'U050', 'U025', 'U010', 'U005', 'U002', 'U001', 'UTOP', 'FSNT', 'FLNT' - fincl3 = 'PSL','T200','T500','U850','V850','UBOT','VBOT','TREFHT', 'Z700', 'TBOT:M' - fincl4 = 'FLUT','U200','U850','PRECT','OMEGA500' - fincl5 = 'PRECT','PRECC','TUQ','TVQ','QFLX','SHFLX','U90M','V90M' - fincl6 = 'CLDTOT_ISCCP','MEANCLDALB_ISCCP','MEANTAU_ISCCP','MEANPTOP_ISCCP','MEANTB_ISCCP','CLDTOT_CAL','CLDTOT_CAL_LIQ','CLDTOT_CAL_ICE','CLDTOT_CAL_UN','CLDHGH_CAL','CLDHGH_CAL_LIQ','CLDHGH_CAL_ICE','CLDHGH_CAL_UN','CLDMED_CAL','CLDMED_CAL_LIQ','CLDMED_CAL_ICE','CLDMED_CAL_UN','CLDLOW_CAL','CLDLOW_CAL_LIQ','CLDLOW_CAL_ICE','CLDLOW_CAL_UN' - fincl7 = 'O3', 'PS', 'TROP_P' +cosp_lite = .true. + +empty_htapes = .true. + +avgflag_pertape = 'A','A','A','A','I','I' +nhtfrq = -24,-24,-6,-3,-1,-24 +mfilt = 1,30,120,240,720,1 + +fincl1 = 'AODALL','AODBC','AODDUST','AODPOM','AODSO4','AODSOA','AODSS','AODVIS', + 'CLDLOW','CLDMED','CLDHGH','CLDTOT', + 'CLDHGH_CAL','CLDLOW_CAL','CLDMED_CAL','CLD_MISR','CLDTOT_CAL', + 'CLMODIS','FISCCP1_COSP','FLDS','FLNS','FLNSC','FLNT','FLUT', + 'FLUTC','FSDS','FSDSC','FSNS','FSNSC','FSNT','FSNTOA','FSNTOAC','FSNTC', + 'ICEFRAC','LANDFRAC','LWCF','OCNFRAC','OMEGA','PRECC','PRECL','PRECSC','PRECSL','PS','PSL','Q', + 'QFLX','QREFHT','RELHUM','SCO','SHFLX','SOLIN','SWCF','T','TAUX','TAUY','TCO', + 'TGCLDLWP','TMQ','TREFHT','TREFMNAV','TREFMXAV','TS','U','U10','V','Z3', + 'dst_a1DDF','dst_a3DDF','dst_c1DDF','dst_c3DDF','dst_a1SFWET','dst_a3SFWET','dst_c1SFWET','dst_c3SFWET', + 'O3','LHFLX', + 'O3_2DTDA_trop','O3_2DTDB_trop','O3_2DTDD_trop','O3_2DTDE_trop','O3_2DTDI_trop','O3_2DTDL_trop', + 'O3_2DTDN_trop','O3_2DTDO_trop','O3_2DTDS_trop','O3_2DTDU_trop','O3_2DTRE_trop','O3_2DTRI_trop', + 'O3_SRF','NO_2DTDS','NO_TDLgt','NO2_2DTDD','NO2_2DTDS','NO2_TDAcf','CO_SRF','TROPE3D_P','TROP_P', + 'CDNUMC','SFDMS','so4_a1_sfgaex1','so4_a2_sfgaex1','so4_a3_sfgaex1','so4_a5_sfgaex1','soa_a1_sfgaex1', + 'soa_a2_sfgaex1','soa_a3_sfgaex1','GS_soa_a1','GS_soa_a2','GS_soa_a3','AQSO4_H2O2','AQSO4_O3', + 'SFSO2','SO2_CLXF','SO2','DF_SO2','AQ_SO2','GS_SO2','WD_SO2','ABURDENSO4_STR','ABURDENSO4_TRO', + 'ABURDENSO4','ABURDENBC','ABURDENDUST','ABURDENMOM','ABURDENPOM','ABURDENSEASALT', + 'ABURDENSOA','AODSO4_STR','AODSO4_TRO', + 'EXTINCT','AODABS','AODABSBC','CLDICE','CLDLIQ','CLD_CAL_TMPLIQ','CLD_CAL_TMPICE','Mass_bc_srf', + 'Mass_dst_srf','Mass_mom_srf','Mass_ncl_srf','Mass_pom_srf','Mass_so4_srf','Mass_soa_srf','Mass_bc_850', + 'Mass_dst_850','Mass_mom_850','Mass_ncl_850','Mass_pom_850','Mass_so4_850','Mass_soa_850','Mass_bc_500', + 'Mass_dst_500','Mass_mom_500','Mass_ncl_500','Mass_pom_500','Mass_so4_500','Mass_soa_500','Mass_bc_330', + 'Mass_dst_330','Mass_mom_330','Mass_ncl_330','Mass_pom_330','Mass_so4_330','Mass_soa_330','Mass_bc_200', + 'Mass_dst_200','Mass_mom_200','Mass_ncl_200','Mass_pom_200','Mass_so4_200','Mass_soa_200', + 'O3_2DTDD','O3_2DCIP','O3_2DCIL','CO_2DTDS','CO_2DTDD','CO_2DCEP','CO_2DCEL','NO_2DTDD', + 'FLNTC','SAODVIS', + 'H2OLNZ', + 'dst_a1SF','dst_a3SF', + 'PHIS','CLOUD','TGCLDIWP','TGCLDCWP','AREL', + 'CLDTOT_ISCCP','MEANCLDALB_ISCCP','MEANPTOP_ISCCP','CLD_CAL', + 'CLDTOT_CAL_LIQ','CLDTOT_CAL_ICE','CLDTOT_CAL_UN', + 'CLDHGH_CAL_LIQ','CLDHGH_CAL_ICE','CLDHGH_CAL_UN', + 'CLDMED_CAL_LIQ','CLDMED_CAL_ICE','CLDMED_CAL_UN', + 'CLDLOW_CAL_LIQ','CLDLOW_CAL_ICE','CLDLOW_CAL_UN', + 'CLWMODIS','CLIMODIS' + +fincl2 = 'PS', 'FLUT','PRECT','U200','V200','U850','V850', + 'TCO','SCO','TREFHTMN','TREFHTMX','TREFHT','QREFHT' +fincl3 = 'PS', 'PSL','PRECT','TUQ','TVQ','UBOT','VBOT','TREFHT','FLUT','OMEGA500','TBOT','U850','V850','U200','V200','T200','T500','Z700' +fincl4 = 'PRECT' +fincl5 = 'O3_SRF' +fincl6 = 'CO_2DMSD','NO2_2DMSD','NO_2DMSD','O3_2DMSD','O3_2DMSD_trop' + +! -- chemUCI settings ------------------ +history_chemdyg_summary = .true. +history_gaschmbudget_2D = .false. +history_gaschmbudget_2D_levels = .false. +history_gaschmbudget_num = 6 !! no impact if history_gaschmbudget_2D = .false. + +! -- MAM5 settings ------------------ +is_output_interactive_volc = .true. diff --git a/cime_config/testmods_dirs/bench/wcycl/lores/user_nl_elm b/cime_config/testmods_dirs/bench/wcycl/lores/user_nl_elm index a93edc10b690..cd1adab77404 100644 --- a/cime_config/testmods_dirs/bench/wcycl/lores/user_nl_elm +++ b/cime_config/testmods_dirs/bench/wcycl/lores/user_nl_elm @@ -1,6 +1,40 @@ - finidat = ' ' - hist_dov2xy = .true.,.true. - hist_fincl2 = 'H2OSNO', 'FSNO', 'QRUNOFF', 'QSNOMELT', 'FSNO_EFF', 'SNORDSL', 'SNOW', 'FSDS', 'FSR', 'FLDS', 'FIRE', 'FIRA' - hist_mfilt = 1,365 - hist_nhtfrq = -24,-24 - hist_avgflag_pertape = 'A','A' +hist_dov2xy = .true.,.true. +hist_fexcl1 = 'AGWDNPP','ALTMAX_LASTYEAR','AVAIL_RETRANSP','AVAILC','BAF_CROP', + 'BAF_PEATF','BIOCHEM_PMIN_TO_PLANT','CH4_SURF_AERE_SAT','CH4_SURF_AERE_UNSAT','CH4_SURF_DIFF_SAT', + 'CH4_SURF_DIFF_UNSAT','CH4_SURF_EBUL_SAT','CH4_SURF_EBUL_UNSAT','CMASS_BALANCE_ERROR','cn_scalar', + 'COL_PTRUNC','CONC_CH4_SAT','CONC_CH4_UNSAT','CONC_O2_SAT','CONC_O2_UNSAT', + 'cp_scalar','CWDC_HR','CWDC_LOSS','CWDC_TO_LITR2C','CWDC_TO_LITR3C', + 'CWDC_vr','CWDN_TO_LITR2N','CWDN_TO_LITR3N','CWDN_vr','CWDP_TO_LITR2P', + 'CWDP_TO_LITR3P','CWDP_vr','DWT_CONV_CFLUX_DRIBBLED','F_CO2_SOIL','F_CO2_SOIL_vr', + 'F_DENIT_vr','F_N2O_DENIT','F_N2O_NIT','F_NIT_vr','FCH4_DFSAT', + 'FINUNDATED_LAG','FPI_P_vr','FPI_vr','FROOTC_LOSS','HR_vr', + 'LABILEP_TO_SECONDP','LABILEP_vr','LAND_UPTAKE','LEAF_MR','leaf_npimbalance', + 'LEAFC_LOSS','LEAFC_TO_LITTER','LFC2','LITR1_HR','LITR1C_TO_SOIL1C', + 'LITR1C_vr','LITR1N_TNDNCY_VERT_TRANS','LITR1N_TO_SOIL1N','LITR1N_vr','LITR1P_TNDNCY_VERT_TRANS', + 'LITR1P_TO_SOIL1P','LITR1P_vr','LITR2_HR','LITR2C_TO_SOIL2C','LITR2C_vr', + 'LITR2N_TNDNCY_VERT_TRANS','LITR2N_TO_SOIL2N','LITR2N_vr','LITR2P_TNDNCY_VERT_TRANS','LITR2P_TO_SOIL2P', + 'LITR2P_vr','LITR3_HR','LITR3C_TO_SOIL3C','LITR3C_vr','LITR3N_TNDNCY_VERT_TRANS', + 'LITR3N_TO_SOIL3N','LITR3N_vr','LITR3P_TNDNCY_VERT_TRANS','LITR3P_TO_SOIL3P','LITR3P_vr', + 'M_LITR1C_TO_LEACHING','M_LITR2C_TO_LEACHING','M_LITR3C_TO_LEACHING','M_SOIL1C_TO_LEACHING','M_SOIL2C_TO_LEACHING', + 'M_SOIL3C_TO_LEACHING','M_SOIL4C_TO_LEACHING','NDEPLOY','NEM','nlim_m', + 'o2_decomp_depth_unsat','OCCLP_vr','PDEPLOY','PLANT_CALLOC','PLANT_NDEMAND', + 'PLANT_NDEMAND_COL','PLANT_PALLOC','PLANT_PDEMAND','PLANT_PDEMAND_COL','plim_m', + 'POT_F_DENIT','POT_F_NIT','POTENTIAL_IMMOB','POTENTIAL_IMMOB_P','PRIMP_TO_LABILEP', + 'PRIMP_vr','PROD1P_LOSS','QOVER_LAG','RETRANSN_TO_NPOOL','RETRANSP_TO_PPOOL', + 'SCALARAVG_vr','SECONDP_TO_LABILEP','SECONDP_TO_OCCLP','SECONDP_vr','SMIN_NH4_vr', + 'SMIN_NO3_vr','SMINN_TO_SOIL1N_L1','SMINN_TO_SOIL2N_L2','SMINN_TO_SOIL2N_S1','SMINN_TO_SOIL3N_L3', + 'SMINN_TO_SOIL3N_S2','SMINN_TO_SOIL4N_S3','SMINP_TO_SOIL1P_L1','SMINP_TO_SOIL2P_L2','SMINP_TO_SOIL2P_S1', + 'SMINP_TO_SOIL3P_L3','SMINP_TO_SOIL3P_S2','SMINP_TO_SOIL4P_S3','SMINP_vr','SOIL1_HR','SOIL1C_TO_SOIL2C','SOIL1C_vr','SOIL1N_TNDNCY_VERT_TRANS','SOIL1N_TO_SOIL2N','SOIL1N_vr', + 'SOIL1P_TNDNCY_VERT_TRANS','SOIL1P_TO_SOIL2P','SOIL1P_vr','SOIL2_HR','SOIL2C_TO_SOIL3C', + 'SOIL2C_vr','SOIL2N_TNDNCY_VERT_TRANS','SOIL2N_TO_SOIL3N','SOIL2N_vr','SOIL2P_TNDNCY_VERT_TRANS', + 'SOIL2P_TO_SOIL3P','SOIL2P_vr','SOIL3_HR','SOIL3C_TO_SOIL4C','SOIL3C_vr', + 'SOIL3N_TNDNCY_VERT_TRANS','SOIL3N_TO_SOIL4N','SOIL3N_vr','SOIL3P_TNDNCY_VERT_TRANS','SOIL3P_TO_SOIL4P', + 'SOIL3P_vr','SOIL4_HR','SOIL4C_vr','SOIL4N_TNDNCY_VERT_TRANS','SOIL4N_TO_SMINN', + 'SOIL4N_vr','SOIL4P_TNDNCY_VERT_TRANS','SOIL4P_TO_SMINP','SOIL4P_vr','SOLUTIONP_vr', + 'TCS_MONTH_BEGIN','TCS_MONTH_END','TOTCOLCH4','water_scalar','WF', + 'wlim_m','WOODC_LOSS','WTGQ' +hist_fincl1 = 'SNOWDP','COL_FIRE_CLOSS','NPOOL','PPOOL','TOTPRODC' +hist_fincl2 = 'H2OSNO', 'FSNO', 'QRUNOFF', 'QSNOMELT', 'FSNO_EFF', 'SNORDSL', 'SNOW', 'FSDS', 'FSR', 'FLDS', 'FIRE', 'FIRA' +hist_mfilt = 1,365 +hist_nhtfrq = -24,-24 +hist_avgflag_pertape = 'A','A' diff --git a/cime_config/tests.py b/cime_config/tests.py index 6491f85943c9..8828b08ad7e1 100644 --- a/cime_config/tests.py +++ b/cime_config/tests.py @@ -583,20 +583,20 @@ "share" : True, "time" : "03:00:00", "tests" : ( - "PFS_P320.T62_EC30to60E2r2.GMPAS-IAF.bench-gmpas_noio", - "PFS_P480.T62_EC30to60E2r2.GMPAS-IAF.bench-gmpas_noio", - "PFS_P640.T62_EC30to60E2r2.GMPAS-IAF.bench-gmpas_noio", - "PFS_P960.T62_EC30to60E2r2.GMPAS-IAF.bench-gmpas_noio", - "PFS_P1280.T62_EC30to60E2r2.GMPAS-IAF.bench-gmpas_noio", + "PFS_P320.T62_IcoswISC30E3r5.GMPAS-IAF.bench-gmpas_noio", + "PFS_P480.T62_IcoswISC30E3r5.GMPAS-IAF.bench-gmpas_noio", + "PFS_P640.T62_IcoswISC30E3r5.GMPAS-IAF.bench-gmpas_noio", + "PFS_P960.T62_IcoswISC30E3r5.GMPAS-IAF.bench-gmpas_noio", + "PFS_P1280.T62_IcoswISC30E3r5.GMPAS-IAF.bench-gmpas_noio", ) }, "e3sm_bench_lores_f" : { "share" : True, "time" : "03:00:00", "tests" : ( - "PFS_P1350.ne30pg2_EC30to60E2r2.F2010.eam-bench-noio", - "PFS_P2700.ne30pg2_EC30to60E2r2.F2010.eam-bench-noio", - "PFS_P5400.ne30pg2_EC30to60E2r2.F2010.eam-bench-noio", + "PFS_P1350.ne30pg2_r05_IcoswISC30E3r5.F2010.eam-bench-noio", + "PFS_P2700.ne30pg2_r05_IcoswISC30E3r5.F2010.eam-bench-noio", + "PFS_P5400.ne30pg2_r05_IcoswISC30E3r5.F2010.eam-bench-noio", ) }, "e3sm_bench_lores" : { @@ -604,9 +604,9 @@ "inherit" : ("e3sm_bench_lores_g", "e3sm_bench_lores_f"), "time" : "03:00:00", "tests" : ( - "PFS_PS.ne30pg2_EC30to60E2r2.WCYCL1850.bench-wcycl-lores", - "PFS_PM.ne30pg2_EC30to60E2r2.WCYCL1850.bench-wcycl-lores", - "PFS_PL.ne30pg2_EC30to60E2r2.WCYCL1850.bench-wcycl-lores", + "PFS_PS.ne30pg2_r05_IcoswISC30E3r5.WCYCL1850.bench-wcycl-lores", + "PFS_PM.ne30pg2_r05_IcoswISC30E3r5.WCYCL1850.bench-wcycl-lores", + "PFS_PL.ne30pg2_r05_IcoswISC30E3r5.WCYCL1850.bench-wcycl-lores", ) }, "e3sm_bench_all" : { From 53b636a5cbd3d5796021f4983b62d3d73d27e770 Mon Sep 17 00:00:00 2001 From: Walter Hannah Date: Wed, 3 Jul 2024 14:33:44 -0700 Subject: [PATCH 173/451] update docn_comp_mod.F90 --- .../data_comps/docn/src/docn_comp_mod.F90 | 20 +++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/components/data_comps/docn/src/docn_comp_mod.F90 b/components/data_comps/docn/src/docn_comp_mod.F90 index 002ed655b404..ac1278673656 100644 --- a/components/data_comps/docn/src/docn_comp_mod.F90 +++ b/components/data_comps/docn/src/docn_comp_mod.F90 @@ -1178,46 +1178,46 @@ subroutine prescribed_sst(xc, yc, lsize, sst_option, sst) !------------------------------------------------------------------------------- ! RCEMIP phase 2 - Mock-Walker - ! MW_295dT1p25 - mean SST = 295 / dSST = 1.25 K + ! MW_295dT1p25 - mean SST = 295 K / dSST = 1.25 K if (sst_option == 11) then - mean_SST = 295 + mean_SST = 295 - TkFrz delta_SST = 1.25 do i = 1, lsize sst(i) = mean_SST + (delta_SST/2) * cos( rlat(i) * 360/54 ) end do end if - ! MW_300dT0p625 - mean SST = 300 / dSST = 0.625 K + ! MW_300dT0p625 - mean SST = 300 K / dSST = 0.625 K if (sst_option == 12) then - mean_SST = 300 + mean_SST = 300 - TkFrz delta_SST = 0.625 do i = 1, lsize sst(i) = mean_SST + (delta_SST/2) * cos( rlat(i) * 360/54 ) end do end if - ! MW_300dT1p25 - mean SST = 300 / dSST = 1.25 K + ! MW_300dT1p25 - mean SST = 300 K / dSST = 1.25 K if (sst_option == 13) then - mean_SST = 300 + mean_SST = 300 - TkFrz delta_SST = 1.25 do i = 1, lsize sst(i) = mean_SST + (delta_SST/2) * cos( rlat(i) * 360/54 ) end do end if - ! MW_300dT2p5 - mean SST = 300 / dSST = 2.5 K + ! MW_300dT2p5 - mean SST = 300 K / dSST = 2.5 K if (sst_option == 14) then - mean_SST = 300 + mean_SST = 300 - TkFrz delta_SST = 2.5 do i = 1, lsize sst(i) = mean_SST + (delta_SST/2) * cos( rlat(i) * 360/54 ) end do end if - ! MW_305dT1p25 - mean SST = 305 / dSST = 1.25 K + ! MW_305dT1p25 - mean SST = 305 K / dSST = 1.25 K if (sst_option == 15) then - mean_SST = 305 + mean_SST = 305 - TkFrz delta_SST = 1.25 do i = 1, lsize sst(i) = mean_SST + (delta_SST/2) * cos( rlat(i) * 360/54 ) From 57fee69019b3ccc1ed5682966c486cf59bd430ad Mon Sep 17 00:00:00 2001 From: Walter Hannah Date: Wed, 3 Jul 2024 14:34:37 -0700 Subject: [PATCH 174/451] add TOA rad history variables --- .../eam/src/physics/crm/rrtmgp/radiation.F90 | 19 +++++++++++++++++++ .../eam/src/physics/rrtmgp/radiation.F90 | 19 +++++++++++++++++++ 2 files changed, 38 insertions(+) diff --git a/components/eam/src/physics/crm/rrtmgp/radiation.F90 b/components/eam/src/physics/crm/rrtmgp/radiation.F90 index b7b253d1b6c4..b80ea0c2fe10 100644 --- a/components/eam/src/physics/crm/rrtmgp/radiation.F90 +++ b/components/eam/src/physics/crm/rrtmgp/radiation.F90 @@ -768,6 +768,18 @@ subroutine radiation_init(state) call addfld('FLNTC'//diag(icall), horiz_only, 'A', 'W/m2', & 'Clearsky net longwave flux at top of model', & sampling_seq='rad_lwsw', flag_xyfill=.true.) + call addfld('FLUTOA'//diag(icall), horiz_only, 'A', 'W/m2', & + 'Upwelling longwave flux at top of atmosphere', & + sampling_seq='rad_lwsw', flag_xyfill=.true.) + call addfld('FLNTOA'//diag(icall), horiz_only, 'A', 'W/m2', & + 'Net longwave flux at top of atmosphere', & + sampling_seq='rad_lwsw', flag_xyfill=.true.) + call addfld('FLUTOAC'//diag(icall), horiz_only, 'A', 'W/m2', & + 'Clearsky upwelling longwave flux at top of atmosphere', & + sampling_seq='rad_lwsw', flag_xyfill=.true.) + call addfld('FLNTOAC'//diag(icall), horiz_only, 'A', 'W/m2', & + 'Clearsky net longwave flux at top of atmosphere', & + sampling_seq='rad_lwsw', flag_xyfill=.true.) call addfld('LWCF'//diag(icall), horiz_only, 'A', 'W/m2', & 'Longwave cloud forcing', & sampling_seq='rad_lwsw', flag_xyfill=.true.) @@ -2494,6 +2506,7 @@ subroutine output_fluxes_lw(icall, state, flux_all, flux_clr, qrl, qrlc) ! Working arrays real(r8), dimension(pcols,pver+1) :: flux_up, flux_dn, flux_net integer :: ncol + integer :: ktop_rad = 1 ncol = state%ncol @@ -2531,6 +2544,12 @@ subroutine output_fluxes_lw(icall, state, flux_all, flux_clr, qrl, qrlc) call outfld('FLUTC'//diag(icall), flux_clr%flux_up(1:ncol,ktop), ncol, state%lchnk) call outfld('FLDSC'//diag(icall), flux_clr%flux_dn(1:ncol,kbot+1), ncol, state%lchnk) + ! TOA fluxes (above model top, use index to rad top) + call outfld('FLUTOA'//diag(icall), flux_all%flux_up(1:ncol,ktop_rad), ncol, state%lchnk) + call outfld('FLNTOA'//diag(icall), flux_all%flux_net(1:ncol,ktop_rad), ncol, state%lchnk) + call outfld('FLUTOAC'//diag(icall), flux_clr%flux_up(1:ncol,ktop_rad), ncol, state%lchnk) + call outfld('FLNTOAC'//diag(icall), flux_clr%flux_net(1:ncol,ktop_rad), ncol, state%lchnk) + ! Calculate and output the cloud radiative effect (LWCF in history) cloud_radiative_effect(1:ncol) = flux_all%flux_net(1:ncol,ktop) - flux_clr%flux_net(1:ncol,ktop) call outfld('LWCF'//diag(icall), cloud_radiative_effect, ncol, state%lchnk) diff --git a/components/eam/src/physics/rrtmgp/radiation.F90 b/components/eam/src/physics/rrtmgp/radiation.F90 index 0c715000951d..5c87c3376d9d 100644 --- a/components/eam/src/physics/rrtmgp/radiation.F90 +++ b/components/eam/src/physics/rrtmgp/radiation.F90 @@ -767,6 +767,18 @@ subroutine radiation_init(state,pbuf) call addfld('FLNTC'//diag(icall), horiz_only, 'A', 'W/m2', & 'Clearsky net longwave flux at top of model', & sampling_seq='rad_lwsw', flag_xyfill=.true.) + call addfld('FLUTOA'//diag(icall), horiz_only, 'A', 'W/m2', & + 'Upwelling longwave flux at top of atmosphere', & + sampling_seq='rad_lwsw', flag_xyfill=.true.) + call addfld('FLNTOA'//diag(icall), horiz_only, 'A', 'W/m2', & + 'Net longwave flux at top of atmosphere', & + sampling_seq='rad_lwsw', flag_xyfill=.true.) + call addfld('FLUTOAC'//diag(icall), horiz_only, 'A', 'W/m2', & + 'Clearsky upwelling longwave flux at top of atmosphere', & + sampling_seq='rad_lwsw', flag_xyfill=.true.) + call addfld('FLNTOAC'//diag(icall), horiz_only, 'A', 'W/m2', & + 'Clearsky net longwave flux at top of atmosphere', & + sampling_seq='rad_lwsw', flag_xyfill=.true.) call addfld('LWCF'//diag(icall), horiz_only, 'A', 'W/m2', & 'Longwave cloud forcing', & sampling_seq='rad_lwsw', flag_xyfill=.true.) @@ -2375,6 +2387,7 @@ subroutine output_fluxes_lw(icall, state, flux_all, flux_clr, qrl, qrlc) ! Working arrays real(r8), dimension(pcols,pver+1) :: flux_up, flux_dn, flux_net integer :: ncol + integer :: ktop_rad = 1 ncol = state%ncol @@ -2412,6 +2425,12 @@ subroutine output_fluxes_lw(icall, state, flux_all, flux_clr, qrl, qrlc) call outfld('FLUTC'//diag(icall), flux_clr%flux_up(1:ncol,ktop), ncol, state%lchnk) call outfld('FLDSC'//diag(icall), flux_clr%flux_dn(1:ncol,kbot+1), ncol, state%lchnk) + ! TOA fluxes (above model top, use index to rad top) + call outfld('FLUTOA'//diag(icall), flux_all%flux_up(1:ncol,ktop_rad), ncol, state%lchnk) + call outfld('FLNTOA'//diag(icall), flux_all%flux_net(1:ncol,ktop_rad), ncol, state%lchnk) + call outfld('FLUTOAC'//diag(icall), flux_clr%flux_up(1:ncol,ktop_rad), ncol, state%lchnk) + call outfld('FLNTOAC'//diag(icall), flux_clr%flux_net(1:ncol,ktop_rad), ncol, state%lchnk) + ! Calculate and output the cloud radiative effect (LWCF in history) cloud_radiative_effect(1:ncol) = flux_all%flux_net(1:ncol,ktop) - flux_clr%flux_net(1:ncol,ktop) call outfld('LWCF'//diag(icall), cloud_radiative_effect, ncol, state%lchnk) From 71e1d832ca4dbd6924c33e97d0291a1be95e1d0e Mon Sep 17 00:00:00 2001 From: Azamat Mametjanov Date: Wed, 3 Jul 2024 14:51:19 -0700 Subject: [PATCH 175/451] Add high-res perf-test suite --- .../bench/wcycl/hires/shell_commands | 5 ++++ cime_config/tests.py | 28 ++++++++++++------- 2 files changed, 23 insertions(+), 10 deletions(-) diff --git a/cime_config/testmods_dirs/bench/wcycl/hires/shell_commands b/cime_config/testmods_dirs/bench/wcycl/hires/shell_commands index a90a9cc89765..615b8f21ffcd 100644 --- a/cime_config/testmods_dirs/bench/wcycl/hires/shell_commands +++ b/cime_config/testmods_dirs/bench/wcycl/hires/shell_commands @@ -3,3 +3,8 @@ # save benchmark timing info for provenance ./xmlchange SAVE_TIMING=TRUE + +# increase mem-tolerance on pm-cpu to 30% +if [ `./xmlquery --value MACH` == pm-cpu ]; then + ./xmlchange TEST_MEMLEAK_TOLERANCE=0.3 +fi diff --git a/cime_config/tests.py b/cime_config/tests.py index 8828b08ad7e1..a9c4809acad4 100644 --- a/cime_config/tests.py +++ b/cime_config/tests.py @@ -560,13 +560,13 @@ "share" : True, "time" : "03:00:00", "tests" : ( - "PFS_P7200.ne120pg2_r05_EC30to60E2r2.F2010.eam-bench-noio", - "PFS_P8640.ne120pg2_r05_EC30to60E2r2.F2010.eam-bench-noio", - "PFS_P10800.ne120pg2_r05_EC30to60E2r2.F2010.eam-bench-noio", - "PFS_P14400.ne120pg2_r05_EC30to60E2r2.F2010.eam-bench-noio", - "PFS_P21600.ne120pg2_r05_EC30to60E2r2.F2010.eam-bench-noio", - "PFS_P43200.ne120pg2_r05_EC30to60E2r2.F2010.eam-bench-noio", - "PFS_P86400.ne120pg2_r05_EC30to60E2r2.F2010.eam-bench-noio", + "PFS_P7200.ne120pg2_r025_RRSwISC6to18E3r5.F2010.eam-bench-noio", + "PFS_P8640.ne120pg2_r025_RRSwISC6to18E3r5.F2010.eam-bench-noio", + "PFS_P10800.ne120pg2_r025_RRSwISC6to18E3r5.F2010.eam-bench-noio", + "PFS_P14400.ne120pg2_r025_RRSwISC6to18E3r5.F2010.eam-bench-noio", + "PFS_P21600.ne120pg2_r025_RRSwISC6to18E3r5.F2010.eam-bench-noio", + "PFS_P43200.ne120pg2_r025_RRSwISC6to18E3r5.F2010.eam-bench-noio", + "PFS_P86400.ne120pg2_r025_RRSwISC6to18E3r5.F2010.eam-bench-noio", ) }, "e3sm_bench_hires" : { @@ -574,11 +574,19 @@ "inherit" : ("e3sm_bench_hires_g", "e3sm_bench_hires_f"), "time" : "03:00:00", "tests" : ( - "PFS_PS.ne120pg2_r0125_oRRS18to6v3.WCYCL1950.bench-wcycl-hires", - "PFS_PM.ne120pg2_r0125_oRRS18to6v3.WCYCL1950.bench-wcycl-hires", - "PFS_PL.ne120pg2_r0125_oRRS18to6v3.WCYCL1950.bench-wcycl-hires", + "PFS_PS.ne120pg2_r025_RRSwISC6to18E3r5.WCYCL1850NS.bench-wcycl-hires", + "PFS_PM.ne120pg2_r025_RRSwISC6to18E3r5.WCYCL1850NS.bench-wcycl-hires", + "PFS_PL.ne120pg2_r025_RRSwISC6to18E3r5.WCYCL1850NS.bench-wcycl-hires", ) }, + "e3sm_bench_hires_tiny" : { + "time" : "03:00:00", + "tests" : ( + "PFS_P16384.T62_RRSwISC6to18E3r5.GMPAS-IAF.bench-gmpas_noio", + "PFS_P16384.ne120pg2_r025_RRSwISC6to18E3r5.F2010.eam-bench-noio", + "PFS.ne120pg2_r025_RRSwISC6to18E3r5.WCYCL1850NS.bench-wcycl-hires", + ) + }, "e3sm_bench_lores_g" : { "share" : True, "time" : "03:00:00", From 4f116b40bfa9b2e22b83fdde3606a477729f6ebd Mon Sep 17 00:00:00 2001 From: Walter Hannah Date: Tue, 9 Jul 2024 16:21:57 -0600 Subject: [PATCH 176/451] clean up for PR --- docs/dev-guide/adding-grid-support/index.md | 1 - docs/dev-guide/some-tools/mkatmsrffile.md | 2 -- mkdocs.yaml | 2 -- 3 files changed, 5 deletions(-) delete mode 100644 docs/dev-guide/some-tools/mkatmsrffile.md diff --git a/docs/dev-guide/adding-grid-support/index.md b/docs/dev-guide/adding-grid-support/index.md index 4decc3976d33..f7c25043747a 100644 --- a/docs/dev-guide/adding-grid-support/index.md +++ b/docs/dev-guide/adding-grid-support/index.md @@ -6,4 +6,3 @@ - [Atmosphere Grid Overview ](../../EAM/tech-guide/atmosphere-grid-overview.md) - [Grid Description File Overview ](adding-grid-support-grid-types.md) - [Step-by-Step Guide to Support a New Grid ](adding-grid-support-step-by-step-guide.md) -- [Some test ](../some-tools/mkatmsrffile.md) diff --git a/docs/dev-guide/some-tools/mkatmsrffile.md b/docs/dev-guide/some-tools/mkatmsrffile.md deleted file mode 100644 index 1c0fec1cf2bd..000000000000 --- a/docs/dev-guide/some-tools/mkatmsrffile.md +++ /dev/null @@ -1,2 +0,0 @@ - ---8<-- 'components/eam/tools/mkatmsrffile/test.md' diff --git a/mkdocs.yaml b/mkdocs.yaml index 66a694115b9c..5c57a22993c3 100644 --- a/mkdocs.yaml +++ b/mkdocs.yaml @@ -9,7 +9,6 @@ nav: - Development: - Introduction: 'dev-guide/index.md' - Adding Support for New Grids: 'dev-guide/adding-grid-support/index.md' - - mkatmsrffile: 'dev-guide/some-tools/mkatmsrffile.md' - Components: '*include ./components/*/mkdocs.yml' - Tools: '*include ./tools/*/mkdocs.yml' - More Information: @@ -58,7 +57,6 @@ markdown_extensions: - pymdownx.details - pymdownx.highlight - pymdownx.superfences - - pymdownx.snippets - pymdownx.tabbed: alternate_style: true - pymdownx.arithmatex: From 3f69824119af0dad0a12d8c9541430a20449b7d2 Mon Sep 17 00:00:00 2001 From: Jon Wolfe Date: Wed, 10 Jul 2024 13:25:22 -0500 Subject: [PATCH 177/451] Update bld files to match Registry --- components/mpas-seaice/bld/build-namelist | 7 ++++++- .../bld/namelist_files/namelist_defaults_mpassi.xml | 2 -- .../bld/namelist_files/namelist_definition_mpassi.xml | 2 +- 3 files changed, 7 insertions(+), 4 deletions(-) diff --git a/components/mpas-seaice/bld/build-namelist b/components/mpas-seaice/bld/build-namelist index b5faa4ceeb2d..3d7ce2c619f8 100755 --- a/components/mpas-seaice/bld/build-namelist +++ b/components/mpas-seaice/bld/build-namelist @@ -628,7 +628,12 @@ add_default($nl, 'config_recover_tracer_means_check'); ################################## # Namelist group: column_package # ################################## -add_default($nl, 'config_column_physics_type'); + +if ($ice_bgc eq 'ice_bgc') { + add_default($nl, 'config_column_physics_type', 'val'=>"column_package"); +} else { + add_default($nl, 'config_column_physics_type'); +} add_default($nl, 'config_use_column_shortwave'); add_default($nl, 'config_use_column_vertical_thermodynamics'); if ($ice_bgc eq 'ice_bgc') { 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 1ac5bfe8a04b..d840b317785e 100644 --- a/components/mpas-seaice/bld/namelist_files/namelist_defaults_mpassi.xml +++ b/components/mpas-seaice/bld/namelist_files/namelist_defaults_mpassi.xml @@ -80,7 +80,6 @@ 75.0 85.0 75.0 - 70.0 70.0 85.0 @@ -95,7 +94,6 @@ -75.0 -85.0 -75.0 - -60.0 -60.0 -85.0 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 548004a78dcf..efbaef07cb9d 100644 --- a/components/mpas-seaice/bld/namelist_files/namelist_definition_mpassi.xml +++ b/components/mpas-seaice/bld/namelist_files/namelist_definition_mpassi.xml @@ -333,7 +333,7 @@ Default: Defined in namelist_defaults.xml -Sea ice concentration at initialization. +Sea ice fraction at initialization. Valid values: A real number between 0.0 and 1.0 inclusive. Default: Defined in namelist_defaults.xml From 56e9d2efd44924b09ed99eca0331d97999ab3326 Mon Sep 17 00:00:00 2001 From: Walter Hannah Date: Wed, 10 Jul 2024 13:58:10 -0500 Subject: [PATCH 178/451] PAM fixes following SCREAM merge into E3SM --- components/eam/src/physics/crm/pam/CMakeLists.txt | 6 ++++-- components/eam/src/physics/crm/pam/pam_driver.cpp | 6 +++--- 2 files changed, 7 insertions(+), 5 deletions(-) diff --git a/components/eam/src/physics/crm/pam/CMakeLists.txt b/components/eam/src/physics/crm/pam/CMakeLists.txt index 95075debd4fd..4a8f88f669b0 100644 --- a/components/eam/src/physics/crm/pam/CMakeLists.txt +++ b/components/eam/src/physics/crm/pam/CMakeLists.txt @@ -11,6 +11,9 @@ set(PAM_DRIVER_SRC add_library(pam_driver ${PAM_DRIVER_SRC}) +set(SCREAM_HOME ${CMAKE_CURRENT_SOURCE_DIR}/../../../../../..) +add_library(eamxx_physics INTERFACE ${SCREAM_HOME}/components/eamxx/src/physics/) + if (${USE_CUDA}) # PAM will be CUDA-linked with device symbols resolved at library creation set_target_properties(pam_driver @@ -37,7 +40,6 @@ set(PAM_MICRO p3) set(PAM_SGS shoc) set(PAM_RAD forced) set(PAM_SCREAM_USE_CXX True) -set(SCREAM_HOME ${CMAKE_CURRENT_SOURCE_DIR}/../../../../../..) # removing this once the cime cmake_macros aren't using obsolete # Kokkos settings like KOKKOS_OPTIONS. @@ -124,7 +126,7 @@ target_compile_options(pam_driver PUBLIC ) if (PAM_SCREAM_USE_CXX) - target_link_libraries(pam_driver pam_core physics dynamics pam_scream_cxx_interfaces ekat p3 shoc physics_share scream_share) + target_link_libraries(pam_driver pam_core physics dynamics pam_scream_cxx_interfaces ekat p3 shoc physics_share scream_share eamxx_physics) else() target_link_libraries(pam_driver pam_core physics dynamics ) endif() diff --git a/components/eam/src/physics/crm/pam/pam_driver.cpp b/components/eam/src/physics/crm/pam/pam_driver.cpp index 5fd1c5071d16..c7038343f08a 100644 --- a/components/eam/src/physics/crm/pam/pam_driver.cpp +++ b/components/eam/src/physics/crm/pam/pam_driver.cpp @@ -70,13 +70,13 @@ inline int pam_driver_set_subcycle_timestep( pam::PamCoupler &coupler, real crm_ real crm_dz = input_zint(k_gcm,n) - input_zint(k_gcm+1,n); real cfl_u = uvel_max(k,n)*crm_dt_fixed/crm_dx; real cfl_w = wvel_max(k,n)*crm_dt_fixed/crm_dz; - cfl_max(k,n) = max(cfl_u,cfl_w); + cfl_max(k,n) = std::max(cfl_u,cfl_w); }); // calculate final CFL across ensemble real cfl_loc = yakl::intrinsics::maxval(cfl_max); - cfl = max(cfl,cfl_loc); + cfl = std::max(cfl,cfl_loc); // update number of subcycles and time step - num_subcycle = max(num_subcycle,max(1,static_cast(ceil(cfl/0.7)))); + num_subcycle = std::max(num_subcycle,std::max(1,static_cast(ceil(cfl/0.7)))); real crm_dt_subcycle = crm_dt_fixed / num_subcycle; coupler.set_option("crm_dt",crm_dt_subcycle); // check for excessive subcylcing - don't exit, just print From 4c94ac4cfb67e41c217c457c5de9c09363aba9a0 Mon Sep 17 00:00:00 2001 From: Jon Wolfe Date: Wed, 10 Jul 2024 14:47:02 -0500 Subject: [PATCH 179/451] Add mesh-dependent dust_iron_file to streams --- components/mpas-seaice/cime_config/buildnml | 20 +++++++++++++------- 1 file changed, 13 insertions(+), 7 deletions(-) diff --git a/components/mpas-seaice/cime_config/buildnml b/components/mpas-seaice/cime_config/buildnml index c79de6314b06..2b7ca33eba21 100755 --- a/components/mpas-seaice/cime_config/buildnml +++ b/components/mpas-seaice/cime_config/buildnml @@ -72,6 +72,7 @@ def buildnml(case, caseroot, compname): decomp_prefix = '' data_iceberg_file = '' points_file = '' + dust_iron_file = '' if ice_grid == 'oEC60to30v3': decomp_date = '230424' @@ -299,6 +300,7 @@ def buildnml(case, caseroot, compname): decomp_date = '20231120' decomp_prefix = 'partitions/mpas-seaice.graph.info.' data_iceberg_file = 'Iceberg_Climatology_Merino.IcoswISC30E3r5.20231120.nc' + dust_iron_file = 'ecoForcingSurfaceMonthly+WetDryDustSolFrac.IcoswISC30E3r5.20240511.nc' if ice_ic_mode == 'spunup': if iceberg_mode == 'data': grid_date = '20240207' @@ -346,6 +348,8 @@ def buildnml(case, caseroot, compname): input_list.write("points = {}/ice/mpas-seaice/{}/{}\n".format(din_loc_root, ice_mask, points_file)) if iceberg_mode == 'data': input_list.write("data_iceberg = {}/ice/mpas-seaice/{}/{}\n".format(din_loc_root, ice_mask, data_iceberg_file)) + if dust_iron_file != '': + input_list.write("dust_iron = {}/ocn/mpas-o/{}/{}\n".format(din_loc_root, ice_mask, dust_iron_file)) #-------------------------------------------------------------------- # Invoke mpas build-namelist - output will go in $CASEBUILD/mpassiconf @@ -591,13 +595,15 @@ def buildnml(case, caseroot, compname): lines.append(' filename_interval="none"') lines.append(' input_interval="none" />') lines.append('') - lines.append('') - lines.append('') + if dust_iron_file != '': + lines.append('') + lines.append('') + lines.append('') From d56618a94cc405089b10323334c7a94f6ad854f7 Mon Sep 17 00:00:00 2001 From: Irena Vankova Date: Tue, 9 Jul 2024 12:22:14 -0600 Subject: [PATCH 180/451] resolved: registry topodrag --- components/mpas-ocean/src/Registry.xml | 21 ++++++++++++++- .../src/shared/mpas_ocn_diagnostics.F | 26 ++++++++++++++----- .../mpas-ocean/src/shared/mpas_ocn_forcing.F | 19 +++++++++++++- .../shared/mpas_ocn_surface_bulk_forcing.F | 18 +++++++++---- .../mpas-ocean/src/shared/mpas_ocn_tendency.F | 20 ++++++++++---- .../src/shared/mpas_ocn_thick_surface_flux.F | 26 ++++++++++++++----- 6 files changed, 105 insertions(+), 25 deletions(-) diff --git a/components/mpas-ocean/src/Registry.xml b/components/mpas-ocean/src/Registry.xml index 825fe607a5b4..0ed2b0c42462 100644 --- a/components/mpas-ocean/src/Registry.xml +++ b/components/mpas-ocean/src/Registry.xml @@ -702,6 +702,10 @@ description="The length scale of exponential decay of river runoff. Fluxes are multiplied by $e^{z/\gamma}$, where this coefficient is $\gamma$." possible_values="Any positive real number." /> + + @@ -3347,6 +3352,9 @@ + + - + + \date 15 September 2011 !> \details !> This routine computes the horizontal advection tendency for -!> thicknes based on current state and user choices of forcings. +!> thickness based on current state and user choices of forcings. ! !----------------------------------------------------------------------- subroutine ocn_thick_surface_flux_tend(transmissionCoefficients, transmissionCoefficientsRunoff, & - surfaceThicknessFlux, surfaceThicknessFluxRunoff, tend, err)!{{{ + transmissionCoefficientsSubglacialRunoff, surfaceThicknessFlux, surfaceThicknessFluxRunoff, & + surfaceThicknessFluxSubglacialRunoff, tend, err)!{{{ !----------------------------------------------------------------- ! ! input variables @@ -83,11 +84,13 @@ subroutine ocn_thick_surface_flux_tend(transmissionCoefficients, transmissionCoe real (kind=RKIND), dimension(:,:), intent(in) :: & transmissionCoefficients, &!< Input: Coefficients for the transmission of surface fluxes - transmissionCoefficientsRunoff !< Input: Coefficients for the transmission of surface fluxes due to river runoff + transmissionCoefficientsRunoff, &!< Input: Coefficients for the transmission of surface fluxes due to river runoff + transmissionCoefficientsSubglacialRunoff !< Input: Coefficients for the transmission of surface fluxes due to river runoff real (kind=RKIND), dimension(:), intent(in) :: & surfaceThicknessFlux, &!< Input: surface flux of thickness - surfaceThicknessFluxRunoff !< Input: surface flux of thickness due to river runoff + surfaceThicknessFluxRunoff, &!< Input: surface flux of thickness due to river runoff + surfaceThicknessFluxSubglacialRunoff !< Input: surface flux of thickness due to subglacial runoff !----------------------------------------------------------------- @@ -124,10 +127,11 @@ subroutine ocn_thick_surface_flux_tend(transmissionCoefficients, transmissionCoe call mpas_timer_start("thick surface flux") #ifdef MPAS_OPENACC - !$acc enter data copyin(transmissionCoefficients, transmissionCoefficientsRunoff) + !$acc enter data copyin(transmissionCoefficients, transmissionCoefficientsRunoff, transmissionCoefficientsSubglacialRunoff) !$acc parallel loop & !$acc present(tend, surfaceThicknessFlux, surfaceThicknessFluxRunoff, & + !$acc surfaceThicknessFluxSubglacialRunoff, transmissionCoefficientsSubglacialRunoff, & !$acc transmissionCoefficients, transmissionCoefficientsRunoff, minLevelCell, maxLevelCell) & !$acc private(k, remainingFlux, remainingFluxRunoff) #else @@ -137,12 +141,15 @@ subroutine ocn_thick_surface_flux_tend(transmissionCoefficients, transmissionCoe do iCell = 1, nCellsOwned remainingFlux = 1.0_RKIND remainingFluxRunoff = 1.0_RKIND + remainingFluxSubglacialRunoff = 1.0_RKIND do k = minLevelCell(iCell), maxLevelCell(iCell) remainingFlux = remainingFlux - transmissionCoefficients(k, iCell) remainingFluxRunoff = remainingFluxRunoff - transmissionCoefficientsRunoff(k, iCell) + remainingFluxSubglacialRunoff = remainingFluxSubglacialRunoff - transmissionCoefficientsSubglacialRunoff(k, iCell) tend(k, iCell) = tend(k, iCell) + surfaceThicknessFlux(iCell) * transmissionCoefficients(k, iCell) & - + surfaceThicknessFluxRunoff(iCell) * transmissionCoefficientsRunoff(k, iCell) + + surfaceThicknessFluxRunoff(iCell) * transmissionCoefficientsRunoff(k, iCell) & + + surfaceThicknessFluxSubglacialRunoff(iCell) * transmissionCoefficientsSubglacialRunoff(k, iCell) end do if(maxLevelCell(iCell) > 0 .and. remainingFlux > 0.0_RKIND) then @@ -153,6 +160,11 @@ subroutine ocn_thick_surface_flux_tend(transmissionCoefficients, transmissionCoe tend(maxLevelCell(iCell), iCell) = tend(maxLevelCell(iCell), iCell) & + remainingFluxRunoff * surfaceThicknessFluxRunoff(iCell) end if + + if(maxLevelCell(iCell) > 0 .and. remainingFluxSubglacialRunoff > 0.0_RKIND) then + tend(maxLevelCell(iCell), iCell) = tend(maxLevelCell(iCell), iCell) & + + remainingFluxSubglacialRunoff * surfaceThicknessFluxSubglacialRunoff(iCell) + end if end do #ifndef MPAS_OPENACC !$omp end do @@ -160,7 +172,7 @@ subroutine ocn_thick_surface_flux_tend(transmissionCoefficients, transmissionCoe #endif #ifdef MPAS_OPENACC - !$acc exit data delete(transmissionCoefficients, transmissionCoefficientsRunoff) + !$acc exit data delete(transmissionCoefficients, transmissionCoefficientsRunoff, transmissionCoefficientsSubglacialRunoff) #endif call mpas_timer_stop("thick surface flux") From f57b015c4c3532f94787fca00f3ed1a7a0ddb054 Mon Sep 17 00:00:00 2001 From: Irena Vankova Date: Tue, 9 Jul 2024 12:23:19 -0600 Subject: [PATCH 181/451] resolved: gitignore --- .gitignore | 13 +++++++++++++ .../mpas-ocean/src/shared/mpas_ocn_diagnostics.F | 13 +++++++++++++ .../src/shared/mpas_ocn_diagnostics_variables.F | 13 ++++++++++--- 3 files changed, 36 insertions(+), 3 deletions(-) diff --git a/.gitignore b/.gitignore index d7a1fabfd6bc..d2fcc80bbb71 100644 --- a/.gitignore +++ b/.gitignore @@ -51,3 +51,16 @@ components/eamxx/docs/common/eamxx_params.md components/eamxx/src/python/build components/eamxx/src/python/build_src components/eamxx/src/python/dist + +# OS generated files # +###################### +.DS_Store +.DS_Store? +._* +.Spotlight-V100 +.Trashes +ehthumbs.db +Thumbs.db + +# idea folder +.idea/ diff --git a/components/mpas-ocean/src/shared/mpas_ocn_diagnostics.F b/components/mpas-ocean/src/shared/mpas_ocn_diagnostics.F index a8807b995067..0ca331b57b68 100644 --- a/components/mpas-ocean/src/shared/mpas_ocn_diagnostics.F +++ b/components/mpas-ocean/src/shared/mpas_ocn_diagnostics.F @@ -4442,6 +4442,19 @@ subroutine ocn_validate_state(domain, timeLevel)!{{{ call ocn_write_field_statistics(debugUnit, fieldName, minValue, maxValue) end if + ! Test riverRunoffFlux + fieldName = 'subglacialRunoffFlux' + minValue = HUGE(minValue) + maxValue = -HUGE(maxValue) + call mpas_pool_get_array(forcingPool, fieldName, real1DArr) + if ( associated(real1DArr) ) then + do iCell = 1, nCellsSolve + minValue = min( minValue, real1DArr(iCell) ) + maxValue = max( maxValue, real1DArr(iCell) ) + end do + call ocn_write_field_statistics(debugUnit, fieldName, minValue, maxValue) + end if + ! Test seaIceSalinityFlux fieldName = 'seaIceSalinityFlux' minValue = HUGE(minValue) diff --git a/components/mpas-ocean/src/shared/mpas_ocn_diagnostics_variables.F b/components/mpas-ocean/src/shared/mpas_ocn_diagnostics_variables.F index 30a62f68c8b9..38f32f88e17c 100644 --- a/components/mpas-ocean/src/shared/mpas_ocn_diagnostics_variables.F +++ b/components/mpas-ocean/src/shared/mpas_ocn_diagnostics_variables.F @@ -85,6 +85,7 @@ module ocn_diagnostics_variables real (kind=RKIND), dimension(:), pointer :: sfcFlxAttCoeff real (kind=RKIND), dimension(:), pointer :: surfaceFluxAttenuationCoefficientRunoff + real (kind=RKIND), dimension(:), pointer :: surfaceFluxAttenuationCoefficientSubglacialRunoff real (kind=RKIND), dimension(:), pointer :: landIceFrictionVelocity real (kind=RKIND), dimension(:), pointer :: velocityTidalRMS @@ -680,6 +681,9 @@ subroutine ocn_diagnostics_variables_init(domain, jenkinsOn, hollandJenkinsOn, e call mpas_pool_get_array(diagnosticsPool, & 'surfaceFluxAttenuationCoefficientRunoff', & surfaceFluxAttenuationCoefficientRunoff) + call mpas_pool_get_array(diagnosticsPool, & + 'surfaceFluxAttenuationCoefficientSubglacialRunoff', & + surfaceFluxAttenuationCoefficientSubglacialRunoff) call mpas_pool_get_array(diagnosticsPool, & 'boundaryLayerDepth', & boundaryLayerDepth) @@ -964,7 +968,8 @@ subroutine ocn_diagnostics_variables_init(domain, jenkinsOn, hollandJenkinsOn, e !$acc Time_bnds, & !$acc simulationStartTime, & !$acc boundaryLayerDepthSmooth, & - !$acc surfaceFluxAttenuationCoefficientRunoff & + !$acc surfaceFluxAttenuationCoefficientRunoff, & + !$acc surfaceFluxAttenuationCoefficientSubglacialRunoff & !$acc ) end subroutine ocn_diagnostics_variables_init!}}} @@ -1223,7 +1228,8 @@ subroutine ocn_diagnostics_variables_destroy(err) !{{{ !$acc Time_bnds, & !$acc simulationStartTime, & !$acc boundaryLayerDepthSmooth, & - !$acc surfaceFluxAttenuationCoefficientRunoff & + !$acc surfaceFluxAttenuationCoefficientRunoff, & + !$acc surfaceFluxAttenuationCoefficientSubglacialRunoff & !$acc ) ! Nullify pointers @@ -1425,7 +1431,8 @@ subroutine ocn_diagnostics_variables_destroy(err) !{{{ Time_bnds, & simulationStartTime, & boundaryLayerDepthSmooth, & - surfaceFluxAttenuationCoefficientRunoff) + surfaceFluxAttenuationCoefficientRunoff, & + surfaceFluxAttenuationCoefficientSubglacialRunoff) end subroutine ocn_diagnostics_variables_destroy!}}} From b4198e827e55af9f6c29cfe3510de83de20a1a46 Mon Sep 17 00:00:00 2001 From: Irena Vankova Date: Wed, 18 Oct 2023 17:28:44 -0600 Subject: [PATCH 182/451] subglacial runoff for tracers, part 1 --- .../src/shared/mpas_ocn_diagnostics.F | 22 ++++++++-- .../shared/mpas_ocn_surface_bulk_forcing.F | 21 +++++++--- .../mpas-ocean/src/shared/mpas_ocn_tendency.F | 31 +++++++++++--- .../src/shared/mpas_ocn_thick_surface_flux.F | 2 +- .../mpas_ocn_tracer_surface_flux_to_tend.F | 40 ++++++++++++++++++- 5 files changed, 98 insertions(+), 18 deletions(-) diff --git a/components/mpas-ocean/src/shared/mpas_ocn_diagnostics.F b/components/mpas-ocean/src/shared/mpas_ocn_diagnostics.F index 0ca331b57b68..4e75d743130a 100644 --- a/components/mpas-ocean/src/shared/mpas_ocn_diagnostics.F +++ b/components/mpas-ocean/src/shared/mpas_ocn_diagnostics.F @@ -3298,6 +3298,7 @@ subroutine ocn_compute_KPP_input_fields(statePool, forcingPool, & real (kind=RKIND) :: & fracAbsorbed, &! fraction of sfc flux absorbed fracAbsorbedRunoff, &! same for runoff + fracAbsorbedSubglacialRunoff, &! same for subglacial runoff sumSurfaceStressSquared ! sum of sfc stress squared ! pointers for variable/pool retrievals @@ -3313,6 +3314,7 @@ subroutine ocn_compute_KPP_input_fields(statePool, forcingPool, & penetrativeTemperatureFlux, &! various sfc flux components surfaceThicknessFlux, & surfaceThicknessFluxRunoff, & + surfaceThicknessFluxSubglacialRunoff, & rainTemperatureFlux, & evapTemperatureFlux, & icebergTemperatureFlux, & @@ -3325,6 +3327,7 @@ subroutine ocn_compute_KPP_input_fields(statePool, forcingPool, & normalVelocity, &! normal velocity activeTracersSurfaceFlux, &! sfc flux of active tracers (T,S) activeTracersSurfaceFluxRunoff, &! flx of tracers in runoff + activeTracersSurfaceFluxSubglacialRunoff, &! flx of tracers in subglacial runoff nonLocalSurfaceTracerFlux ! non-local flux of tracers real (kind=RKIND), dimension(:,:,:), pointer :: & @@ -3388,11 +3391,16 @@ subroutine ocn_compute_KPP_input_fields(statePool, forcingPool, & call mpas_pool_get_array(tracersSurfaceFluxPool, & 'activeTracersSurfaceFluxRunoff', & activeTracersSurfaceFluxRunoff) + call mpas_pool_get_array(tracersSurfaceFluxPool, & + 'activeTracersSurfaceFluxSubglacialRunoff', & + activeTracersSurfaceFluxSubglacialRunoff) call mpas_pool_get_array(forcingPool, 'surfaceThicknessFlux', & surfaceThicknessFlux) call mpas_pool_get_array(forcingPool, 'surfaceThicknessFluxRunoff', & surfaceThicknessFluxRunoff) + call mpas_pool_get_array(forcingPool, 'surfaceThicknessFluxSubglacialRunoff', & + surfaceThicknessFluxSubglacialRunoff) call mpas_pool_get_array(forcingPool, 'penetrativeTemperatureFlux', & penetrativeTemperatureFlux) call mpas_pool_get_array(forcingPool, 'surfaceStress', & @@ -3465,7 +3473,7 @@ subroutine ocn_compute_KPP_input_fields(statePool, forcingPool, & !$omp parallel !$omp do schedule(runtime) & - !$omp private(kmin, fracAbsorbed, fracAbsorbedRunoff, & + !$omp private(kmin, fracAbsorbed, fracAbsorbedRunoff, fracAbsorbedSubglacialRunoff, & !$omp sumSurfaceStressSquared, i, iEdge) do iCell = 1, nCells @@ -3479,6 +3487,10 @@ subroutine ocn_compute_KPP_input_fields(statePool, forcingPool, & - exp( max(-100.0_RKIND, & -layerThickness(kmin, iCell)/ & config_flux_attenuation_coefficient_runoff)) + fracAbsorbedSubglacialRunoff = 1.0_RKIND & + - exp( max(-100.0_RKIND, & + -layerThickness(kmin, iCell)/ & + config_flux_attenuation_coefficient_subglacial_runoff)) ! Store the total tracer flux below in ! nonLocalSurfaceTemperatureFlux for use in the CVMix nonlocal @@ -3493,13 +3505,17 @@ subroutine ocn_compute_KPP_input_fields(statePool, forcingPool, & seaIceTemperatureFlux(iCell) + & icebergTemperatureFlux(iCell)) & - fracAbsorbedRunoff* & - activeTracersSurfaceFluxRunoff(indexTempFlux,iCell) + activeTracersSurfaceFluxRunoff(indexTempFlux,iCell) & + - fracAbsorbedSubglacialRunoff* & + activeTracersSurfaceFluxSubglacialRunoff(indexTempFlux,iCell) nonLocalSurfaceTracerFlux(indexSaltFlux,iCell) = & activeTracersSurfaceFlux(indexSaltFlux,iCell) & - fracAbsorbed*surfaceThicknessFlux(iCell)* & activeTracers(indexSaltFlux,kmin,iCell) & - fracAbsorbedRunoff*surfaceThicknessFluxRunoff(iCell)* & + activeTracers(indexSaltFlux,kmin,iCell) & + - fracAbsorbedSubglacialRunoff*surfaceThicknessFluxSubglacialRunoff(iCell)* & activeTracers(indexSaltFlux,kmin,iCell) surfaceBuoyancyForcing(iCell) = & @@ -4442,7 +4458,7 @@ subroutine ocn_validate_state(domain, timeLevel)!{{{ call ocn_write_field_statistics(debugUnit, fieldName, minValue, maxValue) end if - ! Test riverRunoffFlux + ! Test subglacialRunoffFlux fieldName = 'subglacialRunoffFlux' minValue = HUGE(minValue) maxValue = -HUGE(maxValue) diff --git a/components/mpas-ocean/src/shared/mpas_ocn_surface_bulk_forcing.F b/components/mpas-ocean/src/shared/mpas_ocn_surface_bulk_forcing.F index ca0ca9fc4b89..f37305381792 100644 --- a/components/mpas-ocean/src/shared/mpas_ocn_surface_bulk_forcing.F +++ b/components/mpas-ocean/src/shared/mpas_ocn_surface_bulk_forcing.F @@ -78,7 +78,7 @@ module ocn_surface_bulk_forcing !----------------------------------------------------------------------- subroutine ocn_surface_bulk_forcing_tracers(meshPool, groupName, forcingPool, tracerGroup, & - tracersSurfaceFlux, tracersSurfaceFluxRunoff, tracersSurfaceFluxRemoved, dt, layerThickness, err)!{{{ + tracersSurfaceFlux, tracersSurfaceFluxRunoff, tracersSurfaceFluxSubglacialRunoff, tracersSurfaceFluxRemoved, dt, layerThickness, err)!{{{ !----------------------------------------------------------------- ! @@ -98,6 +98,8 @@ subroutine ocn_surface_bulk_forcing_tracers(meshPool, groupName, forcingPool, tr real (kind=RKIND), dimension(:,:), intent(inout) :: tracersSurfaceFlux !< Input/Output: Surface flux for tracer group real (kind=RKIND), dimension(:,:), intent(inout) :: & tracersSurfaceFluxRunoff !< Input/Output: Surface flux for tracer group due to river runoff + real (kind=RKIND), dimension(:,:), intent(inout) :: & + tracersSurfaceFluxSubglacialRunoff !< Input/Output: Surface flux for tracer group due to subglacial runoff real (kind=RKIND), dimension(:,:), intent(inout) :: & tracersSurfaceFluxRemoved !< Input/Output: Accumulator for ignored Surface flux for tracer group real (kind=RKIND), dimension(:,:), intent(in) :: layerThickness @@ -122,7 +124,7 @@ subroutine ocn_surface_bulk_forcing_tracers(meshPool, groupName, forcingPool, tr call mpas_timer_start("bulk_" // trim(groupName)) if ( trim(groupName) == 'activeTracers' ) then call ocn_surface_bulk_forcing_active_tracers(meshPool, forcingPool, tracerGroup, & - tracersSurfaceFlux, tracersSurfaceFluxRunoff, tracersSurfaceFluxRemoved, layerThickness, dt, err) + tracersSurfaceFlux, tracersSurfaceFluxRunoff, tracersSurfaceFluxSubglacialRunoff, tracersSurfaceFluxRemoved, layerThickness, dt, err) end if call mpas_timer_stop("bulk_" // trim(groupName)) @@ -426,7 +428,7 @@ end subroutine ocn_surface_bulk_forcing_init!}}} !----------------------------------------------------------------------- subroutine ocn_surface_bulk_forcing_active_tracers(meshPool, forcingPool, tracerGroup, & - tracersSurfaceFlux, tracersSurfaceFluxRunoff, tracersSurfaceFluxRemoved, layerThickness, dt, err)!{{{ + tracersSurfaceFlux, tracersSurfaceFluxRunoff, tracersSurfaceFluxSubglacialRunoff, tracersSurfaceFluxRemoved, layerThickness, dt, err)!{{{ !----------------------------------------------------------------- ! @@ -443,6 +445,7 @@ subroutine ocn_surface_bulk_forcing_active_tracers(meshPool, forcingPool, tracer type (mpas_pool_type), intent(inout) :: forcingPool !< Input: Forcing information real (kind=RKIND), dimension(:,:), intent(inout) :: tracersSurfaceFlux real (kind=RKIND), dimension(:,:), intent(inout) :: tracersSurfaceFluxRunoff + real (kind=RKIND), dimension(:,:), intent(inout) :: tracersSurfaceFluxSubglacialRunoff real (kind=RKIND), dimension(:,:), intent(inout) :: tracersSurfaceFluxRemoved real (kind=RKIND), dimension(:,:,:), intent(inout) :: tracerGroup real (kind=RKIND), dimension(:,:), intent(in) :: layerThickness @@ -470,7 +473,7 @@ subroutine ocn_surface_bulk_forcing_active_tracers(meshPool, forcingPool, tracer type(mpas_pool_type),pointer :: tracersSurfaceFluxPool real (kind=RKIND), dimension(:), pointer :: latentHeatFlux, sensibleHeatFlux, longWaveHeatFluxUp, longWaveHeatFluxDown, & - seaIceHeatFlux, icebergHeatFlux, evaporationFlux, riverRunoffFlux + seaIceHeatFlux, icebergHeatFlux, evaporationFlux, riverRunoffFlux, subglacialRunoffFlux real (kind=RKIND), dimension(:), pointer :: seaIceFreshWaterFlux, icebergFreshWaterFlux, seaIceSalinityFlux, iceRunoffFlux real (kind=RKIND), dimension(:), pointer :: shortWaveHeatFlux, penetrativeTemperatureFlux real (kind=RKIND), dimension(:), pointer :: snowFlux, rainFlux @@ -572,6 +575,11 @@ subroutine ocn_surface_bulk_forcing_active_tracers(meshPool, forcingPool, tracer tracersSurfaceFluxRunoff(index_temperature_flux,iCell) = riverRunoffFlux(iCell) & * max(tracerGroup(index_temperature_flux,minLevelCell(iCell),iCell), 0.0_RKIND) / rho_sw + ! Subglacial runoff can have temperature below 0.0C, since it can come out at great depth + tracersSurfaceFluxSubglacialRunoff(index_temperature_flux,iCell) = subglacialRunoffFlux(iCell) * & + ocn_freezing_temperature(salinity=0.0_RKIND, pressure=interfacePressure(iCell), & + inLandIceCavity=.true.) / rho_sw + ! Accumulate fluxes that use the freezing point ! mrp performance note: should call ocn_freezing_temperature just once here seaIceTemperatureFlux(iCell) = seaIceFreshWaterFlux(iCell) * & @@ -587,9 +595,10 @@ subroutine ocn_surface_bulk_forcing_active_tracers(meshPool, forcingPool, tracer tracersSurfaceFlux(index_temperature_flux, iCell) = tracersSurfaceFlux(index_temperature_flux, iCell) & + surfaceTemperatureFluxWithoutRunoff - ! add runoff contribution for sending through coupler + ! add river and subglacial runoff contribution for sending through coupler totalFreshWaterTemperatureFlux(iCell) = surfaceTemperatureFluxWithoutRunoff & - + tracersSurfaceFluxRunoff(index_temperature_flux,iCell) + + tracersSurfaceFluxRunoff(index_temperature_flux,iCell) & + + tracersSurfaceFluxSubglacialRunoff(index_temperature_flux,iCell) ! Fields with zero temperature are not accumulated. These include: ! snowFlux diff --git a/components/mpas-ocean/src/shared/mpas_ocn_tendency.F b/components/mpas-ocean/src/shared/mpas_ocn_tendency.F index 10188a3be11c..2d3dd66cbdb9 100644 --- a/components/mpas-ocean/src/shared/mpas_ocn_tendency.F +++ b/components/mpas-ocean/src/shared/mpas_ocn_tendency.F @@ -134,7 +134,8 @@ subroutine ocn_tend_thick(tendPool, forcingPool)!{{{ real (kind=RKIND), dimension(:,:), pointer, contiguous :: & tendThick, &! accumulated layer thickness tendency fractionAbsorbed, &! fraction of sfc flux absorbed - fractionAbsorbedRunoff ! fraction of runoff flux absorbed + fractionAbsorbedRunoff, &! fraction of sfc flux absorbed + fractionAbsorbedSubglacialRunoff ! fraction of subglacial runoff flux absorbed !----------------------------------------------------------------- ! local variables @@ -161,6 +162,10 @@ subroutine ocn_tend_thick(tendPool, forcingPool)!{{{ fractionAbsorbed) call mpas_pool_get_array(forcingPool, 'fractionAbsorbedRunoff', & fractionAbsorbedRunoff) + call mpas_pool_get_array(forcingPool, 'fractionAbsorbedSubglacialRunoff', & + fractionAbsorbedSubglacialRunoff) + + ! ! layer thickness tendency: @@ -610,9 +615,11 @@ subroutine ocn_tend_tracer(tendPool, statePool, forcingPool, & real (kind=RKIND), dimension(:,:), pointer, contiguous :: & layerThickness, &! layer thickness tracerGroupSurfaceFlux, &! tracer flux at surface - fractionAbsorbed, &! frac sfc flux aborbed - fractionAbsorbedRunoff, &! frac runoff flux aborbed + fractionAbsorbed, &! frac sfc flux absorbed + fractionAbsorbedRunoff, &! frac runoff flux absorbed + fractionAbsorbedSubglacialRunoff, &! frac subglacial runoff flux absorbed tracerGroupSurfaceFluxRunoff, &! runoff flux + tracerGroupSurfaceFluxSubglacialRunoff, &! subglacial runoff flux tracerGroupSurfaceFluxRemoved,&! total sfc flux absorbed nonLocalSurfaceTracerFlux ! non-local fluxes (eg KPP) @@ -674,6 +681,8 @@ subroutine ocn_tend_tracer(tendPool, statePool, forcingPool, & fractionAbsorbed) call mpas_pool_get_array(forcingPool, 'fractionAbsorbedRunoff', & fractionAbsorbedRunoff) + call mpas_pool_get_array(forcingPool, 'fractionAbsorbedSubglacialRunoff', & + fractionAbsorbedSubglacialRunoff) ! allocate and transfer data not specific to tracer groups allocate(normalThicknessFlux(nVertLevels, nEdgesAll+1)) @@ -798,6 +807,14 @@ subroutine ocn_tend_tracer(tendPool, statePool, forcingPool, & modifiedGroupName, & tracerGroupSurfaceFluxRunoff) + ! Get surface flux due to subglacial runoff array + ! only active tracers have subglacial runoff flux for now, + ! but we still need to associate for ALL tracers + modifiedGroupName = groupName // "SurfaceFluxSubglacialRunoff" + call mpas_pool_get_array(tracersSurfaceFluxPool, & + modifiedGroupName, & + tracerGroupSurfaceFluxSubglacialRunoff) + ! Get surface flux removed array to keep track of how much ! flux is ignored modifiedGroupName = groupName // "SurfaceFluxRemoved" @@ -824,6 +841,7 @@ subroutine ocn_tend_tracer(tendPool, statePool, forcingPool, & do n=1,nTracersGroup tracerGroupSurfaceFlux (n,iCell) = 0.0_RKIND tracerGroupSurfaceFluxRunoff (n,iCell) = 0.0_RKIND + tracerGroupSurfaceFluxSubglacialRunoff (n,iCell) = 0.0_RKIND tracerGroupSurfaceFluxRemoved(n,iCell) = 0.0_RKIND end do end do @@ -839,6 +857,7 @@ subroutine ocn_tend_tracer(tendPool, statePool, forcingPool, & forcingPool, tracerGroup, & tracerGroupSurfaceFlux, & tracerGroupSurfaceFluxRunoff, & + tracerGroupSurfaceFluxSubglacialRunoff, & tracerGroupSurfaceFluxRemoved, & dt, layerThickness, err) @@ -1198,9 +1217,9 @@ subroutine ocn_tend_tracer(tendPool, statePool, forcingPool, & endif ! compute budgets call ocn_tracer_surface_flux_tend(meshPool, fractionAbsorbed, & - fractionAbsorbedRunoff, layerThickness, & - tracerGroupSurfaceFlux, & - tracerGroupSurfaceFluxRunoff, & + fractionAbsorbedRunoff, fractionAbsorbedSubglacialRunoff, & + layerThickness, tracerGroupSurfaceFlux, & + tracerGroupSurfaceFluxRunoff, tracerGroupSurfaceFluxSubglacialRunoff, & tracerGroupTend, err) ! diff --git a/components/mpas-ocean/src/shared/mpas_ocn_thick_surface_flux.F b/components/mpas-ocean/src/shared/mpas_ocn_thick_surface_flux.F index 043ed7b2862b..180b4f79a753 100644 --- a/components/mpas-ocean/src/shared/mpas_ocn_thick_surface_flux.F +++ b/components/mpas-ocean/src/shared/mpas_ocn_thick_surface_flux.F @@ -85,7 +85,7 @@ subroutine ocn_thick_surface_flux_tend(transmissionCoefficients, transmissionCoe real (kind=RKIND), dimension(:,:), intent(in) :: & transmissionCoefficients, &!< Input: Coefficients for the transmission of surface fluxes transmissionCoefficientsRunoff, &!< Input: Coefficients for the transmission of surface fluxes due to river runoff - transmissionCoefficientsSubglacialRunoff !< Input: Coefficients for the transmission of surface fluxes due to river runoff + transmissionCoefficientsSubglacialRunoff !< Input: Coefficients for the transmission of surface fluxes due to subglacial runoff real (kind=RKIND), dimension(:), intent(in) :: & surfaceThicknessFlux, &!< Input: surface flux of thickness diff --git a/components/mpas-ocean/src/shared/mpas_ocn_tracer_surface_flux_to_tend.F b/components/mpas-ocean/src/shared/mpas_ocn_tracer_surface_flux_to_tend.F index 57e2949bac9b..4303d1b78ff2 100644 --- a/components/mpas-ocean/src/shared/mpas_ocn_tracer_surface_flux_to_tend.F +++ b/components/mpas-ocean/src/shared/mpas_ocn_tracer_surface_flux_to_tend.F @@ -71,8 +71,8 @@ module ocn_tracer_surface_flux_to_tend ! !----------------------------------------------------------------------- - subroutine ocn_tracer_surface_flux_tend(meshPool, fractionAbsorbed, fractionAbsorbedRunoff, layerThickness, & - surfaceTracerFlux, surfaceTracerFluxRunoff, tend, err)!{{{ + subroutine ocn_tracer_surface_flux_tend(meshPool, fractionAbsorbed, fractionAbsorbedRunoff, fractionAbsorbedSubglacialRunoff, & + layerThickness, surfaceTracerFlux, surfaceTracerFluxRunoff, surfaceTracerFluxSubglacialRunoff, tend, err)!{{{ !----------------------------------------------------------------- ! ! input variables @@ -97,6 +97,13 @@ subroutine ocn_tracer_surface_flux_tend(meshPool, fractionAbsorbed, fractionAbso real (kind=RKIND), dimension(:,:), intent(in) :: & fractionAbsorbedRunoff !< Input: Coefficients for the application of surface fluxes due to river runoff + real (kind=RKIND), dimension(:,:), intent(in), pointer :: & + surfaceTracerFluxSubglacialRunoff !< Input: surface tracer fluxes from subglacial runoff + + real (kind=RKIND), dimension(:,:), intent(in) :: & + fractionAbsorbedSubglacialRunoff !< Input: Coefficients for the application of surface fluxes due to subglacial runoff + + !----------------------------------------------------------------- ! ! input/output variables @@ -197,7 +204,36 @@ subroutine ocn_tracer_surface_flux_tend(meshPool, fractionAbsorbed, fractionAbso call mpas_timer_stop("surface_tracer_runoff_flux") end if + ! now do subglacial runoff component + + if (associated(surfaceTracerFluxSubglacialRunoff)) then + call mpas_timer_start("surface_tracer_subglacial_runoff_flux") + + !$omp parallel + !$omp do schedule(runtime) private(remainingFlux, k, iTracer) + do iCell = 1, nCells + remainingFlux = 1.0_RKIND + do k = minLevelCell(iCell), maxLevelCell(iCell) + remainingFlux = remainingFlux - fractionAbsorbedSubglacialRunoff(k, iCell) + do iTracer = 1, nTracers + tend(iTracer, k, iCell) = tend(iTracer, k, iCell) + & + surfaceTracerFluxSubglacialRunoff(iTracer, iCell) * fractionAbsorbedSubglacialRunoff(k, iCell) + end do + end do + + if(maxLevelCell(iCell) > 0 .and. remainingFlux > 0.0_RKIND) then + do iTracer = 1, nTracers + tend(iTracer, maxLevelCell(iCell), iCell) = tend(iTracer, maxLevelCell(iCell), iCell) & + + surfaceTracerFluxSubglacialRunoff(iTracer, iCell) * remainingFlux + end do + end if + end do + !$omp end do + !$omp end parallel + + call mpas_timer_stop("surface_tracer_subglacial_runoff_flux") + end if !-------------------------------------------------------------------- end subroutine ocn_tracer_surface_flux_tend!}}} From 5cb8a57d5b11a2220b317d28ba2bad76b332457f Mon Sep 17 00:00:00 2001 From: Irena Vankova Date: Thu, 19 Oct 2023 11:40:43 -0600 Subject: [PATCH 183/451] subglacial runoff for tracers, part 2 - registry --- .../src/tracer_groups/Registry_CFC.xml | 9 ++ .../src/tracer_groups/Registry_DMS.xml | 9 ++ .../tracer_groups/Registry_MacroMolecules.xml | 12 ++ .../tracer_groups/Registry_activeTracers.xml | 8 ++ .../tracer_groups/Registry_debugTracers.xml | 11 ++ .../src/tracer_groups/Registry_ecosys.xml | 128 +++++++++++++++++- .../src/tracer_groups/Registry_idealAge.xml | 5 + 7 files changed, 181 insertions(+), 1 deletion(-) diff --git a/components/mpas-ocean/src/tracer_groups/Registry_CFC.xml b/components/mpas-ocean/src/tracer_groups/Registry_CFC.xml index d77859dcef86..b0adb7d595f5 100644 --- a/components/mpas-ocean/src/tracer_groups/Registry_CFC.xml +++ b/components/mpas-ocean/src/tracer_groups/Registry_CFC.xml @@ -95,6 +95,15 @@ description="CFC12 Surface Flux Due to Runoff" /> + + + + + + + + + + + + + + + + + + + + + + + + + - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/components/mpas-ocean/src/tracer_groups/Registry_idealAge.xml b/components/mpas-ocean/src/tracer_groups/Registry_idealAge.xml index c6adca3ea636..3a45bc10b794 100644 --- a/components/mpas-ocean/src/tracer_groups/Registry_idealAge.xml +++ b/components/mpas-ocean/src/tracer_groups/Registry_idealAge.xml @@ -69,6 +69,11 @@ description="Flux of iAge through the ocean surface due to river runoff. Positive into ocean." /> + + + Date: Thu, 19 Oct 2023 15:43:37 -0600 Subject: [PATCH 184/451] subglacial runoff freezing temperature at landicepressure --- components/mpas-ocean/src/Registry.xml | 8 ++++++++ .../mpas-ocean/src/shared/mpas_ocn_surface_bulk_forcing.F | 5 ++++- 2 files changed, 12 insertions(+), 1 deletion(-) diff --git a/components/mpas-ocean/src/Registry.xml b/components/mpas-ocean/src/Registry.xml index 0ed2b0c42462..3a11826169d4 100644 --- a/components/mpas-ocean/src/Registry.xml +++ b/components/mpas-ocean/src/Registry.xml @@ -3787,6 +3787,14 @@ description="Global sum of fresh water flux from river runoff from the coupler that was removed due to config_remove_AIS_coupler_runoff option. Positive into the ocean." packages="thicknessBulkPKG" /> + + Date: Tue, 9 Jul 2024 12:27:07 -0600 Subject: [PATCH 185/451] resolved: compsets tmix --- components/mpas-ocean/bld/build-namelist | 7 +++++ .../mpas-ocean/bld/build-namelist-section | 1 + .../namelist_defaults_mpaso.xml | 1 + .../namelist_definition_mpaso.xml | 8 ++++++ components/mpas-ocean/cime_config/buildnml | 27 +++++++++++++++++++ .../cime_config/config_component.xml | 13 +++++++++ .../cime_config/config_compsets.xml | 10 +++++++ components/mpas-ocean/src/Registry.xml | 2 +- 8 files changed, 68 insertions(+), 1 deletion(-) diff --git a/components/mpas-ocean/bld/build-namelist b/components/mpas-ocean/bld/build-namelist index 1c55bcb7be1d..ad8e268fbb0a 100755 --- a/components/mpas-ocean/bld/build-namelist +++ b/components/mpas-ocean/bld/build-namelist @@ -54,6 +54,9 @@ OPTIONS -ocn_ismf variable for defining how the ocn model will handle ice shelf melt fluxes Options are: none, data, internal, coupled + -ocn_sgr variable for defining how the ocn model will handle subglacial + runoff + Options are: none, data, coupled -decomp_prefix decomp_prefix variable -date_stamp date_stamp variable -cfg_grid Directory containing MPASO configuration scripts. @@ -111,6 +114,7 @@ my %opts = ( help => 0, ocn_forcing => undef, ocn_iceberg => undef, ocn_ismf => undef, + ocn_sgr => undef, decomp_prefix => undef, date_stamp => undef, ocn_bgc => undef, @@ -137,6 +141,7 @@ GetOptions( "ocn_forcing=s" => \$opts{'ocn_forcing'}, "ocn_iceberg=s" => \$opts{'ocn_iceberg'}, "ocn_ismf=s" => \$opts{'ocn_ismf'}, + "ocn_sgr=s" => \$opts{'ocn_sgr'}, "decomp_prefix=s" => \$opts{'decomp_prefix'}, "date_stamp=s" => \$opts{'date_stamp'}, "ocn_bgc=s" => \$opts{'ocn_bgc'}, @@ -180,6 +185,7 @@ my $OCN_GRID = $opts{'ocn_grid'}; my $OCN_FORCING = $opts{'ocn_forcing'}; my $OCN_ICEBERG = $opts{'ocn_iceberg'}; my $OCN_ISMF = $opts{'ocn_ismf'}; +my $OCN_SGR = $opts{'ocn_sgr'}; my $decomp_prefix = $opts{'decomp_prefix'}; my $date_stamp = $opts{'date_stamp'}; my $ocn_bgc = $opts{'ocn_bgc'}; @@ -702,6 +708,7 @@ add_default($nl, 'config_use_bulk_wind_stress'); add_default($nl, 'config_use_bulk_thickness_flux'); add_default($nl, 'config_flux_attenuation_coefficient'); add_default($nl, 'config_flux_attenuation_coefficient_runoff'); +add_default($nl, 'config_flux_attenuation_coefficient_subglacial_runoff'); ############################ # Namelist group: coupling # diff --git a/components/mpas-ocean/bld/build-namelist-section b/components/mpas-ocean/bld/build-namelist-section index cc1695243faa..7a1d06b35a7c 100644 --- a/components/mpas-ocean/bld/build-namelist-section +++ b/components/mpas-ocean/bld/build-namelist-section @@ -224,6 +224,7 @@ add_default($nl, 'config_use_bulk_wind_stress'); add_default($nl, 'config_use_bulk_thickness_flux'); add_default($nl, 'config_flux_attenuation_coefficient'); add_default($nl, 'config_flux_attenuation_coefficient_runoff'); +add_default($nl, 'config_flux_attenuation_coefficient_subglacial_runoff'); ############################ # Namelist group: coupling # diff --git a/components/mpas-ocean/bld/namelist_files/namelist_defaults_mpaso.xml b/components/mpas-ocean/bld/namelist_files/namelist_defaults_mpaso.xml index c7441c6b2214..5686c0e0a012 100644 --- a/components/mpas-ocean/bld/namelist_files/namelist_defaults_mpaso.xml +++ b/components/mpas-ocean/bld/namelist_files/namelist_defaults_mpaso.xml @@ -342,6 +342,7 @@ .true. 0.001 10.0 +10.0 .false. diff --git a/components/mpas-ocean/bld/namelist_files/namelist_definition_mpaso.xml b/components/mpas-ocean/bld/namelist_files/namelist_definition_mpaso.xml index f6c2f9c5b765..ac2bfd411e4b 100644 --- a/components/mpas-ocean/bld/namelist_files/namelist_definition_mpaso.xml +++ b/components/mpas-ocean/bld/namelist_files/namelist_definition_mpaso.xml @@ -1188,6 +1188,14 @@ Valid values: Any positive real number. Default: Defined in namelist_defaults.xml + +The length scale of exponential decay of subglacial runoff. Fluxes are multiplied by $e^{z/\gamma}$, where this coefficient is $\gamma$. + +Valid values: Any positive real number. +Default: Defined in namelist_defaults.xml + + diff --git a/components/mpas-ocean/cime_config/buildnml b/components/mpas-ocean/cime_config/buildnml index 4c7ed2c0a311..7ee71aee3a33 100755 --- a/components/mpas-ocean/cime_config/buildnml +++ b/components/mpas-ocean/cime_config/buildnml @@ -35,6 +35,7 @@ def buildnml(case, caseroot, compname): ocn_forcing = case.get_value("MPASO_FORCING") ocn_iceberg = case.get_value("MPASO_ICEBERG") ocn_ismf = case.get_value("MPASO_ISMF") + ocn_sgr = case.get_value("MPASO_SGR") ocn_bgc = case.get_value("MPASO_BGC") ocn_wave = case.get_value("MPASO_WAVE") ocn_tidal_mixing = case.get_value("MPASO_TIDAL_MIXING") @@ -76,6 +77,7 @@ def buildnml(case, caseroot, compname): analysis_mask_file = '' eco_forcing_file = '' u_tidal_rms_file = '' + data_sgr_file = '' if ocn_grid == 'oEC60to30v3': decomp_date = '230424' @@ -140,6 +142,8 @@ def buildnml(case, caseroot, compname): data_ismf_file = 'prescribed_ismf_paolo2023.oQU240wLI.20240404.nc' if ocn_tidal_mixing == 'true': u_tidal_rms_file = 'velocityTidalRMS_CATS2008.oQU240wLI.20240221.nc' + if ocn_sgr == 'data': + data_sgr_file = 'oQU240wLI_DSGR.nc' elif ocn_grid == 'oQU120': decomp_date = '230424' @@ -352,6 +356,8 @@ def buildnml(case, caseroot, compname): data_ismf_file = 'prescribed_ismf_adusumilli2020.ECwISC30to60E2r1.230429.nc' if ocn_tidal_mixing == 'true': u_tidal_rms_file = 'velocityTidalRMS_CATS2008.ECwISC30to60E2r1.20240221.nc' + if ocn_sgr == 'data': + data_sgr_file = 'ECwISC30to60E2r1_DSGR.nc' elif ocn_grid == 'IcoswISC30E3r5': decomp_date = '20231120' @@ -436,6 +442,9 @@ def buildnml(case, caseroot, compname): if u_tidal_rms_file != '': input_list.write("u_tidal_rms = {}/ocn/mpas-o/{}/{}\n".format(din_loc_root, ocn_mask, u_tidal_rms_file)) + if data_sgr_file != '': + input_list.write("subglacial_runoff = {}/ocn/mpas-o/{}/{}\n".format(din_loc_root, ocn_mask, data_sgr_file)) + #-------------------------------------------------------------------- # Invoke mpas build-namelist - output will go in $CASEBUILD/mpasoconf #-------------------------------------------------------------------- @@ -495,6 +504,7 @@ def buildnml(case, caseroot, compname): sysmod += " -ocn_forcing '{}'".format(ocn_forcing) sysmod += " -ocn_iceberg '{}'".format(ocn_iceberg) sysmod += " -ocn_ismf '{}'".format(ocn_ismf) + sysmod += " -ocn_sgr '{}'".format(ocn_sgr) sysmod += " -ocn_bgc '{}'".format(ocn_bgc) sysmod += " -ocn_wave '{}'".format(ocn_wave) sysmod += " -ocn_tidal_mixing '{}'".format(ocn_tidal_mixing) @@ -702,6 +712,19 @@ def buildnml(case, caseroot, compname): lines.append('') lines.append('') + if data_sgr_file != '': + lines.append('') + lines.append('') + lines.append(' ') + lines.append('') + lines.append('') + if analysis_mask_file != '': lines.append('') lines.append(' ') lines.append(' ') + lines.append(' ') lines.append(' ') lines.append(' ') lines.append(' ') @@ -1533,6 +1557,7 @@ def buildnml(case, caseroot, compname): lines.append(' ') lines.append(' ') + lines.append(' ') lines.append(' ') lines.append(' ') lines.append(' ') @@ -1598,6 +1623,7 @@ def buildnml(case, caseroot, compname): lines.append(' ') lines.append(' ') + lines.append(' ') lines.append(' ') lines.append(' ') lines.append(' ') @@ -1812,6 +1838,7 @@ def buildnml(case, caseroot, compname): lines.append(' ') lines.append(' ') lines.append(' ') + lines.append(' ') lines.append(' ') lines.append(' ') lines.append(' ') diff --git a/components/mpas-ocean/cime_config/config_component.xml b/components/mpas-ocean/cime_config/config_component.xml index e95b63682d95..eb8e09519829 100644 --- a/components/mpas-ocean/cime_config/config_component.xml +++ b/components/mpas-ocean/cime_config/config_component.xml @@ -39,6 +39,19 @@ Option to describe the MPASO prescribed tidal mixing + + char + none,data,coupled + none + + none + data + + case_comp + env_case.xml + Option to describe how MPASO will handle subglacial runoff fluxes + + char false,true diff --git a/components/mpas-ocean/cime_config/config_compsets.xml b/components/mpas-ocean/cime_config/config_compsets.xml index 448aa7a82b57..27b0218f4a26 100644 --- a/components/mpas-ocean/cime_config/config_compsets.xml +++ b/components/mpas-ocean/cime_config/config_compsets.xml @@ -87,6 +87,11 @@ 2000_DATM%JRA-1p5_SLND_MPASSI%DIB_MPASO%IBPISMFDATMFORCED_DROF%JRA-1p5-AIS0ROF_SGLC_SWAV + + GMPAS-JRA1p5-DIB-PISMF-DSGR + 2000_DATM%JRA-1p5_SLND_MPASSI%DIB_MPASO%IBPISMFDATMFORCEDDSGR_DROF%JRA-1p5-AIS0ROF_SGLC_SWAV + + GMPAS-JRA1p5-DIB-DISMF 2000_DATM%JRA-1p5_SLND_MPASSI%DIB_MPASO%IBDISMFDATMFORCED_DROF%JRA-1p5-AIS0ROF_SGLC_SWAV @@ -97,6 +102,11 @@ 2000_DATM%JRA-1p5_SLND_MPASSI%DIB_MPASO%IBPISMFDATMFORCEDTMIX_DROF%JRA-1p5-AIS0ROF_SGLC_SWAV + + GMPAS-JRA1p5-DIB-DISMF-DSGR + 2000_DATM%JRA-1p5_SLND_MPASSI%DIB_MPASO%IBDISMFDATMFORCEDDSGR_DROF%JRA-1p5-AIS0ROF_SGLC_SWAV + + GMPAS-JRA1p4 2000_DATM%JRA-1p4-2018_SLND_MPASSI_MPASO%DATMFORCED_DROF%JRA-1p4-2018_SGLC_SWAV diff --git a/components/mpas-ocean/src/Registry.xml b/components/mpas-ocean/src/Registry.xml index 3a11826169d4..5e36e828f32b 100644 --- a/components/mpas-ocean/src/Registry.xml +++ b/components/mpas-ocean/src/Registry.xml @@ -702,7 +702,7 @@ description="The length scale of exponential decay of river runoff. Fluxes are multiplied by $e^{z/\gamma}$, where this coefficient is $\gamma$." possible_values="Any positive real number." /> - From 0fccd7005f50caf729c14c2df81b79224e5c3b11 Mon Sep 17 00:00:00 2001 From: Irena Vankova Date: Fri, 20 Oct 2023 14:36:43 -0600 Subject: [PATCH 186/451] typo --- components/mpas-ocean/src/Registry.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/components/mpas-ocean/src/Registry.xml b/components/mpas-ocean/src/Registry.xml index 5e36e828f32b..f56799eaaf07 100644 --- a/components/mpas-ocean/src/Registry.xml +++ b/components/mpas-ocean/src/Registry.xml @@ -703,7 +703,7 @@ possible_values="Any positive real number." /> From f820afb71ee2e22ae6326f0e7c5bda7bf67c3eef Mon Sep 17 00:00:00 2001 From: Irena Vankova Date: Fri, 20 Oct 2023 15:13:14 -0600 Subject: [PATCH 187/451] more compsets --- components/mpas-ocean/cime_config/config_compsets.xml | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/components/mpas-ocean/cime_config/config_compsets.xml b/components/mpas-ocean/cime_config/config_compsets.xml index 27b0218f4a26..766b1397bcf2 100644 --- a/components/mpas-ocean/cime_config/config_compsets.xml +++ b/components/mpas-ocean/cime_config/config_compsets.xml @@ -37,6 +37,11 @@ 2000_DATM%NYF_SLND_MPASSI_MPASO%PISMFDATMFORCED_DROF%NYFAIS45_SGLC_SWAV + + GMPAS-NYF-PISMF-DSGR + 2000_DATM%NYF_SLND_MPASSI_MPASO%PISMFDATMFORCEDDSGR_DROF%NYFAIS45_SGLC_SWAV + + GMPAS-NYF-DISMF 2000_DATM%NYF_SLND_MPASSI_MPASO%DISMFDATMFORCED_DROF%NYFAIS45_SGLC_SWAV @@ -142,6 +147,11 @@ 2000_DATM%IAF_SLND_MPASSI_MPASO%PISMFDATMFORCED_DROF%IAFAIS45_SGLC_SWAV + + GMPAS-IAF-PISMF-DSGR + 2000_DATM%IAF_SLND_MPASSI_MPASO%PISMFDATMFORCEDDSGR_DROF%IAFAIS45_SGLC_SWAV + + GMPAS-IAF-DISMF 2000_DATM%IAF_SLND_MPASSI_MPASO%DISMFDATMFORCED_DROF%IAFAIS45_SGLC_SWAV From 71dc2ee55e2b9beabfd713e421f6fed87301b6b8 Mon Sep 17 00:00:00 2001 From: Irena Vankova Date: Mon, 23 Oct 2023 16:53:14 -0600 Subject: [PATCH 188/451] typo: remainingFluxSubglacialRunoff --- .../mpas-ocean/src/shared/mpas_ocn_thick_surface_flux.F | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/components/mpas-ocean/src/shared/mpas_ocn_thick_surface_flux.F b/components/mpas-ocean/src/shared/mpas_ocn_thick_surface_flux.F index 180b4f79a753..1f7c67b88e09 100644 --- a/components/mpas-ocean/src/shared/mpas_ocn_thick_surface_flux.F +++ b/components/mpas-ocean/src/shared/mpas_ocn_thick_surface_flux.F @@ -118,7 +118,7 @@ subroutine ocn_thick_surface_flux_tend(transmissionCoefficients, transmissionCoe integer :: iCell, k - real (kind=RKIND) :: remainingFlux, remainingFluxRunoff + real (kind=RKIND) :: remainingFlux, remainingFluxRunoff, remainingFluxSubglacialRunoff err = 0 @@ -133,10 +133,10 @@ subroutine ocn_thick_surface_flux_tend(transmissionCoefficients, transmissionCoe !$acc present(tend, surfaceThicknessFlux, surfaceThicknessFluxRunoff, & !$acc surfaceThicknessFluxSubglacialRunoff, transmissionCoefficientsSubglacialRunoff, & !$acc transmissionCoefficients, transmissionCoefficientsRunoff, minLevelCell, maxLevelCell) & - !$acc private(k, remainingFlux, remainingFluxRunoff) + !$acc private(k, remainingFlux, remainingFluxRunoff, remainingFluxSubglacialRunoff) #else !$omp parallel - !$omp do schedule(runtime) private(remainingFlux, remainingFluxRunoff, k) + !$omp do schedule(runtime) private(remainingFlux, remainingFluxRunoff, remainingFluxSubglacialRunoff, k) #endif do iCell = 1, nCellsOwned remainingFlux = 1.0_RKIND From 2637229a9be48f2d82474f961d0dc18132da86c3 Mon Sep 17 00:00:00 2001 From: Irena Vankova Date: Thu, 26 Oct 2023 10:58:22 -0600 Subject: [PATCH 189/451] updated sg units --- components/mpas-ocean/src/Registry.xml | 2 +- .../mpas-ocean/src/shared/mpas_ocn_surface_bulk_forcing.F | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/components/mpas-ocean/src/Registry.xml b/components/mpas-ocean/src/Registry.xml index f56799eaaf07..ad8ce6752441 100644 --- a/components/mpas-ocean/src/Registry.xml +++ b/components/mpas-ocean/src/Registry.xml @@ -3775,7 +3775,7 @@ description="Fresh water flux from river runoff at cell centers from coupler. Positive into the ocean." packages="thicknessBulkPKG" /> - diff --git a/components/mpas-ocean/src/shared/mpas_ocn_surface_bulk_forcing.F b/components/mpas-ocean/src/shared/mpas_ocn_surface_bulk_forcing.F index 4714400951d2..c3a8a6691ddd 100644 --- a/components/mpas-ocean/src/shared/mpas_ocn_surface_bulk_forcing.F +++ b/components/mpas-ocean/src/shared/mpas_ocn_surface_bulk_forcing.F @@ -351,7 +351,7 @@ subroutine ocn_surface_bulk_forcing_thick(forcingPool, surfaceThicknessFlux, sur surfaceThicknessFlux(iCell) = surfaceThicknessFlux(iCell) + ( snowFlux(iCell) + rainFlux(iCell) + evaporationFlux(iCell) & + seaIceFreshWaterFlux(iCell) + icebergFreshWaterFlux(iCell) + iceRunoffFlux(iCell) ) / rho_sw surfaceThicknessFluxRunoff(iCell) = riverRunoffFlux(iCell) / rho_sw - surfaceThicknessFluxSubglacialRunoff(iCell) = subglacialRunoffFlux(iCell) / rho_sw + surfaceThicknessFluxSubglacialRunoff(iCell) = subglacialRunoffFlux(iCell) / areaCell(iCell) end do #ifndef MPAS_OPENACC !$omp end do @@ -581,7 +581,7 @@ subroutine ocn_surface_bulk_forcing_active_tracers(meshPool, forcingPool, tracer ! Subglacial runoff can have temperature below 0.0C, since it can come out at great depth tracersSurfaceFluxSubglacialRunoff(index_temperature_flux,iCell) = subglacialRunoffFlux(iCell) * & ocn_freezing_temperature(salinity=0.0_RKIND, pressure=landIcePressure(iCell), & - inLandIceCavity=.true.) / rho_sw + inLandIceCavity=.true.) / areaCell(iCell) ! Accumulate fluxes that use the freezing point ! mrp performance note: should call ocn_freezing_temperature just once here From 98dc48b3a0c3f04948e9225f0c7ce808573a35f2 Mon Sep 17 00:00:00 2001 From: Irena Vankova Date: Tue, 31 Oct 2023 14:08:09 -0600 Subject: [PATCH 190/451] change config_flux_attenuation_coefficient_subglacial_runoff default to 1 mm --- .../mpas-ocean/bld/namelist_files/namelist_defaults_mpaso.xml | 2 +- components/mpas-ocean/src/Registry.xml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/components/mpas-ocean/bld/namelist_files/namelist_defaults_mpaso.xml b/components/mpas-ocean/bld/namelist_files/namelist_defaults_mpaso.xml index 5686c0e0a012..66a6482c54aa 100644 --- a/components/mpas-ocean/bld/namelist_files/namelist_defaults_mpaso.xml +++ b/components/mpas-ocean/bld/namelist_files/namelist_defaults_mpaso.xml @@ -342,7 +342,7 @@ .true. 0.001 10.0 -10.0 +0.001 .false. diff --git a/components/mpas-ocean/src/Registry.xml b/components/mpas-ocean/src/Registry.xml index ad8ce6752441..76e868860a41 100644 --- a/components/mpas-ocean/src/Registry.xml +++ b/components/mpas-ocean/src/Registry.xml @@ -702,7 +702,7 @@ description="The length scale of exponential decay of river runoff. Fluxes are multiplied by $e^{z/\gamma}$, where this coefficient is $\gamma$." possible_values="Any positive real number." /> - From 239697803ded5efafc22d345fe5fe6adc0d05582 Mon Sep 17 00:00:00 2001 From: Irena Vankova Date: Tue, 31 Oct 2023 14:53:00 -0600 Subject: [PATCH 191/451] add namelist option to include some parts of runoff only: config_use_SGR_opt --- .../mpas-ocean/bld/build-namelist-section | 1 + .../namelist_defaults_mpaso.xml | 1 + .../namelist_definition_mpaso.xml | 8 ++++++++ components/mpas-ocean/src/Registry.xml | 4 ++++ .../shared/mpas_ocn_surface_bulk_forcing.F | 20 +++++++++++++++---- 5 files changed, 30 insertions(+), 4 deletions(-) diff --git a/components/mpas-ocean/bld/build-namelist-section b/components/mpas-ocean/bld/build-namelist-section index 7a1d06b35a7c..b8f544edabaf 100644 --- a/components/mpas-ocean/bld/build-namelist-section +++ b/components/mpas-ocean/bld/build-namelist-section @@ -225,6 +225,7 @@ add_default($nl, 'config_use_bulk_thickness_flux'); add_default($nl, 'config_flux_attenuation_coefficient'); add_default($nl, 'config_flux_attenuation_coefficient_runoff'); add_default($nl, 'config_flux_attenuation_coefficient_subglacial_runoff'); +add_default($nl, 'config_use_SGR_opt'); ############################ # Namelist group: coupling # diff --git a/components/mpas-ocean/bld/namelist_files/namelist_defaults_mpaso.xml b/components/mpas-ocean/bld/namelist_files/namelist_defaults_mpaso.xml index 66a6482c54aa..92709a4ee45d 100644 --- a/components/mpas-ocean/bld/namelist_files/namelist_defaults_mpaso.xml +++ b/components/mpas-ocean/bld/namelist_files/namelist_defaults_mpaso.xml @@ -343,6 +343,7 @@ 0.001 10.0 0.001 +0 .false. diff --git a/components/mpas-ocean/bld/namelist_files/namelist_definition_mpaso.xml b/components/mpas-ocean/bld/namelist_files/namelist_definition_mpaso.xml index ac2bfd411e4b..fc6374cc2a7f 100644 --- a/components/mpas-ocean/bld/namelist_files/namelist_definition_mpaso.xml +++ b/components/mpas-ocean/bld/namelist_files/namelist_definition_mpaso.xml @@ -1196,6 +1196,14 @@ Valid values: Any positive real number. Default: Defined in namelist_defaults.xml + +Option to use or not subglacial runoff (SGR). + +Valid values: 0 - don't use SGR, 1 - use both mass and TS from SGR, 2 - use mass only from SGR , 3 - use TS only from SGR +Default: Defined in namelist_defaults.xml + + diff --git a/components/mpas-ocean/src/Registry.xml b/components/mpas-ocean/src/Registry.xml index 76e868860a41..083db34082e4 100644 --- a/components/mpas-ocean/src/Registry.xml +++ b/components/mpas-ocean/src/Registry.xml @@ -706,6 +706,10 @@ description="The length scale of exponential decay of subglacial runoff. Fluxes are multiplied by $e^{z/\gamma}$, where this coefficient is $\gamma$." possible_values="Any positive real number." /> + Date: Tue, 31 Oct 2023 14:56:51 -0600 Subject: [PATCH 192/451] more basic compsets --- components/mpas-ocean/cime_config/config_compsets.xml | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/components/mpas-ocean/cime_config/config_compsets.xml b/components/mpas-ocean/cime_config/config_compsets.xml index 766b1397bcf2..6950fd8c2179 100644 --- a/components/mpas-ocean/cime_config/config_compsets.xml +++ b/components/mpas-ocean/cime_config/config_compsets.xml @@ -42,6 +42,11 @@ 2000_DATM%NYF_SLND_MPASSI_MPASO%PISMFDATMFORCEDDSGR_DROF%NYFAIS45_SGLC_SWAV + + GMPAS-NYF-DSGR + 2000_DATM%NYF_SLND_MPASSI_MPASO%DATMFORCEDDSGR_DROF%NYFAIS45_SGLC_SWAV + + GMPAS-NYF-DISMF 2000_DATM%NYF_SLND_MPASSI_MPASO%DISMFDATMFORCED_DROF%NYFAIS45_SGLC_SWAV @@ -97,6 +102,11 @@ 2000_DATM%JRA-1p5_SLND_MPASSI%DIB_MPASO%IBPISMFDATMFORCEDDSGR_DROF%JRA-1p5-AIS0ROF_SGLC_SWAV + + GMPAS-JRA1p5-DSGR + 2000_DATM%JRA-1p5_SLND_MPASSI%DIB_MPASO%DATMFORCEDDSGR_DROF%JRA-1p5-AIS0ROF_SGLC_SWAV + + GMPAS-JRA1p5-DIB-DISMF 2000_DATM%JRA-1p5_SLND_MPASSI%DIB_MPASO%IBDISMFDATMFORCED_DROF%JRA-1p5-AIS0ROF_SGLC_SWAV From 9b786dd97402994a88eca8c1eaa9a6c5663d06aa Mon Sep 17 00:00:00 2001 From: Irena Vankova Date: Tue, 31 Oct 2023 15:35:05 -0600 Subject: [PATCH 193/451] forgotten bld --- components/mpas-ocean/bld/build-namelist | 1 + 1 file changed, 1 insertion(+) diff --git a/components/mpas-ocean/bld/build-namelist b/components/mpas-ocean/bld/build-namelist index ad8e268fbb0a..f70d6204be5f 100755 --- a/components/mpas-ocean/bld/build-namelist +++ b/components/mpas-ocean/bld/build-namelist @@ -709,6 +709,7 @@ add_default($nl, 'config_use_bulk_thickness_flux'); add_default($nl, 'config_flux_attenuation_coefficient'); add_default($nl, 'config_flux_attenuation_coefficient_runoff'); add_default($nl, 'config_flux_attenuation_coefficient_subglacial_runoff'); +add_default($nl, 'config_use_SGR_opt'); ############################ # Namelist group: coupling # From de04001fe002b961ad230936314e17fc7fbe693d Mon Sep 17 00:00:00 2001 From: Irena Vankova Date: Wed, 1 Nov 2023 14:31:42 -0600 Subject: [PATCH 194/451] no sg in kpp option --- components/mpas-ocean/src/shared/mpas_ocn_diagnostics.F | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/components/mpas-ocean/src/shared/mpas_ocn_diagnostics.F b/components/mpas-ocean/src/shared/mpas_ocn_diagnostics.F index 4e75d743130a..999d69337abb 100644 --- a/components/mpas-ocean/src/shared/mpas_ocn_diagnostics.F +++ b/components/mpas-ocean/src/shared/mpas_ocn_diagnostics.F @@ -3487,10 +3487,14 @@ subroutine ocn_compute_KPP_input_fields(statePool, forcingPool, & - exp( max(-100.0_RKIND, & -layerThickness(kmin, iCell)/ & config_flux_attenuation_coefficient_runoff)) - fracAbsorbedSubglacialRunoff = 1.0_RKIND & + if (config_use_SGR_opt == -1) then + fracAbsorbedSubglacialRunoff = 1.0_RKIND & - exp( max(-100.0_RKIND, & -layerThickness(kmin, iCell)/ & config_flux_attenuation_coefficient_subglacial_runoff)) + else + fracAbsorbedSubglacialRunoff = 0.0_RKIND + end if ! Store the total tracer flux below in ! nonLocalSurfaceTemperatureFlux for use in the CVMix nonlocal From 0ab238461d06ad3d605033731346d955c6bf2799 Mon Sep 17 00:00:00 2001 From: Irena Vankova Date: Wed, 1 Nov 2023 17:50:46 -0600 Subject: [PATCH 195/451] config_use_SGR_opt -1 correction --- .../bld/namelist_files/namelist_definition_mpaso.xml | 2 +- components/mpas-ocean/src/Registry.xml | 2 +- .../mpas-ocean/src/shared/mpas_ocn_surface_bulk_forcing.F | 4 ++-- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/components/mpas-ocean/bld/namelist_files/namelist_definition_mpaso.xml b/components/mpas-ocean/bld/namelist_files/namelist_definition_mpaso.xml index fc6374cc2a7f..c38d6edd97ad 100644 --- a/components/mpas-ocean/bld/namelist_files/namelist_definition_mpaso.xml +++ b/components/mpas-ocean/bld/namelist_files/namelist_definition_mpaso.xml @@ -1200,7 +1200,7 @@ Default: Defined in namelist_defaults.xml category="forcing" group="forcing"> Option to use or not subglacial runoff (SGR). -Valid values: 0 - don't use SGR, 1 - use both mass and TS from SGR, 2 - use mass only from SGR , 3 - use TS only from SGR +Valid values: 0 - don't use SGR, 1 - use both mass and TS from SGR, 2 - use mass only from SGR , 3 - use TS only from SGR, -1 use all + KPP Default: Defined in namelist_defaults.xml diff --git a/components/mpas-ocean/src/Registry.xml b/components/mpas-ocean/src/Registry.xml index 083db34082e4..953fa1cb39b4 100644 --- a/components/mpas-ocean/src/Registry.xml +++ b/components/mpas-ocean/src/Registry.xml @@ -708,7 +708,7 @@ /> diff --git a/components/mpas-ocean/src/shared/mpas_ocn_surface_bulk_forcing.F b/components/mpas-ocean/src/shared/mpas_ocn_surface_bulk_forcing.F index a12e628b2cc6..de9898c60997 100644 --- a/components/mpas-ocean/src/shared/mpas_ocn_surface_bulk_forcing.F +++ b/components/mpas-ocean/src/shared/mpas_ocn_surface_bulk_forcing.F @@ -352,7 +352,7 @@ subroutine ocn_surface_bulk_forcing_thick(forcingPool, surfaceThicknessFlux, sur + seaIceFreshWaterFlux(iCell) + icebergFreshWaterFlux(iCell) + iceRunoffFlux(iCell) ) / rho_sw surfaceThicknessFluxRunoff(iCell) = riverRunoffFlux(iCell) / rho_sw - if ((config_use_SGR_opt == 1) .or. (config_use_SGR_opt == 2)) then + if ((config_use_SGR_opt == 1) .or. (config_use_SGR_opt == 2) .or. (config_use_SGR_opt == -1)) then surfaceThicknessFluxSubglacialRunoff(iCell) = subglacialRunoffFlux(iCell) / areaCell(iCell) else surfaceThicknessFluxSubglacialRunoff(iCell) = 0.0_RKIND @@ -587,7 +587,7 @@ subroutine ocn_surface_bulk_forcing_active_tracers(meshPool, forcingPool, tracer * max(tracerGroup(index_temperature_flux,minLevelCell(iCell),iCell), 0.0_RKIND) / rho_sw ! Subglacial runoff can have temperature below 0.0C, since it can come out at great depth - if ((config_use_SGR_opt == 1) .or. (config_use_SGR_opt == 3)) then + if ((config_use_SGR_opt == 1) .or. (config_use_SGR_opt == 3) .or. (config_use_SGR_opt == -1)) then tracersSurfaceFluxSubglacialRunoff(index_temperature_flux,iCell) = subglacialRunoffFlux(iCell) * & ocn_freezing_temperature(salinity=0.0_RKIND, pressure=landIcePressure(iCell), & inLandIceCavity=.true.) / areaCell(iCell) From 81d948887f769ad72ac92a37ad6d78474b467f2c Mon Sep 17 00:00:00 2001 From: Irena Vankova Date: Wed, 8 Nov 2023 10:38:13 -0700 Subject: [PATCH 196/451] config read in forcing --- components/mpas-ocean/src/shared/mpas_ocn_forcing.F | 3 +++ 1 file changed, 3 insertions(+) diff --git a/components/mpas-ocean/src/shared/mpas_ocn_forcing.F b/components/mpas-ocean/src/shared/mpas_ocn_forcing.F index f530f67dfa62..8617cc4f8435 100644 --- a/components/mpas-ocean/src/shared/mpas_ocn_forcing.F +++ b/components/mpas-ocean/src/shared/mpas_ocn_forcing.F @@ -27,6 +27,7 @@ module ocn_forcing use mpas_dmpar use ocn_constants use ocn_diagnostics_variables + use ocn_config !IV comment implicit none private @@ -197,6 +198,8 @@ subroutine ocn_forcing_build_fraction_absorbed_array(meshPool, statePool, forcin end do end do + call mpas_log_write('config_use_SGR_opt: $r', realArgs=(/config_use_SGR_opt/)) + end subroutine ocn_forcing_build_fraction_absorbed_array!}}} !*********************************************************************** From 4745779efa824c568f84e4054e5bbf75f9e45031 Mon Sep 17 00:00:00 2001 From: Irena Vankova Date: Wed, 8 Nov 2023 12:28:44 -0700 Subject: [PATCH 197/451] sgr_flux_vertical_location and SGR to sgr --- components/mpas-ocean/bld/build-namelist | 3 +- .../mpas-ocean/bld/build-namelist-section | 3 +- .../namelist_defaults_mpaso.xml | 3 +- .../namelist_definition_mpaso.xml | 10 +++- components/mpas-ocean/src/Registry.xml | 10 ++-- .../src/shared/mpas_ocn_diagnostics.F | 2 +- .../mpas-ocean/src/shared/mpas_ocn_forcing.F | 53 +++++++++++++------ .../shared/mpas_ocn_surface_bulk_forcing.F | 4 +- 8 files changed, 63 insertions(+), 25 deletions(-) diff --git a/components/mpas-ocean/bld/build-namelist b/components/mpas-ocean/bld/build-namelist index f70d6204be5f..b413599f1778 100755 --- a/components/mpas-ocean/bld/build-namelist +++ b/components/mpas-ocean/bld/build-namelist @@ -709,7 +709,8 @@ add_default($nl, 'config_use_bulk_thickness_flux'); add_default($nl, 'config_flux_attenuation_coefficient'); add_default($nl, 'config_flux_attenuation_coefficient_runoff'); add_default($nl, 'config_flux_attenuation_coefficient_subglacial_runoff'); -add_default($nl, 'config_use_SGR_opt'); +add_default($nl, 'config_sgr_flux_vertical_location'); +add_default($nl, 'config_use_sgr_opt'); ############################ # Namelist group: coupling # diff --git a/components/mpas-ocean/bld/build-namelist-section b/components/mpas-ocean/bld/build-namelist-section index b8f544edabaf..9c0ad217b91f 100644 --- a/components/mpas-ocean/bld/build-namelist-section +++ b/components/mpas-ocean/bld/build-namelist-section @@ -225,7 +225,8 @@ add_default($nl, 'config_use_bulk_thickness_flux'); add_default($nl, 'config_flux_attenuation_coefficient'); add_default($nl, 'config_flux_attenuation_coefficient_runoff'); add_default($nl, 'config_flux_attenuation_coefficient_subglacial_runoff'); -add_default($nl, 'config_use_SGR_opt'); +add_default($nl, 'config_sgr_flux_vertical_location'); +add_default($nl, 'config_use_sgr_opt'); ############################ # Namelist group: coupling # diff --git a/components/mpas-ocean/bld/namelist_files/namelist_defaults_mpaso.xml b/components/mpas-ocean/bld/namelist_files/namelist_defaults_mpaso.xml index 92709a4ee45d..5b3bf93522a6 100644 --- a/components/mpas-ocean/bld/namelist_files/namelist_defaults_mpaso.xml +++ b/components/mpas-ocean/bld/namelist_files/namelist_defaults_mpaso.xml @@ -343,7 +343,8 @@ 0.001 10.0 0.001 -0 +'top' +0 .false. diff --git a/components/mpas-ocean/bld/namelist_files/namelist_definition_mpaso.xml b/components/mpas-ocean/bld/namelist_files/namelist_definition_mpaso.xml index c38d6edd97ad..7629e5663eff 100644 --- a/components/mpas-ocean/bld/namelist_files/namelist_definition_mpaso.xml +++ b/components/mpas-ocean/bld/namelist_files/namelist_definition_mpaso.xml @@ -1196,7 +1196,15 @@ Valid values: Any positive real number. Default: Defined in namelist_defaults.xml - +Selects the vertical location where subglacial runoff is fluxed + +Valid values: 'top','uniform', 'bottom'. +Default: Defined in namelist_defaults.xml + + + Option to use or not subglacial runoff (SGR). diff --git a/components/mpas-ocean/src/Registry.xml b/components/mpas-ocean/src/Registry.xml index 953fa1cb39b4..88928169b1ce 100644 --- a/components/mpas-ocean/src/Registry.xml +++ b/components/mpas-ocean/src/Registry.xml @@ -706,9 +706,13 @@ description="The length scale of exponential decay of subglacial runoff. Fluxes are multiplied by $e^{z/\gamma}$, where this coefficient is $\gamma$." possible_values="Any positive real number." /> - + diff --git a/components/mpas-ocean/src/shared/mpas_ocn_diagnostics.F b/components/mpas-ocean/src/shared/mpas_ocn_diagnostics.F index 999d69337abb..a7d03f5dcc89 100644 --- a/components/mpas-ocean/src/shared/mpas_ocn_diagnostics.F +++ b/components/mpas-ocean/src/shared/mpas_ocn_diagnostics.F @@ -3487,7 +3487,7 @@ subroutine ocn_compute_KPP_input_fields(statePool, forcingPool, & - exp( max(-100.0_RKIND, & -layerThickness(kmin, iCell)/ & config_flux_attenuation_coefficient_runoff)) - if (config_use_SGR_opt == -1) then + if (config_use_sgr_opt == -1) then fracAbsorbedSubglacialRunoff = 1.0_RKIND & - exp( max(-100.0_RKIND, & -layerThickness(kmin, iCell)/ & diff --git a/components/mpas-ocean/src/shared/mpas_ocn_forcing.F b/components/mpas-ocean/src/shared/mpas_ocn_forcing.F index 8617cc4f8435..e642e82e2e67 100644 --- a/components/mpas-ocean/src/shared/mpas_ocn_forcing.F +++ b/components/mpas-ocean/src/shared/mpas_ocn_forcing.F @@ -184,21 +184,44 @@ subroutine ocn_forcing_build_fraction_absorbed_array(meshPool, statePool, forcin ! now do subglacial runoff separately - do iCell = 1, nCells - zTop = 0.0_RKIND - transmissionCoeffTop = ocn_forcing_transmission(zTop, surfaceFluxAttenuationCoefficientSubglacialRunoff(iCell)) - do k = minLevelCell(iCell), maxLevelCell(iCell) - zBot = zTop - layerThickness(k,iCell) - transmissionCoeffBot = ocn_forcing_transmission(zBot, surfaceFluxAttenuationCoefficientSubglacialRunoff(iCell)) - - fractionAbsorbedSubglacialRunoff(k, iCell) = transmissionCoeffTop - transmissionCoeffBot - - zTop = zBot - transmissionCoeffTop = transmissionCoeffBot - end do - end do - - call mpas_log_write('config_use_SGR_opt: $r', realArgs=(/config_use_SGR_opt/)) + if ( trim(config_sgr_flux_vertical_location) == 'top' ) then + do iCell = 1, nCells + zTop = 0.0_RKIND + transmissionCoeffTop = ocn_forcing_transmission(zTop, surfaceFluxAttenuationCoefficientSubglacialRunoff(iCell)) + do k = minLevelCell(iCell), maxLevelCell(iCell) + zBot = zTop - layerThickness(k,iCell) + transmissionCoeffBot = ocn_forcing_transmission(zBot, surfaceFluxAttenuationCoefficientSubglacialRunoff(iCell)) + fractionAbsorbedSubglacialRunoff(k, iCell) = transmissionCoeffTop - transmissionCoeffBot + zTop = zBot + transmissionCoeffTop = transmissionCoeffBot + end do + end do + else if ( trim(config_sgr_flux_vertical_location) == 'uniform' ) then + do iCell = 1, nCells + ! calculate total thickness + zTop = 0.0_RKIND + do k = minLevelCell(iCell), maxLevelCell(iCell) + zTop = zTop + layerThickness(k,iCell) + end do + ! distribute flux evenly throughout water column + zBot = 0.0_RKIND + do k = minLevelCell(iCell), maxLevelCell(iCell) + fractionAbsorbedSubglacialRunoff(k, iCell) = layerThickness(k,iCell) / zTop + end do + end do + else if ( trim(config_sgr_flux_vertical_location) == 'bottom' ) then + do iCell = 1, nCells + zTop = 0.0_RKIND + transmissionCoeffTop = ocn_forcing_transmission(zTop, surfaceFluxAttenuationCoefficientSubglacialRunoff(iCell)) + do k = maxLevelCell(iCell), minLevelCell(iCell), -1 + zBot = zTop - layerThickness(k,iCell) + transmissionCoeffBot = ocn_forcing_transmission(zBot, surfaceFluxAttenuationCoefficientSubglacialRunoff(iCell)) + fractionAbsorbedSubglacialRunoff(k, iCell) = transmissionCoeffTop - transmissionCoeffBot + zTop = zBot + transmissionCoeffTop = transmissionCoeffBot + end do + end do + end if end subroutine ocn_forcing_build_fraction_absorbed_array!}}} diff --git a/components/mpas-ocean/src/shared/mpas_ocn_surface_bulk_forcing.F b/components/mpas-ocean/src/shared/mpas_ocn_surface_bulk_forcing.F index de9898c60997..f6156609df09 100644 --- a/components/mpas-ocean/src/shared/mpas_ocn_surface_bulk_forcing.F +++ b/components/mpas-ocean/src/shared/mpas_ocn_surface_bulk_forcing.F @@ -352,7 +352,7 @@ subroutine ocn_surface_bulk_forcing_thick(forcingPool, surfaceThicknessFlux, sur + seaIceFreshWaterFlux(iCell) + icebergFreshWaterFlux(iCell) + iceRunoffFlux(iCell) ) / rho_sw surfaceThicknessFluxRunoff(iCell) = riverRunoffFlux(iCell) / rho_sw - if ((config_use_SGR_opt == 1) .or. (config_use_SGR_opt == 2) .or. (config_use_SGR_opt == -1)) then + if ((config_use_sgr_opt == 1) .or. (config_use_sgr_opt == 2) .or. (config_use_sgr_opt == -1)) then surfaceThicknessFluxSubglacialRunoff(iCell) = subglacialRunoffFlux(iCell) / areaCell(iCell) else surfaceThicknessFluxSubglacialRunoff(iCell) = 0.0_RKIND @@ -587,7 +587,7 @@ subroutine ocn_surface_bulk_forcing_active_tracers(meshPool, forcingPool, tracer * max(tracerGroup(index_temperature_flux,minLevelCell(iCell),iCell), 0.0_RKIND) / rho_sw ! Subglacial runoff can have temperature below 0.0C, since it can come out at great depth - if ((config_use_SGR_opt == 1) .or. (config_use_SGR_opt == 3) .or. (config_use_SGR_opt == -1)) then + if ((config_use_sgr_opt == 1) .or. (config_use_sgr_opt == 3) .or. (config_use_sgr_opt == -1)) then tracersSurfaceFluxSubglacialRunoff(index_temperature_flux,iCell) = subglacialRunoffFlux(iCell) * & ocn_freezing_temperature(salinity=0.0_RKIND, pressure=landIcePressure(iCell), & inLandIceCavity=.true.) / areaCell(iCell) From e55b516afd33df71a1789b7a32b6f918a5e82b94 Mon Sep 17 00:00:00 2001 From: Irena Vankova Date: Thu, 16 Nov 2023 18:39:57 -0700 Subject: [PATCH 198/451] more sgr testing options for TS separation --- components/mpas-ocean/bld/build-namelist | 6 ++- .../mpas-ocean/bld/build-namelist-section | 6 ++- .../namelist_defaults_mpaso.xml | 7 +++- .../namelist_definition_mpaso.xml | 37 +++++++++++++++++-- components/mpas-ocean/src/Registry.xml | 23 ++++++++++-- .../src/shared/mpas_ocn_diagnostics.F | 2 +- .../shared/mpas_ocn_surface_bulk_forcing.F | 29 ++++++++------- 7 files changed, 87 insertions(+), 23 deletions(-) diff --git a/components/mpas-ocean/bld/build-namelist b/components/mpas-ocean/bld/build-namelist index b413599f1778..e1d2548dffeb 100755 --- a/components/mpas-ocean/bld/build-namelist +++ b/components/mpas-ocean/bld/build-namelist @@ -710,7 +710,11 @@ add_default($nl, 'config_flux_attenuation_coefficient'); add_default($nl, 'config_flux_attenuation_coefficient_runoff'); add_default($nl, 'config_flux_attenuation_coefficient_subglacial_runoff'); add_default($nl, 'config_sgr_flux_vertical_location'); -add_default($nl, 'config_use_sgr_opt'); +add_default($nl, 'config_use_sgr_opt_kpp'); +add_default($nl, 'config_use_sgr_opt_temp'); +add_default($nl, 'config_use_sgr_opt_salt'); +add_default($nl, 'config_sgr_temperature'); +add_default($nl, 'config_sgr_salinity'); ############################ # Namelist group: coupling # diff --git a/components/mpas-ocean/bld/build-namelist-section b/components/mpas-ocean/bld/build-namelist-section index 9c0ad217b91f..0d44d3f328b6 100644 --- a/components/mpas-ocean/bld/build-namelist-section +++ b/components/mpas-ocean/bld/build-namelist-section @@ -226,7 +226,11 @@ add_default($nl, 'config_flux_attenuation_coefficient'); add_default($nl, 'config_flux_attenuation_coefficient_runoff'); add_default($nl, 'config_flux_attenuation_coefficient_subglacial_runoff'); add_default($nl, 'config_sgr_flux_vertical_location'); -add_default($nl, 'config_use_sgr_opt'); +add_default($nl, 'config_use_sgr_opt_kpp'); +add_default($nl, 'config_use_sgr_opt_temp'); +add_default($nl, 'config_use_sgr_opt_salt'); +add_default($nl, 'config_sgr_temperature'); +add_default($nl, 'config_sgr_salinity'); ############################ # Namelist group: coupling # diff --git a/components/mpas-ocean/bld/namelist_files/namelist_defaults_mpaso.xml b/components/mpas-ocean/bld/namelist_files/namelist_defaults_mpaso.xml index 5b3bf93522a6..a2c6465c6d1c 100644 --- a/components/mpas-ocean/bld/namelist_files/namelist_defaults_mpaso.xml +++ b/components/mpas-ocean/bld/namelist_files/namelist_defaults_mpaso.xml @@ -344,7 +344,12 @@ 10.0 0.001 'top' -0 +0 +'sgr' +'sgr' +0.0 +0.0 + .false. diff --git a/components/mpas-ocean/bld/namelist_files/namelist_definition_mpaso.xml b/components/mpas-ocean/bld/namelist_files/namelist_definition_mpaso.xml index 7629e5663eff..8152b1fec724 100644 --- a/components/mpas-ocean/bld/namelist_files/namelist_definition_mpaso.xml +++ b/components/mpas-ocean/bld/namelist_files/namelist_definition_mpaso.xml @@ -1204,14 +1204,45 @@ Valid values: 'top','uniform', 'bottom'. Default: Defined in namelist_defaults.xml - -Option to use or not subglacial runoff (SGR). +Option to use or not subglacial runoff (sgr) in kpp calculation. -Valid values: 0 - don't use SGR, 1 - use both mass and TS from SGR, 2 - use mass only from SGR , 3 - use TS only from SGR, -1 use all + KPP +Valid values: 0 - don't use, 1 - use Default: Defined in namelist_defaults.xml + +Option to choose sgr temperature + +Valid values: 'sgr','current', 'prescribed'. +Default: Defined in namelist_defaults.xml + + + +Option to choose sgr salinity + +Valid values: 'sgr','current', 'prescribed'. +Default: Defined in namelist_defaults.xml + + + +Option to choose sgr temperature, applied when config_use_sgr_opt_temp = 'prescribed' + +Valid values: Any real number. +Default: Defined in namelist_defaults.xml + + + +Option to choose sgr salinity, applied when config_use_sgr_opt_temp = 'prescribed' + +Valid values: Any real number. +Default: Defined in namelist_defaults.xml + diff --git a/components/mpas-ocean/src/Registry.xml b/components/mpas-ocean/src/Registry.xml index 88928169b1ce..b22a9e7f5b94 100644 --- a/components/mpas-ocean/src/Registry.xml +++ b/components/mpas-ocean/src/Registry.xml @@ -710,10 +710,27 @@ description="Selects the vertical location where subglacial runoff is fluxed." possible_values="'top','uniform', 'bottom'" /> - + + + + + Date: Tue, 9 Jul 2024 12:31:41 -0600 Subject: [PATCH 199/451] resolved: conservation check --- components/mpas-ocean/cime_config/buildnml | 3 ++ .../Registry_conservation_check.xml | 17 +++++++++++ .../mpas_ocn_conservation_check.F | 28 ++++++++++++++++++- 3 files changed, 47 insertions(+), 1 deletion(-) diff --git a/components/mpas-ocean/cime_config/buildnml b/components/mpas-ocean/cime_config/buildnml index 7ee71aee3a33..9566cc56bbb8 100755 --- a/components/mpas-ocean/cime_config/buildnml +++ b/components/mpas-ocean/cime_config/buildnml @@ -1192,14 +1192,17 @@ def buildnml(case, caseroot, compname): lines.append('') lines.append('') lines.append('') + lines.append('') lines.append('') lines.append('') lines.append('') lines.append('') lines.append('') lines.append('') + lines.append('') lines.append('') lines.append('') + lines.append('') lines.append('') lines.append('') lines.append('') diff --git a/components/mpas-ocean/src/analysis_members/Registry_conservation_check.xml b/components/mpas-ocean/src/analysis_members/Registry_conservation_check.xml index 0fd2d28d1c6e..646daf743eee 100644 --- a/components/mpas-ocean/src/analysis_members/Registry_conservation_check.xml +++ b/components/mpas-ocean/src/analysis_members/Registry_conservation_check.xml @@ -106,6 +106,9 @@ + @@ -148,6 +151,10 @@ + + @@ -287,14 +298,17 @@ + + + @@ -343,14 +357,17 @@ + + + diff --git a/components/mpas-ocean/src/analysis_members/mpas_ocn_conservation_check.F b/components/mpas-ocean/src/analysis_members/mpas_ocn_conservation_check.F index bdd07e799b5d..612bb2078bf0 100644 --- a/components/mpas-ocean/src/analysis_members/mpas_ocn_conservation_check.F +++ b/components/mpas-ocean/src/analysis_members/mpas_ocn_conservation_check.F @@ -828,8 +828,10 @@ subroutine mass_conservation(domain, err) accumulatedEvaporationFlux, & accumulatedSeaIceFlux, & accumulatedRiverRunoffFlux, & + accumulatedSubglacialRunoffFlux, & accumulatedIceRunoffFlux, & accumulatedRemovedRiverRunoffFlux, & + accumulatedRemovedSubglacialRunoffFlux, & accumulatedRemovedIceRunoffFlux, & accumulatedIcebergFlux, & accumulatedFrazilFlux, & @@ -852,8 +854,10 @@ subroutine mass_conservation(domain, err) evaporationFlux, & seaIceFreshwaterFlux, & riverRunoffFlux, & + subglacialRunoffFlux, & iceRunoffFlux, & removedRiverRunoffFlux, & + removedSubglacialRunoffFlux, & removedIceRunoffFlux, & icebergFreshwaterFlux, & accumulatedFrazilIceMassNew, & @@ -877,7 +881,7 @@ subroutine mass_conservation(domain, err) iCell, ierr, k integer, parameter :: & - nSums = 12 + nSums = 14 integer, dimension(:), pointer :: minLevelCell, maxLevelCell @@ -900,8 +904,10 @@ subroutine mass_conservation(domain, err) call MPAS_pool_get_array(conservationCheckMassAMPool, "accumulatedEvaporationFlux", accumulatedEvaporationFlux) call MPAS_pool_get_array(conservationCheckMassAMPool, "accumulatedSeaIceFlux", accumulatedSeaIceFlux) call MPAS_pool_get_array(conservationCheckMassAMPool, "accumulatedRiverRunoffFlux", accumulatedRiverRunoffFlux) + call MPAS_pool_get_array(conservationCheckMassAMPool, "accumulatedSubglacialRunoffFlux", accumulatedSubglacialRunoffFlux) call MPAS_pool_get_array(conservationCheckMassAMPool, "accumulatedIceRunoffFlux", accumulatedIceRunoffFlux) call MPAS_pool_get_array(conservationCheckMassAMPool, "accumulatedRemovedRiverRunoffFlux",accumulatedRemovedRiverRunoffFlux) + call MPAS_pool_get_array(conservationCheckMassAMPool, "accumulatedRemovedSubglacialRunoffFlux",accumulatedRemovedSubglacialRunoffFlux) call MPAS_pool_get_array(conservationCheckMassAMPool, "accumulatedRemovedIceRunoffFlux", accumulatedRemovedIceRunoffFlux) call MPAS_pool_get_array(conservationCheckMassAMPool, "accumulatedIcebergFlux", accumulatedIcebergFlux) call MPAS_pool_get_array(conservationCheckMassAMPool, "accumulatedFrazilFlux", accumulatedFrazilFlux) @@ -937,8 +943,10 @@ subroutine mass_conservation(domain, err) call mpas_pool_get_array(forcingPool, 'evaporationFlux', evaporationFlux) call mpas_pool_get_array(forcingPool, 'seaIceFreshWaterFlux', seaIceFreshwaterFlux) call mpas_pool_get_array(forcingPool, 'riverRunoffFlux', riverRunoffFlux) + call mpas_pool_get_array(forcingPool, 'subglacialRunoffFlux', subglacialRunoffFlux) call mpas_pool_get_array(forcingPool, 'iceRunoffFlux', iceRunoffFlux) call mpas_pool_get_array(forcingPool, 'removedRiverRunoffFlux', removedRiverRunoffFlux) + call mpas_pool_get_array(forcingPool, 'removedSubglacialRunoffFlux', removedSubglacialRunoffFlux) call mpas_pool_get_array(forcingPool, 'removedIceRunoffFlux', removedIceRunoffFlux) call mpas_pool_get_array(forcingPool, 'icebergFreshWaterFlux', icebergFreshwaterFlux) call mpas_pool_get_array(forcingPool, 'landIceFreshwaterFlux', landIceFreshwaterFlux) @@ -956,6 +964,8 @@ subroutine mass_conservation(domain, err) sumArray( 7) = sumArray( 7) + areaCell(iCell) * removedRiverRunoffFlux(iCell) sumArray( 8) = sumArray( 8) + areaCell(iCell) * removedIceRunoffFlux(iCell) sumArray( 9) = sumArray( 9) + areaCell(iCell) * icebergFreshwaterFlux(iCell) + sumArray(13) = sumArray(13) + areaCell(iCell) * subglacialRunoffFlux(iCell) + sumArray(14) = sumArray(14) + areaCell(iCell) * removedSubglacialRunoffFlux(iCell) enddo if (config_use_frazil_ice_formation) then @@ -1002,6 +1012,8 @@ subroutine mass_conservation(domain, err) accumulatedFrazilFlux = accumulatedFrazilFlux + sumArrayOut(10) accumulatedLandIceFlux = accumulatedLandIceFlux + sumArrayOut(11) accumulatedLandIceFrazilFlux = accumulatedLandIceFrazilFlux + sumArrayOut(12) + accumulatedSubglacialRunoffFlux = accumulatedSubglacialRunoffFlux + sumArrayOut(13) + accumulatedRemovedSubglacialRunoffFlux = accumulatedRemovedSubglacialRunoffFlux + sumArrayOut(14) ! cleanup deallocate(sumArray) @@ -1021,8 +1033,10 @@ subroutine mass_conservation(domain, err) accumulatedEvaporationFlux = accumulatedEvaporationFlux /accumulatedFluxCounter accumulatedSeaIceFlux = accumulatedSeaIceFlux /accumulatedFluxCounter accumulatedRiverRunoffFlux = accumulatedRiverRunoffFlux /accumulatedFluxCounter + accumulatedSubglacialRunoffFlux = accumulatedSubglacialRunoffFlux /accumulatedFluxCounter accumulatedIceRunoffFlux = accumulatedIceRunoffFlux /accumulatedFluxCounter accumulatedRemovedRiverRunoffFlux = accumulatedRemovedRiverRunoffFlux /accumulatedFluxCounter + accumulatedRemovedSubglacialRunoffFlux = accumulatedRemovedSubglacialRunoffFlux /accumulatedFluxCounter accumulatedRemovedIceRunoffFlux = accumulatedRemovedIceRunoffFlux /accumulatedFluxCounter accumulatedIcebergFlux = accumulatedIcebergFlux /accumulatedFluxCounter accumulatedFrazilFlux = accumulatedFrazilFlux /accumulatedFluxCounter @@ -1049,6 +1063,7 @@ subroutine mass_conservation(domain, err) + accumulatedEvaporationFlux & + accumulatedSeaIceFlux & + accumulatedRiverRunoffFlux & + + accumulatedSubglacialRunoffFlux & + accumulatedIceRunoffFlux & + accumulatedIcebergFlux & + accumulatedFrazilFlux & @@ -1083,10 +1098,15 @@ subroutine mass_conservation(domain, err) v=accumulatedIcebergFlux ; write(m,"('icebergFreshwaterFlux ',es16.8,' x2o_Fioi_bergw wberg ',f16.8)") v,v*c; call mpas_log_write(m); s=s+v v=accumulatedEvaporationFlux ; write(m,"('evaporationFlux ',es16.8,' x2o_Foxx_evap wevap ',f16.8)") v,v*c; call mpas_log_write(m); s=s+v v=accumulatedRiverRunoffFlux ; write(m,"('riverRunoffFlux ',es16.8,' x2o_Foxx_rofl wrunoff ',f16.8)") v,v*c; call mpas_log_write(m); s=s+v +v=accumulatedSubglacialRunoffFlux ; write(m,"('subglacialRunoffFlux ',es16.8,' x2o_Foxx_rofl wsgr ',f16.8)") v,v*c; call mpas_log_write(m); s=s+v + if (landIceFreshwaterFluxesOn) then v=accumulatedRemovedRiverRunoffFlux; write(m,"('removedRiverRunoffFlux ',es16.8,' wrunoff ',f16.8)") v,v*c; call mpas_log_write(m); v=accumulatedRiverRunoffFlux+accumulatedRemovedRiverRunoffFlux; write(m,"(' SUM: river runoff',es16.8,' x2o_Foxx_rofl wrunoff SUM ',f16.8)") v,v*c; call mpas_log_write(m) +v=accumulatedRemovedSubglacialRunoffFlux; write(m,"('removedSubglacialRunoffFlux ',es16.8,' wsgr ',f16.8)") v,v*c; call mpas_log_write(m); +v=accumulatedSubglacialRunoffFlux+accumulatedRemovedSubglacialRunoffFlux; + write(m,"(' SUM: subglacial runoff',es16.8,' x2o_Foxx_rofl wsgr SUM ',f16.8)") v,v*c; call mpas_log_write(m) endif v=accumulatedIceRunoffFlux ; write(m,"('iceRunoffFlux ',es16.8,' x2o_Foxx_rofi wfrzrof ',f16.8)") v,v*c; call mpas_log_write(m); s=s+v if (landIceFreshwaterFluxesOn) then @@ -2240,8 +2260,10 @@ subroutine reset_accumulated_variables(domain) accumulatedEvaporationFlux, & accumulatedSeaIceFlux, & accumulatedRiverRunoffFlux, & + accumulatedSubglacialRunoffFlux, & accumulatedIceRunoffFlux, & accumulatedRemovedRiverRunoffFlux, & + accumulatedRemovedSubglacialRunoffFlux, & accumulatedRemovedIceRunoffFlux, & accumulatedIcebergFlux, & accumulatedFrazilFlux, & @@ -2310,8 +2332,10 @@ subroutine reset_accumulated_variables(domain) call MPAS_pool_get_array(conservationCheckMassAMPool, "accumulatedEvaporationFlux", accumulatedEvaporationFlux) call MPAS_pool_get_array(conservationCheckMassAMPool, "accumulatedSeaIceFlux", accumulatedSeaIceFlux) call MPAS_pool_get_array(conservationCheckMassAMPool, "accumulatedRiverRunoffFlux", accumulatedRiverRunoffFlux) + call MPAS_pool_get_array(conservationCheckMassAMPool, "accumulatedSubglacialRunoffFlux", accumulatedSubglacialRunoffFlux) call MPAS_pool_get_array(conservationCheckMassAMPool, "accumulatedIceRunoffFlux", accumulatedIceRunoffFlux) call MPAS_pool_get_array(conservationCheckMassAMPool, "accumulatedRemovedRiverRunoffFlux",accumulatedRemovedRiverRunoffFlux) + call MPAS_pool_get_array(conservationCheckMassAMPool, "accumulatedRemovedSubglacialRunoffFlux",accumulatedRemovedSubglacialRunoffFlux) call MPAS_pool_get_array(conservationCheckMassAMPool, "accumulatedRemovedIceRunoffFlux", accumulatedRemovedIceRunoffFlux) call MPAS_pool_get_array(conservationCheckMassAMPool, "accumulatedIcebergFlux", accumulatedIcebergFlux) call MPAS_pool_get_array(conservationCheckMassAMPool, "accumulatedFrazilFlux", accumulatedFrazilFlux) @@ -2323,8 +2347,10 @@ subroutine reset_accumulated_variables(domain) accumulatedEvaporationFlux = 0.0_RKIND accumulatedSeaIceFlux = 0.0_RKIND accumulatedRiverRunoffFlux = 0.0_RKIND + accumulatedSubglacialRunoffFlux = 0.0_RKIND accumulatedIceRunoffFlux = 0.0_RKIND accumulatedRemovedRiverRunoffFlux = 0.0_RKIND + accumulatedRemovedSubglacialRunoffFlux = 0.0_RKIND accumulatedRemovedIceRunoffFlux = 0.0_RKIND accumulatedIcebergFlux = 0.0_RKIND accumulatedFrazilFlux = 0.0_RKIND From af89287b4221cc4a514ccad511b92b850561f323 Mon Sep 17 00:00:00 2001 From: Irena Vankova Date: Wed, 22 Nov 2023 14:20:29 -0700 Subject: [PATCH 200/451] removed redundant removedSubglacialRunoffFlux --- components/mpas-ocean/cime_config/buildnml | 1 - components/mpas-ocean/src/Registry.xml | 8 -------- .../mpas_ocn_conservation_check.F | 15 +-------------- 3 files changed, 1 insertion(+), 23 deletions(-) diff --git a/components/mpas-ocean/cime_config/buildnml b/components/mpas-ocean/cime_config/buildnml index 9566cc56bbb8..fca676ae03d5 100755 --- a/components/mpas-ocean/cime_config/buildnml +++ b/components/mpas-ocean/cime_config/buildnml @@ -1202,7 +1202,6 @@ def buildnml(case, caseroot, compname): lines.append('') lines.append('') lines.append('') - lines.append('') lines.append('') lines.append('') lines.append('') diff --git a/components/mpas-ocean/src/Registry.xml b/components/mpas-ocean/src/Registry.xml index b22a9e7f5b94..7e3b1d125dae 100644 --- a/components/mpas-ocean/src/Registry.xml +++ b/components/mpas-ocean/src/Registry.xml @@ -3812,14 +3812,6 @@ description="Global sum of fresh water flux from river runoff from the coupler that was removed due to config_remove_AIS_coupler_runoff option. Positive into the ocean." packages="thicknessBulkPKG" /> - - Date: Mon, 27 Nov 2023 16:57:56 -0700 Subject: [PATCH 201/451] correct sgr units in flux add up --- .../src/analysis_members/mpas_ocn_conservation_check.F | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/components/mpas-ocean/src/analysis_members/mpas_ocn_conservation_check.F b/components/mpas-ocean/src/analysis_members/mpas_ocn_conservation_check.F index cc1f2f3e288e..18ba8d6989de 100644 --- a/components/mpas-ocean/src/analysis_members/mpas_ocn_conservation_check.F +++ b/components/mpas-ocean/src/analysis_members/mpas_ocn_conservation_check.F @@ -28,6 +28,7 @@ module ocn_conservation_check use ocn_constants use ocn_config + use ocn_mesh implicit none private @@ -960,7 +961,7 @@ subroutine mass_conservation(domain, err) sumArray( 7) = sumArray( 7) + areaCell(iCell) * removedRiverRunoffFlux(iCell) sumArray( 8) = sumArray( 8) + areaCell(iCell) * removedIceRunoffFlux(iCell) sumArray( 9) = sumArray( 9) + areaCell(iCell) * icebergFreshwaterFlux(iCell) - sumArray(13) = sumArray(13) + areaCell(iCell) * subglacialRunoffFlux(iCell) + sumArray(13) = sumArray(13) + areaCell(iCell) * subglacialRunoffFlux(iCell) / areaCell(iCell) * rho_sw enddo if (config_use_frazil_ice_formation) then From 957d8b218d3cf06b2c4d94325d48a8507c0bdcfd Mon Sep 17 00:00:00 2001 From: Irena Vankova Date: Mon, 27 Nov 2023 17:46:10 -0700 Subject: [PATCH 202/451] energy conservation check --- .../mpas_ocn_conservation_check.F | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) diff --git a/components/mpas-ocean/src/analysis_members/mpas_ocn_conservation_check.F b/components/mpas-ocean/src/analysis_members/mpas_ocn_conservation_check.F index 18ba8d6989de..e793babb51a1 100644 --- a/components/mpas-ocean/src/analysis_members/mpas_ocn_conservation_check.F +++ b/components/mpas-ocean/src/analysis_members/mpas_ocn_conservation_check.F @@ -428,6 +428,7 @@ subroutine energy_conservation(domain, err) accumulatedEvapTemperatureFlux, & accumulatedSeaIceTemperatureFlux, & accumulatedRiverRunoffTemperatureFlux, & + accumulatedSubglacialRunoffTemperatureFlux, & accumulatedIcebergTemperatureFlux real(kind=RKIND), dimension(:), allocatable :: & @@ -464,7 +465,8 @@ subroutine energy_conservation(domain, err) real(kind=RKIND), dimension(:,:), pointer :: & - activeTracersSurfaceFluxRunoff + activeTracersSurfaceFluxRunoff, & + activeTracersSurfaceFluxSubglacialRunoff type (MPAS_timeInterval_type) :: & timeStepESMF @@ -481,7 +483,7 @@ subroutine energy_conservation(domain, err) ierr integer, parameter :: & - nSums = 19 + nSums = 20 character(len=160) :: & m @@ -514,6 +516,7 @@ subroutine energy_conservation(domain, err) call MPAS_pool_get_array(conservationCheckEnergyAMPool, "accumulatedEvapTemperatureFlux", accumulatedEvapTemperatureFlux) call MPAS_pool_get_array(conservationCheckEnergyAMPool, "accumulatedSeaIceTemperatureFlux", accumulatedSeaIceTemperatureFlux) call MPAS_pool_get_array(conservationCheckEnergyAMPool, "accumulatedRiverRunoffTemperatureFlux", accumulatedRiverRunoffTemperatureFlux) + call MPAS_pool_get_array(conservationCheckEnergyAMPool, "accumulatedSubglacialRunoffTemperatureFlux", accumulatedSubglacialRunoffTemperatureFlux) call MPAS_pool_get_array(conservationCheckEnergyAMPool, "accumulatedIcebergTemperatureFlux", accumulatedIcebergTemperatureFlux) !------------------------------------------------------------- @@ -557,6 +560,7 @@ subroutine energy_conservation(domain, err) call mpas_pool_get_subpool(forcingPool, 'tracersSurfaceFlux',tracersSurfaceFluxPool) call mpas_pool_get_dimension(tracersSurfaceFluxPool, 'index_temperatureSurfaceFlux', index_temperature_flux) call mpas_pool_get_array(tracersSurfaceFluxPool, 'activeTracersSurfaceFluxRunoff', activeTracersSurfaceFluxRunoff) + call mpas_pool_get_array(tracersSurfaceFluxPool, 'activeTracersSurfaceFluxSubglacialRunoff', activeTracersSurfaceFluxSubglacialRunoff) call mpas_pool_get_array(statePool, 'accumulatedFrazilIceMass', accumulatedFrazilIceMassNew, 2) call mpas_pool_get_array(statePool, 'accumulatedFrazilIceMass', accumulatedFrazilIceMassOld, 1) @@ -581,6 +585,7 @@ subroutine energy_conservation(domain, err) ! river runoff temperature flux sumArray(14) = sumArray(14) + areaCell(iCell) * activeTracersSurfaceFluxRunoff(index_temperature_flux,iCell) sumArray(15) = sumArray(15) + areaCell(iCell) * icebergTemperatureFlux(iCell) + sumArray(20) = sumArray(20) + areaCell(iCell) * activeTracersSurfaceFluxSubglacialRunoff(index_temperature_flux,iCell) enddo ! iCell @@ -635,6 +640,7 @@ subroutine energy_conservation(domain, err) accumulatedLandIceHeatFlux = accumulatedLandIceHeatFlux + sumArrayOut(17) accumulatedLandIceFrazilHeatFlux = accumulatedLandIceFrazilHeatFlux + sumArrayOut(18) accumulatedRemovedIceRunoffHeatFlux = accumulatedRemovedIceRunoffHeatFlux + sumArrayOut(19) + accumulatedSubglacialRunoffTemperatureFlux = accumulatedSubglacialRunoffTemperatureFlux + sumArrayOut(20) ! cleanup deallocate(sumArray) @@ -664,6 +670,7 @@ subroutine energy_conservation(domain, err) accumulatedEvapTemperatureFlux = accumulatedEvapTemperatureFlux /accumulatedFluxCounter accumulatedSeaIceTemperatureFlux = accumulatedSeaIceTemperatureFlux /accumulatedFluxCounter accumulatedRiverRunoffTemperatureFlux = accumulatedRiverRunoffTemperatureFlux /accumulatedFluxCounter + accumulatedSubglacialRunoffTemperatureFlux = accumulatedSubglacialRunoffTemperatureFlux /accumulatedFluxCounter accumulatedIcebergTemperatureFlux = accumulatedIcebergTemperatureFlux /accumulatedFluxCounter accumulatedLandIceFrazilHeatFlux = accumulatedLandIceFrazilHeatFlux /accumulatedFluxCounter accumulatedRemovedIceRunoffHeatFlux = accumulatedRemovedIceRunoffHeatFlux /accumulatedFluxCounter @@ -698,6 +705,7 @@ subroutine energy_conservation(domain, err) + accumulatedEvapTemperatureFlux *rho_sw*cp_sw & + accumulatedSeaIceTemperatureFlux *rho_sw*cp_sw & + accumulatedRiverRunoffTemperatureFlux *rho_sw*cp_sw & + + accumulatedSubglacialRunoffTemperatureFlux *rho_sw*cp_sw & + accumulatedIcebergTemperatureFlux*rho_sw*cp_sw ! note, accumulatedLandIceFrazilHeatFlux not added because already in accumulatedFrazilHeatFlux @@ -761,6 +769,7 @@ subroutine energy_conservation(domain, err) v=accumulatedEvapTemperatureFlux *rho_sw*cp_sw; write(m,"('EvapTemperatureFlux ',es16.8,' ',f16.8)") v,v/A; call mpas_log_write(m); s=s+v v=accumulatedSeaIceTemperatureFlux *rho_sw*cp_sw; write(m,"('SeaIceTemperatureFlux ',es16.8,' ',f16.8)") v,v/A; call mpas_log_write(m); s=s+v v=accumulatedRiverRunoffTemperatureFlux*rho_sw*cp_sw; write(m,"('RiverRunoffTempFlux ',es16.8,' ',f16.8)") v,v/A; call mpas_log_write(m); s=s+v +v=accumulatedSubglacialRunoffTemperatureFlux*rho_sw*cp_sw; write(m,"('RiverRunoffTempFlux ',es16.8,' ',f16.8)") v,v/A; call mpas_log_write(m); s=s+v v=accumulatedIcebergTemperatureFlux*rho_sw*cp_sw; write(m,"('IcebergTemperatureFlux ',es16.8,' ',f16.8)") v,v/A; call mpas_log_write(m); s=s+v write(m,"('SUM IMPLICIT HEAT FLUXES ',es16.8,' hh20temp ',f16.8,es16.8)") s, s/A; call mpas_log_write(m) s = s + explicitHeatFluxSum @@ -2243,6 +2252,7 @@ subroutine reset_accumulated_variables(domain) accumulatedEvapTemperatureFlux, & accumulatedSeaIceTemperatureFlux, & accumulatedRiverRunoffTemperatureFlux, & + accumulatedSubglacialRunoffTemperatureFlux, & accumulatedIcebergTemperatureFlux real(kind=RKIND), pointer :: & @@ -2292,6 +2302,7 @@ subroutine reset_accumulated_variables(domain) call MPAS_pool_get_array(conservationCheckEnergyAMPool, "accumulatedEvapTemperatureFlux", accumulatedEvapTemperatureFlux) call MPAS_pool_get_array(conservationCheckEnergyAMPool, "accumulatedSeaIceTemperatureFlux", accumulatedSeaIceTemperatureFlux) call MPAS_pool_get_array(conservationCheckEnergyAMPool, "accumulatedRiverRunoffTemperatureFlux", accumulatedRiverRunoffTemperatureFlux) + call MPAS_pool_get_array(conservationCheckEnergyAMPool, "accumulatedSubglacialRunoffTemperatureFlux", accumulatedSubglacialRunoffTemperatureFlux) call MPAS_pool_get_array(conservationCheckEnergyAMPool, "accumulatedIcebergTemperatureFlux", accumulatedIcebergTemperatureFlux) accumulatedFluxCounter = 0 @@ -2310,6 +2321,7 @@ subroutine reset_accumulated_variables(domain) accumulatedEvapTemperatureFlux = 0.0_RKIND accumulatedSeaIceTemperatureFlux = 0.0_RKIND accumulatedRiverRunoffTemperatureFlux = 0.0_RKIND + accumulatedSubglacialRunoffTemperatureFlux = 0.0_RKIND accumulatedIcebergTemperatureFlux = 0.0_RKIND accumulatedLandIceFrazilHeatFlux = 0.0_RKIND accumulatedRemovedIceRunoffHeatFlux = 0.0_RKIND From ecb06580badc28a55316eea6caae273eb1fd415b Mon Sep 17 00:00:00 2001 From: Irena Vankova Date: Tue, 9 Jul 2024 12:34:50 -0600 Subject: [PATCH 203/451] resolved: conservation check #2 --- components/mpas-ocean/cime_config/buildnml | 1 + .../Registry_conservation_check.xml | 5 +++ .../mpas_ocn_conservation_check.F | 32 ++++++++++++++++--- 3 files changed, 33 insertions(+), 5 deletions(-) diff --git a/components/mpas-ocean/cime_config/buildnml b/components/mpas-ocean/cime_config/buildnml index fca676ae03d5..725c26d28181 100755 --- a/components/mpas-ocean/cime_config/buildnml +++ b/components/mpas-ocean/cime_config/buildnml @@ -1208,6 +1208,7 @@ def buildnml(case, caseroot, compname): lines.append('') lines.append('') lines.append('') + lines.append('') lines.append('') lines.append('') lines.append('') diff --git a/components/mpas-ocean/src/analysis_members/Registry_conservation_check.xml b/components/mpas-ocean/src/analysis_members/Registry_conservation_check.xml index 646daf743eee..8a79ac12629e 100644 --- a/components/mpas-ocean/src/analysis_members/Registry_conservation_check.xml +++ b/components/mpas-ocean/src/analysis_members/Registry_conservation_check.xml @@ -205,6 +205,9 @@ + + @@ -375,6 +379,7 @@ + diff --git a/components/mpas-ocean/src/analysis_members/mpas_ocn_conservation_check.F b/components/mpas-ocean/src/analysis_members/mpas_ocn_conservation_check.F index e793babb51a1..cdba7b357f2d 100644 --- a/components/mpas-ocean/src/analysis_members/mpas_ocn_conservation_check.F +++ b/components/mpas-ocean/src/analysis_members/mpas_ocn_conservation_check.F @@ -1180,10 +1180,14 @@ subroutine salt_conservation(domain, err) absoluteSaltError, & relativeSaltError + real(kind=RKIND), dimension(:,:), pointer :: & + activeTracersSurfaceFluxSubglacialRunoff + real(kind=RKIND), pointer :: & accumulatedSeaIceSalinityFlux, & - accumulatedFrazilSalinityFlux ! accumulatedLandIceFrazilSalinityFlux is not present because it is always 0 + accumulatedFrazilSalinityFlux, & + accumulatedSubglacialRunoffSalinityFlux real(kind=RKIND), dimension(:), allocatable :: & sumArray, & @@ -1204,14 +1208,15 @@ subroutine salt_conservation(domain, err) dt, dtAvg, v, A, s, c integer, pointer :: & - nCellsSolve + nCellsSolve, & + index_salinity_flux integer :: & iCell, & ierr integer, parameter :: & - nSums = 3 + nSums = 4 logical, pointer :: & activeTracersBulkRestoringPKG @@ -1229,6 +1234,7 @@ subroutine salt_conservation(domain, err) call MPAS_pool_get_array(conservationCheckSaltAMPool, "accumulatedSeaIceSalinityFlux", accumulatedSeaIceSalinityFlux) call MPAS_pool_get_array(conservationCheckSaltAMPool, "accumulatedFrazilSalinityFlux", accumulatedFrazilSalinityFlux) + call MPAS_pool_get_array(conservationCheckSaltAMPool, "accumulatedSubglacialRunoffSalinityFlux", accumulatedSubglacialRunoffSalinityFlux) !------------------------------------------------------------- ! Net salt flux to ice @@ -1254,11 +1260,17 @@ subroutine salt_conservation(domain, err) call mpas_pool_get_array(forcingPool, 'seaIceSalinityFlux', seaIceSalinityFlux) call mpas_pool_get_array(statePool, 'accumulatedFrazilIceSalinity', accumulatedFrazilIceSalinityOld, 1) call mpas_pool_get_array(statePool, 'accumulatedFrazilIceSalinity', accumulatedFrazilIceSalinityNew, 2) + call mpas_pool_get_array(tracersSurfaceFluxPool, 'activeTracersSurfaceFluxSubglacialRunoff', activeTracersSurfaceFluxSubglacialRunoff) + call mpas_pool_get_dimension(tracersSurfaceFluxPool, 'index_salinitySurfaceFlux', index_salinity_flux) + + do iCell = 1, nCellsSolve ! salt flux to ocean sumArray(1) = sumArray(1) + areaCell(iCell) * seaIceSalinityFlux(iCell) + ! subglacial runoff + sumArray(4) = sumArray(4) + areaCell(iCell) * activeTracersSurfaceFluxSubglacialRunoff(index_salinity_flux,iCell) enddo ! iCell if (config_use_frazil_ice_formation) then @@ -1285,6 +1297,7 @@ subroutine salt_conservation(domain, err) ! accumulate fluxes accumulatedSeaIceSalinityFlux = accumulatedSeaIceSalinityFlux + sumArrayOut(1) accumulatedFrazilSalinityFlux = accumulatedFrazilSalinityFlux + sumArrayOut(2) + accumulatedSubglacialRunoffSalinityFlux = accumulatedSubglacialRunoffSalinityFlux + sumArrayOut(4) ! cleanup deallocate(sumArray) @@ -1301,6 +1314,7 @@ subroutine salt_conservation(domain, err) ! Average the fluxes accumulatedSeaIceSalinityFlux = accumulatedSeaIceSalinityFlux /accumulatedFluxCounter accumulatedFrazilSalinityFlux = accumulatedFrazilSalinityFlux /accumulatedFluxCounter + accumulatedSubglacialRunoffSalinityFlux = accumulatedSubglacialRunoffSalinityFlux /accumulatedFluxCounter ! get initial salt content call MPAS_pool_get_array(conservationCheckSaltAMPool, "initialSalt", initialSalt) @@ -1317,7 +1331,8 @@ subroutine salt_conservation(domain, err) call MPAS_pool_get_array(conservationCheckSaltAMPool, "netSaltFlux", netSaltFlux) netSaltFlux = accumulatedSeaIceSalinityFlux & - + accumulatedFrazilSalinityFlux + + accumulatedFrazilSalinityFlux & + + accumulatedSubglacialRunoffSalinityFlux ! compute the final salt error call MPAS_pool_get_array(conservationCheckSaltAMPool, "absoluteSaltError", absoluteSaltError) @@ -1347,6 +1362,8 @@ subroutine salt_conservation(domain, err) .and.config_frazil_under_land_ice) then v=0; write(m,"('LandIceFrazilSalinityFlux',es16.8,' (already in wmelt, do not sum) ',f16.8)") v,v*c; call mpas_log_write(m); !no sum: s=s+v end if +v=accumulatedSubglacialRunoffSalinityFlux ; write(m,"('SubglacialRunoffSalinityFlux ',es16.8,' x2o_Fioi_salt salt ',f16.8)") v,v*c; call mpas_log_write(m); s=s+v + write(m,"('SUM VOLUME FLUXES ',es16.8,' ',f16.8,es16.8)") s, s*c; call mpas_log_write(m) call mpas_log_write(' ') @@ -2272,7 +2289,8 @@ subroutine reset_accumulated_variables(domain) real(kind=RKIND), pointer :: & accumulatedSeaIceSalinityFlux, & - accumulatedFrazilSalinityFlux + accumulatedFrazilSalinityFlux, & + accumulatedSubglacialRunoffSalinityFlux real(kind=RKIND), pointer :: & accumulatedCarbonSourceSink, & @@ -2362,9 +2380,13 @@ subroutine reset_accumulated_variables(domain) call MPAS_pool_get_array(conservationCheckSaltAMPool, "accumulatedSeaIceSalinityFlux", accumulatedSeaIceSalinityFlux) call MPAS_pool_get_array(conservationCheckSaltAMPool, "accumulatedFrazilSalinityFlux", accumulatedFrazilSalinityFlux) + call MPAS_pool_get_array(conservationCheckSaltAMPool, "accumulatedLandIceFrazilSalinityFlux", accumulatedLandIceFrazilSalinityFlux) + call MPAS_pool_get_array(conservationCheckSaltAMPool, "accumulatedSubglacialRunoffSalinityFlux", accumulatedSubglacialRunoffSalinityFlux) + accumulatedSeaIceSalinityFlux = 0.0_RKIND accumulatedFrazilSalinityFlux = 0.0_RKIND + accumulatedSubglacialRunoffSalinityFlux = 0.0_RKIND call MPAS_pool_get_subpool(domain % blocklist % structs, "conservationCheckCarbonAM", conservationCheckCarbonAMPool) From a430272a1d1c41468387cc47e1a3038f2aa7187e Mon Sep 17 00:00:00 2001 From: Irena Vankova Date: Tue, 28 Nov 2023 09:54:29 -0700 Subject: [PATCH 204/451] salt: added tracersSurfaceFluxPool definition --- .../src/analysis_members/mpas_ocn_conservation_check.F | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/components/mpas-ocean/src/analysis_members/mpas_ocn_conservation_check.F b/components/mpas-ocean/src/analysis_members/mpas_ocn_conservation_check.F index cdba7b357f2d..1278342ceb2d 100644 --- a/components/mpas-ocean/src/analysis_members/mpas_ocn_conservation_check.F +++ b/components/mpas-ocean/src/analysis_members/mpas_ocn_conservation_check.F @@ -1170,7 +1170,8 @@ subroutine salt_conservation(domain, err) conservationCheckSaltAMPool, & meshPool, & statePool, & - forcingPool + forcingPool, & + tracersSurfaceFluxPool real(kind=RKIND), pointer :: & initialSalt, & @@ -1260,6 +1261,7 @@ subroutine salt_conservation(domain, err) call mpas_pool_get_array(forcingPool, 'seaIceSalinityFlux', seaIceSalinityFlux) call mpas_pool_get_array(statePool, 'accumulatedFrazilIceSalinity', accumulatedFrazilIceSalinityOld, 1) call mpas_pool_get_array(statePool, 'accumulatedFrazilIceSalinity', accumulatedFrazilIceSalinityNew, 2) + call mpas_pool_get_subpool(forcingPool, 'tracersSurfaceFlux',tracersSurfaceFluxPool) call mpas_pool_get_array(tracersSurfaceFluxPool, 'activeTracersSurfaceFluxSubglacialRunoff', activeTracersSurfaceFluxSubglacialRunoff) call mpas_pool_get_dimension(tracersSurfaceFluxPool, 'index_salinitySurfaceFlux', index_salinity_flux) From 7c404b94c7c25415fac6d8e54b10257b4a20c58c Mon Sep 17 00:00:00 2001 From: Irena Vankova Date: Tue, 28 Nov 2023 18:19:49 -0700 Subject: [PATCH 205/451] typo in print sgheatflux --- .../src/analysis_members/mpas_ocn_conservation_check.F | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/components/mpas-ocean/src/analysis_members/mpas_ocn_conservation_check.F b/components/mpas-ocean/src/analysis_members/mpas_ocn_conservation_check.F index 1278342ceb2d..881b53efd5b5 100644 --- a/components/mpas-ocean/src/analysis_members/mpas_ocn_conservation_check.F +++ b/components/mpas-ocean/src/analysis_members/mpas_ocn_conservation_check.F @@ -769,7 +769,7 @@ subroutine energy_conservation(domain, err) v=accumulatedEvapTemperatureFlux *rho_sw*cp_sw; write(m,"('EvapTemperatureFlux ',es16.8,' ',f16.8)") v,v/A; call mpas_log_write(m); s=s+v v=accumulatedSeaIceTemperatureFlux *rho_sw*cp_sw; write(m,"('SeaIceTemperatureFlux ',es16.8,' ',f16.8)") v,v/A; call mpas_log_write(m); s=s+v v=accumulatedRiverRunoffTemperatureFlux*rho_sw*cp_sw; write(m,"('RiverRunoffTempFlux ',es16.8,' ',f16.8)") v,v/A; call mpas_log_write(m); s=s+v -v=accumulatedSubglacialRunoffTemperatureFlux*rho_sw*cp_sw; write(m,"('RiverRunoffTempFlux ',es16.8,' ',f16.8)") v,v/A; call mpas_log_write(m); s=s+v +v=accumulatedSubglacialRunoffTemperatureFlux*rho_sw*cp_sw; write(m,"('SubglacialRunoffTempFlux ',es16.8,' ',f16.8)") v,v/A; call mpas_log_write(m); s=s+v v=accumulatedIcebergTemperatureFlux*rho_sw*cp_sw; write(m,"('IcebergTemperatureFlux ',es16.8,' ',f16.8)") v,v/A; call mpas_log_write(m); s=s+v write(m,"('SUM IMPLICIT HEAT FLUXES ',es16.8,' hh20temp ',f16.8,es16.8)") s, s/A; call mpas_log_write(m) s = s + explicitHeatFluxSum From e89e8544f1ef2740cca4e105fff2a3ea98153e82 Mon Sep 17 00:00:00 2001 From: Irena Vankova Date: Thu, 30 Nov 2023 11:52:31 -0700 Subject: [PATCH 206/451] add subglacial to kpp in diagnostics --- .../src/shared/mpas_ocn_diagnostics.F | 35 +++++++++++++++---- 1 file changed, 29 insertions(+), 6 deletions(-) diff --git a/components/mpas-ocean/src/shared/mpas_ocn_diagnostics.F b/components/mpas-ocean/src/shared/mpas_ocn_diagnostics.F index f65749af25fc..f04893b671c0 100644 --- a/components/mpas-ocean/src/shared/mpas_ocn_diagnostics.F +++ b/components/mpas-ocean/src/shared/mpas_ocn_diagnostics.F @@ -3289,16 +3289,18 @@ subroutine ocn_compute_KPP_input_fields(statePool, forcingPool, & !----------------------------------------------------------------- integer :: & - iCell, iEdge, i, &! loop indices for cell, edge, neighbors - kmin, &! topmost active cell index - nCells, &! number of cells - err, &! local error code - timeLevel ! time level for state variables (default 1) + iCell, iEdge, i, k, &! loop indices for cell, edge, neighbors + kmin, &! topmost active cell index + nCells, &! number of cells + err, &! local error code + timeLevel ! time level for state variables (default 1) real (kind=RKIND) :: & fracAbsorbed, &! fraction of sfc flux absorbed fracAbsorbedRunoff, &! same for runoff fracAbsorbedSubglacialRunoff, &! same for subglacial runoff + zTop,zBot, &! temporary variables + transmissionCoeffTop,transmissionCoeffBot, &! temporary variables sumSurfaceStressSquared ! sum of sfc stress squared ! pointers for variable/pool retrievals @@ -3488,10 +3490,31 @@ subroutine ocn_compute_KPP_input_fields(statePool, forcingPool, & -layerThickness(kmin, iCell)/ & config_flux_attenuation_coefficient_runoff)) if (config_use_sgr_opt_kpp == 1) then - fracAbsorbedSubglacialRunoff = 1.0_RKIND & + if ( trim(config_sgr_flux_vertical_location) == 'top' ) then + fracAbsorbedSubglacialRunoff = 1.0_RKIND & - exp( max(-100.0_RKIND, & -layerThickness(kmin, iCell)/ & config_flux_attenuation_coefficient_subglacial_runoff)) + else if ( trim(config_sgr_flux_vertical_location) == 'uniform' ) then + ! calculate total thickness into variable zTop + zTop = 0.0_RKIND + do k = minLevelCell(iCell), maxLevelCell(iCell) + zTop = zTop + layerThickness(k,iCell) + end do + ! distribute flux evenly throughout water column + fracAbsorbedSubglacialRunoff = layerThickness(kmin, iCell) / zTop + else if ( trim(config_sgr_flux_vertical_location) == 'bottom' ) then + zTop = 0.0_RKIND + do k = maxLevelCell(iCell), minLevelCell(iCell), -1 + zBot = zTop - layerThickness(k,iCell) + if (k == minLevelCell(iCell)) then + transmissionCoeffTop = exp( max(zTop / config_flux_attenuation_coefficient_runoff, -100.0_RKIND) ) + transmissionCoeffBot = exp( max(zBot / config_flux_attenuation_coefficient_runoff, -100.0_RKIND) ) + fracAbsorbedSubglacialRunoff = transmissionCoeffTop - transmissionCoeffBot + end if + zTop = zBot + end do + end if else fracAbsorbedSubglacialRunoff = 0.0_RKIND end if From 52a47584d0f553a65f0f386516cac415c83e2eee Mon Sep 17 00:00:00 2001 From: Irena Vankova Date: Tue, 9 Jul 2024 12:36:10 -0600 Subject: [PATCH 207/451] resolved: fris meshes --- components/mpas-ocean/cime_config/buildnml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/components/mpas-ocean/cime_config/buildnml b/components/mpas-ocean/cime_config/buildnml index 725c26d28181..f5a05e03aade 100755 --- a/components/mpas-ocean/cime_config/buildnml +++ b/components/mpas-ocean/cime_config/buildnml @@ -281,6 +281,8 @@ def buildnml(case, caseroot, compname): data_ismf_file = 'prescribed_ismf_adusumilli2020.SOwISC12to60E2r4.230516.nc' if ocn_tidal_mixing == 'true': u_tidal_rms_file = 'velocityTidalRMS_CATS2008.SOwISC12to60E2r4.20210114.nc' + if ocn_sgr == 'data': + data_sgr_file = 'SOwISC12to60E2r4_DSGR.nc' elif ocn_grid == 'FRISwISC08to60E3r1': decomp_date = '20230913' # changed to date of partiotions in ../files_for_e3sm/assembled_files/inputdata/ocn/mpas-o/FRISwISC08to60E3r1/partitions From c6a0104624162cf57cf49241d3655446cb697885 Mon Sep 17 00:00:00 2001 From: Irena Vankova Date: Thu, 1 Feb 2024 10:53:19 -0700 Subject: [PATCH 208/451] cleanup --- components/mpas-ocean/bld/build-namelist | 2 +- .../bld/namelist_files/namelist_definition_mpaso.xml | 4 ++-- components/mpas-ocean/cime_config/config_component.xml | 2 +- components/mpas-ocean/src/Registry.xml | 4 ++-- components/mpas-ocean/src/shared/mpas_ocn_forcing.F | 2 +- 5 files changed, 7 insertions(+), 7 deletions(-) diff --git a/components/mpas-ocean/bld/build-namelist b/components/mpas-ocean/bld/build-namelist index e1d2548dffeb..e33f4dc1c796 100755 --- a/components/mpas-ocean/bld/build-namelist +++ b/components/mpas-ocean/bld/build-namelist @@ -56,7 +56,7 @@ OPTIONS Options are: none, data, internal, coupled -ocn_sgr variable for defining how the ocn model will handle subglacial runoff - Options are: none, data, coupled + Options are: none, data -decomp_prefix decomp_prefix variable -date_stamp date_stamp variable -cfg_grid Directory containing MPASO configuration scripts. diff --git a/components/mpas-ocean/bld/namelist_files/namelist_definition_mpaso.xml b/components/mpas-ocean/bld/namelist_files/namelist_definition_mpaso.xml index 8152b1fec724..97bd989f06c5 100644 --- a/components/mpas-ocean/bld/namelist_files/namelist_definition_mpaso.xml +++ b/components/mpas-ocean/bld/namelist_files/namelist_definition_mpaso.xml @@ -1216,7 +1216,7 @@ Default: Defined in namelist_defaults.xml category="forcing" group="forcing"> Option to choose sgr temperature -Valid values: 'sgr','current', 'prescribed'. +Valid values: 'sgr', 'prescribed'. Default: Defined in namelist_defaults.xml @@ -1224,7 +1224,7 @@ Default: Defined in namelist_defaults.xml category="forcing" group="forcing"> Option to choose sgr salinity -Valid values: 'sgr','current', 'prescribed'. +Valid values: 'sgr', 'prescribed'. Default: Defined in namelist_defaults.xml diff --git a/components/mpas-ocean/cime_config/config_component.xml b/components/mpas-ocean/cime_config/config_component.xml index eb8e09519829..83b4501ee5e5 100644 --- a/components/mpas-ocean/cime_config/config_component.xml +++ b/components/mpas-ocean/cime_config/config_component.xml @@ -41,7 +41,7 @@ char - none,data,coupled + none,data none none diff --git a/components/mpas-ocean/src/Registry.xml b/components/mpas-ocean/src/Registry.xml index 7e3b1d125dae..1ba2259da87f 100644 --- a/components/mpas-ocean/src/Registry.xml +++ b/components/mpas-ocean/src/Registry.xml @@ -716,11 +716,11 @@ /> Date: Tue, 9 Jul 2024 12:37:17 -0600 Subject: [PATCH 209/451] resolved: fris meshes #2 --- .../mpas-ocean/bld/namelist_files/namelist_defaults_mpaso.xml | 2 +- components/mpas-ocean/cime_config/buildnml | 3 ++- components/mpas-ocean/src/Registry.xml | 2 +- 3 files changed, 4 insertions(+), 3 deletions(-) diff --git a/components/mpas-ocean/bld/namelist_files/namelist_defaults_mpaso.xml b/components/mpas-ocean/bld/namelist_files/namelist_defaults_mpaso.xml index a2c6465c6d1c..9e14fbf04d1b 100644 --- a/components/mpas-ocean/bld/namelist_files/namelist_defaults_mpaso.xml +++ b/components/mpas-ocean/bld/namelist_files/namelist_defaults_mpaso.xml @@ -343,7 +343,7 @@ 0.001 10.0 0.001 -'top' +'uniform' 0 'sgr' 'sgr' diff --git a/components/mpas-ocean/cime_config/buildnml b/components/mpas-ocean/cime_config/buildnml index f5a05e03aade..4d5029555afc 100755 --- a/components/mpas-ocean/cime_config/buildnml +++ b/components/mpas-ocean/cime_config/buildnml @@ -379,6 +379,8 @@ def buildnml(case, caseroot, compname): data_ismf_file = 'prescribed_ismf_paolo2023.IcoswISC30E3r5.20240227.nc' if ocn_tidal_mixing == 'true': u_tidal_rms_file = 'velocityTidalRMS_CATS2008.IcoswISC30E3r5.20231120.nc' + if ocn_sgr == 'data': + data_sgr_file = 'IcoswISC30E3r5_DSGR.nc' elif ocn_grid == 'IcosXISC30E3r7': decomp_date = '20240314' @@ -404,7 +406,6 @@ def buildnml(case, caseroot, compname): if ocn_ismf == 'data': data_ismf_file = 'prescribed_ismf_paolo2023.RRSwISC6to18E3r5.20240327.nc' - #-------------------------------------------------------------------- # Set OCN_FORCING = datm_forced_restoring if restoring file is available #-------------------------------------------------------------------- diff --git a/components/mpas-ocean/src/Registry.xml b/components/mpas-ocean/src/Registry.xml index 1ba2259da87f..e48a84d2437c 100644 --- a/components/mpas-ocean/src/Registry.xml +++ b/components/mpas-ocean/src/Registry.xml @@ -706,7 +706,7 @@ description="The length scale of exponential decay of subglacial runoff. Fluxes are multiplied by $e^{z/\gamma}$, where this coefficient is $\gamma$." possible_values="Any positive real number." /> - From cdc60afb77c6129f2ece53ee85b4d49e7c92f095 Mon Sep 17 00:00:00 2001 From: Irena Vankova Date: Wed, 7 Feb 2024 16:13:31 -0700 Subject: [PATCH 210/451] changed sgr kpp default to 1 = use --- .../mpas-ocean/bld/namelist_files/namelist_defaults_mpaso.xml | 2 +- components/mpas-ocean/src/Registry.xml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/components/mpas-ocean/bld/namelist_files/namelist_defaults_mpaso.xml b/components/mpas-ocean/bld/namelist_files/namelist_defaults_mpaso.xml index 9e14fbf04d1b..40a3b3ca86f5 100644 --- a/components/mpas-ocean/bld/namelist_files/namelist_defaults_mpaso.xml +++ b/components/mpas-ocean/bld/namelist_files/namelist_defaults_mpaso.xml @@ -344,7 +344,7 @@ 10.0 0.001 'uniform' -0 +1 'sgr' 'sgr' 0.0 diff --git a/components/mpas-ocean/src/Registry.xml b/components/mpas-ocean/src/Registry.xml index e48a84d2437c..506dd5772c09 100644 --- a/components/mpas-ocean/src/Registry.xml +++ b/components/mpas-ocean/src/Registry.xml @@ -710,7 +710,7 @@ description="Selects the vertical location where subglacial runoff is fluxed." possible_values="'top','uniform', 'bottom'" /> - From 1664002c0aba6072e624795f62bb72fa1b185298 Mon Sep 17 00:00:00 2001 From: Irena Vankova Date: Mon, 8 Jul 2024 16:04:08 -0600 Subject: [PATCH 211/451] change config_sgr_flux_vertical_location default to bottom --- components/mpas-ocean/src/Registry.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/components/mpas-ocean/src/Registry.xml b/components/mpas-ocean/src/Registry.xml index 506dd5772c09..1ceddac39fcb 100644 --- a/components/mpas-ocean/src/Registry.xml +++ b/components/mpas-ocean/src/Registry.xml @@ -706,7 +706,7 @@ description="The length scale of exponential decay of subglacial runoff. Fluxes are multiplied by $e^{z/\gamma}$, where this coefficient is $\gamma$." possible_values="Any positive real number." /> - From f0e802d4a6d447c9dcadcced6bcb02fc06770438 Mon Sep 17 00:00:00 2001 From: Irena Vankova Date: Tue, 9 Jul 2024 13:07:55 -0600 Subject: [PATCH 212/451] rmv conservation check on sgr --- .../Registry_conservation_check.xml | 22 ----- .../mpas_ocn_conservation_check.F | 96 +++++-------------- 2 files changed, 23 insertions(+), 95 deletions(-) diff --git a/components/mpas-ocean/src/analysis_members/Registry_conservation_check.xml b/components/mpas-ocean/src/analysis_members/Registry_conservation_check.xml index 8a79ac12629e..0fd2d28d1c6e 100644 --- a/components/mpas-ocean/src/analysis_members/Registry_conservation_check.xml +++ b/components/mpas-ocean/src/analysis_members/Registry_conservation_check.xml @@ -106,9 +106,6 @@ - @@ -151,10 +148,6 @@ - - @@ -205,9 +194,6 @@ - - - - @@ -319,7 +302,6 @@ - @@ -361,17 +343,14 @@ - - - @@ -379,7 +358,6 @@ - diff --git a/components/mpas-ocean/src/analysis_members/mpas_ocn_conservation_check.F b/components/mpas-ocean/src/analysis_members/mpas_ocn_conservation_check.F index 881b53efd5b5..5551d5758db2 100644 --- a/components/mpas-ocean/src/analysis_members/mpas_ocn_conservation_check.F +++ b/components/mpas-ocean/src/analysis_members/mpas_ocn_conservation_check.F @@ -28,7 +28,6 @@ module ocn_conservation_check use ocn_constants use ocn_config - use ocn_mesh implicit none private @@ -428,7 +427,6 @@ subroutine energy_conservation(domain, err) accumulatedEvapTemperatureFlux, & accumulatedSeaIceTemperatureFlux, & accumulatedRiverRunoffTemperatureFlux, & - accumulatedSubglacialRunoffTemperatureFlux, & accumulatedIcebergTemperatureFlux real(kind=RKIND), dimension(:), allocatable :: & @@ -465,8 +463,7 @@ subroutine energy_conservation(domain, err) real(kind=RKIND), dimension(:,:), pointer :: & - activeTracersSurfaceFluxRunoff, & - activeTracersSurfaceFluxSubglacialRunoff + activeTracersSurfaceFluxRunoff type (MPAS_timeInterval_type) :: & timeStepESMF @@ -483,7 +480,7 @@ subroutine energy_conservation(domain, err) ierr integer, parameter :: & - nSums = 20 + nSums = 19 character(len=160) :: & m @@ -516,7 +513,6 @@ subroutine energy_conservation(domain, err) call MPAS_pool_get_array(conservationCheckEnergyAMPool, "accumulatedEvapTemperatureFlux", accumulatedEvapTemperatureFlux) call MPAS_pool_get_array(conservationCheckEnergyAMPool, "accumulatedSeaIceTemperatureFlux", accumulatedSeaIceTemperatureFlux) call MPAS_pool_get_array(conservationCheckEnergyAMPool, "accumulatedRiverRunoffTemperatureFlux", accumulatedRiverRunoffTemperatureFlux) - call MPAS_pool_get_array(conservationCheckEnergyAMPool, "accumulatedSubglacialRunoffTemperatureFlux", accumulatedSubglacialRunoffTemperatureFlux) call MPAS_pool_get_array(conservationCheckEnergyAMPool, "accumulatedIcebergTemperatureFlux", accumulatedIcebergTemperatureFlux) !------------------------------------------------------------- @@ -560,7 +556,6 @@ subroutine energy_conservation(domain, err) call mpas_pool_get_subpool(forcingPool, 'tracersSurfaceFlux',tracersSurfaceFluxPool) call mpas_pool_get_dimension(tracersSurfaceFluxPool, 'index_temperatureSurfaceFlux', index_temperature_flux) call mpas_pool_get_array(tracersSurfaceFluxPool, 'activeTracersSurfaceFluxRunoff', activeTracersSurfaceFluxRunoff) - call mpas_pool_get_array(tracersSurfaceFluxPool, 'activeTracersSurfaceFluxSubglacialRunoff', activeTracersSurfaceFluxSubglacialRunoff) call mpas_pool_get_array(statePool, 'accumulatedFrazilIceMass', accumulatedFrazilIceMassNew, 2) call mpas_pool_get_array(statePool, 'accumulatedFrazilIceMass', accumulatedFrazilIceMassOld, 1) @@ -585,7 +580,6 @@ subroutine energy_conservation(domain, err) ! river runoff temperature flux sumArray(14) = sumArray(14) + areaCell(iCell) * activeTracersSurfaceFluxRunoff(index_temperature_flux,iCell) sumArray(15) = sumArray(15) + areaCell(iCell) * icebergTemperatureFlux(iCell) - sumArray(20) = sumArray(20) + areaCell(iCell) * activeTracersSurfaceFluxSubglacialRunoff(index_temperature_flux,iCell) enddo ! iCell @@ -640,7 +634,6 @@ subroutine energy_conservation(domain, err) accumulatedLandIceHeatFlux = accumulatedLandIceHeatFlux + sumArrayOut(17) accumulatedLandIceFrazilHeatFlux = accumulatedLandIceFrazilHeatFlux + sumArrayOut(18) accumulatedRemovedIceRunoffHeatFlux = accumulatedRemovedIceRunoffHeatFlux + sumArrayOut(19) - accumulatedSubglacialRunoffTemperatureFlux = accumulatedSubglacialRunoffTemperatureFlux + sumArrayOut(20) ! cleanup deallocate(sumArray) @@ -670,7 +663,6 @@ subroutine energy_conservation(domain, err) accumulatedEvapTemperatureFlux = accumulatedEvapTemperatureFlux /accumulatedFluxCounter accumulatedSeaIceTemperatureFlux = accumulatedSeaIceTemperatureFlux /accumulatedFluxCounter accumulatedRiverRunoffTemperatureFlux = accumulatedRiverRunoffTemperatureFlux /accumulatedFluxCounter - accumulatedSubglacialRunoffTemperatureFlux = accumulatedSubglacialRunoffTemperatureFlux /accumulatedFluxCounter accumulatedIcebergTemperatureFlux = accumulatedIcebergTemperatureFlux /accumulatedFluxCounter accumulatedLandIceFrazilHeatFlux = accumulatedLandIceFrazilHeatFlux /accumulatedFluxCounter accumulatedRemovedIceRunoffHeatFlux = accumulatedRemovedIceRunoffHeatFlux /accumulatedFluxCounter @@ -705,7 +697,6 @@ subroutine energy_conservation(domain, err) + accumulatedEvapTemperatureFlux *rho_sw*cp_sw & + accumulatedSeaIceTemperatureFlux *rho_sw*cp_sw & + accumulatedRiverRunoffTemperatureFlux *rho_sw*cp_sw & - + accumulatedSubglacialRunoffTemperatureFlux *rho_sw*cp_sw & + accumulatedIcebergTemperatureFlux*rho_sw*cp_sw ! note, accumulatedLandIceFrazilHeatFlux not added because already in accumulatedFrazilHeatFlux @@ -769,7 +760,6 @@ subroutine energy_conservation(domain, err) v=accumulatedEvapTemperatureFlux *rho_sw*cp_sw; write(m,"('EvapTemperatureFlux ',es16.8,' ',f16.8)") v,v/A; call mpas_log_write(m); s=s+v v=accumulatedSeaIceTemperatureFlux *rho_sw*cp_sw; write(m,"('SeaIceTemperatureFlux ',es16.8,' ',f16.8)") v,v/A; call mpas_log_write(m); s=s+v v=accumulatedRiverRunoffTemperatureFlux*rho_sw*cp_sw; write(m,"('RiverRunoffTempFlux ',es16.8,' ',f16.8)") v,v/A; call mpas_log_write(m); s=s+v -v=accumulatedSubglacialRunoffTemperatureFlux*rho_sw*cp_sw; write(m,"('SubglacialRunoffTempFlux ',es16.8,' ',f16.8)") v,v/A; call mpas_log_write(m); s=s+v v=accumulatedIcebergTemperatureFlux*rho_sw*cp_sw; write(m,"('IcebergTemperatureFlux ',es16.8,' ',f16.8)") v,v/A; call mpas_log_write(m); s=s+v write(m,"('SUM IMPLICIT HEAT FLUXES ',es16.8,' hh20temp ',f16.8,es16.8)") s, s/A; call mpas_log_write(m) s = s + explicitHeatFluxSum @@ -838,7 +828,6 @@ subroutine mass_conservation(domain, err) accumulatedEvaporationFlux, & accumulatedSeaIceFlux, & accumulatedRiverRunoffFlux, & - accumulatedSubglacialRunoffFlux, & accumulatedIceRunoffFlux, & accumulatedRemovedRiverRunoffFlux, & accumulatedRemovedIceRunoffFlux, & @@ -863,7 +852,6 @@ subroutine mass_conservation(domain, err) evaporationFlux, & seaIceFreshwaterFlux, & riverRunoffFlux, & - subglacialRunoffFlux, & iceRunoffFlux, & removedRiverRunoffFlux, & removedIceRunoffFlux, & @@ -889,7 +877,7 @@ subroutine mass_conservation(domain, err) iCell, ierr, k integer, parameter :: & - nSums = 13 + nSums = 12 integer, dimension(:), pointer :: minLevelCell, maxLevelCell @@ -912,7 +900,6 @@ subroutine mass_conservation(domain, err) call MPAS_pool_get_array(conservationCheckMassAMPool, "accumulatedEvaporationFlux", accumulatedEvaporationFlux) call MPAS_pool_get_array(conservationCheckMassAMPool, "accumulatedSeaIceFlux", accumulatedSeaIceFlux) call MPAS_pool_get_array(conservationCheckMassAMPool, "accumulatedRiverRunoffFlux", accumulatedRiverRunoffFlux) - call MPAS_pool_get_array(conservationCheckMassAMPool, "accumulatedSubglacialRunoffFlux", accumulatedSubglacialRunoffFlux) call MPAS_pool_get_array(conservationCheckMassAMPool, "accumulatedIceRunoffFlux", accumulatedIceRunoffFlux) call MPAS_pool_get_array(conservationCheckMassAMPool, "accumulatedRemovedRiverRunoffFlux",accumulatedRemovedRiverRunoffFlux) call MPAS_pool_get_array(conservationCheckMassAMPool, "accumulatedRemovedIceRunoffFlux", accumulatedRemovedIceRunoffFlux) @@ -950,7 +937,6 @@ subroutine mass_conservation(domain, err) call mpas_pool_get_array(forcingPool, 'evaporationFlux', evaporationFlux) call mpas_pool_get_array(forcingPool, 'seaIceFreshWaterFlux', seaIceFreshwaterFlux) call mpas_pool_get_array(forcingPool, 'riverRunoffFlux', riverRunoffFlux) - call mpas_pool_get_array(forcingPool, 'subglacialRunoffFlux', subglacialRunoffFlux) call mpas_pool_get_array(forcingPool, 'iceRunoffFlux', iceRunoffFlux) call mpas_pool_get_array(forcingPool, 'removedRiverRunoffFlux', removedRiverRunoffFlux) call mpas_pool_get_array(forcingPool, 'removedIceRunoffFlux', removedIceRunoffFlux) @@ -970,7 +956,6 @@ subroutine mass_conservation(domain, err) sumArray( 7) = sumArray( 7) + areaCell(iCell) * removedRiverRunoffFlux(iCell) sumArray( 8) = sumArray( 8) + areaCell(iCell) * removedIceRunoffFlux(iCell) sumArray( 9) = sumArray( 9) + areaCell(iCell) * icebergFreshwaterFlux(iCell) - sumArray(13) = sumArray(13) + areaCell(iCell) * subglacialRunoffFlux(iCell) / areaCell(iCell) * rho_sw enddo if (config_use_frazil_ice_formation) then @@ -1017,7 +1002,6 @@ subroutine mass_conservation(domain, err) accumulatedFrazilFlux = accumulatedFrazilFlux + sumArrayOut(10) accumulatedLandIceFlux = accumulatedLandIceFlux + sumArrayOut(11) accumulatedLandIceFrazilFlux = accumulatedLandIceFrazilFlux + sumArrayOut(12) - accumulatedSubglacialRunoffFlux = accumulatedSubglacialRunoffFlux + sumArrayOut(13) ! cleanup deallocate(sumArray) @@ -1037,7 +1021,6 @@ subroutine mass_conservation(domain, err) accumulatedEvaporationFlux = accumulatedEvaporationFlux /accumulatedFluxCounter accumulatedSeaIceFlux = accumulatedSeaIceFlux /accumulatedFluxCounter accumulatedRiverRunoffFlux = accumulatedRiverRunoffFlux /accumulatedFluxCounter - accumulatedSubglacialRunoffFlux = accumulatedSubglacialRunoffFlux /accumulatedFluxCounter accumulatedIceRunoffFlux = accumulatedIceRunoffFlux /accumulatedFluxCounter accumulatedRemovedRiverRunoffFlux = accumulatedRemovedRiverRunoffFlux /accumulatedFluxCounter accumulatedRemovedIceRunoffFlux = accumulatedRemovedIceRunoffFlux /accumulatedFluxCounter @@ -1066,7 +1049,6 @@ subroutine mass_conservation(domain, err) + accumulatedEvaporationFlux & + accumulatedSeaIceFlux & + accumulatedRiverRunoffFlux & - + accumulatedSubglacialRunoffFlux & + accumulatedIceRunoffFlux & + accumulatedIcebergFlux & + accumulatedFrazilFlux & @@ -1101,8 +1083,6 @@ subroutine mass_conservation(domain, err) v=accumulatedIcebergFlux ; write(m,"('icebergFreshwaterFlux ',es16.8,' x2o_Fioi_bergw wberg ',f16.8)") v,v*c; call mpas_log_write(m); s=s+v v=accumulatedEvaporationFlux ; write(m,"('evaporationFlux ',es16.8,' x2o_Foxx_evap wevap ',f16.8)") v,v*c; call mpas_log_write(m); s=s+v v=accumulatedRiverRunoffFlux ; write(m,"('riverRunoffFlux ',es16.8,' x2o_Foxx_rofl wrunoff ',f16.8)") v,v*c; call mpas_log_write(m); s=s+v -v=accumulatedSubglacialRunoffFlux ; write(m,"('subglacialRunoffFlux ',es16.8,' x2o_Foxx_rofl wsgr ',f16.8)") v,v*c; call mpas_log_write(m); s=s+v - if (landIceFreshwaterFluxesOn) then v=accumulatedRemovedRiverRunoffFlux; write(m,"('removedRiverRunoffFlux ',es16.8,' wrunoff ',f16.8)") v,v*c; call mpas_log_write(m); v=accumulatedRiverRunoffFlux+accumulatedRemovedRiverRunoffFlux; @@ -1170,8 +1150,7 @@ subroutine salt_conservation(domain, err) conservationCheckSaltAMPool, & meshPool, & statePool, & - forcingPool, & - tracersSurfaceFluxPool + forcingPool real(kind=RKIND), pointer :: & initialSalt, & @@ -1181,14 +1160,10 @@ subroutine salt_conservation(domain, err) absoluteSaltError, & relativeSaltError - real(kind=RKIND), dimension(:,:), pointer :: & - activeTracersSurfaceFluxSubglacialRunoff - real(kind=RKIND), pointer :: & accumulatedSeaIceSalinityFlux, & + accumulatedFrazilSalinityFlux ! accumulatedLandIceFrazilSalinityFlux is not present because it is always 0 - accumulatedFrazilSalinityFlux, & - accumulatedSubglacialRunoffSalinityFlux real(kind=RKIND), dimension(:), allocatable :: & sumArray, & @@ -1209,15 +1184,14 @@ subroutine salt_conservation(domain, err) dt, dtAvg, v, A, s, c integer, pointer :: & - nCellsSolve, & - index_salinity_flux + nCellsSolve integer :: & iCell, & ierr integer, parameter :: & - nSums = 4 + nSums = 3 logical, pointer :: & activeTracersBulkRestoringPKG @@ -1235,7 +1209,6 @@ subroutine salt_conservation(domain, err) call MPAS_pool_get_array(conservationCheckSaltAMPool, "accumulatedSeaIceSalinityFlux", accumulatedSeaIceSalinityFlux) call MPAS_pool_get_array(conservationCheckSaltAMPool, "accumulatedFrazilSalinityFlux", accumulatedFrazilSalinityFlux) - call MPAS_pool_get_array(conservationCheckSaltAMPool, "accumulatedSubglacialRunoffSalinityFlux", accumulatedSubglacialRunoffSalinityFlux) !------------------------------------------------------------- ! Net salt flux to ice @@ -1261,18 +1234,11 @@ subroutine salt_conservation(domain, err) call mpas_pool_get_array(forcingPool, 'seaIceSalinityFlux', seaIceSalinityFlux) call mpas_pool_get_array(statePool, 'accumulatedFrazilIceSalinity', accumulatedFrazilIceSalinityOld, 1) call mpas_pool_get_array(statePool, 'accumulatedFrazilIceSalinity', accumulatedFrazilIceSalinityNew, 2) - call mpas_pool_get_subpool(forcingPool, 'tracersSurfaceFlux',tracersSurfaceFluxPool) - call mpas_pool_get_array(tracersSurfaceFluxPool, 'activeTracersSurfaceFluxSubglacialRunoff', activeTracersSurfaceFluxSubglacialRunoff) - call mpas_pool_get_dimension(tracersSurfaceFluxPool, 'index_salinitySurfaceFlux', index_salinity_flux) - - do iCell = 1, nCellsSolve ! salt flux to ocean sumArray(1) = sumArray(1) + areaCell(iCell) * seaIceSalinityFlux(iCell) - ! subglacial runoff - sumArray(4) = sumArray(4) + areaCell(iCell) * activeTracersSurfaceFluxSubglacialRunoff(index_salinity_flux,iCell) enddo ! iCell if (config_use_frazil_ice_formation) then @@ -1299,7 +1265,6 @@ subroutine salt_conservation(domain, err) ! accumulate fluxes accumulatedSeaIceSalinityFlux = accumulatedSeaIceSalinityFlux + sumArrayOut(1) accumulatedFrazilSalinityFlux = accumulatedFrazilSalinityFlux + sumArrayOut(2) - accumulatedSubglacialRunoffSalinityFlux = accumulatedSubglacialRunoffSalinityFlux + sumArrayOut(4) ! cleanup deallocate(sumArray) @@ -1316,7 +1281,6 @@ subroutine salt_conservation(domain, err) ! Average the fluxes accumulatedSeaIceSalinityFlux = accumulatedSeaIceSalinityFlux /accumulatedFluxCounter accumulatedFrazilSalinityFlux = accumulatedFrazilSalinityFlux /accumulatedFluxCounter - accumulatedSubglacialRunoffSalinityFlux = accumulatedSubglacialRunoffSalinityFlux /accumulatedFluxCounter ! get initial salt content call MPAS_pool_get_array(conservationCheckSaltAMPool, "initialSalt", initialSalt) @@ -1333,8 +1297,7 @@ subroutine salt_conservation(domain, err) call MPAS_pool_get_array(conservationCheckSaltAMPool, "netSaltFlux", netSaltFlux) netSaltFlux = accumulatedSeaIceSalinityFlux & - + accumulatedFrazilSalinityFlux & - + accumulatedSubglacialRunoffSalinityFlux + + accumulatedFrazilSalinityFlux ! compute the final salt error call MPAS_pool_get_array(conservationCheckSaltAMPool, "absoluteSaltError", absoluteSaltError) @@ -1364,8 +1327,6 @@ subroutine salt_conservation(domain, err) .and.config_frazil_under_land_ice) then v=0; write(m,"('LandIceFrazilSalinityFlux',es16.8,' (already in wmelt, do not sum) ',f16.8)") v,v*c; call mpas_log_write(m); !no sum: s=s+v end if -v=accumulatedSubglacialRunoffSalinityFlux ; write(m,"('SubglacialRunoffSalinityFlux ',es16.8,' x2o_Fioi_salt salt ',f16.8)") v,v*c; call mpas_log_write(m); s=s+v - write(m,"('SUM VOLUME FLUXES ',es16.8,' ',f16.8,es16.8)") s, s*c; call mpas_log_write(m) call mpas_log_write(' ') @@ -1562,11 +1523,11 @@ subroutine carbon_conservation(domain, err) block => domain % blocklist do while (associated(block)) call MPAS_pool_get_dimension(block % dimensions, "nCellsSolve", nCellsSolve) - + call MPAS_pool_get_subpool(block % structs, "mesh", meshPool) call MPAS_pool_get_subpool(block % structs, "forcing", forcingPool) call MPAS_pool_get_subpool(block % structs, "state", statePool) - + call MPAS_pool_get_array(meshPool, "areaCell", areaCell) call mpas_pool_get_array(meshPool, 'maxLevelCell', maxLevelCell) @@ -1633,7 +1594,7 @@ subroutine carbon_conservation(domain, err) + ecosysTracersSurfaceFlux(index_spCFlux, iCell) & + ecosysTracersSurfaceFlux(index_diatCFlux, iCell) & + ecosysTracersSurfaceFlux(index_diazCFlux, iCell)) - + do k = 1, maxLevelCell(iCell) sumArray(4) = sumArray(4) + areaCell(iCell) * ( & ecosysTracersTend(index_DICTend, k, iCell) & @@ -1684,7 +1645,7 @@ subroutine carbon_conservation(domain, err) !------------------------------------------------------------- if (MPAS_stream_mgr_ringing_alarms(domain % streamManager, "conservationCheckOutput", ierr=ierr)) then - + ! Average the fluxes accumulatedCarbonSourceSink = accumulatedCarbonSourceSink /accumulatedFluxCounter accumulatedCarbonSedimentFlux = accumulatedCarbonSedimentFlux /accumulatedFluxCounter @@ -1696,7 +1657,7 @@ subroutine carbon_conservation(domain, err) ! get initial carbon call MPAS_pool_get_array(conservationCheckCarbonAMPool, "initialCarbon", initialCarbon) - + ! get final carbon call MPAS_pool_get_array(conservationCheckCarbonAMPool, "finalCarbon", finalCarbon) call compute_total_carbon(domain, finalCarbon) @@ -1733,13 +1694,13 @@ subroutine carbon_conservation(domain, err) relativeCarbonErrorBounds = & relativeCarbonErrorStepBounds*relativeCarbonErrorBoundsFac*totalTimeSteps relativeCarbonErrorPerTimeStep = relativeCarbonError/accumulatedFluxCounter - + !------------------------------------------------------------- ! Output to log file !------------------------------------------------------------- if (config_AM_conservationCheck_write_to_logfile) then - + call mpas_log_write('') call mpas_log_write('----------------------------------------------------------') call mpas_log_write('CARBON CONSERVATION CHECK') @@ -1770,7 +1731,7 @@ subroutine carbon_conservation(domain, err) v=accumulatedIceOceanInorganicCarbonFlux*mmol_to_kg_C write(m,"('Ice-Ocean Inorganic Flux ',es16.8,' ',f16.8)") v,v*c call mpas_log_write(m) - write(m,"('SUM FLUXES (surf + sed) ',es16.8,' ',f16.8,es16.8)") s, s*c; + write(m,"('SUM FLUXES (surf + sed) ',es16.8,' ',f16.8,es16.8)") s, s*c; call mpas_log_write(m) call mpas_log_write(' ') @@ -1790,24 +1751,24 @@ subroutine carbon_conservation(domain, err) write(m,"('Carbon change ', 3es16.8)") & carbonChange*mmol_to_kg_C, & carbonChange*mmol_to_kg_C/dtAvg, & - carbonChange*mmol_to_kg_C/dtAvg*c + carbonChange*mmol_to_kg_C/dtAvg*c call mpas_log_write(m) write(m,"('Net carbon flux ', 3es16.8)") & netCarbonFlux*mmol_to_kg_C*dtAvg, & netCarbonFlux*mmol_to_kg_C, & - netCarbonFlux*mmol_to_kg_C*c + netCarbonFlux*mmol_to_kg_C*c call mpas_log_write(m) write(m,"('Absolute carbon error ', 3es16.8)") & absoluteCarbonError*mmol_to_kg_C, & absoluteCarbonError*mmol_to_kg_C/dtAvg, & - absoluteCarbonError*mmol_to_kg_C/dtAvg*c + absoluteCarbonError*mmol_to_kg_C/dtAvg*c call mpas_log_write(m) call mpas_log_write(' ') write(m,"('RELATIVE CARBON ERROR =', es16.8)") & relativeCarbonError call mpas_log_write(m) call mpas_log_write(' ') - + write(m,"('Relative carbon error per timestep = ', es16.8)") & relativeCarbonErrorPerTimeStep call mpas_log_write(m) @@ -1853,7 +1814,7 @@ subroutine carbon_conservation(domain, err) endif end subroutine carbon_conservation - + !*********************************************************************** ! ! routine compute_total_energy @@ -2229,7 +2190,7 @@ subroutine compute_total_carbon(domain, totalCarbon) call MPAS_dmpar_sum_real(domain % dminfo, carbon, totalCarbon) end subroutine compute_total_carbon - + !*********************************************************************** ! ! routine reset_accumulated_variables @@ -2271,7 +2232,6 @@ subroutine reset_accumulated_variables(domain) accumulatedEvapTemperatureFlux, & accumulatedSeaIceTemperatureFlux, & accumulatedRiverRunoffTemperatureFlux, & - accumulatedSubglacialRunoffTemperatureFlux, & accumulatedIcebergTemperatureFlux real(kind=RKIND), pointer :: & @@ -2280,7 +2240,6 @@ subroutine reset_accumulated_variables(domain) accumulatedEvaporationFlux, & accumulatedSeaIceFlux, & accumulatedRiverRunoffFlux, & - accumulatedSubglacialRunoffFlux, & accumulatedIceRunoffFlux, & accumulatedRemovedRiverRunoffFlux, & accumulatedRemovedIceRunoffFlux, & @@ -2291,8 +2250,7 @@ subroutine reset_accumulated_variables(domain) real(kind=RKIND), pointer :: & accumulatedSeaIceSalinityFlux, & - accumulatedFrazilSalinityFlux, & - accumulatedSubglacialRunoffSalinityFlux + accumulatedFrazilSalinityFlux real(kind=RKIND), pointer :: & accumulatedCarbonSourceSink, & @@ -2322,7 +2280,6 @@ subroutine reset_accumulated_variables(domain) call MPAS_pool_get_array(conservationCheckEnergyAMPool, "accumulatedEvapTemperatureFlux", accumulatedEvapTemperatureFlux) call MPAS_pool_get_array(conservationCheckEnergyAMPool, "accumulatedSeaIceTemperatureFlux", accumulatedSeaIceTemperatureFlux) call MPAS_pool_get_array(conservationCheckEnergyAMPool, "accumulatedRiverRunoffTemperatureFlux", accumulatedRiverRunoffTemperatureFlux) - call MPAS_pool_get_array(conservationCheckEnergyAMPool, "accumulatedSubglacialRunoffTemperatureFlux", accumulatedSubglacialRunoffTemperatureFlux) call MPAS_pool_get_array(conservationCheckEnergyAMPool, "accumulatedIcebergTemperatureFlux", accumulatedIcebergTemperatureFlux) accumulatedFluxCounter = 0 @@ -2341,7 +2298,6 @@ subroutine reset_accumulated_variables(domain) accumulatedEvapTemperatureFlux = 0.0_RKIND accumulatedSeaIceTemperatureFlux = 0.0_RKIND accumulatedRiverRunoffTemperatureFlux = 0.0_RKIND - accumulatedSubglacialRunoffTemperatureFlux = 0.0_RKIND accumulatedIcebergTemperatureFlux = 0.0_RKIND accumulatedLandIceFrazilHeatFlux = 0.0_RKIND accumulatedRemovedIceRunoffHeatFlux = 0.0_RKIND @@ -2354,7 +2310,6 @@ subroutine reset_accumulated_variables(domain) call MPAS_pool_get_array(conservationCheckMassAMPool, "accumulatedEvaporationFlux", accumulatedEvaporationFlux) call MPAS_pool_get_array(conservationCheckMassAMPool, "accumulatedSeaIceFlux", accumulatedSeaIceFlux) call MPAS_pool_get_array(conservationCheckMassAMPool, "accumulatedRiverRunoffFlux", accumulatedRiverRunoffFlux) - call MPAS_pool_get_array(conservationCheckMassAMPool, "accumulatedSubglacialRunoffFlux", accumulatedSubglacialRunoffFlux) call MPAS_pool_get_array(conservationCheckMassAMPool, "accumulatedIceRunoffFlux", accumulatedIceRunoffFlux) call MPAS_pool_get_array(conservationCheckMassAMPool, "accumulatedRemovedRiverRunoffFlux",accumulatedRemovedRiverRunoffFlux) call MPAS_pool_get_array(conservationCheckMassAMPool, "accumulatedRemovedIceRunoffFlux", accumulatedRemovedIceRunoffFlux) @@ -2368,7 +2323,6 @@ subroutine reset_accumulated_variables(domain) accumulatedEvaporationFlux = 0.0_RKIND accumulatedSeaIceFlux = 0.0_RKIND accumulatedRiverRunoffFlux = 0.0_RKIND - accumulatedSubglacialRunoffFlux = 0.0_RKIND accumulatedIceRunoffFlux = 0.0_RKIND accumulatedRemovedRiverRunoffFlux = 0.0_RKIND accumulatedRemovedIceRunoffFlux = 0.0_RKIND @@ -2382,13 +2336,9 @@ subroutine reset_accumulated_variables(domain) call MPAS_pool_get_array(conservationCheckSaltAMPool, "accumulatedSeaIceSalinityFlux", accumulatedSeaIceSalinityFlux) call MPAS_pool_get_array(conservationCheckSaltAMPool, "accumulatedFrazilSalinityFlux", accumulatedFrazilSalinityFlux) - call MPAS_pool_get_array(conservationCheckSaltAMPool, "accumulatedLandIceFrazilSalinityFlux", accumulatedLandIceFrazilSalinityFlux) - call MPAS_pool_get_array(conservationCheckSaltAMPool, "accumulatedSubglacialRunoffSalinityFlux", accumulatedSubglacialRunoffSalinityFlux) - accumulatedSeaIceSalinityFlux = 0.0_RKIND accumulatedFrazilSalinityFlux = 0.0_RKIND - accumulatedSubglacialRunoffSalinityFlux = 0.0_RKIND call MPAS_pool_get_subpool(domain % blocklist % structs, "conservationCheckCarbonAM", conservationCheckCarbonAMPool) From ea8bb59c4710c99561d0993a57cdfc505ac39216 Mon Sep 17 00:00:00 2001 From: Irena Vankova Date: Tue, 9 Jul 2024 13:32:31 -0600 Subject: [PATCH 213/451] rmv conservation check on sgr buildnml --- components/mpas-ocean/cime_config/buildnml | 1 - 1 file changed, 1 deletion(-) diff --git a/components/mpas-ocean/cime_config/buildnml b/components/mpas-ocean/cime_config/buildnml index 4d5029555afc..91c481ad8f5c 100755 --- a/components/mpas-ocean/cime_config/buildnml +++ b/components/mpas-ocean/cime_config/buildnml @@ -1195,7 +1195,6 @@ def buildnml(case, caseroot, compname): lines.append('') lines.append('') lines.append('') - lines.append('') lines.append('') lines.append('') lines.append('') From e969c31a02875303c5e0f0435195fb7a0ff1edcb Mon Sep 17 00:00:00 2001 From: Irena Vankova Date: Tue, 9 Jul 2024 13:56:39 -0600 Subject: [PATCH 214/451] rmv conservation check on sgr buildnml #2 --- components/mpas-ocean/cime_config/buildnml | 2 -- 1 file changed, 2 deletions(-) diff --git a/components/mpas-ocean/cime_config/buildnml b/components/mpas-ocean/cime_config/buildnml index 91c481ad8f5c..d6d40491baa6 100755 --- a/components/mpas-ocean/cime_config/buildnml +++ b/components/mpas-ocean/cime_config/buildnml @@ -1201,7 +1201,6 @@ def buildnml(case, caseroot, compname): lines.append('') lines.append('') lines.append('') - lines.append('') lines.append('') lines.append('') lines.append('') @@ -1210,7 +1209,6 @@ def buildnml(case, caseroot, compname): lines.append('') lines.append('') lines.append('') - lines.append('') lines.append('') lines.append('') lines.append('') From 800961c2e6f6efa310da7a00018b91fa51f3ba93 Mon Sep 17 00:00:00 2001 From: Irena Vankova Date: Mon, 8 Jul 2024 12:14:43 -0600 Subject: [PATCH 215/451] pkg change in bld --- components/mpas-ocean/bld/build-namelist | 5 +++++ components/mpas-ocean/bld/build-namelist-section | 1 + .../bld/namelist_files/namelist_defaults_mpaso.xml | 2 +- .../bld/namelist_files/namelist_definition_mpaso.xml | 8 ++++++++ 4 files changed, 15 insertions(+), 1 deletion(-) diff --git a/components/mpas-ocean/bld/build-namelist b/components/mpas-ocean/bld/build-namelist index e33f4dc1c796..2c5ee97b0df2 100755 --- a/components/mpas-ocean/bld/build-namelist +++ b/components/mpas-ocean/bld/build-namelist @@ -715,6 +715,11 @@ add_default($nl, 'config_use_sgr_opt_temp'); add_default($nl, 'config_use_sgr_opt_salt'); add_default($nl, 'config_sgr_temperature'); add_default($nl, 'config_sgr_salinity'); +if ($OCN_SGR eq 'data') { + add_default($nl, 'config_subglacial_runoff_mode', 'val'=>"data"); +} else { + add_default($nl, 'config_subglacial_runoff_mode'); +} ############################ # Namelist group: coupling # diff --git a/components/mpas-ocean/bld/build-namelist-section b/components/mpas-ocean/bld/build-namelist-section index 0d44d3f328b6..3f2d4ab4839d 100644 --- a/components/mpas-ocean/bld/build-namelist-section +++ b/components/mpas-ocean/bld/build-namelist-section @@ -231,6 +231,7 @@ add_default($nl, 'config_use_sgr_opt_temp'); add_default($nl, 'config_use_sgr_opt_salt'); add_default($nl, 'config_sgr_temperature'); add_default($nl, 'config_sgr_salinity'); +add_default($nl, 'config_subglacial_runoff_mode'); ############################ # Namelist group: coupling # diff --git a/components/mpas-ocean/bld/namelist_files/namelist_defaults_mpaso.xml b/components/mpas-ocean/bld/namelist_files/namelist_defaults_mpaso.xml index 40a3b3ca86f5..0514704b9514 100644 --- a/components/mpas-ocean/bld/namelist_files/namelist_defaults_mpaso.xml +++ b/components/mpas-ocean/bld/namelist_files/namelist_defaults_mpaso.xml @@ -349,7 +349,7 @@ 'sgr' 0.0 0.0 - +'off' .false. diff --git a/components/mpas-ocean/bld/namelist_files/namelist_definition_mpaso.xml b/components/mpas-ocean/bld/namelist_files/namelist_definition_mpaso.xml index 97bd989f06c5..616ec67d24cd 100644 --- a/components/mpas-ocean/bld/namelist_files/namelist_definition_mpaso.xml +++ b/components/mpas-ocean/bld/namelist_files/namelist_definition_mpaso.xml @@ -1244,6 +1244,14 @@ Valid values: Any real number. Default: Defined in namelist_defaults.xml + +Selects the mode in which subglacial runoff fluxes are computed. + +Valid values: 'off', 'data' +Default: Defined in namelist_defaults.xml + + Date: Mon, 8 Jul 2024 12:32:42 -0600 Subject: [PATCH 216/451] pkg in driver and registry --- components/mpas-ocean/src/Registry.xml | 5 +++++ .../mpas-ocean/src/driver/mpas_ocn_core_interface.F | 11 +++++++++++ 2 files changed, 16 insertions(+) diff --git a/components/mpas-ocean/src/Registry.xml b/components/mpas-ocean/src/Registry.xml index 1ceddac39fcb..bab430733500 100644 --- a/components/mpas-ocean/src/Registry.xml +++ b/components/mpas-ocean/src/Registry.xml @@ -702,6 +702,10 @@ description="The length scale of exponential decay of river runoff. Fluxes are multiplied by $e^{z/\gamma}$, where this coefficient is $\gamma$." possible_values="Any positive real number." /> + + diff --git a/components/mpas-ocean/src/driver/mpas_ocn_core_interface.F b/components/mpas-ocean/src/driver/mpas_ocn_core_interface.F index 7d9eb083f907..6d542fb0c3f3 100644 --- a/components/mpas-ocean/src/driver/mpas_ocn_core_interface.F +++ b/components/mpas-ocean/src/driver/mpas_ocn_core_interface.F @@ -123,6 +123,7 @@ function ocn_setup_packages(configPool, packagePool, iocontext) result(ierr)!{{{ logical, pointer :: dataLandIceFluxesPKGActive logical, pointer :: landIceFluxesPKGActive logical, pointer :: landIceCouplingPKGActive + logical, pointer :: dataSubglacialRunoffFluxPKGActive logical, pointer :: thicknessBulkPKGActive logical, pointer :: frazilIceActive logical, pointer :: tidalForcingActive @@ -186,6 +187,7 @@ function ocn_setup_packages(configPool, packagePool, iocontext) result(ierr)!{{{ logical, pointer :: config_use_bulk_thickness_flux logical, pointer :: config_compute_active_tracer_budgets character (len=StrKIND), pointer :: config_land_ice_flux_mode + character (len=StrKIND), pointer :: config_subglacial_runoff_mode type (mpas_pool_iterator_type) :: groupItr character (len=StrKIND) :: tracerGroupName, configName, packageName @@ -319,6 +321,15 @@ function ocn_setup_packages(configPool, packagePool, iocontext) result(ierr)!{{{ landIceCouplingPKGActive = .true. end if + ! + ! test for use of subglacial runoff flux, dataSubglacialRunoffFluxPKGActive + ! + call mpas_pool_get_package(packagePool, 'dataSubglacialRunoffFluxPKGActive', dataSubglacialRunoffFluxPKGActive) + call mpas_pool_get_config(configPool, 'config_subglacial_runoff_mode', config_subglacial_runoff_mode) + if ( trim(config_subglacial_runoff_mode) == 'data' ) then + dataSubglacialRunoffFluxPKGActive = .true. + end if + ! ! test for use of frazil ice formation, frazilIceActive ! From b07587b10a5d5f9c767dcbd07ee58a384c5aa09c Mon Sep 17 00:00:00 2001 From: Irena Vankova Date: Mon, 8 Jul 2024 13:05:43 -0600 Subject: [PATCH 217/451] fix group for sgr in namelist_definition_mpaso --- .../mpas-ocean/bld/namelist_files/namelist_definition_mpaso.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/components/mpas-ocean/bld/namelist_files/namelist_definition_mpaso.xml b/components/mpas-ocean/bld/namelist_files/namelist_definition_mpaso.xml index 616ec67d24cd..43ba139ab65f 100644 --- a/components/mpas-ocean/bld/namelist_files/namelist_definition_mpaso.xml +++ b/components/mpas-ocean/bld/namelist_files/namelist_definition_mpaso.xml @@ -1245,7 +1245,7 @@ Default: Defined in namelist_defaults.xml + category="forcing" group="forcing"> Selects the mode in which subglacial runoff fluxes are computed. Valid values: 'off', 'data' From f1b13ba8657dd579a5aae5e2fa18c8fd8a3ccb5a Mon Sep 17 00:00:00 2001 From: Irena Vankova Date: Mon, 8 Jul 2024 14:10:11 -0600 Subject: [PATCH 218/451] sgr pkg in shared folder, add loops --- .../src/shared/mpas_ocn_diagnostics.F | 100 ++++++++++-------- .../mpas-ocean/src/shared/mpas_ocn_forcing.F | 77 +++++++------- .../shared/mpas_ocn_surface_bulk_forcing.F | 55 ++++++---- .../mpas-ocean/src/shared/mpas_ocn_tendency.F | 12 ++- .../src/shared/mpas_ocn_thick_surface_flux.F | 21 ++-- .../mpas_ocn_tracer_surface_flux_to_tend.F | 2 +- 6 files changed, 153 insertions(+), 114 deletions(-) diff --git a/components/mpas-ocean/src/shared/mpas_ocn_diagnostics.F b/components/mpas-ocean/src/shared/mpas_ocn_diagnostics.F index f04893b671c0..daf9bfcab6d5 100644 --- a/components/mpas-ocean/src/shared/mpas_ocn_diagnostics.F +++ b/components/mpas-ocean/src/shared/mpas_ocn_diagnostics.F @@ -1904,9 +1904,13 @@ subroutine ocn_diagnostic_solve_surfaceLayer(layerThickness, & config_flux_attenuation_coefficient surfaceFluxAttenuationCoefficientRunoff(iCell) = & config_flux_attenuation_coefficient_runoff - surfaceFluxAttenuationCoefficientSubglacialRunoff(iCell) = & - config_flux_attenuation_coefficient_subglacial_runoff end do + if (trim(config_subglacial_runoff_mode) == 'data') then + do iCell = 1, nCells + surfaceFluxAttenuationCoefficientSubglacialRunoff(iCell) = & + config_flux_attenuation_coefficient_subglacial_runoff + end do + end if #ifndef MPAS_OPENACC !$omp end do !$omp end parallel @@ -3489,34 +3493,36 @@ subroutine ocn_compute_KPP_input_fields(statePool, forcingPool, & - exp( max(-100.0_RKIND, & -layerThickness(kmin, iCell)/ & config_flux_attenuation_coefficient_runoff)) - if (config_use_sgr_opt_kpp == 1) then - if ( trim(config_sgr_flux_vertical_location) == 'top' ) then - fracAbsorbedSubglacialRunoff = 1.0_RKIND & - - exp( max(-100.0_RKIND, & - -layerThickness(kmin, iCell)/ & - config_flux_attenuation_coefficient_subglacial_runoff)) - else if ( trim(config_sgr_flux_vertical_location) == 'uniform' ) then - ! calculate total thickness into variable zTop - zTop = 0.0_RKIND - do k = minLevelCell(iCell), maxLevelCell(iCell) - zTop = zTop + layerThickness(k,iCell) - end do - ! distribute flux evenly throughout water column - fracAbsorbedSubglacialRunoff = layerThickness(kmin, iCell) / zTop - else if ( trim(config_sgr_flux_vertical_location) == 'bottom' ) then - zTop = 0.0_RKIND - do k = maxLevelCell(iCell), minLevelCell(iCell), -1 - zBot = zTop - layerThickness(k,iCell) - if (k == minLevelCell(iCell)) then - transmissionCoeffTop = exp( max(zTop / config_flux_attenuation_coefficient_runoff, -100.0_RKIND) ) - transmissionCoeffBot = exp( max(zBot / config_flux_attenuation_coefficient_runoff, -100.0_RKIND) ) - fracAbsorbedSubglacialRunoff = transmissionCoeffTop - transmissionCoeffBot - end if - zTop = zBot - end do - end if - else - fracAbsorbedSubglacialRunoff = 0.0_RKIND + if (trim(config_subglacial_runoff_mode) == 'data') then + if (config_use_sgr_opt_kpp == 1) then + if ( trim(config_sgr_flux_vertical_location) == 'top' ) then + fracAbsorbedSubglacialRunoff = 1.0_RKIND & + - exp( max(-100.0_RKIND, & + -layerThickness(kmin, iCell)/ & + config_flux_attenuation_coefficient_subglacial_runoff)) + else if ( trim(config_sgr_flux_vertical_location) == 'uniform' ) then + ! calculate total thickness into variable zTop + zTop = 0.0_RKIND + do k = minLevelCell(iCell), maxLevelCell(iCell) + zTop = zTop + layerThickness(k,iCell) + end do + ! distribute flux evenly throughout water column + fracAbsorbedSubglacialRunoff = layerThickness(kmin, iCell) / zTop + else if ( trim(config_sgr_flux_vertical_location) == 'bottom' ) then + zTop = 0.0_RKIND + do k = maxLevelCell(iCell), minLevelCell(iCell), -1 + zBot = zTop - layerThickness(k,iCell) + if (k == minLevelCell(iCell)) then + transmissionCoeffTop = exp( max(zTop / config_flux_attenuation_coefficient_runoff, -100.0_RKIND) ) + transmissionCoeffBot = exp( max(zBot / config_flux_attenuation_coefficient_runoff, -100.0_RKIND) ) + fracAbsorbedSubglacialRunoff = transmissionCoeffTop - transmissionCoeffBot + end if + zTop = zBot + end do + end if + else + fracAbsorbedSubglacialRunoff = 0.0_RKIND + end if end if ! Store the total tracer flux below in @@ -3532,18 +3538,24 @@ subroutine ocn_compute_KPP_input_fields(statePool, forcingPool, & seaIceTemperatureFlux(iCell) + & icebergTemperatureFlux(iCell)) & - fracAbsorbedRunoff* & - activeTracersSurfaceFluxRunoff(indexTempFlux,iCell) & + activeTracersSurfaceFluxRunoff(indexTempFlux,iCell) + if (trim(config_subglacial_runoff_mode) == 'data') then + nonLocalSurfaceTracerFlux(indexTempFlux, iCell) = nonLocalSurfaceTracerFlux(indexTempFlux, iCell) & - fracAbsorbedSubglacialRunoff* & activeTracersSurfaceFluxSubglacialRunoff(indexTempFlux,iCell) + end if nonLocalSurfaceTracerFlux(indexSaltFlux,iCell) = & activeTracersSurfaceFlux(indexSaltFlux,iCell) & - fracAbsorbed*surfaceThicknessFlux(iCell)* & activeTracers(indexSaltFlux,kmin,iCell) & - fracAbsorbedRunoff*surfaceThicknessFluxRunoff(iCell)* & - activeTracers(indexSaltFlux,kmin,iCell) & + activeTracers(indexSaltFlux,kmin,iCell) + if (trim(config_subglacial_runoff_mode) == 'data') then + nonLocalSurfaceTracerFlux(indexSaltFlux,iCell) = nonLocalSurfaceTracerFlux(indexSaltFlux,iCell) & - fracAbsorbedSubglacialRunoff*surfaceThicknessFluxSubglacialRunoff(iCell)* & activeTracers(indexSaltFlux,kmin,iCell) + end if surfaceBuoyancyForcing(iCell) = & thermalExpansionCoeff(kmin,iCell)* & @@ -4485,17 +4497,19 @@ subroutine ocn_validate_state(domain, timeLevel)!{{{ call ocn_write_field_statistics(debugUnit, fieldName, minValue, maxValue) end if - ! Test subglacialRunoffFlux - fieldName = 'subglacialRunoffFlux' - minValue = HUGE(minValue) - maxValue = -HUGE(maxValue) - call mpas_pool_get_array(forcingPool, fieldName, real1DArr) - if ( associated(real1DArr) ) then - do iCell = 1, nCellsSolve - minValue = min( minValue, real1DArr(iCell) ) - maxValue = max( maxValue, real1DArr(iCell) ) - end do - call ocn_write_field_statistics(debugUnit, fieldName, minValue, maxValue) + if (trim(config_subglacial_runoff_mode) == 'data') then + ! Test subglacialRunoffFlux + fieldName = 'subglacialRunoffFlux' + minValue = HUGE(minValue) + maxValue = -HUGE(maxValue) + call mpas_pool_get_array(forcingPool, fieldName, real1DArr) + if ( associated(real1DArr) ) then + do iCell = 1, nCellsSolve + minValue = min( minValue, real1DArr(iCell) ) + maxValue = max( maxValue, real1DArr(iCell) ) + end do + call ocn_write_field_statistics(debugUnit, fieldName, minValue, maxValue) + end if end if ! Test seaIceSalinityFlux diff --git a/components/mpas-ocean/src/shared/mpas_ocn_forcing.F b/components/mpas-ocean/src/shared/mpas_ocn_forcing.F index 75fc20c8d7ed..5cfce4c4e690 100644 --- a/components/mpas-ocean/src/shared/mpas_ocn_forcing.F +++ b/components/mpas-ocean/src/shared/mpas_ocn_forcing.F @@ -183,44 +183,45 @@ subroutine ocn_forcing_build_fraction_absorbed_array(meshPool, statePool, forcin end do ! now do subglacial runoff separately - - if ( trim(config_sgr_flux_vertical_location) == 'top' ) then - do iCell = 1, nCells - zTop = 0.0_RKIND - transmissionCoeffTop = ocn_forcing_transmission(zTop, surfaceFluxAttenuationCoefficientSubglacialRunoff(iCell)) - do k = minLevelCell(iCell), maxLevelCell(iCell) - zBot = zTop - layerThickness(k,iCell) - transmissionCoeffBot = ocn_forcing_transmission(zBot, surfaceFluxAttenuationCoefficientSubglacialRunoff(iCell)) - fractionAbsorbedSubglacialRunoff(k, iCell) = transmissionCoeffTop - transmissionCoeffBot - zTop = zBot - transmissionCoeffTop = transmissionCoeffBot - end do - end do - else if ( trim(config_sgr_flux_vertical_location) == 'uniform' ) then - do iCell = 1, nCells - ! calculate total thickness - zTop = 0.0_RKIND - do k = minLevelCell(iCell), maxLevelCell(iCell) - zTop = zTop + layerThickness(k,iCell) - end do - ! distribute flux evenly throughout water column - zBot = 0.0_RKIND - do k = minLevelCell(iCell), maxLevelCell(iCell) - fractionAbsorbedSubglacialRunoff(k, iCell) = layerThickness(k,iCell) / zTop - end do - end do - else if ( trim(config_sgr_flux_vertical_location) == 'bottom' ) then - do iCell = 1, nCells - zTop = 0.0_RKIND - transmissionCoeffTop = ocn_forcing_transmission(zTop, surfaceFluxAttenuationCoefficientSubglacialRunoff(iCell)) - do k = maxLevelCell(iCell), minLevelCell(iCell), -1 - zBot = zTop - layerThickness(k,iCell) - transmissionCoeffBot = ocn_forcing_transmission(zBot, surfaceFluxAttenuationCoefficientSubglacialRunoff(iCell)) - fractionAbsorbedSubglacialRunoff(k, iCell) = transmissionCoeffTop - transmissionCoeffBot - zTop = zBot - transmissionCoeffTop = transmissionCoeffBot - end do - end do + if ( trim(config_subglacial_runoff_mode) == 'data' ) then + if ( trim(config_sgr_flux_vertical_location) == 'top' ) then + do iCell = 1, nCells + zTop = 0.0_RKIND + transmissionCoeffTop = ocn_forcing_transmission(zTop, surfaceFluxAttenuationCoefficientSubglacialRunoff(iCell)) + do k = minLevelCell(iCell), maxLevelCell(iCell) + zBot = zTop - layerThickness(k,iCell) + transmissionCoeffBot = ocn_forcing_transmission(zBot, surfaceFluxAttenuationCoefficientSubglacialRunoff(iCell)) + fractionAbsorbedSubglacialRunoff(k, iCell) = transmissionCoeffTop - transmissionCoeffBot + zTop = zBot + transmissionCoeffTop = transmissionCoeffBot + end do + end do + else if ( trim(config_sgr_flux_vertical_location) == 'uniform' ) then + do iCell = 1, nCells + ! calculate total thickness + zTop = 0.0_RKIND + do k = minLevelCell(iCell), maxLevelCell(iCell) + zTop = zTop + layerThickness(k,iCell) + end do + ! distribute flux evenly throughout water column + zBot = 0.0_RKIND + do k = minLevelCell(iCell), maxLevelCell(iCell) + fractionAbsorbedSubglacialRunoff(k, iCell) = layerThickness(k,iCell) / zTop + end do + end do + else if ( trim(config_sgr_flux_vertical_location) == 'bottom' ) then + do iCell = 1, nCells + zTop = 0.0_RKIND + transmissionCoeffTop = ocn_forcing_transmission(zTop, surfaceFluxAttenuationCoefficientSubglacialRunoff(iCell)) + do k = maxLevelCell(iCell), minLevelCell(iCell), -1 + zBot = zTop - layerThickness(k,iCell) + transmissionCoeffBot = ocn_forcing_transmission(zBot, surfaceFluxAttenuationCoefficientSubglacialRunoff(iCell)) + fractionAbsorbedSubglacialRunoff(k, iCell) = transmissionCoeffTop - transmissionCoeffBot + zTop = zBot + transmissionCoeffTop = transmissionCoeffBot + end do + end do + end if end if end subroutine ocn_forcing_build_fraction_absorbed_array!}}} diff --git a/components/mpas-ocean/src/shared/mpas_ocn_surface_bulk_forcing.F b/components/mpas-ocean/src/shared/mpas_ocn_surface_bulk_forcing.F index fe4f2cac5abf..0547f73319dd 100644 --- a/components/mpas-ocean/src/shared/mpas_ocn_surface_bulk_forcing.F +++ b/components/mpas-ocean/src/shared/mpas_ocn_surface_bulk_forcing.F @@ -351,8 +351,12 @@ subroutine ocn_surface_bulk_forcing_thick(forcingPool, surfaceThicknessFlux, sur surfaceThicknessFlux(iCell) = surfaceThicknessFlux(iCell) + ( snowFlux(iCell) + rainFlux(iCell) + evaporationFlux(iCell) & + seaIceFreshWaterFlux(iCell) + icebergFreshWaterFlux(iCell) + iceRunoffFlux(iCell) ) / rho_sw surfaceThicknessFluxRunoff(iCell) = riverRunoffFlux(iCell) / rho_sw - surfaceThicknessFluxSubglacialRunoff(iCell) = subglacialRunoffFlux(iCell) / areaCell(iCell) end do + if (trim(config_subglacial_runoff_mode) == 'data') then + do iCell = 1, nCells + surfaceThicknessFluxSubglacialRunoff(iCell) = subglacialRunoffFlux(iCell) / areaCell(iCell) + end do + end if #ifndef MPAS_OPENACC !$omp end do !$omp end parallel @@ -578,28 +582,30 @@ subroutine ocn_surface_bulk_forcing_active_tracers(meshPool, forcingPool, tracer tracersSurfaceFluxRunoff(index_temperature_flux,iCell) = riverRunoffFlux(iCell) & * max(tracerGroup(index_temperature_flux,minLevelCell(iCell),iCell), 0.0_RKIND) / rho_sw - if ( trim(config_use_sgr_opt_temp) == 'prescribed' ) then - !sgr with fixed prescribed temperature (for debugging only) - tracersSurfaceFluxSubglacialRunoff(index_temperature_flux,iCell) = subglacialRunoffFlux(iCell) * & - config_sgr_temperature / areaCell(iCell) - else if ( trim(config_use_sgr_opt_temp) == 'sgr' ) then - !sgr with temperature equal to the local freezing point of freshwater - tracersSurfaceFluxSubglacialRunoff(index_temperature_flux,iCell) = subglacialRunoffFlux(iCell) * & - ocn_freezing_temperature(salinity=0.0_RKIND, pressure=landIcePressure(iCell), & - inLandIceCavity=.true.) / areaCell(iCell) - end if - - if ( trim(config_use_sgr_opt_salt) == 'prescribed' ) then - !sgr with fixed prescribed temperature (for debugging only) - tracersSurfaceFluxSubglacialRunoff(index_salinity_flux,iCell) = subglacialRunoffFlux(iCell) * & - config_sgr_salinity / areaCell(iCell) - else if ( trim(config_use_sgr_opt_salt) == 'sgr' ) then - !sgr with temperature equal to the local freezing point of freshwater - tracersSurfaceFluxSubglacialRunoff(index_salinity_flux,iCell) = 0.0_RKIND + if (trim(config_subglacial_runoff_mode) == 'data') then + if ( trim(config_use_sgr_opt_temp) == 'prescribed' ) then + !sgr with fixed prescribed temperature (for debugging only) + tracersSurfaceFluxSubglacialRunoff(index_temperature_flux,iCell) = subglacialRunoffFlux(iCell) * & + config_sgr_temperature / areaCell(iCell) + else if ( trim(config_use_sgr_opt_temp) == 'sgr' ) then + !sgr with temperature equal to the local freezing point of freshwater + tracersSurfaceFluxSubglacialRunoff(index_temperature_flux,iCell) = subglacialRunoffFlux(iCell) * & + ocn_freezing_temperature(salinity=0.0_RKIND, pressure=landIcePressure(iCell), & + inLandIceCavity=.true.) / areaCell(iCell) + end if + + if ( trim(config_use_sgr_opt_salt) == 'prescribed' ) then + !sgr with fixed prescribed temperature (for debugging only) + tracersSurfaceFluxSubglacialRunoff(index_salinity_flux,iCell) = subglacialRunoffFlux(iCell) * & + config_sgr_salinity / areaCell(iCell) + else if ( trim(config_use_sgr_opt_salt) == 'sgr' ) then + !sgr with temperature equal to the local freezing point of freshwater + tracersSurfaceFluxSubglacialRunoff(index_salinity_flux,iCell) = 0.0_RKIND + end if end if ! Accumulate fluxes that use the freezing point -! mrp performance note: should call ocn_freezing_temperature just once here +! mrp performance note: should call ocn_freezing_temperature just once here seaIceTemperatureFlux(iCell) = seaIceFreshWaterFlux(iCell) * & ocn_freezing_temperature( tracerGroup(index_salinity_flux, minLevelCell(iCell), iCell), pressure=0.0_RKIND, & inLandIceCavity=.false.) / rho_sw @@ -613,10 +619,15 @@ subroutine ocn_surface_bulk_forcing_active_tracers(meshPool, forcingPool, tracer tracersSurfaceFlux(index_temperature_flux, iCell) = tracersSurfaceFlux(index_temperature_flux, iCell) & + surfaceTemperatureFluxWithoutRunoff - ! add river and subglacial runoff contribution for sending through coupler + ! add river runoff contribution for sending through coupler totalFreshWaterTemperatureFlux(iCell) = surfaceTemperatureFluxWithoutRunoff & - + tracersSurfaceFluxRunoff(index_temperature_flux,iCell) & + + tracersSurfaceFluxRunoff(index_temperature_flux,iCell) + + ! add subglacial runoff contribution for sending through coupler + if (trim(config_subglacial_runoff_mode) == 'data') then + totalFreshWaterTemperatureFlux(iCell) = totalFreshWaterTemperatureFlux(iCell) & + tracersSurfaceFluxSubglacialRunoff(index_temperature_flux,iCell) + end if ! Fields with zero temperature are not accumulated. These include: ! snowFlux diff --git a/components/mpas-ocean/src/shared/mpas_ocn_tendency.F b/components/mpas-ocean/src/shared/mpas_ocn_tendency.F index 2d3dd66cbdb9..30584386666c 100644 --- a/components/mpas-ocean/src/shared/mpas_ocn_tendency.F +++ b/components/mpas-ocean/src/shared/mpas_ocn_tendency.F @@ -186,11 +186,15 @@ subroutine ocn_tend_thick(tendPool, forcingPool)!{{{ do iCell = 1, nCellsAll surfaceThicknessFlux(iCell) = 0.0_RKIND surfaceThicknessFluxRunoff(iCell) = 0.0_RKIND - surfaceThicknessFluxSubglacialRunoff(iCell) = 0.0_RKIND do k=1,nVertLevels tendThick(k, iCell) = 0.0_RKIND end do end do + if (trim(config_subglacial_runoff_mode) == 'data') then + do iCell = 1, nCellsAll + surfaceThicknessFluxSubglacialRunoff(iCell) = 0.0_RKIND + end do + end if #ifndef MPAS_OPENACC !$omp end do !$omp end parallel @@ -841,9 +845,13 @@ subroutine ocn_tend_tracer(tendPool, statePool, forcingPool, & do n=1,nTracersGroup tracerGroupSurfaceFlux (n,iCell) = 0.0_RKIND tracerGroupSurfaceFluxRunoff (n,iCell) = 0.0_RKIND - tracerGroupSurfaceFluxSubglacialRunoff (n,iCell) = 0.0_RKIND tracerGroupSurfaceFluxRemoved(n,iCell) = 0.0_RKIND end do + if (trim(config_subglacial_runoff_mode) == 'data') then + do n=1,nTracersGroup + tracerGroupSurfaceFluxSubglacialRunoff (n,iCell) = 0.0_RKIND + end do + end if end do !$omp end do !$omp end parallel diff --git a/components/mpas-ocean/src/shared/mpas_ocn_thick_surface_flux.F b/components/mpas-ocean/src/shared/mpas_ocn_thick_surface_flux.F index 1f7c67b88e09..eb531a999582 100644 --- a/components/mpas-ocean/src/shared/mpas_ocn_thick_surface_flux.F +++ b/components/mpas-ocean/src/shared/mpas_ocn_thick_surface_flux.F @@ -141,15 +141,18 @@ subroutine ocn_thick_surface_flux_tend(transmissionCoefficients, transmissionCoe do iCell = 1, nCellsOwned remainingFlux = 1.0_RKIND remainingFluxRunoff = 1.0_RKIND - remainingFluxSubglacialRunoff = 1.0_RKIND + if (trim(config_subglacial_runoff_mode) == 'data') then + remainingFluxSubglacialRunoff = 1.0_RKIND + end if do k = minLevelCell(iCell), maxLevelCell(iCell) remainingFlux = remainingFlux - transmissionCoefficients(k, iCell) remainingFluxRunoff = remainingFluxRunoff - transmissionCoefficientsRunoff(k, iCell) - remainingFluxSubglacialRunoff = remainingFluxSubglacialRunoff - transmissionCoefficientsSubglacialRunoff(k, iCell) - tend(k, iCell) = tend(k, iCell) + surfaceThicknessFlux(iCell) * transmissionCoefficients(k, iCell) & - + surfaceThicknessFluxRunoff(iCell) * transmissionCoefficientsRunoff(k, iCell) & - + surfaceThicknessFluxSubglacialRunoff(iCell) * transmissionCoefficientsSubglacialRunoff(k, iCell) + + surfaceThicknessFluxRunoff(iCell) * transmissionCoefficientsRunoff(k, iCell) + if (trim(config_subglacial_runoff_mode) == 'data') then + remainingFluxSubglacialRunoff = remainingFluxSubglacialRunoff - transmissionCoefficientsSubglacialRunoff(k, iCell) + tend(k, iCell) = tend(k, iCell) + surfaceThicknessFluxSubglacialRunoff(iCell) * transmissionCoefficientsSubglacialRunoff(k, iCell) + end if end do if(maxLevelCell(iCell) > 0 .and. remainingFlux > 0.0_RKIND) then @@ -161,9 +164,11 @@ subroutine ocn_thick_surface_flux_tend(transmissionCoefficients, transmissionCoe + remainingFluxRunoff * surfaceThicknessFluxRunoff(iCell) end if - if(maxLevelCell(iCell) > 0 .and. remainingFluxSubglacialRunoff > 0.0_RKIND) then - tend(maxLevelCell(iCell), iCell) = tend(maxLevelCell(iCell), iCell) & - + remainingFluxSubglacialRunoff * surfaceThicknessFluxSubglacialRunoff(iCell) + if (trim(config_subglacial_runoff_mode) == 'data') then + if(maxLevelCell(iCell) > 0 .and. remainingFluxSubglacialRunoff > 0.0_RKIND) then + tend(maxLevelCell(iCell), iCell) = tend(maxLevelCell(iCell), iCell) & + + remainingFluxSubglacialRunoff * surfaceThicknessFluxSubglacialRunoff(iCell) + end if end if end do #ifndef MPAS_OPENACC diff --git a/components/mpas-ocean/src/shared/mpas_ocn_tracer_surface_flux_to_tend.F b/components/mpas-ocean/src/shared/mpas_ocn_tracer_surface_flux_to_tend.F index 4303d1b78ff2..4a1dc5fce098 100644 --- a/components/mpas-ocean/src/shared/mpas_ocn_tracer_surface_flux_to_tend.F +++ b/components/mpas-ocean/src/shared/mpas_ocn_tracer_surface_flux_to_tend.F @@ -206,7 +206,7 @@ subroutine ocn_tracer_surface_flux_tend(meshPool, fractionAbsorbed, fractionAbso ! now do subglacial runoff component - if (associated(surfaceTracerFluxSubglacialRunoff)) then + if (trim(config_subglacial_runoff_mode) == 'data') then call mpas_timer_start("surface_tracer_subglacial_runoff_flux") !$omp parallel From 9b3e339867dfbf0f564be21ef25deb71ce089ffe Mon Sep 17 00:00:00 2001 From: Irena Vankova Date: Mon, 8 Jul 2024 14:46:56 -0600 Subject: [PATCH 219/451] pkg dataSubglacialRunoffFluxPKG into registry variables --- components/mpas-ocean/src/Registry.xml | 7 ++++--- .../src/tracer_groups/Registry_activeTracers.xml | 2 +- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/components/mpas-ocean/src/Registry.xml b/components/mpas-ocean/src/Registry.xml index bab430733500..79ef88b33181 100644 --- a/components/mpas-ocean/src/Registry.xml +++ b/components/mpas-ocean/src/Registry.xml @@ -3384,6 +3384,7 @@ /> @@ -3807,7 +3808,7 @@ /> - + From 5ea51b28153984ba3c484d453a55cd48181b8edb Mon Sep 17 00:00:00 2001 From: Irena Vankova Date: Tue, 9 Jul 2024 16:30:12 -0600 Subject: [PATCH 220/451] add conservation registry and streams --- components/mpas-ocean/cime_config/buildnml | 3 +++ .../Registry_conservation_check.xml | 19 +++++++++++++++++++ 2 files changed, 22 insertions(+) diff --git a/components/mpas-ocean/cime_config/buildnml b/components/mpas-ocean/cime_config/buildnml index d6d40491baa6..4d5029555afc 100755 --- a/components/mpas-ocean/cime_config/buildnml +++ b/components/mpas-ocean/cime_config/buildnml @@ -1195,12 +1195,14 @@ def buildnml(case, caseroot, compname): lines.append('') lines.append('') lines.append('') + lines.append('') lines.append('') lines.append('') lines.append('') lines.append('') lines.append('') lines.append('') + lines.append('') lines.append('') lines.append('') lines.append('') @@ -1209,6 +1211,7 @@ def buildnml(case, caseroot, compname): lines.append('') lines.append('') lines.append('') + lines.append('') lines.append('') lines.append('') lines.append('') diff --git a/components/mpas-ocean/src/analysis_members/Registry_conservation_check.xml b/components/mpas-ocean/src/analysis_members/Registry_conservation_check.xml index 0fd2d28d1c6e..7870e6fc2178 100644 --- a/components/mpas-ocean/src/analysis_members/Registry_conservation_check.xml +++ b/components/mpas-ocean/src/analysis_members/Registry_conservation_check.xml @@ -106,6 +106,10 @@ + @@ -145,6 +149,10 @@ description="Fresh water flux from river runoff from coupler. Positive into the ocean." packages="thicknessBulkPKG" /> + @@ -194,6 +202,11 @@ + + + + @@ -302,6 +317,7 @@ + @@ -343,12 +359,14 @@ + + @@ -358,6 +376,7 @@ + From 361900104fd6e9fa284639f73395d5ca04732ffc Mon Sep 17 00:00:00 2001 From: Irena Vankova Date: Tue, 9 Jul 2024 17:04:01 -0600 Subject: [PATCH 221/451] try copy mpas_ocn_conservation_check.F --- .../mpas_ocn_conservation_check.F | 105 ++++++++++++++++-- 1 file changed, 97 insertions(+), 8 deletions(-) diff --git a/components/mpas-ocean/src/analysis_members/mpas_ocn_conservation_check.F b/components/mpas-ocean/src/analysis_members/mpas_ocn_conservation_check.F index 5551d5758db2..756328a3d5dd 100644 --- a/components/mpas-ocean/src/analysis_members/mpas_ocn_conservation_check.F +++ b/components/mpas-ocean/src/analysis_members/mpas_ocn_conservation_check.F @@ -28,6 +28,7 @@ module ocn_conservation_check use ocn_constants use ocn_config + use ocn_mesh implicit none private @@ -427,6 +428,7 @@ subroutine energy_conservation(domain, err) accumulatedEvapTemperatureFlux, & accumulatedSeaIceTemperatureFlux, & accumulatedRiverRunoffTemperatureFlux, & + accumulatedSubglacialRunoffTemperatureFlux, & accumulatedIcebergTemperatureFlux real(kind=RKIND), dimension(:), allocatable :: & @@ -463,7 +465,8 @@ subroutine energy_conservation(domain, err) real(kind=RKIND), dimension(:,:), pointer :: & - activeTracersSurfaceFluxRunoff + activeTracersSurfaceFluxRunoff, & + activeTracersSurfaceFluxSubglacialRunoff type (MPAS_timeInterval_type) :: & timeStepESMF @@ -480,7 +483,7 @@ subroutine energy_conservation(domain, err) ierr integer, parameter :: & - nSums = 19 + nSums = 20 character(len=160) :: & m @@ -513,6 +516,7 @@ subroutine energy_conservation(domain, err) call MPAS_pool_get_array(conservationCheckEnergyAMPool, "accumulatedEvapTemperatureFlux", accumulatedEvapTemperatureFlux) call MPAS_pool_get_array(conservationCheckEnergyAMPool, "accumulatedSeaIceTemperatureFlux", accumulatedSeaIceTemperatureFlux) call MPAS_pool_get_array(conservationCheckEnergyAMPool, "accumulatedRiverRunoffTemperatureFlux", accumulatedRiverRunoffTemperatureFlux) + call MPAS_pool_get_array(conservationCheckEnergyAMPool, "accumulatedSubglacialRunoffTemperatureFlux", accumulatedSubglacialRunoffTemperatureFlux) call MPAS_pool_get_array(conservationCheckEnergyAMPool, "accumulatedIcebergTemperatureFlux", accumulatedIcebergTemperatureFlux) !------------------------------------------------------------- @@ -556,6 +560,7 @@ subroutine energy_conservation(domain, err) call mpas_pool_get_subpool(forcingPool, 'tracersSurfaceFlux',tracersSurfaceFluxPool) call mpas_pool_get_dimension(tracersSurfaceFluxPool, 'index_temperatureSurfaceFlux', index_temperature_flux) call mpas_pool_get_array(tracersSurfaceFluxPool, 'activeTracersSurfaceFluxRunoff', activeTracersSurfaceFluxRunoff) + call mpas_pool_get_array(tracersSurfaceFluxPool, 'activeTracersSurfaceFluxSubglacialRunoff', activeTracersSurfaceFluxSubglacialRunoff) call mpas_pool_get_array(statePool, 'accumulatedFrazilIceMass', accumulatedFrazilIceMassNew, 2) call mpas_pool_get_array(statePool, 'accumulatedFrazilIceMass', accumulatedFrazilIceMassOld, 1) @@ -581,6 +586,11 @@ subroutine energy_conservation(domain, err) sumArray(14) = sumArray(14) + areaCell(iCell) * activeTracersSurfaceFluxRunoff(index_temperature_flux,iCell) sumArray(15) = sumArray(15) + areaCell(iCell) * icebergTemperatureFlux(iCell) + ! subglacial river runoff temperature flux + if (trim(config_subglacial_runoff_mode) == 'data') then + sumArray(20) = sumArray(20) + areaCell(iCell) * activeTracersSurfaceFluxSubglacialRunoff(index_temperature_flux,iCell) + end if + enddo ! iCell if (config_use_frazil_ice_formation) then @@ -634,6 +644,9 @@ subroutine energy_conservation(domain, err) accumulatedLandIceHeatFlux = accumulatedLandIceHeatFlux + sumArrayOut(17) accumulatedLandIceFrazilHeatFlux = accumulatedLandIceFrazilHeatFlux + sumArrayOut(18) accumulatedRemovedIceRunoffHeatFlux = accumulatedRemovedIceRunoffHeatFlux + sumArrayOut(19) + if (trim(config_subglacial_runoff_mode) == 'data') then + accumulatedSubglacialRunoffTemperatureFlux = accumulatedSubglacialRunoffTemperatureFlux + sumArrayOut(20) + end if ! cleanup deallocate(sumArray) @@ -663,6 +676,9 @@ subroutine energy_conservation(domain, err) accumulatedEvapTemperatureFlux = accumulatedEvapTemperatureFlux /accumulatedFluxCounter accumulatedSeaIceTemperatureFlux = accumulatedSeaIceTemperatureFlux /accumulatedFluxCounter accumulatedRiverRunoffTemperatureFlux = accumulatedRiverRunoffTemperatureFlux /accumulatedFluxCounter + if (trim(config_subglacial_runoff_mode) == 'data') then + accumulatedSubglacialRunoffTemperatureFlux = accumulatedSubglacialRunoffTemperatureFlux /accumulatedFluxCounter + end if accumulatedIcebergTemperatureFlux = accumulatedIcebergTemperatureFlux /accumulatedFluxCounter accumulatedLandIceFrazilHeatFlux = accumulatedLandIceFrazilHeatFlux /accumulatedFluxCounter accumulatedRemovedIceRunoffHeatFlux = accumulatedRemovedIceRunoffHeatFlux /accumulatedFluxCounter @@ -699,6 +715,9 @@ subroutine energy_conservation(domain, err) + accumulatedRiverRunoffTemperatureFlux *rho_sw*cp_sw & + accumulatedIcebergTemperatureFlux*rho_sw*cp_sw ! note, accumulatedLandIceFrazilHeatFlux not added because already in accumulatedFrazilHeatFlux + if (trim(config_subglacial_runoff_mode) == 'data') then + netEnergyFlux = netEnergyFlux + accumulatedSubglacialRunoffTemperatureFlux * rho_sw*cp_sw + end if ! compute the final energy error call MPAS_pool_get_array(conservationCheckEnergyAMPool, "absoluteEnergyError", absoluteEnergyError) @@ -760,6 +779,9 @@ subroutine energy_conservation(domain, err) v=accumulatedEvapTemperatureFlux *rho_sw*cp_sw; write(m,"('EvapTemperatureFlux ',es16.8,' ',f16.8)") v,v/A; call mpas_log_write(m); s=s+v v=accumulatedSeaIceTemperatureFlux *rho_sw*cp_sw; write(m,"('SeaIceTemperatureFlux ',es16.8,' ',f16.8)") v,v/A; call mpas_log_write(m); s=s+v v=accumulatedRiverRunoffTemperatureFlux*rho_sw*cp_sw; write(m,"('RiverRunoffTempFlux ',es16.8,' ',f16.8)") v,v/A; call mpas_log_write(m); s=s+v +if (trim(config_subglacial_runoff_mode) == 'data') then + v=accumulatedSubglacialRunoffTemperatureFlux*rho_sw*cp_sw; write(m,"('SubglacialRunoffTempFlux ',es16.8,' ',f16.8)") v,v/A; call mpas_log_write(m); s=s+v +end if v=accumulatedIcebergTemperatureFlux*rho_sw*cp_sw; write(m,"('IcebergTemperatureFlux ',es16.8,' ',f16.8)") v,v/A; call mpas_log_write(m); s=s+v write(m,"('SUM IMPLICIT HEAT FLUXES ',es16.8,' hh20temp ',f16.8,es16.8)") s, s/A; call mpas_log_write(m) s = s + explicitHeatFluxSum @@ -828,6 +850,7 @@ subroutine mass_conservation(domain, err) accumulatedEvaporationFlux, & accumulatedSeaIceFlux, & accumulatedRiverRunoffFlux, & + accumulatedSubglacialRunoffFlux, & accumulatedIceRunoffFlux, & accumulatedRemovedRiverRunoffFlux, & accumulatedRemovedIceRunoffFlux, & @@ -852,6 +875,7 @@ subroutine mass_conservation(domain, err) evaporationFlux, & seaIceFreshwaterFlux, & riverRunoffFlux, & + subglacialRunoffFlux, & iceRunoffFlux, & removedRiverRunoffFlux, & removedIceRunoffFlux, & @@ -877,7 +901,7 @@ subroutine mass_conservation(domain, err) iCell, ierr, k integer, parameter :: & - nSums = 12 + nSums = 13 integer, dimension(:), pointer :: minLevelCell, maxLevelCell @@ -900,6 +924,7 @@ subroutine mass_conservation(domain, err) call MPAS_pool_get_array(conservationCheckMassAMPool, "accumulatedEvaporationFlux", accumulatedEvaporationFlux) call MPAS_pool_get_array(conservationCheckMassAMPool, "accumulatedSeaIceFlux", accumulatedSeaIceFlux) call MPAS_pool_get_array(conservationCheckMassAMPool, "accumulatedRiverRunoffFlux", accumulatedRiverRunoffFlux) + call MPAS_pool_get_array(conservationCheckMassAMPool, "accumulatedSubglacialRunoffFlux", accumulatedSubglacialRunoffFlux) call MPAS_pool_get_array(conservationCheckMassAMPool, "accumulatedIceRunoffFlux", accumulatedIceRunoffFlux) call MPAS_pool_get_array(conservationCheckMassAMPool, "accumulatedRemovedRiverRunoffFlux",accumulatedRemovedRiverRunoffFlux) call MPAS_pool_get_array(conservationCheckMassAMPool, "accumulatedRemovedIceRunoffFlux", accumulatedRemovedIceRunoffFlux) @@ -937,6 +962,7 @@ subroutine mass_conservation(domain, err) call mpas_pool_get_array(forcingPool, 'evaporationFlux', evaporationFlux) call mpas_pool_get_array(forcingPool, 'seaIceFreshWaterFlux', seaIceFreshwaterFlux) call mpas_pool_get_array(forcingPool, 'riverRunoffFlux', riverRunoffFlux) + call mpas_pool_get_array(forcingPool, 'subglacialRunoffFlux', subglacialRunoffFlux) call mpas_pool_get_array(forcingPool, 'iceRunoffFlux', iceRunoffFlux) call mpas_pool_get_array(forcingPool, 'removedRiverRunoffFlux', removedRiverRunoffFlux) call mpas_pool_get_array(forcingPool, 'removedIceRunoffFlux', removedIceRunoffFlux) @@ -956,6 +982,9 @@ subroutine mass_conservation(domain, err) sumArray( 7) = sumArray( 7) + areaCell(iCell) * removedRiverRunoffFlux(iCell) sumArray( 8) = sumArray( 8) + areaCell(iCell) * removedIceRunoffFlux(iCell) sumArray( 9) = sumArray( 9) + areaCell(iCell) * icebergFreshwaterFlux(iCell) + if (trim(config_subglacial_runoff_mode) == 'data') then + sumArray(13) = sumArray(13) + areaCell(iCell) * subglacialRunoffFlux(iCell) / areaCell(iCell) * rho_sw + end if enddo if (config_use_frazil_ice_formation) then @@ -1002,6 +1031,9 @@ subroutine mass_conservation(domain, err) accumulatedFrazilFlux = accumulatedFrazilFlux + sumArrayOut(10) accumulatedLandIceFlux = accumulatedLandIceFlux + sumArrayOut(11) accumulatedLandIceFrazilFlux = accumulatedLandIceFrazilFlux + sumArrayOut(12) + if (trim(config_subglacial_runoff_mode) == 'data') then + accumulatedSubglacialRunoffFlux = accumulatedSubglacialRunoffFlux + sumArrayOut(13) + end if ! cleanup deallocate(sumArray) @@ -1021,6 +1053,9 @@ subroutine mass_conservation(domain, err) accumulatedEvaporationFlux = accumulatedEvaporationFlux /accumulatedFluxCounter accumulatedSeaIceFlux = accumulatedSeaIceFlux /accumulatedFluxCounter accumulatedRiverRunoffFlux = accumulatedRiverRunoffFlux /accumulatedFluxCounter + if (trim(config_subglacial_runoff_mode) == 'data') then + accumulatedSubglacialRunoffFlux = accumulatedSubglacialRunoffFlux /accumulatedFluxCounter + end if accumulatedIceRunoffFlux = accumulatedIceRunoffFlux /accumulatedFluxCounter accumulatedRemovedRiverRunoffFlux = accumulatedRemovedRiverRunoffFlux /accumulatedFluxCounter accumulatedRemovedIceRunoffFlux = accumulatedRemovedIceRunoffFlux /accumulatedFluxCounter @@ -1054,6 +1089,9 @@ subroutine mass_conservation(domain, err) + accumulatedFrazilFlux & + accumulatedLandIceFlux ! note, accumulatedLandIceFrazilFlux not added because already in accumulatedFrazilFlux + if (trim(config_subglacial_runoff_mode) == 'data') then + netMassFlux = netMassFlux + accumulatedSubglacialRunoffFlux + end if ! compute the final mass error call MPAS_pool_get_array(conservationCheckMassAMPool, "absoluteMassError", absoluteMassError) @@ -1083,6 +1121,10 @@ subroutine mass_conservation(domain, err) v=accumulatedIcebergFlux ; write(m,"('icebergFreshwaterFlux ',es16.8,' x2o_Fioi_bergw wberg ',f16.8)") v,v*c; call mpas_log_write(m); s=s+v v=accumulatedEvaporationFlux ; write(m,"('evaporationFlux ',es16.8,' x2o_Foxx_evap wevap ',f16.8)") v,v*c; call mpas_log_write(m); s=s+v v=accumulatedRiverRunoffFlux ; write(m,"('riverRunoffFlux ',es16.8,' x2o_Foxx_rofl wrunoff ',f16.8)") v,v*c; call mpas_log_write(m); s=s+v +if (trim(config_subglacial_runoff_mode) == 'data') then + v=accumulatedSubglacialRunoffFlux ; write(m,"('subglacialRunoffFlux ',es16.8,' x2o_Foxx_rofl wsgr ',f16.8)") v,v*c; call mpas_log_write(m); s=s+v +end if + if (landIceFreshwaterFluxesOn) then v=accumulatedRemovedRiverRunoffFlux; write(m,"('removedRiverRunoffFlux ',es16.8,' wrunoff ',f16.8)") v,v*c; call mpas_log_write(m); v=accumulatedRiverRunoffFlux+accumulatedRemovedRiverRunoffFlux; @@ -1150,7 +1192,8 @@ subroutine salt_conservation(domain, err) conservationCheckSaltAMPool, & meshPool, & statePool, & - forcingPool + forcingPool, & + tracersSurfaceFluxPool real(kind=RKIND), pointer :: & initialSalt, & @@ -1160,9 +1203,13 @@ subroutine salt_conservation(domain, err) absoluteSaltError, & relativeSaltError + real(kind=RKIND), dimension(:,:), pointer :: & + activeTracersSurfaceFluxSubglacialRunoff + real(kind=RKIND), pointer :: & accumulatedSeaIceSalinityFlux, & - accumulatedFrazilSalinityFlux + accumulatedFrazilSalinityFlux, & + accumulatedSubglacialRunoffSalinityFlux ! accumulatedLandIceFrazilSalinityFlux is not present because it is always 0 real(kind=RKIND), dimension(:), allocatable :: & @@ -1184,14 +1231,15 @@ subroutine salt_conservation(domain, err) dt, dtAvg, v, A, s, c integer, pointer :: & - nCellsSolve + nCellsSolve, & + index_salinity_flux integer :: & iCell, & ierr integer, parameter :: & - nSums = 3 + nSums = 4 logical, pointer :: & activeTracersBulkRestoringPKG @@ -1209,6 +1257,7 @@ subroutine salt_conservation(domain, err) call MPAS_pool_get_array(conservationCheckSaltAMPool, "accumulatedSeaIceSalinityFlux", accumulatedSeaIceSalinityFlux) call MPAS_pool_get_array(conservationCheckSaltAMPool, "accumulatedFrazilSalinityFlux", accumulatedFrazilSalinityFlux) + call MPAS_pool_get_array(conservationCheckSaltAMPool, "accumulatedSubglacialRunoffSalinityFlux", accumulatedSubglacialRunoffSalinityFlux) !------------------------------------------------------------- ! Net salt flux to ice @@ -1234,12 +1283,23 @@ subroutine salt_conservation(domain, err) call mpas_pool_get_array(forcingPool, 'seaIceSalinityFlux', seaIceSalinityFlux) call mpas_pool_get_array(statePool, 'accumulatedFrazilIceSalinity', accumulatedFrazilIceSalinityOld, 1) call mpas_pool_get_array(statePool, 'accumulatedFrazilIceSalinity', accumulatedFrazilIceSalinityNew, 2) + call mpas_pool_get_subpool(forcingPool, 'tracersSurfaceFlux',tracersSurfaceFluxPool) + call mpas_pool_get_array(tracersSurfaceFluxPool, 'activeTracersSurfaceFluxSubglacialRunoff', activeTracersSurfaceFluxSubglacialRunoff) + call mpas_pool_get_dimension(tracersSurfaceFluxPool, 'index_salinitySurfaceFlux', index_salinity_flux) + + do iCell = 1, nCellsSolve ! salt flux to ocean sumArray(1) = sumArray(1) + areaCell(iCell) * seaIceSalinityFlux(iCell) enddo ! iCell + ! subglacial runoff + if (trim(config_subglacial_runoff_mode) == 'data') then + do iCell = 1, nCellsSolve + sumArray(4) = sumArray(4) + areaCell(iCell) * activeTracersSurfaceFluxSubglacialRunoff(index_salinity_flux,iCell) + enddo ! iCell + end if if (config_use_frazil_ice_formation) then do iCell = 1, nCellsSolve @@ -1265,6 +1325,9 @@ subroutine salt_conservation(domain, err) ! accumulate fluxes accumulatedSeaIceSalinityFlux = accumulatedSeaIceSalinityFlux + sumArrayOut(1) accumulatedFrazilSalinityFlux = accumulatedFrazilSalinityFlux + sumArrayOut(2) + if (trim(config_subglacial_runoff_mode) == 'data') then + accumulatedSubglacialRunoffSalinityFlux = accumulatedSubglacialRunoffSalinityFlux + sumArrayOut(4) + end if ! cleanup deallocate(sumArray) @@ -1281,6 +1344,9 @@ subroutine salt_conservation(domain, err) ! Average the fluxes accumulatedSeaIceSalinityFlux = accumulatedSeaIceSalinityFlux /accumulatedFluxCounter accumulatedFrazilSalinityFlux = accumulatedFrazilSalinityFlux /accumulatedFluxCounter + if (trim(config_subglacial_runoff_mode) == 'data') then + accumulatedSubglacialRunoffSalinityFlux = accumulatedSubglacialRunoffSalinityFlux /accumulatedFluxCounter + end if ! get initial salt content call MPAS_pool_get_array(conservationCheckSaltAMPool, "initialSalt", initialSalt) @@ -1299,6 +1365,10 @@ subroutine salt_conservation(domain, err) netSaltFlux = accumulatedSeaIceSalinityFlux & + accumulatedFrazilSalinityFlux + if (trim(config_subglacial_runoff_mode) == 'data') then + netSaltFlux = netSaltFlux + accumulatedSubglacialRunoffSalinityFlux + end if + ! compute the final salt error call MPAS_pool_get_array(conservationCheckSaltAMPool, "absoluteSaltError", absoluteSaltError) call MPAS_pool_get_array(conservationCheckSaltAMPool, "relativeSaltError", relativeSaltError) @@ -1327,6 +1397,10 @@ subroutine salt_conservation(domain, err) .and.config_frazil_under_land_ice) then v=0; write(m,"('LandIceFrazilSalinityFlux',es16.8,' (already in wmelt, do not sum) ',f16.8)") v,v*c; call mpas_log_write(m); !no sum: s=s+v end if +if (trim(config_subglacial_runoff_mode) == 'data') then + v=accumulatedSubglacialRunoffSalinityFlux ; write(m,"('SubglacialRunoffSalinityFlux ',es16.8,' x2o_Fioi_salt salt ',f16.8)") v,v*c; call mpas_log_write(m); s=s+v +end if + write(m,"('SUM VOLUME FLUXES ',es16.8,' ',f16.8,es16.8)") s, s*c; call mpas_log_write(m) call mpas_log_write(' ') @@ -2232,6 +2306,7 @@ subroutine reset_accumulated_variables(domain) accumulatedEvapTemperatureFlux, & accumulatedSeaIceTemperatureFlux, & accumulatedRiverRunoffTemperatureFlux, & + accumulatedSubglacialRunoffTemperatureFlux, & accumulatedIcebergTemperatureFlux real(kind=RKIND), pointer :: & @@ -2240,6 +2315,7 @@ subroutine reset_accumulated_variables(domain) accumulatedEvaporationFlux, & accumulatedSeaIceFlux, & accumulatedRiverRunoffFlux, & + accumulatedSubglacialRunoffFlux, & accumulatedIceRunoffFlux, & accumulatedRemovedRiverRunoffFlux, & accumulatedRemovedIceRunoffFlux, & @@ -2250,7 +2326,8 @@ subroutine reset_accumulated_variables(domain) real(kind=RKIND), pointer :: & accumulatedSeaIceSalinityFlux, & - accumulatedFrazilSalinityFlux + accumulatedFrazilSalinityFlux, & + accumulatedSubglacialRunoffSalinityFlux real(kind=RKIND), pointer :: & accumulatedCarbonSourceSink, & @@ -2280,6 +2357,7 @@ subroutine reset_accumulated_variables(domain) call MPAS_pool_get_array(conservationCheckEnergyAMPool, "accumulatedEvapTemperatureFlux", accumulatedEvapTemperatureFlux) call MPAS_pool_get_array(conservationCheckEnergyAMPool, "accumulatedSeaIceTemperatureFlux", accumulatedSeaIceTemperatureFlux) call MPAS_pool_get_array(conservationCheckEnergyAMPool, "accumulatedRiverRunoffTemperatureFlux", accumulatedRiverRunoffTemperatureFlux) + call MPAS_pool_get_array(conservationCheckEnergyAMPool, "accumulatedSubglacialRunoffTemperatureFlux", accumulatedSubglacialRunoffTemperatureFlux) call MPAS_pool_get_array(conservationCheckEnergyAMPool, "accumulatedIcebergTemperatureFlux", accumulatedIcebergTemperatureFlux) accumulatedFluxCounter = 0 @@ -2298,6 +2376,9 @@ subroutine reset_accumulated_variables(domain) accumulatedEvapTemperatureFlux = 0.0_RKIND accumulatedSeaIceTemperatureFlux = 0.0_RKIND accumulatedRiverRunoffTemperatureFlux = 0.0_RKIND + if (trim(config_subglacial_runoff_mode) == 'data') then + accumulatedSubglacialRunoffTemperatureFlux = 0.0_RKIND + end if accumulatedIcebergTemperatureFlux = 0.0_RKIND accumulatedLandIceFrazilHeatFlux = 0.0_RKIND accumulatedRemovedIceRunoffHeatFlux = 0.0_RKIND @@ -2310,6 +2391,7 @@ subroutine reset_accumulated_variables(domain) call MPAS_pool_get_array(conservationCheckMassAMPool, "accumulatedEvaporationFlux", accumulatedEvaporationFlux) call MPAS_pool_get_array(conservationCheckMassAMPool, "accumulatedSeaIceFlux", accumulatedSeaIceFlux) call MPAS_pool_get_array(conservationCheckMassAMPool, "accumulatedRiverRunoffFlux", accumulatedRiverRunoffFlux) + call MPAS_pool_get_array(conservationCheckMassAMPool, "accumulatedSubglacialRunoffFlux", accumulatedSubglacialRunoffFlux) call MPAS_pool_get_array(conservationCheckMassAMPool, "accumulatedIceRunoffFlux", accumulatedIceRunoffFlux) call MPAS_pool_get_array(conservationCheckMassAMPool, "accumulatedRemovedRiverRunoffFlux",accumulatedRemovedRiverRunoffFlux) call MPAS_pool_get_array(conservationCheckMassAMPool, "accumulatedRemovedIceRunoffFlux", accumulatedRemovedIceRunoffFlux) @@ -2323,6 +2405,9 @@ subroutine reset_accumulated_variables(domain) accumulatedEvaporationFlux = 0.0_RKIND accumulatedSeaIceFlux = 0.0_RKIND accumulatedRiverRunoffFlux = 0.0_RKIND + if (trim(config_subglacial_runoff_mode) == 'data') then + accumulatedSubglacialRunoffFlux = 0.0_RKIND + end if accumulatedIceRunoffFlux = 0.0_RKIND accumulatedRemovedRiverRunoffFlux = 0.0_RKIND accumulatedRemovedIceRunoffFlux = 0.0_RKIND @@ -2336,9 +2421,13 @@ subroutine reset_accumulated_variables(domain) call MPAS_pool_get_array(conservationCheckSaltAMPool, "accumulatedSeaIceSalinityFlux", accumulatedSeaIceSalinityFlux) call MPAS_pool_get_array(conservationCheckSaltAMPool, "accumulatedFrazilSalinityFlux", accumulatedFrazilSalinityFlux) + call MPAS_pool_get_array(conservationCheckSaltAMPool, "accumulatedSubglacialRunoffSalinityFlux", accumulatedSubglacialRunoffSalinityFlux) accumulatedSeaIceSalinityFlux = 0.0_RKIND accumulatedFrazilSalinityFlux = 0.0_RKIND + if (trim(config_subglacial_runoff_mode) == 'data') then + accumulatedSubglacialRunoffSalinityFlux = 0.0_RKIND + end if call MPAS_pool_get_subpool(domain % blocklist % structs, "conservationCheckCarbonAM", conservationCheckCarbonAMPool) From 26720b56bd801322af5b5cb92bc9f2e491be035a Mon Sep 17 00:00:00 2001 From: Irena Vankova Date: Wed, 10 Jul 2024 15:45:14 -0600 Subject: [PATCH 222/451] update dsgr files --- components/mpas-ocean/cime_config/buildnml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/components/mpas-ocean/cime_config/buildnml b/components/mpas-ocean/cime_config/buildnml index 4d5029555afc..6ac2b043aaf3 100755 --- a/components/mpas-ocean/cime_config/buildnml +++ b/components/mpas-ocean/cime_config/buildnml @@ -143,7 +143,7 @@ def buildnml(case, caseroot, compname): if ocn_tidal_mixing == 'true': u_tidal_rms_file = 'velocityTidalRMS_CATS2008.oQU240wLI.20240221.nc' if ocn_sgr == 'data': - data_sgr_file = 'oQU240wLI_DSGR.nc' + data_sgr_file = 'DSGR.MALI.out2055.oQU240wLI.20240328.nc' elif ocn_grid == 'oQU120': decomp_date = '230424' @@ -282,7 +282,7 @@ def buildnml(case, caseroot, compname): if ocn_tidal_mixing == 'true': u_tidal_rms_file = 'velocityTidalRMS_CATS2008.SOwISC12to60E2r4.20210114.nc' if ocn_sgr == 'data': - data_sgr_file = 'SOwISC12to60E2r4_DSGR.nc' + data_sgr_file = 'DSGR.MALI.out2055.SOwISC12to60E2r4.20240328.nc' elif ocn_grid == 'FRISwISC08to60E3r1': decomp_date = '20230913' # changed to date of partiotions in ../files_for_e3sm/assembled_files/inputdata/ocn/mpas-o/FRISwISC08to60E3r1/partitions @@ -359,7 +359,7 @@ def buildnml(case, caseroot, compname): if ocn_tidal_mixing == 'true': u_tidal_rms_file = 'velocityTidalRMS_CATS2008.ECwISC30to60E2r1.20240221.nc' if ocn_sgr == 'data': - data_sgr_file = 'ECwISC30to60E2r1_DSGR.nc' + data_sgr_file = 'DSGR.MALI.out2055.ECwISC30to60E2r1.20240328.nc' elif ocn_grid == 'IcoswISC30E3r5': decomp_date = '20231120' @@ -380,7 +380,7 @@ def buildnml(case, caseroot, compname): if ocn_tidal_mixing == 'true': u_tidal_rms_file = 'velocityTidalRMS_CATS2008.IcoswISC30E3r5.20231120.nc' if ocn_sgr == 'data': - data_sgr_file = 'IcoswISC30E3r5_DSGR.nc' + data_sgr_file = 'DSGR.MALI.out2055.IcoswISC30E3r5.20240328.nc.nc' elif ocn_grid == 'IcosXISC30E3r7': decomp_date = '20240314' From 21a593e20d77166c25ea6b09ec02d0789c9139e7 Mon Sep 17 00:00:00 2001 From: Irena Vankova Date: Wed, 10 Jul 2024 15:51:33 -0600 Subject: [PATCH 223/451] remove redundant compsets --- .../cime_config/config_compsets.xml | 19 ++----------------- 1 file changed, 2 insertions(+), 17 deletions(-) diff --git a/components/mpas-ocean/cime_config/config_compsets.xml b/components/mpas-ocean/cime_config/config_compsets.xml index 6950fd8c2179..be36f0103472 100644 --- a/components/mpas-ocean/cime_config/config_compsets.xml +++ b/components/mpas-ocean/cime_config/config_compsets.xml @@ -42,11 +42,6 @@ 2000_DATM%NYF_SLND_MPASSI_MPASO%PISMFDATMFORCEDDSGR_DROF%NYFAIS45_SGLC_SWAV - - GMPAS-NYF-DSGR - 2000_DATM%NYF_SLND_MPASSI_MPASO%DATMFORCEDDSGR_DROF%NYFAIS45_SGLC_SWAV - - GMPAS-NYF-DISMF 2000_DATM%NYF_SLND_MPASSI_MPASO%DISMFDATMFORCED_DROF%NYFAIS45_SGLC_SWAV @@ -103,8 +98,8 @@ - GMPAS-JRA1p5-DSGR - 2000_DATM%JRA-1p5_SLND_MPASSI%DIB_MPASO%DATMFORCEDDSGR_DROF%JRA-1p5-AIS0ROF_SGLC_SWAV + GMPAS-JRA1p5-DIB-PISMF-DSGR-TMIX + 2000_DATM%JRA-1p5_SLND_MPASSI%DIB_MPASO%IBPISMFDATMFORCEDDSGRTMIX_DROF%JRA-1p5-AIS0ROF_SGLC_SWAV @@ -117,11 +112,6 @@ 2000_DATM%JRA-1p5_SLND_MPASSI%DIB_MPASO%IBPISMFDATMFORCEDTMIX_DROF%JRA-1p5-AIS0ROF_SGLC_SWAV - - GMPAS-JRA1p5-DIB-DISMF-DSGR - 2000_DATM%JRA-1p5_SLND_MPASSI%DIB_MPASO%IBDISMFDATMFORCEDDSGR_DROF%JRA-1p5-AIS0ROF_SGLC_SWAV - - GMPAS-JRA1p4 2000_DATM%JRA-1p4-2018_SLND_MPASSI_MPASO%DATMFORCED_DROF%JRA-1p4-2018_SGLC_SWAV @@ -157,11 +147,6 @@ 2000_DATM%IAF_SLND_MPASSI_MPASO%PISMFDATMFORCED_DROF%IAFAIS45_SGLC_SWAV - - GMPAS-IAF-PISMF-DSGR - 2000_DATM%IAF_SLND_MPASSI_MPASO%PISMFDATMFORCEDDSGR_DROF%IAFAIS45_SGLC_SWAV - - GMPAS-IAF-DISMF 2000_DATM%IAF_SLND_MPASSI_MPASO%DISMFDATMFORCED_DROF%IAFAIS45_SGLC_SWAV From fe4380c621bd7c5ea21c6fe15337c56ed9572c0a Mon Sep 17 00:00:00 2001 From: Irena Vankova Date: Wed, 10 Jul 2024 16:25:01 -0600 Subject: [PATCH 224/451] fix typo in dsgr filename --- components/mpas-ocean/cime_config/buildnml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/components/mpas-ocean/cime_config/buildnml b/components/mpas-ocean/cime_config/buildnml index 6ac2b043aaf3..192fd70bc6ae 100755 --- a/components/mpas-ocean/cime_config/buildnml +++ b/components/mpas-ocean/cime_config/buildnml @@ -380,7 +380,7 @@ def buildnml(case, caseroot, compname): if ocn_tidal_mixing == 'true': u_tidal_rms_file = 'velocityTidalRMS_CATS2008.IcoswISC30E3r5.20231120.nc' if ocn_sgr == 'data': - data_sgr_file = 'DSGR.MALI.out2055.IcoswISC30E3r5.20240328.nc.nc' + data_sgr_file = 'DSGR.MALI.out2055.IcoswISC30E3r5.20240328.nc' elif ocn_grid == 'IcosXISC30E3r7': decomp_date = '20240314' From 8f147f9101c196801cfcb0663cce9df37cee0043 Mon Sep 17 00:00:00 2001 From: Irena Vankova Date: Thu, 11 Jul 2024 10:44:22 -0600 Subject: [PATCH 225/451] fix omp and acc added loops --- .../src/shared/mpas_ocn_diagnostics.F | 17 ++++++++++--- .../shared/mpas_ocn_surface_bulk_forcing.F | 22 +++++++++++++---- .../mpas-ocean/src/shared/mpas_ocn_tendency.F | 24 +++++++++++++++++-- 3 files changed, 54 insertions(+), 9 deletions(-) diff --git a/components/mpas-ocean/src/shared/mpas_ocn_diagnostics.F b/components/mpas-ocean/src/shared/mpas_ocn_diagnostics.F index daf9bfcab6d5..7dc43284a755 100644 --- a/components/mpas-ocean/src/shared/mpas_ocn_diagnostics.F +++ b/components/mpas-ocean/src/shared/mpas_ocn_diagnostics.F @@ -1893,8 +1893,7 @@ subroutine ocn_diagnostic_solve_surfaceLayer(layerThickness, & #ifdef MPAS_OPENACC !$acc parallel loop & !$acc present(surfaceFluxAttenuationCoefficient, & - !$acc surfaceFluxAttenuationCoefficientRunoff, & - !$acc surfaceFluxAttenuationCoefficientSubglacialRunoff) + !$acc surfaceFluxAttenuationCoefficientRunoff) #else !$omp parallel !$omp do schedule(runtime) @@ -1905,16 +1904,28 @@ subroutine ocn_diagnostic_solve_surfaceLayer(layerThickness, & surfaceFluxAttenuationCoefficientRunoff(iCell) = & config_flux_attenuation_coefficient_runoff end do +#ifndef MPAS_OPENACC + !$omp end do + !$omp end parallel +#endif + if (trim(config_subglacial_runoff_mode) == 'data') then +#ifdef MPAS_OPENACC + !$acc parallel loop & + !$acc present(surfaceFluxAttenuationCoefficientSubglacialRunoff) +#else + !$omp parallel + !$omp do schedule(runtime) +#endif do iCell = 1, nCells surfaceFluxAttenuationCoefficientSubglacialRunoff(iCell) = & config_flux_attenuation_coefficient_subglacial_runoff end do - end if #ifndef MPAS_OPENACC !$omp end do !$omp end parallel #endif + end if !-------------------------------------------------------------------- diff --git a/components/mpas-ocean/src/shared/mpas_ocn_surface_bulk_forcing.F b/components/mpas-ocean/src/shared/mpas_ocn_surface_bulk_forcing.F index 0547f73319dd..4375ae8f9eaf 100644 --- a/components/mpas-ocean/src/shared/mpas_ocn_surface_bulk_forcing.F +++ b/components/mpas-ocean/src/shared/mpas_ocn_surface_bulk_forcing.F @@ -336,13 +336,13 @@ subroutine ocn_surface_bulk_forcing_thick(forcingPool, surfaceThicknessFlux, sur ! Build surface fluxes at cell centers #ifdef MPAS_OPENACC !$acc enter data copyin(evaporationFlux, snowFlux, seaIceFreshWaterFlux, icebergFreshWaterFlux, & - !$acc riverRunoffFlux, subglacialRunoffFlux, iceRunoffFlux, rainFlux) + !$acc riverRunoffFlux, iceRunoffFlux, rainFlux) !$acc parallel loop & !$acc present(surfaceThicknessFlux, surfaceThicknessFluxRunoff, & - !$acc surfaceThicknessFluxSubglacialRunoff, evaporationFlux, snowFlux, & + !$acc evaporationFlux, snowFlux, & !$acc seaIceFreshWaterFlux, icebergFreshWaterFlux, riverRunoffFlux, & - !$acc subglacialRunoffFlux, iceRunoffFlux, rainFlux) + !$acc iceRunoffFlux, rainFlux) #else !$omp parallel !$omp do schedule(runtime) @@ -352,15 +352,29 @@ subroutine ocn_surface_bulk_forcing_thick(forcingPool, surfaceThicknessFlux, sur + seaIceFreshWaterFlux(iCell) + icebergFreshWaterFlux(iCell) + iceRunoffFlux(iCell) ) / rho_sw surfaceThicknessFluxRunoff(iCell) = riverRunoffFlux(iCell) / rho_sw end do +#ifndef MPAS_OPENACC + !$omp end do + !$omp end parallel +#endif + if (trim(config_subglacial_runoff_mode) == 'data') then +#ifdef MPAS_OPENACC + !$acc enter data copyin(subglacialRunoffFlux) + + !$acc parallel loop & + !$acc present(surfaceThicknessFluxSubglacialRunoff, subglacialRunoffFlux, areaCell) +#else + !$omp parallel + !$omp do schedule(runtime) +#endif do iCell = 1, nCells surfaceThicknessFluxSubglacialRunoff(iCell) = subglacialRunoffFlux(iCell) / areaCell(iCell) end do - end if #ifndef MPAS_OPENACC !$omp end do !$omp end parallel #endif + end if #ifdef MPAS_OPENACC !$acc exit data delete(evaporationFlux, snowFlux, seaIceFreshWaterFlux, icebergFreshWaterFlux, & diff --git a/components/mpas-ocean/src/shared/mpas_ocn_tendency.F b/components/mpas-ocean/src/shared/mpas_ocn_tendency.F index 30584386666c..727b55f4e5b8 100644 --- a/components/mpas-ocean/src/shared/mpas_ocn_tendency.F +++ b/components/mpas-ocean/src/shared/mpas_ocn_tendency.F @@ -190,15 +190,29 @@ subroutine ocn_tend_thick(tendPool, forcingPool)!{{{ tendThick(k, iCell) = 0.0_RKIND end do end do +#ifndef MPAS_OPENACC + !$omp end do + !$omp end parallel +#endif + if (trim(config_subglacial_runoff_mode) == 'data') then +#ifdef MPAS_OPENACC + !$acc enter data create(surfaceThicknessFluxSubglacialRunoff) + + !$acc parallel loop & + !$acc present(surfaceThicknessFluxSubglacialRunoff) +#else + !$omp parallel + !$omp do schedule(runtime) +#endif do iCell = 1, nCellsAll surfaceThicknessFluxSubglacialRunoff(iCell) = 0.0_RKIND end do - end if #ifndef MPAS_OPENACC !$omp end do !$omp end parallel #endif + end if ! If turned off, return with zero fluxes, tendencies ! Otherwise, start time and call routines to accumulate @@ -847,14 +861,20 @@ subroutine ocn_tend_tracer(tendPool, statePool, forcingPool, & tracerGroupSurfaceFluxRunoff (n,iCell) = 0.0_RKIND tracerGroupSurfaceFluxRemoved(n,iCell) = 0.0_RKIND end do + end do + !$omp end do + !$omp end parallel + if (trim(config_subglacial_runoff_mode) == 'data') then + !$omp do schedule(runtime) private(n) + do iCell = 1, nCellsAll do n=1,nTracersGroup tracerGroupSurfaceFluxSubglacialRunoff (n,iCell) = 0.0_RKIND end do - end if end do !$omp end do !$omp end parallel + end if ! ! compute surface tracer flux from bulk forcing From 43c3190dd1f0ee672f5e7aba701a914fa452b323 Mon Sep 17 00:00:00 2001 From: Irena Vankova Date: Thu, 11 Jul 2024 11:14:30 -0600 Subject: [PATCH 226/451] fix omp in tendency --- components/mpas-ocean/src/shared/mpas_ocn_tendency.F | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/components/mpas-ocean/src/shared/mpas_ocn_tendency.F b/components/mpas-ocean/src/shared/mpas_ocn_tendency.F index 727b55f4e5b8..c6d9e72f83a9 100644 --- a/components/mpas-ocean/src/shared/mpas_ocn_tendency.F +++ b/components/mpas-ocean/src/shared/mpas_ocn_tendency.F @@ -172,12 +172,10 @@ subroutine ocn_tend_thick(tendPool, forcingPool)!{{{ ! initialize to zero and start accumulating tendency terms ! #ifdef MPAS_OPENACC - !$acc enter data create(tendThick, surfaceThicknessFlux, surfaceThicknessFluxRunoff, & - !$acc surfaceThicknessFluxSubglacialRunoff) + !$acc enter data create(tendThick, surfaceThicknessFlux, surfaceThicknessFluxRunoff) !$acc parallel loop & - !$acc present(tendThick, surfaceThicknessFlux, surfaceThicknessFluxRunoff, & - !$acc surfaceThicknessFluxSubglacialRunoff) & + !$acc present(tendThick, surfaceThicknessFlux, surfaceThicknessFluxRunoff) & !$acc private(k) #else !$omp parallel @@ -866,6 +864,7 @@ subroutine ocn_tend_tracer(tendPool, statePool, forcingPool, & !$omp end parallel if (trim(config_subglacial_runoff_mode) == 'data') then + !$omp parallel !$omp do schedule(runtime) private(n) do iCell = 1, nCellsAll do n=1,nTracersGroup From 89c14b8540fcf1916d92356738361f00fd010950 Mon Sep 17 00:00:00 2001 From: Irena Vankova Date: Thu, 11 Jul 2024 11:42:50 -0600 Subject: [PATCH 227/451] add sgr fail if bad string option --- components/mpas-ocean/src/shared/mpas_ocn_diagnostics.F | 2 ++ components/mpas-ocean/src/shared/mpas_ocn_forcing.F | 2 ++ 2 files changed, 4 insertions(+) diff --git a/components/mpas-ocean/src/shared/mpas_ocn_diagnostics.F b/components/mpas-ocean/src/shared/mpas_ocn_diagnostics.F index 7dc43284a755..3e7f432a415b 100644 --- a/components/mpas-ocean/src/shared/mpas_ocn_diagnostics.F +++ b/components/mpas-ocean/src/shared/mpas_ocn_diagnostics.F @@ -3530,6 +3530,8 @@ subroutine ocn_compute_KPP_input_fields(statePool, forcingPool, & end if zTop = zBot end do + else + call mpas_log_write("config_sgr_flux_vertical_location not one of 'bottom', 'uniform', 'top'.", MPAS_LOG_CRIT) end if else fracAbsorbedSubglacialRunoff = 0.0_RKIND diff --git a/components/mpas-ocean/src/shared/mpas_ocn_forcing.F b/components/mpas-ocean/src/shared/mpas_ocn_forcing.F index 5cfce4c4e690..afdacc6c942c 100644 --- a/components/mpas-ocean/src/shared/mpas_ocn_forcing.F +++ b/components/mpas-ocean/src/shared/mpas_ocn_forcing.F @@ -221,6 +221,8 @@ subroutine ocn_forcing_build_fraction_absorbed_array(meshPool, statePool, forcin transmissionCoeffTop = transmissionCoeffBot end do end do + else + call mpas_log_write("config_sgr_flux_vertical_location not one of 'bottom', 'uniform', 'top'.", MPAS_LOG_CRIT) end if end if From 7491a836e534a13d4ef1d59ae98b6f36b4f92870 Mon Sep 17 00:00:00 2001 From: Irena Vankova Date: Thu, 11 Jul 2024 12:12:34 -0600 Subject: [PATCH 228/451] add line --- components/mpas-ocean/src/Registry.xml | 1 + 1 file changed, 1 insertion(+) diff --git a/components/mpas-ocean/src/Registry.xml b/components/mpas-ocean/src/Registry.xml index 79ef88b33181..01e96c635c1d 100644 --- a/components/mpas-ocean/src/Registry.xml +++ b/components/mpas-ocean/src/Registry.xml @@ -3740,6 +3740,7 @@ description="Divergence of transmission through interfaces of surface fluxes below the surface layer at cell centers. These are applied only to subglacial runoff." packages="dataSubglacialRunoffFluxPKG" /> + Date: Thu, 11 Jul 2024 16:11:22 -0500 Subject: [PATCH 229/451] Fixes gotm interface for vertical mixing if GOTM is enabled surface friction velocity is not calculated at present. This fixes that issue Addresses #6507 --- components/mpas-ocean/src/shared/mpas_ocn_tendency.F | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/components/mpas-ocean/src/shared/mpas_ocn_tendency.F b/components/mpas-ocean/src/shared/mpas_ocn_tendency.F index a16e52f14499..99a3bf49844b 100644 --- a/components/mpas-ocean/src/shared/mpas_ocn_tendency.F +++ b/components/mpas-ocean/src/shared/mpas_ocn_tendency.F @@ -1243,12 +1243,12 @@ subroutine ocn_tend_tracer(tendPool, statePool, forcingPool, & ! ! Compute tracer tendency due to non-local flux computed in KPP ! - if (config_use_cvmix_kpp) then - call mpas_timer_start("non-local flux from KPP") - if (.not. config_cvmix_kpp_nonlocal_with_implicit_mix) then - call ocn_compute_KPP_input_fields(statePool, forcingPool,& + if (config_use_cvmix_kpp .or. config_use_gotm) then + call ocn_compute_KPP_input_fields(statePool, forcingPool,& meshPool, timeLevel) + if (.not. config_cvmix_kpp_nonlocal_with_implicit_mix) then + call mpas_timer_start("non-local flux from KPP") if (computeBudgets) then !$omp parallel !$omp do schedule(runtime) private(k,n) @@ -1291,8 +1291,8 @@ subroutine ocn_tend_tracer(tendPool, statePool, forcingPool, & !$omp end do !$omp end parallel endif ! compute budgets + call mpas_timer_stop("non-local flux from KPP") end if ! not non-local with implicit mix - call mpas_timer_stop("non-local flux from KPP") end if ! KPP ! Compute tracer tendency due to production/destruction of From a4209e476757684a82da1d395383db01d24b315a Mon Sep 17 00:00:00 2001 From: irenavankova Date: Fri, 12 Jul 2024 10:11:39 -0600 Subject: [PATCH 230/451] Update components/mpas-ocean/src/Registry.xml description Co-authored-by: Carolyn Begeman --- components/mpas-ocean/src/Registry.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/components/mpas-ocean/src/Registry.xml b/components/mpas-ocean/src/Registry.xml index 01e96c635c1d..8dbd4870dc65 100644 --- a/components/mpas-ocean/src/Registry.xml +++ b/components/mpas-ocean/src/Registry.xml @@ -707,7 +707,7 @@ possible_values="'off', 'data'" /> Date: Mon, 15 Jul 2024 10:25:48 +0000 Subject: [PATCH 231/451] Bump actions/setup-python from 5.1.0 to 5.1.1 Bumps [actions/setup-python](https://github.com/actions/setup-python) from 5.1.0 to 5.1.1. - [Release notes](https://github.com/actions/setup-python/releases) - [Commits](https://github.com/actions/setup-python/compare/v5.1.0...v5.1.1) --- updated-dependencies: - dependency-name: actions/setup-python dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- .github/workflows/e3sm-gh-pages.yml | 2 +- .github/workflows/eamxx-gh-pages.yml | 2 +- .github/workflows/eamxx_default_files.yml | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/e3sm-gh-pages.yml b/.github/workflows/e3sm-gh-pages.yml index ccca0c479f26..9ea25ae1864e 100644 --- a/.github/workflows/e3sm-gh-pages.yml +++ b/.github/workflows/e3sm-gh-pages.yml @@ -31,7 +31,7 @@ jobs: - name: Show action trigger run: echo "= The job was automatically triggered by a ${{github.event_name}} event on repo ${{github.event.repository.name}}." - name: Set up Python 3.10 - uses: actions/setup-python@v5.1.0 + uses: actions/setup-python@v5.1.1 with: python-version: "3.10" - name: Install python deps diff --git a/.github/workflows/eamxx-gh-pages.yml b/.github/workflows/eamxx-gh-pages.yml index abd8b92e4f6c..e6fb53ba29f5 100644 --- a/.github/workflows/eamxx-gh-pages.yml +++ b/.github/workflows/eamxx-gh-pages.yml @@ -54,7 +54,7 @@ jobs: echo "= The job was automatically triggered by a ${{github.event_name}} event." - name: Set up Python 3.11 - uses: actions/setup-python@v5.1.0 + uses: actions/setup-python@v5.1.1 with: python-version: "3.11" diff --git a/.github/workflows/eamxx_default_files.yml b/.github/workflows/eamxx_default_files.yml index 5ecdf6dec00c..e0a8e19f9c01 100644 --- a/.github/workflows/eamxx_default_files.yml +++ b/.github/workflows/eamxx_default_files.yml @@ -21,7 +21,7 @@ jobs: show-progress: false submodules: false - name: Set up Python 3.11 - uses: actions/setup-python@v5.1.0 + uses: actions/setup-python@v5.1.1 with: python-version: "3.11" - name: Run unit tests From c8f15f52dfed06a7de14e5a2d983059cad817fbc Mon Sep 17 00:00:00 2001 From: Irena Vankova Date: Tue, 16 Jul 2024 09:36:47 -0600 Subject: [PATCH 232/451] rename config_sgr_salinity to config_sgr_salinity_prescribed --- components/mpas-ocean/bld/build-namelist | 4 ++-- components/mpas-ocean/bld/build-namelist-section | 4 ++-- .../bld/namelist_files/namelist_defaults_mpaso.xml | 4 ++-- .../bld/namelist_files/namelist_definition_mpaso.xml | 4 ++-- components/mpas-ocean/src/Registry.xml | 8 ++++---- .../mpas-ocean/src/shared/mpas_ocn_surface_bulk_forcing.F | 4 ++-- 6 files changed, 14 insertions(+), 14 deletions(-) diff --git a/components/mpas-ocean/bld/build-namelist b/components/mpas-ocean/bld/build-namelist index 2c5ee97b0df2..f891c5d089a8 100755 --- a/components/mpas-ocean/bld/build-namelist +++ b/components/mpas-ocean/bld/build-namelist @@ -713,8 +713,8 @@ add_default($nl, 'config_sgr_flux_vertical_location'); add_default($nl, 'config_use_sgr_opt_kpp'); add_default($nl, 'config_use_sgr_opt_temp'); add_default($nl, 'config_use_sgr_opt_salt'); -add_default($nl, 'config_sgr_temperature'); -add_default($nl, 'config_sgr_salinity'); +add_default($nl, 'config_sgr_temperature_prescribed'); +add_default($nl, 'config_sgr_salinity_prescribed'); if ($OCN_SGR eq 'data') { add_default($nl, 'config_subglacial_runoff_mode', 'val'=>"data"); } else { diff --git a/components/mpas-ocean/bld/build-namelist-section b/components/mpas-ocean/bld/build-namelist-section index 3f2d4ab4839d..9091c1e961c0 100644 --- a/components/mpas-ocean/bld/build-namelist-section +++ b/components/mpas-ocean/bld/build-namelist-section @@ -229,8 +229,8 @@ add_default($nl, 'config_sgr_flux_vertical_location'); add_default($nl, 'config_use_sgr_opt_kpp'); add_default($nl, 'config_use_sgr_opt_temp'); add_default($nl, 'config_use_sgr_opt_salt'); -add_default($nl, 'config_sgr_temperature'); -add_default($nl, 'config_sgr_salinity'); +add_default($nl, 'config_sgr_temperature_prescribed'); +add_default($nl, 'config_sgr_salinity_prescribed'); add_default($nl, 'config_subglacial_runoff_mode'); ############################ diff --git a/components/mpas-ocean/bld/namelist_files/namelist_defaults_mpaso.xml b/components/mpas-ocean/bld/namelist_files/namelist_defaults_mpaso.xml index 0514704b9514..4957f2ce60f9 100644 --- a/components/mpas-ocean/bld/namelist_files/namelist_defaults_mpaso.xml +++ b/components/mpas-ocean/bld/namelist_files/namelist_defaults_mpaso.xml @@ -347,8 +347,8 @@ 1 'sgr' 'sgr' -0.0 -0.0 +0.0 +0.0 'off' diff --git a/components/mpas-ocean/bld/namelist_files/namelist_definition_mpaso.xml b/components/mpas-ocean/bld/namelist_files/namelist_definition_mpaso.xml index 43ba139ab65f..725308006f53 100644 --- a/components/mpas-ocean/bld/namelist_files/namelist_definition_mpaso.xml +++ b/components/mpas-ocean/bld/namelist_files/namelist_definition_mpaso.xml @@ -1228,7 +1228,7 @@ Valid values: 'sgr', 'prescribed'. Default: Defined in namelist_defaults.xml - Option to choose sgr temperature, applied when config_use_sgr_opt_temp = 'prescribed' @@ -1236,7 +1236,7 @@ Valid values: Any real number. Default: Defined in namelist_defaults.xml - Option to choose sgr salinity, applied when config_use_sgr_opt_temp = 'prescribed' diff --git a/components/mpas-ocean/src/Registry.xml b/components/mpas-ocean/src/Registry.xml index 8dbd4870dc65..07afdb0f9af4 100644 --- a/components/mpas-ocean/src/Registry.xml +++ b/components/mpas-ocean/src/Registry.xml @@ -720,17 +720,17 @@ /> - - diff --git a/components/mpas-ocean/src/shared/mpas_ocn_surface_bulk_forcing.F b/components/mpas-ocean/src/shared/mpas_ocn_surface_bulk_forcing.F index 4375ae8f9eaf..1c7cba2f39cf 100644 --- a/components/mpas-ocean/src/shared/mpas_ocn_surface_bulk_forcing.F +++ b/components/mpas-ocean/src/shared/mpas_ocn_surface_bulk_forcing.F @@ -600,7 +600,7 @@ subroutine ocn_surface_bulk_forcing_active_tracers(meshPool, forcingPool, tracer if ( trim(config_use_sgr_opt_temp) == 'prescribed' ) then !sgr with fixed prescribed temperature (for debugging only) tracersSurfaceFluxSubglacialRunoff(index_temperature_flux,iCell) = subglacialRunoffFlux(iCell) * & - config_sgr_temperature / areaCell(iCell) + config_sgr_temperature_prescribed / areaCell(iCell) else if ( trim(config_use_sgr_opt_temp) == 'sgr' ) then !sgr with temperature equal to the local freezing point of freshwater tracersSurfaceFluxSubglacialRunoff(index_temperature_flux,iCell) = subglacialRunoffFlux(iCell) * & @@ -611,7 +611,7 @@ subroutine ocn_surface_bulk_forcing_active_tracers(meshPool, forcingPool, tracer if ( trim(config_use_sgr_opt_salt) == 'prescribed' ) then !sgr with fixed prescribed temperature (for debugging only) tracersSurfaceFluxSubglacialRunoff(index_salinity_flux,iCell) = subglacialRunoffFlux(iCell) * & - config_sgr_salinity / areaCell(iCell) + config_sgr_salinity_prescribed / areaCell(iCell) else if ( trim(config_use_sgr_opt_salt) == 'sgr' ) then !sgr with temperature equal to the local freezing point of freshwater tracersSurfaceFluxSubglacialRunoff(index_salinity_flux,iCell) = 0.0_RKIND From 307b4d0e3f5abe341fada74494c86a4d2e1a232a Mon Sep 17 00:00:00 2001 From: Irena Vankova Date: Tue, 16 Jul 2024 10:51:53 -0600 Subject: [PATCH 233/451] change config_use_sgr_opt_property from character to logical --- components/mpas-ocean/bld/build-namelist | 4 ++-- components/mpas-ocean/bld/build-namelist-section | 4 ++-- .../namelist_files/namelist_defaults_mpaso.xml | 4 ++-- .../namelist_files/namelist_definition_mpaso.xml | 16 ++++++++-------- components/mpas-ocean/src/Registry.xml | 16 ++++++++-------- .../src/shared/mpas_ocn_surface_bulk_forcing.F | 12 ++++++------ 6 files changed, 28 insertions(+), 28 deletions(-) diff --git a/components/mpas-ocean/bld/build-namelist b/components/mpas-ocean/bld/build-namelist index f891c5d089a8..490100040c00 100755 --- a/components/mpas-ocean/bld/build-namelist +++ b/components/mpas-ocean/bld/build-namelist @@ -711,8 +711,8 @@ add_default($nl, 'config_flux_attenuation_coefficient_runoff'); add_default($nl, 'config_flux_attenuation_coefficient_subglacial_runoff'); add_default($nl, 'config_sgr_flux_vertical_location'); add_default($nl, 'config_use_sgr_opt_kpp'); -add_default($nl, 'config_use_sgr_opt_temp'); -add_default($nl, 'config_use_sgr_opt_salt'); +add_default($nl, 'config_use_sgr_opt_temp_prescribed'); +add_default($nl, 'config_use_sgr_opt_salt_prescribed'); add_default($nl, 'config_sgr_temperature_prescribed'); add_default($nl, 'config_sgr_salinity_prescribed'); if ($OCN_SGR eq 'data') { diff --git a/components/mpas-ocean/bld/build-namelist-section b/components/mpas-ocean/bld/build-namelist-section index 9091c1e961c0..189d32fc7b52 100644 --- a/components/mpas-ocean/bld/build-namelist-section +++ b/components/mpas-ocean/bld/build-namelist-section @@ -227,8 +227,8 @@ add_default($nl, 'config_flux_attenuation_coefficient_runoff'); add_default($nl, 'config_flux_attenuation_coefficient_subglacial_runoff'); add_default($nl, 'config_sgr_flux_vertical_location'); add_default($nl, 'config_use_sgr_opt_kpp'); -add_default($nl, 'config_use_sgr_opt_temp'); -add_default($nl, 'config_use_sgr_opt_salt'); +add_default($nl, 'config_use_sgr_opt_temp_prescribed'); +add_default($nl, 'config_use_sgr_opt_salt_prescribed'); add_default($nl, 'config_sgr_temperature_prescribed'); add_default($nl, 'config_sgr_salinity_prescribed'); add_default($nl, 'config_subglacial_runoff_mode'); diff --git a/components/mpas-ocean/bld/namelist_files/namelist_defaults_mpaso.xml b/components/mpas-ocean/bld/namelist_files/namelist_defaults_mpaso.xml index 4957f2ce60f9..3147d1cc92d4 100644 --- a/components/mpas-ocean/bld/namelist_files/namelist_defaults_mpaso.xml +++ b/components/mpas-ocean/bld/namelist_files/namelist_defaults_mpaso.xml @@ -345,8 +345,8 @@ 0.001 'uniform' 1 -'sgr' -'sgr' +.false. +.false. 0.0 0.0 'off' diff --git a/components/mpas-ocean/bld/namelist_files/namelist_definition_mpaso.xml b/components/mpas-ocean/bld/namelist_files/namelist_definition_mpaso.xml index 725308006f53..803b280a1241 100644 --- a/components/mpas-ocean/bld/namelist_files/namelist_definition_mpaso.xml +++ b/components/mpas-ocean/bld/namelist_files/namelist_definition_mpaso.xml @@ -1212,25 +1212,25 @@ Valid values: 0 - don't use, 1 - use Default: Defined in namelist_defaults.xml - -Option to choose sgr temperature +If true, subglacial runoff temperature is set to config_sgr_temperature_prescribed. If false, the temperature is set to local freezing point. -Valid values: 'sgr', 'prescribed'. +Valid values: .true. or .false. Default: Defined in namelist_defaults.xml - -Option to choose sgr salinity +If true, subglacial runoff salinity is set to config_sgr_salinity_prescribed. If false, the salinity is set to 0 PSU. -Valid values: 'sgr', 'prescribed'. +Valid values: .true. or .false. Default: Defined in namelist_defaults.xml -Option to choose sgr temperature, applied when config_use_sgr_opt_temp = 'prescribed' +Prescribed subglacial runoff temperature value, applied when config_use_sgr_opt_temp_prescribed = .true. Valid values: Any real number. Default: Defined in namelist_defaults.xml @@ -1238,7 +1238,7 @@ Default: Defined in namelist_defaults.xml -Option to choose sgr salinity, applied when config_use_sgr_opt_temp = 'prescribed' +Prescribed subglacial runoff salinity value, applied when config_use_sgr_opt_salt_prescribed = .true. Valid values: Any real number. Default: Defined in namelist_defaults.xml diff --git a/components/mpas-ocean/src/Registry.xml b/components/mpas-ocean/src/Registry.xml index 07afdb0f9af4..3fdfd58ca61d 100644 --- a/components/mpas-ocean/src/Registry.xml +++ b/components/mpas-ocean/src/Registry.xml @@ -718,20 +718,20 @@ description="option to use or not subglacial runoff (sgr) in kpp calculation" possible_values="0 - don't use, 1 - use" /> - - diff --git a/components/mpas-ocean/src/shared/mpas_ocn_surface_bulk_forcing.F b/components/mpas-ocean/src/shared/mpas_ocn_surface_bulk_forcing.F index 1c7cba2f39cf..ce019053fc7c 100644 --- a/components/mpas-ocean/src/shared/mpas_ocn_surface_bulk_forcing.F +++ b/components/mpas-ocean/src/shared/mpas_ocn_surface_bulk_forcing.F @@ -597,22 +597,22 @@ subroutine ocn_surface_bulk_forcing_active_tracers(meshPool, forcingPool, tracer * max(tracerGroup(index_temperature_flux,minLevelCell(iCell),iCell), 0.0_RKIND) / rho_sw if (trim(config_subglacial_runoff_mode) == 'data') then - if ( trim(config_use_sgr_opt_temp) == 'prescribed' ) then - !sgr with fixed prescribed temperature (for debugging only) + if ( config_use_sgr_opt_temp_prescribed ) then + !sgr with fixed prescribed temperature tracersSurfaceFluxSubglacialRunoff(index_temperature_flux,iCell) = subglacialRunoffFlux(iCell) * & config_sgr_temperature_prescribed / areaCell(iCell) - else if ( trim(config_use_sgr_opt_temp) == 'sgr' ) then + else !sgr with temperature equal to the local freezing point of freshwater tracersSurfaceFluxSubglacialRunoff(index_temperature_flux,iCell) = subglacialRunoffFlux(iCell) * & ocn_freezing_temperature(salinity=0.0_RKIND, pressure=landIcePressure(iCell), & inLandIceCavity=.true.) / areaCell(iCell) end if - if ( trim(config_use_sgr_opt_salt) == 'prescribed' ) then - !sgr with fixed prescribed temperature (for debugging only) + if ( config_use_sgr_opt_salt_prescribed ) then + !sgr with fixed prescribed temperature tracersSurfaceFluxSubglacialRunoff(index_salinity_flux,iCell) = subglacialRunoffFlux(iCell) * & config_sgr_salinity_prescribed / areaCell(iCell) - else if ( trim(config_use_sgr_opt_salt) == 'sgr' ) then + else !sgr with temperature equal to the local freezing point of freshwater tracersSurfaceFluxSubglacialRunoff(index_salinity_flux,iCell) = 0.0_RKIND end if From f6cbc38e7ef811504d6b90bd45d813d00659aea6 Mon Sep 17 00:00:00 2001 From: Irena Vankova Date: Tue, 16 Jul 2024 11:01:42 -0600 Subject: [PATCH 234/451] change config_use_sgr_opt_kpp to logical variable --- .../bld/namelist_files/namelist_defaults_mpaso.xml | 2 +- .../bld/namelist_files/namelist_definition_mpaso.xml | 6 +++--- components/mpas-ocean/src/Registry.xml | 10 +++++----- .../mpas-ocean/src/shared/mpas_ocn_diagnostics.F | 2 +- 4 files changed, 10 insertions(+), 10 deletions(-) diff --git a/components/mpas-ocean/bld/namelist_files/namelist_defaults_mpaso.xml b/components/mpas-ocean/bld/namelist_files/namelist_defaults_mpaso.xml index 3147d1cc92d4..dce88f0127e3 100644 --- a/components/mpas-ocean/bld/namelist_files/namelist_defaults_mpaso.xml +++ b/components/mpas-ocean/bld/namelist_files/namelist_defaults_mpaso.xml @@ -344,7 +344,7 @@ 10.0 0.001 'uniform' -1 +.true. .false. .false. 0.0 diff --git a/components/mpas-ocean/bld/namelist_files/namelist_definition_mpaso.xml b/components/mpas-ocean/bld/namelist_files/namelist_definition_mpaso.xml index 803b280a1241..fed7828e6a8b 100644 --- a/components/mpas-ocean/bld/namelist_files/namelist_definition_mpaso.xml +++ b/components/mpas-ocean/bld/namelist_files/namelist_definition_mpaso.xml @@ -1204,11 +1204,11 @@ Valid values: 'top','uniform', 'bottom'. Default: Defined in namelist_defaults.xml - -Option to use or not subglacial runoff (sgr) in kpp calculation. +If true, include subglacial runoff (sgr) contribution in kpp calculation. -Valid values: 0 - don't use, 1 - use +Valid values: .true. or .false. Default: Defined in namelist_defaults.xml diff --git a/components/mpas-ocean/src/Registry.xml b/components/mpas-ocean/src/Registry.xml index 3fdfd58ca61d..3e339aefe1a3 100644 --- a/components/mpas-ocean/src/Registry.xml +++ b/components/mpas-ocean/src/Registry.xml @@ -714,16 +714,16 @@ description="Selects the vertical location where subglacial runoff is fluxed." possible_values="'top','uniform', 'bottom'" /> - Date: Tue, 16 Jul 2024 11:18:15 -0600 Subject: [PATCH 235/451] Move checking for valid string in config_sgr_flux_vertical_location to an init routine --- components/mpas-ocean/src/shared/mpas_ocn_diagnostics.F | 9 +++++++-- components/mpas-ocean/src/shared/mpas_ocn_forcing.F | 2 -- 2 files changed, 7 insertions(+), 4 deletions(-) diff --git a/components/mpas-ocean/src/shared/mpas_ocn_diagnostics.F b/components/mpas-ocean/src/shared/mpas_ocn_diagnostics.F index 368e4e9a50da..a6539f520f1b 100644 --- a/components/mpas-ocean/src/shared/mpas_ocn_diagnostics.F +++ b/components/mpas-ocean/src/shared/mpas_ocn_diagnostics.F @@ -3530,8 +3530,6 @@ subroutine ocn_compute_KPP_input_fields(statePool, forcingPool, & end if zTop = zBot end do - else - call mpas_log_write("config_sgr_flux_vertical_location not one of 'bottom', 'uniform', 'top'.", MPAS_LOG_CRIT) end if else fracAbsorbedSubglacialRunoff = 0.0_RKIND @@ -4695,6 +4693,13 @@ subroutine ocn_diagnostics_init(domain, err)!{{{ call ocn_diagnostics_variables_init(domain, jenkinsOn, & hollandJenkinsOn, err) + if ( trim(config_sgr_flux_vertical_location) == 'top' ) then + else if ( trim(config_sgr_flux_vertical_location) == 'uniform' ) then + else if ( trim(config_sgr_flux_vertical_location) == 'bottom' ) then + else + call mpas_log_write("config_sgr_flux_vertical_location not one of 'bottom', 'uniform', 'top'.", MPAS_LOG_CRIT) + end if + end subroutine ocn_diagnostics_init!}}} !*********************************************************************** diff --git a/components/mpas-ocean/src/shared/mpas_ocn_forcing.F b/components/mpas-ocean/src/shared/mpas_ocn_forcing.F index afdacc6c942c..5cfce4c4e690 100644 --- a/components/mpas-ocean/src/shared/mpas_ocn_forcing.F +++ b/components/mpas-ocean/src/shared/mpas_ocn_forcing.F @@ -221,8 +221,6 @@ subroutine ocn_forcing_build_fraction_absorbed_array(meshPool, statePool, forcin transmissionCoeffTop = transmissionCoeffBot end do end do - else - call mpas_log_write("config_sgr_flux_vertical_location not one of 'bottom', 'uniform', 'top'.", MPAS_LOG_CRIT) end if end if From c1616ddef28349131adedd98741dccc2a19d1b0f Mon Sep 17 00:00:00 2001 From: Irena Vankova Date: Tue, 16 Jul 2024 11:31:26 -0600 Subject: [PATCH 236/451] set config_sgr_flux_vertical_location to bottom in namelist_defaults_mpaso.xml for consistency with Registry --- .../mpas-ocean/bld/namelist_files/namelist_defaults_mpaso.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/components/mpas-ocean/bld/namelist_files/namelist_defaults_mpaso.xml b/components/mpas-ocean/bld/namelist_files/namelist_defaults_mpaso.xml index dce88f0127e3..c57920e5c388 100644 --- a/components/mpas-ocean/bld/namelist_files/namelist_defaults_mpaso.xml +++ b/components/mpas-ocean/bld/namelist_files/namelist_defaults_mpaso.xml @@ -343,7 +343,7 @@ 0.001 10.0 0.001 -'uniform' +'bottom' .true. .false. .false. From b45249581205070d1f39e2400cc574907a4ab6d8 Mon Sep 17 00:00:00 2001 From: Irena Vankova Date: Tue, 16 Jul 2024 12:35:25 -0600 Subject: [PATCH 237/451] Change subglacialRunoffFlux into mass flux from volume flux for consistency with riverRunoffFlux and reference density, update DSGR files --- components/mpas-ocean/cime_config/buildnml | 8 ++++---- components/mpas-ocean/src/Registry.xml | 2 +- .../src/shared/mpas_ocn_surface_bulk_forcing.F | 10 +++++----- 3 files changed, 10 insertions(+), 10 deletions(-) diff --git a/components/mpas-ocean/cime_config/buildnml b/components/mpas-ocean/cime_config/buildnml index 192fd70bc6ae..f3eb22881683 100755 --- a/components/mpas-ocean/cime_config/buildnml +++ b/components/mpas-ocean/cime_config/buildnml @@ -143,7 +143,7 @@ def buildnml(case, caseroot, compname): if ocn_tidal_mixing == 'true': u_tidal_rms_file = 'velocityTidalRMS_CATS2008.oQU240wLI.20240221.nc' if ocn_sgr == 'data': - data_sgr_file = 'DSGR.MALI.out2055.oQU240wLI.20240328.nc' + data_sgr_file = 'DSGR.massFlux.MALI.out2055.oQU240wLI.20240328.nc' elif ocn_grid == 'oQU120': decomp_date = '230424' @@ -282,7 +282,7 @@ def buildnml(case, caseroot, compname): if ocn_tidal_mixing == 'true': u_tidal_rms_file = 'velocityTidalRMS_CATS2008.SOwISC12to60E2r4.20210114.nc' if ocn_sgr == 'data': - data_sgr_file = 'DSGR.MALI.out2055.SOwISC12to60E2r4.20240328.nc' + data_sgr_file = 'DSGR.massFlux.MALI.out2055.SOwISC12to60E2r4.20240328.nc' elif ocn_grid == 'FRISwISC08to60E3r1': decomp_date = '20230913' # changed to date of partiotions in ../files_for_e3sm/assembled_files/inputdata/ocn/mpas-o/FRISwISC08to60E3r1/partitions @@ -359,7 +359,7 @@ def buildnml(case, caseroot, compname): if ocn_tidal_mixing == 'true': u_tidal_rms_file = 'velocityTidalRMS_CATS2008.ECwISC30to60E2r1.20240221.nc' if ocn_sgr == 'data': - data_sgr_file = 'DSGR.MALI.out2055.ECwISC30to60E2r1.20240328.nc' + data_sgr_file = 'DSGR.massFlux.MALI.out2055.ECwISC30to60E2r1.20240328.nc' elif ocn_grid == 'IcoswISC30E3r5': decomp_date = '20231120' @@ -380,7 +380,7 @@ def buildnml(case, caseroot, compname): if ocn_tidal_mixing == 'true': u_tidal_rms_file = 'velocityTidalRMS_CATS2008.IcoswISC30E3r5.20231120.nc' if ocn_sgr == 'data': - data_sgr_file = 'DSGR.MALI.out2055.IcoswISC30E3r5.20240328.nc' + data_sgr_file = 'DSGR.massFlux.massFlux.MALI.out2055.IcoswISC30E3r5.20240328.nc' elif ocn_grid == 'IcosXISC30E3r7': decomp_date = '20240314' diff --git a/components/mpas-ocean/src/Registry.xml b/components/mpas-ocean/src/Registry.xml index 3e339aefe1a3..bf02edf96b51 100644 --- a/components/mpas-ocean/src/Registry.xml +++ b/components/mpas-ocean/src/Registry.xml @@ -3807,7 +3807,7 @@ description="Fresh water flux from river runoff at cell centers from coupler. Positive into the ocean." packages="thicknessBulkPKG" /> - diff --git a/components/mpas-ocean/src/shared/mpas_ocn_surface_bulk_forcing.F b/components/mpas-ocean/src/shared/mpas_ocn_surface_bulk_forcing.F index ce019053fc7c..2cf79881a7f8 100644 --- a/components/mpas-ocean/src/shared/mpas_ocn_surface_bulk_forcing.F +++ b/components/mpas-ocean/src/shared/mpas_ocn_surface_bulk_forcing.F @@ -362,13 +362,13 @@ subroutine ocn_surface_bulk_forcing_thick(forcingPool, surfaceThicknessFlux, sur !$acc enter data copyin(subglacialRunoffFlux) !$acc parallel loop & - !$acc present(surfaceThicknessFluxSubglacialRunoff, subglacialRunoffFlux, areaCell) + !$acc present(surfaceThicknessFluxSubglacialRunoff, subglacialRunoffFlux) #else !$omp parallel !$omp do schedule(runtime) #endif do iCell = 1, nCells - surfaceThicknessFluxSubglacialRunoff(iCell) = subglacialRunoffFlux(iCell) / areaCell(iCell) + surfaceThicknessFluxSubglacialRunoff(iCell) = subglacialRunoffFlux(iCell) / rho_sw end do #ifndef MPAS_OPENACC !$omp end do @@ -600,18 +600,18 @@ subroutine ocn_surface_bulk_forcing_active_tracers(meshPool, forcingPool, tracer if ( config_use_sgr_opt_temp_prescribed ) then !sgr with fixed prescribed temperature tracersSurfaceFluxSubglacialRunoff(index_temperature_flux,iCell) = subglacialRunoffFlux(iCell) * & - config_sgr_temperature_prescribed / areaCell(iCell) + config_sgr_temperature_prescribed / rho_sw else !sgr with temperature equal to the local freezing point of freshwater tracersSurfaceFluxSubglacialRunoff(index_temperature_flux,iCell) = subglacialRunoffFlux(iCell) * & ocn_freezing_temperature(salinity=0.0_RKIND, pressure=landIcePressure(iCell), & - inLandIceCavity=.true.) / areaCell(iCell) + inLandIceCavity=.true.) / rho_sw end if if ( config_use_sgr_opt_salt_prescribed ) then !sgr with fixed prescribed temperature tracersSurfaceFluxSubglacialRunoff(index_salinity_flux,iCell) = subglacialRunoffFlux(iCell) * & - config_sgr_salinity_prescribed / areaCell(iCell) + config_sgr_salinity_prescribed / rho_sw else !sgr with temperature equal to the local freezing point of freshwater tracersSurfaceFluxSubglacialRunoff(index_salinity_flux,iCell) = 0.0_RKIND From e064017ea2622687f3305832d3c8c66d37d4ba11 Mon Sep 17 00:00:00 2001 From: Azamat Mametjanov Date: Tue, 16 Jul 2024 20:09:31 -0700 Subject: [PATCH 238/451] Update grids in superBFB tests --- .../bench/gmpas_noio/user_nl_mpaso | 1 + cime_config/tests.py | 112 +++++++++--------- 2 files changed, 57 insertions(+), 56 deletions(-) diff --git a/cime_config/testmods_dirs/bench/gmpas_noio/user_nl_mpaso b/cime_config/testmods_dirs/bench/gmpas_noio/user_nl_mpaso index 18d93c003d90..e0e9bc591fb6 100644 --- a/cime_config/testmods_dirs/bench/gmpas_noio/user_nl_mpaso +++ b/cime_config/testmods_dirs/bench/gmpas_noio/user_nl_mpaso @@ -1,2 +1,3 @@ config_am_highfrequencyoutput_enable=false config_am_globalstats_enable=false +config_am_conservationcheck_enable=false diff --git a/cime_config/tests.py b/cime_config/tests.py index a9c4809acad4..45ab0595d52e 100644 --- a/cime_config/tests.py +++ b/cime_config/tests.py @@ -800,38 +800,38 @@ # super-BFB OCN "e3sm_superbfb_ocn_opt" : { # opt + pureMPI - #"share" : True, + "share" : True, "time" : "00:30:00", "tests" : ( - "ERS_Ld3.T62_EC30to60E2r2.CMPASO-NYF.pemod-omp1", - "PEM_Lh3.T62_EC30to60E2r2.CMPASO-NYF.pemod-omp1", + "ERS_Ld3.T62_IcoswISC30E3r5.CMPASO-NYF.pemod-omp1", + "PEM_Lh3.T62_IcoswISC30E3r5.CMPASO-NYF.pemod-omp1", ) }, "e3sm_superbfb_ocn_dbg" : { # dbg + pureMPI - #"share" : True, + "share" : True, "time" : "01:00:00", "tests" : ( - "ERS_Ld3_D.T62_EC30to60E2r2.CMPASO-NYF.pemod-omp1", - "PEM_Lh3_D.T62_EC30to60E2r2.CMPASO-NYF.pemod-omp1", + "ERS_Ld3_D.T62_IcoswISC30E3r5.CMPASO-NYF.pemod-omp1", + "PEM_Lh3_D.T62_IcoswISC30E3r5.CMPASO-NYF.pemod-omp1", ) }, "e3sm_superbfb_ocn_opt_thrd" : { # opt + threads - #"share" : True, + "share" : True, "time" : "00:30:00", "tests" : ( - "ERS_Ld3.T62_EC30to60E2r2.CMPASO-NYF.pemod-omp2", - "PET_Lh3.T62_EC30to60E2r2.CMPASO-NYF.pemod-ompfull", + "ERS_Ld3.T62_IcoswISC30E3r5.CMPASO-NYF.pemod-omp2", + "PET_Lh3.T62_IcoswISC30E3r5.CMPASO-NYF.pemod-ompfull", ) }, "e3sm_superbfb_ocn_dbg_thrd" : { # dbg + threads - #"share" : True, + "share" : True, "time" : "01:00:00", "tests" : ( - "ERS_Ld3_D.T62_EC30to60E2r2.CMPASO-NYF.pemod-omp2", - "PET_Lh3_D.T62_EC30to60E2r2.CMPASO-NYF.pemod-ompfull", + "ERS_Ld3_D.T62_IcoswISC30E3r5.CMPASO-NYF.pemod-omp2", + "PET_Lh3_D.T62_IcoswISC30E3r5.CMPASO-NYF.pemod-ompfull", ) }, @@ -842,38 +842,38 @@ # super-BFB ICE "e3sm_superbfb_ice_opt" : { # opt + pureMPI - #"share" : True, + "share" : True, "time" : "00:30:00", "tests" : ( - "ERS_Lh3.T62_EC30to60E2r2.DTESTM.pemod-omp1", - "PEM_Lh3.T62_EC30to60E2r2.DTESTM.pemod-omp1", + "ERS_Lh3.T62_IcoswISC30E3r5.DTESTM.pemod-omp1", + "PEM_Lh3.T62_IcoswISC30E3r5.DTESTM.pemod-omp1", ) }, "e3sm_superbfb_ice_dbg" : { # dbg + pureMPI - #"share" : True, + "share" : True, "time" : "01:00:00", "tests" : ( - "ERS_Lh3_D.T62_EC30to60E2r2.DTESTM.pemod-omp1", - "PEM_Lh3_D.T62_EC30to60E2r2.DTESTM.pemod-omp1", + "ERS_Lh3_D.T62_IcoswISC30E3r5.DTESTM.pemod-omp1", + "PEM_Lh3_D.T62_IcoswISC30E3r5.DTESTM.pemod-omp1", ) }, "e3sm_superbfb_ice_opt_thrd" : { # opt + threads - #"share" : True, + "share" : True, "time" : "00:30:00", "tests" : ( - "ERS_Lh3.T62_EC30to60E2r2.DTESTM.pemod-ompfull", - "PET_Lh3.T62_EC30to60E2r2.DTESTM.pemod-omp2", + "ERS_Lh3.T62_IcoswISC30E3r5.DTESTM.pemod-ompfull", + "PET_Lh3.T62_IcoswISC30E3r5.DTESTM.pemod-omp2", ) }, "e3sm_superbfb_ice_dbg_thrd" : { # dbg + threads - #"share" : True, + "share" : True, "time" : "01:00:00", "tests" : ( - "ERS_Lh3_D.T62_EC30to60E2r2.DTESTM.pemod-ompfull", - "PET_Lh3_D.T62_EC30to60E2r2.DTESTM.pemod-omp2", + "ERS_Lh3_D.T62_IcoswISC30E3r5.DTESTM.pemod-ompfull", + "PET_Lh3_D.T62_IcoswISC30E3r5.DTESTM.pemod-omp2", ) }, @@ -884,38 +884,38 @@ # super-BFB LND "e3sm_superbfb_lnd_opt" : { # opt + pureMPI - #"share" : True, + "share" : True, "time" : "00:30:00", "tests" : ( - "ERS_Lh3.ne30pg2_ne30pg2.IELMTEST.pemod-omp1", - "PEM_Lh3.ne30pg2_ne30pg2.IELMTEST.pemod-omp1", + "ERS_Lh3.r05_r05.IELMTEST.pemod-omp1", + "PEM_Lh3.r05_r05.IELMTEST.pemod-omp1", ) }, "e3sm_superbfb_lnd_dbg" : { # dbg + pureMPI - #"share" : True, + "share" : True, "time" : "01:00:00", "tests" : ( - "ERS_Lh3_D.ne30pg2_ne30pg2.IELMTEST.pemod-omp1", - "PEM_Lh3_D.ne30pg2_ne30pg2.IELMTEST.pemod-omp1", + "ERS_Lh3_D.r05_r05.IELMTEST.pemod-omp1", + "PEM_Lh3_D.r05_r05.IELMTEST.pemod-omp1", ) }, "e3sm_superbfb_lnd_opt_thrd" : { # opt + threads - #"share" : True, + "share" : True, "time" : "00:30:00", "tests" : ( - "PET_Lh3.ne30pg2_ne30pg2.IELMTEST.pemod-omp2", - "ERS_Lh3.ne30pg2_ne30pg2.IELMTEST.pemod-ompfull", + "PET_Lh3.r05_r05.IELMTEST.pemod-omp2", + "ERS_Lh3.r05_r05.IELMTEST.pemod-ompfull", ) }, "e3sm_superbfb_lnd_dbg_thrd" : { # dbg + threads - #"share" : True, + "share" : True, "time" : "01:00:00", "tests" : ( - "PET_Lh3_D.ne30pg2_ne30pg2.IELMTEST.pemod-omp2", - "ERS_Lh3_D.ne30pg2_ne30pg2.IELMTEST.pemod-ompfull", + "PET_Lh3_D.r05_r05.IELMTEST.pemod-omp2", + "ERS_Lh3_D.r05_r05.IELMTEST.pemod-ompfull", ) }, @@ -926,7 +926,7 @@ # super-BFB ROF "e3sm_superbfb_rof_opt" : { # opt + pureMPI - #"share" : True, + "share" : True, "time" : "00:30:00", "tests" : ( "ERS_Ld3.r05_r05.RMOSGPCC.pemod-omp1", @@ -935,7 +935,7 @@ }, "e3sm_superbfb_rof_dbg" : { # dbg + pureMPI - #"share" : True, + "share" : True, "time" : "01:00:00", "tests" : ( "ERS_Ld3_D.r05_r05.RMOSGPCC.pemod-omp1", @@ -944,7 +944,7 @@ }, "e3sm_superbfb_rof_opt_thrd" : { # opt + threads - #"share" : True, + "share" : True, "time" : "00:30:00", "tests" : ( "PET_Ld3.r05_r05.RMOSGPCC.pemod-omp2", @@ -953,7 +953,7 @@ }, "e3sm_superbfb_rof_dbg_thrd" : { # dbg + threads - #"share" : True, + "share" : True, "time" : "01:00:00", "tests" : ( "PET_Ld3_D.r05_r05.RMOSGPCC.pemod-omp2", @@ -968,7 +968,7 @@ # super-BFB ATM "e3sm_superbfb_atm_opt" : { # opt + pureMPI - #"share" : True, + "share" : True, "time" : "00:30:00", "tests" : ( "ERS_Lh3.ne30pg2_ne30pg2.FAQP.pemod-omp1", @@ -977,7 +977,7 @@ }, "e3sm_superbfb_atm_dbg" : { # dbg + pureMPI - #"share" : True, + "share" : True, "time" : "01:00:00", "tests" : ( "ERS_Lh3_D.ne30pg2_ne30pg2.FAQP.pemod-omp1", @@ -986,7 +986,7 @@ }, "e3sm_superbfb_atm_opt_thrd" : { # opt + threads - #"share" : True, + "share" : True, "time" : "00:30:00", "tests" : ( "PET_Lh3.ne30pg2_ne30pg2.FAQP.pemod-omp2", @@ -995,7 +995,7 @@ }, "e3sm_superbfb_atm_dbg_thrd" : { # dbg + threads - #"share" : True, + "share" : True, "time" : "01:00:00", "tests" : ( "PET_Lh3_D.ne30pg2_ne30pg2.FAQP.pemod-omp2", @@ -1010,38 +1010,38 @@ # super-BFB all-active "e3sm_superbfb_wcycl_opt" : { # opt + pureMPI - #"share" : True, + "share" : True, "time" : "01:00:00", "tests" : ( - "ERS_Ld3.ne30pg2_EC30to60E2r2.WCYCL1850.pemod-omp1", - "PEM_Ld3.ne30pg2_EC30to60E2r2.WCYCL1850.pemod-omp1", + "ERS_Ld3.ne30pg2_r05_IcoswISC30E3r5.WCYCL1850.pemod-omp1", + "PEM_Ld3.ne30pg2_r05_IcoswISC30E3r5.WCYCL1850.pemod-omp1", ) }, "e3sm_superbfb_wcycl_dbg" : { # dbg + pureMPI - #"share" : True, + "share" : True, "time" : "02:00:00", "tests" : ( - "ERS_Ld3_D.ne30pg2_EC30to60E2r2.WCYCL1850.pemod-omp1", - "PEM_Ld3_D.ne30pg2_EC30to60E2r2.WCYCL1850.pemod-omp1", + "ERS_Ld3_D.ne30pg2_r05_IcoswISC30E3r5.WCYCL1850.pemod-omp1", + "PEM_Ld3_D.ne30pg2_r05_IcoswISC30E3r5.WCYCL1850.pemod-omp1", ) }, "e3sm_superbfb_wcycl_opt_thrd" : { # opt + threads - #"share" : True, + "share" : True, "time" : "01:00:00", "tests" : ( - "PET_Ld3.ne30pg2_EC30to60E2r2.WCYCL1850.pemod-omp2", - "ERS_Ld3.ne30pg2_EC30to60E2r2.WCYCL1850.pemod-ompfull", + "PET_Ld3.ne30pg2_r05_IcoswISC30E3r5.WCYCL1850.pemod-omp2", + "ERS_Ld3.ne30pg2_r05_IcoswISC30E3r5.WCYCL1850.pemod-ompfull", ) }, "e3sm_superbfb_wcycl_dbg_thrd" : { # dbg + threads - #"share" : True, + "share" : True, "time" : "02:00:00", "tests" : ( - "PET_Ld3_D.ne30pg2_EC30to60E2r2.WCYCL1850.pemod-omp2", - "ERS_Ld3_D.ne30pg2_EC30to60E2r2.WCYCL1850.pemod-omp2", + "PET_Ld3_D.ne30pg2_r05_IcoswISC30E3r5.WCYCL1850.pemod-omp2", + "ERS_Ld3_D.ne30pg2_r05_IcoswISC30E3r5.WCYCL1850.pemod-omp2", ) }, From 3b0dca4de256cc4c14c0b907a8371e7074d6aa48 Mon Sep 17 00:00:00 2001 From: Irena Vankova Date: Wed, 17 Jul 2024 10:53:17 -0600 Subject: [PATCH 239/451] introduce separate subroutine ocn_diagnostic_solve_surfaceLayer_subglacialRunoff --- .../src/shared/mpas_ocn_diagnostics.F | 88 ++++++++++++++----- 1 file changed, 68 insertions(+), 20 deletions(-) diff --git a/components/mpas-ocean/src/shared/mpas_ocn_diagnostics.F b/components/mpas-ocean/src/shared/mpas_ocn_diagnostics.F index a6539f520f1b..82fe1d9a950d 100644 --- a/components/mpas-ocean/src/shared/mpas_ocn_diagnostics.F +++ b/components/mpas-ocean/src/shared/mpas_ocn_diagnostics.F @@ -452,13 +452,16 @@ subroutine ocn_diagnostic_solve(dt, statePool, forcingPool, meshPool, verticalMe ! ! inputs: layerThickness, activeTracers, layerThicknessEdgeFlux, normalVelocity ! outputs: tracersSurfaceLayerValue, indexSurfaceLayerDepth, normalVelocitySurfaceLayer, - ! surfaceFluxAttenuationCoefficient, surfaceFluxAttenuationCoefficientRunoff, - ! surfaceFluxAttenuationCoefficientSubglacialRunoff + ! surfaceFluxAttenuationCoefficient, surfaceFluxAttenuationCoefficientRunoff call ocn_diagnostic_solve_surfaceLayer(layerThickness, activeTracers, & layerThickEdgeFlux, normalVelocity, tracersSurfaceLayerValue, & indexSurfaceLayerDepth, normalVelocitySurfaceLayer, & - sfcFlxAttCoeff, surfaceFluxAttenuationCoefficientRunoff, & - surfaceFluxAttenuationCoefficientSubglacialRunoff) + sfcFlxAttCoeff, surfaceFluxAttenuationCoefficientRunoff) + + if (trim(config_subglacial_runoff_mode) == 'data') then + ! outputs: surfaceFluxAttenuationCoefficientSubglacialRunoff + call ocn_diagnostic_solve_surfaceLayer_subglacialRunoff(surfaceFluxAttenuationCoefficientSubglacialRunoff) + end if end if ! full_compute @@ -565,8 +568,11 @@ subroutine ocn_diagnostic_solve(dt, statePool, forcingPool, meshPool, verticalMe ! !$acc indexSurfaceLayerDepth, & ! !$acc normalVelocitySurfaceLayer, & ! !$acc sfcFlxAttCoeff, & -! !$acc surfaceFluxAttenuationCoefficientRunoff, & -! !$acc surfaceFluxAttenuationCoefficientSubglacialRunoff) +! !$acc surfaceFluxAttenuationCoefficientRunoff) +! if (trim(config_subglacial_runoff_mode) == 'data') then +! !$acc update host(surfaceFluxAttenuationCoefficientSubglacialRunoff) +! end if + ! end if ! full_compute ! !$acc exit data delete (atmosphericPressure, seaIcePressure) @@ -1701,9 +1707,7 @@ subroutine ocn_diagnostic_solve_surfaceLayer(layerThickness, & activeTracers, layerThicknessEdgeFlux, normalVelocity, & tracersSurfaceLayerValue, indexSurfaceLayerDepth, & normalVelocitySurfaceLayer, & - surfaceFluxAttenuationCoefficient, & - surfaceFluxAttenuationCoefficientRunoff, & - surfaceFluxAttenuationCoefficientSubglacialRunoff)!{{{ + surfaceFluxAttenuationCoefficient)!{{{ !----------------------------------------------------------------- ! input variables @@ -1728,8 +1732,7 @@ subroutine ocn_diagnostic_solve_surfaceLayer(layerThickness, & indexSurfaceLayerDepth, &!< [out] layer index at sfc lyr depth normalVelocitySurfaceLayer, &!< [out] avg velocity over sfc layer surfaceFluxAttenuationCoefficient, &!< [out] sfc flx attenuation - surfaceFluxAttenuationCoefficientRunoff, &!< [out] sfc flx attenuation - surfaceFluxAttenuationCoefficientSubglacialRunoff !< [out] sfc flx attenuation + surfaceFluxAttenuationCoefficientRunoff &!< [out] sfc flx attenuation !----------------------------------------------------------------- ! local variables @@ -1909,27 +1912,72 @@ subroutine ocn_diagnostic_solve_surfaceLayer(layerThickness, & !$omp end parallel #endif - if (trim(config_subglacial_runoff_mode) == 'data') then + !-------------------------------------------------------------------- + + end subroutine ocn_diagnostic_solve_surfaceLayer !}}} + +!*********************************************************************** +! +! routine ocn_diagnostic_solve_surfaceLayer_subglacialRunoff +! +!> \brief Computes diagnostic subglacialRunoff variables for surface layer +!> \author Irena Vankova +!> \date July 2024 +!> \details +! +!----------------------------------------------------------------------- + + subroutine ocn_diagnostic_solve_surfaceLayer_subglacialRunoff(surfaceFluxAttenuationCoefficientSubglacialRunoff)!{{{ + + !----------------------------------------------------------------- + ! input variables + !----------------------------------------------------------------- + + !----------------------------------------------------------------- + ! output variables + !----------------------------------------------------------------- + + real (kind=RKIND), dimension(:), intent(out) :: & + surfaceFluxAttenuationCoefficientSubglacialRunoff !< [out] sfc flx attenuation + + !----------------------------------------------------------------- + ! local variables + !----------------------------------------------------------------- + + integer :: & + nCells, &! num of cells + iCell ! loop indices for cell + + ! End preamble + !----------------------------------------------------------------- + ! Begin code + + ! compute the attenuation coefficient for subglacial runoff surface fluxes + + nCells = nCellsHalo( 1 ) + #ifdef MPAS_OPENACC - !$acc parallel loop & - !$acc present(surfaceFluxAttenuationCoefficientSubglacialRunoff) + !$acc parallel loop & + !$acc present(surfaceFluxAttenuationCoefficientSubglacialRunoff) #else - !$omp parallel - !$omp do schedule(runtime) + !$omp parallel + !$omp do schedule(runtime) #endif - do iCell = 1, nCells + do iCell = 1, nCells surfaceFluxAttenuationCoefficientSubglacialRunoff(iCell) = & config_flux_attenuation_coefficient_subglacial_runoff - end do + end do #ifndef MPAS_OPENACC !$omp end do !$omp end parallel #endif - end if !-------------------------------------------------------------------- - end subroutine ocn_diagnostic_solve_surfaceLayer !}}} + end subroutine ocn_diagnostic_solve_surfaceLayer_subglacialRunoff !}}} + +!*********************************************************************** + !*********************************************************************** ! From 7fa3a50ebc4d682f52d125ac85874da692665676 Mon Sep 17 00:00:00 2001 From: Irena Vankova Date: Wed, 17 Jul 2024 11:14:07 -0600 Subject: [PATCH 240/451] correct extra delete --- components/mpas-ocean/src/shared/mpas_ocn_diagnostics.F | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/components/mpas-ocean/src/shared/mpas_ocn_diagnostics.F b/components/mpas-ocean/src/shared/mpas_ocn_diagnostics.F index 82fe1d9a950d..f50d6bb697a3 100644 --- a/components/mpas-ocean/src/shared/mpas_ocn_diagnostics.F +++ b/components/mpas-ocean/src/shared/mpas_ocn_diagnostics.F @@ -1707,7 +1707,8 @@ subroutine ocn_diagnostic_solve_surfaceLayer(layerThickness, & activeTracers, layerThicknessEdgeFlux, normalVelocity, & tracersSurfaceLayerValue, indexSurfaceLayerDepth, & normalVelocitySurfaceLayer, & - surfaceFluxAttenuationCoefficient)!{{{ + surfaceFluxAttenuationCoefficient, & + surfaceFluxAttenuationCoefficientRunoff)!{{{ !----------------------------------------------------------------- ! input variables From 579e3dd8eab64098afb47109bd6175302eba3fc0 Mon Sep 17 00:00:00 2001 From: Irena Vankova Date: Wed, 17 Jul 2024 13:59:02 -0600 Subject: [PATCH 241/451] remove & --- components/mpas-ocean/src/shared/mpas_ocn_diagnostics.F | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/components/mpas-ocean/src/shared/mpas_ocn_diagnostics.F b/components/mpas-ocean/src/shared/mpas_ocn_diagnostics.F index f50d6bb697a3..5046e19d5d59 100644 --- a/components/mpas-ocean/src/shared/mpas_ocn_diagnostics.F +++ b/components/mpas-ocean/src/shared/mpas_ocn_diagnostics.F @@ -1733,7 +1733,7 @@ subroutine ocn_diagnostic_solve_surfaceLayer(layerThickness, & indexSurfaceLayerDepth, &!< [out] layer index at sfc lyr depth normalVelocitySurfaceLayer, &!< [out] avg velocity over sfc layer surfaceFluxAttenuationCoefficient, &!< [out] sfc flx attenuation - surfaceFluxAttenuationCoefficientRunoff &!< [out] sfc flx attenuation + surfaceFluxAttenuationCoefficientRunoff !< [out] sfc flx attenuation !----------------------------------------------------------------- ! local variables From c76dcd59ac81a497d2460d80c045635c867a7ab7 Mon Sep 17 00:00:00 2001 From: jayeshkrishna Date: Wed, 17 Jul 2024 20:44:12 -0500 Subject: [PATCH 242/451] Adding a testmod for adios testing Adding a testmod to force adios I/O type for tests --- cime_config/testmods_dirs/io/force_adios/shell_commands | 2 ++ 1 file changed, 2 insertions(+) create mode 100644 cime_config/testmods_dirs/io/force_adios/shell_commands diff --git a/cime_config/testmods_dirs/io/force_adios/shell_commands b/cime_config/testmods_dirs/io/force_adios/shell_commands new file mode 100644 index 000000000000..e7169a8283bb --- /dev/null +++ b/cime_config/testmods_dirs/io/force_adios/shell_commands @@ -0,0 +1,2 @@ +#!/bin/bash +./xmlchange PIO_TYPENAME="adios" From 9e74909234360689fb4932ae161833846641c888 Mon Sep 17 00:00:00 2001 From: James Foucar Date: Thu, 13 Jun 2024 12:43:07 -0600 Subject: [PATCH 243/451] Clean up kokkos/tril situation If Trilinos is being used, we should use the kokkos that comes with it. This removes the need to explicitly set Kokkos_ROOT in config_machines.xml to the Trilinos one. --- components/cmake/find_dep_packages.cmake | 10 +++++++--- share/build/buildlib.kokkos | 8 +++++++- 2 files changed, 14 insertions(+), 4 deletions(-) diff --git a/components/cmake/find_dep_packages.cmake b/components/cmake/find_dep_packages.cmake index 9d5628bb0bd4..a963fd494330 100644 --- a/components/cmake/find_dep_packages.cmake +++ b/components/cmake/find_dep_packages.cmake @@ -16,10 +16,14 @@ # errors. if (USE_KOKKOS) - # Kokkos will be built in the sharedlibs if Kokkos_ROOT is - # unset. if (NOT DEFINED ENV{Kokkos_ROOT}) - set(ENV{Kokkos_ROOT} ${INSTALL_SHAREDPATH}) + # We should use the kokkos from Trilinos if we are using Trilinos + if (USE_TRILINOS) + set (ENV{Kokkos_ROOT} ${Trilinos_ROOT}) + else() + # Kokkos will be built in the sharedlibs if Kokkos_ROOT is unset. + set(ENV{Kokkos_ROOT} ${INSTALL_SHAREDPATH}) + endif() endif() find_package(Kokkos REQUIRED) diff --git a/share/build/buildlib.kokkos b/share/build/buildlib.kokkos index 035e86b0df2a..8184997615a6 100755 --- a/share/build/buildlib.kokkos +++ b/share/build/buildlib.kokkos @@ -50,6 +50,11 @@ OR ############################################################################### def buildlib(bldroot, installpath, case): ############################################################################### + # If we are using Trilinos, we must use the Kokkos that comes with it + if case.get_value("USE_TRILINOS"): + print ("You case is using Trilinos and will use its Kokkos") + return + installed_kokkos_dir = os.environ.get("Kokkos_ROOT") if installed_kokkos_dir is not None: # We are trying to use a pre-installed kokkos. Look for the relevant folders/libs, @@ -65,9 +70,10 @@ def buildlib(bldroot, installpath, case): # often arch dependent (e.g., $prefix/lib or $prefix/lib64)... The best thing # would be to run a small cmake script, that calls find_package. But E3SM's # cmake build system will do that soon enough, so any error will be caught there. + print (f"Using pre-installed Kokkos_ROOT: {kokkos_root}") return else: - print ("no value foudn in env for Kokkos_ROOT. building from scratch") + print ("no value found in env for Kokkos_ROOT. building from scratch") srcroot = case.get_value("SRCROOT") ekat_dir = os.path.join(srcroot, "externals", "ekat") From ae7e0603e41acfd62f3dc4347a1c2fcfeaf2f8c6 Mon Sep 17 00:00:00 2001 From: Luca Bertagna Date: Tue, 2 Jul 2024 16:15:29 -0600 Subject: [PATCH 244/451] Look for kokkos only if albany/trilinos are not used --- components/cmake/find_dep_packages.cmake | 29 +++++++----------------- 1 file changed, 8 insertions(+), 21 deletions(-) diff --git a/components/cmake/find_dep_packages.cmake b/components/cmake/find_dep_packages.cmake index a963fd494330..1f4cc57d0c72 100644 --- a/components/cmake/find_dep_packages.cmake +++ b/components/cmake/find_dep_packages.cmake @@ -11,37 +11,24 @@ # This will allow users to easily specify a different location for all their cases by # simply setting ${Package}_ROOT in their shell. -# Kokkos' find_package needs to come before other find_packages -# that may define Kokkos targets so we can avoid duplicate target -# errors. -if (USE_KOKKOS) - +# If using albany or trilinos, we should already have kokkos +if (USE_ALBANY) + find_package(Albany REQUIRED) +elseif(USE_TRILINOS) + find_package(Trilinos REQUIRED) +elseif(USE_KOKKOS) if (NOT DEFINED ENV{Kokkos_ROOT}) - # We should use the kokkos from Trilinos if we are using Trilinos - if (USE_TRILINOS) - set (ENV{Kokkos_ROOT} ${Trilinos_ROOT}) - else() - # Kokkos will be built in the sharedlibs if Kokkos_ROOT is unset. - set(ENV{Kokkos_ROOT} ${INSTALL_SHAREDPATH}) - endif() + # Kokkos will be built in the sharedlibs if Kokkos_ROOT is unset. + set(ENV{Kokkos_ROOT} ${INSTALL_SHAREDPATH}) endif() find_package(Kokkos REQUIRED) endif() -# Albany depends on Trilinos -if (USE_ALBANY OR USE_TRILINOS) - find_package(Trilinos REQUIRED) -endif() - if (USE_MOAB) find_package(MOAB REQUIRED) endif() -if (USE_ALBANY) - find_package(Albany REQUIRED) -endif() - if (USE_PETSC) find_package(PETSc REQUIRED) endif() From 72f0ed043c0c3a128689eba24901eb1f60ef910b Mon Sep 17 00:00:00 2001 From: Luca Bertagna Date: Tue, 2 Jul 2024 16:42:58 -0600 Subject: [PATCH 245/451] Find Albany after Trilinos, since AlbanyConfig.cmake is not done right yet If it contained a line like find_dependency(Trilinos REQUIRED) then things would work correctly. Until then, find Trilinos first. --- components/cmake/find_dep_packages.cmake | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/components/cmake/find_dep_packages.cmake b/components/cmake/find_dep_packages.cmake index 1f4cc57d0c72..b1e083f4f0dd 100644 --- a/components/cmake/find_dep_packages.cmake +++ b/components/cmake/find_dep_packages.cmake @@ -12,9 +12,7 @@ # simply setting ${Package}_ROOT in their shell. # If using albany or trilinos, we should already have kokkos -if (USE_ALBANY) - find_package(Albany REQUIRED) -elseif(USE_TRILINOS) +if(USE_TRILINOS) find_package(Trilinos REQUIRED) elseif(USE_KOKKOS) if (NOT DEFINED ENV{Kokkos_ROOT}) @@ -25,6 +23,13 @@ elseif(USE_KOKKOS) find_package(Kokkos REQUIRED) endif() +# When Albany becomes a nice cmake package, that finds its deps, you can +# move this line above if (USE_TRILINOS), and turn that if in elseif. +# Until then, we must find Albany *after* trilinos has been found +if (USE_ALBANY) + find_package(Albany REQUIRED) +endif() + if (USE_MOAB) find_package(MOAB REQUIRED) endif() From dbd0374c2787031a8d7147ff9f5ed3c874ea83c4 Mon Sep 17 00:00:00 2001 From: Jerry Watkins Date: Thu, 18 Jul 2024 15:16:36 -0500 Subject: [PATCH 246/451] Use preinstalled kokkos when using albany - also update trilinos/albany installs on pmcpu/chrysalis --- cime_config/machines/config_machines.xml | 12 +++++------ components/cmake/find_dep_packages.cmake | 21 ++++++++++--------- .../bld/namelist_files/albany_input.yaml | 12 +---------- share/build/buildlib.kokkos | 6 +++--- 4 files changed, 21 insertions(+), 30 deletions(-) diff --git a/cime_config/machines/config_machines.xml b/cime_config/machines/config_machines.xml index a1cf8744de83..092aecdda3ce 100644 --- a/cime_config/machines/config_machines.xml +++ b/cime_config/machines/config_machines.xml @@ -275,8 +275,8 @@ $SHELL{if [ -z "$ADIOS2_ROOT" ]; then echo /global/cfs/cdirs/e3sm/3rdparty/adios2/2.9.1/cray-mpich-8.1.25/gcc-11.2.0; else echo "$ADIOS2_ROOT"; fi} Generic - $SHELL{if [ -z "$Albany_ROOT" ]; then echo /global/common/software/e3sm/mali_tpls/albany-e3sm-serial-release-gcc-cmake-fix; else echo "$Albany_ROOT"; fi} - $SHELL{if [ -z "$Trilinos_ROOT" ]; then echo /global/common/software/e3sm/mali_tpls/trilinos-e3sm-serial-release-gcc; else echo "$Trilinos_ROOT"; fi} + $SHELL{if [ -z "$Albany_ROOT" ]; then echo /global/common/software/e3sm/albany/2024.03.26/gcc/11.2.0; else echo "$Albany_ROOT"; fi} + $SHELL{if [ -z "$Trilinos_ROOT" ]; then echo /global/common/software/e3sm/trilinos/15.1.1/gcc/11.2.0; else echo "$Trilinos_ROOT"; fi} $SHELL{if [ -z "$ADIOS2_ROOT" ]; then echo /global/cfs/cdirs/e3sm/3rdparty/adios2/2.9.1/cray-mpich-8.1.25/nvidia-22.7; else echo "$ADIOS2_ROOT"; fi} @@ -2652,13 +2652,13 @@ $SHELL{if [ -z "$MOAB_ROOT" ]; then echo /lcrc/soft/climate/moab/chrysalis/intel; else echo "$MOAB_ROOT"; fi} + $SHELL{if [ -z "$Albany_ROOT" ]; then echo /lcrc/group/e3sm/soft/albany/2024.03.26/intel/20.0.4; else echo "$Albany_ROOT"; fi} + $SHELL{if [ -z "$Trilinos_ROOT" ]; then echo /lcrc/group/e3sm/soft/trilinos/15.1.1/intel/20.0.4; else echo "$Trilinos_ROOT"; fi} $SHELL{if [ -z "$MOAB_ROOT" ]; then echo /lcrc/soft/climate/moab/chrysalis/gnu; else echo "$MOAB_ROOT"; fi} - - - $SHELL{if [ -z "$Albany_ROOT" ]; then echo /lcrc/group/e3sm/ac.jwatkins/LandIce/AlbanyBuilds/build-gcc-sfad12-e3sm/install; else echo "$Albany_ROOT"; fi} - $SHELL{if [ -z "$Trilinos_ROOT" ]; then echo /lcrc/group/e3sm/ac.jwatkins/LandIce/TrilinosBuilds/build-gcc-e3sm/install; else echo "$Trilinos_ROOT"; fi} + $SHELL{if [ -z "$Albany_ROOT" ]; then echo /lcrc/group/e3sm/soft/albany/2024.03.26/gcc/9.2.0; else echo "$Albany_ROOT"; fi} + $SHELL{if [ -z "$Trilinos_ROOT" ]; then echo /lcrc/group/e3sm/soft/trilinos/15.1.1/gcc/9.2.0; else echo "$Trilinos_ROOT"; fi} diff --git a/components/cmake/find_dep_packages.cmake b/components/cmake/find_dep_packages.cmake index b1e083f4f0dd..24e513b9b5e4 100644 --- a/components/cmake/find_dep_packages.cmake +++ b/components/cmake/find_dep_packages.cmake @@ -12,24 +12,25 @@ # simply setting ${Package}_ROOT in their shell. # If using albany or trilinos, we should already have kokkos -if(USE_TRILINOS) +if (USE_ALBANY OR USE_TRILINOS) find_package(Trilinos REQUIRED) -elseif(USE_KOKKOS) + + # When Albany becomes a nice cmake package, that finds its deps, you can + # move this line above if (USE_TRILINOS), and turn that if in elseif. + # Until then, we must find Albany *after* trilinos has been found + if (USE_ALBANY) + find_package(Albany REQUIRED) + endif() +elseif (USE_KOKKOS) + # Kokkos will be built in the sharedlibs if Kokkos_ROOT is + # unset. if (NOT DEFINED ENV{Kokkos_ROOT}) # Kokkos will be built in the sharedlibs if Kokkos_ROOT is unset. set(ENV{Kokkos_ROOT} ${INSTALL_SHAREDPATH}) endif() - find_package(Kokkos REQUIRED) endif() -# When Albany becomes a nice cmake package, that finds its deps, you can -# move this line above if (USE_TRILINOS), and turn that if in elseif. -# Until then, we must find Albany *after* trilinos has been found -if (USE_ALBANY) - find_package(Albany REQUIRED) -endif() - if (USE_MOAB) find_package(MOAB REQUIRED) endif() diff --git a/components/mpas-albany-landice/bld/namelist_files/albany_input.yaml b/components/mpas-albany-landice/bld/namelist_files/albany_input.yaml index 478ed9dd6580..689c2d526df3 100644 --- a/components/mpas-albany-landice/bld/namelist_files/albany_input.yaml +++ b/components/mpas-albany-landice/bld/namelist_files/albany_input.yaml @@ -1,16 +1,14 @@ %YAML 1.1 --- ANONYMOUS: - Build Type: Tpetra - Problem: + Basal Cubature Degree: 4 LandIce Field Norm: sliding_velocity_basalside: Regularization Type: Given Value Regularization Value: 1.0e-4 LandIce BCs: BC 0: - Cubature Degree: 4 Basal Friction Coefficient: Type: Power Law Power Exponent: 1.0 @@ -82,14 +80,6 @@ ANONYMOUS: # Linear Solver Information Linear Solver Type: Belos Linear Solver Types: - AztecOO: - Forward Solve: - AztecOO Settings: - Aztec Solver: GMRES - Convergence Test: r0 - Size of Krylov Subspace: 200 - Output Frequency: 20 - Max Iterations: 200 Belos: Solver Type: Block GMRES Solver Types: diff --git a/share/build/buildlib.kokkos b/share/build/buildlib.kokkos index 8184997615a6..81d3e01d80d6 100755 --- a/share/build/buildlib.kokkos +++ b/share/build/buildlib.kokkos @@ -50,9 +50,9 @@ OR ############################################################################### def buildlib(bldroot, installpath, case): ############################################################################### - # If we are using Trilinos, we must use the Kokkos that comes with it - if case.get_value("USE_TRILINOS"): - print ("You case is using Trilinos and will use its Kokkos") + # If we are using Albany/Trilinos, we must use the Kokkos that comes with it + if case.get_value("USE_ALBANY") or case.get_value("USE_TRILINOS"): + print ("case is using Trilinos and will use its Kokkos") return installed_kokkos_dir = os.environ.get("Kokkos_ROOT") From a913c76aa83755c5519961bfa05f1f5c755256f3 Mon Sep 17 00:00:00 2001 From: noel Date: Fri, 19 Jul 2024 12:49:36 -0700 Subject: [PATCH 247/451] update pm-cpu GNU compiler version to 12.2 --- cime_config/machines/config_machines.xml | 45 +++++++++++------------- 1 file changed, 21 insertions(+), 24 deletions(-) diff --git a/cime_config/machines/config_machines.xml b/cime_config/machines/config_machines.xml index a1cf8744de83..8187b49322e0 100644 --- a/cime_config/machines/config_machines.xml +++ b/cime_config/machines/config_machines.xml @@ -200,12 +200,13 @@ PrgEnv-nvidia PrgEnv-cray PrgEnv-aocc - intel + gcc-native intel-oneapi nvidia aocc cudatoolkit climate-utils + cray-libsci matlab craype-accel-nvidia80 craype-accel-host @@ -215,8 +216,8 @@ - PrgEnv-gnu/8.3.3 - gcc/11.2.0 + PrgEnv-gnu/8.5.0 + gcc/12.2.0 cray-libsci/23.02.1.1 @@ -282,8 +283,8 @@ $SHELL{if [ -z "$ADIOS2_ROOT" ]; then echo /global/cfs/cdirs/e3sm/3rdparty/adios2/2.9.1/cray-mpich-8.1.25/nvidia-22.7; else echo "$ADIOS2_ROOT"; fi} - $SHELL{if [ -z "$BLAS_ROOT" ]; then echo /opt/nvidia/hpc_sdk/Linux_x86_64/22.7/compilers; else echo "$BLAS_ROOT"; fi} - $SHELL{if [ -z "$LAPACK_ROOT" ]; then echo /opt/nvidia/hpc_sdk/Linux_x86_64/22.7/compilers; else echo "$LAPACK_ROOT"; fi} + $SHELL{if [ -z "$BLAS_ROOT" ]; then echo $NVIDIA_PATH/compilers; else echo "$BLAS_ROOT"; fi} + $SHELL{if [ -z "$LAPACK_ROOT" ]; then echo $NVIDIA_PATH/compilers; else echo "$LAPACK_ROOT"; fi} NVHPC @@ -508,12 +509,14 @@ PrgEnv-nvidia PrgEnv-cray PrgEnv-aocc + gcc-native intel intel-oneapi nvidia aocc cudatoolkit climate-utils + cray-libsci matlab craype-accel-nvidia80 craype-accel-host @@ -523,24 +526,19 @@ - PrgEnv-gnu/8.5.0 gcc-native/12.3 cray-libsci/23.12.5 - PrgEnv-intel/8.5.0 - intel/2023.2.0 + intel/2024.1.0 PrgEnv-nvidia - nvidia/23.9 + nvidia/24.5 cray-libsci/23.12.5 @@ -554,9 +552,6 @@ craype-accel-host craype/2.7.30 cray-mpich/8.1.28 - cray-hdf5-parallel/1.12.2.9 cray-netcdf-hdf5parallel/4.9.0.9 cray-parallel-netcdf/1.12.3.9 @@ -596,8 +591,8 @@ $SHELL{if [ -z "$ADIOS2_ROOT" ]; then echo /global/cfs/cdirs/e3sm/3rdparty/adios2/2.9.1/cray-mpich-8.1.25/nvidia-22.7; else echo "$ADIOS2_ROOT"; fi} - $SHELL{if [ -z "$BLAS_ROOT" ]; then echo /opt/nvidia/hpc_sdk/Linux_x86_64/22.7/compilers; else echo "$BLAS_ROOT"; fi} - $SHELL{if [ -z "$LAPACK_ROOT" ]; then echo /opt/nvidia/hpc_sdk/Linux_x86_64/22.7/compilers; else echo "$LAPACK_ROOT"; fi} + $SHELL{if [ -z "$BLAS_ROOT" ]; then echo $NVIDIA_PATH/compilers; else echo "$BLAS_ROOT"; fi} + $SHELL{if [ -z "$LAPACK_ROOT" ]; then echo $NVIDIA_PATH/compilers; else echo "$LAPACK_ROOT"; fi} NVHPC @@ -825,12 +820,14 @@ PrgEnv-nvidia PrgEnv-cray PrgEnv-aocc + gcc-native intel intel-oneapi nvidia aocc cudatoolkit climate-utils + cray-libsci matlab craype-accel-nvidia80 craype-accel-host @@ -852,24 +849,24 @@ PrgEnv-nvidia - nvidia/22.7 + nvidia/24.5 cray-libsci PrgEnv-aocc - aocc/4.0.0 + aocc/4.0.1 cray-libsci craype-accel-host cray-libsci - craype/2.7.21 - cray-mpich/8.1.26 - cray-hdf5-parallel/1.12.2.3 - cray-netcdf-hdf5parallel/4.9.0.3 - cray-parallel-netcdf/1.12.3.3 + craype/2.7.30 + cray-mpich/8.1.28 + cray-hdf5-parallel/1.12.2.9 + cray-netcdf-hdf5parallel/4.9.0.9 + cray-parallel-netcdf/1.12.3.9 cmake/3.24.3 From 29a415e48f6389dbde5be6fae58c3634dc1a6e42 Mon Sep 17 00:00:00 2001 From: noel Date: Fri, 19 Jul 2024 16:43:38 -0700 Subject: [PATCH 248/451] Add flag for 2 files to avoid hang with this newer 12.3 gnu compiler for certain DEBUG tests --- .../machines/Depends.muller-cpu.gnu.cmake | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/cime_config/machines/Depends.muller-cpu.gnu.cmake b/cime_config/machines/Depends.muller-cpu.gnu.cmake index 9ebd88ff8762..5c7331f979a9 100644 --- a/cime_config/machines/Depends.muller-cpu.gnu.cmake +++ b/cime_config/machines/Depends.muller-cpu.gnu.cmake @@ -8,6 +8,22 @@ if (NOT DEBUG) endforeach() endif() +# On pm-cpu (and muller-cpu), with gcc-native/12.3, we see hang with DEBUG runs of certain tests. +# https://github.com/E3SM-Project/E3SM/issues/6516 +# Currently, we have pm-cpu using gcc/12.2.0 which does not have this issue, but using muller-cpu to test 12.3 +# Turning off -O0 for these 2 files (by adding -O) at least avoids hang and will produce FPE in HOMME code +if (CMAKE_Fortran_COMPILER_VERSION VERSION_GREATER_EQUAL 12.3) + if (DEBUG) + set(ADJUST + eam/src/dynamics/se/inidat.F90 + eam/src/dynamics/se/dyn_comp.F90 + ) + foreach(ITEM IN LISTS ADJUST) + e3sm_add_flags("${ITEM}" "-O") + #e3sm_add_flags("${ITEM}" "-DNDEBUG -O") + endforeach() + endif() +endif() From c9ebe5061153f7702386d66aced823c098c6e75c Mon Sep 17 00:00:00 2001 From: noel Date: Fri, 19 Jul 2024 17:26:57 -0700 Subject: [PATCH 249/451] test with gcc-native on alvarez as well (though machine rarely available for testing) --- cime_config/machines/config_machines.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cime_config/machines/config_machines.xml b/cime_config/machines/config_machines.xml index 8187b49322e0..a07e369c969b 100644 --- a/cime_config/machines/config_machines.xml +++ b/cime_config/machines/config_machines.xml @@ -838,7 +838,7 @@ PrgEnv-gnu - gcc + gcc-native cray-libsci From 17e01c12eea0a380037d2cb1687db9021c09894c Mon Sep 17 00:00:00 2001 From: noel Date: Sat, 20 Jul 2024 18:49:15 -0700 Subject: [PATCH 250/451] correct accidental removal of a module unload statement --- cime_config/machines/config_machines.xml | 1 + 1 file changed, 1 insertion(+) diff --git a/cime_config/machines/config_machines.xml b/cime_config/machines/config_machines.xml index a07e369c969b..87cb120042a1 100644 --- a/cime_config/machines/config_machines.xml +++ b/cime_config/machines/config_machines.xml @@ -201,6 +201,7 @@ PrgEnv-cray PrgEnv-aocc gcc-native + intel intel-oneapi nvidia aocc From f78062d1a993acd389681c7f4445e45cc258f4bf Mon Sep 17 00:00:00 2001 From: Irena Vankova Date: Sun, 21 Jul 2024 17:56:52 -0600 Subject: [PATCH 251/451] make separate subroutines whenever subglacial needs to be in subroutine argument --- .../shared/mpas_ocn_surface_bulk_forcing.F | 79 ++++++++-- .../mpas-ocean/src/shared/mpas_ocn_tendency.F | 20 ++- .../src/shared/mpas_ocn_thick_surface_flux.F | 139 ++++++++++++++---- .../mpas_ocn_tracer_surface_flux_to_tend.F | 116 ++++++++++++--- 4 files changed, 291 insertions(+), 63 deletions(-) diff --git a/components/mpas-ocean/src/shared/mpas_ocn_surface_bulk_forcing.F b/components/mpas-ocean/src/shared/mpas_ocn_surface_bulk_forcing.F index 2cf79881a7f8..168f8c31e279 100644 --- a/components/mpas-ocean/src/shared/mpas_ocn_surface_bulk_forcing.F +++ b/components/mpas-ocean/src/shared/mpas_ocn_surface_bulk_forcing.F @@ -49,7 +49,8 @@ module ocn_surface_bulk_forcing public :: ocn_surface_bulk_forcing_tracers, & ocn_surface_bulk_forcing_vel, & ocn_surface_bulk_forcing_thick, & - ocn_surface_bulk_forcing_init + ocn_surface_bulk_forcing_init, & + ocn_surface_bulk_forcing_thick_subglacial_runoff !-------------------------------------------------------------------- ! @@ -281,7 +282,7 @@ end subroutine ocn_surface_bulk_forcing_vel!}}} ! !----------------------------------------------------------------------- - subroutine ocn_surface_bulk_forcing_thick(forcingPool, surfaceThicknessFlux, surfaceThicknessFluxRunoff, surfaceThicknessFluxSubglacialRunoff, err)!{{{ + subroutine ocn_surface_bulk_forcing_thick(forcingPool, surfaceThicknessFlux, surfaceThicknessFluxRunoff, err)!{{{ !----------------------------------------------------------------- ! @@ -292,8 +293,6 @@ subroutine ocn_surface_bulk_forcing_thick(forcingPool, surfaceThicknessFlux, sur real (kind=RKIND), dimension(:), intent(inout) :: surfaceThicknessFlux !< Input/Output: Array for surface thickness flux real (kind=RKIND), dimension(:), intent(inout) :: & surfaceThicknessFluxRunoff !< Input/Output: Array for surface thickness flux due to river runoff - real (kind=RKIND), dimension(:), intent(inout) :: & - surfaceThicknessFluxSubglacialRunoff !< Input/Output: Array for surface thickness flux due to subglacial runoff !----------------------------------------------------------------- ! @@ -313,7 +312,6 @@ subroutine ocn_surface_bulk_forcing_thick(forcingPool, surfaceThicknessFlux, sur real (kind=RKIND), dimension(:), pointer :: evaporationFlux, snowFlux real (kind=RKIND), dimension(:), pointer :: seaIceFreshWaterFlux, icebergFreshWaterFlux, riverRunoffFlux, iceRunoffFlux - real (kind=RKIND), dimension(:), pointer :: subglacialRunoffFlux real (kind=RKIND), dimension(:), pointer :: rainFlux err = 0 @@ -327,7 +325,6 @@ subroutine ocn_surface_bulk_forcing_thick(forcingPool, surfaceThicknessFlux, sur call mpas_pool_get_array(forcingPool, 'seaIceFreshWaterFlux', seaIceFreshWaterFlux) call mpas_pool_get_array(forcingPool, 'icebergFreshWaterFlux', icebergFreshWaterFlux) call mpas_pool_get_array(forcingPool, 'riverRunoffFlux', riverRunoffFlux) - call mpas_pool_get_array(forcingPool, 'subglacialRunoffFlux', subglacialRunoffFlux) call mpas_pool_get_array(forcingPool, 'iceRunoffFlux', iceRunoffFlux) call mpas_pool_get_array(forcingPool, 'rainFlux', rainFlux) @@ -357,7 +354,68 @@ subroutine ocn_surface_bulk_forcing_thick(forcingPool, surfaceThicknessFlux, sur !$omp end parallel #endif - if (trim(config_subglacial_runoff_mode) == 'data') then +#ifdef MPAS_OPENACC + !$acc exit data delete(evaporationFlux, snowFlux, seaIceFreshWaterFlux, icebergFreshWaterFlux, & + !$acc riverRunoffFlux, iceRunoffFlux, rainFlux) +#endif + + call mpas_timer_stop("bulk_thick") + + end subroutine ocn_surface_bulk_forcing_thick!}}} + +!*********************************************************************** +! +! routine ocn_surface_bulk_forcing_thick_subglacial_runoff +! +!> \brief Determines the thickness forcing array used for the bulk forcing. +!> \author Doug Jacobsen +!> \date 04/25/12 +!> \details +!> This routine computes the thickness forcing arrays used later in MPAS. +! +!----------------------------------------------------------------------- + + subroutine ocn_surface_bulk_forcing_thick_subglacial_runoff(forcingPool, surfaceThicknessFluxSubglacialRunoff, err)!{{{ + + !----------------------------------------------------------------- + ! + ! input/output variables + ! + !----------------------------------------------------------------- + type (mpas_pool_type), intent(inout) :: forcingPool !< Input: Forcing information + real (kind=RKIND), dimension(:), intent(inout) :: & + surfaceThicknessFluxSubglacialRunoff !< Input/Output: Array for surface thickness flux due to subglacial runoff + + !----------------------------------------------------------------- + ! + ! output variables + ! + !----------------------------------------------------------------- + + integer, intent(out) :: err !< Output: Error flag + + !----------------------------------------------------------------- + ! + ! local variables + ! + !----------------------------------------------------------------- + + integer :: iCell, nCells + + real (kind=RKIND), dimension(:), pointer :: subglacialRunoffFlux + + err = 0 + + if (bulkThicknessFluxOff) return + + call mpas_timer_start("bulk_thick", .false.) + + call mpas_pool_get_array(forcingPool, 'subglacialRunoffFlux', subglacialRunoffFlux) + + nCells = nCellsHalo( 2 ) + + ! Build surface fluxes at cell centers + #ifdef MPAS_OPENACC !$acc enter data copyin(subglacialRunoffFlux) @@ -374,16 +432,15 @@ subroutine ocn_surface_bulk_forcing_thick(forcingPool, surfaceThicknessFlux, sur !$omp end do !$omp end parallel #endif - end if #ifdef MPAS_OPENACC - !$acc exit data delete(evaporationFlux, snowFlux, seaIceFreshWaterFlux, icebergFreshWaterFlux, & - !$acc riverRunoffFlux, subglacialRunoffFlux, iceRunoffFlux, rainFlux) + !$acc exit data delete(subglacialRunoffFlux) #endif call mpas_timer_stop("bulk_thick") - end subroutine ocn_surface_bulk_forcing_thick!}}} + end subroutine ocn_surface_bulk_forcing_thick_subglacial_runoff!}}} + !*********************************************************************** ! diff --git a/components/mpas-ocean/src/shared/mpas_ocn_tendency.F b/components/mpas-ocean/src/shared/mpas_ocn_tendency.F index c6d9e72f83a9..e3f47d1316b0 100644 --- a/components/mpas-ocean/src/shared/mpas_ocn_tendency.F +++ b/components/mpas-ocean/src/shared/mpas_ocn_tendency.F @@ -220,8 +220,12 @@ subroutine ocn_tend_thick(tendPool, forcingPool)!{{{ ! Compute surface mass flux array from bulk forcing call ocn_surface_bulk_forcing_thick(forcingPool, & surfaceThicknessFlux, & - surfaceThicknessFluxRunoff, & + surfaceThicknessFluxRunoff, err) + + if (trim(config_subglacial_runoff_mode) == 'data') then + call ocn_surface_bulk_forcing_thick_subglacial_runoff(forcingPool, & surfaceThicknessFluxSubglacialRunoff, err) + end if ! Compute surface thickness flux from land ice call ocn_surface_land_ice_fluxes_thick(forcingPool, & @@ -242,11 +246,14 @@ subroutine ocn_tend_thick(tendPool, forcingPool)!{{{ ! Compute surface flux tendency call ocn_thick_surface_flux_tend(fractionAbsorbed, & fractionAbsorbedRunoff, & - fractionAbsorbedSubglacialRunoff, & surfaceThicknessFlux, & surfaceThicknessFluxRunoff, & + tendThick, err) + if (trim(config_subglacial_runoff_mode) == 'data') then + call ocn_thick_surface_flux_tend(fractionAbsorbedSubglacialRunoff, & surfaceThicknessFluxSubglacialRunoff, & tendThick, err) + end if ! Compute contribution from frazil ice formation call ocn_frazil_forcing_layer_thickness(forcingPool, & @@ -1244,10 +1251,15 @@ subroutine ocn_tend_tracer(tendPool, statePool, forcingPool, & endif ! compute budgets call ocn_tracer_surface_flux_tend(meshPool, fractionAbsorbed, & - fractionAbsorbedRunoff, fractionAbsorbedSubglacialRunoff, & + fractionAbsorbedRunoff, & layerThickness, tracerGroupSurfaceFlux, & - tracerGroupSurfaceFluxRunoff, tracerGroupSurfaceFluxSubglacialRunoff, & + tracerGroupSurfaceFluxRunoff, & + tracerGroupTend, err) + if (trim(config_subglacial_runoff_mode) == 'data') then + call ocn_tracer_surface_flux_tend(meshPool, fractionAbsorbedSubglacialRunoff, & + layerThickness, tracerGroupSurfaceFluxSubglacialRunoff, & tracerGroupTend, err) + end if ! ! Compute shortwave absorption diff --git a/components/mpas-ocean/src/shared/mpas_ocn_thick_surface_flux.F b/components/mpas-ocean/src/shared/mpas_ocn_thick_surface_flux.F index eb531a999582..8e389a74ba37 100644 --- a/components/mpas-ocean/src/shared/mpas_ocn_thick_surface_flux.F +++ b/components/mpas-ocean/src/shared/mpas_ocn_thick_surface_flux.F @@ -46,7 +46,8 @@ module ocn_thick_surface_flux !-------------------------------------------------------------------- public :: ocn_thick_surface_flux_tend, & - ocn_thick_surface_flux_init + ocn_thick_surface_flux_init, & + ocn_thick_surface_flux_tend_subglacial_runoff !-------------------------------------------------------------------- ! @@ -74,8 +75,7 @@ module ocn_thick_surface_flux !----------------------------------------------------------------------- subroutine ocn_thick_surface_flux_tend(transmissionCoefficients, transmissionCoefficientsRunoff, & - transmissionCoefficientsSubglacialRunoff, surfaceThicknessFlux, surfaceThicknessFluxRunoff, & - surfaceThicknessFluxSubglacialRunoff, tend, err)!{{{ + surfaceThicknessFlux, surfaceThicknessFluxRunoff, tend, err)!{{{ !----------------------------------------------------------------- ! ! input variables @@ -84,13 +84,11 @@ subroutine ocn_thick_surface_flux_tend(transmissionCoefficients, transmissionCoe real (kind=RKIND), dimension(:,:), intent(in) :: & transmissionCoefficients, &!< Input: Coefficients for the transmission of surface fluxes - transmissionCoefficientsRunoff, &!< Input: Coefficients for the transmission of surface fluxes due to river runoff - transmissionCoefficientsSubglacialRunoff !< Input: Coefficients for the transmission of surface fluxes due to subglacial runoff + transmissionCoefficientsRunoff !< Input: Coefficients for the transmission of surface fluxes due to river runoff real (kind=RKIND), dimension(:), intent(in) :: & - surfaceThicknessFlux, &!< Input: surface flux of thickness - surfaceThicknessFluxRunoff, &!< Input: surface flux of thickness due to river runoff - surfaceThicknessFluxSubglacialRunoff !< Input: surface flux of thickness due to subglacial runoff + surfaceThicknessFlux, &!< Input: surface flux of thickness + surfaceThicknessFluxRunoff !< Input: surface flux of thickness due to river runoff !----------------------------------------------------------------- @@ -118,7 +116,7 @@ subroutine ocn_thick_surface_flux_tend(transmissionCoefficients, transmissionCoe integer :: iCell, k - real (kind=RKIND) :: remainingFlux, remainingFluxRunoff, remainingFluxSubglacialRunoff + real (kind=RKIND) :: remainingFlux, remainingFluxRunoff err = 0 @@ -127,32 +125,24 @@ subroutine ocn_thick_surface_flux_tend(transmissionCoefficients, transmissionCoe call mpas_timer_start("thick surface flux") #ifdef MPAS_OPENACC - !$acc enter data copyin(transmissionCoefficients, transmissionCoefficientsRunoff, transmissionCoefficientsSubglacialRunoff) + !$acc enter data copyin(transmissionCoefficients, transmissionCoefficientsRunoff) !$acc parallel loop & !$acc present(tend, surfaceThicknessFlux, surfaceThicknessFluxRunoff, & - !$acc surfaceThicknessFluxSubglacialRunoff, transmissionCoefficientsSubglacialRunoff, & !$acc transmissionCoefficients, transmissionCoefficientsRunoff, minLevelCell, maxLevelCell) & - !$acc private(k, remainingFlux, remainingFluxRunoff, remainingFluxSubglacialRunoff) + !$acc private(k, remainingFlux, remainingFluxRunoff) #else !$omp parallel - !$omp do schedule(runtime) private(remainingFlux, remainingFluxRunoff, remainingFluxSubglacialRunoff, k) + !$omp do schedule(runtime) private(remainingFlux, remainingFluxRunoff, k) #endif do iCell = 1, nCellsOwned remainingFlux = 1.0_RKIND remainingFluxRunoff = 1.0_RKIND - if (trim(config_subglacial_runoff_mode) == 'data') then - remainingFluxSubglacialRunoff = 1.0_RKIND - end if do k = minLevelCell(iCell), maxLevelCell(iCell) remainingFlux = remainingFlux - transmissionCoefficients(k, iCell) remainingFluxRunoff = remainingFluxRunoff - transmissionCoefficientsRunoff(k, iCell) tend(k, iCell) = tend(k, iCell) + surfaceThicknessFlux(iCell) * transmissionCoefficients(k, iCell) & + surfaceThicknessFluxRunoff(iCell) * transmissionCoefficientsRunoff(k, iCell) - if (trim(config_subglacial_runoff_mode) == 'data') then - remainingFluxSubglacialRunoff = remainingFluxSubglacialRunoff - transmissionCoefficientsSubglacialRunoff(k, iCell) - tend(k, iCell) = tend(k, iCell) + surfaceThicknessFluxSubglacialRunoff(iCell) * transmissionCoefficientsSubglacialRunoff(k, iCell) - end if end do if(maxLevelCell(iCell) > 0 .and. remainingFlux > 0.0_RKIND) then @@ -164,12 +154,6 @@ subroutine ocn_thick_surface_flux_tend(transmissionCoefficients, transmissionCoe + remainingFluxRunoff * surfaceThicknessFluxRunoff(iCell) end if - if (trim(config_subglacial_runoff_mode) == 'data') then - if(maxLevelCell(iCell) > 0 .and. remainingFluxSubglacialRunoff > 0.0_RKIND) then - tend(maxLevelCell(iCell), iCell) = tend(maxLevelCell(iCell), iCell) & - + remainingFluxSubglacialRunoff * surfaceThicknessFluxSubglacialRunoff(iCell) - end if - end if end do #ifndef MPAS_OPENACC !$omp end do @@ -177,7 +161,7 @@ subroutine ocn_thick_surface_flux_tend(transmissionCoefficients, transmissionCoe #endif #ifdef MPAS_OPENACC - !$acc exit data delete(transmissionCoefficients, transmissionCoefficientsRunoff, transmissionCoefficientsSubglacialRunoff) + !$acc exit data delete(transmissionCoefficients, transmissionCoefficientsRunoff) #endif call mpas_timer_stop("thick surface flux") @@ -186,6 +170,107 @@ subroutine ocn_thick_surface_flux_tend(transmissionCoefficients, transmissionCoe end subroutine ocn_thick_surface_flux_tend!}}} +!*********************************************************************** +! +! routine ocn_thick_surface_flux_tend_subglacial_runoff +! +!> \brief Computes tendency term from horizontal advection of thickness +!> \author Doug Jacobsen +!> \date 15 September 2011 +!> \details +!> This routine computes the horizontal advection tendency for +!> thickness based on current state and user choices of forcings. +! +!----------------------------------------------------------------------- + + subroutine ocn_thick_surface_flux_tend_subglacial_runoff(transmissionCoefficientsSubglacialRunoff, & + surfaceThicknessFluxSubglacialRunoff, tend, err)!{{{ + !----------------------------------------------------------------- + ! + ! input variables + ! + !----------------------------------------------------------------- + + real (kind=RKIND), dimension(:,:), intent(in) :: & + transmissionCoefficientsSubglacialRunoff !< Input: Coefficients for the transmission of surface fluxes due to subglacial runoff + + real (kind=RKIND), dimension(:), intent(in) :: & + surfaceThicknessFluxSubglacialRunoff !< Input: surface flux of thickness due to subglacial runoff + + + !----------------------------------------------------------------- + ! + ! input/output variables + ! + !----------------------------------------------------------------- + + real (kind=RKIND), dimension(:,:), intent(inout) :: & + tend !< Input/Output: thickness tendency + + !----------------------------------------------------------------- + ! + ! output variables + ! + !----------------------------------------------------------------- + + integer, intent(out) :: err !< Output: error flag + + !----------------------------------------------------------------- + ! + ! local variables + ! + !----------------------------------------------------------------- + + integer :: iCell, k + + real (kind=RKIND) :: remainingFlux, remainingFluxRunoff, remainingFluxSubglacialRunoff + + err = 0 + + if (.not. surfaceThicknessFluxOn) return + + call mpas_timer_start("thick surface flux") + +#ifdef MPAS_OPENACC + !$acc enter data copyin(transmissionCoefficientsSubglacialRunoff) + + !$acc parallel loop & + !$acc present(tend, & + !$acc surfaceThicknessFluxSubglacialRunoff, transmissionCoefficientsSubglacialRunoff, & + !$acc minLevelCell, maxLevelCell) & + !$acc private(k, remainingFluxSubglacialRunoff) +#else + !$omp parallel + !$omp do schedule(runtime) private(remainingFluxSubglacialRunoff, k) +#endif + do iCell = 1, nCellsOwned + remainingFluxSubglacialRunoff = 1.0_RKIND + do k = minLevelCell(iCell), maxLevelCell(iCell) + remainingFluxSubglacialRunoff = remainingFluxSubglacialRunoff - transmissionCoefficientsSubglacialRunoff(k, iCell) + tend(k, iCell) = tend(k, iCell) + surfaceThicknessFluxSubglacialRunoff(iCell) * transmissionCoefficientsSubglacialRunoff(k, iCell) + end do + + if(maxLevelCell(iCell) > 0 .and. remainingFluxSubglacialRunoff > 0.0_RKIND) then + tend(maxLevelCell(iCell), iCell) = tend(maxLevelCell(iCell), iCell) & + + remainingFluxSubglacialRunoff * surfaceThicknessFluxSubglacialRunoff(iCell) + end if + + end do +#ifndef MPAS_OPENACC + !$omp end do + !$omp end parallel +#endif + +#ifdef MPAS_OPENACC + !$acc exit data delete(transmissionCoefficientsSubglacialRunoff) +#endif + + call mpas_timer_stop("thick surface flux") + + !-------------------------------------------------------------------- + + end subroutine ocn_thick_surface_flux_tend_subglacial_runoff!}}} + !*********************************************************************** ! ! routine ocn_thick_surface_flux_init diff --git a/components/mpas-ocean/src/shared/mpas_ocn_tracer_surface_flux_to_tend.F b/components/mpas-ocean/src/shared/mpas_ocn_tracer_surface_flux_to_tend.F index 4a1dc5fce098..fd754562a579 100644 --- a/components/mpas-ocean/src/shared/mpas_ocn_tracer_surface_flux_to_tend.F +++ b/components/mpas-ocean/src/shared/mpas_ocn_tracer_surface_flux_to_tend.F @@ -45,7 +45,8 @@ module ocn_tracer_surface_flux_to_tend !-------------------------------------------------------------------- public :: ocn_tracer_surface_flux_tend, & - ocn_tracer_surface_flux_init + ocn_tracer_surface_flux_init, & + ocn_tracer_surface_flux_tend_subglacial_runoff !-------------------------------------------------------------------- ! @@ -71,8 +72,8 @@ module ocn_tracer_surface_flux_to_tend ! !----------------------------------------------------------------------- - subroutine ocn_tracer_surface_flux_tend(meshPool, fractionAbsorbed, fractionAbsorbedRunoff, fractionAbsorbedSubglacialRunoff, & - layerThickness, surfaceTracerFlux, surfaceTracerFluxRunoff, surfaceTracerFluxSubglacialRunoff, tend, err)!{{{ + subroutine ocn_tracer_surface_flux_tend(meshPool, fractionAbsorbed, fractionAbsorbedRunoff, & + layerThickness, surfaceTracerFlux, surfaceTracerFluxRunoff, tend, err)!{{{ !----------------------------------------------------------------- ! ! input variables @@ -97,13 +98,6 @@ subroutine ocn_tracer_surface_flux_tend(meshPool, fractionAbsorbed, fractionAbso real (kind=RKIND), dimension(:,:), intent(in) :: & fractionAbsorbedRunoff !< Input: Coefficients for the application of surface fluxes due to river runoff - real (kind=RKIND), dimension(:,:), intent(in), pointer :: & - surfaceTracerFluxSubglacialRunoff !< Input: surface tracer fluxes from subglacial runoff - - real (kind=RKIND), dimension(:,:), intent(in) :: & - fractionAbsorbedSubglacialRunoff !< Input: Coefficients for the application of surface fluxes due to subglacial runoff - - !----------------------------------------------------------------- ! ! input/output variables @@ -204,14 +198,96 @@ subroutine ocn_tracer_surface_flux_tend(meshPool, fractionAbsorbed, fractionAbso call mpas_timer_stop("surface_tracer_runoff_flux") end if + !-------------------------------------------------------------------- + + end subroutine ocn_tracer_surface_flux_tend!}}} + + +!*********************************************************************** +! +! routine ocn_tracer_surface_flux_tend_subglacial_runoff +! +!> \brief Computes tendency term for surface fluxes +!> \author Doug Jacobsen +!> \date 12/17/12 +!> \details +!> This routine computes the tendency for tracers based on surface fluxes. +! +!----------------------------------------------------------------------- + + subroutine ocn_tracer_surface_flux_tend_subglacial_runoff(meshPool, fractionAbsorbedSubglacialRunoff, & + layerThickness, surfaceTracerFluxSubglacialRunoff, tend, err)!{{{ + !----------------------------------------------------------------- + ! + ! input variables + ! + !----------------------------------------------------------------- + + type (mpas_pool_type), intent(in) :: & + meshPool !< Input: mesh information + + real (kind=RKIND), dimension(:,:), intent(in) :: & + layerThickness !< Input: Layer thickness + + real (kind=RKIND), dimension(:,:), intent(in), pointer :: & + surfaceTracerFluxSubglacialRunoff !< Input: surface tracer fluxes from subglacial runoff + + real (kind=RKIND), dimension(:,:), intent(in) :: & + fractionAbsorbedSubglacialRunoff !< Input: Coefficients for the application of surface fluxes due to subglacial runoff + + + !----------------------------------------------------------------- + ! + ! input/output variables + ! + !----------------------------------------------------------------- + + real (kind=RKIND), dimension(:,:,:), intent(inout) :: & + tend !< Input/Output: velocity tendency + + !----------------------------------------------------------------- + ! + ! output variables + ! + !----------------------------------------------------------------- + + integer, intent(out) :: err !< Output: error flag + + !----------------------------------------------------------------- + ! + ! local variables + ! + !----------------------------------------------------------------- + + integer :: iCell, k, iTracer, nTracers, nCells + integer, pointer :: nVertLevels + integer, dimension(:), pointer :: nCellsArray + integer, dimension(:), pointer :: minLevelCell, maxLevelCell + + real (kind=RKIND) :: remainingFlux + + err = 0 + + if (.not. surfaceTracerFluxOn) return + + call mpas_timer_start("surface_tracer_flux") + + call mpas_pool_get_dimension(meshPool, 'nCellsArray', nCellsArray) + call mpas_pool_get_dimension(meshPool, 'nVertLevels', nVertLevels) + nTracers = size(tend, dim=1) + + call mpas_pool_get_array(meshPool, 'minLevelCell', minLevelCell) + call mpas_pool_get_array(meshPool, 'maxLevelCell', maxLevelCell) + + nCells = nCellsArray( 1 ) + ! now do subglacial runoff component - if (trim(config_subglacial_runoff_mode) == 'data') then - call mpas_timer_start("surface_tracer_subglacial_runoff_flux") + call mpas_timer_start("surface_tracer_subglacial_runoff_flux") - !$omp parallel - !$omp do schedule(runtime) private(remainingFlux, k, iTracer) - do iCell = 1, nCells + !$omp parallel + !$omp do schedule(runtime) private(remainingFlux, k, iTracer) + do iCell = 1, nCells remainingFlux = 1.0_RKIND do k = minLevelCell(iCell), maxLevelCell(iCell) remainingFlux = remainingFlux - fractionAbsorbedSubglacialRunoff(k, iCell) @@ -228,15 +304,13 @@ subroutine ocn_tracer_surface_flux_tend(meshPool, fractionAbsorbed, fractionAbso + surfaceTracerFluxSubglacialRunoff(iTracer, iCell) * remainingFlux end do end if - end do - !$omp end do - !$omp end parallel + end do + !$omp end do + !$omp end parallel - call mpas_timer_stop("surface_tracer_subglacial_runoff_flux") - end if !-------------------------------------------------------------------- - end subroutine ocn_tracer_surface_flux_tend!}}} + end subroutine ocn_tracer_surface_flux_tend_subglacial_runoff!}}} !*********************************************************************** ! From 9ff4253ce41be1da822001d6cb7f3208e0a92260 Mon Sep 17 00:00:00 2001 From: Irena Vankova Date: Sun, 21 Jul 2024 18:53:48 -0600 Subject: [PATCH 252/451] fix function call typos --- components/mpas-ocean/src/shared/mpas_ocn_tendency.F | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/components/mpas-ocean/src/shared/mpas_ocn_tendency.F b/components/mpas-ocean/src/shared/mpas_ocn_tendency.F index e3f47d1316b0..b855512fb294 100644 --- a/components/mpas-ocean/src/shared/mpas_ocn_tendency.F +++ b/components/mpas-ocean/src/shared/mpas_ocn_tendency.F @@ -250,7 +250,7 @@ subroutine ocn_tend_thick(tendPool, forcingPool)!{{{ surfaceThicknessFluxRunoff, & tendThick, err) if (trim(config_subglacial_runoff_mode) == 'data') then - call ocn_thick_surface_flux_tend(fractionAbsorbedSubglacialRunoff, & + call ocn_thick_surface_flux_tend_subglacial_runoff(fractionAbsorbedSubglacialRunoff, & surfaceThicknessFluxSubglacialRunoff, & tendThick, err) end if @@ -1256,7 +1256,7 @@ subroutine ocn_tend_tracer(tendPool, statePool, forcingPool, & tracerGroupSurfaceFluxRunoff, & tracerGroupTend, err) if (trim(config_subglacial_runoff_mode) == 'data') then - call ocn_tracer_surface_flux_tend(meshPool, fractionAbsorbedSubglacialRunoff, & + call ocn_tracer_surface_flux_tend_subglacial_runoff(meshPool, fractionAbsorbedSubglacialRunoff, & layerThickness, tracerGroupSurfaceFluxSubglacialRunoff, & tracerGroupTend, err) end if From 767332e820ff3656bb9a916984b355139c216fdb Mon Sep 17 00:00:00 2001 From: Naser Mahfouz Date: Sun, 21 Jul 2024 17:10:56 -0400 Subject: [PATCH 253/451] upgrade e3sm-imgs to 0.0.9 and add singularity2 --- .github/workflows/e3sm-gh-ci-cime-tests.yml | 18 ++++---- .github/workflows/e3sm-gh-ci-w-cime-tests.yml | 18 ++++---- cime_config/machines/config_machines.xml | 45 +++++++++++++++++++ 3 files changed, 63 insertions(+), 18 deletions(-) diff --git a/.github/workflows/e3sm-gh-ci-cime-tests.yml b/.github/workflows/e3sm-gh-ci-cime-tests.yml index 366fef018f20..b90ed2f01198 100644 --- a/.github/workflows/e3sm-gh-ci-cime-tests.yml +++ b/.github/workflows/e3sm-gh-ci-cime-tests.yml @@ -27,16 +27,16 @@ jobs: fail-fast: false matrix: test: - - SMS_D_P4.ne4pg2_oQU480.F2010.singularity_gnu - - SMS_P4.ne4pg2_oQU480.F2010.singularity_gnu - - REP_P4.ne4pg2_oQU480.F2010.singularity_gnu - - ERS_P4.ne4pg2_oQU480.F2010.singularity_gnu - - ERS_P4.ne4pg2_oQU480.F2010.singularity_gnu.eam-wcprod_F2010 - - ERP_P4.ne4pg2_oQU480.F2010.singularity_gnu - - PET_P4.ne4pg2_oQU480.F2010.singularity_gnu - - PEM_P4.ne4pg2_oQU480.F2010.singularity_gnu + - SMS_D_P4.ne4pg2_oQU480.F2010.singularity2_gnu + - SMS_P4.ne4pg2_oQU480.F2010.singularity2_gnu + - REP_P4.ne4pg2_oQU480.F2010.singularity2_gnu + - ERS_P4.ne4pg2_oQU480.F2010.singularity2_gnu + - ERS_P4.ne4pg2_oQU480.F2010.singularity2_gnu.eam-wcprod_F2010 + - ERP_P4.ne4pg2_oQU480.F2010.singularity2_gnu + - PET_P4.ne4pg2_oQU480.F2010.singularity2_gnu + - PEM_P4.ne4pg2_oQU480.F2010.singularity2_gnu container: - image: ghcr.io/mahf708/e3sm-imgs:v0.0.6 + image: ghcr.io/mahf708/e3sm-imgs:v0.0.9 steps: - diff --git a/.github/workflows/e3sm-gh-ci-w-cime-tests.yml b/.github/workflows/e3sm-gh-ci-w-cime-tests.yml index 595518c326d7..c24604d4ad0e 100644 --- a/.github/workflows/e3sm-gh-ci-w-cime-tests.yml +++ b/.github/workflows/e3sm-gh-ci-w-cime-tests.yml @@ -19,16 +19,16 @@ jobs: fail-fast: false matrix: test: - - SMS_D_P8.ne4pg2_oQU480.WCYCL2010NS.singularity_gnu - - SMS_P8.ne4pg2_oQU480.WCYCL2010NS.singularity_gnu - - REP_P8.ne4pg2_oQU480.WCYCL2010NS.singularity_gnu - - ERS_P8.ne4pg2_oQU480.WCYCL2010NS.singularity_gnu - - ERS_P8.ne4pg2_oQU480.WCYCL2010NS.singularity_gnu.allactive-wcprod_1850 - - ERP_P8.ne4pg2_oQU480.WCYCL2010NS.singularity_gnu - - PET_P8.ne4pg2_oQU480.WCYCL2010NS.singularity_gnu - - PEM_P8.ne4pg2_oQU480.WCYCL2010NS.singularity_gnu + - SMS_D_P8.ne4pg2_oQU480.WCYCL2010NS.singularity2_gnu + - SMS_P8.ne4pg2_oQU480.WCYCL2010NS.singularity2_gnu + - REP_P8.ne4pg2_oQU480.WCYCL2010NS.singularity2_gnu + - ERS_P8.ne4pg2_oQU480.WCYCL2010NS.singularity2_gnu + - ERS_P8.ne4pg2_oQU480.WCYCL2010NS.singularity2_gnu.allactive-wcprod_1850 + - ERP_P8.ne4pg2_oQU480.WCYCL2010NS.singularity2_gnu + - PET_P8.ne4pg2_oQU480.WCYCL2010NS.singularity2_gnu + - PEM_P8.ne4pg2_oQU480.WCYCL2010NS.singularity2_gnu container: - image: ghcr.io/mahf708/e3sm-imgs:v0.0.6 + image: ghcr.io/mahf708/e3sm-imgs:v0.0.9 steps: - diff --git a/cime_config/machines/config_machines.xml b/cime_config/machines/config_machines.xml index a1cf8744de83..5b97ab58626d 100644 --- a/cime_config/machines/config_machines.xml +++ b/cime_config/machines/config_machines.xml @@ -1714,6 +1714,51 @@ + + Singularity container 2.0 + singularity2 + LINUX + gnu + mpich + $ENV{HOME}/projects/e3sm/scratch + $ENV{HOME}/projects/e3sm/cesm-inputdata + $ENV{HOME}/projects/e3sm/ptclm-data + $ENV{HOME}/projects/e3sm/scratch/archive/$CASE + $ENV{HOME}/projects/e3sm/baselines/$COMPILER + /usr/local/packages/bin/cprnc + make + 4 + e3sm_developer + none + e3sm-team + 16 + 16 + + mpirun + + -launcher fork -hosts localhost -np {{ total_tasks }} + + + + $ENV{HOME}/projects/e3sm/scratch/$CASE/run + $ENV{HOME}/projects/e3sm/scratch/$CASE/bld + + $SRCROOT + + + /usr/local/packages + /usr/local/packages/bin:$ENV{PATH} + /usr/local/packages/lib + + + /usr/local/packages + /usr/local/packages + /usr/local/packages + /usr/local/packages/bin:$ENV{PATH} + /usr/local/packages/lib + + + Linux workstation for Jenkins testing (melvin|watson|s999964|climate|penn|sems) From 476908cbf811143a1066833171c2b1c9f250f925 Mon Sep 17 00:00:00 2001 From: Irena Vankova Date: Sun, 21 Jul 2024 21:15:47 -0600 Subject: [PATCH 254/451] more new subrutines with _subglacial_runoff --- .../shared/mpas_ocn_surface_bulk_forcing.F | 218 +++++++++++++++--- .../mpas-ocean/src/shared/mpas_ocn_tendency.F | 6 +- 2 files changed, 187 insertions(+), 37 deletions(-) diff --git a/components/mpas-ocean/src/shared/mpas_ocn_surface_bulk_forcing.F b/components/mpas-ocean/src/shared/mpas_ocn_surface_bulk_forcing.F index 168f8c31e279..81732b637a97 100644 --- a/components/mpas-ocean/src/shared/mpas_ocn_surface_bulk_forcing.F +++ b/components/mpas-ocean/src/shared/mpas_ocn_surface_bulk_forcing.F @@ -50,8 +50,10 @@ module ocn_surface_bulk_forcing ocn_surface_bulk_forcing_vel, & ocn_surface_bulk_forcing_thick, & ocn_surface_bulk_forcing_init, & + ocn_surface_bulk_forcing_tracers_subglacial_runoff, & ocn_surface_bulk_forcing_thick_subglacial_runoff + !-------------------------------------------------------------------- ! ! Private module variables @@ -79,7 +81,7 @@ module ocn_surface_bulk_forcing !----------------------------------------------------------------------- subroutine ocn_surface_bulk_forcing_tracers(meshPool, groupName, forcingPool, tracerGroup, & - tracersSurfaceFlux, tracersSurfaceFluxRunoff, tracersSurfaceFluxSubglacialRunoff, tracersSurfaceFluxRemoved, dt, layerThickness, err)!{{{ + tracersSurfaceFlux, tracersSurfaceFluxRunoff, tracersSurfaceFluxRemoved, dt, layerThickness, err)!{{{ !----------------------------------------------------------------- ! @@ -99,8 +101,6 @@ subroutine ocn_surface_bulk_forcing_tracers(meshPool, groupName, forcingPool, tr real (kind=RKIND), dimension(:,:), intent(inout) :: tracersSurfaceFlux !< Input/Output: Surface flux for tracer group real (kind=RKIND), dimension(:,:), intent(inout) :: & tracersSurfaceFluxRunoff !< Input/Output: Surface flux for tracer group due to river runoff - real (kind=RKIND), dimension(:,:), intent(inout) :: & - tracersSurfaceFluxSubglacialRunoff !< Input/Output: Surface flux for tracer group due to subglacial runoff real (kind=RKIND), dimension(:,:), intent(inout) :: & tracersSurfaceFluxRemoved !< Input/Output: Accumulator for ignored Surface flux for tracer group real (kind=RKIND), dimension(:,:), intent(in) :: layerThickness @@ -125,12 +125,69 @@ subroutine ocn_surface_bulk_forcing_tracers(meshPool, groupName, forcingPool, tr call mpas_timer_start("bulk_" // trim(groupName)) if ( trim(groupName) == 'activeTracers' ) then call ocn_surface_bulk_forcing_active_tracers(meshPool, forcingPool, tracerGroup, & - tracersSurfaceFlux, tracersSurfaceFluxRunoff, tracersSurfaceFluxSubglacialRunoff, tracersSurfaceFluxRemoved, layerThickness, dt, err) + tracersSurfaceFlux, tracersSurfaceFluxRunoff, tracersSurfaceFluxRemoved, layerThickness, dt, err) end if call mpas_timer_stop("bulk_" // trim(groupName)) end subroutine ocn_surface_bulk_forcing_tracers!}}} +!*********************************************************************** +! +! routine ocn_surface_bulk_forcing_tracers_subglacial_runoff +! +!> \brief Determines the tracers forcing array used for the bulk forcing. +!> \author Doug Jacobsen +!> \date 04/25/12 +!> \details +!> This routine computes the tracers forcing arrays used later in MPAS. +! +!----------------------------------------------------------------------- + + subroutine ocn_surface_bulk_forcing_tracers_subglacial_runoff(meshPool, groupName, forcingPool, & + tracersSurfaceFluxSubglacialRunoff, err)!{{{ + + !----------------------------------------------------------------- + ! + ! input variables + ! + !----------------------------------------------------------------- + type (mpas_pool_type), intent(in) :: meshPool !< Input: mesh information + character (len=*) :: groupName !< Input: Name of tracer group + + !----------------------------------------------------------------- + ! + ! input/output variables + ! + !----------------------------------------------------------------- + type (mpas_pool_type), intent(inout) :: forcingPool !< Input: Forcing information + real (kind=RKIND), dimension(:,:), intent(inout) :: & + tracersSurfaceFluxSubglacialRunoff !< Input/Output: Surface flux for tracer group due to subglacial runoff + + !----------------------------------------------------------------- + ! + ! output variables + ! + !----------------------------------------------------------------- + + integer, intent(out) :: err !< Output: Error flag + + !----------------------------------------------------------------- + ! + ! local variables + ! + !----------------------------------------------------------------- + + err = 0 + + call mpas_timer_start("bulk_" // trim(groupName)) + if ( trim(groupName) == 'activeTracers' ) then + call ocn_surface_bulk_forcing_active_tracers_subglacial_runoff(meshPool, forcingPool, & + tracersSurfaceFluxSubglacialRunoff, err) + end if + call mpas_timer_stop("bulk_" // trim(groupName)) + + end subroutine ocn_surface_bulk_forcing_tracers_subglacial_runoff!}}} + !*********************************************************************** ! ! routine ocn_surface_bulk_forcing_vel @@ -503,7 +560,7 @@ end subroutine ocn_surface_bulk_forcing_init!}}} !----------------------------------------------------------------------- subroutine ocn_surface_bulk_forcing_active_tracers(meshPool, forcingPool, tracerGroup, & - tracersSurfaceFlux, tracersSurfaceFluxRunoff, tracersSurfaceFluxSubglacialRunoff, tracersSurfaceFluxRemoved, layerThickness, dt, err)!{{{ + tracersSurfaceFlux, tracersSurfaceFluxRunoff, tracersSurfaceFluxRemoved, layerThickness, dt, err)!{{{ !----------------------------------------------------------------- ! @@ -520,7 +577,6 @@ subroutine ocn_surface_bulk_forcing_active_tracers(meshPool, forcingPool, tracer type (mpas_pool_type), intent(inout) :: forcingPool !< Input: Forcing information real (kind=RKIND), dimension(:,:), intent(inout) :: tracersSurfaceFlux real (kind=RKIND), dimension(:,:), intent(inout) :: tracersSurfaceFluxRunoff - real (kind=RKIND), dimension(:,:), intent(inout) :: tracersSurfaceFluxSubglacialRunoff real (kind=RKIND), dimension(:,:), intent(inout) :: tracersSurfaceFluxRemoved real (kind=RKIND), dimension(:,:,:), intent(inout) :: tracerGroup real (kind=RKIND), dimension(:,:), intent(in) :: layerThickness @@ -548,7 +604,7 @@ subroutine ocn_surface_bulk_forcing_active_tracers(meshPool, forcingPool, tracer type(mpas_pool_type),pointer :: tracersSurfaceFluxPool real (kind=RKIND), dimension(:), pointer :: latentHeatFlux, sensibleHeatFlux, longWaveHeatFluxUp, longWaveHeatFluxDown, & - seaIceHeatFlux, icebergHeatFlux, evaporationFlux, riverRunoffFlux, subglacialRunoffFlux + seaIceHeatFlux, icebergHeatFlux, evaporationFlux, riverRunoffFlux real (kind=RKIND), dimension(:), pointer :: seaIceFreshWaterFlux, icebergFreshWaterFlux, seaIceSalinityFlux, iceRunoffFlux real (kind=RKIND), dimension(:), pointer :: shortWaveHeatFlux, penetrativeTemperatureFlux real (kind=RKIND), dimension(:), pointer :: snowFlux, rainFlux @@ -589,7 +645,6 @@ subroutine ocn_surface_bulk_forcing_active_tracers(meshPool, forcingPool, tracer call mpas_pool_get_array(forcingPool, 'seaIceSalinityFlux', seaIceSalinityFlux) call mpas_pool_get_array(forcingPool, 'iceRunoffFlux', iceRunoffFlux) call mpas_pool_get_array(forcingPool, 'riverRunoffFlux', riverRunoffFlux) - call mpas_pool_get_array(forcingPool, 'subglacialRunoffFlux', subglacialRunoffFlux) call mpas_pool_get_array(forcingPool, 'penetrativeTemperatureFlux', penetrativeTemperatureFlux) call mpas_pool_get_array(forcingPool, 'landIcePressure', landIcePressure) @@ -653,28 +708,6 @@ subroutine ocn_surface_bulk_forcing_active_tracers(meshPool, forcingPool, tracer tracersSurfaceFluxRunoff(index_temperature_flux,iCell) = riverRunoffFlux(iCell) & * max(tracerGroup(index_temperature_flux,minLevelCell(iCell),iCell), 0.0_RKIND) / rho_sw - if (trim(config_subglacial_runoff_mode) == 'data') then - if ( config_use_sgr_opt_temp_prescribed ) then - !sgr with fixed prescribed temperature - tracersSurfaceFluxSubglacialRunoff(index_temperature_flux,iCell) = subglacialRunoffFlux(iCell) * & - config_sgr_temperature_prescribed / rho_sw - else - !sgr with temperature equal to the local freezing point of freshwater - tracersSurfaceFluxSubglacialRunoff(index_temperature_flux,iCell) = subglacialRunoffFlux(iCell) * & - ocn_freezing_temperature(salinity=0.0_RKIND, pressure=landIcePressure(iCell), & - inLandIceCavity=.true.) / rho_sw - end if - - if ( config_use_sgr_opt_salt_prescribed ) then - !sgr with fixed prescribed temperature - tracersSurfaceFluxSubglacialRunoff(index_salinity_flux,iCell) = subglacialRunoffFlux(iCell) * & - config_sgr_salinity_prescribed / rho_sw - else - !sgr with temperature equal to the local freezing point of freshwater - tracersSurfaceFluxSubglacialRunoff(index_salinity_flux,iCell) = 0.0_RKIND - end if - end if - ! Accumulate fluxes that use the freezing point ! mrp performance note: should call ocn_freezing_temperature just once here seaIceTemperatureFlux(iCell) = seaIceFreshWaterFlux(iCell) * & @@ -694,12 +727,6 @@ subroutine ocn_surface_bulk_forcing_active_tracers(meshPool, forcingPool, tracer totalFreshWaterTemperatureFlux(iCell) = surfaceTemperatureFluxWithoutRunoff & + tracersSurfaceFluxRunoff(index_temperature_flux,iCell) - ! add subglacial runoff contribution for sending through coupler - if (trim(config_subglacial_runoff_mode) == 'data') then - totalFreshWaterTemperatureFlux(iCell) = totalFreshWaterTemperatureFlux(iCell) & - + tracersSurfaceFluxSubglacialRunoff(index_temperature_flux,iCell) - end if - ! Fields with zero temperature are not accumulated. These include: ! snowFlux ! iceRunoffFlux @@ -720,6 +747,125 @@ subroutine ocn_surface_bulk_forcing_active_tracers(meshPool, forcingPool, tracer end subroutine ocn_surface_bulk_forcing_active_tracers!}}} +!*********************************************************************** +! +! routine ocn_surface_bulk_forcing_active_tracers_subglacial_runoff +! +!> \brief Determines the active tracers forcing array used for the bulk forcing. +!> \author Doug Jacobsen +!> \date 04/25/12 +!> \details +!> This routine computes the active tracers forcing arrays used later in MPAS. +! +!----------------------------------------------------------------------- + + subroutine ocn_surface_bulk_forcing_active_tracers_subglacial_runoff(meshPool, forcingPool, & + tracersSurfaceFluxSubglacialRunoff, err)!{{{ + + !----------------------------------------------------------------- + ! + ! input variables + ! + !----------------------------------------------------------------- + type (mpas_pool_type), intent(in) :: meshPool !< Input: mesh information + + !----------------------------------------------------------------- + ! + ! input/output variables + ! + !----------------------------------------------------------------- + type (mpas_pool_type), intent(inout) :: forcingPool !< Input: Forcing information + real (kind=RKIND), dimension(:,:), intent(inout) :: tracersSurfaceFluxSubglacialRunoff + + !----------------------------------------------------------------- + ! + ! output variables + ! + !----------------------------------------------------------------- + + integer, intent(out) :: err !< Output: Error flag + + !----------------------------------------------------------------- + ! + ! local variables + ! + !----------------------------------------------------------------- + + integer :: iCell, nCells + integer, pointer :: index_temperature_fluxPtr, index_salinity_fluxPtr + integer :: index_temperature_flux, index_salinity_flux + integer, dimension(:), pointer :: nCellsArray + + type(mpas_pool_type),pointer :: tracersSurfaceFluxPool + + real (kind=RKIND), dimension(:), pointer :: subglacialRunoffFlux + real (kind=RKIND), dimension(:), pointer :: totalFreshWaterTemperatureFlux + real (kind=RKIND), dimension(:), pointer :: landIcePressure + + err = 0 + + call mpas_pool_get_dimension(meshPool, 'nCellsArray', nCellsArray) + + call mpas_pool_get_subpool(forcingPool, 'tracersSurfaceFlux',tracersSurfaceFluxPool) + + call mpas_pool_get_dimension(tracersSurfaceFluxPool, & + 'index_temperatureSurfaceFlux', & + index_temperature_fluxPtr) + call mpas_pool_get_dimension(tracersSurfaceFluxPool, & + 'index_salinitySurfaceFlux', & + index_salinity_fluxPtr) + index_temperature_flux = index_temperature_fluxPtr + index_salinity_flux = index_salinity_fluxPtr + + call mpas_pool_get_array(forcingPool, 'subglacialRunoffFlux', subglacialRunoffFlux) + + call mpas_pool_get_array(forcingPool, 'landIcePressure', landIcePressure) + + call mpas_pool_get_array(forcingPool, 'totalFreshWaterTemperatureFlux', totalFreshWaterTemperatureFlux) + + nCells = nCellsArray( 3 ) + + ! Surface fluxes of water have an associated heat content, but the coupled system does not account for this + ! Assume surface fluxes of water have a temperature dependent on the incoming mass flux. + ! Assume surface fluxes of water have zero salinity. So the RHS forcing is zero for salinity. + ! Only include this heat forcing when bulk thickness is turned on + ! indices on tracerGroup are (iTracer, iLevel, iCell) + if (.not. bulkThicknessFluxOff) then + !$omp parallel + !$omp do schedule(runtime) + do iCell = 1, nCells + + if ( config_use_sgr_opt_temp_prescribed ) then + !sgr with fixed prescribed temperature + tracersSurfaceFluxSubglacialRunoff(index_temperature_flux,iCell) = subglacialRunoffFlux(iCell) * & + config_sgr_temperature_prescribed / rho_sw + else + !sgr with temperature equal to the local freezing point of freshwater + tracersSurfaceFluxSubglacialRunoff(index_temperature_flux,iCell) = subglacialRunoffFlux(iCell) * & + ocn_freezing_temperature(salinity=0.0_RKIND, pressure=landIcePressure(iCell), & + inLandIceCavity=.true.) / rho_sw + end if + + if ( config_use_sgr_opt_salt_prescribed ) then + !sgr with fixed prescribed temperature + tracersSurfaceFluxSubglacialRunoff(index_salinity_flux,iCell) = subglacialRunoffFlux(iCell) * & + config_sgr_salinity_prescribed / rho_sw + else + !sgr with temperature equal to the local freezing point of freshwater + tracersSurfaceFluxSubglacialRunoff(index_salinity_flux,iCell) = 0.0_RKIND + end if + + ! add subglacial runoff contribution for sending through coupler + totalFreshWaterTemperatureFlux(iCell) = totalFreshWaterTemperatureFlux(iCell) & + + tracersSurfaceFluxSubglacialRunoff(index_temperature_flux,iCell) + + end do + !$omp end do + !$omp end parallel + endif ! bulkThicknessFluxOn + + end subroutine ocn_surface_bulk_forcing_active_tracers_subglacial_runoff!}}} + end module ocn_surface_bulk_forcing diff --git a/components/mpas-ocean/src/shared/mpas_ocn_tendency.F b/components/mpas-ocean/src/shared/mpas_ocn_tendency.F index b855512fb294..f42df59a629c 100644 --- a/components/mpas-ocean/src/shared/mpas_ocn_tendency.F +++ b/components/mpas-ocean/src/shared/mpas_ocn_tendency.F @@ -891,9 +891,13 @@ subroutine ocn_tend_tracer(tendPool, statePool, forcingPool, & forcingPool, tracerGroup, & tracerGroupSurfaceFlux, & tracerGroupSurfaceFluxRunoff, & - tracerGroupSurfaceFluxSubglacialRunoff, & tracerGroupSurfaceFluxRemoved, & dt, layerThickness, err) + if (trim(config_subglacial_runoff_mode) == 'data') then + call ocn_surface_bulk_forcing_tracers(meshPool, groupName, & + forcingPool, & + tracerGroupSurfaceFluxSubglacialRunoff, err) + end if end if ! sfc bulk forcing From 5a54e97cf2577dbc9bed3bff0c25379ad4fc72e1 Mon Sep 17 00:00:00 2001 From: Irena Vankova Date: Sun, 21 Jul 2024 21:43:49 -0600 Subject: [PATCH 255/451] fix function call typo _subglacial_runoff --- components/mpas-ocean/src/shared/mpas_ocn_tendency.F | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/components/mpas-ocean/src/shared/mpas_ocn_tendency.F b/components/mpas-ocean/src/shared/mpas_ocn_tendency.F index f42df59a629c..a0f4ae74e5ec 100644 --- a/components/mpas-ocean/src/shared/mpas_ocn_tendency.F +++ b/components/mpas-ocean/src/shared/mpas_ocn_tendency.F @@ -894,7 +894,7 @@ subroutine ocn_tend_tracer(tendPool, statePool, forcingPool, & tracerGroupSurfaceFluxRemoved, & dt, layerThickness, err) if (trim(config_subglacial_runoff_mode) == 'data') then - call ocn_surface_bulk_forcing_tracers(meshPool, groupName, & + call ocn_surface_bulk_forcing_tracers_subglacial_runoff(meshPool, groupName, & forcingPool, & tracerGroupSurfaceFluxSubglacialRunoff, err) end if From bdd8761563b4e46fb575c11830289c0fd4facd13 Mon Sep 17 00:00:00 2001 From: Irena Vankova Date: Sun, 21 Jul 2024 23:12:28 -0600 Subject: [PATCH 256/451] fix timer for sgr --- .../src/shared/mpas_ocn_tracer_surface_flux_to_tend.F | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/components/mpas-ocean/src/shared/mpas_ocn_tracer_surface_flux_to_tend.F b/components/mpas-ocean/src/shared/mpas_ocn_tracer_surface_flux_to_tend.F index fd754562a579..280ebc72844b 100644 --- a/components/mpas-ocean/src/shared/mpas_ocn_tracer_surface_flux_to_tend.F +++ b/components/mpas-ocean/src/shared/mpas_ocn_tracer_surface_flux_to_tend.F @@ -270,8 +270,6 @@ subroutine ocn_tracer_surface_flux_tend_subglacial_runoff(meshPool, fractionAbso if (.not. surfaceTracerFluxOn) return - call mpas_timer_start("surface_tracer_flux") - call mpas_pool_get_dimension(meshPool, 'nCellsArray', nCellsArray) call mpas_pool_get_dimension(meshPool, 'nVertLevels', nVertLevels) nTracers = size(tend, dim=1) @@ -308,6 +306,8 @@ subroutine ocn_tracer_surface_flux_tend_subglacial_runoff(meshPool, fractionAbso !$omp end do !$omp end parallel + call mpas_timer_stop("surface_tracer_subglacial_runoff_flux") + !-------------------------------------------------------------------- end subroutine ocn_tracer_surface_flux_tend_subglacial_runoff!}}} From 3bea55f109ccdca502d26909fbb0a66054a16c4b Mon Sep 17 00:00:00 2001 From: Iulian Grindeanu Date: Mon, 22 Jul 2024 12:59:58 -0500 Subject: [PATCH 257/451] new argument for apply weights --- driver-moab/main/seq_map_mod.F90 | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/driver-moab/main/seq_map_mod.F90 b/driver-moab/main/seq_map_mod.F90 index be47473f444c..82e67b8b195e 100644 --- a/driver-moab/main/seq_map_mod.F90 +++ b/driver-moab/main/seq_map_mod.F90 @@ -355,6 +355,7 @@ subroutine seq_map_map( mapper, av_s, av_d, fldlist, norm, avwts_s, avwtsfld_s, real(r8), dimension(:), allocatable :: wghts real(kind=r8) , allocatable :: targtags(:,:), targtags_ini(:,:) real(kind=r8) :: factor + integer :: filter_type ! used for caas projection #endif ! ! Local Variables @@ -649,7 +650,8 @@ subroutine seq_map_map( mapper, av_s, av_d, fldlist, norm, avwts_s, avwtsfld_s, call shr_sys_flush(logunit) endif #endif - ierr = iMOAB_ApplyScalarProjectionWeights ( mapper%intx_mbid, mapper%weight_identifier, fldlist_moab, fldlist_moab) + filter_type = 0 ! no + ierr = iMOAB_ApplyScalarProjectionWeights ( mapper%intx_mbid, filter_type, mapper%weight_identifier, fldlist_moab, fldlist_moab) if (ierr .ne. 0) then write(logunit,*) subname,' error in applying weights ' call shr_sys_abort(subname//' ERROR in applying weights') From 0b72d7532ee6d28b926ed2365b3d68c86a022f54 Mon Sep 17 00:00:00 2001 From: Irena Vankova Date: Mon, 22 Jul 2024 13:20:13 -0600 Subject: [PATCH 258/451] corrected subglacialRunoffFlux add up in conservation check so that it is as mass, not volume flux --- .../src/analysis_members/mpas_ocn_conservation_check.F | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/components/mpas-ocean/src/analysis_members/mpas_ocn_conservation_check.F b/components/mpas-ocean/src/analysis_members/mpas_ocn_conservation_check.F index 756328a3d5dd..beed937d6767 100644 --- a/components/mpas-ocean/src/analysis_members/mpas_ocn_conservation_check.F +++ b/components/mpas-ocean/src/analysis_members/mpas_ocn_conservation_check.F @@ -983,7 +983,7 @@ subroutine mass_conservation(domain, err) sumArray( 8) = sumArray( 8) + areaCell(iCell) * removedIceRunoffFlux(iCell) sumArray( 9) = sumArray( 9) + areaCell(iCell) * icebergFreshwaterFlux(iCell) if (trim(config_subglacial_runoff_mode) == 'data') then - sumArray(13) = sumArray(13) + areaCell(iCell) * subglacialRunoffFlux(iCell) / areaCell(iCell) * rho_sw + sumArray(13) = sumArray(13) + areaCell(iCell) * subglacialRunoffFlux(iCell) end if enddo From 00fc2618b0ad0d064870659e92ac51d8f4246c13 Mon Sep 17 00:00:00 2001 From: irenavankova Date: Wed, 17 Jul 2024 12:18:10 -0600 Subject: [PATCH 259/451] Change if statement for config_sgr_flux_vertical_location init check Co-authored-by: Carolyn Begeman --- components/mpas-ocean/src/shared/mpas_ocn_diagnostics.F | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/components/mpas-ocean/src/shared/mpas_ocn_diagnostics.F b/components/mpas-ocean/src/shared/mpas_ocn_diagnostics.F index 5046e19d5d59..a2d6586a7d63 100644 --- a/components/mpas-ocean/src/shared/mpas_ocn_diagnostics.F +++ b/components/mpas-ocean/src/shared/mpas_ocn_diagnostics.F @@ -4742,10 +4742,9 @@ subroutine ocn_diagnostics_init(domain, err)!{{{ call ocn_diagnostics_variables_init(domain, jenkinsOn, & hollandJenkinsOn, err) - if ( trim(config_sgr_flux_vertical_location) == 'top' ) then - else if ( trim(config_sgr_flux_vertical_location) == 'uniform' ) then - else if ( trim(config_sgr_flux_vertical_location) == 'bottom' ) then - else + if ( trim(config_sgr_flux_vertical_location) /= 'top' .and. & + trim(config_sgr_flux_vertical_location) /= 'uniform' .and. & + trim(config_sgr_flux_vertical_location) /= 'bottom' ) then call mpas_log_write("config_sgr_flux_vertical_location not one of 'bottom', 'uniform', 'top'.", MPAS_LOG_CRIT) end if From 71af25a190706654cb5ae9e52ec253d9f54d03e8 Mon Sep 17 00:00:00 2001 From: Iulian Grindeanu Date: Mon, 22 Jul 2024 15:12:35 -0500 Subject: [PATCH 260/451] extra endif in mpas ocean mct module --- components/mpas-ocean/driver/ocn_comp_mct.F | 1 - 1 file changed, 1 deletion(-) diff --git a/components/mpas-ocean/driver/ocn_comp_mct.F b/components/mpas-ocean/driver/ocn_comp_mct.F index bd425e7e806a..5bedda574003 100644 --- a/components/mpas-ocean/driver/ocn_comp_mct.F +++ b/components/mpas-ocean/driver/ocn_comp_mct.F @@ -3936,7 +3936,6 @@ subroutine ocn_import_moab( Eclock, errorCode)!{{{ call mpas_dmpar_exch_halo_field(iceFluxDMSPField) endif endif - endif !----------------------------------------------------------------------- !EOC From 77feb929dcad7ab939f7108c6b4f292d716e5530 Mon Sep 17 00:00:00 2001 From: Irena Vankova Date: Tue, 23 Jul 2024 13:45:38 -0600 Subject: [PATCH 261/451] change author on new subroutines --- .../src/shared/mpas_ocn_surface_bulk_forcing.F | 12 ++++++------ .../src/shared/mpas_ocn_thick_surface_flux.F | 8 ++++---- 2 files changed, 10 insertions(+), 10 deletions(-) diff --git a/components/mpas-ocean/src/shared/mpas_ocn_surface_bulk_forcing.F b/components/mpas-ocean/src/shared/mpas_ocn_surface_bulk_forcing.F index 81732b637a97..11d70ae9c40d 100644 --- a/components/mpas-ocean/src/shared/mpas_ocn_surface_bulk_forcing.F +++ b/components/mpas-ocean/src/shared/mpas_ocn_surface_bulk_forcing.F @@ -136,8 +136,8 @@ end subroutine ocn_surface_bulk_forcing_tracers!}}} ! routine ocn_surface_bulk_forcing_tracers_subglacial_runoff ! !> \brief Determines the tracers forcing array used for the bulk forcing. -!> \author Doug Jacobsen -!> \date 04/25/12 +!> \author Irena Vankova +!> \date July 2024 !> \details !> This routine computes the tracers forcing arrays used later in MPAS. ! @@ -425,8 +425,8 @@ end subroutine ocn_surface_bulk_forcing_thick!}}} ! routine ocn_surface_bulk_forcing_thick_subglacial_runoff ! !> \brief Determines the thickness forcing array used for the bulk forcing. -!> \author Doug Jacobsen -!> \date 04/25/12 +!> \author Irena Vankova +!> \date July 2024 !> \details !> This routine computes the thickness forcing arrays used later in MPAS. ! @@ -752,8 +752,8 @@ end subroutine ocn_surface_bulk_forcing_active_tracers!}}} ! routine ocn_surface_bulk_forcing_active_tracers_subglacial_runoff ! !> \brief Determines the active tracers forcing array used for the bulk forcing. -!> \author Doug Jacobsen -!> \date 04/25/12 +!> \author Irena Vankova +!> \date July 2024 !> \details !> This routine computes the active tracers forcing arrays used later in MPAS. ! diff --git a/components/mpas-ocean/src/shared/mpas_ocn_thick_surface_flux.F b/components/mpas-ocean/src/shared/mpas_ocn_thick_surface_flux.F index 8e389a74ba37..b959a89bff1d 100644 --- a/components/mpas-ocean/src/shared/mpas_ocn_thick_surface_flux.F +++ b/components/mpas-ocean/src/shared/mpas_ocn_thick_surface_flux.F @@ -175,8 +175,8 @@ end subroutine ocn_thick_surface_flux_tend!}}} ! routine ocn_thick_surface_flux_tend_subglacial_runoff ! !> \brief Computes tendency term from horizontal advection of thickness -!> \author Doug Jacobsen -!> \date 15 September 2011 +!> \author Irena Vankova +!> \date July 2024 !> \details !> This routine computes the horizontal advection tendency for !> thickness based on current state and user choices of forcings. @@ -276,8 +276,8 @@ end subroutine ocn_thick_surface_flux_tend_subglacial_runoff!}}} ! routine ocn_thick_surface_flux_init ! !> \brief Initializes ocean horizontal thickness surface fluxes -!> \author Doug Jacobsen -!> \date 12/17/12 +!> \author Irena Vankova +!> \date July 2024 !> \details !> This routine initializes quantities related to thickness !> surface fluxes in the ocean. From 181b07ccc550fd079e11d2ce4ff3b9ae723fefac Mon Sep 17 00:00:00 2001 From: Iulian Grindeanu Date: Wed, 24 Jul 2024 11:44:33 -0500 Subject: [PATCH 262/451] local compile changes --- components/mpas-ocean/driver/ocn_comp_mct.F | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/components/mpas-ocean/driver/ocn_comp_mct.F b/components/mpas-ocean/driver/ocn_comp_mct.F index bd425e7e806a..d1b140563bb7 100644 --- a/components/mpas-ocean/driver/ocn_comp_mct.F +++ b/components/mpas-ocean/driver/ocn_comp_mct.F @@ -2952,6 +2952,8 @@ subroutine ocn_export_mct(o2x_o, errorCode) !{{{ block_ptr => block_ptr % next end do + errorCode = 0 + !----------------------------------------------------------------------- !EOC @@ -3936,7 +3938,6 @@ subroutine ocn_import_moab( Eclock, errorCode)!{{{ call mpas_dmpar_exch_halo_field(iceFluxDMSPField) endif endif - endif !----------------------------------------------------------------------- !EOC From ea2a9360f4d0c22bbe5260aaf1b06a8cd692a135 Mon Sep 17 00:00:00 2001 From: jayeshkrishna Date: Wed, 24 Jul 2024 16:08:08 -0500 Subject: [PATCH 263/451] Changing default NetCDF format to CDF5 Changing the default NetCDF file format from CDF2 (64bit_offset) to CDF5 (64bit_data). The CDF5 format gets rid of limitations (for all practical purposes) on NetCDF variable size imposed by the older CDF2 file format. Also note that all E3SM run scripts already explicitly set the NetCDF file format to CDF5/64bit_data for all production runs. --- driver-mct/cime_config/config_component.xml | 20 ++++++++++---------- driver-moab/cime_config/config_component.xml | 20 ++++++++++---------- 2 files changed, 20 insertions(+), 20 deletions(-) diff --git a/driver-mct/cime_config/config_component.xml b/driver-mct/cime_config/config_component.xml index 5b5126af8930..271c13139555 100644 --- a/driver-mct/cime_config/config_component.xml +++ b/driver-mct/cime_config/config_component.xml @@ -2655,16 +2655,16 @@ https://www.unidata.ucar.edu/software/netcdf/docs/data_type.html - 64bit_offset - 64bit_offset - 64bit_offset - 64bit_offset - 64bit_offset - 64bit_offset - 64bit_offset - 64bit_offset - 64bit_offset - 64bit_offset + 64bit_data + 64bit_data + 64bit_data + 64bit_data + 64bit_data + 64bit_data + 64bit_data + 64bit_data + 64bit_data + 64bit_data diff --git a/driver-moab/cime_config/config_component.xml b/driver-moab/cime_config/config_component.xml index be0ee0fbd776..0f21eeb02097 100644 --- a/driver-moab/cime_config/config_component.xml +++ b/driver-moab/cime_config/config_component.xml @@ -2647,16 +2647,16 @@ https://www.unidata.ucar.edu/software/netcdf/docs/data_type.html - 64bit_offset - 64bit_offset - 64bit_offset - 64bit_offset - 64bit_offset - 64bit_offset - 64bit_offset - 64bit_offset - 64bit_offset - 64bit_offset + 64bit_data + 64bit_data + 64bit_data + 64bit_data + 64bit_data + 64bit_data + 64bit_data + 64bit_data + 64bit_data + 64bit_data From 0288938beae15cf92f0a86d077e0cd12b3ffaf3c Mon Sep 17 00:00:00 2001 From: Jon Wolfe Date: Thu, 25 Jul 2024 11:06:20 -0500 Subject: [PATCH 264/451] Make bld files consistent with Registry --- components/mpas-ocean/bld/build-namelist | 10 ++++---- .../mpas-ocean/bld/build-namelist-section | 2 +- .../namelist_defaults_mpaso.xml | 2 +- .../namelist_definition_mpaso.xml | 23 ++++++++++--------- 4 files changed, 19 insertions(+), 18 deletions(-) diff --git a/components/mpas-ocean/bld/build-namelist b/components/mpas-ocean/bld/build-namelist index 490100040c00..37c8b88f67e6 100755 --- a/components/mpas-ocean/bld/build-namelist +++ b/components/mpas-ocean/bld/build-namelist @@ -708,6 +708,11 @@ add_default($nl, 'config_use_bulk_wind_stress'); add_default($nl, 'config_use_bulk_thickness_flux'); add_default($nl, 'config_flux_attenuation_coefficient'); add_default($nl, 'config_flux_attenuation_coefficient_runoff'); +if ($OCN_SGR eq 'data') { + add_default($nl, 'config_subglacial_runoff_mode', 'val'=>"data"); +} else { + add_default($nl, 'config_subglacial_runoff_mode'); +} add_default($nl, 'config_flux_attenuation_coefficient_subglacial_runoff'); add_default($nl, 'config_sgr_flux_vertical_location'); add_default($nl, 'config_use_sgr_opt_kpp'); @@ -715,11 +720,6 @@ add_default($nl, 'config_use_sgr_opt_temp_prescribed'); add_default($nl, 'config_use_sgr_opt_salt_prescribed'); add_default($nl, 'config_sgr_temperature_prescribed'); add_default($nl, 'config_sgr_salinity_prescribed'); -if ($OCN_SGR eq 'data') { - add_default($nl, 'config_subglacial_runoff_mode', 'val'=>"data"); -} else { - add_default($nl, 'config_subglacial_runoff_mode'); -} ############################ # Namelist group: coupling # diff --git a/components/mpas-ocean/bld/build-namelist-section b/components/mpas-ocean/bld/build-namelist-section index 189d32fc7b52..9e646beb6b5e 100644 --- a/components/mpas-ocean/bld/build-namelist-section +++ b/components/mpas-ocean/bld/build-namelist-section @@ -224,6 +224,7 @@ add_default($nl, 'config_use_bulk_wind_stress'); add_default($nl, 'config_use_bulk_thickness_flux'); add_default($nl, 'config_flux_attenuation_coefficient'); add_default($nl, 'config_flux_attenuation_coefficient_runoff'); +add_default($nl, 'config_subglacial_runoff_mode'); add_default($nl, 'config_flux_attenuation_coefficient_subglacial_runoff'); add_default($nl, 'config_sgr_flux_vertical_location'); add_default($nl, 'config_use_sgr_opt_kpp'); @@ -231,7 +232,6 @@ add_default($nl, 'config_use_sgr_opt_temp_prescribed'); add_default($nl, 'config_use_sgr_opt_salt_prescribed'); add_default($nl, 'config_sgr_temperature_prescribed'); add_default($nl, 'config_sgr_salinity_prescribed'); -add_default($nl, 'config_subglacial_runoff_mode'); ############################ # Namelist group: coupling # diff --git a/components/mpas-ocean/bld/namelist_files/namelist_defaults_mpaso.xml b/components/mpas-ocean/bld/namelist_files/namelist_defaults_mpaso.xml index c57920e5c388..b70f7942686e 100644 --- a/components/mpas-ocean/bld/namelist_files/namelist_defaults_mpaso.xml +++ b/components/mpas-ocean/bld/namelist_files/namelist_defaults_mpaso.xml @@ -342,6 +342,7 @@ .true. 0.001 10.0 +'off' 0.001 'bottom' .true. @@ -349,7 +350,6 @@ .false. 0.0 0.0 -'off' .false. diff --git a/components/mpas-ocean/bld/namelist_files/namelist_definition_mpaso.xml b/components/mpas-ocean/bld/namelist_files/namelist_definition_mpaso.xml index fed7828e6a8b..601b121e5768 100644 --- a/components/mpas-ocean/bld/namelist_files/namelist_definition_mpaso.xml +++ b/components/mpas-ocean/bld/namelist_files/namelist_definition_mpaso.xml @@ -1188,9 +1188,17 @@ Valid values: Any positive real number. Default: Defined in namelist_defaults.xml + +Selects the mode in which subglacial runoff fluxes are implemented. + +Valid values: 'off', 'data' +Default: Defined in namelist_defaults.xml + + -The length scale of exponential decay of subglacial runoff. Fluxes are multiplied by $e^{z/\gamma}$, where this coefficient is $\gamma$. +The length scale of exponential decay of subglacial runoff, used when config_sgr_flux_vertical_location is 'top' or 'bottom'. Fluxes are multiplied by $e^{z/\gamma}$, where this coefficient is $\gamma$. Valid values: Any positive real number. Default: Defined in namelist_defaults.xml @@ -1198,9 +1206,9 @@ Default: Defined in namelist_defaults.xml -Selects the vertical location where subglacial runoff is fluxed +Selects the vertical location where subglacial runoff is fluxed. -Valid values: 'top','uniform', 'bottom'. +Valid values: 'top','uniform', 'bottom' Default: Defined in namelist_defaults.xml @@ -1240,17 +1248,10 @@ Default: Defined in namelist_defaults.xml category="forcing" group="forcing"> Prescribed subglacial runoff salinity value, applied when config_use_sgr_opt_salt_prescribed = .true. -Valid values: Any real number. +Valid values: Any positive real number Default: Defined in namelist_defaults.xml - -Selects the mode in which subglacial runoff fluxes are computed. - -Valid values: 'off', 'data' -Default: Defined in namelist_defaults.xml - From 48cee50966dfefddfad8b90e8502c9296bf62573 Mon Sep 17 00:00:00 2001 From: irenavankova Date: Thu, 25 Jul 2024 10:12:31 -0600 Subject: [PATCH 265/451] Correct DSGR file name Co-authored-by: Xylar Asay-Davis --- components/mpas-ocean/cime_config/buildnml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/components/mpas-ocean/cime_config/buildnml b/components/mpas-ocean/cime_config/buildnml index f3eb22881683..8f5193c334be 100755 --- a/components/mpas-ocean/cime_config/buildnml +++ b/components/mpas-ocean/cime_config/buildnml @@ -380,7 +380,7 @@ def buildnml(case, caseroot, compname): if ocn_tidal_mixing == 'true': u_tidal_rms_file = 'velocityTidalRMS_CATS2008.IcoswISC30E3r5.20231120.nc' if ocn_sgr == 'data': - data_sgr_file = 'DSGR.massFlux.massFlux.MALI.out2055.IcoswISC30E3r5.20240328.nc' + data_sgr_file = 'DSGR.massFlux.MALI.out2055.IcoswISC30E3r5.20240328.nc' elif ocn_grid == 'IcosXISC30E3r7': decomp_date = '20240314' From 5a0f2842c03cb058d51dd8c09a133efece7cd2ca Mon Sep 17 00:00:00 2001 From: Irena Vankova Date: Thu, 25 Jul 2024 10:44:04 -0600 Subject: [PATCH 266/451] Corrected authorship --- .../mpas-ocean/src/shared/mpas_ocn_thick_surface_flux.F | 4 ++-- .../src/shared/mpas_ocn_tracer_surface_flux_to_tend.F | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/components/mpas-ocean/src/shared/mpas_ocn_thick_surface_flux.F b/components/mpas-ocean/src/shared/mpas_ocn_thick_surface_flux.F index b959a89bff1d..1c535532cea2 100644 --- a/components/mpas-ocean/src/shared/mpas_ocn_thick_surface_flux.F +++ b/components/mpas-ocean/src/shared/mpas_ocn_thick_surface_flux.F @@ -276,8 +276,8 @@ end subroutine ocn_thick_surface_flux_tend_subglacial_runoff!}}} ! routine ocn_thick_surface_flux_init ! !> \brief Initializes ocean horizontal thickness surface fluxes -!> \author Irena Vankova -!> \date July 2024 +!> \author Doug Jacobsen +!> \date 12/17/12 !> \details !> This routine initializes quantities related to thickness !> surface fluxes in the ocean. diff --git a/components/mpas-ocean/src/shared/mpas_ocn_tracer_surface_flux_to_tend.F b/components/mpas-ocean/src/shared/mpas_ocn_tracer_surface_flux_to_tend.F index 280ebc72844b..ba97203c4ec3 100644 --- a/components/mpas-ocean/src/shared/mpas_ocn_tracer_surface_flux_to_tend.F +++ b/components/mpas-ocean/src/shared/mpas_ocn_tracer_surface_flux_to_tend.F @@ -208,8 +208,8 @@ end subroutine ocn_tracer_surface_flux_tend!}}} ! routine ocn_tracer_surface_flux_tend_subglacial_runoff ! !> \brief Computes tendency term for surface fluxes -!> \author Doug Jacobsen -!> \date 12/17/12 +!> \author Irena Vankova +!> \date July 2024 !> \details !> This routine computes the tendency for tracers based on surface fluxes. ! From 9ddd011645f60d3c59e7783476f75d5359ed06ae Mon Sep 17 00:00:00 2001 From: Irena Vankova Date: Thu, 25 Jul 2024 10:49:40 -0600 Subject: [PATCH 267/451] Added DSGR to stealth feature tests --- cime_config/tests.py | 1 + 1 file changed, 1 insertion(+) diff --git a/cime_config/tests.py b/cime_config/tests.py index c1f6cfaa1b70..12ab829c51dd 100644 --- a/cime_config/tests.py +++ b/cime_config/tests.py @@ -274,6 +274,7 @@ "ERS_P480_Ld5.TL319_IcoswISC30E3r5.GMPAS-JRA1p5-DIB-PISMF.mpaso-jra_1958", "PEM_P480_Ld5.TL319_IcoswISC30E3r5.GMPAS-JRA1p5-DIB-PISMF.mpaso-jra_1958", "SMS_P480_Ld5.TL319_IcoswISC30E3r5.GMPAS-JRA1p5-DIB-PISMF-TMIX.mpaso-jra_1958", + "SMS_P480_Ld5.TL319_IcoswISC30E3r5.GMPAS-JRA1p5-DIB-PISMF-DSGR.mpaso-jra_1958", ) }, From 9e14e13e4ea83846d03ecca91dd0bdb2aedcd4b7 Mon Sep 17 00:00:00 2001 From: Walter Hannah Date: Thu, 25 Jul 2024 12:37:56 -0500 Subject: [PATCH 268/451] disable MMF2 integration test --- cime_config/tests.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cime_config/tests.py b/cime_config/tests.py index dd394f381425..525312fef2ce 100644 --- a/cime_config/tests.py +++ b/cime_config/tests.py @@ -339,7 +339,7 @@ "ERP_Ln9.ne4pg2_oQU480.WCYCL20TRNS-MMF1.allactive-mmf_fixed_subcycle", "ERS_Ln9.ne4pg2_ne4pg2.FRCE-MMF1.eam-cosp_nhtfrq9", "SMS_Ln5.ne4_ne4.FSCM-ARM97-MMF1", - "SMS_Ln3.ne4pg2_ne4pg2.F2010-MMF2", + # "SMS_Ln3.ne4pg2_ne4pg2.F2010-MMF2", - temporarily disabled due to ongoing dev issues ) }, From d75fb49f30b9597f76126c0cd2fbdeb3f6b1d6f6 Mon Sep 17 00:00:00 2001 From: Jason Boutte Date: Thu, 25 Jul 2024 10:51:41 -0700 Subject: [PATCH 269/451] Moves to workspace from gdata --- cime_config/machines/config_machines.xml | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/cime_config/machines/config_machines.xml b/cime_config/machines/config_machines.xml index 092aecdda3ce..5cf5c3de2b5b 100644 --- a/cime_config/machines/config_machines.xml +++ b/cime_config/machines/config_machines.xml @@ -2996,11 +2996,11 @@ mpich cbronze /p/lustre2/$USER/e3sm_scratch/ruby - /usr/gdata/e3sm/ccsm3data/inputdata - /usr/gdata/e3sm/ccsm3data/inputdata/atm/datm7 + /usr/workspace/e3sm/ccsm3data/inputdata + /usr/workspace/e3sm/ccsm3data/inputdata/atm/datm7 /p/lustre2/$USER/archive/$CASE /p/lustre2/$USER/ccsm_baselines/$COMPILER - /usr/gdata/e3sm/tools/cprnc + /usr/workspace/e3sm/tools/cprnc 8 lc_slurm donahue5 -at- llnl.gov @@ -3028,7 +3028,7 @@ intel-classic/2021.6.0-magic mvapich2/2.3.7 cmake/3.19.2 - /usr/gdata/e3sm/install/quartz/modulefiles + /usr/workspace/e3sm/install/quartz/modulefiles hdf5/1.12.2 netcdf-c/4.9.0 netcdf-fortran/4.6.0 @@ -3040,7 +3040,7 @@ $CIME_OUTPUT_ROOT/$CASE/run $CIME_OUTPUT_ROOT/$CASE/bld - /usr/gdata/e3sm/install/quartz/netcdf-fortran/ + /usr/workspace/e3sm/install/quartz/netcdf-fortran/ /usr/tce/packages/parallel-netcdf/parallel-netcdf-1.12.3-mvapich2-2.3.7-intel-classic-2021.6.0 @@ -3052,11 +3052,11 @@ mpich cbronze /p/lustre2/$USER/e3sm_scratch/quartz - /usr/gdata/e3sm/ccsm3data/inputdata - /usr/gdata/e3sm/ccsm3data/inputdata/atm/datm7 + /usr/workspace/e3sm/ccsm3data/inputdata + /usr/workspace/e3sm/ccsm3data/inputdata/atm/datm7 /p/lustre2/$USER/archive/$CASE /p/lustre2/$USER/ccsm_baselines/$COMPILER - /usr/gdata/e3sm/tools/cprnc + /usr/workspace/e3sm/tools/cprnc 8 lc_slurm donahue5 -at- llnl.gov @@ -3084,7 +3084,7 @@ intel-classic/2021.6.0-magic mvapich2/2.3.7 cmake/3.19.2 - /usr/gdata/e3sm/install/quartz/modulefiles + /usr/workspace/e3sm/install/quartz/modulefiles hdf5/1.12.2 netcdf-c/4.9.0 netcdf-fortran/4.6.0 @@ -3096,7 +3096,7 @@ $CIME_OUTPUT_ROOT/$CASE/run $CIME_OUTPUT_ROOT/$CASE/bld - /usr/gdata/e3sm/install/quartz/netcdf-fortran/ + /usr/workspace/e3sm/install/quartz/netcdf-fortran/ /usr/tce/packages/parallel-netcdf/parallel-netcdf-1.12.3-mvapich2-2.3.7-intel-classic-2021.6.0 From 524c69d40632317228d611a0f5abb31a6066382a Mon Sep 17 00:00:00 2001 From: Jason Boutte Date: Thu, 25 Jul 2024 14:54:54 -0700 Subject: [PATCH 270/451] Removes quartz and adds dane --- cime_config/machines/config_machines.xml | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/cime_config/machines/config_machines.xml b/cime_config/machines/config_machines.xml index 5cf5c3de2b5b..081bc229c707 100644 --- a/cime_config/machines/config_machines.xml +++ b/cime_config/machines/config_machines.xml @@ -3045,13 +3045,13 @@ - - LLNL Linux Cluster, Linux (pgi), 36 pes/node, batch system is Slurm + + LLNL Linux Cluster, 112 pes/node, batch system is Slurm LINUX intel mpich cbronze - /p/lustre2/$USER/e3sm_scratch/quartz + /p/lustre2/$USER/e3sm_scratch/dane /usr/workspace/e3sm/ccsm3data/inputdata /usr/workspace/e3sm/ccsm3data/inputdata/atm/datm7 /p/lustre2/$USER/archive/$CASE @@ -3060,8 +3060,8 @@ 8 lc_slurm donahue5 -at- llnl.gov - 72 - 36 + 224 + 112 From 24f24b88665c4e671f91bde4aacb0f3007c20d3b Mon Sep 17 00:00:00 2001 From: Irena Vankova Date: Mon, 29 Jul 2024 09:28:12 -0600 Subject: [PATCH 271/451] added package condition in tendency tracers --- .../mpas-ocean/src/shared/mpas_ocn_tendency.F | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/components/mpas-ocean/src/shared/mpas_ocn_tendency.F b/components/mpas-ocean/src/shared/mpas_ocn_tendency.F index a0f4ae74e5ec..601d134ceec8 100644 --- a/components/mpas-ocean/src/shared/mpas_ocn_tendency.F +++ b/components/mpas-ocean/src/shared/mpas_ocn_tendency.F @@ -830,13 +830,15 @@ subroutine ocn_tend_tracer(tendPool, statePool, forcingPool, & modifiedGroupName, & tracerGroupSurfaceFluxRunoff) - ! Get surface flux due to subglacial runoff array - ! only active tracers have subglacial runoff flux for now, - ! but we still need to associate for ALL tracers - modifiedGroupName = groupName // "SurfaceFluxSubglacialRunoff" - call mpas_pool_get_array(tracersSurfaceFluxPool, & - modifiedGroupName, & - tracerGroupSurfaceFluxSubglacialRunoff) + if (trim(config_subglacial_runoff_mode) == 'data') then + ! Get surface flux due to subglacial runoff array + ! only active tracers have subglacial runoff flux for now, + ! but we still need to associate for ALL tracers + modifiedGroupName = groupName // "SurfaceFluxSubglacialRunoff" + call mpas_pool_get_array(tracersSurfaceFluxPool, & + modifiedGroupName, & + tracerGroupSurfaceFluxSubglacialRunoff) + end if ! Get surface flux removed array to keep track of how much ! flux is ignored From 3dd57a09719bbe03628e353163e78098c027e594 Mon Sep 17 00:00:00 2001 From: Jason Boutte Date: Mon, 29 Jul 2024 12:24:31 -0700 Subject: [PATCH 272/451] Renames quartz cmake macros to dane --- .../cmake_macros/{intel_quartz.cmake => intel_dane.cmake} | 0 cime_config/machines/config_machines.xml | 4 ++-- 2 files changed, 2 insertions(+), 2 deletions(-) rename cime_config/machines/cmake_macros/{intel_quartz.cmake => intel_dane.cmake} (100%) diff --git a/cime_config/machines/cmake_macros/intel_quartz.cmake b/cime_config/machines/cmake_macros/intel_dane.cmake similarity index 100% rename from cime_config/machines/cmake_macros/intel_quartz.cmake rename to cime_config/machines/cmake_macros/intel_dane.cmake diff --git a/cime_config/machines/config_machines.xml b/cime_config/machines/config_machines.xml index 081bc229c707..d62cc289fc27 100644 --- a/cime_config/machines/config_machines.xml +++ b/cime_config/machines/config_machines.xml @@ -3003,7 +3003,7 @@ /usr/workspace/e3sm/tools/cprnc 8 lc_slurm - donahue5 -at- llnl.gov + boutte3 -at- llnl.gov 56 56 @@ -3059,7 +3059,7 @@ /usr/workspace/e3sm/tools/cprnc 8 lc_slurm - donahue5 -at- llnl.gov + boutte3 -at- llnl.gov 224 112 From b4352409b890093a34ab600915543a02bbd811be Mon Sep 17 00:00:00 2001 From: Naser Mahfouz Date: Tue, 30 Jul 2024 20:39:22 -0400 Subject: [PATCH 273/451] small mods to v3 script --- run_e3sm.template.sh | 59 +++++++++++++++++++++++++++++++++++++------- 1 file changed, 50 insertions(+), 9 deletions(-) diff --git a/run_e3sm.template.sh b/run_e3sm.template.sh index 623867c01904..1a55dc933d87 100755 --- a/run_e3sm.template.sh +++ b/run_e3sm.template.sh @@ -5,9 +5,6 @@ # Bash coding style inspired by: # http://kfirlavi.herokuapp.com/blog/2012/11/14/defensive-bash-programming -# TO DO: -# - custom pelayout - main() { # For debugging, uncomment line below @@ -46,8 +43,8 @@ readonly GET_REFCASE=TRUE #readonly RUN_REFDATE="" # same as MODEL_START_DATE for 'branch', can be different for 'hybrid' # Set paths -readonly CODE_ROOT="${HOME}/E3SMv3/code/${CHECKOUT}" -readonly CASE_ROOT="/pscratch/sd/r/${USER}/e3sm-scratch/${CASE_NAME}" +readonly CODE_ROOT="/pscratch/sd/${USER:0:1}/${USER}/e3sm-scratch/${MACHINE}/your_casename/code/${CHECKOUT}" +readonly CASE_ROOT="/pscratch/sd/${USER:0:1}/${USER}/e3sm-scratch/${MACHINE}/${CASE_NAME}" # Sub-directories readonly CASE_BUILD_DIR=${CASE_ROOT}/build @@ -56,6 +53,7 @@ readonly CASE_ARCHIVE_DIR=${CASE_ROOT}/archive # Define type of run # short tests: 'XS_2x5_ndays', 'XS_1x10_ndays', 'S_1x10_ndays', # 'M_1x10_ndays', 'M2_1x10_ndays', 'M80_1x10_ndays', 'L_1x10_ndays' +# * can replace XS, M, etc with custom-XY with XY being the node count # or 'production' for full simulation readonly run='XS_2x5_ndays' if [ "${run}" != "production" ]; then @@ -118,6 +116,9 @@ fetch_code # Create case create_newcase +# Custom PE layout +custom_pelayout + # Setup case_setup @@ -322,6 +323,14 @@ create_newcase() { echo $'\n----- Starting create_newcase -----\n' + + if [[ ${PELAYOUT} == custom-* ]]; + then + layout="M" # temporary placeholder for create_newcase + else + layout=${PELAYOUT} + fi + if [[ -z "$CASE_GROUP" ]]; then ${CODE_ROOT}/cime/scripts/create_newcase \ --case ${CASE_NAME} \ @@ -333,7 +342,7 @@ create_newcase() { --machine ${MACHINE} \ --project ${PROJECT} \ --walltime ${WALLTIME} \ - --pecount ${PELAYOUT} + --pecount ${layout} else ${CODE_ROOT}/cime/scripts/create_newcase \ --case ${CASE_NAME} \ @@ -346,7 +355,7 @@ create_newcase() { --machine ${MACHINE} \ --project ${PROJECT} \ --walltime ${WALLTIME} \ - --pecount ${PELAYOUT} + --pecount ${layout} fi @@ -398,6 +407,37 @@ case_setup() { popd } +#----------------------------------------------------- +custom_pelayout() { + +if [[ ${PELAYOUT} == custom-* ]]; +then + echo $'\n CUSTOMIZE PROCESSOR CONFIGURATION:' + + # Number of cores per node (machine specific) + if [ "${MACHINE}" == "pm-cpu" ]; then + ncore=128 + else + echo 'ERROR: MACHINE = '${MACHINE}' is not supported for custom PE layout.' + exit 400 + fi + + # Extract number of nodes + tmp=($(echo ${PELAYOUT} | tr "-" " ")) + nnodes=${tmp[1]} + + # Customize + pushd ${CASE_SCRIPTS_DIR} + ./xmlchange NTASKS=$(( $nnodes * $ncore )) + ./xmlchange NTHRDS=1 + ./xmlchange MAX_MPITASKS_PER_NODE=$ncore + ./xmlchange MAX_TASKS_PER_NODE=$ncore + popd + +fi + +} + #----------------------------------------------------- case_build() { @@ -534,9 +574,10 @@ copy_script() { local script_provenance_dir=${CASE_SCRIPTS_DIR}/run_script_provenance mkdir -p ${script_provenance_dir} - local this_script_name=`basename $0` + local this_script_name=$( basename -- "$0"; ) + local this_script_dir=$( dirname -- "$0"; ) local script_provenance_name=${this_script_name}.`date +%Y%m%d-%H%M%S` - cp -vp ${this_script_name} ${script_provenance_dir}/${script_provenance_name} + cp -vp "${this_script_dir}/${this_script_name}" ${script_provenance_dir}/${script_provenance_name} } From 33b4eaa5c04b7f1a8e866c5ef4b174e1c8016b1d Mon Sep 17 00:00:00 2001 From: Naser Mahfouz Date: Tue, 30 Jul 2024 20:44:30 -0400 Subject: [PATCH 274/451] Use $PSCRATCH instead --- run_e3sm.template.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/run_e3sm.template.sh b/run_e3sm.template.sh index 1a55dc933d87..e2a5b603ba79 100755 --- a/run_e3sm.template.sh +++ b/run_e3sm.template.sh @@ -43,8 +43,8 @@ readonly GET_REFCASE=TRUE #readonly RUN_REFDATE="" # same as MODEL_START_DATE for 'branch', can be different for 'hybrid' # Set paths -readonly CODE_ROOT="/pscratch/sd/${USER:0:1}/${USER}/e3sm-scratch/${MACHINE}/your_casename/code/${CHECKOUT}" -readonly CASE_ROOT="/pscratch/sd/${USER:0:1}/${USER}/e3sm-scratch/${MACHINE}/${CASE_NAME}" +readonly CASE_ROOT="${PSCRATCH}/e3sm-scratch/${MACHINE}/${CASE_NAME}" +readonly CODE_ROOT="${PSCRATCH}/e3sm-scratch/${MACHINE}/${CASE_NAME}/code/${CHECKOUT}" # Sub-directories readonly CASE_BUILD_DIR=${CASE_ROOT}/build From a7369fb62f48b293342ec637241a4f9d38cbbe2f Mon Sep 17 00:00:00 2001 From: Xylar Asay-Davis Date: Wed, 31 Jul 2024 16:34:38 -0500 Subject: [PATCH 275/451] Fix bottomDepth when filling bathymetry holes In MPAS-Ocean init mode, when filling holes in the bathymetry (cells with deepest layers that are deeper than any of their neighbors) as part of the Haney-number-constrained vertical coordinate used for ice shelves, the bottom depth was not also being updated correctly for some cells. This merge fixes the issue for cells in the z-level region of the ocean (far from ice-shelf cavities) by setting the bottom depth to the deepest depth within the same z level as the deepest neighbor. --- .../mpas-ocean/src/mode_init/mpas_ocn_init_vertical_grids.F | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/components/mpas-ocean/src/mode_init/mpas_ocn_init_vertical_grids.F b/components/mpas-ocean/src/mode_init/mpas_ocn_init_vertical_grids.F index 5c0ac5a0e114..d84291ed376b 100644 --- a/components/mpas-ocean/src/mode_init/mpas_ocn_init_vertical_grids.F +++ b/components/mpas-ocean/src/mode_init/mpas_ocn_init_vertical_grids.F @@ -1480,6 +1480,7 @@ subroutine ocn_init_vertical_grid_with_max_rx1(domain, iErr) call mpas_pool_get_dimension(meshPool, 'nCellsSolve', nCellsSolve) call mpas_pool_get_array(meshPool, 'nEdgesOnCell', nEdgesOnCell) call mpas_pool_get_array(meshPool, 'cellsOnCell', cellsOnCell) + call mpas_pool_get_array(meshPool, 'bottomDepth', bottomDepth) ! Fill bathymetry holes, i.e. single cells that are deeper than all neighbors. ! These cells can collect tracer extrema and are not able to use @@ -1497,6 +1498,9 @@ subroutine ocn_init_vertical_grid_with_max_rx1(domain, iErr) if (maxLevelCell(iCell) > maxLevelNeighbors) then maxLevelCell(iCell) = maxLevelNeighbors + if (smoothingMask(iCell) == 0) then + bottomDepth(iCell) = refBottomDepth(maxLevelNeighbors) + end if end if end do From 48fb3c0faee1391a078c76dcd1d80b2cf2a5de38 Mon Sep 17 00:00:00 2001 From: Walter Hannah Date: Wed, 31 Jul 2024 17:17:03 -0500 Subject: [PATCH 276/451] update PAM submodule --- components/eam/src/physics/crm/pam/external | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/components/eam/src/physics/crm/pam/external b/components/eam/src/physics/crm/pam/external index 5931666c95a3..3ea20ad38f28 160000 --- a/components/eam/src/physics/crm/pam/external +++ b/components/eam/src/physics/crm/pam/external @@ -1 +1 @@ -Subproject commit 5931666c95a3b75ae63fbe5bff6e743e74cb2c0a +Subproject commit 3ea20ad38f286730973429e0d491420a6f599f11 From 7d69007b0ec4a15872584ebd6faa38642cfe4729 Mon Sep 17 00:00:00 2001 From: Walter Hannah Date: Wed, 31 Jul 2024 17:17:35 -0500 Subject: [PATCH 277/451] add negative mass checks for pam_debug.h --- components/eam/src/physics/crm/pam/pam_debug.h | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/components/eam/src/physics/crm/pam/pam_debug.h b/components/eam/src/physics/crm/pam/pam_debug.h index 7e54f437f691..a168710afc6d 100644 --- a/components/eam/src/physics/crm/pam/pam_debug.h +++ b/components/eam/src/physics/crm/pam/pam_debug.h @@ -134,7 +134,9 @@ void pam_debug_check_state( pam::PamCoupler &coupler, int id, int nstep ) { const auto is_neg_t_atm = temp(k,j,i,iens)<0; const auto is_neg_d_atm = rhod(k,j,i,iens)<0; const auto is_neg_q_atm = rhov(k,j,i,iens)<0; - if ( is_neg_t_atm || is_neg_q_atm || is_neg_d_atm ) { + const auto is_neg_c_atm = rhoc(k,j,i,iens)<0; + const auto is_neg_i_atm = rhoi(k,j,i,iens)<0; + if ( is_neg_t_atm || is_neg_q_atm || is_neg_d_atm || is_neg_c_atm || is_neg_i_atm ) { auto phis = input_phis(iens)/grav; printf("PAM-DEBUG neg-found - st:%3.3d id:%2.2d k:%3.3d i:%3.3d n:%3.3d y:%5.1f x:%5.1f ph:%6.1f -- t:%8.2g rd:%8.2g rv:%8.2g rc:%8.2g ri:%8.2g u:%8.2g w:%8.2g -- t:%8.2g rd:%8.2g rv:%8.2g rc:%8.2g ri:%8.2g u:%8.2g w:%8.2g \n", nstep,id,k,i,iens,lat(iens),lon(iens),phis, From 1d9dae3ad3016776b8aad0a03be1fd7b5d14fb4d Mon Sep 17 00:00:00 2001 From: Yunpeng Shan Date: Wed, 31 Jul 2024 21:34:19 -0500 Subject: [PATCH 278/451] Add outfld lines for in-cloud properties output. --- components/eam/src/physics/p3/eam/micro_p3_interface.F90 | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/components/eam/src/physics/p3/eam/micro_p3_interface.F90 b/components/eam/src/physics/p3/eam/micro_p3_interface.F90 index bb6e164b4a14..c6c533329a3f 100644 --- a/components/eam/src/physics/p3/eam/micro_p3_interface.F90 +++ b/components/eam/src/physics/p3/eam/micro_p3_interface.F90 @@ -1630,6 +1630,12 @@ subroutine micro_p3_tend(state, ptend, dtime, pbuf) call outfld('FREQI', freqi, pcols, lchnk) call outfld('FREQR', freqr, psetcols, lchnk) call outfld('CDNUMC', cdnumc, pcols, lchnk) +! call outfld('CLOUDFRAC_LIQ_MICRO', cld_frac_l, pcols, lchnk) call outfld('CLOUDFRAC_ICE_MICRO', cld_frac_i, pcols, lchnk) From dfeed49c6d27ae162dea07c6c3fda869f4451234 Mon Sep 17 00:00:00 2001 From: Azamat Mametjanov Date: Thu, 1 Aug 2024 15:23:44 -0500 Subject: [PATCH 279/451] Add S,M,L PEs for v3-grid WCYCL cases on Anvil --- cime_config/allactive/config_pesall.xml | 59 +++++++++++++++++++++++++ 1 file changed, 59 insertions(+) diff --git a/cime_config/allactive/config_pesall.xml b/cime_config/allactive/config_pesall.xml index c0c48b954e3c..2a24d6683c8f 100644 --- a/cime_config/allactive/config_pesall.xml +++ b/cime_config/allactive/config_pesall.xml @@ -1322,6 +1322,65 @@ + + + --compset WCYCL* --res ne30pg2_r05_IcoswISC30E3r5 on 25 nodes pure-MPI, ~2.9 sypd + + 675 + 324 + 324 + 360 + 216 + 684 + + + 0 + 360 + 360 + 0 + 684 + 0 + + + + --compset WCYCL* --res ne30pg2_r05_IcoswISC30E3r5 on 50 nodes pure-MPI, ~5.6 sypd + + 1350 + 648 + 648 + 720 + 432 + 1368 + + + 0 + 720 + 720 + 0 + 1368 + 0 + + + + --compset WCYCL* --res ne30pg2_r05_IcoswISC30E3r5 on 100 nodes pure-MPI, ~8.8 sypd + + 2700 + 1260 + 1260 + 1440 + 900 + 2700 + + + 0 + 1440 + 1440 + 0 + 2700 + 0 + + + gcp12 --compset WCYCL* --res ne30pg2_r05_IcoswISC30E3r5 on 4 nodes From 3758fdf6b02def31551d9c4642d963d458e0a545 Mon Sep 17 00:00:00 2001 From: jayeshkrishna Date: Thu, 1 Aug 2024 21:59:29 -0500 Subject: [PATCH 280/451] Upgrading to SCORPIO v1.6.5 SCORPIO v1.6.5 includes the following changes/fixes, * Fix to support CDF5 file format when PnetCDF is not available This upgrade fixes runtime issues when writing large variables using the CDF5 file format on machines (like mappy) that do not have support for PnetCDF --- externals/scorpio | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/externals/scorpio b/externals/scorpio index 34422f362e9e..804f87c48fc9 160000 --- a/externals/scorpio +++ b/externals/scorpio @@ -1 +1 @@ -Subproject commit 34422f362e9e83b5bc5e013b5992fc2555d02ece +Subproject commit 804f87c48fc9013009307b806d1aff2afa3a0d7c From 7581ae045f308b6544e61f9c30db20536441a27a Mon Sep 17 00:00:00 2001 From: Naser Mahfouz Date: Mon, 5 Aug 2024 09:19:07 -0400 Subject: [PATCH 281/451] fix link to best practices, save code in home --- run_e3sm.template.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/run_e3sm.template.sh b/run_e3sm.template.sh index e2a5b603ba79..413f2bf75286 100755 --- a/run_e3sm.template.sh +++ b/run_e3sm.template.sh @@ -3,7 +3,7 @@ # E3SM Coupled Model Group run_e3sm script template. # # Bash coding style inspired by: -# http://kfirlavi.herokuapp.com/blog/2012/11/14/defensive-bash-programming +# https://web.archive.org/web/20200620202413/http://kfirlavi.herokuapp.com/blog/2012/11/14/defensive-bash-programming main() { @@ -44,7 +44,7 @@ readonly GET_REFCASE=TRUE # Set paths readonly CASE_ROOT="${PSCRATCH}/e3sm-scratch/${MACHINE}/${CASE_NAME}" -readonly CODE_ROOT="${PSCRATCH}/e3sm-scratch/${MACHINE}/${CASE_NAME}/code/${CHECKOUT}" +readonly CODE_ROOT="${HOME}/E3SMv3/code/${CHECKOUT}" # Sub-directories readonly CASE_BUILD_DIR=${CASE_ROOT}/build From 05e03144b859e8e69e71b28d8aeec91ec25bb6c9 Mon Sep 17 00:00:00 2001 From: Althea Denlinger Date: Fri, 2 Aug 2024 13:44:00 -0600 Subject: [PATCH 282/451] Add updated Omega link --- docs/index.md | 1 + 1 file changed, 1 insertion(+) diff --git a/docs/index.md b/docs/index.md index 3dd05a4f62fc..4d979cf0afee 100644 --- a/docs/index.md +++ b/docs/index.md @@ -23,6 +23,7 @@ research problems and Department of Energy mission needs while efficiently using - [MOSART](./MOSART/index.md) - [MPAS-Ocean](./MPAS-Ocean/index.md) - [MPAS-seaice](./MPAS-seaice/index.md) +- [Omega](https://docs.e3sm.org/Omega/omega/) — not yet supported. ## Tools From 6a90aec81038b1b79a69c2755cce7b067db04f5f Mon Sep 17 00:00:00 2001 From: Azamat Mametjanov Date: Wed, 7 Aug 2024 21:05:33 -0500 Subject: [PATCH 283/451] Update ANL LCRC Improv --- cime_config/machines/config_machines.xml | 3 ++- components/eam/cime_config/config_pes.xml | 22 +++++++++++----------- 2 files changed, 13 insertions(+), 12 deletions(-) diff --git a/cime_config/machines/config_machines.xml b/cime_config/machines/config_machines.xml index 45ed919b4d03..6cd9d585a25b 100644 --- a/cime_config/machines/config_machines.xml +++ b/cime_config/machines/config_machines.xml @@ -3006,7 +3006,7 @@ module module - + cmake/3.27.4 @@ -3023,6 +3023,7 @@ /lcrc/group/e3sm/soft/improv/pnetcdf/1.12.3/gcc-12.3.0/openmpi-4.1.6 /lcrc/group/e3sm/soft/improv/pnetcdf/1.12.3/gcc-12.3.0/openmpi-4.1.6/bin:/lcrc/group/e3sm/soft/improv/netcdf-fortran/4.6.1b/gcc-12.3.0/openmpi-4.1.6/bin:/lcrc/group/e3sm/soft/improv/netcdf-c/4.9.2b/gcc-12.3.0/openmpi-4.1.6/bin:/lcrc/group/e3sm/soft/improv/openmpi/4.1.6/gcc-12.3.0/bin:/lcrc/group/e3sm/soft/perl/improv/bin:$ENV{PATH} $SHELL{lp=/lcrc/group/e3sm/soft/improv/netlib-lapack/3.12.0/gcc-12.3.0:/lcrc/group/e3sm/soft/improv/pnetcdf/1.12.3/gcc-12.3.0/openmpi-4.1.6/lib:/lcrc/group/e3sm/soft/improv/netcdf-fortran/4.6.1b/gcc-12.3.0/openmpi-4.1.6/lib:/lcrc/group/e3sm/soft/improv/netcdf-c/4.9.2b/gcc-12.3.0/openmpi-4.1.6/lib:/opt/pbs/lib:/lcrc/group/e3sm/soft/improv/openmpi/4.1.6/gcc-12.3.0/lib; if [ -z "$LD_LIBRARY_PATH" ]; then echo $lp; else echo "$lp:$LD_LIBRARY_PATH"; fi} + ^lockedfile 128M diff --git a/components/eam/cime_config/config_pes.xml b/components/eam/cime_config/config_pes.xml index 002e41d5a883..2b50fded44a2 100644 --- a/components/eam/cime_config/config_pes.xml +++ b/components/eam/cime_config/config_pes.xml @@ -772,17 +772,17 @@ - - improv pelayout for tri-grid BGC tests with EAM+DOCN - - -4 - -4 - -4 - -4 - -4 - -4 - -4 - -4 + + improv pelayout for any EAM compset on ne30np4.pg2 grid + + -6 + -6 + -6 + -6 + -6 + -6 + -6 + -6 From d879143ed2c5593909a30c4aeb26f1f32530df34 Mon Sep 17 00:00:00 2001 From: Matthew Hoffman Date: Mon, 6 May 2024 17:02:39 -0500 Subject: [PATCH 284/451] add 2 new AIS meshes for MALI This commit adds the mpas.ais4to20km and mpas.ais8to30km meshes for MALI. Mapping file entries are added but the mapping files themselves don't exist yet. --- cime_config/config_grids.xml | 117 ++++++++++++++++++ .../mpas-albany-landice/cime_config/buildnml | 20 ++- driver-mct/cime_config/config_component.xml | 2 +- driver-moab/cime_config/config_component.xml | 2 +- 4 files changed, 134 insertions(+), 7 deletions(-) diff --git a/cime_config/config_grids.xml b/cime_config/config_grids.xml index 6d1ca9d6b8e5..bc4af123c519 100755 --- a/cime_config/config_grids.xml +++ b/cime_config/config_grids.xml @@ -1845,6 +1845,8 @@ + + ne30np4 ne30np4 @@ -1865,6 +1867,8 @@ oEC60to30v3wLI + + ne30np4 ne30np4 @@ -1995,6 +1999,8 @@ gx1v6 + + 0.9x1.25 0.9x1.25 @@ -2015,6 +2021,46 @@ oQU240wLI + + ne30np4.pg2 + r05 + IcoswISC30E3r5 + r05 + mpas.ais8to30km + null + IcoswISC30E3r5 + + + + TL319 + TL319 + IcoswISC30E3r5 + JRA025 + mpas.ais8to30km + null + IcoswISC30E3r5 + + + + ne30np4.pg2 + r05 + IcoswISC30E3r5 + r05 + mpas.ais4to20km + null + IcoswISC30E3r5 + + + + TL319 + TL319 + IcoswISC30E3r5 + JRA025 + mpas.ais4to20km + null + IcoswISC30E3r5 + + @@ -3289,6 +3335,18 @@ mpas.ais20km is a uniform-resolution 20km MALI grid of the Antarctic Ice Sheet. It is primarily intended for testing. + + 98341 + 1 + mpas.ais8to30km is a variable resolution MALI mesh of the Antarctic Ice Sheet with resolution varying from 8 km in fast flowing regions and near the ice-sheet margins to 30 km in the ice-sheet interior. It behaves reasonably well for most of the ice sheet but results in Thwaites Glacier retreating too rapidly due to insufficient resolution there. It is meant as a cheaper alternative to mpas.ais4to20km for testing realistic conditions. + + + + 385379 + 1 + mpas.ais4to20km is a variable resolution MALI mesh of the Antarctic Ice Sheet with resolution varying from 4 km in fast flowing regions and near the ice-sheet margins to 20 km in the ice-sheet interior. It was the primary mesh and initial condition used for ISMIP6-Antarctica-2300 and is the primary Antarctic mesh to use for E3SM v3 simulation and development with an active Antarctic Ice Sheet component. + + @@ -5632,6 +5690,65 @@ cpl/gridmaps/mpas.ais20km/map_ais20km_to_oQU240wLI_esmfnearestdtos.20240509.nc + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/components/mpas-albany-landice/cime_config/buildnml b/components/mpas-albany-landice/cime_config/buildnml index 0a3b35df93eb..62e8dbc92449 100755 --- a/components/mpas-albany-landice/cime_config/buildnml +++ b/components/mpas-albany-landice/cime_config/buildnml @@ -62,16 +62,26 @@ def buildnml(case, caseroot, compname): grid_prefix += 'aisgis20km' decomp_date += '20190326' decomp_prefix += 'mpasli.graph.info.' - elif glc_grid == 'mpas.gis20km': - grid_date += '20210824' - grid_prefix += 'gis_20km_r01' - decomp_date += '150922' - decomp_prefix += 'mpasli.graph.info.' elif glc_grid == 'mpas.ais20km': grid_date += '150910' grid_prefix += 'ais20km' decomp_date += '150910' decomp_prefix += 'mpasli.graph.info.' + elif glc_grid == 'mpas.ais8to30km': + grid_date += '20231222' + grid_prefix += 'ais8to30km' + decomp_date += '240507' + decomp_prefix += 'mpasli.graph.info.' + elif glc_grid == 'mpas.ais4to20km': + grid_date += '20230105' + grid_prefix += 'ais4to20km' + decomp_date += '240507' + decomp_prefix += 'mpasli.graph.info.' + elif glc_grid == 'mpas.gis20km': + grid_date += '20210824' + grid_prefix += 'gis_20km_r01' + decomp_date += '150922' + decomp_prefix += 'mpasli.graph.info.' elif glc_grid == 'mpas.gis1to10km': grid_date += '20210824' grid_prefix += 'gis_1to10km_r01' diff --git a/driver-mct/cime_config/config_component.xml b/driver-mct/cime_config/config_component.xml index 271c13139555..8cddad0abf89 100644 --- a/driver-mct/cime_config/config_component.xml +++ b/driver-mct/cime_config/config_component.xml @@ -1085,7 +1085,7 @@ char - mpas.aisgis20km,mpas.gis20km,mpas.ais20km,mpas.gis1to10km,mpas.gis1to10kmR2,null + mpas.aisgis20km,mpas.ais20km,mpas.ais8to30km,mpas.ais4to20km,mpas.gis20km,mpas.gis1to10km,mpas.gis1to10kmR2,null mpas.gis20km build_grid env_build.xml diff --git a/driver-moab/cime_config/config_component.xml b/driver-moab/cime_config/config_component.xml index 0f21eeb02097..d3685126c61e 100644 --- a/driver-moab/cime_config/config_component.xml +++ b/driver-moab/cime_config/config_component.xml @@ -1085,7 +1085,7 @@ char - mpas.aisgis20km,mpas.gis20km,mpas.ais20km,mpas.gis1to10km,gis1to10kmR2,null + mpas.aisgis20km,mpas.ais20km,mpas.ais8to30km,mpas.ais4to20km,mpas.gis20km,mpas.gis1to10km,mpas.gis1to10kmR2,null mpas.gis20km build_grid env_build.xml From 8fc885168ba6c255d8a4e064fa83bce8a81e3c4d Mon Sep 17 00:00:00 2001 From: Matthew Hoffman Date: Tue, 7 May 2024 11:22:40 -0500 Subject: [PATCH 285/451] Add TL319_oQU240wLI_ais8to30 grid This will provide a low res testing configuration. Mapping files are listed but the filenames not yet added. --- cime_config/config_grids.xml | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/cime_config/config_grids.xml b/cime_config/config_grids.xml index bc4af123c519..ee618e83dcb2 100755 --- a/cime_config/config_grids.xml +++ b/cime_config/config_grids.xml @@ -2021,6 +2021,16 @@ oQU240wLI + + TL319 + TL319 + oQU240wLI + JRA025 + mpas.ais8to30km + null + oQU240wLI + + ne30np4.pg2 r05 @@ -5708,6 +5718,17 @@ + + + + + + + + + + + From a264ba99ab7cf6c7174cd3b0cf2faf2d098bffea Mon Sep 17 00:00:00 2001 From: Matthew Hoffman Date: Wed, 26 Jun 2024 12:46:17 -0500 Subject: [PATCH 286/451] Correct filenames in buildnml --- components/mpas-albany-landice/cime_config/buildnml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/components/mpas-albany-landice/cime_config/buildnml b/components/mpas-albany-landice/cime_config/buildnml index 62e8dbc92449..5f5caed83a80 100755 --- a/components/mpas-albany-landice/cime_config/buildnml +++ b/components/mpas-albany-landice/cime_config/buildnml @@ -69,12 +69,12 @@ def buildnml(case, caseroot, compname): decomp_prefix += 'mpasli.graph.info.' elif glc_grid == 'mpas.ais8to30km': grid_date += '20231222' - grid_prefix += 'ais8to30km' + grid_prefix += 'ais_8to30km' decomp_date += '240507' decomp_prefix += 'mpasli.graph.info.' elif glc_grid == 'mpas.ais4to20km': grid_date += '20230105' - grid_prefix += 'ais4to20km' + grid_prefix += 'ais_4to20km' decomp_date += '240507' decomp_prefix += 'mpasli.graph.info.' elif glc_grid == 'mpas.gis20km': From 687149b3bbc9d2734fa8e88eb4f34f02e749cca2 Mon Sep 17 00:00:00 2001 From: Jon Wolfe Date: Wed, 3 Jul 2024 14:21:58 -0500 Subject: [PATCH 287/451] Add mapping files for ais4to20 and ais8to30 --- cime_config/config_grids.xml | 80 ++++++++++++++++++------------------ 1 file changed, 40 insertions(+), 40 deletions(-) diff --git a/cime_config/config_grids.xml b/cime_config/config_grids.xml index ee618e83dcb2..0f1c3512ec8a 100755 --- a/cime_config/config_grids.xml +++ b/cime_config/config_grids.xml @@ -5705,39 +5705,39 @@ - - - - + cpl/gridmaps/r05/map_r05_to_ais8to30_traave.20240701.nc + cpl/gridmaps/r05/map_r05_to_ais8to30_trbilin.20240701.nc + cpl/gridmaps/mpas.ais8to30km/map_ais8to30_to_r05_traave.20240701.nc + cpl/gridmaps/mpas.ais8to30km/map_ais8to30_to_r05_traave.20240701.nc - - - - + cpl/gridmaps/TL319/map_TL319_to_ais8to30_traave.20240701.nc + cpl/gridmaps/TL319/map_TL319_to_ais8to30_trbilin.20240701.nc + cpl/gridmaps/mpas.ais8to30km/map_ais8to30_to_TL319_traave.20240701.nc + cpl/gridmaps/mpas.ais8to30km/map_ais8to30_to_TL319_traave.20240701.nc - - - - - - - - + cpl/gridmaps/oQU240wLI/map_oQU240wLI-nomask_to_ais8to30_esmfaave.20240701.nc + cpl/gridmaps/oQU240wLI/map_oQU240wLI-nomask_to_ais8to30_esmfbilin.20240701.nc + cpl/gridmaps/mpas.ais8to30km/map_ais8to30_to_oQU240wLI-nomask_esmfaave.20240701.nc + cpl/gridmaps/mpas.ais8to30km/map_ais8to30_to_oQU240wLI-nomask_esmfbilin.20240701.nc + cpl/gridmaps/mpas.ais8to30km/map_ais8to30_to_oQU240wLI-nomask_esmfaave.20240701.nc + cpl/gridmaps/mpas.ais8to30km/map_ais8to30_to_oQU240wLI-nomask_esmfbilin.20240701.nc + cpl/gridmaps/mpas.ais8to30km/map_ais8to30_to_oQU240wLI-nomask_esmfnearestdtos.20240701.nc + cpl/gridmaps/mpas.ais8to30km/map_ais8to30_to_oQU240wLI_esmfnearestdtos.20240701.nc - - - - - - - - + cpl/gridmaps/IcoswISC30E3r5/map_IcoswISC30E3r5-nomask_to_ais8to30_esmfaave.20240701.nc + cpl/gridmaps/IcoswISC30E3r5/map_IcoswISC30E3r5-nomask_to_ais8to30_esmfbilin.20240701.nc + cpl/gridmaps/mpas.ais8to30km/map_ais8to30_to_IcoswISC30E3r5-nomask_esmfaave.20240701.nc + cpl/gridmaps/mpas.ais8to30km/map_ais8to30_to_IcoswISC30E3r5-nomask_esmfbilin.20240701.nc + cpl/gridmaps/mpas.ais8to30km/map_ais8to30_to_IcoswISC30E3r5-nomask_esmfaave.20240701.nc + cpl/gridmaps/mpas.ais8to30km/map_ais8to30_to_IcoswISC30E3r5-nomask_esmfbilin.20240701.nc + cpl/gridmaps/mpas.ais8to30km/map_ais8to30_to_IcoswISC30E3r5-nomask_esmfnearestdtos.20240701.nc + cpl/gridmaps/mpas.ais8to30km/map_ais8to30_to_IcoswISC30E3r5_esmfnearestdtos.20240701.nc @@ -5745,28 +5745,28 @@ - - - - + cpl/gridmaps/r05/map_r05_to_ais4to20_traave.20240701.nc + cpl/gridmaps/r05/map_r05_to_ais4to20_trbilin.20240701.nc + cpl/gridmaps/mpas.ais4to20km/map_ais4to20_to_r05_traave.20240701.nc + cpl/gridmaps/mpas.ais4to20km/map_ais4to20_to_r05_traave.20240701.nc - - - - + cpl/gridmaps/TL319/map_TL319_to_ais4to20_traave.20240701.nc + cpl/gridmaps/TL319/map_TL319_to_ais4to20_trbilin.20240701.nc + cpl/gridmaps/mpas.ais4to20km/map_ais4to20_to_TL319_traave.20240701.nc + cpl/gridmaps/mpas.ais4to20km/map_ais4to20_to_TL319_traave.20240701.nc - - - - - - - - + cpl/gridmaps/IcoswISC30E3r5/map_IcoswISC30E3r5-nomask_to_ais4to20_esmfaave.20240701.nc + cpl/gridmaps/IcoswISC30E3r5/map_IcoswISC30E3r5-nomask_to_ais4to20_esmfbilin.20240701.nc + cpl/gridmaps/mpas.ais4to20km/map_ais4to20_to_IcoswISC30E3r5-nomask_esmfaave.20240701.nc + cpl/gridmaps/mpas.ais4to20km/map_ais4to20_to_IcoswISC30E3r5-nomask_esmfbilin.20240701.nc + cpl/gridmaps/mpas.ais4to20km/map_ais4to20_to_IcoswISC30E3r5-nomask_esmfaave.20240701.nc + cpl/gridmaps/mpas.ais4to20km/map_ais4to20_to_IcoswISC30E3r5-nomask_esmfbilin.20240701.nc + cpl/gridmaps/mpas.ais4to20km/map_ais4to20_to_IcoswISC30E3r5-nomask_esmfnearestdtos.20240701.nc + cpl/gridmaps/mpas.ais4to20km/map_ais4to20_to_IcoswISC30E3r5_esmfnearestdtos.20240701.nc From 4975d490b2236fcf8c78901bc2f27e6322519b60 Mon Sep 17 00:00:00 2001 From: Matthew Hoffman Date: Wed, 24 Jul 2024 09:49:21 -0500 Subject: [PATCH 288/451] Update mpas.ais4to20km and mpas.ais8to30km meshes to new versions The updated mpas.ais4to20km mesh correctly handles merging bedmap2 for Amundsen Sea Sector into the BedMachine geometry elsewhere. The previous version had an error in how that was done. The updated mpas.ais8to30km mesh rolls back from an inadequately tested 8km mesh to the version that was used in ISMIP6-AIS-2300. --- components/mpas-albany-landice/cime_config/buildnml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/components/mpas-albany-landice/cime_config/buildnml b/components/mpas-albany-landice/cime_config/buildnml index 5f5caed83a80..4d927c4370fd 100755 --- a/components/mpas-albany-landice/cime_config/buildnml +++ b/components/mpas-albany-landice/cime_config/buildnml @@ -68,12 +68,12 @@ def buildnml(case, caseroot, compname): decomp_date += '150910' decomp_prefix += 'mpasli.graph.info.' elif glc_grid == 'mpas.ais8to30km': - grid_date += '20231222' + grid_date += '20221027' grid_prefix += 'ais_8to30km' decomp_date += '240507' decomp_prefix += 'mpasli.graph.info.' elif glc_grid == 'mpas.ais4to20km': - grid_date += '20230105' + grid_date += '20240708' grid_prefix += 'ais_4to20km' decomp_date += '240507' decomp_prefix += 'mpasli.graph.info.' From 0a92e253ec7f155e7d6483d07f894ef50969ba7b Mon Sep 17 00:00:00 2001 From: Matthew Hoffman Date: Wed, 24 Jul 2024 15:08:33 -0500 Subject: [PATCH 289/451] Add FOLISIO compset This commit adds a FOLISIO compset (First-Order Land Ice, Sea Ice, Ocean) that uses the Albany First-Order velocity solver in MALI instead of the standard shallow-ice approximation solver. The SIA solver is inappropriate for Antarctica and was causing CFL violations when used with the new mesh, making it not practical to use even for smoketesting. --- cime_config/allactive/config_compsets.xml | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/cime_config/allactive/config_compsets.xml b/cime_config/allactive/config_compsets.xml index 6ecf2fbf29c6..21032c483714 100755 --- a/cime_config/allactive/config_compsets.xml +++ b/cime_config/allactive/config_compsets.xml @@ -421,6 +421,11 @@ 2000_DATM%JRA-1p5_SLND_MPASSI_MPASO%DATMFORCED_DROF%JRA-1p5_MALI%SIA_SWAV + + MPAS_FOLISIO_JRA1p5 + 2000_DATM%JRA-1p5_SLND_MPASSI_MPASO%DATMFORCED_DROF%JRA-1p5_MALI_SWAV + + E1850C5ELM From c98564b256b19cff0875b3417f1e1d22ebd6fd44 Mon Sep 17 00:00:00 2001 From: Jon Wolfe Date: Wed, 14 Aug 2024 11:54:06 -0500 Subject: [PATCH 290/451] Update bld files to match Registry --- .../mpas-albany-landice/bld/build-namelist | 2 ++ .../bld/build-namelist-section | 2 ++ .../namelist_files/namelist_defaults_mali.xml | 4 +++- .../namelist_definition_mali.xml | 24 +++++++++++++++---- 4 files changed, 27 insertions(+), 5 deletions(-) diff --git a/components/mpas-albany-landice/bld/build-namelist b/components/mpas-albany-landice/bld/build-namelist index 068363fb98c6..15272f7a2dab 100755 --- a/components/mpas-albany-landice/bld/build-namelist +++ b/components/mpas-albany-landice/bld/build-namelist @@ -663,6 +663,7 @@ add_default($nl, 'config_SGH_bed_roughness'); add_default($nl, 'config_SGH_bed_roughness_max'); add_default($nl, 'config_SGH_creep_coefficient'); add_default($nl, 'config_SGH_englacial_porosity'); +add_default($nl, 'config_SGH_use_iceThicknessHydro'); add_default($nl, 'config_SGH_chnl_active'); add_default($nl, 'config_SGH_chnl_include_DCFL'); add_default($nl, 'config_SGH_chnl_alpha'); @@ -673,6 +674,7 @@ add_default($nl, 'config_SGH_incipient_channel_width'); add_default($nl, 'config_SGH_include_pressure_melt'); add_default($nl, 'config_SGH_shmip_forcing'); add_default($nl, 'config_SGH_basal_melt'); +add_default($nl, 'config_SGH_iter_smooth_waterPressureSlopeNormal'); ################################## # Namelist group: AM_globalStats # diff --git a/components/mpas-albany-landice/bld/build-namelist-section b/components/mpas-albany-landice/bld/build-namelist-section index 8f4bc139c98a..4b5e05ec3cd5 100644 --- a/components/mpas-albany-landice/bld/build-namelist-section +++ b/components/mpas-albany-landice/bld/build-namelist-section @@ -225,6 +225,7 @@ add_default($nl, 'config_SGH_bed_roughness'); add_default($nl, 'config_SGH_bed_roughness_max'); add_default($nl, 'config_SGH_creep_coefficient'); add_default($nl, 'config_SGH_englacial_porosity'); +add_default($nl, 'config_SGH_use_iceThicknessHydro'); add_default($nl, 'config_SGH_chnl_active'); add_default($nl, 'config_SGH_chnl_include_DCFL'); add_default($nl, 'config_SGH_chnl_alpha'); @@ -235,6 +236,7 @@ add_default($nl, 'config_SGH_incipient_channel_width'); add_default($nl, 'config_SGH_include_pressure_melt'); add_default($nl, 'config_SGH_shmip_forcing'); add_default($nl, 'config_SGH_basal_melt'); +add_default($nl, 'config_SGH_iter_smooth_waterPressureSlopeNormal'); ################################## # Namelist group: AM_globalStats # diff --git a/components/mpas-albany-landice/bld/namelist_files/namelist_defaults_mali.xml b/components/mpas-albany-landice/bld/namelist_files/namelist_defaults_mali.xml index 5cebbf9cd136..535fdbdc4d49 100644 --- a/components/mpas-albany-landice/bld/namelist_files/namelist_defaults_mali.xml +++ b/components/mpas-albany-landice/bld/namelist_files/namelist_defaults_mali.xml @@ -26,7 +26,7 @@ 'none' -'0002-00-00_00:00:00' +2 'mpas_to_grid.nc' 'grid_to_mpas.nc' @@ -184,6 +184,7 @@ 0.1 0.04 0.01 +.true. .false. .false. 1.25 @@ -194,6 +195,7 @@ .true. 'none' 'file' +1 .true. diff --git a/components/mpas-albany-landice/bld/namelist_files/namelist_definition_mali.xml b/components/mpas-albany-landice/bld/namelist_files/namelist_definition_mali.xml index c04d52840a6c..e16e7042a2cb 100644 --- a/components/mpas-albany-landice/bld/namelist_files/namelist_definition_mali.xml +++ b/components/mpas-albany-landice/bld/namelist_files/namelist_definition_mali.xml @@ -194,11 +194,11 @@ Valid values: 'none', 'data', 'sealevelmodel' Default: Defined in namelist_defaults.xml - -Time interval at which the sea-level model is called by MALI. The interval has to be an even multiple of the option 'config_adaptive_timestep_force_interval +Time interval at which the sea-level model is called by MALI. Only integer years are currently supported. The user must set 'dt1' in namelist.sealevel to match this value. Note that the user needs to set config_adaptive_timestep_force_interval to divide evenly into config_slm_coupling_interval. Also, restart file output_interval needs to be a multiple of config_slm_coupling_interval. -Valid values: Any time interval of the format 'YYYY-MM-DD_HH:MM:SS' +Valid values: Any positive integer Default: Defined in namelist_defaults.xml @@ -1218,7 +1218,7 @@ Default: Defined in namelist_defaults.xml -Selection of the method for calculating the tangent component of slope at edges. 'from_vertex_barycentric' interpolates scalar values from cell centers to vertices using the barycentric interpolation routine in operators (mpas_cells_to_points_using_baryweights) and then calculates the slope between vertices. It works for obtuse triangles, but will not work correctly across the edges of periodic meshes. 'from_vertex_barycentric_kiteareas' interpolates scalar values from cell centers to vertices using barycentric interpolation based on kiterea values and then calculates the slope between vertices. It will work across the edges of periodic meshes, but will not work correctly for obtuse triangles. 'from_normal_slope' uses the vector operator mpas_tangential_vector_1d to calculate the tangent slopes from the normal slopes on the edges of the adjacent cells. It will work for any mesh configuration, but is the least accurate method. +Selection of the method for calculating the tangent component of slope at edges. 'from_vertex_barycentric' interpolates scalar values from cell centers to vertices using the barycentric interpolation routine in operators (mpas_cells_to_points_using_baryweights) and then calculates the slope between vertices. It works for obtuse triangles, but will not work correctly across the edges of periodic meshes. 'from_vertex_barycentric_kiteareas' interpolates scalar values from cell centers to vertices using barycentric interpolation based on kiterea values and then calculates the slope between vertices. It will work across the edges of periodic meshes, but will not work correctly for obtuse triangles. 'from_normal_slope' uses the vector operator mpas_tangential_vector_1d to calculate the tangent slopes from the normal slopes on the edges of the adjacent cells. It will work for any mesh configuration. 'from_normal_slope' uses a larger stencil, so may therefore produce a smoother 'gradMagPhiEdge' field. Detailed testing yielded nearly identical results between 'from_normal_slope' and 'from_vertex_barycentric' methods, but 'from_normal_slope' seemed to produce slightly more stable results at the grounding line. Valid values: 'from_vertex_barycentric', 'from_vertex_barycentric_kiteareas', 'from_normal_slope' Default: Defined in namelist_defaults.xml @@ -1320,6 +1320,14 @@ Valid values: positive real number Default: Defined in namelist_defaults.xml + +Option to use an altered ice thickness field called iceThicknessHydro that replaces local maxima/minima in upperSurface with a mean of the cells neighbors. This option has no significant effect on the behavior of the model but makes it more stable. + +Valid values: .true. or .false. +Default: Defined in namelist_defaults.xml + + activate channels in subglacial hydrology model @@ -1400,6 +1408,14 @@ Valid values: 'file', 'thermal', 'basal_heat' Default: Defined in namelist_defaults.xml + +number of iterations to smooth waterPressure over when calculating waterPressureSlopeNormal. Used only to keep channelPressureFreeze stable and will not affect other aspects of the model that rely on waterPressure. + +Valid values: positive integer or zero +Default: Defined in namelist_defaults.xml + + From 3e37d4a8f9cf48ade58364cf87f9a6e6b4b51f54 Mon Sep 17 00:00:00 2001 From: Jason Boutte Date: Wed, 14 Aug 2024 11:58:57 -0700 Subject: [PATCH 291/451] Updates cime imports --- cime_config/customize/case_post_run_io.py | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/cime_config/customize/case_post_run_io.py b/cime_config/customize/case_post_run_io.py index 83419aa81348..4451040db848 100755 --- a/cime_config/customize/case_post_run_io.py +++ b/cime_config/customize/case_post_run_io.py @@ -3,7 +3,11 @@ """ import os from CIME.XML.standard_module_setup import * -from CIME.utils import new_lid, run_and_log_case_status +try: + from CIME.utils import new_lid, run_and_log_case_status +except ImportError: + from CIME.utils import new_lid + from CIME.status import run_and_log_case_status logger = logging.getLogger(__name__) From 87068eda3d10d1b8486023bcde28382720b0fd69 Mon Sep 17 00:00:00 2001 From: Nicole Jeffery Date: Thu, 15 Aug 2024 09:56:51 -0500 Subject: [PATCH 292/451] Updates bgc defaults for grazing parameters Bugfix. Registry defaults were updated when implicit grazing was adding for E3SMv2, but the build defaults were kept the same. non-bfb in ice bgc runs. BFB for all others --- .../bld/namelist_files/namelist_defaults_mpassi.xml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) 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 70db1f04189a..d62797de4518 100644 --- a/components/mpas-seaice/bld/namelist_files/namelist_defaults_mpassi.xml +++ b/components/mpas-seaice/bld/namelist_files/namelist_defaults_mpassi.xml @@ -289,9 +289,9 @@ 0.063 0.063 0.063 -0.0 -0.7 -0.7 +0.19 +0.19 +0.19 0.007 0.007 0.007 From c411a79da7d7d2ab6f3c1224feeb964ff9707d46 Mon Sep 17 00:00:00 2001 From: Jayesh Krishna Date: Thu, 15 Aug 2024 17:42:37 -0500 Subject: [PATCH 293/451] Adding support for PnetCDF in HOMME on Chrysalis Adding support for the PnetCDF library in HOMME on Chrysalis. This configuration files are used for standalone HOMME builds on Chrysalis --- components/homme/cmake/machineFiles/chrysalis.cmake | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/components/homme/cmake/machineFiles/chrysalis.cmake b/components/homme/cmake/machineFiles/chrysalis.cmake index a336809f6d33..68ff76ec8082 100644 --- a/components/homme/cmake/machineFiles/chrysalis.cmake +++ b/components/homme/cmake/machineFiles/chrysalis.cmake @@ -20,7 +20,13 @@ SET (USE_MPI_OPTIONS "-K --cpu_bind=cores" CACHE STRING "") # Set kokkos arch, to get correct avx flags SET (Kokkos_ARCH_ZEN2 ON CACHE BOOL "") -SET (WITH_PNETCDF FALSE CACHE FILEPATH "") +EXECUTE_PROCESS(COMMAND pnetcdf-config --prefix + RESULT_VARIABLE PNCCONFIG_RESULT + OUTPUT_VARIABLE PNCCONFIG_OUTPUT + ERROR_VARIABLE PNCCONFIG_ERROR + OUTPUT_STRIP_TRAILING_WHITESPACE +) +SET (PnetCDF_PATH "${PNCCONFIG_OUTPUT}" CACHE STRING "") EXECUTE_PROCESS(COMMAND nf-config --prefix RESULT_VARIABLE NFCONFIG_RESULT From df53433349c56a895a32d6064eab952dd47ced24 Mon Sep 17 00:00:00 2001 From: Jayesh Krishna Date: Thu, 15 Aug 2024 19:05:12 -0500 Subject: [PATCH 294/451] Adding support for PnetCDF in HOMME on Anvil Adding support for the PnetCDF library in HOMME on Anvil. This configuration files are used for standalone HOMME builds on Anvil --- components/homme/cmake/machineFiles/anvil.cmake | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/components/homme/cmake/machineFiles/anvil.cmake b/components/homme/cmake/machineFiles/anvil.cmake index 325a9caa280f..2abee260b44c 100644 --- a/components/homme/cmake/machineFiles/anvil.cmake +++ b/components/homme/cmake/machineFiles/anvil.cmake @@ -20,7 +20,14 @@ ENDIF() # Set kokkos arch, to get correct avx flags SET (Kokkos_ARCH_BDW ON CACHE BOOL "") -SET (WITH_PNETCDF FALSE CACHE FILEPATH "") +EXECUTE_PROCESS(COMMAND pnetcdf-config --prefix + RESULT_VARIABLE PNCCONFIG_RESULT + OUTPUT_VARIABLE PNCCONFIG_OUTPUT + ERROR_VARIABLE PNCCONFIG_ERROR + OUTPUT_STRIP_TRAILING_WHITESPACE +) +SET (PnetCDF_PATH "${PNCCONFIG_OUTPUT}" CACHE STRING "") + # # anvil module system doesn't set environment variables, but will put # nc-config in our path. anvil seperates C and Fortran libraries, From ffdb1bc85ea4c7849346f2b80115cb436391bfc2 Mon Sep 17 00:00:00 2001 From: Azamat Mametjanov Date: Fri, 16 Aug 2024 17:32:13 +0000 Subject: [PATCH 295/451] Update ALCF Sunspot machine config --- cime_config/machines/config_machines.xml | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/cime_config/machines/config_machines.xml b/cime_config/machines/config_machines.xml index 6cd9d585a25b..67611a0de225 100644 --- a/cime_config/machines/config_machines.xml +++ b/cime_config/machines/config_machines.xml @@ -3413,13 +3413,9 @@ module /soft/packaging/lmod/lmod/libexec/lmod python - - /soft/modulefiles - spack cmake/3.26.3-gcc-11.2.0-vnn7ncx - prepend-deps/default + cmake - gcc oneapi/eng-compiler/2023.05.15.007 From ef08ba7dfb75f413772be4347913b2b98ae36cc9 Mon Sep 17 00:00:00 2001 From: Chloe Date: Thu, 13 Jun 2024 09:31:57 -0700 Subject: [PATCH 296/451] Added new snow Thermal Conductivity in SoilTemperatureMod.F90 based on Fourteau, et al. (2021) - is now density and temp dependent --- .../namelist_files/namelist_definition.xml | 4 ++ .../elm/src/biogeophys/SoilTemperatureMod.F90 | 61 ++++++++++++++++--- components/elm/src/main/controlMod.F90 | 10 ++- components/elm/src/main/elm_varctl.F90 | 1 + 4 files changed, 67 insertions(+), 9 deletions(-) diff --git a/components/elm/bld/namelist_files/namelist_definition.xml b/components/elm/bld/namelist_files/namelist_definition.xml index 74e1967fc529..312119ff15f8 100644 --- a/components/elm/bld/namelist_files/namelist_definition.xml +++ b/components/elm/bld/namelist_files/namelist_definition.xml @@ -766,6 +766,10 @@ This option enables more realistic snowpack conditions on glaciers and ice sheets, including a semi-empirical firn densification model. uses the same physics as use_extrasnowlayers but uses the original 5 snow layer scheme + + +Toggle to use new snow thermal conductivity that relies on snow temperature and density. = snl(c)+1) .AND. (j <= 0)) then + bw(c,j) = (h2osoi_ice(c,j)+h2osoi_liq(c,j))/(frac_sno(c)*dz(c,j)) + !write(iulog,*)"CAW bw(c,j)",bw(c,j) + + do i = 1, 5 + if (i == 1) then + k_snw_vals(i) = 2.564 * (bw(c,j)/ rho_ice)**2 - 0.059 * (bw(c,j)/ rho_ice) + 0.0205 + else if (i == 2) then + k_snw_vals(i) = 2.172 * (bw(c,j)/ rho_ice)**2 + 0.015 * (bw(c,j)/ rho_ice) + 0.0252 + else if (i == 3) then + k_snw_vals(i) = 1.985 * (bw(c,j)/ rho_ice)**2 + 0.073 * (bw(c,j)/ rho_ice) + 0.0336 + else if (i == 4) then + k_snw_vals(i) = 1.883 * (bw(c,j)/ rho_ice)**2 + 0.107 * (bw(c,j)/ rho_ice) + 0.0386 + else if (i == 5) then + k_snw_vals(i) = 1.776 * (bw(c,j)/ rho_ice)**2 + 0.147 * (bw(c,j)/ rho_ice) + 0.0455 + end if + end do + + do i = 1, size(k_snw_tmps) - 1 + if (k_snw_tmps(i) <= t_soisno(c,j) .and. t_soisno(c,j) <= k_snw_tmps(i + 1)) then + thk(c,j) = k_snw_vals(i) + (t_soisno(c,j) - k_snw_tmps(i))*(k_snw_vals(i + 1)-k_snw_vals(i))/(k_snw_tmps(i + 1)-k_snw_tmps(i)) + end if + end do + + ! Handle edge cases if t_soisno(c,j) is outside the given range + if (t_soisno(c,j) < k_snw_tmps(1)) then + thk(c,j) = k_snw_vals(1) + else if (t_soisno(c,j) > k_snw_tmps(size(k_snw_tmps))) then + thk(c,j) = k_snw_vals(size(k_snw_tmps)) + end if + + ! write(iulog,*)"CAW snow layer:",j + ! write(iulog,*)"CAW snow temp:",t_soisno(c,j) + ! write(iulog,*)"CAW snow density:",bw(c,j) + ! write(iulog,*)"CAW snow thk:",thk(c,j) + end if - ! Thermal conductivity of snow, which from Jordan (1991) pp. 18 - ! Only examine levels from snl(c)+1 -> 0 where snl(c) < 1 - if (snl(c)+1 < 1 .AND. (j >= snl(c)+1) .AND. (j <= 0)) then - bw(c,j) = (h2osoi_ice(c,j)+h2osoi_liq(c,j))/(frac_sno(c)*dz(c,j)) - thk(c,j) = tkair + (7.75e-5_r8 *bw(c,j) + 1.105e-6_r8*bw(c,j)*bw(c,j))*(tkice-tkair) - end if + else + ! Thermal conductivity of snow, which from Jordan (1991) pp. 18 + ! Only examine levels from snl(c)+1 -> 0 where snl(c) < 1 + if (snl(c)+1 < 1 .AND. (j >= snl(c)+1) .AND. (j <= 0)) then + bw(c,j) = (h2osoi_ice(c,j)+h2osoi_liq(c,j))/(frac_sno(c)*dz(c,j)) + thk(c,j) = tkair + (7.75e-5_r8 *bw(c,j) + 1.105e-6_r8*bw(c,j)*bw(c,j))*(tkice-tkair) + end if + endif end do end do diff --git a/components/elm/src/main/controlMod.F90 b/components/elm/src/main/controlMod.F90 index 24bb855ff61a..0663bace9fc3 100755 --- a/components/elm/src/main/controlMod.F90 +++ b/components/elm/src/main/controlMod.F90 @@ -285,7 +285,7 @@ subroutine control_init( ) use_nofire, use_lch4, use_vertsoilc, use_extralakelayers, & use_vichydro, use_century_decomp, use_cn, use_crop, use_snicar_frc, & use_snicar_ad, use_firn_percolation_and_compaction, use_extrasnowlayers,& - use_vancouver, use_mexicocity, use_noio + use_snow_thk, use_vancouver, use_mexicocity, use_noio ! cpl_bypass variables namelist /elm_inparm/ metdata_type, metdata_bypass, metdata_biases, & @@ -726,7 +726,11 @@ subroutine control_spmd() call mpi_bcast (use_vertsoilc, 1, MPI_LOGICAL, 0, mpicom, ier) call mpi_bcast (use_extralakelayers, 1, MPI_LOGICAL, 0, mpicom, ier) call mpi_bcast (use_extrasnowlayers, 1, MPI_LOGICAL, 0, mpicom, ier) +<<<<<<< HEAD call mpi_bcast (use_firn_percolation_and_compaction, 1, MPI_LOGICAL, 0, mpicom, ier) +======= + call mpi_bcast (use_snow_thk, 1, MPI_LOGICAL, 0, mpicom, ier) +>>>>>>> aa0f583905 (Added new snow Thermal Conductivity in SoilTemperatureMod.F90) call mpi_bcast (use_vichydro, 1, MPI_LOGICAL, 0, mpicom, ier) call mpi_bcast (use_century_decomp, 1, MPI_LOGICAL, 0, mpicom, ier) call mpi_bcast (use_cn, 1, MPI_LOGICAL, 0, mpicom, ier) @@ -1030,7 +1034,11 @@ subroutine control_print () write(iulog,*) ' use_lake_wat_storage = ', use_lake_wat_storage write(iulog,*) ' use_extralakelayers = ', use_extralakelayers write(iulog,*) ' use_extrasnowlayers = ', use_extrasnowlayers +<<<<<<< HEAD write(iulog,*) ' use_firn_percolation_and_compaction = ', use_firn_percolation_and_compaction +======= + write(iulog,*) ' use_snow_thk = ', use_snow_thk +>>>>>>> aa0f583905 (Added new snow Thermal Conductivity in SoilTemperatureMod.F90) write(iulog,*) ' use_vichydro = ', use_vichydro write(iulog,*) ' use_century_decomp = ', use_century_decomp write(iulog,*) ' use_cn = ', use_cn diff --git a/components/elm/src/main/elm_varctl.F90 b/components/elm/src/main/elm_varctl.F90 index 46b0d3c65a41..cbba48c84cba 100644 --- a/components/elm/src/main/elm_varctl.F90 +++ b/components/elm/src/main/elm_varctl.F90 @@ -376,6 +376,7 @@ module elm_varctl logical, public :: use_snicar_ad = .false. logical, public :: use_extrasnowlayers = .false. logical, public :: use_firn_percolation_and_compaction = .false. + logical, public :: use_snow_thk = .false. logical, public :: use_vancouver = .false. logical, public :: use_mexicocity = .false. logical, public :: use_noio = .false. From 2b7fbc01572fe783c34cccb2edc88ef5f574e17e Mon Sep 17 00:00:00 2001 From: Chloe Date: Thu, 20 Jun 2024 12:57:55 -0700 Subject: [PATCH 297/451] changed flag name for new snow thk flag to be more descriptive --- .../elm/bld/namelist_files/namelist_definition.xml | 2 +- components/elm/src/biogeophys/SoilTemperatureMod.F90 | 4 ++-- components/elm/src/main/controlMod.F90 | 10 +++++++++- components/elm/src/main/elm_varctl.F90 | 2 +- 4 files changed, 13 insertions(+), 5 deletions(-) diff --git a/components/elm/bld/namelist_files/namelist_definition.xml b/components/elm/bld/namelist_files/namelist_definition.xml index 312119ff15f8..dfc61f9fd8fc 100644 --- a/components/elm/bld/namelist_files/namelist_definition.xml +++ b/components/elm/bld/namelist_files/namelist_definition.xml @@ -767,7 +767,7 @@ snowpack conditions on glaciers and ice sheets, including a semi-empirical firn densification model. uses the same physics as use_extrasnowlayers but uses the original 5 snow layer scheme - Toggle to use new snow thermal conductivity that relies on snow temperature and density. diff --git a/components/elm/src/biogeophys/SoilTemperatureMod.F90 b/components/elm/src/biogeophys/SoilTemperatureMod.F90 index 7d262e295a10..3011538cedb6 100644 --- a/components/elm/src/biogeophys/SoilTemperatureMod.F90 +++ b/components/elm/src/biogeophys/SoilTemperatureMod.F90 @@ -834,7 +834,7 @@ subroutine SoilThermProp (bounds, num_nolakec, filter_nolakec, & use elm_varcon , only : denh2o, denice, tfrz, tkwat, tkice, tkair, cpice, cpliq, thk_bedrock use landunit_varcon , only : istice, istice_mec, istwet use column_varcon , only : icol_roof, icol_sunwall, icol_shadewall, icol_road_perv, icol_road_imperv - use elm_varctl , only : iulog, use_snow_thk + use elm_varctl , only : iulog, use_T_rho_dependent_snowthk ! ! !ARGUMENTS: type(bounds_type) , intent(in) :: bounds @@ -949,7 +949,7 @@ subroutine SoilThermProp (bounds, num_nolakec, filter_nolakec, & endif endif - if (use_snow_thk) then ! chose which snow thermal conductivity to use + if (use_T_rho_dependent_snowthk) then ! chose which snow thermal conductivity to use if (snl(c)+1 < 1 .AND. (j >= snl(c)+1) .AND. (j <= 0)) then bw(c,j) = (h2osoi_ice(c,j)+h2osoi_liq(c,j))/(frac_sno(c)*dz(c,j)) !write(iulog,*)"CAW bw(c,j)",bw(c,j) diff --git a/components/elm/src/main/controlMod.F90 b/components/elm/src/main/controlMod.F90 index 0663bace9fc3..c00db6dd7399 100755 --- a/components/elm/src/main/controlMod.F90 +++ b/components/elm/src/main/controlMod.F90 @@ -285,7 +285,7 @@ subroutine control_init( ) use_nofire, use_lch4, use_vertsoilc, use_extralakelayers, & use_vichydro, use_century_decomp, use_cn, use_crop, use_snicar_frc, & use_snicar_ad, use_firn_percolation_and_compaction, use_extrasnowlayers,& - use_snow_thk, use_vancouver, use_mexicocity, use_noio + use_T_rho_dependent_snowthk, use_vancouver, use_mexicocity, use_noio ! cpl_bypass variables namelist /elm_inparm/ metdata_type, metdata_bypass, metdata_biases, & @@ -726,11 +726,15 @@ subroutine control_spmd() call mpi_bcast (use_vertsoilc, 1, MPI_LOGICAL, 0, mpicom, ier) call mpi_bcast (use_extralakelayers, 1, MPI_LOGICAL, 0, mpicom, ier) call mpi_bcast (use_extrasnowlayers, 1, MPI_LOGICAL, 0, mpicom, ier) +<<<<<<< HEAD <<<<<<< HEAD call mpi_bcast (use_firn_percolation_and_compaction, 1, MPI_LOGICAL, 0, mpicom, ier) ======= call mpi_bcast (use_snow_thk, 1, MPI_LOGICAL, 0, mpicom, ier) >>>>>>> aa0f583905 (Added new snow Thermal Conductivity in SoilTemperatureMod.F90) +======= + call mpi_bcast (use_T_rho_dependent_snowthk, 1, MPI_LOGICAL, 0, mpicom, ier) +>>>>>>> 7d87f8c1ac (changed flag name for new snow thk flag to be more descriptive) call mpi_bcast (use_vichydro, 1, MPI_LOGICAL, 0, mpicom, ier) call mpi_bcast (use_century_decomp, 1, MPI_LOGICAL, 0, mpicom, ier) call mpi_bcast (use_cn, 1, MPI_LOGICAL, 0, mpicom, ier) @@ -1034,11 +1038,15 @@ subroutine control_print () write(iulog,*) ' use_lake_wat_storage = ', use_lake_wat_storage write(iulog,*) ' use_extralakelayers = ', use_extralakelayers write(iulog,*) ' use_extrasnowlayers = ', use_extrasnowlayers +<<<<<<< HEAD <<<<<<< HEAD write(iulog,*) ' use_firn_percolation_and_compaction = ', use_firn_percolation_and_compaction ======= write(iulog,*) ' use_snow_thk = ', use_snow_thk >>>>>>> aa0f583905 (Added new snow Thermal Conductivity in SoilTemperatureMod.F90) +======= + write(iulog,*) ' use_T_rho_dependent_snowthk = ', use_T_rho_dependent_snowthk +>>>>>>> 7d87f8c1ac (changed flag name for new snow thk flag to be more descriptive) write(iulog,*) ' use_vichydro = ', use_vichydro write(iulog,*) ' use_century_decomp = ', use_century_decomp write(iulog,*) ' use_cn = ', use_cn diff --git a/components/elm/src/main/elm_varctl.F90 b/components/elm/src/main/elm_varctl.F90 index cbba48c84cba..fb9ca0dbd24e 100644 --- a/components/elm/src/main/elm_varctl.F90 +++ b/components/elm/src/main/elm_varctl.F90 @@ -376,11 +376,11 @@ module elm_varctl logical, public :: use_snicar_ad = .false. logical, public :: use_extrasnowlayers = .false. logical, public :: use_firn_percolation_and_compaction = .false. - logical, public :: use_snow_thk = .false. logical, public :: use_vancouver = .false. logical, public :: use_mexicocity = .false. logical, public :: use_noio = .false. logical, public :: use_var_soil_thick = .false. + logical, public :: use_T_rho_dependent_snowthk = .false. logical, public :: use_atm_downscaling_to_topunit = .false. character(len = SHR_KIND_CS), public :: precip_downscaling_method = 'ERMM' ! Precip downscaling method values can be ERMM or FNM logical, public :: use_lake_wat_storage = .false. From 7af3988119f772deb04acaf5de5817ff93757fa4 Mon Sep 17 00:00:00 2001 From: Chloe Date: Fri, 19 Jul 2024 12:32:33 -0700 Subject: [PATCH 298/451] clean up master & feature branch merge --- components/elm/src/main/controlMod.F90 | 14 -------------- 1 file changed, 14 deletions(-) diff --git a/components/elm/src/main/controlMod.F90 b/components/elm/src/main/controlMod.F90 index c00db6dd7399..1d8f48d7cc7d 100755 --- a/components/elm/src/main/controlMod.F90 +++ b/components/elm/src/main/controlMod.F90 @@ -726,15 +726,8 @@ subroutine control_spmd() call mpi_bcast (use_vertsoilc, 1, MPI_LOGICAL, 0, mpicom, ier) call mpi_bcast (use_extralakelayers, 1, MPI_LOGICAL, 0, mpicom, ier) call mpi_bcast (use_extrasnowlayers, 1, MPI_LOGICAL, 0, mpicom, ier) -<<<<<<< HEAD -<<<<<<< HEAD call mpi_bcast (use_firn_percolation_and_compaction, 1, MPI_LOGICAL, 0, mpicom, ier) -======= - call mpi_bcast (use_snow_thk, 1, MPI_LOGICAL, 0, mpicom, ier) ->>>>>>> aa0f583905 (Added new snow Thermal Conductivity in SoilTemperatureMod.F90) -======= call mpi_bcast (use_T_rho_dependent_snowthk, 1, MPI_LOGICAL, 0, mpicom, ier) ->>>>>>> 7d87f8c1ac (changed flag name for new snow thk flag to be more descriptive) call mpi_bcast (use_vichydro, 1, MPI_LOGICAL, 0, mpicom, ier) call mpi_bcast (use_century_decomp, 1, MPI_LOGICAL, 0, mpicom, ier) call mpi_bcast (use_cn, 1, MPI_LOGICAL, 0, mpicom, ier) @@ -1038,15 +1031,8 @@ subroutine control_print () write(iulog,*) ' use_lake_wat_storage = ', use_lake_wat_storage write(iulog,*) ' use_extralakelayers = ', use_extralakelayers write(iulog,*) ' use_extrasnowlayers = ', use_extrasnowlayers -<<<<<<< HEAD -<<<<<<< HEAD write(iulog,*) ' use_firn_percolation_and_compaction = ', use_firn_percolation_and_compaction -======= - write(iulog,*) ' use_snow_thk = ', use_snow_thk ->>>>>>> aa0f583905 (Added new snow Thermal Conductivity in SoilTemperatureMod.F90) -======= write(iulog,*) ' use_T_rho_dependent_snowthk = ', use_T_rho_dependent_snowthk ->>>>>>> 7d87f8c1ac (changed flag name for new snow thk flag to be more descriptive) write(iulog,*) ' use_vichydro = ', use_vichydro write(iulog,*) ' use_century_decomp = ', use_century_decomp write(iulog,*) ' use_cn = ', use_cn From c2219551fdade1192ca6992b8c9ea27bca2ebbcc Mon Sep 17 00:00:00 2001 From: Chloe Date: Wed, 24 Jul 2024 12:07:11 -0700 Subject: [PATCH 299/451] removed testing write statements --- components/elm/src/biogeophys/SoilTemperatureMod.F90 | 5 ----- 1 file changed, 5 deletions(-) diff --git a/components/elm/src/biogeophys/SoilTemperatureMod.F90 b/components/elm/src/biogeophys/SoilTemperatureMod.F90 index 3011538cedb6..9bda1ab7918e 100644 --- a/components/elm/src/biogeophys/SoilTemperatureMod.F90 +++ b/components/elm/src/biogeophys/SoilTemperatureMod.F90 @@ -952,7 +952,6 @@ subroutine SoilThermProp (bounds, num_nolakec, filter_nolakec, & if (use_T_rho_dependent_snowthk) then ! chose which snow thermal conductivity to use if (snl(c)+1 < 1 .AND. (j >= snl(c)+1) .AND. (j <= 0)) then bw(c,j) = (h2osoi_ice(c,j)+h2osoi_liq(c,j))/(frac_sno(c)*dz(c,j)) - !write(iulog,*)"CAW bw(c,j)",bw(c,j) do i = 1, 5 if (i == 1) then @@ -981,10 +980,6 @@ subroutine SoilThermProp (bounds, num_nolakec, filter_nolakec, & thk(c,j) = k_snw_vals(size(k_snw_tmps)) end if - ! write(iulog,*)"CAW snow layer:",j - ! write(iulog,*)"CAW snow temp:",t_soisno(c,j) - ! write(iulog,*)"CAW snow density:",bw(c,j) - ! write(iulog,*)"CAW snow thk:",thk(c,j) end if From a4e9c067a4edebadbd31394e2b27e3c01d7cd39b Mon Sep 17 00:00:00 2001 From: Chloe Date: Fri, 16 Aug 2024 14:17:53 -0700 Subject: [PATCH 300/451] minor stylistic / precision mods --- .../elm/src/biogeophys/SoilTemperatureMod.F90 | 26 ++++++++----------- 1 file changed, 11 insertions(+), 15 deletions(-) diff --git a/components/elm/src/biogeophys/SoilTemperatureMod.F90 b/components/elm/src/biogeophys/SoilTemperatureMod.F90 index 9bda1ab7918e..524ee65d1205 100644 --- a/components/elm/src/biogeophys/SoilTemperatureMod.F90 +++ b/components/elm/src/biogeophys/SoilTemperatureMod.F90 @@ -860,7 +860,13 @@ subroutine SoilThermProp (bounds, num_nolakec, filter_nolakec, & real(r8), parameter :: rho_ice = 917._r8 real(r8) :: k_snw_vals(5) real(r8) :: k_snw_tmps(5) - data k_snw_tmps(:) /223.0, 248.0, 263.0, 268.0, 273.0/ + real(r8) :: k_snw_coe1(5) + real(r8) :: k_snw_coe2(5) + real(r8) :: k_snw_coe3(5) + data k_snw_tmps(:) /223.0_r8, 248.0_r8, 263.0_r8, 268.0_r8, 273.0_r8/ + data k_snw_coe1(:) /2.564_r8,2.172_r8,1.985_r8,1.883_r8,1.776_r8/ + data k_snw_coe2(:) /-0.059_r8, 0.015_r8, 0.073_r8, 0.107_r8, 0.147_r8/ + data k_snw_coe3(:) /0.0205_r8, 0.0252_r8, 0.0336_r8, 0.0386_r8, 0.0455_r8/ !----------------------------------------------------------------------- event = 'SoilThermProp' call t_start_lnd( event ) @@ -949,27 +955,17 @@ subroutine SoilThermProp (bounds, num_nolakec, filter_nolakec, & endif endif - if (use_T_rho_dependent_snowthk) then ! chose which snow thermal conductivity to use + if (use_T_rho_dependent_snowthk) then ! choose which snow thermal conductivity to use if (snl(c)+1 < 1 .AND. (j >= snl(c)+1) .AND. (j <= 0)) then - bw(c,j) = (h2osoi_ice(c,j)+h2osoi_liq(c,j))/(frac_sno(c)*dz(c,j)) + bw(c,j) = (h2osoi_ice(c,j) + h2osoi_liq(c,j)) / (frac_sno(c) * dz(c,j)) do i = 1, 5 - if (i == 1) then - k_snw_vals(i) = 2.564 * (bw(c,j)/ rho_ice)**2 - 0.059 * (bw(c,j)/ rho_ice) + 0.0205 - else if (i == 2) then - k_snw_vals(i) = 2.172 * (bw(c,j)/ rho_ice)**2 + 0.015 * (bw(c,j)/ rho_ice) + 0.0252 - else if (i == 3) then - k_snw_vals(i) = 1.985 * (bw(c,j)/ rho_ice)**2 + 0.073 * (bw(c,j)/ rho_ice) + 0.0336 - else if (i == 4) then - k_snw_vals(i) = 1.883 * (bw(c,j)/ rho_ice)**2 + 0.107 * (bw(c,j)/ rho_ice) + 0.0386 - else if (i == 5) then - k_snw_vals(i) = 1.776 * (bw(c,j)/ rho_ice)**2 + 0.147 * (bw(c,j)/ rho_ice) + 0.0455 - end if + k_snw_vals(i) = k_snw_coe1(i) * (bw(c,j) / rho_ice)**2 - k_snw_coe2(i) * (bw(c,j) / rho_ice) + k_snw_coe3(i) end do do i = 1, size(k_snw_tmps) - 1 if (k_snw_tmps(i) <= t_soisno(c,j) .and. t_soisno(c,j) <= k_snw_tmps(i + 1)) then - thk(c,j) = k_snw_vals(i) + (t_soisno(c,j) - k_snw_tmps(i))*(k_snw_vals(i + 1)-k_snw_vals(i))/(k_snw_tmps(i + 1)-k_snw_tmps(i)) + thk(c,j) = k_snw_vals(i) + (t_soisno(c,j) - k_snw_tmps(i)) * (k_snw_vals(i + 1)-k_snw_vals(i)) / (k_snw_tmps(i + 1) - k_snw_tmps(i)) end if end do From 7c473e334e68aef5d142c55e245109f624a6aaaa Mon Sep 17 00:00:00 2001 From: Azamat Mametjanov Date: Mon, 19 Aug 2024 22:26:49 +0000 Subject: [PATCH 301/451] Update oneapi to latest default --- cime_config/machines/config_machines.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cime_config/machines/config_machines.xml b/cime_config/machines/config_machines.xml index 67611a0de225..446262a3a9b2 100644 --- a/cime_config/machines/config_machines.xml +++ b/cime_config/machines/config_machines.xml @@ -3416,7 +3416,7 @@ cmake - oneapi/eng-compiler/2023.05.15.007 + oneapi/eng-compiler/2024.04.15.002 spack cmake From a4b7c3b9a75acdef005b3bbfc6dd671c7b2c2248 Mon Sep 17 00:00:00 2001 From: Azamat Mametjanov Date: Mon, 19 Aug 2024 22:29:07 +0000 Subject: [PATCH 302/451] Run BGC couppled cases on at least 2 nodes --- cime_config/allactive/config_pesall.xml | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/cime_config/allactive/config_pesall.xml b/cime_config/allactive/config_pesall.xml index e99230e7cb04..78ba011d9b78 100644 --- a/cime_config/allactive/config_pesall.xml +++ b/cime_config/allactive/config_pesall.xml @@ -1472,6 +1472,21 @@ + + + sunspot: --compset BGC* --res ne30pg2_r05_IcoswISC30E3r5 on 2 nodes pure-MPI + + -2 + -2 + -2 + -2 + -2 + -2 + -2 + -2 + + + From e3e52e2b833f57d74231107cfcc3efc4c940b393 Mon Sep 17 00:00:00 2001 From: Azamat Mametjanov Date: Mon, 19 Aug 2024 22:34:11 +0000 Subject: [PATCH 303/451] Remove -check flags from debug builds They lead to link errors in currently available oneapi versions. --- cime_config/machines/cmake_macros/oneapi-ifx.cmake | 2 +- cime_config/machines/cmake_macros/oneapi-ifxgpu.cmake | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/cime_config/machines/cmake_macros/oneapi-ifx.cmake b/cime_config/machines/cmake_macros/oneapi-ifx.cmake index e98a65d32a67..9ab0cdda7d51 100644 --- a/cime_config/machines/cmake_macros/oneapi-ifx.cmake +++ b/cime_config/machines/cmake_macros/oneapi-ifx.cmake @@ -7,7 +7,7 @@ endif() string(APPEND CMAKE_C_FLAGS_RELEASE " -O2") string(APPEND CMAKE_Fortran_FLAGS_RELEASE " -O2") string(APPEND CMAKE_CXX_FLAGS_RELEASE " -O2") -string(APPEND CMAKE_Fortran_FLAGS_DEBUG " -O0 -g -check uninit -check bounds -check pointers -fpe0 -check noarg_temp_created") +string(APPEND CMAKE_Fortran_FLAGS_DEBUG " -O0 -g -fpe0") string(APPEND CMAKE_C_FLAGS_DEBUG " -O0 -g") string(APPEND CMAKE_CXX_FLAGS_DEBUG " -O0 -g") string(APPEND CMAKE_C_FLAGS " -fp-model precise -std=gnu99") diff --git a/cime_config/machines/cmake_macros/oneapi-ifxgpu.cmake b/cime_config/machines/cmake_macros/oneapi-ifxgpu.cmake index 9d08ca6c6302..d7dfae002192 100644 --- a/cime_config/machines/cmake_macros/oneapi-ifxgpu.cmake +++ b/cime_config/machines/cmake_macros/oneapi-ifxgpu.cmake @@ -7,7 +7,7 @@ endif() string(APPEND CMAKE_C_FLAGS_RELEASE " -O2") string(APPEND CMAKE_Fortran_FLAGS_RELEASE " -O2") string(APPEND CMAKE_CXX_FLAGS_RELEASE " -O2") -string(APPEND CMAKE_Fortran_FLAGS_DEBUG " -O0 -g -check uninit -check bounds -check pointers -fpe0 -check noarg_temp_created") +string(APPEND CMAKE_Fortran_FLAGS_DEBUG " -O0 -g -fpe0") string(APPEND CMAKE_C_FLAGS_DEBUG " -O0 -g") string(APPEND CMAKE_CXX_FLAGS_DEBUG " -O0 -g") string(APPEND CMAKE_C_FLAGS " -fp-model precise -std=gnu99") From c6e75e3fa6b3f9c1c1814ca7d368f4111a626949 Mon Sep 17 00:00:00 2001 From: Azamat Mametjanov Date: Mon, 19 Aug 2024 22:50:35 +0000 Subject: [PATCH 304/451] Cleanup unused mpilib refs --- cime_config/machines/config_machines.xml | 15 +-------------- 1 file changed, 1 insertion(+), 14 deletions(-) diff --git a/cime_config/machines/config_machines.xml b/cime_config/machines/config_machines.xml index 446262a3a9b2..c94a2bbcf7d2 100644 --- a/cime_config/machines/config_machines.xml +++ b/cime_config/machines/config_machines.xml @@ -3365,7 +3365,7 @@ uan-.* LINUX oneapi-ifx,oneapi-ifxgpu,gnu - mpich,impi,openmpi + mpich CSC249ADSE15_CNDA /gila/CSC249ADSE15_CNDA/performance_archive .* @@ -3398,13 +3398,6 @@ $ENV{GPU_TILE_COMPACT} - - mpirun - - --tag-output -n {{ total_tasks }} - --map-by ppr:{{ tasks_per_numa }}:socket:PE=$ENV{OMP_NUM_THREADS} --bind-to hwthread - - /soft/packaging/lmod/lmod/init/sh /soft/packaging/lmod/lmod/init/csh @@ -3434,12 +3427,6 @@ 1 - - 10 - omp - spread - unit - level_zero:gpu NO_GPU From eae53e54007c2be42ef3ee9f0d809e1ff88c53d9 Mon Sep 17 00:00:00 2001 From: Azamat Mametjanov Date: Tue, 20 Aug 2024 03:21:06 +0000 Subject: [PATCH 305/451] Run ne4-cases at 96x1 MPIxOMP --- cime_config/allactive/config_pesall.xml | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/cime_config/allactive/config_pesall.xml b/cime_config/allactive/config_pesall.xml index 78ba011d9b78..84c0e24d8c9b 100644 --- a/cime_config/allactive/config_pesall.xml +++ b/cime_config/allactive/config_pesall.xml @@ -1759,6 +1759,21 @@ + + + allactive+sunspot: default, 96 mpi x 1 omp @ root 0 + + 96 + 96 + 96 + 96 + 96 + 96 + 96 + 96 + + + From ffec269d010a34f04b3ff132981dbeb0bcc24ac3 Mon Sep 17 00:00:00 2001 From: Azamat Mametjanov Date: Tue, 20 Aug 2024 03:22:36 +0000 Subject: [PATCH 306/451] Add initial sunspot machine file for eamxx --- components/eamxx/cmake/machine-files/sunspot.cmake | 10 ++++++++++ 1 file changed, 10 insertions(+) create mode 100644 components/eamxx/cmake/machine-files/sunspot.cmake diff --git a/components/eamxx/cmake/machine-files/sunspot.cmake b/components/eamxx/cmake/machine-files/sunspot.cmake new file mode 100644 index 000000000000..09ff6d4e6c48 --- /dev/null +++ b/components/eamxx/cmake/machine-files/sunspot.cmake @@ -0,0 +1,10 @@ +include(${CMAKE_CURRENT_LIST_DIR}/common.cmake) +common_setup() + +include (${EKAT_MACH_FILES_PATH}/kokkos/serial.cmake) +include (${EKAT_MACH_FILES_PATH}/mpi/other.cmake) + +set(EKAT_MPIRUN_EXE "mpiexec" CACHE STRING "" FORCE) +set(EKAT_MPI_NP_FLAG "-np" CACHE STRING "" FORCE) +set(EKAT_MPI_EXTRA_ARGS "--label --cpu-bind depth -envall" CACHE STRING "") +set(EKAT_MPI_THREAD_FLAG "-d" CACHE STRING "") From 04258da74cb7eb2845cccf6ea3a54c71109b378c Mon Sep 17 00:00:00 2001 From: Chloe Date: Tue, 20 Aug 2024 09:09:15 -0700 Subject: [PATCH 307/451] minor stylistic change --- components/elm/src/biogeophys/SoilTemperatureMod.F90 | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/components/elm/src/biogeophys/SoilTemperatureMod.F90 b/components/elm/src/biogeophys/SoilTemperatureMod.F90 index 524ee65d1205..d4a1074bf4a7 100644 --- a/components/elm/src/biogeophys/SoilTemperatureMod.F90 +++ b/components/elm/src/biogeophys/SoilTemperatureMod.F90 @@ -864,7 +864,7 @@ subroutine SoilThermProp (bounds, num_nolakec, filter_nolakec, & real(r8) :: k_snw_coe2(5) real(r8) :: k_snw_coe3(5) data k_snw_tmps(:) /223.0_r8, 248.0_r8, 263.0_r8, 268.0_r8, 273.0_r8/ - data k_snw_coe1(:) /2.564_r8,2.172_r8,1.985_r8,1.883_r8,1.776_r8/ + data k_snw_coe1(:) /2.564_r8, 2.172_r8, 1.985_r8, 1.883_r8, 1.776_r8/ data k_snw_coe2(:) /-0.059_r8, 0.015_r8, 0.073_r8, 0.107_r8, 0.147_r8/ data k_snw_coe3(:) /0.0205_r8, 0.0252_r8, 0.0336_r8, 0.0386_r8, 0.0455_r8/ !----------------------------------------------------------------------- @@ -982,9 +982,9 @@ subroutine SoilThermProp (bounds, num_nolakec, filter_nolakec, & else ! Thermal conductivity of snow, which from Jordan (1991) pp. 18 ! Only examine levels from snl(c)+1 -> 0 where snl(c) < 1 - if (snl(c)+1 < 1 .AND. (j >= snl(c)+1) .AND. (j <= 0)) then - bw(c,j) = (h2osoi_ice(c,j)+h2osoi_liq(c,j))/(frac_sno(c)*dz(c,j)) - thk(c,j) = tkair + (7.75e-5_r8 *bw(c,j) + 1.105e-6_r8*bw(c,j)*bw(c,j))*(tkice-tkair) + if (snl(c) + 1 < 1 .AND. (j >= snl(c) + 1) .AND. (j <= 0)) then + bw(c,j) = (h2osoi_ice(c,j) + h2osoi_liq(c,j)) / (frac_sno(c) * dz(c,j)) + thk(c,j) = tkair + (7.75e-5_r8 * bw(c,j) + 1.105e-6_r8 * bw(c,j) * bw(c,j)) * (tkice - tkair) end if endif end do From 7c182a67279b6499b34ba9d2d4aee6953b221c1e Mon Sep 17 00:00:00 2001 From: Iulian Grindeanu Date: Thu, 27 Jun 2024 17:26:26 -0500 Subject: [PATCH 308/451] data land for moab driver use existing lnd_domain attribute in infodata we do not differentiate on coupler side if data land or not still need to send the proper land domain file --- .../data_comps/dlnd/src/dlnd_comp_mod.F90 | 181 +++++++++++++++++- .../data_comps/dlnd/src/lnd_comp_mct.F90 | 40 +++- 2 files changed, 216 insertions(+), 5 deletions(-) diff --git a/components/data_comps/dlnd/src/dlnd_comp_mod.F90 b/components/data_comps/dlnd/src/dlnd_comp_mod.F90 index bf723259be48..7768b2dfe815 100644 --- a/components/data_comps/dlnd/src/dlnd_comp_mod.F90 +++ b/components/data_comps/dlnd/src/dlnd_comp_mod.F90 @@ -29,6 +29,10 @@ module dlnd_comp_mod use dlnd_shr_mod , only: domain_fracname ! namelist input use dlnd_shr_mod , only: nullstr +#ifdef HAVE_MOAB + use seq_comm_mct, only : mlnid ! id of moab lnd app + use iso_c_binding +#endif ! !PUBLIC TYPES: implicit none private ! except @@ -100,6 +104,12 @@ subroutine dlnd_comp_init(Eclock, x2l, l2x, & scmMode, scmlat, scmlon) ! !DESCRIPTION: initialize dlnd model +#ifdef HAVE_MOAB + use iMOAB, only: iMOAB_DefineTagStorage, iMOAB_GetDoubleTagStorage, & + iMOAB_SetIntTagStorage, iMOAB_SetDoubleTagStorage, & + iMOAB_ResolveSharedEntities, iMOAB_CreateVertices, & + iMOAB_GetMeshInfo, iMOAB_UpdateMeshInfo, iMOAB_WriteMesh +#endif implicit none ! !INPUT/OUTPUT PARAMETERS: @@ -135,6 +145,18 @@ subroutine dlnd_comp_init(Eclock, x2l, l2x, & character(nec_len) :: nec_str ! elevation class, as character string character(*), parameter :: domain_fracname_unset = 'null' +#ifdef HAVE_MOAB + character*400 tagname + real(R8) latv, lonv + integer iv, tagindex, ilat, ilon !, arrsize, nfields ! ierr is already defined as integer above + real(R8), allocatable, target :: data(:) + integer(IN), pointer :: idata(:) ! temporary + real(r8), dimension(:), allocatable :: moab_vert_coords ! temporary +#ifdef MOABDEBUG + character*100 outfile, wopts +#endif +#endif + !--- formats --- character(*), parameter :: F00 = "('(dlnd_comp_init) ',8a)" character(*), parameter :: F0L = "('(dlnd_comp_init) ',a, l2)" @@ -256,6 +278,119 @@ subroutine dlnd_comp_init(Eclock, x2l, l2x, & call t_stopf('dlnd_initmctdom') +#ifdef HAVE_MOAB + ilat = mct_aVect_indexRA(ggrid%data,'lat') + ilon = mct_aVect_indexRA(ggrid%data,'lon') + allocate(moab_vert_coords(lsize*3)) + do iv = 1, lsize + lonv = ggrid%data%rAttr(ilon, iv) * SHR_CONST_PI/180. + latv = ggrid%data%rAttr(ilat, iv) * SHR_CONST_PI/180. + moab_vert_coords(3*iv-2)=COS(latv)*COS(lonv) + moab_vert_coords(3*iv-1)=COS(latv)*SIN(lonv) + moab_vert_coords(3*iv )=SIN(latv) + enddo + + ! create the vertices with coordinates from MCT domain + ierr = iMOAB_CreateVertices(mlnid, lsize*3, 3, moab_vert_coords) + if (ierr .ne. 0) & + call shr_sys_abort('Error: fail to create MOAB vertices in data lnd model') + + tagname='GLOBAL_ID'//C_NULL_CHAR + ierr = iMOAB_DefineTagStorage(mlnid, tagname, & + 0, & ! dense, integer + 1, & ! number of components + tagindex ) + if (ierr .ne. 0) & + call shr_sys_abort('Error: fail to retrieve GLOBAL_ID tag ') + + ! get list of global IDs for Dofs + call mct_gsMap_orderedPoints(gsMap, my_task, idata) + + ierr = iMOAB_SetIntTagStorage ( mlnid, tagname, lsize, & + 0, & ! vertex type + idata) + if (ierr .ne. 0) & + call shr_sys_abort('Error: fail to set GLOBAL_ID tag ') + + ierr = iMOAB_ResolveSharedEntities( mlnid, lsize, idata ); + if (ierr .ne. 0) & + call shr_sys_abort('Error: fail to resolve shared entities') + + deallocate(moab_vert_coords) + deallocate(idata) + + ierr = iMOAB_UpdateMeshInfo( mlnid ) + if (ierr .ne. 0) & + call shr_sys_abort('Error: fail to update mesh info ') + + allocate(data(lsize)) + ierr = iMOAB_DefineTagStorage( mlnid, "area:aream:frac:mask"//C_NULL_CHAR, & + 1, & ! dense, double + 1, & ! number of components + tagindex ) + if (ierr > 0 ) & + call shr_sys_abort('Error: fail to create tag: area:aream:frac:mask' ) + + data(:) = ggrid%data%rAttr(mct_aVect_indexRA(ggrid%data,'area'),:) + tagname='area'//C_NULL_CHAR + ierr = iMOAB_SetDoubleTagStorage ( mlnid, tagname, lsize, & + 0, & ! set data on vertices + data) + if (ierr > 0 ) & + call shr_sys_abort('Error: fail to get area tag ') + + ! set the same data for aream (model area) as area + ! data(:) = ggrid%data%rAttr(mct_aVect_indexRA(ggrid%data,'aream'),:) + tagname='aream'//C_NULL_CHAR + ierr = iMOAB_SetDoubleTagStorage ( mlnid, tagname, lsize, & + 0, & ! set data on vertices + data) + if (ierr > 0 ) & + call shr_sys_abort('Error: fail to set aream tag ') + + data(:) = ggrid%data%rAttr(mct_aVect_indexRA(ggrid%data,'mask'),:) + tagname='mask'//C_NULL_CHAR + ierr = iMOAB_SetDoubleTagStorage ( mlnid, tagname, lsize, & + 0, & ! set data on vertices + data) + if (ierr > 0 ) & + call shr_sys_abort('Error: fail to set mask tag ') + + data(:) = ggrid%data%rAttr(mct_aVect_indexRA(ggrid%data,'frac'),:) + tagname='frac'//C_NULL_CHAR + ierr = iMOAB_SetDoubleTagStorage ( mlnid, tagname, lsize, & + 0, & ! set data on vertices + data) + if (ierr > 0 ) & + call shr_sys_abort('Error: fail to set frac tag ') + + deallocate(data) + + ! define tags + ierr = iMOAB_DefineTagStorage( mlnid, trim(seq_flds_x2l_fields)//C_NULL_CHAR, & + 1, & ! dense, double + 1, & ! number of components + tagindex ) + if (ierr > 0 ) & + call shr_sys_abort('Error: fail to create seq_flds_x2l_fields tags ') + + ierr = iMOAB_DefineTagStorage( mlnid, trim(seq_flds_l2x_fields)//C_NULL_CHAR, & + 1, & ! dense, double + 1, & ! number of components + tagindex ) + if (ierr > 0 ) & + call shr_sys_abort('Error: fail to create seq_flds_l2x_fields tags ') +#ifdef MOABDEBUG + ! debug test + outfile = 'LndDataMesh.h5m'//C_NULL_CHAR + wopts = ';PARALLEL=WRITE_PART'//C_NULL_CHAR ! + ! write out the mesh file to disk + ierr = iMOAB_WriteMesh(mlnid, trim(outfile), trim(wopts)) + if (ierr .ne. 0) then + call shr_sys_abort(subname//' ERROR in writing data mesh lnd ') + endif +#endif +#endif !---------------------------------------------------------------------------- ! Initialize MCT attribute vectors !---------------------------------------------------------------------------- @@ -339,8 +474,15 @@ subroutine dlnd_comp_run(EClock, x2l, l2x, & inst_suffix, logunit, case_name) ! !DESCRIPTION: run method for dlnd model - implicit none +#ifdef HAVE_MOAB +#ifdef MOABDEBUG + use iMOAB, only: iMOAB_WriteMesh +#endif + use seq_flds_mod , only: seq_flds_l2x_fields + use seq_flds_mod , only: moab_set_tag_from_av +#endif + implicit none ! !INPUT/OUTPUT PARAMETERS: type(ESMF_Clock) , intent(in) :: EClock type(mct_aVect) , intent(inout) :: x2l @@ -366,6 +508,17 @@ subroutine dlnd_comp_run(EClock, x2l, l2x, & integer(IN) :: nu ! unit number logical :: write_restart ! restart now character(len=18) :: date_str +#ifdef HAVE_MOAB + real(R8), allocatable, target :: datam(:) + type(mct_list) :: temp_list + integer :: size_list, index_list, lsize + type(mct_string) :: mctOStr ! + character*400 tagname, mct_field +#ifdef MOABDEBUG + integer :: cur_dlnd_stepno, ierr + character*100 outfile, wopts, lnum +#endif +#endif character(*), parameter :: F00 = "('(dlnd_comp_run) ',8a)" character(*), parameter :: F04 = "('(dlnd_comp_run) ',2a,2i8,'s')" @@ -464,6 +617,32 @@ subroutine dlnd_comp_run(EClock, x2l, l2x, & call t_stopf('DLND_RUN') +#ifdef HAVE_MOAB + lsize = mct_avect_lsize(l2x) ! is it the same as mct_avect_lsize(avstrm) ? + allocate(datam(lsize)) ! + call mct_list_init(temp_list ,seq_flds_l2x_fields) + size_list=mct_list_nitem (temp_list) + do index_list = 1, size_list + call mct_list_get(mctOStr,index_list,temp_list) + mct_field = mct_string_toChar(mctOStr) + tagname= trim(mct_field)//C_NULL_CHAR + call moab_set_tag_from_av(tagname, l2x, index_list, mlnid, datam, lsize) ! loop over all a2x fields, not just a few + enddo + call mct_list_clean(temp_list) + deallocate(datam) ! maybe we should keep it around, deallocate at the final only? + +#ifdef MOABDEBUG + call seq_timemgr_EClockGetData( EClock, stepno=cur_dlnd_stepno ) + write(lnum,"(I0.2)")cur_dlnd_stepno + outfile = 'dlnd_comp_run_'//trim(lnum)//'.h5m'//C_NULL_CHAR + wopts = 'PARALLEL=WRITE_PART'//C_NULL_CHAR + ierr = iMOAB_WriteMesh(mlnid, outfile, wopts) + if (ierr > 0 ) then + write(logunit,*) 'Failed to write data lnd component state ' + endif +#endif +#endif + end subroutine dlnd_comp_run !=============================================================================== diff --git a/components/data_comps/dlnd/src/lnd_comp_mct.F90 b/components/data_comps/dlnd/src/lnd_comp_mct.F90 index f5193ca84580..8361a8522d8a 100644 --- a/components/data_comps/dlnd/src/lnd_comp_mct.F90 +++ b/components/data_comps/dlnd/src/lnd_comp_mct.F90 @@ -16,7 +16,11 @@ module lnd_comp_mct use dlnd_comp_mod , only: dlnd_comp_init, dlnd_comp_run, dlnd_comp_final use dlnd_shr_mod , only: dlnd_shr_read_namelists use seq_flds_mod , only: seq_flds_x2l_fields, seq_flds_l2x_fields - +#ifdef HAVE_MOAB + use seq_comm_mct, only : mlnid ! iMOAB app id for lnd + use iso_c_binding + use iMOAB , only: iMOAB_RegisterApplication +#endif ! !PUBLIC TYPES: implicit none private ! except @@ -52,7 +56,9 @@ module lnd_comp_mct !=============================================================================== subroutine lnd_init_mct( EClock, cdata, x2l, l2x, NLFilename ) - +#ifdef HAVE_MOAB + use shr_stream_mod, only: shr_stream_getDomainInfo, shr_stream_getFile +#endif ! !DESCRIPTION: initialize dlnd model implicit none @@ -78,6 +84,16 @@ subroutine lnd_init_mct( EClock, cdata, x2l, l2x, NLFilename ) real(R8) :: scmLon = shr_const_SPVAL ! single column lon character(*), parameter :: subName = "(lnd_init_mct) " !------------------------------------------------------------------------------- +#ifdef HAVE_MOAB + character(CL) :: filePath ! generic file path + character(CL) :: fileName ! generic file name + character(CS) :: timeName ! domain file: time variable name + character(CS) :: lonName ! domain file: lon variable name + character(CS) :: latName ! domain file: lat variable name + character(CS) :: hgtName ! domain file: hgt variable name + character(CS) :: maskName ! domain file: mask variable name + character(CS) :: areaName ! domain file: area variable name +#endif ! Set cdata pointers call seq_cdata_setptrs(cdata, & @@ -146,13 +162,29 @@ subroutine lnd_init_mct( EClock, cdata, x2l, l2x, NLFilename ) !---------------------------------------------------------------------------- ! Initialize dlnd !---------------------------------------------------------------------------- - +#ifdef HAVE_MOAB + ierr = iMOAB_RegisterApplication(trim("DLND")//C_NULL_CHAR, mpicom, compid, mlnid) + if (ierr .ne. 0) then + write(logunit,*) subname,' error in registering data lnd comp' + call shr_sys_abort(subname//' ERROR in registering data lnd comp') + endif +#endif call dlnd_comp_init(Eclock, x2l, l2x, & seq_flds_x2l_fields, seq_flds_l2x_fields, & SDLND, gsmap, ggrid, mpicom, compid, my_task, master_task, & inst_suffix, inst_name, logunit, read_restart, & scmMode, scmlat, scmlon) - +#ifdef HAVE_MOAB + if (my_task == master_task) then + call shr_stream_getDomainInfo(SDLND%stream(1), filePath,fileName,timeName,lonName, & + latName,hgtName,maskName,areaName) + call shr_stream_getFile(filePath,fileName) + ! send path of data lnd domain to MOAB coupler. + call seq_infodata_PutData( infodata, lnd_domain=fileName) ! we use the same one for regular case + ! in regular case, it is copied from fatmlndfrc ; so we don't know if it is data land or not + write(logunit,*), ' filename: ', filename + endif +#endif !---------------------------------------------------------------------------- ! Fill infodata that needs to be returned from dlnd !---------------------------------------------------------------------------- From 2ad116ba0b787f1c9ab391eb3d95025a27cb19db Mon Sep 17 00:00:00 2001 From: Iulian Grindeanu Date: Fri, 28 Jun 2024 09:12:11 -0500 Subject: [PATCH 309/451] domain file or land data case domain file is actually set, in shr_strdata_type%domainFile all the other data models use the first stream file for domain information land is the one that actually has that member set in the SDLND structure it is easier to get it from there, then from stream the domain file in regular land case is defined by fatmlndfrac file --- .../data_comps/dlnd/src/lnd_comp_mct.F90 | 18 ++---------------- 1 file changed, 2 insertions(+), 16 deletions(-) diff --git a/components/data_comps/dlnd/src/lnd_comp_mct.F90 b/components/data_comps/dlnd/src/lnd_comp_mct.F90 index 8361a8522d8a..b699ec217f00 100644 --- a/components/data_comps/dlnd/src/lnd_comp_mct.F90 +++ b/components/data_comps/dlnd/src/lnd_comp_mct.F90 @@ -84,16 +84,6 @@ subroutine lnd_init_mct( EClock, cdata, x2l, l2x, NLFilename ) real(R8) :: scmLon = shr_const_SPVAL ! single column lon character(*), parameter :: subName = "(lnd_init_mct) " !------------------------------------------------------------------------------- -#ifdef HAVE_MOAB - character(CL) :: filePath ! generic file path - character(CL) :: fileName ! generic file name - character(CS) :: timeName ! domain file: time variable name - character(CS) :: lonName ! domain file: lon variable name - character(CS) :: latName ! domain file: lat variable name - character(CS) :: hgtName ! domain file: hgt variable name - character(CS) :: maskName ! domain file: mask variable name - character(CS) :: areaName ! domain file: area variable name -#endif ! Set cdata pointers call seq_cdata_setptrs(cdata, & @@ -176,13 +166,9 @@ subroutine lnd_init_mct( EClock, cdata, x2l, l2x, NLFilename ) scmMode, scmlat, scmlon) #ifdef HAVE_MOAB if (my_task == master_task) then - call shr_stream_getDomainInfo(SDLND%stream(1), filePath,fileName,timeName,lonName, & - latName,hgtName,maskName,areaName) - call shr_stream_getFile(filePath,fileName) - ! send path of data lnd domain to MOAB coupler. - call seq_infodata_PutData( infodata, lnd_domain=fileName) ! we use the same one for regular case + call seq_infodata_PutData( infodata, lnd_domain=SDLND%domainFile) ! we use the same one for regular case ! in regular case, it is copied from fatmlndfrc ; so we don't know if it is data land or not - write(logunit,*), ' filename: ', filename + write(logunit,*), ' use this land domain file: ', SDLND%domainFile endif #endif !---------------------------------------------------------------------------- From 9f0a28c35186b7f68daf7cf79b1643258ac73485 Mon Sep 17 00:00:00 2001 From: Iulian Grindeanu Date: Mon, 15 Jul 2024 10:33:50 -0500 Subject: [PATCH 310/451] apply weights is not used anymore in fractions iMOAB_ApplyScalarProjectionWeights is not used anymore all maps are done now with seq_map method, and there is only one instance of iMOAB_ApplyScalarProjectionWeights in E3SM using moab driver --- driver-moab/main/seq_frac_mct.F90 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/driver-moab/main/seq_frac_mct.F90 b/driver-moab/main/seq_frac_mct.F90 index a89fc0b9aa4f..031845a102ef 100644 --- a/driver-moab/main/seq_frac_mct.F90 +++ b/driver-moab/main/seq_frac_mct.F90 @@ -180,7 +180,7 @@ module seq_frac_mct use iMOAB, only : iMOAB_DefineTagStorage, iMOAB_SetDoubleTagStorage, & iMOAB_GetMeshInfo, iMOAB_SetDoubleTagStorageWithGid, iMOAB_WriteMesh, & - iMOAB_ApplyScalarProjectionWeights, iMOAB_SendElementTag, iMOAB_ReceiveElementTag, & + iMOAB_SendElementTag, iMOAB_ReceiveElementTag, & iMOAB_FreeSenderBuffers, iMOAB_GetDoubleTagStorage #ifdef MOABDEBUG use seq_comm_mct, only : num_moab_exports From a39296ce127815b05ef80253d1a986e75fc75dae Mon Sep 17 00:00:00 2001 From: Walter Hannah Date: Tue, 20 Aug 2024 16:46:20 -0400 Subject: [PATCH 311/451] re-enable MMF2 test --- cime_config/tests.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cime_config/tests.py b/cime_config/tests.py index 059c280e2bb4..0248077934d6 100644 --- a/cime_config/tests.py +++ b/cime_config/tests.py @@ -370,7 +370,7 @@ "ERP_Ln9.ne4pg2_oQU480.WCYCL20TRNS-MMF1.allactive-mmf_fixed_subcycle", "ERS_Ln9.ne4pg2_ne4pg2.FRCE-MMF1.eam-cosp_nhtfrq9", "SMS_Ln5.ne4_ne4.FSCM-ARM97-MMF1", - # "SMS_Ln3.ne4pg2_ne4pg2.F2010-MMF2", - temporarily disabled due to ongoing dev issues + "SMS_Ln3.ne4pg2_oQU480.F2010-MMF2", ) }, From fd620a5c8779956548980e335498ffef16552581 Mon Sep 17 00:00:00 2001 From: Naser Mahfouz Date: Wed, 21 Aug 2024 09:37:50 -0400 Subject: [PATCH 312/451] gen custom_pelayout, better case loc, and default proj --- run_e3sm.template.sh | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/run_e3sm.template.sh b/run_e3sm.template.sh index 413f2bf75286..86e360157598 100755 --- a/run_e3sm.template.sh +++ b/run_e3sm.template.sh @@ -15,7 +15,7 @@ main() { # Machine and project readonly MACHINE=pm-cpu # BEFORE RUNNING: CHANGE this to your project -readonly PROJECT="e3sm" +readonly PROJECT="$(sacctmgr show user $USER format=DefaultAccount | tail -n1 | tr -d ' ')" # Simulation readonly COMPSET="WCYCL1850" @@ -43,7 +43,7 @@ readonly GET_REFCASE=TRUE #readonly RUN_REFDATE="" # same as MODEL_START_DATE for 'branch', can be different for 'hybrid' # Set paths -readonly CASE_ROOT="${PSCRATCH}/e3sm-scratch/${MACHINE}/${CASE_NAME}" +readonly CASE_ROOT="${PSCRATCH}/E3SMv3/${CASE_NAME}" readonly CODE_ROOT="${HOME}/E3SMv3/code/${CHECKOUT}" # Sub-directories @@ -417,6 +417,12 @@ then # Number of cores per node (machine specific) if [ "${MACHINE}" == "pm-cpu" ]; then ncore=128 + elif [ "${MACHINE}" == "chrysalis" ]; then + ncore=64 + elif [ "${MACHINE}" == "compy" ]; then + ncore=40 + elif [ "${MACHINE}" == "anvil" ]; then + ncore=36 else echo 'ERROR: MACHINE = '${MACHINE}' is not supported for custom PE layout.' exit 400 From ec9833930b90653215a118f7295bf8bba4998632 Mon Sep 17 00:00:00 2001 From: Benjamin Hillman Date: Thu, 2 Mar 2023 07:33:31 -0800 Subject: [PATCH 313/451] Add F2010-SCREAMv1 test to e3sm_gpucxx suite --- cime_config/tests.py | 1 + 1 file changed, 1 insertion(+) diff --git a/cime_config/tests.py b/cime_config/tests.py index 059c280e2bb4..e0f2967fdadd 100644 --- a/cime_config/tests.py +++ b/cime_config/tests.py @@ -762,6 +762,7 @@ "e3sm_gpucxx" : { "tests" : ( "SMS_Ln9.ne4pg2_ne4pg2.F2010-MMF1", + "ERP_Ln9.ne4pg2_ne4pg2.F2010-SCREAMv1", ) }, From b326f278047eacc245c4d92e87d836ceee68f4af Mon Sep 17 00:00:00 2001 From: Benjamin Hillman Date: Wed, 21 Aug 2024 09:40:48 -0700 Subject: [PATCH 314/451] Revert to external cosp.F90 to fix build error for EAMxx --- components/eamxx/src/physics/cosp/CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/components/eamxx/src/physics/cosp/CMakeLists.txt b/components/eamxx/src/physics/cosp/CMakeLists.txt index e6ba4c363794..cd5c966a501a 100644 --- a/components/eamxx/src/physics/cosp/CMakeLists.txt +++ b/components/eamxx/src/physics/cosp/CMakeLists.txt @@ -17,7 +17,7 @@ set(EXTERNAL_SRC ${EAM_COSP_DIR}/external/src/cosp_constants.F90 ${EAM_COSP_DIR}/external/src/simulator/cosp_cloudsat_interface.F90 ${EAM_COSP_DIR}/external/src/cosp_config.F90 - ${EAM_COSP_DIR}/local/cosp.F90 + ${EAM_COSP_DIR}/external/src/cosp.F90 ${EAM_COSP_DIR}/external/src/cosp_stats.F90 ${EAM_COSP_DIR}/external/src/simulator/quickbeam/quickbeam.F90 ${EAM_COSP_DIR}/external/src/simulator/parasol/parasol.F90 From 49e1cb2ebda26e15c33ab62245606db132211576 Mon Sep 17 00:00:00 2001 From: Matthew Hoffman Date: Tue, 13 Aug 2024 12:30:05 -0500 Subject: [PATCH 315/451] Add additional fields to history files --- .../mpas-albany-landice/cime_config/buildnml | 36 +++++++++---------- 1 file changed, 18 insertions(+), 18 deletions(-) diff --git a/components/mpas-albany-landice/cime_config/buildnml b/components/mpas-albany-landice/cime_config/buildnml index 4d927c4370fd..e345853f84a5 100755 --- a/components/mpas-albany-landice/cime_config/buildnml +++ b/components/mpas-albany-landice/cime_config/buildnml @@ -229,25 +229,31 @@ def buildnml(case, caseroot, compname): lines.append(' ') lines.append(' ') lines.append(' ') + lines.append(' ') lines.append(' ') lines.append(' ') lines.append(' ') lines.append(' ') -# lines.append(' ') -# lines.append(' ') lines.append(' ') lines.append(' ') lines.append(' ') lines.append(' ') - lines.append(' ') - lines.append(' ') + lines.append(' ') + lines.append(' ') + lines.append(' ') + lines.append(' ') lines.append(' ') lines.append(' ') + lines.append(' ') lines.append(' ') lines.append(' ') lines.append(' ') lines.append(' ') lines.append(' ') + lines.append(' ') + lines.append(' ') + lines.append(' ') + lines.append(' ') lines.append('') lines.append('') lines.append('') @@ -263,22 +269,16 @@ def buildnml(case, caseroot, compname): lines.append(' filename_interval="0001-00-00_00:00:00"') lines.append(' clobber_mode="truncate"') lines.append(' packages="globalStatsAMPKG"') - lines.append(' output_interval="0000_01:00:00">') + lines.append(' output_interval="0000_00:00:01">') lines.append('') - lines.append(' ') - lines.append(' ') - lines.append(' ') - lines.append(' ') - lines.append(' ') - lines.append(' ') - lines.append(' ') - lines.append(' ') - lines.append(' ') - lines.append(' ') - lines.append(' ') - lines.append(' ') - lines.append(' ') + lines.append(' ') lines.append(' ') + lines.append(' ') + lines.append(' ') + lines.append(' ') + lines.append(' ') + lines.append(' ') + lines.append(' ') lines.append('') lines.append('') lines.append(' -'none' +'temperature' .true. 'file' 0.0 From 36147b9482bf6ca18009f368f02c083c2a63f39d Mon Sep 17 00:00:00 2001 From: Matthew Hoffman Date: Wed, 14 Aug 2024 16:03:06 -0500 Subject: [PATCH 317/451] Adjust MALI buildnml to look for mesh-specific albany_input.yaml files Also create the corresponding albany_input.*.yaml files --- .../namelist_files/albany_input.ais20km.yaml | 231 ++++++++++++++++ .../albany_input.ais_4to20km.yaml | 246 ++++++++++++++++++ .../albany_input.ais_8to30km.yaml | 246 ++++++++++++++++++ .../albany_input.aisgis20km.yaml | 231 ++++++++++++++++ .../albany_input.gis_1to10km_r01.yaml | 231 ++++++++++++++++ ...yaml => albany_input.gis_1to10km_r02.yaml} | 118 +++++---- .../albany_input.gis_20km_r01.yaml | 231 ++++++++++++++++ .../mpas-albany-landice/cime_config/buildnml | 6 +- 8 files changed, 1479 insertions(+), 61 deletions(-) create mode 100644 components/mpas-albany-landice/bld/namelist_files/albany_input.ais20km.yaml create mode 100644 components/mpas-albany-landice/bld/namelist_files/albany_input.ais_4to20km.yaml create mode 100644 components/mpas-albany-landice/bld/namelist_files/albany_input.ais_8to30km.yaml create mode 100644 components/mpas-albany-landice/bld/namelist_files/albany_input.aisgis20km.yaml create mode 100644 components/mpas-albany-landice/bld/namelist_files/albany_input.gis_1to10km_r01.yaml rename components/mpas-albany-landice/bld/namelist_files/{albany_input.yaml => albany_input.gis_1to10km_r02.yaml} (81%) create mode 100644 components/mpas-albany-landice/bld/namelist_files/albany_input.gis_20km_r01.yaml diff --git a/components/mpas-albany-landice/bld/namelist_files/albany_input.ais20km.yaml b/components/mpas-albany-landice/bld/namelist_files/albany_input.ais20km.yaml new file mode 100644 index 000000000000..589e163bba7f --- /dev/null +++ b/components/mpas-albany-landice/bld/namelist_files/albany_input.ais20km.yaml @@ -0,0 +1,231 @@ +%YAML 1.1 +--- +ANONYMOUS: + +# Discretization Description + Discretization: + #Exodus Output File Name: albany_output.exo + + Piro: +# Nonlinear Solver Information + NOX: + Nonlinear Solver: Line Search Based + Line Search: + Full Step: + Full Step: 1.0e+00 + Method: Backtrack + Solver Options: + Status Test Check Type: Minimal + Status Tests: + Test Type: Combo + Combo Type: OR + Number of Tests: 2 + Test 0: + Test Type: Combo + Combo Type: AND + Number of Tests: 2 + Test 0: + Test Type: NormF + Norm Type: Two Norm + Scale Type: Unscaled + Tolerance: 1.0e-03 + Test 1: + Test Type: RelativeNormF + Norm Type: Two Norm + Tolerance: 0.9999 + Test 1: + Test Type: MaxIters + Maximum Iterations: 100 + Printing: + Output Precision: 3 + Output Processor: 0 + Output Information: + Error: true + Warning: true + Outer Iteration: true + Parameters: false + Details: false + Linear Solver Details: false + Stepper Iteration: true + Stepper Details: true + Stepper Parameters: true + + Direction: + Method: Newton + Newton: + Forcing Term Method: Type 2 + Rescue Bad Newton Solve: true + Linear Solver: + Write Linear System: false + Tolerance: 1.0e-8 + + Stratimikos Linear Solver: + Stratimikos: + +# Linear Solver Information + Linear Solver Type: Belos + Linear Solver Types: + Belos: + Solver Type: Block GMRES + Solver Types: + Block GMRES: + Output Frequency: 20 + Output Style: 1 + Verbosity: 33 + Maximum Iterations: 200 + Block Size: 1 + Num Blocks: 200 + Flexible Gmres: false + VerboseObject: + Output File: none + Verbosity Level: low + +# Preconditioner Information + Preconditioner Type: MueLu + Preconditioner Types: + + Ifpack2: + Overlap: 1 + Prec Type: ILUT + + MueLu: + Matrix: + PDE equations: 2 + Factories: + myLineDetectionFact: + factory: LineDetectionFactory + 'linedetection: orientation': coordinates + mySemiCoarsenPFact1: + factory: SemiCoarsenPFactory + 'semicoarsen: coarsen rate': 14 + UncoupledAggregationFact2: + factory: UncoupledAggregationFactory + 'aggregation: ordering': graph + 'aggregation: max selected neighbors': 0 + 'aggregation: min agg size': 3 + 'aggregation: phase3 avoid singletons': true + MyCoarseMap2: + factory: CoarseMapFactory + Aggregates: UncoupledAggregationFact2 + myTentativePFact2: + 'tentative: calculate qr': true + factory: TentativePFactory + Aggregates: UncoupledAggregationFact2 + CoarseMap: MyCoarseMap2 + mySaPFact2: + 'sa: eigenvalue estimate num iterations': 10 + 'sa: damping factor': 1.33333e+00 + factory: SaPFactory + P: myTentativePFact2 + myTransferCoordinatesFact: + factory: CoordinatesTransferFactory + CoarseMap: MyCoarseMap2 + Aggregates: UncoupledAggregationFact2 + myTogglePFact: + factory: TogglePFactory + 'semicoarsen: number of levels': 2 + TransferFactories: + P1: mySemiCoarsenPFact1 + P2: mySaPFact2 + Ptent1: mySemiCoarsenPFact1 + Ptent2: myTentativePFact2 + Nullspace1: mySemiCoarsenPFact1 + Nullspace2: myTentativePFact2 + myRestrictorFact: + factory: TransPFactory + P: myTogglePFact + myToggleTransferCoordinatesFact: + factory: ToggleCoordinatesTransferFactory + Chosen P: myTogglePFact + TransferFactories: + Coordinates1: mySemiCoarsenPFact1 + Coordinates2: myTransferCoordinatesFact + myRAPFact: + factory: RAPFactory + P: myTogglePFact + R: myRestrictorFact + TransferFactories: + For Coordinates: myToggleTransferCoordinatesFact + myRepartitionHeuristicFact: + factory: RepartitionHeuristicFactory + A: myRAPFact + 'repartition: min rows per proc': 3000 + 'repartition: max imbalance': 1.327e+00 + 'repartition: start level': 1 + myZoltanInterface: + factory: ZoltanInterface + A: myRAPFact + Coordinates: myToggleTransferCoordinatesFact + number of partitions: myRepartitionHeuristicFact + myRepartitionFact: + factory: RepartitionFactory + A: myRAPFact + Partition: myZoltanInterface + 'repartition: remap parts': true + number of partitions: myRepartitionHeuristicFact + myRebalanceProlongatorFact: + factory: RebalanceTransferFactory + type: Interpolation + P: myTogglePFact + Coordinates: myToggleTransferCoordinatesFact + Nullspace: myTogglePFact + myRebalanceRestrictionFact: + factory: RebalanceTransferFactory + type: Restriction + R: myRestrictorFact + myRebalanceAFact: + factory: RebalanceAcFactory + A: myRAPFact + TransferFactories: { } + mySmoother1: + factory: TrilinosSmoother + type: LINESMOOTHING_BANDEDRELAXATION + 'smoother: pre or post': both + ParameterList: + 'relaxation: type': Gauss-Seidel + 'relaxation: sweeps': 1 + 'relaxation: damping factor': 1.0 + mySmoother3: + factory: TrilinosSmoother + type: RELAXATION + 'smoother: pre or post': both + ParameterList: + 'relaxation: type': Gauss-Seidel + 'relaxation: sweeps': 1 + 'relaxation: damping factor': 1.0 + mySmoother4: + factory: TrilinosSmoother + type: RELAXATION + 'smoother: pre or post': pre + ParameterList: + 'relaxation: type': Gauss-Seidel + 'relaxation: sweeps': 4 + 'relaxation: damping factor': 1.0 + Hierarchy: + max levels: 7 + 'coarse: max size': 2000 + verbosity: None + Finest: + Smoother: mySmoother1 + CoarseSolver: mySmoother4 + P: myRebalanceProlongatorFact + Nullspace: myRebalanceProlongatorFact + CoarseNumZLayers: myLineDetectionFact + LineDetection_Layers: myLineDetectionFact + LineDetection_VertLineIds: myLineDetectionFact + A: myRebalanceAFact + Coordinates: myRebalanceProlongatorFact + Importer: myRepartitionFact + All: + startLevel: 1 + Smoother: mySmoother4 + CoarseSolver: mySmoother4 + P: myRebalanceProlongatorFact + Nullspace: myRebalanceProlongatorFact + CoarseNumZLayers: myLineDetectionFact + LineDetection_Layers: myLineDetectionFact + LineDetection_VertLineIds: myLineDetectionFact + A: myRebalanceAFact + Coordinates: myRebalanceProlongatorFact + Importer: myRepartitionFact + diff --git a/components/mpas-albany-landice/bld/namelist_files/albany_input.ais_4to20km.yaml b/components/mpas-albany-landice/bld/namelist_files/albany_input.ais_4to20km.yaml new file mode 100644 index 000000000000..c3bc0cf8bd56 --- /dev/null +++ b/components/mpas-albany-landice/bld/namelist_files/albany_input.ais_4to20km.yaml @@ -0,0 +1,246 @@ +%YAML 1.1 +--- +ANONYMOUS: + Problem: + Basal Cubature Degree: 4 + LandIce Field Norm: + sliding_velocity_basalside: + Regularization Type: Given Value + Regularization Value: 1.0e-4 + LandIce BCs: + BC 0: + Basal Friction Coefficient: + Type: Power Law + Power Exponent: 0.2 + Mu Type: Field + Effective Pressure Type: Constant + Effective Pressure: 1.0 + # Zero Effective Pressure On Floating Ice At Nodes: true + Zero Beta On Floating Ice: true +# Discretization Description + Discretization: + #Exodus Output File Name: albany_output.exo + + Piro: +# Nonlinear Solver Information + NOX: + Nonlinear Solver: Line Search Based + Line Search: + Full Step: + Full Step: 1.0e+00 + Method: Backtrack + Solver Options: + Status Test Check Type: Minimal + Status Tests: + Test Type: Combo + Combo Type: OR + Number of Tests: 2 + Test 0: + Test Type: Combo + Combo Type: AND + Number of Tests: 2 + Test 0: + Test Type: NormF + Norm Type: Two Norm + Scale Type: Unscaled + Tolerance: 1.0e-03 + Test 1: + Test Type: RelativeNormF + Norm Type: Two Norm + Tolerance: 0.9999 + Test 1: + Test Type: MaxIters + Maximum Iterations: 100 + Printing: + Output Precision: 3 + Output Processor: 0 + Output Information: + Error: true + Warning: true + Outer Iteration: true + Parameters: false + Details: false + Linear Solver Details: false + Stepper Iteration: true + Stepper Details: true + Stepper Parameters: true + + Direction: + Method: Newton + Newton: + Forcing Term Method: Type 2 + Rescue Bad Newton Solve: true + Linear Solver: + Write Linear System: false + Tolerance: 1.0e-8 + + Stratimikos Linear Solver: + Stratimikos: + +# Linear Solver Information + Linear Solver Type: Belos + Linear Solver Types: + Belos: + Solver Type: Block GMRES + Solver Types: + Block GMRES: + Output Frequency: 20 + Output Style: 1 + Verbosity: 33 + Maximum Iterations: 200 + Block Size: 1 + Num Blocks: 200 + Flexible Gmres: false + VerboseObject: + Output File: none + Verbosity Level: low + +# Preconditioner Information + Preconditioner Type: MueLu + Preconditioner Types: + + Ifpack2: + Overlap: 1 + Prec Type: ILUT + + MueLu: + Matrix: + PDE equations: 2 + Factories: + myLineDetectionFact: + factory: LineDetectionFactory + 'linedetection: orientation': coordinates + mySemiCoarsenPFact1: + factory: SemiCoarsenPFactory + 'semicoarsen: coarsen rate': 14 + UncoupledAggregationFact2: + factory: UncoupledAggregationFactory + 'aggregation: ordering': graph + 'aggregation: max selected neighbors': 0 + 'aggregation: min agg size': 3 + 'aggregation: phase3 avoid singletons': true + MyCoarseMap2: + factory: CoarseMapFactory + Aggregates: UncoupledAggregationFact2 + myTentativePFact2: + 'tentative: calculate qr': true + factory: TentativePFactory + Aggregates: UncoupledAggregationFact2 + CoarseMap: MyCoarseMap2 + mySaPFact2: + 'sa: eigenvalue estimate num iterations': 10 + 'sa: damping factor': 1.33333e+00 + factory: SaPFactory + P: myTentativePFact2 + myTransferCoordinatesFact: + factory: CoordinatesTransferFactory + CoarseMap: MyCoarseMap2 + Aggregates: UncoupledAggregationFact2 + myTogglePFact: + factory: TogglePFactory + 'semicoarsen: number of levels': 2 + TransferFactories: + P1: mySemiCoarsenPFact1 + P2: mySaPFact2 + Ptent1: mySemiCoarsenPFact1 + Ptent2: myTentativePFact2 + Nullspace1: mySemiCoarsenPFact1 + Nullspace2: myTentativePFact2 + myRestrictorFact: + factory: TransPFactory + P: myTogglePFact + myToggleTransferCoordinatesFact: + factory: ToggleCoordinatesTransferFactory + Chosen P: myTogglePFact + TransferFactories: + Coordinates1: mySemiCoarsenPFact1 + Coordinates2: myTransferCoordinatesFact + myRAPFact: + factory: RAPFactory + P: myTogglePFact + R: myRestrictorFact + TransferFactories: + For Coordinates: myToggleTransferCoordinatesFact + myRepartitionHeuristicFact: + factory: RepartitionHeuristicFactory + A: myRAPFact + 'repartition: min rows per proc': 3000 + 'repartition: max imbalance': 1.327e+00 + 'repartition: start level': 1 + myZoltanInterface: + factory: ZoltanInterface + A: myRAPFact + Coordinates: myToggleTransferCoordinatesFact + number of partitions: myRepartitionHeuristicFact + myRepartitionFact: + factory: RepartitionFactory + A: myRAPFact + Partition: myZoltanInterface + 'repartition: remap parts': true + number of partitions: myRepartitionHeuristicFact + myRebalanceProlongatorFact: + factory: RebalanceTransferFactory + type: Interpolation + P: myTogglePFact + Coordinates: myToggleTransferCoordinatesFact + Nullspace: myTogglePFact + myRebalanceRestrictionFact: + factory: RebalanceTransferFactory + type: Restriction + R: myRestrictorFact + myRebalanceAFact: + factory: RebalanceAcFactory + A: myRAPFact + TransferFactories: { } + mySmoother1: + factory: TrilinosSmoother + type: LINESMOOTHING_BANDEDRELAXATION + 'smoother: pre or post': both + ParameterList: + 'relaxation: type': Gauss-Seidel + 'relaxation: sweeps': 1 + 'relaxation: damping factor': 1.0 + mySmoother3: + factory: TrilinosSmoother + type: RELAXATION + 'smoother: pre or post': both + ParameterList: + 'relaxation: type': Gauss-Seidel + 'relaxation: sweeps': 1 + 'relaxation: damping factor': 1.0 + mySmoother4: + factory: TrilinosSmoother + type: RELAXATION + 'smoother: pre or post': pre + ParameterList: + 'relaxation: type': Gauss-Seidel + 'relaxation: sweeps': 4 + 'relaxation: damping factor': 1.0 + Hierarchy: + max levels: 7 + 'coarse: max size': 2000 + verbosity: None + Finest: + Smoother: mySmoother1 + CoarseSolver: mySmoother4 + P: myRebalanceProlongatorFact + Nullspace: myRebalanceProlongatorFact + CoarseNumZLayers: myLineDetectionFact + LineDetection_Layers: myLineDetectionFact + LineDetection_VertLineIds: myLineDetectionFact + A: myRebalanceAFact + Coordinates: myRebalanceProlongatorFact + Importer: myRepartitionFact + All: + startLevel: 1 + Smoother: mySmoother4 + CoarseSolver: mySmoother4 + P: myRebalanceProlongatorFact + Nullspace: myRebalanceProlongatorFact + CoarseNumZLayers: myLineDetectionFact + LineDetection_Layers: myLineDetectionFact + LineDetection_VertLineIds: myLineDetectionFact + A: myRebalanceAFact + Coordinates: myRebalanceProlongatorFact + Importer: myRepartitionFact + diff --git a/components/mpas-albany-landice/bld/namelist_files/albany_input.ais_8to30km.yaml b/components/mpas-albany-landice/bld/namelist_files/albany_input.ais_8to30km.yaml new file mode 100644 index 000000000000..c3bc0cf8bd56 --- /dev/null +++ b/components/mpas-albany-landice/bld/namelist_files/albany_input.ais_8to30km.yaml @@ -0,0 +1,246 @@ +%YAML 1.1 +--- +ANONYMOUS: + Problem: + Basal Cubature Degree: 4 + LandIce Field Norm: + sliding_velocity_basalside: + Regularization Type: Given Value + Regularization Value: 1.0e-4 + LandIce BCs: + BC 0: + Basal Friction Coefficient: + Type: Power Law + Power Exponent: 0.2 + Mu Type: Field + Effective Pressure Type: Constant + Effective Pressure: 1.0 + # Zero Effective Pressure On Floating Ice At Nodes: true + Zero Beta On Floating Ice: true +# Discretization Description + Discretization: + #Exodus Output File Name: albany_output.exo + + Piro: +# Nonlinear Solver Information + NOX: + Nonlinear Solver: Line Search Based + Line Search: + Full Step: + Full Step: 1.0e+00 + Method: Backtrack + Solver Options: + Status Test Check Type: Minimal + Status Tests: + Test Type: Combo + Combo Type: OR + Number of Tests: 2 + Test 0: + Test Type: Combo + Combo Type: AND + Number of Tests: 2 + Test 0: + Test Type: NormF + Norm Type: Two Norm + Scale Type: Unscaled + Tolerance: 1.0e-03 + Test 1: + Test Type: RelativeNormF + Norm Type: Two Norm + Tolerance: 0.9999 + Test 1: + Test Type: MaxIters + Maximum Iterations: 100 + Printing: + Output Precision: 3 + Output Processor: 0 + Output Information: + Error: true + Warning: true + Outer Iteration: true + Parameters: false + Details: false + Linear Solver Details: false + Stepper Iteration: true + Stepper Details: true + Stepper Parameters: true + + Direction: + Method: Newton + Newton: + Forcing Term Method: Type 2 + Rescue Bad Newton Solve: true + Linear Solver: + Write Linear System: false + Tolerance: 1.0e-8 + + Stratimikos Linear Solver: + Stratimikos: + +# Linear Solver Information + Linear Solver Type: Belos + Linear Solver Types: + Belos: + Solver Type: Block GMRES + Solver Types: + Block GMRES: + Output Frequency: 20 + Output Style: 1 + Verbosity: 33 + Maximum Iterations: 200 + Block Size: 1 + Num Blocks: 200 + Flexible Gmres: false + VerboseObject: + Output File: none + Verbosity Level: low + +# Preconditioner Information + Preconditioner Type: MueLu + Preconditioner Types: + + Ifpack2: + Overlap: 1 + Prec Type: ILUT + + MueLu: + Matrix: + PDE equations: 2 + Factories: + myLineDetectionFact: + factory: LineDetectionFactory + 'linedetection: orientation': coordinates + mySemiCoarsenPFact1: + factory: SemiCoarsenPFactory + 'semicoarsen: coarsen rate': 14 + UncoupledAggregationFact2: + factory: UncoupledAggregationFactory + 'aggregation: ordering': graph + 'aggregation: max selected neighbors': 0 + 'aggregation: min agg size': 3 + 'aggregation: phase3 avoid singletons': true + MyCoarseMap2: + factory: CoarseMapFactory + Aggregates: UncoupledAggregationFact2 + myTentativePFact2: + 'tentative: calculate qr': true + factory: TentativePFactory + Aggregates: UncoupledAggregationFact2 + CoarseMap: MyCoarseMap2 + mySaPFact2: + 'sa: eigenvalue estimate num iterations': 10 + 'sa: damping factor': 1.33333e+00 + factory: SaPFactory + P: myTentativePFact2 + myTransferCoordinatesFact: + factory: CoordinatesTransferFactory + CoarseMap: MyCoarseMap2 + Aggregates: UncoupledAggregationFact2 + myTogglePFact: + factory: TogglePFactory + 'semicoarsen: number of levels': 2 + TransferFactories: + P1: mySemiCoarsenPFact1 + P2: mySaPFact2 + Ptent1: mySemiCoarsenPFact1 + Ptent2: myTentativePFact2 + Nullspace1: mySemiCoarsenPFact1 + Nullspace2: myTentativePFact2 + myRestrictorFact: + factory: TransPFactory + P: myTogglePFact + myToggleTransferCoordinatesFact: + factory: ToggleCoordinatesTransferFactory + Chosen P: myTogglePFact + TransferFactories: + Coordinates1: mySemiCoarsenPFact1 + Coordinates2: myTransferCoordinatesFact + myRAPFact: + factory: RAPFactory + P: myTogglePFact + R: myRestrictorFact + TransferFactories: + For Coordinates: myToggleTransferCoordinatesFact + myRepartitionHeuristicFact: + factory: RepartitionHeuristicFactory + A: myRAPFact + 'repartition: min rows per proc': 3000 + 'repartition: max imbalance': 1.327e+00 + 'repartition: start level': 1 + myZoltanInterface: + factory: ZoltanInterface + A: myRAPFact + Coordinates: myToggleTransferCoordinatesFact + number of partitions: myRepartitionHeuristicFact + myRepartitionFact: + factory: RepartitionFactory + A: myRAPFact + Partition: myZoltanInterface + 'repartition: remap parts': true + number of partitions: myRepartitionHeuristicFact + myRebalanceProlongatorFact: + factory: RebalanceTransferFactory + type: Interpolation + P: myTogglePFact + Coordinates: myToggleTransferCoordinatesFact + Nullspace: myTogglePFact + myRebalanceRestrictionFact: + factory: RebalanceTransferFactory + type: Restriction + R: myRestrictorFact + myRebalanceAFact: + factory: RebalanceAcFactory + A: myRAPFact + TransferFactories: { } + mySmoother1: + factory: TrilinosSmoother + type: LINESMOOTHING_BANDEDRELAXATION + 'smoother: pre or post': both + ParameterList: + 'relaxation: type': Gauss-Seidel + 'relaxation: sweeps': 1 + 'relaxation: damping factor': 1.0 + mySmoother3: + factory: TrilinosSmoother + type: RELAXATION + 'smoother: pre or post': both + ParameterList: + 'relaxation: type': Gauss-Seidel + 'relaxation: sweeps': 1 + 'relaxation: damping factor': 1.0 + mySmoother4: + factory: TrilinosSmoother + type: RELAXATION + 'smoother: pre or post': pre + ParameterList: + 'relaxation: type': Gauss-Seidel + 'relaxation: sweeps': 4 + 'relaxation: damping factor': 1.0 + Hierarchy: + max levels: 7 + 'coarse: max size': 2000 + verbosity: None + Finest: + Smoother: mySmoother1 + CoarseSolver: mySmoother4 + P: myRebalanceProlongatorFact + Nullspace: myRebalanceProlongatorFact + CoarseNumZLayers: myLineDetectionFact + LineDetection_Layers: myLineDetectionFact + LineDetection_VertLineIds: myLineDetectionFact + A: myRebalanceAFact + Coordinates: myRebalanceProlongatorFact + Importer: myRepartitionFact + All: + startLevel: 1 + Smoother: mySmoother4 + CoarseSolver: mySmoother4 + P: myRebalanceProlongatorFact + Nullspace: myRebalanceProlongatorFact + CoarseNumZLayers: myLineDetectionFact + LineDetection_Layers: myLineDetectionFact + LineDetection_VertLineIds: myLineDetectionFact + A: myRebalanceAFact + Coordinates: myRebalanceProlongatorFact + Importer: myRepartitionFact + diff --git a/components/mpas-albany-landice/bld/namelist_files/albany_input.aisgis20km.yaml b/components/mpas-albany-landice/bld/namelist_files/albany_input.aisgis20km.yaml new file mode 100644 index 000000000000..589e163bba7f --- /dev/null +++ b/components/mpas-albany-landice/bld/namelist_files/albany_input.aisgis20km.yaml @@ -0,0 +1,231 @@ +%YAML 1.1 +--- +ANONYMOUS: + +# Discretization Description + Discretization: + #Exodus Output File Name: albany_output.exo + + Piro: +# Nonlinear Solver Information + NOX: + Nonlinear Solver: Line Search Based + Line Search: + Full Step: + Full Step: 1.0e+00 + Method: Backtrack + Solver Options: + Status Test Check Type: Minimal + Status Tests: + Test Type: Combo + Combo Type: OR + Number of Tests: 2 + Test 0: + Test Type: Combo + Combo Type: AND + Number of Tests: 2 + Test 0: + Test Type: NormF + Norm Type: Two Norm + Scale Type: Unscaled + Tolerance: 1.0e-03 + Test 1: + Test Type: RelativeNormF + Norm Type: Two Norm + Tolerance: 0.9999 + Test 1: + Test Type: MaxIters + Maximum Iterations: 100 + Printing: + Output Precision: 3 + Output Processor: 0 + Output Information: + Error: true + Warning: true + Outer Iteration: true + Parameters: false + Details: false + Linear Solver Details: false + Stepper Iteration: true + Stepper Details: true + Stepper Parameters: true + + Direction: + Method: Newton + Newton: + Forcing Term Method: Type 2 + Rescue Bad Newton Solve: true + Linear Solver: + Write Linear System: false + Tolerance: 1.0e-8 + + Stratimikos Linear Solver: + Stratimikos: + +# Linear Solver Information + Linear Solver Type: Belos + Linear Solver Types: + Belos: + Solver Type: Block GMRES + Solver Types: + Block GMRES: + Output Frequency: 20 + Output Style: 1 + Verbosity: 33 + Maximum Iterations: 200 + Block Size: 1 + Num Blocks: 200 + Flexible Gmres: false + VerboseObject: + Output File: none + Verbosity Level: low + +# Preconditioner Information + Preconditioner Type: MueLu + Preconditioner Types: + + Ifpack2: + Overlap: 1 + Prec Type: ILUT + + MueLu: + Matrix: + PDE equations: 2 + Factories: + myLineDetectionFact: + factory: LineDetectionFactory + 'linedetection: orientation': coordinates + mySemiCoarsenPFact1: + factory: SemiCoarsenPFactory + 'semicoarsen: coarsen rate': 14 + UncoupledAggregationFact2: + factory: UncoupledAggregationFactory + 'aggregation: ordering': graph + 'aggregation: max selected neighbors': 0 + 'aggregation: min agg size': 3 + 'aggregation: phase3 avoid singletons': true + MyCoarseMap2: + factory: CoarseMapFactory + Aggregates: UncoupledAggregationFact2 + myTentativePFact2: + 'tentative: calculate qr': true + factory: TentativePFactory + Aggregates: UncoupledAggregationFact2 + CoarseMap: MyCoarseMap2 + mySaPFact2: + 'sa: eigenvalue estimate num iterations': 10 + 'sa: damping factor': 1.33333e+00 + factory: SaPFactory + P: myTentativePFact2 + myTransferCoordinatesFact: + factory: CoordinatesTransferFactory + CoarseMap: MyCoarseMap2 + Aggregates: UncoupledAggregationFact2 + myTogglePFact: + factory: TogglePFactory + 'semicoarsen: number of levels': 2 + TransferFactories: + P1: mySemiCoarsenPFact1 + P2: mySaPFact2 + Ptent1: mySemiCoarsenPFact1 + Ptent2: myTentativePFact2 + Nullspace1: mySemiCoarsenPFact1 + Nullspace2: myTentativePFact2 + myRestrictorFact: + factory: TransPFactory + P: myTogglePFact + myToggleTransferCoordinatesFact: + factory: ToggleCoordinatesTransferFactory + Chosen P: myTogglePFact + TransferFactories: + Coordinates1: mySemiCoarsenPFact1 + Coordinates2: myTransferCoordinatesFact + myRAPFact: + factory: RAPFactory + P: myTogglePFact + R: myRestrictorFact + TransferFactories: + For Coordinates: myToggleTransferCoordinatesFact + myRepartitionHeuristicFact: + factory: RepartitionHeuristicFactory + A: myRAPFact + 'repartition: min rows per proc': 3000 + 'repartition: max imbalance': 1.327e+00 + 'repartition: start level': 1 + myZoltanInterface: + factory: ZoltanInterface + A: myRAPFact + Coordinates: myToggleTransferCoordinatesFact + number of partitions: myRepartitionHeuristicFact + myRepartitionFact: + factory: RepartitionFactory + A: myRAPFact + Partition: myZoltanInterface + 'repartition: remap parts': true + number of partitions: myRepartitionHeuristicFact + myRebalanceProlongatorFact: + factory: RebalanceTransferFactory + type: Interpolation + P: myTogglePFact + Coordinates: myToggleTransferCoordinatesFact + Nullspace: myTogglePFact + myRebalanceRestrictionFact: + factory: RebalanceTransferFactory + type: Restriction + R: myRestrictorFact + myRebalanceAFact: + factory: RebalanceAcFactory + A: myRAPFact + TransferFactories: { } + mySmoother1: + factory: TrilinosSmoother + type: LINESMOOTHING_BANDEDRELAXATION + 'smoother: pre or post': both + ParameterList: + 'relaxation: type': Gauss-Seidel + 'relaxation: sweeps': 1 + 'relaxation: damping factor': 1.0 + mySmoother3: + factory: TrilinosSmoother + type: RELAXATION + 'smoother: pre or post': both + ParameterList: + 'relaxation: type': Gauss-Seidel + 'relaxation: sweeps': 1 + 'relaxation: damping factor': 1.0 + mySmoother4: + factory: TrilinosSmoother + type: RELAXATION + 'smoother: pre or post': pre + ParameterList: + 'relaxation: type': Gauss-Seidel + 'relaxation: sweeps': 4 + 'relaxation: damping factor': 1.0 + Hierarchy: + max levels: 7 + 'coarse: max size': 2000 + verbosity: None + Finest: + Smoother: mySmoother1 + CoarseSolver: mySmoother4 + P: myRebalanceProlongatorFact + Nullspace: myRebalanceProlongatorFact + CoarseNumZLayers: myLineDetectionFact + LineDetection_Layers: myLineDetectionFact + LineDetection_VertLineIds: myLineDetectionFact + A: myRebalanceAFact + Coordinates: myRebalanceProlongatorFact + Importer: myRepartitionFact + All: + startLevel: 1 + Smoother: mySmoother4 + CoarseSolver: mySmoother4 + P: myRebalanceProlongatorFact + Nullspace: myRebalanceProlongatorFact + CoarseNumZLayers: myLineDetectionFact + LineDetection_Layers: myLineDetectionFact + LineDetection_VertLineIds: myLineDetectionFact + A: myRebalanceAFact + Coordinates: myRebalanceProlongatorFact + Importer: myRepartitionFact + diff --git a/components/mpas-albany-landice/bld/namelist_files/albany_input.gis_1to10km_r01.yaml b/components/mpas-albany-landice/bld/namelist_files/albany_input.gis_1to10km_r01.yaml new file mode 100644 index 000000000000..589e163bba7f --- /dev/null +++ b/components/mpas-albany-landice/bld/namelist_files/albany_input.gis_1to10km_r01.yaml @@ -0,0 +1,231 @@ +%YAML 1.1 +--- +ANONYMOUS: + +# Discretization Description + Discretization: + #Exodus Output File Name: albany_output.exo + + Piro: +# Nonlinear Solver Information + NOX: + Nonlinear Solver: Line Search Based + Line Search: + Full Step: + Full Step: 1.0e+00 + Method: Backtrack + Solver Options: + Status Test Check Type: Minimal + Status Tests: + Test Type: Combo + Combo Type: OR + Number of Tests: 2 + Test 0: + Test Type: Combo + Combo Type: AND + Number of Tests: 2 + Test 0: + Test Type: NormF + Norm Type: Two Norm + Scale Type: Unscaled + Tolerance: 1.0e-03 + Test 1: + Test Type: RelativeNormF + Norm Type: Two Norm + Tolerance: 0.9999 + Test 1: + Test Type: MaxIters + Maximum Iterations: 100 + Printing: + Output Precision: 3 + Output Processor: 0 + Output Information: + Error: true + Warning: true + Outer Iteration: true + Parameters: false + Details: false + Linear Solver Details: false + Stepper Iteration: true + Stepper Details: true + Stepper Parameters: true + + Direction: + Method: Newton + Newton: + Forcing Term Method: Type 2 + Rescue Bad Newton Solve: true + Linear Solver: + Write Linear System: false + Tolerance: 1.0e-8 + + Stratimikos Linear Solver: + Stratimikos: + +# Linear Solver Information + Linear Solver Type: Belos + Linear Solver Types: + Belos: + Solver Type: Block GMRES + Solver Types: + Block GMRES: + Output Frequency: 20 + Output Style: 1 + Verbosity: 33 + Maximum Iterations: 200 + Block Size: 1 + Num Blocks: 200 + Flexible Gmres: false + VerboseObject: + Output File: none + Verbosity Level: low + +# Preconditioner Information + Preconditioner Type: MueLu + Preconditioner Types: + + Ifpack2: + Overlap: 1 + Prec Type: ILUT + + MueLu: + Matrix: + PDE equations: 2 + Factories: + myLineDetectionFact: + factory: LineDetectionFactory + 'linedetection: orientation': coordinates + mySemiCoarsenPFact1: + factory: SemiCoarsenPFactory + 'semicoarsen: coarsen rate': 14 + UncoupledAggregationFact2: + factory: UncoupledAggregationFactory + 'aggregation: ordering': graph + 'aggregation: max selected neighbors': 0 + 'aggregation: min agg size': 3 + 'aggregation: phase3 avoid singletons': true + MyCoarseMap2: + factory: CoarseMapFactory + Aggregates: UncoupledAggregationFact2 + myTentativePFact2: + 'tentative: calculate qr': true + factory: TentativePFactory + Aggregates: UncoupledAggregationFact2 + CoarseMap: MyCoarseMap2 + mySaPFact2: + 'sa: eigenvalue estimate num iterations': 10 + 'sa: damping factor': 1.33333e+00 + factory: SaPFactory + P: myTentativePFact2 + myTransferCoordinatesFact: + factory: CoordinatesTransferFactory + CoarseMap: MyCoarseMap2 + Aggregates: UncoupledAggregationFact2 + myTogglePFact: + factory: TogglePFactory + 'semicoarsen: number of levels': 2 + TransferFactories: + P1: mySemiCoarsenPFact1 + P2: mySaPFact2 + Ptent1: mySemiCoarsenPFact1 + Ptent2: myTentativePFact2 + Nullspace1: mySemiCoarsenPFact1 + Nullspace2: myTentativePFact2 + myRestrictorFact: + factory: TransPFactory + P: myTogglePFact + myToggleTransferCoordinatesFact: + factory: ToggleCoordinatesTransferFactory + Chosen P: myTogglePFact + TransferFactories: + Coordinates1: mySemiCoarsenPFact1 + Coordinates2: myTransferCoordinatesFact + myRAPFact: + factory: RAPFactory + P: myTogglePFact + R: myRestrictorFact + TransferFactories: + For Coordinates: myToggleTransferCoordinatesFact + myRepartitionHeuristicFact: + factory: RepartitionHeuristicFactory + A: myRAPFact + 'repartition: min rows per proc': 3000 + 'repartition: max imbalance': 1.327e+00 + 'repartition: start level': 1 + myZoltanInterface: + factory: ZoltanInterface + A: myRAPFact + Coordinates: myToggleTransferCoordinatesFact + number of partitions: myRepartitionHeuristicFact + myRepartitionFact: + factory: RepartitionFactory + A: myRAPFact + Partition: myZoltanInterface + 'repartition: remap parts': true + number of partitions: myRepartitionHeuristicFact + myRebalanceProlongatorFact: + factory: RebalanceTransferFactory + type: Interpolation + P: myTogglePFact + Coordinates: myToggleTransferCoordinatesFact + Nullspace: myTogglePFact + myRebalanceRestrictionFact: + factory: RebalanceTransferFactory + type: Restriction + R: myRestrictorFact + myRebalanceAFact: + factory: RebalanceAcFactory + A: myRAPFact + TransferFactories: { } + mySmoother1: + factory: TrilinosSmoother + type: LINESMOOTHING_BANDEDRELAXATION + 'smoother: pre or post': both + ParameterList: + 'relaxation: type': Gauss-Seidel + 'relaxation: sweeps': 1 + 'relaxation: damping factor': 1.0 + mySmoother3: + factory: TrilinosSmoother + type: RELAXATION + 'smoother: pre or post': both + ParameterList: + 'relaxation: type': Gauss-Seidel + 'relaxation: sweeps': 1 + 'relaxation: damping factor': 1.0 + mySmoother4: + factory: TrilinosSmoother + type: RELAXATION + 'smoother: pre or post': pre + ParameterList: + 'relaxation: type': Gauss-Seidel + 'relaxation: sweeps': 4 + 'relaxation: damping factor': 1.0 + Hierarchy: + max levels: 7 + 'coarse: max size': 2000 + verbosity: None + Finest: + Smoother: mySmoother1 + CoarseSolver: mySmoother4 + P: myRebalanceProlongatorFact + Nullspace: myRebalanceProlongatorFact + CoarseNumZLayers: myLineDetectionFact + LineDetection_Layers: myLineDetectionFact + LineDetection_VertLineIds: myLineDetectionFact + A: myRebalanceAFact + Coordinates: myRebalanceProlongatorFact + Importer: myRepartitionFact + All: + startLevel: 1 + Smoother: mySmoother4 + CoarseSolver: mySmoother4 + P: myRebalanceProlongatorFact + Nullspace: myRebalanceProlongatorFact + CoarseNumZLayers: myLineDetectionFact + LineDetection_Layers: myLineDetectionFact + LineDetection_VertLineIds: myLineDetectionFact + A: myRebalanceAFact + Coordinates: myRebalanceProlongatorFact + Importer: myRepartitionFact + diff --git a/components/mpas-albany-landice/bld/namelist_files/albany_input.yaml b/components/mpas-albany-landice/bld/namelist_files/albany_input.gis_1to10km_r02.yaml similarity index 81% rename from components/mpas-albany-landice/bld/namelist_files/albany_input.yaml rename to components/mpas-albany-landice/bld/namelist_files/albany_input.gis_1to10km_r02.yaml index 8b770a290ae4..2b70fd9b30fa 100644 --- a/components/mpas-albany-landice/bld/namelist_files/albany_input.yaml +++ b/components/mpas-albany-landice/bld/namelist_files/albany_input.gis_1to10km_r02.yaml @@ -12,35 +12,34 @@ ANONYMOUS: Basal Friction Coefficient: Type: Power Law Power Exponent: 1.0 - Mu Type: Field + Mu Type: Field Effective Pressure Type: Hydrostatic Computed At Nodes Zero Effective Pressure On Floating Ice At Nodes: true Zero Beta On Floating Ice: false Use Pressurized Bed Above Sea Level: false - # Discretization Description Discretization: #Exodus Output File Name: albany_output.exo - - Piro: + + Piro: # Nonlinear Solver Information - NOX: + NOX: Nonlinear Solver: Line Search Based - Line Search: - Full Step: + Line Search: + Full Step: Full Step: 1.0e+00 Method: Backtrack - Solver Options: + Solver Options: Status Test Check Type: Minimal - Status Tests: + Status Tests: Test Type: Combo Combo Type: OR Number of Tests: 2 - Test 0: + Test 0: Test Type: Combo Combo Type: AND Number of Tests: 2 - Test 0: + Test 0: Test Type: NormF Norm Type: Two Norm Scale Type: Unscaled @@ -49,13 +48,13 @@ ANONYMOUS: Test Type: RelativeNormF Norm Type: Two Norm Tolerance: 0.9999 - Test 1: + Test 1: Test Type: MaxIters Maximum Iterations: 100 - Printing: + Printing: Output Precision: 3 Output Processor: 0 - Output Information: + Output Information: Error: true Warning: true Outer Iteration: true @@ -66,21 +65,21 @@ ANONYMOUS: Stepper Details: true Stepper Parameters: true - Direction: + Direction: Method: Newton - Newton: - Forcing Term Method: Type 2 + Newton: + Forcing Term Method: Type 2 Rescue Bad Newton Solve: true Linear Solver: Write Linear System: false Tolerance: 1.0e-8 - - Stratimikos Linear Solver: + + Stratimikos Linear Solver: Stratimikos: - + # Linear Solver Information Linear Solver Type: Belos - Linear Solver Types: + Linear Solver Types: Belos: Solver Type: Block GMRES Solver Types: @@ -95,133 +94,133 @@ ANONYMOUS: VerboseObject: Output File: none Verbosity Level: low - + # Preconditioner Information Preconditioner Type: MueLu - Preconditioner Types: - - Ifpack2: + Preconditioner Types: + + Ifpack2: Overlap: 1 - Prec Type: ILUT - - MueLu: - Matrix: + Prec Type: ILUT + + MueLu: + Matrix: PDE equations: 2 - Factories: - myLineDetectionFact: + Factories: + myLineDetectionFact: factory: LineDetectionFactory 'linedetection: orientation': coordinates - mySemiCoarsenPFact1: + mySemiCoarsenPFact1: factory: SemiCoarsenPFactory 'semicoarsen: coarsen rate': 14 - UncoupledAggregationFact2: + UncoupledAggregationFact2: factory: UncoupledAggregationFactory 'aggregation: ordering': graph 'aggregation: max selected neighbors': 0 'aggregation: min agg size': 3 'aggregation: phase3 avoid singletons': true - MyCoarseMap2: + MyCoarseMap2: factory: CoarseMapFactory Aggregates: UncoupledAggregationFact2 - myTentativePFact2: + myTentativePFact2: 'tentative: calculate qr': true factory: TentativePFactory Aggregates: UncoupledAggregationFact2 CoarseMap: MyCoarseMap2 - mySaPFact2: + mySaPFact2: 'sa: eigenvalue estimate num iterations': 10 'sa: damping factor': 1.33333e+00 factory: SaPFactory P: myTentativePFact2 - myTransferCoordinatesFact: + myTransferCoordinatesFact: factory: CoordinatesTransferFactory CoarseMap: MyCoarseMap2 Aggregates: UncoupledAggregationFact2 - myTogglePFact: + myTogglePFact: factory: TogglePFactory 'semicoarsen: number of levels': 2 - TransferFactories: + TransferFactories: P1: mySemiCoarsenPFact1 P2: mySaPFact2 Ptent1: mySemiCoarsenPFact1 Ptent2: myTentativePFact2 Nullspace1: mySemiCoarsenPFact1 Nullspace2: myTentativePFact2 - myRestrictorFact: + myRestrictorFact: factory: TransPFactory P: myTogglePFact - myToggleTransferCoordinatesFact: + myToggleTransferCoordinatesFact: factory: ToggleCoordinatesTransferFactory Chosen P: myTogglePFact - TransferFactories: + TransferFactories: Coordinates1: mySemiCoarsenPFact1 Coordinates2: myTransferCoordinatesFact - myRAPFact: + myRAPFact: factory: RAPFactory P: myTogglePFact R: myRestrictorFact - TransferFactories: + TransferFactories: For Coordinates: myToggleTransferCoordinatesFact - myRepartitionHeuristicFact: + myRepartitionHeuristicFact: factory: RepartitionHeuristicFactory A: myRAPFact 'repartition: min rows per proc': 3000 'repartition: max imbalance': 1.327e+00 'repartition: start level': 1 - myZoltanInterface: + myZoltanInterface: factory: ZoltanInterface A: myRAPFact Coordinates: myToggleTransferCoordinatesFact number of partitions: myRepartitionHeuristicFact - myRepartitionFact: + myRepartitionFact: factory: RepartitionFactory A: myRAPFact Partition: myZoltanInterface 'repartition: remap parts': true number of partitions: myRepartitionHeuristicFact - myRebalanceProlongatorFact: + myRebalanceProlongatorFact: factory: RebalanceTransferFactory type: Interpolation P: myTogglePFact Coordinates: myToggleTransferCoordinatesFact Nullspace: myTogglePFact - myRebalanceRestrictionFact: + myRebalanceRestrictionFact: factory: RebalanceTransferFactory type: Restriction R: myRestrictorFact - myRebalanceAFact: + myRebalanceAFact: factory: RebalanceAcFactory A: myRAPFact TransferFactories: { } - mySmoother1: + mySmoother1: factory: TrilinosSmoother type: LINESMOOTHING_BANDEDRELAXATION 'smoother: pre or post': both - ParameterList: + ParameterList: 'relaxation: type': Gauss-Seidel 'relaxation: sweeps': 1 'relaxation: damping factor': 1.0 - mySmoother3: + mySmoother3: factory: TrilinosSmoother type: RELAXATION 'smoother: pre or post': both - ParameterList: + ParameterList: 'relaxation: type': Gauss-Seidel 'relaxation: sweeps': 1 'relaxation: damping factor': 1.0 - mySmoother4: + mySmoother4: factory: TrilinosSmoother type: RELAXATION 'smoother: pre or post': pre - ParameterList: + ParameterList: 'relaxation: type': Gauss-Seidel 'relaxation: sweeps': 4 'relaxation: damping factor': 1.0 - Hierarchy: + Hierarchy: max levels: 7 'coarse: max size': 2000 verbosity: None - Finest: + Finest: Smoother: mySmoother1 CoarseSolver: mySmoother4 P: myRebalanceProlongatorFact @@ -232,7 +231,7 @@ ANONYMOUS: A: myRebalanceAFact Coordinates: myRebalanceProlongatorFact Importer: myRepartitionFact - All: + All: startLevel: 1 Smoother: mySmoother4 CoarseSolver: mySmoother4 @@ -244,4 +243,3 @@ ANONYMOUS: A: myRebalanceAFact Coordinates: myRebalanceProlongatorFact Importer: myRepartitionFact - diff --git a/components/mpas-albany-landice/bld/namelist_files/albany_input.gis_20km_r01.yaml b/components/mpas-albany-landice/bld/namelist_files/albany_input.gis_20km_r01.yaml new file mode 100644 index 000000000000..589e163bba7f --- /dev/null +++ b/components/mpas-albany-landice/bld/namelist_files/albany_input.gis_20km_r01.yaml @@ -0,0 +1,231 @@ +%YAML 1.1 +--- +ANONYMOUS: + +# Discretization Description + Discretization: + #Exodus Output File Name: albany_output.exo + + Piro: +# Nonlinear Solver Information + NOX: + Nonlinear Solver: Line Search Based + Line Search: + Full Step: + Full Step: 1.0e+00 + Method: Backtrack + Solver Options: + Status Test Check Type: Minimal + Status Tests: + Test Type: Combo + Combo Type: OR + Number of Tests: 2 + Test 0: + Test Type: Combo + Combo Type: AND + Number of Tests: 2 + Test 0: + Test Type: NormF + Norm Type: Two Norm + Scale Type: Unscaled + Tolerance: 1.0e-03 + Test 1: + Test Type: RelativeNormF + Norm Type: Two Norm + Tolerance: 0.9999 + Test 1: + Test Type: MaxIters + Maximum Iterations: 100 + Printing: + Output Precision: 3 + Output Processor: 0 + Output Information: + Error: true + Warning: true + Outer Iteration: true + Parameters: false + Details: false + Linear Solver Details: false + Stepper Iteration: true + Stepper Details: true + Stepper Parameters: true + + Direction: + Method: Newton + Newton: + Forcing Term Method: Type 2 + Rescue Bad Newton Solve: true + Linear Solver: + Write Linear System: false + Tolerance: 1.0e-8 + + Stratimikos Linear Solver: + Stratimikos: + +# Linear Solver Information + Linear Solver Type: Belos + Linear Solver Types: + Belos: + Solver Type: Block GMRES + Solver Types: + Block GMRES: + Output Frequency: 20 + Output Style: 1 + Verbosity: 33 + Maximum Iterations: 200 + Block Size: 1 + Num Blocks: 200 + Flexible Gmres: false + VerboseObject: + Output File: none + Verbosity Level: low + +# Preconditioner Information + Preconditioner Type: MueLu + Preconditioner Types: + + Ifpack2: + Overlap: 1 + Prec Type: ILUT + + MueLu: + Matrix: + PDE equations: 2 + Factories: + myLineDetectionFact: + factory: LineDetectionFactory + 'linedetection: orientation': coordinates + mySemiCoarsenPFact1: + factory: SemiCoarsenPFactory + 'semicoarsen: coarsen rate': 14 + UncoupledAggregationFact2: + factory: UncoupledAggregationFactory + 'aggregation: ordering': graph + 'aggregation: max selected neighbors': 0 + 'aggregation: min agg size': 3 + 'aggregation: phase3 avoid singletons': true + MyCoarseMap2: + factory: CoarseMapFactory + Aggregates: UncoupledAggregationFact2 + myTentativePFact2: + 'tentative: calculate qr': true + factory: TentativePFactory + Aggregates: UncoupledAggregationFact2 + CoarseMap: MyCoarseMap2 + mySaPFact2: + 'sa: eigenvalue estimate num iterations': 10 + 'sa: damping factor': 1.33333e+00 + factory: SaPFactory + P: myTentativePFact2 + myTransferCoordinatesFact: + factory: CoordinatesTransferFactory + CoarseMap: MyCoarseMap2 + Aggregates: UncoupledAggregationFact2 + myTogglePFact: + factory: TogglePFactory + 'semicoarsen: number of levels': 2 + TransferFactories: + P1: mySemiCoarsenPFact1 + P2: mySaPFact2 + Ptent1: mySemiCoarsenPFact1 + Ptent2: myTentativePFact2 + Nullspace1: mySemiCoarsenPFact1 + Nullspace2: myTentativePFact2 + myRestrictorFact: + factory: TransPFactory + P: myTogglePFact + myToggleTransferCoordinatesFact: + factory: ToggleCoordinatesTransferFactory + Chosen P: myTogglePFact + TransferFactories: + Coordinates1: mySemiCoarsenPFact1 + Coordinates2: myTransferCoordinatesFact + myRAPFact: + factory: RAPFactory + P: myTogglePFact + R: myRestrictorFact + TransferFactories: + For Coordinates: myToggleTransferCoordinatesFact + myRepartitionHeuristicFact: + factory: RepartitionHeuristicFactory + A: myRAPFact + 'repartition: min rows per proc': 3000 + 'repartition: max imbalance': 1.327e+00 + 'repartition: start level': 1 + myZoltanInterface: + factory: ZoltanInterface + A: myRAPFact + Coordinates: myToggleTransferCoordinatesFact + number of partitions: myRepartitionHeuristicFact + myRepartitionFact: + factory: RepartitionFactory + A: myRAPFact + Partition: myZoltanInterface + 'repartition: remap parts': true + number of partitions: myRepartitionHeuristicFact + myRebalanceProlongatorFact: + factory: RebalanceTransferFactory + type: Interpolation + P: myTogglePFact + Coordinates: myToggleTransferCoordinatesFact + Nullspace: myTogglePFact + myRebalanceRestrictionFact: + factory: RebalanceTransferFactory + type: Restriction + R: myRestrictorFact + myRebalanceAFact: + factory: RebalanceAcFactory + A: myRAPFact + TransferFactories: { } + mySmoother1: + factory: TrilinosSmoother + type: LINESMOOTHING_BANDEDRELAXATION + 'smoother: pre or post': both + ParameterList: + 'relaxation: type': Gauss-Seidel + 'relaxation: sweeps': 1 + 'relaxation: damping factor': 1.0 + mySmoother3: + factory: TrilinosSmoother + type: RELAXATION + 'smoother: pre or post': both + ParameterList: + 'relaxation: type': Gauss-Seidel + 'relaxation: sweeps': 1 + 'relaxation: damping factor': 1.0 + mySmoother4: + factory: TrilinosSmoother + type: RELAXATION + 'smoother: pre or post': pre + ParameterList: + 'relaxation: type': Gauss-Seidel + 'relaxation: sweeps': 4 + 'relaxation: damping factor': 1.0 + Hierarchy: + max levels: 7 + 'coarse: max size': 2000 + verbosity: None + Finest: + Smoother: mySmoother1 + CoarseSolver: mySmoother4 + P: myRebalanceProlongatorFact + Nullspace: myRebalanceProlongatorFact + CoarseNumZLayers: myLineDetectionFact + LineDetection_Layers: myLineDetectionFact + LineDetection_VertLineIds: myLineDetectionFact + A: myRebalanceAFact + Coordinates: myRebalanceProlongatorFact + Importer: myRepartitionFact + All: + startLevel: 1 + Smoother: mySmoother4 + CoarseSolver: mySmoother4 + P: myRebalanceProlongatorFact + Nullspace: myRebalanceProlongatorFact + CoarseNumZLayers: myLineDetectionFact + LineDetection_Layers: myLineDetectionFact + LineDetection_VertLineIds: myLineDetectionFact + A: myRebalanceAFact + Coordinates: myRebalanceProlongatorFact + Importer: myRepartitionFact + diff --git a/components/mpas-albany-landice/cime_config/buildnml b/components/mpas-albany-landice/cime_config/buildnml index e345853f84a5..a42011e54073 100755 --- a/components/mpas-albany-landice/cime_config/buildnml +++ b/components/mpas-albany-landice/cime_config/buildnml @@ -300,7 +300,11 @@ def buildnml(case, caseroot, compname): if os.path.exists("{}/SourceMods/src.mali/{}".format(caseroot, albany_input_name)): safe_copy("{}/SourceMods/src.mali/{}".format(caseroot, albany_input_name), os.path.join(rundir, albany_input_name)) else: - safe_copy("{}/components/mpas-albany-landice/bld/namelist_files/{}".format(srcroot, albany_input_name), os.path.join(rundir, albany_input_name)) + # Each supported grid should have a corresponding albany_input.yaml file in + # components/mpas-albany-landice/bld/namelist_files/ + # Naming convention is albany_input.GRID_PREFIX.yaml + albany_input_name_grid = f"albany_input.{grid_prefix}.yaml" + safe_copy(f"{srcroot}/components/mpas-albany-landice/bld/namelist_files/{albany_input_name_grid}", os.path.join(rundir, albany_input_name)) ############################################################################### def _main_func(): From 57c057e5e396ee893d1ef98edfa3275cd56ed2cf Mon Sep 17 00:00:00 2001 From: Matthew Hoffman Date: Wed, 14 Aug 2024 16:28:32 -0500 Subject: [PATCH 318/451] Update glcshelf test to use ais8to30 mesh This was not possible when the mesh was added due to issues with the treatment of temperature in MALI. Now that those issues have been resolved, this test can be updated to the newer mesh. --- cime_config/tests.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cime_config/tests.py b/cime_config/tests.py index 059c280e2bb4..183004df2dd2 100644 --- a/cime_config/tests.py +++ b/cime_config/tests.py @@ -302,7 +302,7 @@ "SMS.ne30_f19_g16_rx1.A", "ERS_Ld5.T62_oQU120.CMPASO-NYF", "ERS.f09_g16_g.MALISIA", - "ERS_Ld5.TL319_oQU240wLI_ais20.MPAS_LISIO_JRA1p5.mpaso-ocn_glcshelf", + "ERS_Ld5.TL319_oQU240wLI_ais8to30.MPAS_LISIO_JRA1p5.mpaso-ocn_glcshelf", "SMS_P12x2.ne4pg2_oQU480.WCYCL1850NS.allactive-mach_mods", "ERS_Ln9.ne4pg2_ne4pg2.F2010-MMF1.eam-mmf_crmout", ) From bd084b04a0980bf9a3e1614997f7c32d8cecd75e Mon Sep 17 00:00:00 2001 From: Robert Jacob Date: Wed, 21 Aug 2024 15:27:19 -0500 Subject: [PATCH 319/451] Add and move a test to e3sm_integration. ERS.ne30pg2_r05_IcoswISC30E3r5.GPMPAS-JRA.mosart-rof_ocn_2way is moved from e3sm_developer to e3sm_integration because it is to large and was taking to much time/memory. To do that, it was removed from land_developer by removing the inheritance of e3sm_mosart_exonoshare Also add a moab-coupler test to e3sm-integration. --- cime_config/tests.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/cime_config/tests.py b/cime_config/tests.py index 059c280e2bb4..c6be199ea73a 100644 --- a/cime_config/tests.py +++ b/cime_config/tests.py @@ -80,7 +80,7 @@ "e3sm_land_developer" : { "share" : True, "time" : "0:45:00", - "inherit" : ("e3sm_mosart_developer", "e3sm_mosart_exenoshare", "e3sm_land_exeshare", "e3sm_land_exenoshare", "e3sm_land_debug", "fates_elm_developer"), + "inherit" : ("e3sm_mosart_developer", "e3sm_land_exeshare", "e3sm_land_exenoshare", "e3sm_land_debug", "fates_elm_developer"), "tests" : ( "ERS.f19_f19.I1850ELMCN", "ERS.f19_f19.I20TRELMCN", @@ -321,6 +321,7 @@ "time" : "03:00:00", "tests" : ( "ERS.ne4pg2_oQU480.WCYCL1850NS", + "ERS_Vmoab.ne4pg2_oQU480.WCYCL1850NS", "SMS_D_Ld1.ne30pg2_r05_IcoswISC30E3r5.WCYCL1850.allactive-wcprod", "SMS_D_Ld1.ne30pg2_r05_IcoswISC30E3r5.WCYCLSSP370.allactive-wcprodssp", "ERS_Ld3.ne4pg2_oQU480.F2010", @@ -337,6 +338,7 @@ "ERS_Ld3.ne30pg2_r05_IcoswISC30E3r5.WCYCL1850.allactive-nlmaps", "SMS_D_Ld1.ne30pg2_r05_IcoswISC30E3r5.CRYO1850-DISMF", "ERS.hcru_hcru.I20TRGSWCNPRDCTCBC.elm-erosion", + "ERS.ne30pg2_r05_IcoswISC30E3r5.GPMPAS-JRA.mosart-rof_ocn_2way", ) }, From 0b58cb0c955bafd28f906f1f1fb006153a0978a4 Mon Sep 17 00:00:00 2001 From: Azamat Mametjanov Date: Wed, 21 Aug 2024 23:18:20 +0000 Subject: [PATCH 320/451] Load pre-built kokkos module for GPU builds Also export ZES_ENABLE_SYSMAN=1 to avoid ext_intel_free_memory run-time errors. --- cime_config/machines/config_machines.xml | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/cime_config/machines/config_machines.xml b/cime_config/machines/config_machines.xml index c94a2bbcf7d2..b6ac815f58f6 100644 --- a/cime_config/machines/config_machines.xml +++ b/cime_config/machines/config_machines.xml @@ -3411,6 +3411,9 @@ oneapi/eng-compiler/2024.04.15.002 + + kokkos/git.7ff87a5-omp-sycl + spack cmake gcc/10.3.0 @@ -3439,6 +3442,8 @@ /soft/tools/mpi_wrapper_utils/gpu_tile_compact.sh 131072 20 + $ENV{KOKKOS_ROOT} + 1 0 From 226ac0ff37064badf2f4237b111a93ecdf20ce74 Mon Sep 17 00:00:00 2001 From: Azamat Mametjanov Date: Wed, 21 Aug 2024 23:21:54 +0000 Subject: [PATCH 321/451] Fix a SYCL typo Also avoid a call to variadic printf in a SYCL kernel within an error diagnostic log. --- components/homme/src/share/compose/cedr_kokkos.hpp | 2 +- components/homme/src/share/compose/compose_slmm_siqk.cpp | 2 ++ 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/components/homme/src/share/compose/cedr_kokkos.hpp b/components/homme/src/share/compose/cedr_kokkos.hpp index 42e423e2913a..758f4148a9a4 100644 --- a/components/homme/src/share/compose/cedr_kokkos.hpp +++ b/components/homme/src/share/compose/cedr_kokkos.hpp @@ -18,7 +18,7 @@ typedef Kokkos::Experimental::HIPSpace CedrGpuSpace; # endif # if defined KOKKOS_ENABLE_SYCL typedef Kokkos::Experimental::SYCL CedrGpuExeSpace; -typedef Kokkos::Experimental::SYCL> CedrGpuSpace; +typedef Kokkos::Experimental::SYCL CedrGpuSpace; # endif #endif diff --git a/components/homme/src/share/compose/compose_slmm_siqk.cpp b/components/homme/src/share/compose/compose_slmm_siqk.cpp index 628c023090cb..56564b0b8ca6 100644 --- a/components/homme/src/share/compose/compose_slmm_siqk.cpp +++ b/components/homme/src/share/compose/compose_slmm_siqk.cpp @@ -60,8 +60,10 @@ class TestSphereToRefKernel { // tol is on dx, not (a,b), so adjust slightly. if ( ! info.success || err > 1e4*tol_) { jinfo.nfails++; +#ifndef KOKKOS_ENABLE_SYCL printf("calc_sphere_to_ref ei %d i %d j %d: nits %d re %1.1e\n", ei, i, j, info.n_iterations, err); +#endif } jinfo.sum_nits += info.n_iterations; jinfo.max_nits = max(jinfo.max_nits, info.n_iterations); From d5c15c3ca7fa41b564b41b30aa79c146dafc399c Mon Sep 17 00:00:00 2001 From: Azamat Mametjanov Date: Wed, 21 Aug 2024 23:30:34 +0000 Subject: [PATCH 322/451] Let SYCL kernels call a virtual function --- .../machines/cmake_macros/oneapi-ifxgpu_aurora.cmake | 1 + .../machines/cmake_macros/oneapi-ifxgpu_sunspot.cmake | 7 +++++++ 2 files changed, 8 insertions(+) create mode 100644 cime_config/machines/cmake_macros/oneapi-ifxgpu_sunspot.cmake diff --git a/cime_config/machines/cmake_macros/oneapi-ifxgpu_aurora.cmake b/cime_config/machines/cmake_macros/oneapi-ifxgpu_aurora.cmake index 47d513408c2c..16288ce4dee7 100644 --- a/cime_config/machines/cmake_macros/oneapi-ifxgpu_aurora.cmake +++ b/cime_config/machines/cmake_macros/oneapi-ifxgpu_aurora.cmake @@ -5,3 +5,4 @@ if (compile_threaded) endif() string(APPEND KOKKOS_OPTIONS " -DCMAKE_CXX_STANDARD=17 -DKokkos_ENABLE_SERIAL=On -DKokkos_ARCH_INTEL_PVC=On -DKokkos_ENABLE_SYCL=On -DKokkos_ENABLE_EXPLICIT_INSTANTIATION=Off") string(APPEND SYCL_FLAGS " -\-intel -fsycl -fsycl-targets=spir64_gen -mlong-double-64 -Xsycl-target-backend \"-device 12.60.7\"") +string(APPEND CMAKE_CXX_FLAGS " -Xclang -fsycl-allow-virtual-functions") diff --git a/cime_config/machines/cmake_macros/oneapi-ifxgpu_sunspot.cmake b/cime_config/machines/cmake_macros/oneapi-ifxgpu_sunspot.cmake new file mode 100644 index 000000000000..6835515164f0 --- /dev/null +++ b/cime_config/machines/cmake_macros/oneapi-ifxgpu_sunspot.cmake @@ -0,0 +1,7 @@ + +string(APPEND CMAKE_EXE_LINKER_FLAGS " -lmkl_intel_lp64 -lmkl_sequential -lmkl_core") +if (compile_threaded) + string(APPEND CMAKE_EXE_LINKER_FLAGS " -fiopenmp -fopenmp-targets=spir64") +endif() +string(APPEND SYCL_FLAGS " -\-intel -fsycl -fsycl-targets=spir64_gen -mlong-double-64 -Xsycl-target-backend \"-device 12.60.7\"") +string(APPEND CMAKE_CXX_FLAGS " -Xclang -fsycl-allow-virtual-functions") From f84cad1e7e817b248ebfe45f7270cb36db29b8f5 Mon Sep 17 00:00:00 2001 From: Naser Mahfouz Date: Fri, 23 Aug 2024 10:15:38 -0400 Subject: [PATCH 323/451] improve the comment regarding PROJECT --- run_e3sm.template.sh | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/run_e3sm.template.sh b/run_e3sm.template.sh index 86e360157598..49869f5c6f63 100755 --- a/run_e3sm.template.sh +++ b/run_e3sm.template.sh @@ -14,7 +14,8 @@ main() { # Machine and project readonly MACHINE=pm-cpu -# BEFORE RUNNING: CHANGE this to your project +# NOTE: The command below will return your default project on SLURM-based systems. +# If you are not using SLURM or need a different project, remove the command and set it directly readonly PROJECT="$(sacctmgr show user $USER format=DefaultAccount | tail -n1 | tr -d ' ')" # Simulation @@ -53,7 +54,7 @@ readonly CASE_ARCHIVE_DIR=${CASE_ROOT}/archive # Define type of run # short tests: 'XS_2x5_ndays', 'XS_1x10_ndays', 'S_1x10_ndays', # 'M_1x10_ndays', 'M2_1x10_ndays', 'M80_1x10_ndays', 'L_1x10_ndays' -# * can replace XS, M, etc with custom-XY with XY being the node count +# * can replace XS, M, etc. with custom-XY with XY being the node count # or 'production' for full simulation readonly run='XS_2x5_ndays' if [ "${run}" != "production" ]; then From 455ac56439af77dfd7450c8718ea8500b0afa3d0 Mon Sep 17 00:00:00 2001 From: Jayesh Krishna Date: Fri, 23 Aug 2024 09:23:18 -0500 Subject: [PATCH 324/451] PnetCDF support for HOMME+BFB on Anvil/Chrysalis Adding support for the PnetCDF library in HOMME for the BFB tests on Anvil and Chrysalis. These configuration files are used for standalone HOMME builds on Anvil and Chrysalis --- components/homme/cmake/machineFiles/anvil-bfb.cmake | 9 ++++++++- components/homme/cmake/machineFiles/chrysalis-bfb.cmake | 8 +++++++- 2 files changed, 15 insertions(+), 2 deletions(-) diff --git a/components/homme/cmake/machineFiles/anvil-bfb.cmake b/components/homme/cmake/machineFiles/anvil-bfb.cmake index d46774646eb1..ab9b1d3edc86 100644 --- a/components/homme/cmake/machineFiles/anvil-bfb.cmake +++ b/components/homme/cmake/machineFiles/anvil-bfb.cmake @@ -20,7 +20,14 @@ ENDIF() # Set kokkos arch, to get correct avx flags SET (Kokkos_ARCH_BDW ON CACHE BOOL "") -SET (WITH_PNETCDF FALSE CACHE FILEPATH "") +EXECUTE_PROCESS(COMMAND pnetcdf-config --prefix + RESULT_VARIABLE PNCCONFIG_RESULT + OUTPUT_VARIABLE PNCCONFIG_OUTPUT + ERROR_VARIABLE PNCCONFIG_ERROR + OUTPUT_STRIP_TRAILING_WHITESPACE +) +SET (PnetCDF_PATH "${PNCCONFIG_OUTPUT}" CACHE STRING "") + # # anvil module system doesn't set environment variables, but will put # nc-config in our path. anvil seperates C and Fortran libraries, diff --git a/components/homme/cmake/machineFiles/chrysalis-bfb.cmake b/components/homme/cmake/machineFiles/chrysalis-bfb.cmake index ddeb7fa78111..b9f0d41a0606 100644 --- a/components/homme/cmake/machineFiles/chrysalis-bfb.cmake +++ b/components/homme/cmake/machineFiles/chrysalis-bfb.cmake @@ -20,7 +20,13 @@ SET (USE_MPI_OPTIONS "-K --cpu_bind=cores" CACHE STRING "") # Set kokkos arch, to get correct avx flags SET (Kokkos_ARCH_ZEN2 ON CACHE BOOL "") -SET (WITH_PNETCDF FALSE CACHE FILEPATH "") +EXECUTE_PROCESS(COMMAND pnetcdf-config --prefix + RESULT_VARIABLE PNCCONFIG_RESULT + OUTPUT_VARIABLE PNCCONFIG_OUTPUT + ERROR_VARIABLE PNCCONFIG_ERROR + OUTPUT_STRIP_TRAILING_WHITESPACE +) +SET (PnetCDF_PATH "${PNCCONFIG_OUTPUT}" CACHE STRING "") EXECUTE_PROCESS(COMMAND nf-config --prefix RESULT_VARIABLE NFCONFIG_RESULT From 5a60663a84c83adefcd3eab6c7613611ec3dd187 Mon Sep 17 00:00:00 2001 From: Walter Hannah Date: Fri, 23 Aug 2024 08:55:47 -0600 Subject: [PATCH 325/451] fix commens and add file global attributes --- .../eam/tools/mkatmsrffile/mkatmsrffile.py | 23 +++++++++++++------ 1 file changed, 16 insertions(+), 7 deletions(-) diff --git a/components/eam/tools/mkatmsrffile/mkatmsrffile.py b/components/eam/tools/mkatmsrffile/mkatmsrffile.py index 50999b6e945f..826544feb084 100644 --- a/components/eam/tools/mkatmsrffile/mkatmsrffile.py +++ b/components/eam/tools/mkatmsrffile/mkatmsrffile.py @@ -1,9 +1,8 @@ #!/usr/bin/env python3 #--------------------------------------------------------------------------------------------------- ''' -This is a replacement for the legacy gen_domain tool created for CESM. -Most legacy functionality is reproduced, with the notable exception of -the pole point latitude adjustment needed for the CESM FV grid. +This is a replacement for the legacy mkatmsrffile tool created for CESM. +All legacy functionality is reproduced. Created April, 2024 by Walter Hannah (LLNL) ''' @@ -22,12 +21,14 @@ #--------------------------------------------------------------------------------------------------- import datetime, os, numpy as np, xarray as xr, numba, itertools, subprocess as sp user, host = os.getenv('USER'), os.getenv('HOST') -source_code_meta = 'generate_domain_E3SM.py' +source_code_meta = 'mkatmsrffile.py' #--------------------------------------------------------------------------------------------------- class clr:END,RED,GREEN,MAGENTA,CYAN = '\033[0m','\033[31m','\033[32m','\033[35m','\033[36m' #--------------------------------------------------------------------------------------------------- usage = ''' python mkatmsrffile.py --map_file + --vegetation_file + --soil_water_file --dst_grid [--output-root ] [--date-stamp ] @@ -47,7 +48,6 @@ class clr:END,RED,GREEN,MAGENTA,CYAN = '\033[0m','\033[31m','\033[32m','\033[35m The following output file is created: atmsrf__.nc - ???? ''' from optparse import OptionParser @@ -71,11 +71,11 @@ class clr:END,RED,GREEN,MAGENTA,CYAN = '\033[0m','\033[31m','\033[32m','\033[35m parser.add_option('--output_root', dest='output_root', default='./', - help='Output path for domain files') + help='Output path for atmsrf files') parser.add_option('--date-stamp', dest='date_stamp', default=None, - help='Creation date stamp for domain files') + help='Creation date stamp for atmsrf files') (opts, args) = parser.parse_args() #--------------------------------------------------------------------------------------------------- def main(): @@ -252,6 +252,15 @@ def main(): ds_out['soilw'] = xr.DataArray(SOILW ,dims=['month','ncol']) ds_out['lon'] = ds_map.xc_b.rename({'n_b':'ncol'}) ds_out['lat'] = ds_map.yc_b.rename({'n_b':'ncol'}) + + ds.attrs['title'] = 'E3SM atmosphere surface data' + ds.attrs['source_code'] = source_code_meta + ds.attrs['hostname'] = str(host) + ds.attrs['history'] = f'created by {user}, '+datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S') + ds.attrs['input_map_file'] = opts.map_file + ds.attrs['input_vegetation_file'] = opts.vegetation_file + ds.attrs['input_soil_water_file'] = opts.soil_water_file + ds_out.to_netcdf(path=output_file,mode='w') #----------------------------------------------------------------------------- From b114661343405091a72fe5de722d68376a796a79 Mon Sep 17 00:00:00 2001 From: Wuyin Lin Date: Sun, 25 Aug 2024 23:40:48 -0500 Subject: [PATCH 326/451] Add alternative data stream control for SO2 species in ect_frc --- .../namelist_files/namelist_definition.xml | 18 + .../eam/src/chemistry/mozart/chemistry.F90 | 13 +- .../eam/src/chemistry/mozart/mo_chemini.F90 | 7 +- .../eam/src/chemistry/mozart/mo_extfrc.F90 | 31 +- .../eam/src/chemistry/mozart/tracer_data.F90 | 2884 +++++++++++++++++ 5 files changed, 2945 insertions(+), 8 deletions(-) create mode 100644 components/eam/src/chemistry/mozart/tracer_data.F90 diff --git a/components/eam/bld/namelist_files/namelist_definition.xml b/components/eam/bld/namelist_files/namelist_definition.xml index b3ecb5e9290a..8228c7d8d2e3 100644 --- a/components/eam/bld/namelist_files/namelist_definition.xml +++ b/components/eam/bld/namelist_files/namelist_definition.xml @@ -5138,6 +5138,17 @@ Format: YYYY Default: 0 + +The cycle year of the volcanic SO2 forcing (3D emissions) data. +Use this in place of ext_frc_cycle_yr if non-default, to allow different +speciciations volcanic emission and aerosols/precursors, which may be +invoked for single forcing simulation design. +if ext_frc_volc_type is 'CYCLICAL'. +Format: YYYY +Default: -1 + + Default: current model date @@ -5189,6 +5200,13 @@ Can be set to 'CYCLICAL', 'SERIAL', 'INTERP_MISSING_MONTHS', or 'FIXED'. Default: 'CYCLICAL' + +Type of time interpolation for fixed lower boundary data. See also ext_frc_volc_cycle_yr. +Can be set to 'NULL','CYCLICAL', 'SERIAL', 'INTERP_MISSING_MONTHS', or 'FIXED'. +Default: 'NULL' + + The cycle year of the fixed lower boundary data diff --git a/components/eam/src/chemistry/mozart/chemistry.F90 b/components/eam/src/chemistry/mozart/chemistry.F90 index f78ceda1dea7..3412e1b9bf92 100644 --- a/components/eam/src/chemistry/mozart/chemistry.F90 +++ b/components/eam/src/chemistry/mozart/chemistry.F90 @@ -106,6 +106,13 @@ module chemistry integer :: ext_frc_fixed_ymd = 0 integer :: ext_frc_fixed_tod = 0 + ! alternative type and cycle year for volcanic and other SO2 for controlling single forcing experiments + ! if NULL, same treatment as for the other species. + ! Possible in the future to modify further and apply to volcanic sector of SO2 alone + + character(len=24) :: ext_frc_volc_type = 'NULL' !'NULL'|'CYCLICAL'|'SERIAL'|'INTERP_MISSING_MONTHS' + integer :: ext_frc_volc_cycle_yr = -1 + real(r8) :: dms_emis_scale = 1._r8 ! fixed stratosphere @@ -515,7 +522,7 @@ subroutine chem_readnl(nlfile) srf_emis_type, srf_emis_cycle_yr, srf_emis_fixed_ymd, srf_emis_fixed_tod, srf_emis_specifier, & fstrat_file, fstrat_list, fstrat_efold_list, & ext_frc_specifier, ext_frc_type, ext_frc_cycle_yr, ext_frc_fixed_ymd, ext_frc_fixed_tod, & - dms_emis_scale + ext_frc_volc_type, ext_frc_volc_cycle_yr, dms_emis_scale namelist /chem_inparm/ chem_rad_passive @@ -689,6 +696,8 @@ subroutine chem_readnl(nlfile) call mpibcast (ext_frc_cycle_yr, 1, mpiint, 0, mpicom) call mpibcast (ext_frc_fixed_ymd, 1, mpiint, 0, mpicom) call mpibcast (ext_frc_fixed_tod, 1, mpiint, 0, mpicom) + call mpibcast (ext_frc_volc_type, len(ext_frc_volc_type), mpichar, 0, mpicom) + call mpibcast (ext_frc_volc_cycle_yr, 1, mpiint, 0, mpicom) call mpibcast (dms_emis_scale, 1, mpir8, 0, mpicom) @@ -1033,6 +1042,8 @@ subroutine chem_init(phys_state, pbuf2d, species_class) , ext_frc_cycle_yr & , ext_frc_fixed_ymd & , ext_frc_fixed_tod & + , ext_frc_volc_type & + , ext_frc_volc_cycle_yr & , xactive_prates & , exo_coldens_file & , tuv_xsect_file & diff --git a/components/eam/src/chemistry/mozart/mo_chemini.F90 b/components/eam/src/chemistry/mozart/mo_chemini.F90 index ff0eb0df15f1..564855d76dc5 100644 --- a/components/eam/src/chemistry/mozart/mo_chemini.F90 +++ b/components/eam/src/chemistry/mozart/mo_chemini.F90 @@ -43,6 +43,8 @@ subroutine chemini & , ext_frc_cycle_yr & , ext_frc_fixed_ymd & , ext_frc_fixed_tod & + , ext_frc_volc_type & + , ext_frc_volc_cycle_yr & , xactive_prates & , exo_coldens_file & , tuv_xsect_file & @@ -133,6 +135,8 @@ subroutine chemini & integer, intent(in) :: ext_frc_cycle_yr integer, intent(in) :: ext_frc_fixed_ymd integer, intent(in) :: ext_frc_fixed_tod + character(len=*), intent(in) :: ext_frc_volc_type + integer, intent(in) :: ext_frc_volc_cycle_yr character(len=*), intent(in) :: srf_emis_type integer, intent(in) :: srf_emis_cycle_yr integer, intent(in) :: srf_emis_fixed_ymd @@ -183,7 +187,8 @@ subroutine chemini & ! ... initialize external forcings module !----------------------------------------------------------------------- call setext_inti() - call extfrc_inti(ext_frc_specifier, ext_frc_type, ext_frc_cycle_yr, ext_frc_fixed_ymd, ext_frc_fixed_tod) + call extfrc_inti(ext_frc_specifier, ext_frc_type, ext_frc_cycle_yr, ext_frc_fixed_ymd, ext_frc_fixed_tod, & + ext_frc_volc_type, ext_frc_volc_cycle_yr) if (masterproc) write(iulog,*) 'chemini: after extfrc_inti on node ',iam !----------------------------------------------------------------------- diff --git a/components/eam/src/chemistry/mozart/mo_extfrc.F90 b/components/eam/src/chemistry/mozart/mo_extfrc.F90 index 23b3f480882e..d00e0d5673e9 100644 --- a/components/eam/src/chemistry/mozart/mo_extfrc.F90 +++ b/components/eam/src/chemistry/mozart/mo_extfrc.F90 @@ -46,7 +46,8 @@ module mo_extfrc contains - subroutine extfrc_inti( extfrc_specifier, extfrc_type, extfrc_cycle_yr, extfrc_fixed_ymd, extfrc_fixed_tod) + subroutine extfrc_inti( extfrc_specifier, extfrc_type, extfrc_cycle_yr, extfrc_fixed_ymd, extfrc_fixed_tod, & + extfrc_volc_type, extfrc_volc_cycle_yr) !----------------------------------------------------------------------- ! ... initialize the surface forcings @@ -71,6 +72,8 @@ subroutine extfrc_inti( extfrc_specifier, extfrc_type, extfrc_cycle_yr, extfrc_f integer , intent(in) :: extfrc_cycle_yr integer , intent(in) :: extfrc_fixed_ymd integer , intent(in) :: extfrc_fixed_tod + character(len=*), intent(in) :: extfrc_volc_type + integer , intent(in) :: extfrc_volc_cycle_yr !----------------------------------------------------------------------- ! ... local variables @@ -204,6 +207,14 @@ subroutine extfrc_inti( extfrc_specifier, extfrc_type, extfrc_cycle_yr, extfrc_f else if( extfrc_type == 'CYCLICAL' ) then write(iulog,*) ' cycle year = ',extfrc_cycle_yr end if + if (extfrc_volc_type /= 'NULL' ) then + write(iulog,*) ' ' + write(iulog,*) 'Volcanic SO2 type = ',extfrc_volc_type + if (extfrc_volc_type == 'CYCLICAL' ) then + write(iulog,*) ' ' + write(iulog,*) 'Volcanic SO2 cycle year = ',extfrc_volc_cycle_yr + end if + end if write(iulog,*) ' ' write(iulog,*) 'there are ',extfrc_cnt,' species with external forcing files' do m = 1,extfrc_cnt @@ -264,11 +275,19 @@ subroutine extfrc_inti( extfrc_specifier, extfrc_type, extfrc_cycle_yr, extfrc_f allocate(forcings(m)%file%in_pbuf(size(forcings(m)%sectors))) forcings(m)%file%in_pbuf(:) = .false. - call trcdata_init( forcings(m)%sectors, & - forcings(m)%filename, filelist, datapath, & - forcings(m)%fields, & - forcings(m)%file, & - rmv_file, extfrc_cycle_yr, extfrc_fixed_ymd, extfrc_fixed_tod, extfrc_type) + if (trim(forcings(m)%species) == 'SO2' .and. extfrc_volc_type /= 'NULL') then + call trcdata_init( forcings(m)%sectors, & + forcings(m)%filename, filelist, datapath, & + forcings(m)%fields, & + forcings(m)%file, rmv_file, extfrc_volc_cycle_yr, & + extfrc_fixed_ymd, extfrc_fixed_tod, extfrc_volc_type) + else + call trcdata_init( forcings(m)%sectors, & + forcings(m)%filename, filelist, datapath, & + forcings(m)%fields, & + forcings(m)%file, & + rmv_file, extfrc_cycle_yr, extfrc_fixed_ymd, extfrc_fixed_tod, extfrc_type) + end if enddo frcing_loop diff --git a/components/eam/src/chemistry/mozart/tracer_data.F90 b/components/eam/src/chemistry/mozart/tracer_data.F90 new file mode 100644 index 000000000000..62ccbcef8a25 --- /dev/null +++ b/components/eam/src/chemistry/mozart/tracer_data.F90 @@ -0,0 +1,2884 @@ +module tracer_data +!----------------------------------------------------------------------- +! module used to read (and interpolate) offline tracer data (sources and +! mixing ratios) +! Created by: Francis Vitt -- 2 May 2006 +! Modified by : Jim Edwards -- 10 March 2009 +! Modified by : Cheryl Craig and Chih-Chieh (Jack) Chen -- February 2010 +! Modified by : Jinbo Xie --March 2023 +! Added a new option in interpolate_trcdata to work on linoz +! inputdata. A new UCI interpolation that better conserves +! mass in implemented and added a new function. It is called +! when linoz data are used in interpolate_trcdata. +! +!----------------------------------------------------------------------- + + use perf_mod, only : t_startf, t_stopf + use shr_kind_mod, only : r8 => shr_kind_r8,r4 => shr_kind_r4, shr_kind_cl, SHR_KIND_CS + use time_manager, only : get_curr_date, get_step_size, get_curr_calday + use spmd_utils, only : masterproc + use ppgrid, only : pcols, pver, pverp, begchunk, endchunk + use cam_abortutils, only : endrun + use cam_logfile, only : iulog + + use physics_buffer, only : physics_buffer_desc, pbuf_get_field, pbuf_get_index + use time_manager, only : set_time_float_from_date, set_date_from_time_float + use pio, only : file_desc_t, var_desc_t, & + pio_seterrorhandling, pio_internal_error, pio_bcast_error, & + pio_setdebuglevel, & + pio_char, pio_noerr, & + pio_inq_dimid, pio_inq_varid, & + pio_def_dim, pio_def_var, & + pio_put_att, pio_put_var, & + pio_get_var, pio_get_att, pio_nowrite, pio_inq_dimlen, & + pio_inq_vardimid, pio_inq_dimlen, pio_closefile, & + pio_inquire_variable + + implicit none + + private ! all unless made public + save + + public :: trfld, input3d, input2d, trfile + public :: trcdata_init + public :: advance_trcdata + public :: get_fld_data + public :: put_fld_data + public :: get_fld_ndx + public :: write_trc_restart + public :: read_trc_restart + public :: init_trc_restart + public :: incr_filename + !added public for linoz new function diagnostic + public :: read_next_trcdata + public :: interpolate_trcdata + public :: get_model_time + !!PUBLIC MEMBERS + + type input3d + real(r8), dimension(:,:,:), pointer :: data => null() + endtype input3d + + type input2d + real(r8), dimension(:,:), pointer :: data => null() + endtype input2d + + type trfld + real(r8), dimension(:,:,:), pointer :: data => null() + type(input3d), dimension(4) :: input + character(len=32) :: srcnam + character(len=32) :: fldnam + character(len=32) :: units + type(var_desc_t) :: var_id + integer :: coords(4) ! LATDIM | LONDIM | LEVDIM | TIMDIM + integer :: order(4) ! LATDIM | LONDIM | LEVDIM | TIMDIM + logical :: srf_fld = .false. + integer :: pbuf_ndx = -1 + endtype trfld + + type trfile + type(input2d), dimension(4) :: ps_in + character(len=shr_kind_cl) :: pathname = ' ' + character(len=shr_kind_cl) :: curr_filename = ' ' + character(len=shr_kind_cl) :: next_filename = ' ' + type(file_desc_t) :: curr_fileid + type(file_desc_t) :: next_fileid + + type(var_desc_t), pointer :: currfnameid => null() ! pio restart file var id + type(var_desc_t), pointer :: nextfnameid => null() ! pio restart file var id + + character(len=shr_kind_cl) :: filenames_list = '' + real(r8) :: datatimem = -1.e36_r8 ! time of prv. values read in + real(r8) :: datatimep = -1.e36_r8 ! time of nxt. values read in + real(r8) :: datatimes(4) + integer :: interp_recs + real(r8), pointer, dimension(:) :: curr_data_times => null() + real(r8), pointer, dimension(:) :: next_data_times => null() + logical :: remove_trc_file = .false. ! delete file when finished with it + real(r8) :: offset_time + integer :: cyc_ndx_beg + integer :: cyc_ndx_end + integer :: cyc_yr = 0 + real(r8) :: one_yr = 0 + real(r8) :: curr_mod_time ! model time - calendar day + real(r8) :: next_mod_time ! model time - calendar day - next time step + integer :: nlon + integer :: nlat + integer :: nlev + integer :: nilev + integer :: ps_coords(3) ! LATDIM | LONDIM | TIMDIM + integer :: ps_order(3) ! LATDIM | LONDIM | TIMDIM + real(r8), pointer, dimension(:) :: lons => null() + real(r8), pointer, dimension(:) :: lats => null() + real(r8), pointer, dimension(:) :: levs => null() + real(r8), pointer, dimension(:) :: ilevs => null() + real(r8), pointer, dimension(:) :: hyam => null() + real(r8), pointer, dimension(:) :: hybm => null() + real(r8), pointer, dimension(:,:) :: ps => null() + real(r8), pointer, dimension(:) :: hyai => null() + real(r8), pointer, dimension(:) :: hybi => null() + real(r8), pointer, dimension(:,:) :: weight_x => null(), weight_y => null() + integer, pointer, dimension(:) :: count_x => null(), count_y => null() + integer, pointer, dimension(:,:) :: index_x => null(), index_y => null() + real(r8) :: p0 + type(var_desc_t) :: ps_id + logical, allocatable, dimension(:) :: in_pbuf + logical :: has_ps = .false. + logical :: zonal_ave = .false. + logical :: alt_data = .false. + logical :: cyclical = .false. + logical :: cyclical_list = .false. + logical :: weight_by_lat = .false. + logical :: conserve_column = .false. + logical :: fill_in_months = .false. + logical :: fixed = .false. + logical :: initialized = .false. + logical :: top_bndry = .false. + logical :: stepTime = .false. ! Do not interpolate in time, but use stepwise times + logical :: linoz_v3 = .false. !set for linoz_v3 interpolation only + logical :: linoz_v2 = .false. !set for linoz_v2 interpolation only + endtype trfile + + integer, public, parameter :: MAXTRCRS = 100 + + integer, parameter :: LONDIM = 1 + integer, parameter :: LATDIM = 2 + integer, parameter :: LEVDIM = 3 + integer, parameter :: TIMDIM = 4 + + integer, parameter :: PS_TIMDIM = 3 + + integer, parameter :: ZA_LATDIM = 1 + integer, parameter :: ZA_LEVDIM = 2 + integer, parameter :: ZA_TIMDIM = 3 + + integer, parameter :: nm=1 ! array index for previous (minus) data + integer, parameter :: np=2 ! array index for next (plus) data + + integer :: plon, plat + +contains + +!-------------------------------------------------------------------------- +!-------------------------------------------------------------------------- + subroutine trcdata_init( specifier, filename, filelist, datapath, flds, file, & + rmv_file, data_cycle_yr, data_fixed_ymd, data_fixed_tod, data_type ) + + use mo_constants, only : d2r + use cam_control_mod, only : nsrest + use dyn_grid, only : get_dyn_grid_parm + use string_utils, only : to_upper + use horizontal_interpolate, only : xy_interp_init +#if ( defined SPMD ) + use mpishorthand, only: mpicom, mpir8, mpiint +#endif + + implicit none + + character(len=*), intent(in) :: specifier(:) + character(len=*), intent(in) :: filename + character(len=*), intent(in) :: filelist + character(len=*), intent(in) :: datapath + type(trfld), dimension(:), pointer :: flds + type(trfile), intent(inout) :: file + logical, intent(in) :: rmv_file + integer, intent(in) :: data_cycle_yr + integer, intent(in) :: data_fixed_ymd + integer, intent(in) :: data_fixed_tod + character(len=*), intent(in) :: data_type + + integer :: f, mxnflds, astat + integer :: str_yr, str_mon, str_day + integer :: lon_dimid, lat_dimid, lev_dimid, tim_dimid, old_dimid + integer :: dimids(4), did + type(var_desc_t) :: varid + integer :: idx + integer :: ierr + integer :: errcode + real(r8) :: start_time, time1, time2 + integer :: i1,i2,j1,j2 + integer :: nvardims, vardimids(4) + + character(len=80) :: data_units + + call specify_fields( specifier, flds ) + + file%datatimep=-1.e36_r8 + file%datatimem=-1.e36_r8 + + mxnflds = 0 + if (associated(flds)) mxnflds = size( flds ) + + if (mxnflds < 1) return + + file%remove_trc_file = rmv_file + file%pathname = trim(datapath) + file%filenames_list = trim(filelist) + + file%fill_in_months = .false. + file%cyclical = .false. + file%cyclical_list = .false. + +! does not work when compiled with pathf90 +! select case ( to_upper(data_type) ) + select case ( data_type ) + case( 'FIXED' ) + file%fixed = .true. + case( 'INTERP_MISSING_MONTHS' ) + file%fill_in_months = .true. + case( 'CYCLICAL' ) + file%cyclical = .true. + file%cyc_yr = data_cycle_yr + case( 'CYCLICAL_LIST' ) + file%cyclical_list = .true. + file%cyc_yr = data_cycle_yr + case( 'SERIAL' ) + case default + write(iulog,*) 'trcdata_init: invalid data type: '//trim(data_type)//' file: '//trim(filename) + write(iulog,*) 'trcdata_init: valid data types: SERIAL | CYCLICAL | CYCLICAL_LIST | FIXED | INTERP_MISSING_MONTHS ' + call endrun('trcdata_init: invalid data type: '//trim(data_type)//' file: '//trim(filename)) + endselect + + if ( (.not.file%fixed) .and. ((data_fixed_ymd>0._r8) .or.(data_fixed_tod>0._r8))) then + call endrun('trcdata_init: Cannot specify data_fixed_ymd or data_fixed_tod if data type is not FIXED') + endif + if ( (.not.file%cyclical) .and. (data_cycle_yr>0._r8) ) then + call endrun('trcdata_init: Cannot specify data_cycle_yr if data type is not CYCLICAL') + endif + + if (masterproc) then + write(iulog,*) 'trcdata_init: data type: '//trim(data_type)//' file: '//trim(filename) + endif + + ! if there is no list of files (len_trim(file%filenames_list)<1) then + ! -> set curr_filename from namelist rather from restart data + if ( len_trim(file%curr_filename)<1 .or. len_trim(file%filenames_list)<1 .or. file%fixed ) then ! initial run + file%curr_filename = trim(filename) + + call get_model_time(file) + + if ( file%fixed ) then + str_yr = data_fixed_ymd/10000 + str_mon = (data_fixed_ymd - str_yr*10000)/100 + str_day = data_fixed_ymd - str_yr*10000 - str_mon*100 + call set_time_float_from_date( start_time, str_yr, str_mon, str_day, data_fixed_tod ) + file%offset_time = start_time - file%curr_mod_time + else + file%offset_time = 0 + endif + endif + + call set_time_float_from_date( time2, 2, 1, 1, 0 ) + call set_time_float_from_date( time1, 1, 1, 1, 0 ) + file%one_yr = time2-time1 + + if ( file%cyclical .or. file%cyclical_list) then + file%cyc_ndx_beg = -1 + file%cyc_ndx_end = -1 + if ( file%cyc_yr /= 0 ) then + call set_time_float_from_date( time1, file%cyc_yr , 1, 1, 0 ) + call set_time_float_from_date( time2, file%cyc_yr+1, 1, 1, 0 ) + file%one_yr = time2-time1 + endif + + call open_trc_datafile( file%curr_filename, file%pathname, file%curr_fileid, file%curr_data_times, & + cyc_ndx_beg=file%cyc_ndx_beg, cyc_ndx_end=file%cyc_ndx_end, cyc_yr=file%cyc_yr ) + else + call open_trc_datafile( file%curr_filename, file%pathname, file%curr_fileid, file%curr_data_times ) + file%curr_data_times = file%curr_data_times - file%offset_time + endif + + call pio_seterrorhandling(File%curr_fileid, PIO_BCAST_ERROR) + ierr = pio_inq_dimid( file%curr_fileid, 'lon', idx ) + call pio_seterrorhandling(File%curr_fileid, PIO_INTERNAL_ERROR) + + file%zonal_ave = (ierr/=PIO_NOERR) + + plon = get_dyn_grid_parm('plon') + plat = get_dyn_grid_parm('plat') + + if ( .not. file%zonal_ave ) then + + call get_dimension( file%curr_fileid, 'lon', file%nlon, dimid=old_dimid, data=file%lons ) + + file%lons = file%lons * d2r + + lon_dimid = old_dimid + + endif + + ierr = pio_inq_dimid( file%curr_fileid, 'time', old_dimid) + + ! Hack to work with weird netCDF and old gcc or NAG bug. + tim_dimid = old_dimid + + call get_dimension( file%curr_fileid, 'lat', file%nlat, dimid=old_dimid, data=file%lats ) + file%lats = file%lats * d2r + + lat_dimid = old_dimid + + allocate( file%ps(file%nlon,file%nlat), stat=astat ) + if( astat /= 0 ) then + write(iulog,*) 'trcdata_init: file%ps allocation error = ',astat + call endrun('trcdata_init: failed to allocate x array') + end if + + call pio_seterrorhandling(File%curr_fileid, PIO_BCAST_ERROR) + ierr = pio_inq_varid( file%curr_fileid, 'PS', file%ps_id ) + file%has_ps = (ierr==PIO_NOERR) + ierr = pio_inq_dimid( file%curr_fileid, 'altitude', idx ) + file%alt_data = (ierr==PIO_NOERR) + + call pio_seterrorhandling(File%curr_fileid, PIO_INTERNAL_ERROR) + + if ( file%has_ps) then + ierr = pio_inq_vardimid (file%curr_fileid, file%ps_id, dimids(1:3)) + do did = 1,3 + if ( dimids(did) == lon_dimid ) then + file%ps_coords(LONDIM) = did + file%ps_order(did) = LONDIM + else if ( dimids(did) == lat_dimid ) then + file%ps_coords(LATDIM) = did + file%ps_order(did) = LATDIM + else if ( dimids(did) == tim_dimid ) then + file%ps_coords(PS_TIMDIM) = did + file%ps_order(did) = PS_TIMDIM + endif + enddo + endif + + if (masterproc) then + write(iulog,*) 'trcdata_init: file%has_ps = ' , file%has_ps + endif ! masterproc + + if (file%alt_data) then + call get_dimension( file%curr_fileid, 'altitude_int', file%nilev, data=file%ilevs ) + call get_dimension( file%curr_fileid, 'altitude', file%nlev, dimid=old_dimid, data=file%levs ) + else + call get_dimension( file%curr_fileid, 'lev', file%nlev, dimid=old_dimid, data=file%levs ) + !!added for Linoz_v3 + call get_dimension( file%curr_fileid, 'ilev', file%nilev, data=file%ilevs ) + if (old_dimid>0) then + file%levs = file%levs*100._r8 ! mbar->pascals + endif + endif + + ! For some bizarre reason, netCDF with older gcc is keeping a pointer to the dimid, and overwriting it later! + ! Hackish workaround is to make a copy... + lev_dimid = old_dimid + + if (file%has_ps) then + + allocate( file%hyam(file%nlev), file%hybm(file%nlev), stat=astat ) + if( astat /= 0 ) then + write(iulog,*) 'trcdata_init: file%hyam,file%hybm allocation error = ',astat + call endrun('trcdata_init: failed to allocate file%hyam and file%hybm arrays') + end if + + allocate( file%hyai(file%nlev+1), file%hybi(file%nlev+1), stat=astat ) + if( astat /= 0 ) then + write(iulog,*) 'trcdata_init: file%hyai,file%hybi allocation error = ',astat + call endrun('trcdata_init: failed to allocate file%hyai and file%hybi arrays') + end if + + call pio_seterrorhandling(File%curr_fileid, PIO_BCAST_ERROR) + ierr = pio_inq_varid( file%curr_fileid, 'P0', varid) + call pio_seterrorhandling(File%curr_fileid, PIO_INTERNAL_ERROR) + + if ( ierr == PIO_NOERR ) then + ierr = pio_get_var( file%curr_fileid, varid, file%p0 ) + else + file%p0 = 100000._r8 + endif + ierr = pio_inq_varid( file%curr_fileid, 'hyam', varid ) + ierr = pio_get_var( file%curr_fileid, varid, file%hyam ) + ierr = pio_inq_varid( file%curr_fileid, 'hybm', varid ) + ierr = pio_get_var( file%curr_fileid, varid, file%hybm ) + if (file%conserve_column) then + ierr = pio_inq_varid( file%curr_fileid, 'hyai', varid ) + ierr = pio_get_var( file%curr_fileid, varid, file%hyai ) + ierr = pio_inq_varid( file%curr_fileid, 'hybi', varid ) + ierr = pio_get_var( file%curr_fileid, varid, file%hybi ) + endif + + allocate( file %ps (pcols,begchunk:endchunk), stat=astat ) + if( astat/= 0 ) then + write(iulog,*) 'trcdata_init: failed to allocate file%ps array; error = ',astat + call endrun + end if + allocate( file%ps_in(1)%data(pcols,begchunk:endchunk), stat=astat ) + if( astat/= 0 ) then + write(iulog,*) 'trcdata_init: failed to allocate file%ps_in(1)%data array; error = ',astat + call endrun + end if + allocate( file%ps_in(2)%data(pcols,begchunk:endchunk), stat=astat ) + if( astat/= 0 ) then + write(iulog,*) 'trcdata_init: failed to allocate file%ps_in(2)%data array; error = ',astat + call endrun + end if + if( file%fill_in_months ) then + allocate( file%ps_in(3)%data(pcols,begchunk:endchunk), stat=astat ) + if( astat/= 0 ) then + write(iulog,*) 'trcdata_init: failed to allocate file%ps_in(3)%data array; error = ',astat + call endrun + end if + allocate( file%ps_in(4)%data(pcols,begchunk:endchunk), stat=astat ) + if( astat/= 0 ) then + write(iulog,*) 'trcdata_init: failed to allocate file%ps_in(4)%data array; error = ',astat + call endrun + end if + end if + endif + + flds_loop: do f = 1,mxnflds + + ! initialize the coordinate values to -1, + ! to defend against fields that do not have certain dimension, e.g., zonal average surface fields + ! and check against it when assigning value to cnt3 for that dimension + + do did = 1,4 + flds(f)%coords(did) = -1 + end do + + ! get netcdf variable id for the field + ierr = pio_inq_varid( file%curr_fileid, flds(f)%srcnam, flds(f)%var_id ) + + ! determine if the field has a vertical dimension + if (lev_dimid>0) then + ierr = pio_inquire_variable( file%curr_fileid, flds(f)%var_id, ndims=nvardims ) + ierr = pio_inquire_variable( file%curr_fileid, flds(f)%var_id, dimids=vardimids(:nvardims) ) + flds(f)%srf_fld = .not.any(vardimids(:nvardims)==lev_dimid) + else + flds(f)%srf_fld = .true. + endif + + ! allocate memory only if not already in pbuf2d + + if ( .not. file%in_pbuf(f) ) then + if ( flds(f)%srf_fld .or. file%top_bndry ) then + allocate( flds(f) %data(pcols,1,begchunk:endchunk), stat=astat ) + else + allocate( flds(f) %data(pcols,pver,begchunk:endchunk), stat=astat ) + endif + if( astat/= 0 ) then + write(iulog,*) 'trcdata_init: failed to allocate flds(f)%data array; error = ',astat + call endrun + end if + else + flds(f)%pbuf_ndx = pbuf_get_index(flds(f)%fldnam,errcode) + endif + + if (flds(f)%srf_fld) then + allocate( flds(f)%input(1)%data(pcols,1,begchunk:endchunk), stat=astat ) + else + allocate( flds(f)%input(1)%data(pcols,file%nlev,begchunk:endchunk), stat=astat ) + endif + if( astat/= 0 ) then + write(iulog,*) 'trcdata_init: failed to allocate flds(f)%input(1)%data array; error = ',astat + call endrun + end if + if (flds(f)%srf_fld) then + allocate( flds(f)%input(2)%data(pcols,1,begchunk:endchunk), stat=astat ) + else + allocate( flds(f)%input(2)%data(pcols,file%nlev,begchunk:endchunk), stat=astat ) + endif + if( astat/= 0 ) then + write(iulog,*) 'trcdata_init: failed to allocate flds(f)%input(2)%data array; error = ',astat + call endrun + end if + + if( file%fill_in_months ) then + if (flds(f)%srf_fld) then + allocate( flds(f)%input(3)%data(pcols,1,begchunk:endchunk), stat=astat ) + else + allocate( flds(f)%input(3)%data(pcols,file%nlev,begchunk:endchunk), stat=astat ) + endif + if( astat/= 0 ) then + write(iulog,*) 'trcdata_init: failed to allocate flds(f)%input(3)%data array; error = ',astat + call endrun + end if + if (flds(f)%srf_fld) then + allocate( flds(f)%input(4)%data(pcols,1,begchunk:endchunk), stat=astat ) + else + allocate( flds(f)%input(4)%data(pcols,file%nlev,begchunk:endchunk), stat=astat ) + endif + if( astat/= 0 ) then + write(iulog,*) 'trcdata_init: failed to allocate flds(f)%input(4)%data array; error = ',astat + call endrun + end if + endif + + if ( file%zonal_ave ) then + ierr = pio_inq_vardimid (file%curr_fileid, flds(f)%var_id, dimids(1:3)) + do did = 1,3 + if ( dimids(did) == lat_dimid ) then + flds(f)%coords(ZA_LATDIM) = did + flds(f)%order(did) = ZA_LATDIM + else if ( dimids(did) == lev_dimid ) then + flds(f)%coords(ZA_LEVDIM) = did + flds(f)%order(did) = ZA_LEVDIM + else if ( dimids(did) == tim_dimid ) then + flds(f)%coords(ZA_TIMDIM) = did + flds(f)%order(did) = ZA_TIMDIM + endif + enddo + else if ( flds(f)%srf_fld ) then + ierr = pio_inq_vardimid (file%curr_fileid, flds(f)%var_id, dimids(1:3)) + do did = 1,3 + if ( dimids(did) == lon_dimid ) then + flds(f)%coords(LONDIM) = did + flds(f)%order(did) = LONDIM + else if ( dimids(did) == lat_dimid ) then + flds(f)%coords(LATDIM) = did + flds(f)%order(did) = LATDIM + else if ( dimids(did) == tim_dimid ) then + flds(f)%coords(PS_TIMDIM) = did + flds(f)%order(did) = PS_TIMDIM + endif + enddo + else + ierr = pio_inq_vardimid (file%curr_fileid, flds(f)%var_id, dimids) + do did = 1,4 + if ( dimids(did) == lon_dimid ) then + flds(f)%coords(LONDIM) = did + flds(f)%order(did) = LONDIM + else if ( dimids(did) == lat_dimid ) then + flds(f)%coords(LATDIM) = did + flds(f)%order(did) = LATDIM + else if ( dimids(did) == lev_dimid ) then + flds(f)%coords(LEVDIM) = did + flds(f)%order(did) = LEVDIM + else if ( dimids(did) == tim_dimid ) then + flds(f)%coords(TIMDIM) = did + flds(f)%order(did) = TIMDIM + endif + enddo + endif + + ierr = pio_get_att( file%curr_fileid, flds(f)%var_id, 'units', data_units) + data_units = trim(data_units) + flds(f)%units = data_units(1:32) + + enddo flds_loop + +! if weighting by latitude, compute weighting for horizontal interpolation + if( file%weight_by_lat ) then +! get dimensions of CAM resolution + plon = get_dyn_grid_parm('plon') + plat = get_dyn_grid_parm('plat') + +! weight_x & weight_y are weighting function for x & y interpolation + allocate(file%weight_x(plon,file%nlon)) + allocate(file%weight_y(plat,file%nlat)) + allocate(file%count_x(plon)) + allocate(file%count_y(plat)) + allocate(file%index_x(plon,file%nlon)) + allocate(file%index_y(plat,file%nlat)) + file%weight_x(:,:) = 0.0_r8 + file%weight_y(:,:) = 0.0_r8 + file%count_x(:) = 0 + file%count_y(:) = 0 + file%index_x(:,:) = 0 + file%index_y(:,:) = 0 + + if(masterproc) then +! compute weighting + call xy_interp_init(file%nlon,file%nlat,file%lons,file%lats,plon,plat,file%weight_x,file%weight_y) + + do i2=1,plon + file%count_x(i2) = 0 + do i1=1,file%nlon + if(file%weight_x(i2,i1).gt.0.0_r8 ) then + file%count_x(i2) = file%count_x(i2) + 1 + file%index_x(i2,file%count_x(i2)) = i1 + endif + enddo + enddo + + do j2=1,plat + file%count_y(j2) = 0 + do j1=1,file%nlat + if(file%weight_y(j2,j1).gt.0.0_r8 ) then + file%count_y(j2) = file%count_y(j2) + 1 + file%index_y(j2,file%count_y(j2)) = j1 + endif + enddo + enddo + endif + +#if ( defined SPMD) + call mpibcast(file%weight_x, plon*file%nlon, mpir8 , 0, mpicom) + call mpibcast(file%weight_y, plat*file%nlat, mpir8 , 0, mpicom) + call mpibcast(file%count_x, plon, mpiint , 0, mpicom) + call mpibcast(file%count_y, plat, mpiint , 0, mpicom) + call mpibcast(file%index_x, plon*file%nlon, mpiint , 0, mpicom) + call mpibcast(file%index_y, plat*file%nlat, mpiint , 0, mpicom) +#endif + endif + + end subroutine trcdata_init + +!----------------------------------------------------------------------- +! Reads more data if needed and interpolates data to current model time +!----------------------------------------------------------------------- + subroutine advance_trcdata( flds, file, state, pbuf2d ) + use physics_types,only : physics_state + use physics_buffer, only : physics_buffer_desc + use ppgrid, only : pver,pcols + + implicit none + + type(trfile), intent(inout) :: file + type(trfld), intent(inout) :: flds(:) + type(physics_state), intent(in) :: state(begchunk:endchunk) + + type(physics_buffer_desc), optional, pointer :: pbuf2d(:,:) + integer :: ncol + real(r8) :: data_time + real(r8) :: t(pcols,pver) ! input temperature (K) + real(r8) :: rho(pcols,pver) ! input temperature (K) + real(r8) :: pmid(pcols,pver) ! pressure at layer midpoints (pa) +!--------------------------------------BLH----------------------------------- + + call t_startf('advance_trcdata') + if ( .not.( file%fixed .and. file%initialized ) ) then + + call get_model_time(file) + + data_time = file%datatimep + + if ( file%cyclical .or. file%cyclical_list ) then + ! wrap around + if ( (file%datatimepfile%datatimem) ) then + data_time = data_time + file%one_yr + endif + endif + + ! For stepTime need to advance if the times are equal + ! Should not impact other runs? + if ( file%curr_mod_time >= data_time ) then + call t_startf('read_next_trcdata') + call read_next_trcdata(state, flds, file ) + call t_stopf('read_next_trcdata') + if(masterproc) write(iulog,*) 'READ_NEXT_TRCDATA ', flds%fldnam,data_time + end if + + endif + + ! need to interpolate the data, regardless + ! each mpi task needs to interpolate + call t_startf('interpolate_trcdata') + if(present(pbuf2d)) then + call interpolate_trcdata( state, flds, file, pbuf2d ) + else + call interpolate_trcdata( state, flds, file ) + endif + call t_stopf('interpolate_trcdata') + + file%initialized = .true. + + call t_stopf('advance_trcdata') + + end subroutine advance_trcdata + +!------------------------------------------------------------------- +!------------------------------------------------------------------- + subroutine get_fld_data( flds, field_name, data, ncol, lchnk, pbuf ) + + use physics_buffer, only : physics_buffer_desc, pbuf_get_field + + implicit none + + type(trfld), intent(inout) :: flds(:) + character(len=*), intent(in) :: field_name + real(r8), intent(out) :: data(:,:) + integer, intent(in) :: lchnk + integer, intent(in) :: ncol + type(physics_buffer_desc), pointer :: pbuf(:) + + + integer :: f, nflds + real(r8),pointer :: tmpptr(:,:) + + data(:,:) = 0._r8 + nflds = size(flds) + + do f = 1, nflds + if ( trim(flds(f)%fldnam) == trim(field_name) ) then + if ( flds(f)%pbuf_ndx>0 ) then + call pbuf_get_field(pbuf, flds(f)%pbuf_ndx, tmpptr) + data(:ncol,:) = tmpptr(:ncol,:) + else + data(:ncol,:) = flds(f)%data(:ncol,:,lchnk) + endif + endif + enddo + + end subroutine get_fld_data + +!------------------------------------------------------------------- +!------------------------------------------------------------------- + subroutine put_fld_data( flds, field_name, data, ncol, lchnk, pbuf ) + + use physics_buffer, only : physics_buffer_desc, pbuf_get_field + + implicit none + + type(trfld), intent(inout) :: flds(:) + character(len=*), intent(in) :: field_name + real(r8), intent(in) :: data(:,:) + integer, intent(in) :: lchnk + integer, intent(in) :: ncol + type(physics_buffer_desc), pointer :: pbuf(:) + + + integer :: f, nflds + real(r8),pointer :: tmpptr(:,:) + + nflds = size(flds) + + do f = 1, nflds + if ( trim(flds(f)%fldnam) == trim(field_name) ) then + if ( flds(f)%pbuf_ndx>0 ) then + call pbuf_get_field(pbuf, flds(f)%pbuf_ndx, tmpptr) + tmpptr(:ncol,:) = data(:ncol,:) + else + flds(f)%data(:ncol,:,lchnk) = data(:ncol,:) + endif + endif + enddo + + end subroutine put_fld_data + +!------------------------------------------------------------------- +!------------------------------------------------------------------- + subroutine get_fld_ndx( flds, field_name, idx ) + + implicit none + + type(trfld), intent(in) :: flds(:) + character(len=*), intent(in) :: field_name + integer, intent(out) :: idx + integer :: f, nflds + + idx = -1 + nflds = size(flds) + + do f = 1, nflds + if ( trim(flds(f)%fldnam) == trim(field_name) ) then + idx = f + return + endif + enddo + + end subroutine get_fld_ndx + +!------------------------------------------------------------------------------ +!------------------------------------------------------------------------------ + subroutine get_model_time(file) + implicit none + type(trfile), intent(inout) :: file + + integer yr, mon, day, ncsec ! components of a date + + call get_curr_date(yr, mon, day, ncsec) + + if ( file%cyclical .or. file%cyclical_list) yr = file%cyc_yr + call set_time_float_from_date( file%curr_mod_time, yr, mon, day, ncsec ) + file%next_mod_time = file%curr_mod_time + get_step_size()/86400._r8 + + end subroutine get_model_time + +!------------------------------------------------------------------------------ +!------------------------------------------------------------------------------ + subroutine check_files( file, fids, itms, times_found) + + implicit none + + type(trfile), intent(inout) :: file + type(file_desc_t), intent(out) :: fids(2) ! ids of files that contains these recs + integer, optional, intent(out) :: itms(2) + logical, optional, intent(inout) :: times_found + + !----------------------------------------------------------------------- + ! ... local variables + !----------------------------------------------------------------------- + logical :: list_cycled + + list_cycled = .false. + + !----------------------------------------------------------------------- + ! If next time beyond the end of the time list, + ! then increment the filename and move on to the next file + !----------------------------------------------------------------------- + if ((file%next_mod_time > file%curr_data_times(size(file%curr_data_times))).or.file%cyclical_list) then + if (file%cyclical_list) then + if ( associated(file%next_data_times) ) then + if ((file%curr_mod_time > file%datatimep)) then + + call advance_file(file) + + endif + endif + + endif + if ( .not. associated(file%next_data_times) ) then + ! open next file if not already opened... + if (file%cyclical_list) then + file%next_filename = incr_filename( file%curr_filename, filenames_list=file%filenames_list, datapath=file%pathname ,& + cyclical_list=file%cyclical_list, list_cycled=list_cycled) + else + file%next_filename = incr_filename( file%curr_filename, filenames_list=file%filenames_list, datapath=file%pathname) + endif + call open_trc_datafile( file%next_filename, file%pathname, file%next_fileid, file%next_data_times ) + file%next_data_times = file%next_data_times - file%offset_time + endif + endif + + !----------------------------------------------------------------------- + ! If using next_data_times and the current is greater than or equal to the next, then + ! close the current file, and set up for next file. + !----------------------------------------------------------------------- + if ( associated(file%next_data_times) ) then + if (file%cyclical_list .and. list_cycled) then ! special case - list cycled + + file%datatimem = file%curr_data_times(size(file%curr_data_times)) + itms(1)=size(file%curr_data_times) + fids(1)=file%curr_fileid + + file%datatimep = file%next_data_times(1) + itms(2)=1 + fids(2) = file%next_fileid + + times_found = .true. + + else if (file%curr_mod_time >= file%next_data_times(1)) then + + call advance_file(file) + + endif + endif + + end subroutine check_files + +!----------------------------------------------------------------------- +!----------------------------------------------------------------------- + function incr_filename( filename, filenames_list, datapath, cyclical_list, list_cycled ) + + !----------------------------------------------------------------------- + ! ... Increment or decrement a date string withing a filename + ! the filename date section is assumed to be of the form + ! yyyy-dd-mm + !----------------------------------------------------------------------- + + use string_utils, only : incstr + use shr_file_mod, only : shr_file_getunit, shr_file_freeunit + + implicit none + + + character(len=*), intent(in) :: filename ! present dynamical dataset filename + character(len=*), optional, intent(in) :: filenames_list + character(len=*), optional, intent(in) :: datapath + logical , optional, intent(in) :: cyclical_list ! If true, allow list to cycle + logical , optional, intent(out) :: list_cycled + character(len=shr_kind_cl) :: incr_filename ! next filename in the sequence + + + ! set new next_filename ... + + !----------------------------------------------------------------------- + ! ... local variables + !----------------------------------------------------------------------- + integer :: pos, pos1, istat + character(len=shr_kind_cl) :: fn_new, line, filepath + character(len=6) :: seconds + character(len=5) :: num + integer :: ios,unitnumber + + if (present(list_cycled)) list_cycled = .false. + + if (( .not. present(filenames_list)) .or.(len_trim(filenames_list) == 0)) then + !----------------------------------------------------------------------- + ! ... ccm type filename + !----------------------------------------------------------------------- + pos = len_trim( filename ) + fn_new = filename(:pos) + if ( masterproc ) write(iulog,*) 'incr_flnm: old filename = ',trim(fn_new) + if( fn_new(pos-2:) == '.nc' ) then + pos = pos - 3 + end if + istat = incstr( fn_new(:pos), 1 ) + if( istat /= 0 ) then + write(iulog,*) 'incr_flnm: incstr returned ', istat + write(iulog,*) ' while trying to decrement ',trim( fn_new ) + call endrun + end if + + else + + !------------------------------------------------------------------- + ! ... open filenames_list + !------------------------------------------------------------------- + if ( masterproc ) write(iulog,*) 'incr_flnm: old filename = ',trim(filename) + if ( masterproc ) write(iulog,*) 'incr_flnm: open filenames_list : ',trim(filenames_list) + unitnumber = shr_file_getUnit() + if ( present(datapath) ) then + filepath = trim(datapath) //'/'// trim(filenames_list) + else + filepath = trim(datapath) + endif + + open( unit=unitnumber, file=filepath, iostat=ios, status="OLD") + if (ios /= 0) then + call endrun('not able to open filenames_list file: '//trim(filepath)) + endif + + !------------------------------------------------------------------- + ! ... read file names + !------------------------------------------------------------------- + read( unit=unitnumber, fmt='(A)', iostat=ios ) line + if (ios /= 0) then + call endrun('not able to increment file name from filenames_list file: '//trim(filenames_list)) + endif + + !------------------------------------------------------------------- + ! If current filename is '', then initialize with the first filename read in + ! and skip this section. + !------------------------------------------------------------------- + if (filename /= '') then + + !------------------------------------------------------------------- + ! otherwise read until find current filename + !------------------------------------------------------------------- + do while( trim(line) /= trim(filename) ) + read( unit=unitnumber, fmt='(A)', iostat=ios ) line + if (ios /= 0) then + call endrun('not able to increment file name from filenames_list file: '//trim(filenames_list)) + endif + enddo + + !------------------------------------------------------------------- + ! Read next filename + !------------------------------------------------------------------- + read( unit=unitnumber, fmt='(A)', iostat=ios ) line + + !--------------------------------------------------------------------------------- + ! If cyclical_list, then an end of file is not an error, but rather + ! a signal to rewind and start over + !--------------------------------------------------------------------------------- + + if (ios /= 0) then + if (present(cyclical_list)) then + if (cyclical_list) then + list_cycled=.true. + rewind(unitnumber) + read( unit=unitnumber, fmt='(A)', iostat=ios ) line + ! Error here should never happen, but check just in case + if (ios /= 0) then + call endrun('not able to increment file name from filenames_list file: '//trim(filenames_list)) + endif + else + call endrun('not able to increment file name from filenames_list file: '//trim(filenames_list)) + endif + else + call endrun('not able to increment file name from filenames_list file: '//trim(filenames_list)) + endif + endif + + endif + + !--------------------------------------------------------------------------------- + ! Assign the current filename and close the filelist + !--------------------------------------------------------------------------------- + fn_new = trim(line) + + close(unit=unitnumber) + call shr_file_freeUnit(unitnumber) + endif + + !--------------------------------------------------------------------------------- + ! return the current filename + !--------------------------------------------------------------------------------- + incr_filename = trim(fn_new) + if ( masterproc ) write(iulog,*) 'incr_flnm: new filename = ',trim(incr_filename) + + end function incr_filename + +!------------------------------------------------------------------------------ +!------------------------------------------------------------------------------ + subroutine find_times( itms, fids, time, file, datatimem, datatimep, times_found ) + + implicit none + + type(trfile), intent(in) :: file + real(r8), intent(out) :: datatimem, datatimep + + integer, intent(out) :: itms(2) ! record numbers that bracket time + type(file_desc_t), intent(out) :: fids(2) ! ids of files that contains these recs + + real(r8), intent(in) :: time ! time of interest + logical, intent(inout) :: times_found + + integer :: np1 ! current forward time index of dataset + integer :: n,i ! + integer :: curr_tsize, next_tsize, all_tsize + integer :: astat + integer :: cyc_tsize + + real(r8), allocatable, dimension(:):: all_data_times + + curr_tsize = size(file%curr_data_times) + next_tsize = 0 + if ( associated(file%next_data_times)) next_tsize = size(file%next_data_times) + + all_tsize = curr_tsize + next_tsize + + allocate( all_data_times( all_tsize ), stat=astat ) + if( astat/= 0 ) then + write(iulog,*) 'find_times: failed to allocate all_data_times array; error = ',astat + call endrun + end if + + all_data_times(:curr_tsize) = file%curr_data_times(:) + if (next_tsize > 0) all_data_times(curr_tsize+1:all_tsize) = file%next_data_times(:) + + if ( .not. file%cyclical ) then + if ( all( all_data_times(:) > time ) ) then + write(iulog,*) 'FIND_TIMES: ALL data times are after ', time + write(iulog,*) 'FIND_TIMES: data times: ',all_data_times(:) + write(iulog,*) 'FIND_TIMES: time: ',time + call endrun('find_times: all(all_data_times(:) > time) '// trim(file%curr_filename) ) + endif + + ! find bracketing times + find_times_loop : do n=1, all_tsize-1 + np1 = n + 1 + datatimem = all_data_times(n) !+ file%offset_time + datatimep = all_data_times(np1) !+ file%offset_time + ! When stepTime, datatimep may not equal the time (as only datatimem is used) + ! Should not break other runs? + if ( (time .ge. datatimem) .and. (time .lt. datatimep) ) then + times_found = .true. + exit find_times_loop + endif + enddo find_times_loop + + else ! file%cyclical + + cyc_tsize = file%cyc_ndx_end - file%cyc_ndx_beg + 1 + + if ( cyc_tsize > 1 ) then + + call findplb(all_data_times(file%cyc_ndx_beg:file%cyc_ndx_end),cyc_tsize, time, n ) + + if (n == cyc_tsize) then + np1 = 1 + else + np1 = n+1 + endif + + datatimem = all_data_times(n +file%cyc_ndx_beg-1) + datatimep = all_data_times(np1+file%cyc_ndx_beg-1) + times_found = .true. + + endif + endif + + if ( .not. times_found ) then + if (masterproc) then + write(iulog,*)'FIND_TIMES: Failed to find dates bracketing desired time =', time + write(iulog,*)' datatimem = ',file%datatimem + write(iulog,*)' datatimep = ',file%datatimep + write(iulog,*)' all_data_times = ',all_data_times + !call endrun() + return + endif + endif + + deallocate( all_data_times, stat=astat ) + if( astat/= 0 ) then + write(iulog,*) 'find_times: failed to deallocate all_data_times array; error = ',astat + call endrun + end if + + if ( .not. file%cyclical ) then + itms(1) = n + itms(2) = np1 + else + itms(1) = n +file%cyc_ndx_beg-1 + itms(2) = np1 +file%cyc_ndx_beg-1 + endif + + fids(:) = file%curr_fileid + + do i=1,2 + if ( itms(i) > curr_tsize ) then + itms(i) = itms(i) - curr_tsize + fids(i) = file%next_fileid + endif + enddo + + end subroutine find_times + +!------------------------------------------------------------------------ +!------------------------------------------------------------------------ + subroutine read_next_trcdata(state, flds, file ) + + use shr_const_mod, only:pi => shr_const_pi + use physics_types,only : physics_state + use ppgrid, only: pcols, pver, pverp,begchunk,endchunk + use physconst, only: rair + use iop_data_mod + use rad_constituents, only: rad_cnst_get_info, rad_cnst_get_aer_props, & + rad_cnst_get_mode_props, rad_cnst_get_mode_num + + implicit none + + type (trfile), intent(inout) :: file + type (trfld),intent(inout) :: flds(:) + type(physics_state), intent(in) :: state(begchunk:endchunk) + + integer :: recnos(4),i,f,nflds ! + integer :: cnt4(4) ! array of counts for each dimension + integer :: strt4(4) ! array of starting indices + integer :: cnt3(3) ! array of counts for each dimension + integer :: strt3(3) ! array of starting indices + type(file_desc_t) :: fids(4) + logical :: times_found + + integer :: cur_yr, cur_mon, cur_day, cur_sec, yr1, yr2, mon, date, sec + real(r8) :: series1_time, series2_time + type(file_desc_t) :: fid1, fid2 + + integer :: nspec,nmodes,n,ii,kk,l1,k,lchnk + real(r8) :: profile_p(pver),pp(pver),meanP,meanO,sumii,volfrac,specdens,aero_den(6) + real(r8) :: q_a(3,6) + real(r8) :: rho(pcols,pver) ! air density (kg m-3) + character(len=20) :: aername + character(len=3) :: arnam(7) = (/'so4','pom','soa','bc ','dst','ncl','num'/) + + nflds = size(flds) + times_found = .false. + + if(single_column .and. scm_observed_aero) then + + call ver_profile_aero(pp) + ! The following do loop gets the species properties and calculates the aerosol + ! mass mixing ratio of each species from observed total number and size distribution + ! properties in the unit kg/m^3 for the 3 modes. Data is read from the forcing file. + ! For mode 1 (accumulation mode) q_a(1,1)=q(so4),q_a(1,2)=q(pom),q_a(1,3)=q(soa), + ! q_a(1,4)=q(bc),q_a(1,5)=q(dst),q_a(1,6)=q(ncl). + ! For mode 2 (aitken mode) q_a(2,1)=q(so4),q_a(2,2)=q(soa),q_a(2,3)=q(ncl). + ! For mode 3 (coarse mode) q_a(3,1)=q(dst),q_a(3,2)=q(ncl),q_a(3,3)=q(so4). + + call rad_cnst_get_info(0, nmodes=nmodes) + do n=1, nmodes + call rad_cnst_get_info(0, n, nspec=nspec) + do l1 = 1, nspec + call rad_cnst_get_aer_props(0, n,l1,density_aer=specdens) + call rad_cnst_get_aer_props(0, n, l1, aername=aername) + aero_den(l1)=specdens + q_a(n,l1) = specdens*scm_div(n,l1)*scm_num(n)*((pi/6.0_r8)*( & + scm_dgnum(n)**3)*exp(4.5_r8*(log(scm_std(n))**2) )) + enddo + enddo + + do k = 1, pver + do ii = 1, state(begchunk)%ncol + rho(ii,k) = state(begchunk)%pmid(ii,k)/(rair*state(begchunk)%t(ii,k)) + enddo + enddo + end if + + do while( .not. times_found ) + call find_times( recnos, fids, file%curr_mod_time,file,file%datatimem,file%datatimep, times_found ) + if ( .not. times_found ) then + call check_files( file, fids, recnos, times_found ) + endif + enddo + + ! If single column do not interpolate aerosol data, just use the step function. + ! The exception is if we are trying to "replay" a column from the full model + if(single_column .and. .not. use_replay) then + file%stepTime = .true. + endif + + if (file%stepTime) then + file%interp_recs = 1 + else + file%interp_recs = 2 + end if + + if ( file%fill_in_months ) then + + if( file%datatimep-file%datatimem > file%one_yr ) then + + call get_curr_date(cur_yr, cur_mon, cur_day, cur_sec) + + call set_date_from_time_float(file%datatimem, yr1, mon, date, sec ) + call set_date_from_time_float(file%datatimep, yr2, mon, date, sec ) + + call set_time_float_from_date( series1_time, yr1, cur_mon, cur_day, cur_sec ) + call set_time_float_from_date( series2_time, yr2, cur_mon, cur_day, cur_sec ) + + fid1 = fids(1) + fid2 = fids(2) + file%cyclical = .true. + call set_cycle_indices( fid1, file%cyc_ndx_beg, file%cyc_ndx_end, yr1) + call find_times( recnos(1:2), fids(1:2), series1_time, file, file%datatimes(1), file%datatimes(2), times_found ) + + if ( .not. times_found ) then + call endrun('read_next_trcdata: time not found for series1_time') + endif + call set_cycle_indices( fid2, file%cyc_ndx_beg, file%cyc_ndx_end, yr2) + + if ( fid1%fh /= fid2%fh ) then + file%cyc_ndx_beg = file%cyc_ndx_beg + size(file%curr_data_times) + file%cyc_ndx_end = file%cyc_ndx_end + size(file%curr_data_times) + endif + call find_times( recnos(3:4), fids(3:4), series2_time, file, file%datatimes(3), file%datatimes(4), times_found ) + if ( .not. times_found ) then + call endrun('read_next_trcdata: time not found for series2_time') + endif + file%cyclical = .false. + file%interp_recs = 4 + + call set_date_from_time_float( file%datatimes(1), yr1, mon, date, sec ) + call set_time_float_from_date( file%datatimem, cur_yr, mon, date, sec ) + if (file%datatimes(1) > file%datatimes(2) ) then ! wrap around + if ( cur_mon == 1 ) then + call set_time_float_from_date( file%datatimem, cur_yr-1, mon, date, sec ) + endif + endif + + call set_date_from_time_float( file%datatimes(2), yr1, mon, date, sec ) + call set_time_float_from_date( file%datatimep, cur_yr, mon, date, sec ) + if (file%datatimes(1) > file%datatimes(2) ) then ! wrap around + if ( cur_mon == 12 ) then + call set_time_float_from_date( file%datatimep, cur_yr+1, mon, date, sec ) + endif + endif + + endif + + endif + + ! + ! Set up hyperslab corners + ! + strt4(:) = 1 + strt3(:) = 1 + + do i=1,file%interp_recs + + do f = 1,nflds + if ( file%zonal_ave ) then + ! Defend against zonal mean surface fields that do not set the value via dimension match + if (flds(f)%coords(ZA_LATDIM) .gt. 0) cnt3(flds(f)%coords(ZA_LATDIM)) = file%nlat + if (flds(f)%srf_fld) then + ! Defend against zonal mean surface fields that do not set the value via dimension match + if (flds(f)%coords(ZA_LEVDIM) .gt. 0) cnt3(flds(f)%coords(ZA_LEVDIM)) = 1 + else + cnt3(flds(f)%coords(ZA_LEVDIM)) = file%nlev + endif + cnt3(flds(f)%coords(ZA_TIMDIM)) = 1 + strt3(flds(f)%coords(ZA_TIMDIM)) = recnos(i) + !! + if (file%linoz_v3 .or. file%linoz_v2) then + !!check if these are the surface variables + !!no need to do interpolate since only used + !!in preprocessing, + !!clim +57 is the correspondent srf variable + if (index(flds(f)%fldnam,"_clim") .gt.0.and.& + index(flds(f)%fldnam,"P_clim") .le.0.and.& + index(flds(f)%fldnam,"L_clim") .le.0.and.& + index(flds(f)%fldnam,"_srf") .le.0)then + call read_za_trc_linoz( fids(i), flds(f)%var_id, flds(f)%input(i)%data, strt3, cnt3, file, & + (/ flds(f)%order(ZA_LATDIM),flds(f)%order(ZA_LEVDIM)/), & + vid_srf=flds(f+57)%var_id ) + elseif (index(flds(f)%fldnam,"_srf").gt.0) then + if (index(flds(f)%fldnam,"ch4_avg_srf").gt.0) then + cnt3(1)=1!set 1st dim since no ZA_LATDIM + endif + call read_zasrf_trc_linoz(fids(i), flds(f)%var_id, flds(f)%input(i)%data, strt3, cnt3, file) + else + call read_za_trc_linoz( fids(i), flds(f)%var_id, flds(f)%input(i)%data, strt3, cnt3, file, & + (/ flds(f)%order(ZA_LATDIM),flds(f)%order(ZA_LEVDIM) /) ) + endif + else + call read_za_trc( fids(i), flds(f)%var_id, flds(f)%input(i)%data, strt3, cnt3, file, & + (/ flds(f)%order(ZA_LATDIM),flds(f)%order(ZA_LEVDIM) /) ) + endif + else if ( flds(f)%srf_fld ) then + cnt3( flds(f)%coords(LONDIM)) = file%nlon + cnt3( flds(f)%coords(LATDIM)) = file%nlat + cnt3( flds(f)%coords(PS_TIMDIM)) = 1 + strt3(flds(f)%coords(PS_TIMDIM)) = recnos(i) + call read_2d_trc( fids(i), flds(f)%var_id, flds(f)%input(i)%data(:,1,:), strt3, cnt3, file, & + (/ flds(f)%order(LONDIM),flds(f)%order(LATDIM) /) ) + else + cnt4(flds(f)%coords(LONDIM)) = file%nlon + cnt4(flds(f)%coords(LATDIM)) = file%nlat + cnt4(flds(f)%coords(LEVDIM)) = file%nlev + cnt4(flds(f)%coords(TIMDIM)) = 1 + strt4(flds(f)%coords(TIMDIM)) = recnos(i) + call read_3d_trc( fids(i), flds(f)%var_id, flds(f)%input(i)%data, strt4, cnt4, file, & + (/ flds(f)%order(LONDIM),flds(f)%order(LATDIM),flds(f)%order(LEVDIM) /)) + + ! + ! This section sets the observed aersol mass and number mixing ratios in the + ! appropriate variables. The observed aerosol inforamtion is read from the + ! forcing file as total number and size distribution parameters. Then the total + ! volume is calculated.Using the desnsity of each species, the mass is calculated. + ! Finally the number is partition among the each species using the species fraction + ! data read from the forcing file. + ! + if(single_column .and. scm_observed_aero) then + kk=index(trim(flds(f)%fldnam),'_')-1 + if(index(trim(flds(f)%fldnam),'1') > 0 .and.index(trim(flds(f)%fldnam),'log') < 1) then + if(flds(f)%fldnam(1:kk).eq.arnam(1).and.index(trim(flds(f)%fldnam),'log') < 1) then + call replace_aero_data(flds(f)%fldnam,arnam(1),flds(f)%input(i)%data, & + rho,pp,q_a(1,1),state(begchunk)%ncol) + elseif(flds(f)%fldnam(1:kk).eq.arnam(2).and.index(trim(flds(f)%fldnam),'log') < 1) then + call replace_aero_data(flds(f)%fldnam,arnam(2),flds(f)%input(i)%data, & + rho,pp,q_a(1,2),state(begchunk)%ncol) + elseif(flds(f)%fldnam(1:kk).eq.arnam(3).and.index(trim(flds(f)%fldnam),'log') < 1) then + call replace_aero_data(flds(f)%fldnam,arnam(3),flds(f)%input(i)%data, & + rho,pp,q_a(1,3),state(begchunk)%ncol) + elseif(flds(f)%fldnam(1:kk).eq.arnam(4).and.index(trim(flds(f)%fldnam),'log') < 1) then + call replace_aero_data(flds(f)%fldnam,arnam(4),flds(f)%input(i)%data, & + rho,pp,q_a(1,4),state(begchunk)%ncol) + elseif(flds(f)%fldnam(1:kk).eq.arnam(5).and.index(trim(flds(f)%fldnam),'log') < 1) then + call replace_aero_data(flds(f)%fldnam,arnam(5),flds(f)%input(i)%data, & + rho,pp,q_a(1,5),state(begchunk)%ncol) + elseif(flds(f)%fldnam(1:kk).eq.arnam(6).and.index(trim(flds(f)%fldnam),'log') < 1) then + call replace_aero_data(flds(f)%fldnam,arnam(6),flds(f)%input(i)%data, & + rho,pp,q_a(1,6),state(begchunk)%ncol) + elseif(flds(f)%fldnam(1:kk).eq.arnam(7).and.index(trim(flds(f)%fldnam),'log') < 1) then + call replace_aero_data(flds(f)%fldnam,arnam(7),flds(f)%input(i)%data, & + rho,pp,scm_num(1),state(begchunk)%ncol) + endif + elseif(index(trim(flds(f)%fldnam),'2') > 0 .and.index(trim(flds(f)%fldnam),'log') < 1) then + if(flds(f)%fldnam(1:kk).eq.arnam(1).and.index(trim(flds(f)%fldnam),'log') < 1) then + call replace_aero_data(flds(f)%fldnam,arnam(1),flds(f)%input(i)%data, & + rho,pp,q_a(2,1),state(begchunk)%ncol) + elseif(flds(f)%fldnam(1:kk).eq.arnam(3).and.index(trim(flds(f)%fldnam),'log') < 1) then + call replace_aero_data(flds(f)%fldnam,arnam(3),flds(f)%input(i)%data, & + rho,pp,q_a(2,2),state(begchunk)%ncol) + elseif(flds(f)%fldnam(1:kk).eq.arnam(6).and.index(trim(flds(f)%fldnam),'log') < 1) then + call replace_aero_data(flds(f)%fldnam,arnam(6),flds(f)%input(i)%data, & + rho,pp,q_a(2,3),state(begchunk)%ncol) + elseif(flds(f)%fldnam(1:kk).eq.arnam(7).and.index(trim(flds(f)%fldnam),'log') < 1) then + call replace_aero_data(flds(f)%fldnam,arnam(7),flds(f)%input(i)%data, & + rho,pp,scm_num(2),state(begchunk)%ncol) + endif + elseif(index(trim(flds(f)%fldnam),'3') > 0 .and.index(trim(flds(f)%fldnam),'log') < 1) then + if(flds(f)%fldnam(1:kk).eq.arnam(1).and.index(trim(flds(f)%fldnam),'log') < 1) then + call replace_aero_data(flds(f)%fldnam,arnam(1),flds(f)%input(i)%data, & + rho,pp,q_a(3,3),state(begchunk)%ncol) + elseif(flds(f)%fldnam(1:kk).eq.arnam(5).and.index(trim(flds(f)%fldnam),'log') < 1) then + call replace_aero_data(flds(f)%fldnam,arnam(5),flds(f)%input(i)%data, & + rho,pp,q_a(3,1),state(begchunk)%ncol) + elseif(flds(f)%fldnam(1:kk).eq.arnam(6).and.index(trim(flds(f)%fldnam),'log') < 1) then + call replace_aero_data(flds(f)%fldnam,arnam(6),flds(f)%input(i)%data, & + rho,pp,q_a(3,2),state(begchunk)%ncol) + elseif(flds(f)%fldnam(1:kk).eq.arnam(7).and.index(trim(flds(f)%fldnam),'log') < 1) then + call replace_aero_data(flds(f)%fldnam,arnam(7),flds(f)%input(i)%data, & + rho,pp,scm_num(3),state(begchunk)%ncol) + endif + endif + endif !scm_observed_aero + endif + + enddo + + if ( file%has_ps ) then + cnt3(file%ps_coords(LONDIM)) = file%nlon + cnt3(file%ps_coords(LATDIM)) = file%nlat + cnt3(file%ps_coords(PS_TIMDIM)) = 1 + strt3(file%ps_coords(PS_TIMDIM)) = recnos(i) + call read_2d_trc( fids(i), file%ps_id, file%ps_in(i)%data, strt3, cnt3, file, & + (/ file%ps_order(LONDIM),file%ps_order(LATDIM) /) ) + endif + + enddo + + end subroutine read_next_trcdata + +!-------------------------------------------------------------------------------- +!This subroutine replaces the climatological aerosol information by the observed +!once after they are read +! + subroutine replace_aero_data(aerofulnam,spnam,aero_q_data,rho,pp,q_mix,ncoli) + use ppgrid, only: pcols,pver,begchunk,endchunk + + implicit none + real(r8), intent(inout) :: aero_q_data(pcols,pver,begchunk:endchunk) + real(r8), intent(in) :: rho(pcols,pver),pp(pver) + real(r8) :: sumii,meanO + real(r8), intent(in) :: q_mix + character(len=32),intent(in) ::aerofulnam + character(len=3),intent(in) :: spnam + character(len=32) ::aerosubnam + integer, intent(in) :: ncoli + integer :: ii,k,countj + + if(trim(aerofulnam(1:2)).eq.'bc') then + aerosubnam=aerofulnam(1:4) + else + aerosubnam=aerofulnam(1:5) + endif + + if((trim(aerosubnam).eq.(trim(spnam)//'_a').or.trim(aerosubnam).eq.(trim(spnam)//'_c')) & + .and.index(trim(aerofulnam),'log') < 1) then + + aero_q_data=q_mix + sumii=0._r8 + countj =0 + do ii = 1, ncoli + do k = 1, pver + if(pp(k).gt.0._r8) then + countj=countj+1 + endif + if(trim(spnam).ne.'num') then + aero_q_data(ii,k,begchunk)=(aero_q_data(ii,k,begchunk)*pp(k)) /rho(ii,k) + endif + sumii=sumii + aero_q_data(ii,k,begchunk) + enddo + enddo + meanO=sumii/countj + do k = 1, pver + if(meanO.ne.0.) then + aero_q_data(1,k,begchunk)=pp(k)*meanO + else + aero_q_data(1,k,begchunk)=0._r8 + endif + enddo + endif + + end subroutine replace_aero_data + +!--------------------------------------------------------------------------- +!This subroutine generates a heavyside type profiles for the observed aerosol. +!This setting is constant profile in the lower atmosphere and then exponentially +!decreasing to zero at the top of the atmosphere. The level of initial decay is +!controlled by "initial_val". Larger than -3.5 pushes the decay point up and smaller +!brings it closer to the surface. +! + subroutine ver_profile_aero(vertprof_aero) + use mo_constants, only : pi + use ppgrid, only: pcols,pver + + implicit none + real(r8), intent(inout) :: vertprof_aero(pver) + real(r8) :: initial_val = -3.5_r8 + integer :: k + + do k=1,pver + if(k==1) then + vertprof_aero(k)=0._r8 + elseif(k==2) then + vertprof_aero(k)=1._r8/(1._r8 + exp(-2._r8*initial_val * pi)) + else + vertprof_aero(k)=1._r8/(1._r8 + exp(-2._r8*(initial_val * pi + pi/4._r8*(k-2)))) + endif + enddo + end subroutine ver_profile_aero + +!------------------------------------------------------------------------ + + + subroutine read_2d_trc( fid, vid, loc_arr, strt, cnt, file, order ) + use interpolate_data, only : lininterp_init, lininterp, interp_type, lininterp_finish + + use phys_grid, only : pcols, begchunk, endchunk, get_ncols_p, get_rlat_all_p, get_rlon_all_p, get_lon_all_p, get_lat_all_p + use mo_constants, only : pi + use dycore, only: dycore_is + use polar_avg, only: polar_average + use horizontal_interpolate, only : xy_interp + + implicit none + type(file_desc_t), intent(in) :: fid + type(var_desc_t), intent(in) :: vid + integer, intent(in) :: strt(:), cnt(:), order(2) + real(r8),intent(out) :: loc_arr(:,:) + type (trfile), intent(in) :: file + + real(r8) :: to_lats(pcols), to_lons(pcols), wrk(pcols) + real(r8), allocatable, target :: wrk2d(:,:) + real(r8), pointer :: wrk2d_in(:,:) + + integer :: tsize, c, i, j, ierr, ncols + real(r8), parameter :: zero=0_r8, twopi=2_r8*pi + type(interp_type) :: lon_wgts, lat_wgts + integer :: lons(pcols), lats(pcols) + + nullify(wrk2d_in) + allocate( wrk2d(cnt(1),cnt(2)), stat=ierr ) + if( ierr /= 0 ) then + write(iulog,*) 'read_2d_trc: wrk2d allocation error = ',ierr + call endrun + end if + + if(order(1)/=1 .or. order(2)/=2 .or. cnt(1)/=file%nlon .or. cnt(2)/=file%nlat) then + allocate( wrk2d_in(file%nlon, file%nlat), stat=ierr ) + if( ierr /= 0 ) then + write(iulog,*) 'read_2d_trc: wrk2d_in allocation error = ',ierr + call endrun + end if + end if + + + + ierr = pio_get_var( fid, vid, strt, cnt, wrk2d ) + if(associated(wrk2d_in)) then + wrk2d_in = reshape( wrk2d(:,:),(/file%nlon,file%nlat/), order=order ) + deallocate(wrk2d) + else + wrk2d_in => wrk2d + end if + + j=1 + +! if weighting by latitude, the perform horizontal interpolation by using weight_x, weight_y + + if(file%weight_by_lat) then + + call t_startf('xy_interp') + + do c = begchunk,endchunk + ncols = get_ncols_p(c) + call get_lon_all_p(c,ncols,lons) + call get_lat_all_p(c,ncols,lats) + + call xy_interp(file%nlon,file%nlat,1,plon,plat,pcols,ncols,file%weight_x,file%weight_y,wrk2d_in,loc_arr(:,c-begchunk+1), & + lons,lats,file%count_x,file%count_y,file%index_x,file%index_y) + enddo + + call t_stopf('xy_interp') + + else + do c=begchunk,endchunk + ncols = get_ncols_p(c) + call get_rlat_all_p(c, pcols, to_lats) + call get_rlon_all_p(c, pcols, to_lons) + + call lininterp_init(file%lons, file%nlon, to_lons, ncols, 2, lon_wgts, zero, twopi) + call lininterp_init(file%lats, file%nlat, to_lats, ncols, 1, lat_wgts) + + call lininterp(wrk2d_in, file%nlon, file%nlat, loc_arr(1:ncols,c-begchunk+1), ncols, lon_wgts, lat_wgts) + + call lininterp_finish(lon_wgts) + call lininterp_finish(lat_wgts) + end do + endif + + if(allocated(wrk2d)) then + deallocate(wrk2d) + else + deallocate(wrk2d_in) + end if + if(dycore_is('LR')) call polar_average(loc_arr) + end subroutine read_2d_trc + +!------------------------------------------------------------------------ + + subroutine read_za_trc( fid, vid, loc_arr, strt, cnt, file, order ) + use interpolate_data, only : lininterp_init, lininterp, interp_type, lininterp_finish + use phys_grid, only : pcols, begchunk, endchunk, get_ncols_p, get_rlat_all_p, get_rlon_all_p + use mo_constants, only : pi + use dycore, only : dycore_is + use polar_avg, only : polar_average + + implicit none + type(file_desc_t), intent(in) :: fid + type(var_desc_t), intent(in) :: vid + integer, intent(in) :: strt(:), cnt(:) + integer, intent(in) :: order(2) + real(r8), intent(out):: loc_arr(:,:,:) + type (trfile), intent(in) :: file + + type(interp_type) :: lat_wgts + real(r8) :: to_lats(pcols), to_lons(pcols), wrk(pcols) + real(r8), allocatable, target :: wrk2d(:,:) + real(r8), pointer :: wrk2d_in(:,:) + integer :: c, k, ierr, ncols + + nullify(wrk2d_in) + allocate( wrk2d(cnt(1),cnt(2)), stat=ierr ) + if( ierr /= 0 ) then + write(iulog,*) 'read_2d_trc: wrk2d allocation error = ',ierr + call endrun + end if + + if(order(1)/=1 .or. order(2)/=2 .or. cnt(1)/=file%nlat .or. cnt(2)/=file%nlev) then + allocate( wrk2d_in(file%nlat, file%nlev), stat=ierr ) + if( ierr /= 0 ) then + write(iulog,*) 'read_2d_trc: wrk2d_in allocation error = ',ierr + call endrun + end if + end if + + + ierr = pio_get_var( fid, vid, strt, cnt, wrk2d ) + if(associated(wrk2d_in)) then + wrk2d_in = reshape( wrk2d(:,:),(/file%nlat,file%nlev/), order=order ) + deallocate(wrk2d) + else + wrk2d_in => wrk2d + end if + + + + do c=begchunk,endchunk + ncols = get_ncols_p(c) + call get_rlat_all_p(c, pcols, to_lats) + + call lininterp_init(file%lats, file%nlat, to_lats, ncols, 1, lat_wgts) + do k=1,file%nlev + call lininterp(wrk2d_in(:,k), file%nlat, wrk(1:ncols), ncols, lat_wgts) + loc_arr(1:ncols,k,c-begchunk+1) = wrk(1:ncols) + end do + call lininterp_finish(lat_wgts) + end do + + if(allocated(wrk2d)) then + deallocate(wrk2d) + else + deallocate(wrk2d_in) + end if +! if(dycore_is('LR')) call polar_average(loc_arr) + end subroutine read_za_trc +!------------------------------------------------------------------------ + subroutine read_za_trc_linoz( fid, vid, loc_arr, strt, cnt, file, order ,vid_srf) + use interpolate_data, only : lininterp_init, lininterp, interp_type, lininterp_finish + use phys_grid, only : pcols, begchunk, endchunk, get_ncols_p, get_rlat_all_p, get_rlon_all_p + use mo_constants, only : pi + use dycore, only : dycore_is + use polar_avg, only : polar_average + + implicit none + type(file_desc_t), intent(in) :: fid + type(var_desc_t), intent(in) :: vid + integer, intent(in) :: strt(:), cnt(:) + integer, intent(in) :: order(2) + real(r8), intent(out):: loc_arr(:,:,:) + type (trfile), intent(in) :: file + !! + type(var_desc_t), intent(in), optional :: vid_srf + integer :: cnt_srf(2) + integer :: strt_srf(2) + !! + type(interp_type) :: lat_wgts + real(r8) :: to_lats(pcols), to_lons(pcols), wrk(pcols) + real(r8), allocatable, target :: wrk2d(:,:) + real(r8), allocatable, target :: wrksrf(:) + real(r8), pointer :: wrk2d_in(:,:) + integer :: c, k, ierr, ncols + + nullify(wrk2d_in) + allocate( wrk2d(cnt(1),cnt(2)), stat=ierr ) + if( ierr /= 0 ) then + write(iulog,*) 'read_2d_trc: wrk2d allocation error = ',ierr + call endrun + end if + + if(order(1)/=1 .or. order(2)/=2 .or. cnt(1)/=file%nlat .or. cnt(2)/=file%nlev) then + allocate( wrk2d_in(file%nlat, file%nlev), stat=ierr ) + if( ierr /= 0 ) then + write(iulog,*) 'read_2d_trc: wrk2d_in allocation error = ',ierr + call endrun + end if + end if + !! + ierr = pio_get_var( fid, vid, strt, cnt, wrk2d ) + !! + if (file%linoz_v3) then + !!since io reads in global data for every thread + !!and interpolate to local chunk, we can do surface, + !!polar, and surface padding preprocessfor every variable + !!before interpolation + !!it is put here rather than the data formation process + !!to prevent forget when producing forcing data + !read in order of 0.1hPa~985hPa, pad top with 2nd layer + wrk2d(:,1)=wrk2d(:,2) + !both N/S poles need to pad by nearest data + wrk2d(1,:)=wrk2d(2,:) + wrk2d(file%nlat,:)=wrk2d(file%nlat-1,:) + !!read in srf data to pad surface + !!they are inputs from CMIP forcing and other references + cnt_srf(1)=cnt(1) + cnt_srf(2)=cnt(3) + strt_srf(1)=strt(1) + strt_srf(2)=strt(3) + !!check if vid_srf is present to determine clim variables + if (present(vid_srf)) then + !!padding for clim terms + allocate(wrksrf(cnt(1)), stat=ierr ) + ierr = pio_get_var( fid, vid_srf, strt_srf, cnt_srf, wrksrf ) + !!surface padding + wrk2d(:,file%nlev)=wrksrf + deallocate(wrksrf) + endif + !! + endif + !! + if(associated(wrk2d_in)) then + wrk2d_in = reshape( wrk2d(:,:),(/file%nlat,file%nlev/), order=order ) + deallocate(wrk2d) + else + wrk2d_in => wrk2d + end if + + do c=begchunk,endchunk + ncols = get_ncols_p(c) + call get_rlat_all_p(c, pcols, to_lats) + call lininterp_init(file%lats, file%nlat, to_lats, ncols, 1, lat_wgts) + do k=1,file%nlev + call lininterp(wrk2d_in(:,k), file%nlat, wrk(1:ncols), ncols, lat_wgts) + loc_arr(1:ncols,k,c-begchunk+1) = wrk(1:ncols) + end do + call lininterp_finish(lat_wgts) + end do + + if(allocated(wrk2d)) then + deallocate(wrk2d) + else + deallocate(wrk2d_in) + end if + !! + if(allocated(wrksrf)) then + deallocate(wrksrf) + end if +! if(dycore_is('LR')) call polar_average(loc_arr) + end subroutine read_za_trc_linoz + +!------------------------------------------------------------------------ + subroutine read_zasrf_trc_linoz( fid, vid, loc_arr, strt, cnt, file) + use interpolate_data, only : lininterp_init, lininterp, interp_type, lininterp_finish + use phys_grid, only : pcols, begchunk, endchunk, get_ncols_p, get_rlat_all_p, get_rlon_all_p + !! + implicit none + type(file_desc_t), intent(in) :: fid + type(var_desc_t), intent(in) :: vid + integer, intent(in) :: strt(:), cnt(:) + real(r8), intent(out):: loc_arr(:,:,:) + type (trfile), intent(in) :: file + !! + real(r8), allocatable, target :: wrk(:) + real(r8), pointer :: wrk_in(:) + real(r8) :: wrk_out(pcols) + type(interp_type) :: lat_wgts + real(r8) :: to_lats(pcols), to_lons(pcols) + integer :: c, k, ierr, ncols + integer :: cnt_srf(2) + integer :: strt_srf(2) + !! + nullify(wrk_in) + allocate( wrk(cnt(1)), stat=ierr ) + if( ierr /= 0 ) then + write(iulog,*) 'read_zasrf_trc_linoz: wrk allocation error = ',ierr + call endrun + end if + !! + cnt_srf(1)=cnt(1) + cnt_srf(2)=cnt(3) + strt_srf(1)=strt(1) + strt_srf(2)=strt(3) + !! + !for surface variable with the dimension of (time,lat) or (time,1) + !for (time) it is also set like (time,1) + ierr = pio_get_var( fid, vid, strt_srf, cnt_srf, wrk ) + !! + if(associated(wrk_in)) then + wrk_in = reshape( wrk(:),(/file%nlat/)) + deallocate(wrk) + else + wrk_in => wrk + end if + !! + do c=begchunk,endchunk + ncols = get_ncols_p(c) + call get_rlat_all_p(c, pcols, to_lats) + call lininterp_init(file%lats, file%nlat, to_lats, ncols, 1, lat_wgts) + !! + if (cnt(1).eq.1) then!!for single timeseries + do k=1,1 + loc_arr(1:ncols,k,c-begchunk+1) = wrk_in(1) + end do + else + do k=1,1 + call lininterp(wrk_in(:), file%nlat, wrk_out(1:ncols), ncols, lat_wgts) + loc_arr(1:ncols,k,c-begchunk+1) = wrk_out(1:ncols) + end do + end if + !! + call lininterp_finish(lat_wgts) + end do + !! + if(allocated(wrk)) then + deallocate(wrk) + else + deallocate(wrk_in) + end if + !! + end subroutine read_zasrf_trc_linoz + +!------------------------------------------------------------------------ + + subroutine read_3d_trc( fid, vid, loc_arr, strt, cnt, file, order) + use interpolate_data, only : lininterp_init, lininterp, interp_type, lininterp_finish + use phys_grid, only : pcols, begchunk, endchunk, get_ncols_p, get_rlat_all_p, get_rlon_all_p, get_lon_all_p,& + get_lat_all_p + use mo_constants, only : pi + use dycore, only : dycore_is + use polar_avg, only : polar_average + use dycore, only : dycore_is + use horizontal_interpolate, only : xy_interp + + implicit none + + type(file_desc_t), intent(in) :: fid + type(var_desc_t), intent(in) :: vid + integer, intent(in) :: strt(:), cnt(:), order(3) + real(r8),intent(out) :: loc_arr(:,:,:) + + type (trfile), intent(in) :: file + + integer :: i,j,k, astat, c, ncols + integer :: lons(pcols), lats(pcols) + + integer :: jlim(2), jl, ju, ierr + integer :: gndx + + real(r8), allocatable, target :: wrk3d(:,:,:) + real(r8), pointer :: wrk3d_in(:,:,:) + real(r8) :: to_lons(pcols), to_lats(pcols) + real(r8), parameter :: zero=0_r8, twopi=2_r8*pi + type(interp_type) :: lon_wgts, lat_wgts + + loc_arr(:,:,:) = 0._r8 + nullify(wrk3d_in) + allocate(wrk3d(cnt(1),cnt(2),cnt(3)), stat=ierr) + if( ierr /= 0 ) then + write(iulog,*) 'read_3d_trc: wrk3d allocation error = ',ierr + call endrun + end if + + ierr = pio_get_var( fid, vid, strt, cnt, wrk3d ) + + if(order(1)/=1 .or. order(2)/=2 .or. order(3)/=3 .or. & + cnt(1)/=file%nlon.or.cnt(2)/=file%nlat.or.cnt(3)/=file%nlev) then + allocate(wrk3d_in(file%nlon,file%nlat,file%nlev),stat=ierr) + if( ierr /= 0 ) then + write(iulog,*) 'read_3d_trc: wrk3d allocation error = ',ierr + call endrun + end if + wrk3d_in = reshape( wrk3d(:,:,:),(/file%nlon,file%nlat,file%nlev/), order=order ) + deallocate(wrk3d) + else + wrk3d_in => wrk3d + end if + + j=1 + +! If weighting by latitude, then perform horizontal interpolation by using weight_x, weight_y + + if(file%weight_by_lat) then + + call t_startf('xy_interp') + + do c = begchunk,endchunk + ncols = get_ncols_p(c) + call get_lon_all_p(c,ncols,lons) + call get_lat_all_p(c,ncols,lats) + + call xy_interp(file%nlon,file%nlat,file%nlev,plon,plat,pcols,ncols,file%weight_x,file%weight_y,wrk3d_in, & + loc_arr(:,:,c-begchunk+1), lons,lats,file%count_x,file%count_y,file%index_x,file%index_y) + enddo + + call t_stopf('xy_interp') + + else + do c=begchunk,endchunk + ncols = get_ncols_p(c) + call get_rlat_all_p(c, pcols, to_lats) + call get_rlon_all_p(c, pcols, to_lons) + + call lininterp_init(file%lons, file%nlon, to_lons(1:ncols), ncols, 2, lon_wgts, zero, twopi) + call lininterp_init(file%lats, file%nlat, to_lats(1:ncols), ncols, 1, lat_wgts) + + + call lininterp(wrk3d_in, file%nlon, file%nlat, file%nlev, loc_arr(:,:,c-begchunk+1), ncols, pcols, lon_wgts, lat_wgts) + + + call lininterp_finish(lon_wgts) + call lininterp_finish(lat_wgts) + end do + endif + + if(allocated(wrk3d)) then + deallocate( wrk3d, stat=astat ) + else + deallocate( wrk3d_in, stat=astat ) + end if + if( astat/= 0 ) then + write(iulog,*) 'read_3d_trc: failed to deallocate wrk3d array; error = ',astat + call endrun + endif + if(dycore_is('LR')) call polar_average(file%nlev, loc_arr) + end subroutine read_3d_trc + +!------------------------------------------------------------------------------ + + subroutine interpolate_trcdata( state, flds, file, pbuf2d ) + use mo_util, only : rebin + use physics_types,only : physics_state + use physconst, only : cday + use physics_buffer, only : physics_buffer_desc, pbuf_get_field + + implicit none + + type(physics_state), intent(in) :: state(begchunk:endchunk) + type (trfld), intent(inout) :: flds(:) + type (trfile), intent(inout) :: file + + type(physics_buffer_desc), optional, pointer :: pbuf2d(:,:) + + + real(r8) :: fact1, fact2 + real(r8) :: deltat + integer :: f,nflds,c,ncol, i,k + real(r8) :: ps(pcols) + real(r8) :: datain(pcols,file%nlev) + real(r8) :: pin(pcols,file%nlev) + real(r8) :: pint(pcols,file%nilev) + + real(r8) :: model_z(pverp) + real(r8), parameter :: m2km = 1.e-3_r8 + real(r8), pointer :: data_out3d(:,:,:) + real(r8), pointer :: data_out(:,:) + integer :: chnk_offset + + nflds = size(flds) + + if ( file%interp_recs == 4 ) then + deltat = file%datatimes(3) - file%datatimes(1) + fact1 = (file%datatimes(3) - file%datatimem)/deltat + fact2 = 1._r8-fact1 +!$OMP PARALLEL DO PRIVATE (C, NCOL, F) + do c = begchunk,endchunk + ncol = state(c)%ncol + if ( file%has_ps ) then + file%ps_in(1)%data(:ncol,c) = fact1*file%ps_in(1)%data(:ncol,c) + fact2*file%ps_in(3)%data(:ncol,c) + endif + do f = 1,nflds + flds(f)%input(1)%data(:ncol,:,c) = fact1*flds(f)%input(1)%data(:ncol,:,c) + fact2*flds(f)%input(3)%data(:ncol,:,c) + enddo + enddo + + deltat = file%datatimes(4) - file%datatimes(2) + fact1 = (file%datatimes(4) - file%datatimep)/deltat + fact2 = 1._r8-fact1 + +!$OMP PARALLEL DO PRIVATE (C, NCOL, F) + do c = begchunk,endchunk + ncol = state(c)%ncol + if ( file%has_ps ) then + file%ps_in(2)%data(:ncol,c) = fact1*file%ps_in(2)%data(:ncol,c) + fact2*file%ps_in(4)%data(:ncol,c) + endif + do f = 1,nflds + flds(f)%input(2)%data(:ncol,:,c) = fact1*flds(f)%input(2)%data(:ncol,:,c) + fact2*flds(f)%input(4)%data(:ncol,:,c) + enddo + enddo + + endif + !------------------------------------------------------------------------- + ! If file%interp_recs=1 then no time interpolation -- set + ! fact1=1 and fact2=0 and will just use first value unmodified + !------------------------------------------------------------------------- + + if (file%interp_recs == 1) then + fact1=1._r8 + fact2=0._r8 + else + file%interp_recs = 2 + + deltat = file%datatimep - file%datatimem + + if ( file%cyclical .and. (deltat < 0._r8) ) then + deltat = deltat+file%one_yr + if ( file%datatimep >= file%curr_mod_time ) then + fact1 = (file%datatimep - file%curr_mod_time)/deltat + else + fact1 = (file%datatimep+file%one_yr - file%curr_mod_time)/deltat + endif + else + fact1 = (file%datatimep - file%curr_mod_time)/deltat + endif + + ! this assures that FIXED data are b4b on restarts + if ( file%fixed ) then + fact1 = dble(int(fact1*cday+.5_r8))/dble(cday) + endif + fact2 = 1._r8-fact1 + endif + + chnk_offset=-begchunk+1 + + fld_loop: do f = 1,nflds + + if (flds(f)%pbuf_ndx<=0) then + data_out3d => flds(f)%data(:,:,:) + endif + +!$OMP PARALLEL DO PRIVATE (C, NCOL, PS, I, K, PIN, DATAIN, MODEL_Z, DATA_OUT) + do c = begchunk,endchunk + if (flds(f)%pbuf_ndx>0) then + if(.not.present(pbuf2d)) then + call endrun ('tracer_data.F90(subr interpolate_trcdata):' // & + 'pbuf2d must be passed as an argument for pbuf_get_field subr call') + endif + call pbuf_get_field(pbuf2d, c, flds(f)%pbuf_ndx, data_out) + else + data_out => data_out3d(:,:,c+chnk_offset) + endif + ncol = state(c)%ncol + if (file%alt_data) then + + if (fact2 == 0) then ! This needed as %data is not set if fact2=0 (and lahey compiler core dumps) + datain(:ncol,:) = fact1*flds(f)%input(nm)%data(:ncol,:,c) + else + datain(:ncol,:) = fact1*flds(f)%input(nm)%data(:ncol,:,c) + fact2*flds(f)%input(np)%data(:ncol,:,c) + end if + do i = 1,ncol + model_z(1:pverp) = m2km * state(c)%zi(i,pverp:1:-1) + call rebin( file%nlev, pver, file%ilevs, model_z, datain(i,:), data_out(i,:) ) + enddo + + else + + if ( file%nlev>1 ) then + if ( file%has_ps ) then + if (fact2 == 0) then ! This needed as %data is not set if fact2=0 (and lahey compiler core dumps) + ps(:ncol) = fact1*file%ps_in(nm)%data(:ncol,c) + else + ps(:ncol) = fact1*file%ps_in(nm)%data(:ncol,c) + fact2*file%ps_in(np)%data(:ncol,c) + end if + do i = 1,ncol + do k = 1,file%nlev + pin(i,k) = file%p0*file%hyam(k) + ps(i)*file%hybm(k) + enddo + enddo + else + do k = 1,file%nlev + pin(:,k) = file%levs(k) + enddo + !!Currently designed for linoz_v2/v3 use + if (file%linoz_v3 .or. file%linoz_v2) then + do k = 1,file%nilev + pint(:,k) = file%ilevs(k) + enddo + endif + endif + endif + + if (flds(f)%srf_fld) then + do i = 1,ncol + if (fact2 == 0) then ! This needed as %data is not set if fact2=0 (and lahey compiler core dumps) + data_out(i,1) = & + fact1*flds(f)%input(nm)%data(i,1,c) + else + data_out(i,1) = & + fact1*flds(f)%input(nm)%data(i,1,c) + fact2*flds(f)%input(np)%data(i,1,c) + endif + enddo + else + if (fact2 == 0) then ! This needed as %data is not set if fact2=0 (and lahey compiler core dumps) + datain(:ncol,:) = fact1*flds(f)%input(nm)%data(:ncol,:,c) + else + datain(:ncol,:) = fact1*flds(f)%input(nm)%data(:ncol,:,c) + fact2*flds(f)%input(np)%data(:ncol,:,c) + end if + if ( file%top_bndry ) then + call vert_interp_ub(ncol, file%nlev, file%levs, datain(:ncol,:), data_out(:ncol,:) ) + else if(file%conserve_column) then + call vert_interp_mixrat(ncol,file%nlev,pver,state(c)%pint, & + datain, data_out(:,:), & + file%p0,ps,file%hyai,file%hybi) + else if(file%linoz_v3 .or. file%linoz_v2) then + !!uci chemistry for linoz that better conserves mass + !!uci interpolation for 55 out of 57 variables in linoz_v3 + !!excluding t_clim, o3col_clim + !!for linoz_v2 it is simiar with less variables + if (flds(f)%fldnam.ne.'t_clim ' & + .and.flds(f)%fldnam.ne.'o3col_clim ') then + !!file ilevs is in hPa, while model level in Pa, so times 100 + call vert_interp_uci(ncol, file%nlev, 100*file%ilevs, state(c)%pint, datain, data_out(:,:) ) + else + call vert_interp(ncol, file%nlev, pin, state(c)%pmid, datain, data_out(:,:) ) + endif + !! + else + call vert_interp(ncol, file%nlev, pin, state(c)%pmid, datain, data_out(:,:) ) + endif + endif + + endif + enddo + + enddo fld_loop + + end subroutine interpolate_trcdata + +!----------------------------------------------------------------------- +!----------------------------------------------------------------------- + subroutine get_dimension( fid, dname, dsize, dimid, data ) + implicit none + type(file_desc_t), intent(inout) :: fid + character(*), intent(in) :: dname + integer, intent(out) :: dsize + + integer, optional, intent(out) :: dimid + real(r8), optional, pointer, dimension(:) :: data + + integer :: vid, ierr, id + + call pio_seterrorhandling( fid, PIO_BCAST_ERROR) + ierr = pio_inq_dimid( fid, dname, id ) + call pio_seterrorhandling( fid, PIO_INTERNAL_ERROR) + + if ( ierr==PIO_NOERR ) then + + ierr = pio_inq_dimlen( fid, id, dsize ) + + if ( present(dimid) ) then + dimid = id + endif + + if ( present(data) ) then + if ( associated(data) ) then + deallocate(data, stat=ierr) + if( ierr /= 0 ) then + write(iulog,*) 'get_dimension: data deallocation error = ',ierr + call endrun('get_dimension: failed to deallocate data array') + end if + endif + allocate( data(dsize), stat=ierr ) + if( ierr /= 0 ) then + write(iulog,*) 'get_dimension: data allocation error = ',ierr + call endrun('get_dimension: failed to allocate data array') + end if + + ierr = pio_inq_varid( fid, dname, vid ) + ierr = pio_get_var( fid, vid, data ) + endif + else + dsize = 1 + if ( present(dimid) ) then + dimid = -1 + endif + endif + + end subroutine get_dimension + +!----------------------------------------------------------------------- +!----------------------------------------------------------------------- + subroutine set_cycle_indices( fileid, cyc_ndx_beg, cyc_ndx_end, cyc_yr ) + + implicit none + + type(file_desc_t), intent(inout) :: fileid + integer, intent(out) :: cyc_ndx_beg + integer, intent(out) :: cyc_ndx_end + integer, intent(in) :: cyc_yr + + integer, allocatable , dimension(:) :: dates, datesecs + integer :: timesize, i, astat, year, ierr + type(var_desc_T) :: dateid + call get_dimension( fileid, 'time', timesize ) + cyc_ndx_beg=-1 + + allocate( dates(timesize), stat=astat ) + if( astat/= 0 ) then + write(*,*) 'set_cycle_indices: failed to allocate dates array; error = ',astat + call endrun + end if + + ierr = pio_inq_varid( fileid, 'date', dateid ) + ierr = pio_get_var( fileid, dateid, dates ) + + do i=1,timesize + year = dates(i) / 10000 + if ( year == cyc_yr ) then + if (cyc_ndx_beg < 0) then + cyc_ndx_beg = i + endif + cyc_ndx_end = i + endif + enddo + deallocate( dates, stat=astat ) + if( astat/= 0 ) then + write(*,*) 'set_cycle_indices: failed to deallocate dates array; error = ',astat + call endrun + end if + if (cyc_ndx_beg < 0) then + write(*,*) 'set_cycle_indices: cycle year not found : ' , cyc_yr + call endrun('set_cycle_indices: cycle year not found') + endif + + end subroutine set_cycle_indices +!----------------------------------------------------------------------- + +!----------------------------------------------------------------------- + subroutine open_trc_datafile( fname, path, piofile, times, cyc_ndx_beg, cyc_ndx_end, cyc_yr ) + + use ioFileMod, only: getfil + use cam_pio_utils, only: cam_pio_openfile + + implicit none + + character(*), intent(in) :: fname + character(*), intent(in) :: path + type(file_desc_t), intent(inout) :: piofile + real(r8), pointer :: times(:) + + integer, optional, intent(out) :: cyc_ndx_beg + integer, optional, intent(out) :: cyc_ndx_end + integer, optional, intent(in) :: cyc_yr + + character(len=shr_kind_cl) :: filen, filepath + integer :: year, month, day, dsize, i, timesize + integer :: dateid,secid + integer, allocatable , dimension(:) :: dates, datesecs + integer :: astat, ierr + logical :: need_first_ndx + + if (len_trim(path) == 0) then + filepath = trim(fname) + else + filepath = trim(path) // '/' // trim(fname) + end if + ! + ! open file and get fileid + ! + call getfil( filepath, filen, 0 ) + call cam_pio_openfile( piofile, filen, PIO_NOWRITE) + if(masterproc) write(iulog,*)'open_trc_datafile: ',trim(filen) + + call get_dimension(piofile, 'time', timesize) + + if ( associated(times) ) then + deallocate(times, stat=ierr) + if( ierr /= 0 ) then + write(iulog,*) 'open_trc_datafile: data deallocation error = ',ierr + call endrun('open_trc_datafile: failed to deallocate data array') + end if + endif + allocate( times(timesize), stat=ierr ) + if( ierr /= 0 ) then + write(iulog,*) 'open_trc_datafile: data allocation error = ',ierr + call endrun('open_trc_datafile: failed to allocate data array') + end if + + allocate( dates(timesize), stat=astat ) + if( astat/= 0 ) then + if(masterproc) write(iulog,*) 'open_trc_datafile: failed to allocate dates array; error = ',astat + call endrun + end if + allocate( datesecs(timesize), stat=astat ) + if( astat/= 0 ) then + if(masterproc) write(iulog,*) 'open_trc_datafile: failed to allocate datesec array; error = ',astat + call endrun + end if + + ierr = pio_inq_varid( piofile, 'date', dateid ) + call pio_seterrorhandling( piofile, PIO_BCAST_ERROR) + ierr = pio_inq_varid( piofile, 'datesec', secid ) + call pio_seterrorhandling( piofile, PIO_INTERNAL_ERROR) + + if(ierr==PIO_NOERR) then + ierr = pio_get_var( piofile, secid, datesecs ) + else + datesecs=0 + end if + + ierr = pio_get_var( piofile, dateid, dates ) + need_first_ndx=.true. + + do i=1,timesize + year = dates(i) / 10000 + month = mod(dates(i),10000)/100 + day = mod(dates(i),100) + call set_time_float_from_date( times(i), year, month, day, datesecs(i) ) + if ( present(cyc_yr) ) then + if ( year == cyc_yr ) then + if ( present(cyc_ndx_beg) .and. need_first_ndx ) then + cyc_ndx_beg = i + need_first_ndx = .false. + endif + if ( present(cyc_ndx_end) ) then + cyc_ndx_end = i + endif + endif + endif + enddo + + deallocate( dates, stat=astat ) + if( astat/= 0 ) then + if(masterproc) write(iulog,*) 'open_trc_datafile: failed to deallocate dates array; error = ',astat + call endrun + end if + deallocate( datesecs, stat=astat ) + if( astat/= 0 ) then + if(masterproc) write(iulog,*) 'open_trc_datafile: failed to deallocate datesec array; error = ',astat + call endrun + end if + + if ( present(cyc_yr) .and. present(cyc_ndx_beg) ) then + if (cyc_ndx_beg < 0) then + write(iulog,*) 'open_trc_datafile: cycle year not found : ' , cyc_yr + call endrun('open_trc_datafile: cycle year not found') + endif + endif + + end subroutine open_trc_datafile + +!-------------------------------------------------------------------------- +!-------------------------------------------------------------------------- + subroutine specify_fields( specifier, fields ) + + implicit none + + character(len=*), intent(in) :: specifier(:) + type(trfld), pointer, dimension(:) :: fields + + integer :: fld_cnt, astat + integer :: i,j + character(len=shr_kind_cl) :: str1, str2 + character(len=32), allocatable, dimension(:) :: fld_name, src_name + integer :: nflds + + nflds = size(specifier) + + allocate(fld_name(nflds), src_name(nflds), stat=astat ) + if( astat/= 0 ) then + write(iulog,*) 'specify_fields: failed to allocate fld_name, src_name arrays; error = ',astat + call endrun + end if + + fld_cnt = 0 + + count_cnst: do i = 1, nflds + + if ( len_trim( specifier(i) ) == 0 ) then + exit count_cnst + endif + + j = scan( specifier(i),':') + + if (j > 0) then + str1 = trim(adjustl( specifier(i)(:j-1) )) + str2 = trim(adjustl( specifier(i)(j+1:) )) + fld_name(i) = trim(adjustl( str1 )) + src_name(i) = trim(adjustl( str2 )) + else + fld_name(i) = trim(adjustl( specifier(i) )) + src_name(i) = trim(adjustl( specifier(i) )) + endif + + fld_cnt = fld_cnt + 1 + + enddo count_cnst + + if( fld_cnt < 1 ) then + nullify(fields) + return + end if + + !----------------------------------------------------------------------- + ! ... allocate field type array + !----------------------------------------------------------------------- + allocate( fields(fld_cnt), stat=astat ) + if( astat/= 0 ) then + write(iulog,*) 'specify_fields: failed to allocate fields array; error = ',astat + call endrun + end if + + do i = 1,fld_cnt + fields(i)%fldnam = fld_name(i) + fields(i)%srcnam = src_name(i) + enddo + + deallocate(fld_name, src_name) + + end subroutine specify_fields + +!------------------------------------------------------------------------------ + + subroutine init_trc_restart( whence, piofile, tr_file ) + + implicit none + character(len=*), intent(in) :: whence + type(file_desc_t), intent(inout) :: piofile + type(trfile), intent(inout) :: tr_file + + character(len=32) :: name + integer :: ioerr, mcdimid, maxlen + + + ! Dimension should already be defined in restart file + call pio_seterrorhandling(pioFile, PIO_BCAST_ERROR) + ioerr = pio_inq_dimid(pioFile,'max_chars', mcdimid) + call pio_seterrorhandling(pioFile, PIO_INTERNAL_ERROR) + ! but define it if nessasary + if(ioerr/= PIO_NOERR) then + ioerr = pio_def_dim(pioFile, 'max_chars', SHR_KIND_CL, mcdimid) + end if + + if(len_trim(tr_file%curr_filename)>1) then + allocate(tr_file%currfnameid) + name = trim(whence)//'_curr_fname' + ioerr = pio_def_var(pioFile, name,pio_char, (/mcdimid/), tr_file%currfnameid) + ioerr = pio_put_att(pioFile, tr_file%currfnameid, 'offset_time', tr_file%offset_time) + maxlen = len_trim(tr_file%curr_filename) + ioerr = pio_put_att(pioFile, tr_file%currfnameid, 'actual_len', maxlen) + else + nullify(tr_file%currfnameid) + end if + + if(len_trim(tr_file%next_filename)>1) then + allocate(tr_file%nextfnameid) + name = trim(whence)//'_next_fname' + ioerr = pio_def_var(pioFile, name,pio_char, (/mcdimid/), tr_file%nextfnameid) + maxlen = len_trim(tr_file%next_filename) + ioerr = pio_put_att(pioFile, tr_file%nextfnameid, 'actual_len', maxlen) + else + nullify(tr_file%nextfnameid) + end if + end subroutine init_trc_restart +!------------------------------------------------------------------------- +! writes file names to restart file +!------------------------------------------------------------------------- + subroutine write_trc_restart( piofile, tr_file ) + + implicit none + + type(file_desc_t), intent(inout) :: piofile + type(trfile), intent(inout) :: tr_file + + integer :: ioerr, slen ! error status + if(associated(tr_file%currfnameid)) then + ioerr = pio_put_var(pioFile, tr_file%currfnameid, tr_file%curr_filename) + deallocate(tr_file%currfnameid) + nullify(tr_file%currfnameid) + end if + if(associated(tr_file%nextfnameid)) then + ioerr = pio_put_var(pioFile, tr_file%nextfnameid, tr_file%next_filename) + deallocate(tr_file%nextfnameid) + nullify(tr_file%nextfnameid) + end if + end subroutine write_trc_restart + +!------------------------------------------------------------------------- +! reads file names from restart file +!------------------------------------------------------------------------- + subroutine read_trc_restart( whence, piofile, tr_file ) + + implicit none + + character(len=*), intent(in) :: whence + type(file_desc_t), intent(inout) :: piofile + type(trfile), intent(inout) :: tr_file + type(var_desc_t) :: vdesc + character(len=64) :: name + integer :: ioerr ! error status + integer :: slen + + call PIO_SetErrorHandling(piofile, PIO_BCAST_ERROR) + name = trim(whence)//'_curr_fname' + ioerr = pio_inq_varid(piofile, name, vdesc) + if(ioerr==PIO_NOERR) then + tr_file%curr_filename=' ' + ioerr = pio_get_att(piofile, vdesc, 'offset_time', tr_file%offset_time) + ioerr = pio_get_att(piofile, vdesc, 'actual_len', slen) + ioerr = pio_get_var(piofile, vdesc, tr_file%curr_filename) + if(slen P2 (decreasing up) +!--- integrates (p-avg) the value F0 from F on the grid P +!--- assumes model pressure increases from top to bottom. +!---NOTE reverse order in P's +!---Assume that the quantity is constant over range halfway to layer above/below +!--- and calculate box edges from model top to model bottom +! +!---For a model level between pressure range P1 > P2 (decreasing up) +!---calculate the SOM Z-moments of the loss freq at std z* (log-p) intervals +!-------- the pressure levels BETWEEN z* values are: +! P(i) < P(i+1) bounds z*(i) +!-------- The MOMENTS for a square-wave or 'bar': F(x)=F0 b<=x<=c, =0.0 else +!----- S0 = f0 (x) [from x=b to x=c] +!----------------------------------------------------------------------- + implicit none + integer, intent(in) :: NL + real(r8), intent(in) :: P1,P2,P(NL+1),F(NL) + real(r8), intent(out):: F0 + integer I + real(r8) XB,XC,PC,PB,SGNF0,PF1,PF2 +!----------------------------------------------------------------------- + F0 = 0._r8 + ! + do I = 1,NL + PF1=P(I) + PF2=P(I+1) + ! + PC = min(P1,PF2) + PB = max(P2,PF1) + ! + if (PC .gt. PB) then +!--- have condition: P1 .ge. PC .gt. PB .ge. P2 +!--- and 0 .le. XB .lt. XC .le. 1 + XC = (PC-P2)/(P1-P2) + XB = (PB-P2)/(P1-P2) +!-------- assume that the quantity, F, is constant over interval [XLO,XUP], +!-------- F0: (c-b), +!-------- calculate its contribution to the moments in the interval [0,1] + F0 = F0 +F(I) *(XC -XB) + endif + enddo +!---limiter on Z-moments: force monotonicity (tables can be + or -) + SGNF0 = sign(1._r8, F0) + F0 = abs(F0) + F0 = SGNF0 * F0 + END SUBROUTINE vert_interp_uci_single +!------------------------------------------------------------------------------ + subroutine vert_interp_ub( ncol, nlevs, plevs, datain, dataout ) + use ref_pres, only : ptop_ref + + + !----------------------------------------------------------------------- + ! + ! Interpolate data from current time-interpolated values to top interface pressure + ! -- from mo_tgcm_ubc.F90 + !-------------------------------------------------------------------------- + implicit none + ! Arguments + ! + integer, intent(in) :: ncol + integer, intent(in) :: nlevs + real(r8), intent(in) :: plevs(nlevs) + real(r8), intent(in) :: datain(ncol,nlevs) + real(r8), intent(out) :: dataout(ncol) + + ! + ! local variables + ! + integer :: i,ku,kl,kk + real(r8) :: pinterp, delp + + pinterp = ptop_ref + + if( pinterp <= plevs(1) ) then + kl = 1 + ku = 1 + delp = 0._r8 + else if( pinterp >= plevs(nlevs) ) then + kl = nlevs + ku = nlevs + delp = 0._r8 + else + + do kk = 2,nlevs + if( pinterp <= plevs(kk) ) then + ku = kk + kl = kk - 1 + delp = log( pinterp/plevs(kk) ) / log( plevs(kk-1)/plevs(kk) ) + exit + end if + end do + + end if + + do i = 1,ncol + dataout(i) = datain(i,kl) + delp * (datain(i,ku) - datain(i,kl)) + end do + + end subroutine vert_interp_ub +!------------------------------------------------------------------------------ + +!------------------------------------------------------------------------------ +!------------------------------------------------------------------------------ + subroutine advance_file(file) + + !------------------------------------------------------------------------------ + ! This routine advances to the next file + !------------------------------------------------------------------------------ + + use shr_sys_mod, only: shr_sys_system + use ioFileMod, only: getfil + + implicit none + + type(trfile), intent(inout) :: file + + !----------------------------------------------------------------------- + ! local variables + !----------------------------------------------------------------------- + character(len=shr_kind_cl) :: ctmp + character(len=shr_kind_cl) :: loc_fname + integer :: istat, astat + + !----------------------------------------------------------------------- + ! close current file ... + !----------------------------------------------------------------------- + call pio_closefile( file%curr_fileid ) + + !----------------------------------------------------------------------- + ! remove if requested + !----------------------------------------------------------------------- + if( file%remove_trc_file ) then + call getfil( file%curr_filename, loc_fname, 0 ) + write(iulog,*) 'advance_file: removing file = ',trim(loc_fname) + ctmp = 'rm -f ' // trim(loc_fname) + write(iulog,*) 'advance_file: fsystem issuing command - ' + write(iulog,*) trim(ctmp) + call shr_sys_system( ctmp, istat ) + end if + + !----------------------------------------------------------------------- + ! Advance the filename and file id + !----------------------------------------------------------------------- + file%curr_filename = file%next_filename + file%curr_fileid = file%next_fileid + + !----------------------------------------------------------------------- + ! Advance the curr_data_times + !----------------------------------------------------------------------- + deallocate( file%curr_data_times, stat=astat ) + if( astat/= 0 ) then + write(iulog,*) 'advance_file: failed to deallocate file%curr_data_times array; error = ',astat + call endrun + end if + allocate( file%curr_data_times( size( file%next_data_times ) ), stat=astat ) + if( astat/= 0 ) then + write(iulog,*) 'advance_file: failed to allocate file%curr_data_times array; error = ',astat + call endrun + end if + file%curr_data_times(:) = file%next_data_times(:) + + !----------------------------------------------------------------------- + ! delete information about next file (as was just assigned to current) + !----------------------------------------------------------------------- + file%next_filename = '' + + deallocate( file%next_data_times, stat=astat ) + if( astat/= 0 ) then + write(iulog,*) 'advance_file: failed to deallocate file%next_data_times array; error = ',astat + call endrun + end if + nullify( file%next_data_times ) + + end subroutine advance_file + +end module tracer_data From 104dd9408cbfbc53d24037dcb187d93fba106299 Mon Sep 17 00:00:00 2001 From: Wuyin Lin Date: Sun, 25 Aug 2024 23:49:33 -0500 Subject: [PATCH 327/451] Add compsets and support files for v3 single forcing simulations --- cime_config/allactive/config_compsets.xml | 72 ++++++++++ ...R_eam_CMIP6-GHG_chemUCI-Linoz-mam5-vbs.xml | 121 +++++++++++++++++ ..._eam_CMIP6-LULC_chemUCI-Linoz-mam5-vbs.xml | 124 ++++++++++++++++++ ...R_eam_CMIP6-aer_chemUCI-Linoz-mam5-vbs.xml | 119 +++++++++++++++++ ...R_eam_CMIP6-nat_chemUCI-Linoz-mam5-vbs.xml | 122 +++++++++++++++++ ...eam_CMIP6-ozone_chemUCI-Linoz-mam5-vbs.xml | 121 +++++++++++++++++ ..._eam_CMIP6-volc_chemUCI-Linoz-mam5-vbs.xml | 123 +++++++++++++++++ ...CMIP6-xGHG-xaer_chemUCI-Linoz-mam5-vbs.xml | 120 +++++++++++++++++ .../eam/cime_config/config_component.xml | 9 ++ .../use_cases/20thC_CMIP6xLULC_transient.xml | 48 +++++++ .../elm/cime_config/config_component.xml | 9 +- .../cime_config/config_component_e3sm.xml | 6 + 12 files changed, 993 insertions(+), 1 deletion(-) create mode 100644 components/eam/bld/namelist_files/use_cases/20TR_eam_CMIP6-GHG_chemUCI-Linoz-mam5-vbs.xml create mode 100644 components/eam/bld/namelist_files/use_cases/20TR_eam_CMIP6-LULC_chemUCI-Linoz-mam5-vbs.xml create mode 100644 components/eam/bld/namelist_files/use_cases/20TR_eam_CMIP6-aer_chemUCI-Linoz-mam5-vbs.xml create mode 100644 components/eam/bld/namelist_files/use_cases/20TR_eam_CMIP6-nat_chemUCI-Linoz-mam5-vbs.xml create mode 100644 components/eam/bld/namelist_files/use_cases/20TR_eam_CMIP6-ozone_chemUCI-Linoz-mam5-vbs.xml create mode 100644 components/eam/bld/namelist_files/use_cases/20TR_eam_CMIP6-volc_chemUCI-Linoz-mam5-vbs.xml create mode 100644 components/eam/bld/namelist_files/use_cases/20TR_eam_CMIP6-xGHG-xaer_chemUCI-Linoz-mam5-vbs.xml create mode 100644 components/elm/bld/namelist_files/use_cases/20thC_CMIP6xLULC_transient.xml diff --git a/cime_config/allactive/config_compsets.xml b/cime_config/allactive/config_compsets.xml index 21032c483714..63883bff15d9 100755 --- a/cime_config/allactive/config_compsets.xml +++ b/cime_config/allactive/config_compsets.xml @@ -86,6 +86,78 @@ 20TRSOI_EAM%CMIP6_ELM%CNPRDCTCBCTOP_MPASSI_MPASO_MOSART_SGLC_SWAV + + + + WCYCL20TR-GHG + 20TRSOI_EAM%CMIP6-GHG_ELM%CNPRDCTCBCTOP_MPASSI_MPASO_MOSART_SGLC_SWAV + + + + hist-GHG + 20TRSOI_EAM%CMIP6-GHG_ELM%CNPRDCTCBCTOP_MPASSI_MPASO_MOSART_SGLC_SWAV + + + + WCYCL20TR-aer + 20TRSOI_EAM%CMIP6-AER_ELM%CNPRDCTCBCTOP_MPASSI_MPASO_MOSART_SGLC_SWAV + + + + hist-aer + 20TRSOI_EAM%CMIP6-AER_ELM%CNPRDCTCBCTOP_MPASSI_MPASO_MOSART_SGLC_SWAV + + + + WCYCL20TR-xGHG-xaer + 20TRSOI_EAM%CMIP6-xGHG-xAER_ELM%CNPRDCTCBCTOP_MPASSI_MPASO_MOSART_SGLC_SWAV + + + + hist-all-xGHG-xaer + 20TRSOI_EAM%CMIP6-xGHG-xAER_ELM%CNPRDCTCBCTOP_MPASSI_MPASO_MOSART_SGLC_SWAV + + + + WCYCL20TR-nat + 20TRSOI_EAM%CMIP6-NAT_ELM%CNPRDCTCBCTOP_MPASSI_MPASO_MOSART_SGLC_SWAV + + + + hist-nat + 20TRSOI_EAM%CMIP6-NAT_ELM%CNPRDCTCBCTOP_MPASSI_MPASO_MOSART_SGLC_SWAV + + + + WCYCL20TR-ozone + 20TRSOI_EAM%CMIP6-OZONE_ELM%CNPRDCTCBCTOP_MPASSI_MPASO_MOSART_SGLC_SWAV + + + + hist-ozone + 20TRSOI_EAM%CMIP6-OZONE_ELM%CNPRDCTCBCTOP_MPASSI_MPASO_MOSART_SGLC_SWAV + + + + WCYCL20TR-lulc + 20TRSOI_EAM%CMIP6-LULC_ELM%CNPRDCTCBCTOP_MPASSI_MPASO_MOSART_SGLC_SWAV + + + + hist-lulc + 20TRSOI_EAM%CMIP6-LULC_ELM%CNPRDCTCBCTOP_MPASSI_MPASO_MOSART_SGLC_SWAV + + + + WCYCL20TR-volc + 20TRSOI_EAM%CMIP6-VOLC_ELM%CNPRDCTCBCTOP_MPASSI_MPASO_MOSART_SGLC_SWAV + + + + hist-volc + 20TRSOI_EAM%CMIP6-VOLC_ELM%CNPRDCTCBCTOP_MPASSI_MPASO_MOSART_SGLC_SWAV + + diff --git a/components/eam/bld/namelist_files/use_cases/20TR_eam_CMIP6-GHG_chemUCI-Linoz-mam5-vbs.xml b/components/eam/bld/namelist_files/use_cases/20TR_eam_CMIP6-GHG_chemUCI-Linoz-mam5-vbs.xml new file mode 100644 index 000000000000..cd16d6a0d9a6 --- /dev/null +++ b/components/eam/bld/namelist_files/use_cases/20TR_eam_CMIP6-GHG_chemUCI-Linoz-mam5-vbs.xml @@ -0,0 +1,121 @@ + + + + +.true. + + +.true. +.true. +.true. + + +atm/cam/solar/Solar_1850control_input4MIPS_c20181106.nc +18500101 +FIXED + + +atm/cam/ggas/GHG_CMIP-1-2-0_Annual_Global_0000-2014_c20180105.nc +RAMPED + + +CYCLICAL +1850 +atm/cam/chem/trop_mozart_aero/emis/chem_gases/2degrees/emissions-cmip6_NO2_aircraft_vertical_1750-2015_1.9x2.5_c20170608.nc + +atm/cam/chem/trop_mozart_aero/emis/DECK_ne30/cmip6_1850_2014_avg_so2_elev_strat_1850.nc +atm/cam/chem/trop_mozart_aero/emis/DECK_ne30/emissions-cmip6_e3sm_SOAG0_elev_1850-2014_1.9x2.5_c20230201.nc +atm/cam/chem/trop_mozart_aero/emis/DECK_ne30/cmip6_mam4_bc_a4_elev_1850-2014_c180205.nc +atm/cam/chem/trop_mozart_aero/emis/DECK_ne30/cmip6_mam4_num_a1_elev_1850-2014_c180205.nc +atm/cam/chem/trop_mozart_aero/emis/DECK_ne30/cmip6_mam4_num_a2_elev_1850-2014_c180205.nc +atm/cam/chem/trop_mozart_aero/emis/DECK_ne30/cmip6_mam4_num_a4_elev_1850-2014_c180205.nc +atm/cam/chem/trop_mozart_aero/emis/DECK_ne30/cmip6_mam4_pom_a4_elev_1850-2014_c180205.nc +atm/cam/chem/trop_mozart_aero/emis/DECK_ne30/cmip6_mam4_so4_a1_elev_1850-2014_c180205.nc +atm/cam/chem/trop_mozart_aero/emis/DECK_ne30/cmip6_mam4_so4_a2_elev_1850-2014_c180205.nc + + +CYCLICAL +1850 +atm/cam/chem/trop_mozart_aero/emis/chem_gases/2degrees/emissions-cmip6_e3sm_C2H4_surface_1850-2014_1.9x2.5_c20210323.nc +atm/cam/chem/trop_mozart_aero/emis/chem_gases/2degrees/emissions-cmip6_e3sm_C2H6_surface_1850-2014_1.9x2.5_c20210323.nc +atm/cam/chem/trop_mozart_aero/emis/chem_gases/2degrees/emissions-cmip6_e3sm_C3H8_surface_1850-2014_1.9x2.5_c20210323.nc +atm/cam/chem/trop_mozart_aero/emis/chem_gases/2degrees/emissions-cmip6_e3sm_CH2O_surface_1850-2014_1.9x2.5_c20210323.nc +atm/cam/chem/trop_mozart_aero/emis/chem_gases/2degrees/emissions-cmip6_e3sm_CH3CHO_surface_1850-2014_1.9x2.5_c20210323.nc +atm/cam/chem/trop_mozart_aero/emis/chem_gases/2degrees/emissions-cmip6_e3sm_CH3COCH3_surface_1850-2014_1.9x2.5_c20210323.nc +atm/cam/chem/trop_mozart_aero/emis/chem_gases/2degrees/emissions-cmip6_e3sm_CO_surface_1850-2014_1.9x2.5_c20210323.nc +atm/cam/chem/trop_mozart_aero/emis/chem_gases/2degrees/emissions-cmip6_e3sm_ISOP_surface_1850-2014_1.9x2.5_c20210323.nc +atm/cam/chem/trop_mozart_aero/emis/chem_gases/2degrees/emissions-cmip6_e3sm_ISOP_surface_1850-2014_1.9x2.5_c20210323.nc +atm/cam/chem/trop_mozart_aero/emis/chem_gases/2degrees/emissions-cmip6_e3sm_MTERP_surface_1850-2014_1.9x2.5_c20230126.nc +atm/cam/chem/trop_mozart_aero/emis/chem_gases/2degrees/emissions-cmip6_e3sm_NO_surface_1850-2014_1.9x2.5_c20220425.nc +atm/cam/chem/trop_mozart_aero/emis/DMSflux.1850.1deg_latlon_conserv.POPmonthlyClimFromACES4BGC_c20160416.nc +atm/cam/chem/trop_mozart_aero/emis/DECK_ne30/emissions-cmip6_e3sm_SOAG0_surf_1850-2014_1.9x2.5_c20230201.nc +atm/cam/chem/trop_mozart_aero/emis/DECK_ne30/cmip6_mam4_so2_surf_1850-2014_c180205.nc +atm/cam/chem/trop_mozart_aero/emis/DECK_ne30/cmip6_mam4_bc_a4_surf_1850-2014_c180205.nc +atm/cam/chem/trop_mozart_aero/emis/DECK_ne30/cmip6_mam4_num_a1_surf_1850-2014_c180205.nc +atm/cam/chem/trop_mozart_aero/emis/DECK_ne30/cmip6_mam4_num_a2_surf_1850-2014_c180205.nc +atm/cam/chem/trop_mozart_aero/emis/DECK_ne30/cmip6_mam4_num_a4_surf_1850-2014_c180205.nc +atm/cam/chem/trop_mozart_aero/emis/DECK_ne30/cmip6_mam4_pom_a4_surf_1850-2014_c180205.nc +atm/cam/chem/trop_mozart_aero/emis/DECK_ne30/cmip6_mam4_so4_a1_surf_1850-2014_c180205.nc +atm/cam/chem/trop_mozart_aero/emis/DECK_ne30/cmip6_mam4_so4_a2_surf_1850-2014_c180205.nc +atm/cam/chem/trop_mozart_aero/emis/chem_gases/2degrees/emissions_E90_surface_1750-2015_1.9x2.5_c20210408.nc + + + + +CYCLICAL +1849 +oxid_1.9x2.5_L26_1850-2015_c20181106.nc +'' +atm/cam/chem/trop_mozart_aero/oxid +'prsd_O3:O3','prsd_NO3:NO3','prsd_OH:OH' + + +ch4_oxid_1.9x2.5_L26_1990-1999clim.c090804.nc +atm/cam/chem/methane +CYCLICAL +1995 +'' +'prsd_ch4:CH4' + + + + 'A:H2OLNZ:H2O', 'N:O2:O2', 'N:CO2:CO2', + 'A:O3:O3', 'A:N2OLNZ:N2O', 'A:CH4LNZ:CH4', + 'N:CFC11:CFC11', 'N:CFC12:CFC12', + 'M:mam5_mode1:$INPUTDATA_ROOT/atm/cam/physprops/mam4_mode1_rrtmg_aeronetdust_c141106.nc', + 'M:mam5_mode2:$INPUTDATA_ROOT/atm/cam/physprops/mam4_mode2_rrtmg_c130628.nc', + 'M:mam5_mode3:$INPUTDATA_ROOT/atm/cam/physprops/mam4_mode3_rrtmg_aeronetdust_c141106.nc', + 'M:mam5_mode4:$INPUTDATA_ROOT/atm/cam/physprops/mam4_mode4_rrtmg_c130628.nc', + 'M:mam5_mode5:$INPUTDATA_ROOT/atm/cam/physprops/mam5_mode5_rrtmg_sig1.2_dgnl.40_c03072023.nc' + + + +3 +1 +'atm/cam/chem/trop_mam/marine_BGC/' +'CYCLICAL' +'monthly_macromolecules_0.1deg_bilinear_latlon_year01_merge_date.nc' +0 +0 +'chla:CHL1','mpoly:TRUEPOLYC','mprot:TRUEPROTC','mlip:TRUELIPC' + + +atm/cam/chem/trop_mozart/ub/Linoz_Chlorine_Loading_CMIP6_0003-2017_c20171114.nc +18500101 +FIXED +1850 +linv3_1849-2017_CMIP6_Hist_10deg_58km_c20230705.nc +atm/cam/chem/trop_mozart/ub +CYCLICAL + + +SERIAL + + +'xactive_lnd' +'O3','H2O2','CH2O','CH3OOH','NO','NO2','HNO3','HO2NO2','PAN','CO','CH3COCH3','C2H5OOH','CH3CHO','H2SO4','SO2','NO3','N2O5','SOAG0','SOAG15','SOAG24','SOAG35','SOAG34','SOAG33','SOAG32','SOAG31' +'NEU' +'C2H5OOH','CH2O','CH3CHO','CH3OOH','H2O2','H2SO4','HNO3','HO2NO2','SO2','SOAG0','SOAG15','SOAG24','SOAG35','SOAG34','SOAG33','SOAG32','SOAG31' +'CH2O', 'CH3O2', 'CH3OOH', 'PAN', 'CO', 'C2H6', 'C3H8', 'C2H4', 'ROHO2', 'CH3COCH3', 'C2H5O2', 'C2H5OOH', 'CH3CHO', 'CH3CO3', 'ISOP', 'ISOPO2', 'MVKMACR', 'MVKO2' +'' + diff --git a/components/eam/bld/namelist_files/use_cases/20TR_eam_CMIP6-LULC_chemUCI-Linoz-mam5-vbs.xml b/components/eam/bld/namelist_files/use_cases/20TR_eam_CMIP6-LULC_chemUCI-Linoz-mam5-vbs.xml new file mode 100644 index 000000000000..e2f53df4dc60 --- /dev/null +++ b/components/eam/bld/namelist_files/use_cases/20TR_eam_CMIP6-LULC_chemUCI-Linoz-mam5-vbs.xml @@ -0,0 +1,124 @@ + + + + +.true. + + +.true. +.true. +.true. + + +atm/cam/solar/Solar_1850control_input4MIPS_c20181106.nc +18500101 +FIXED + + + +808.249e-9 +273.0211e-9 +32.1102e-12 +0.0 + + +CYCLICAL +1850 +atm/cam/chem/trop_mozart_aero/emis/chem_gases/2degrees/emissions-cmip6_NO2_aircraft_vertical_1750-2015_1.9x2.5_c20170608.nc + +atm/cam/chem/trop_mozart_aero/emis/DECK_ne30/cmip6_1850_2014_avg_so2_elev_strat_1850.nc +atm/cam/chem/trop_mozart_aero/emis/DECK_ne30/emissions-cmip6_e3sm_SOAG0_elev_1850-2014_1.9x2.5_c20230201.nc +atm/cam/chem/trop_mozart_aero/emis/DECK_ne30/cmip6_mam4_bc_a4_elev_1850-2014_c180205.nc +atm/cam/chem/trop_mozart_aero/emis/DECK_ne30/cmip6_mam4_num_a1_elev_1850-2014_c180205.nc +atm/cam/chem/trop_mozart_aero/emis/DECK_ne30/cmip6_mam4_num_a2_elev_1850-2014_c180205.nc +atm/cam/chem/trop_mozart_aero/emis/DECK_ne30/cmip6_mam4_num_a4_elev_1850-2014_c180205.nc +atm/cam/chem/trop_mozart_aero/emis/DECK_ne30/cmip6_mam4_pom_a4_elev_1850-2014_c180205.nc +atm/cam/chem/trop_mozart_aero/emis/DECK_ne30/cmip6_mam4_so4_a1_elev_1850-2014_c180205.nc +atm/cam/chem/trop_mozart_aero/emis/DECK_ne30/cmip6_mam4_so4_a2_elev_1850-2014_c180205.nc + + +CYCLICAL +1850 +atm/cam/chem/trop_mozart_aero/emis/chem_gases/2degrees/emissions-cmip6_e3sm_C2H4_surface_1850-2014_1.9x2.5_c20210323.nc +atm/cam/chem/trop_mozart_aero/emis/chem_gases/2degrees/emissions-cmip6_e3sm_C2H6_surface_1850-2014_1.9x2.5_c20210323.nc +atm/cam/chem/trop_mozart_aero/emis/chem_gases/2degrees/emissions-cmip6_e3sm_C3H8_surface_1850-2014_1.9x2.5_c20210323.nc +atm/cam/chem/trop_mozart_aero/emis/chem_gases/2degrees/emissions-cmip6_e3sm_CH2O_surface_1850-2014_1.9x2.5_c20210323.nc +atm/cam/chem/trop_mozart_aero/emis/chem_gases/2degrees/emissions-cmip6_e3sm_CH3CHO_surface_1850-2014_1.9x2.5_c20210323.nc +atm/cam/chem/trop_mozart_aero/emis/chem_gases/2degrees/emissions-cmip6_e3sm_CH3COCH3_surface_1850-2014_1.9x2.5_c20210323.nc +atm/cam/chem/trop_mozart_aero/emis/chem_gases/2degrees/emissions-cmip6_e3sm_CO_surface_1850-2014_1.9x2.5_c20210323.nc +atm/cam/chem/trop_mozart_aero/emis/chem_gases/2degrees/emissions-cmip6_e3sm_ISOP_surface_1850-2014_1.9x2.5_c20210323.nc +atm/cam/chem/trop_mozart_aero/emis/chem_gases/2degrees/emissions-cmip6_e3sm_ISOP_surface_1850-2014_1.9x2.5_c20210323.nc +atm/cam/chem/trop_mozart_aero/emis/chem_gases/2degrees/emissions-cmip6_e3sm_MTERP_surface_1850-2014_1.9x2.5_c20230126.nc +atm/cam/chem/trop_mozart_aero/emis/chem_gases/2degrees/emissions-cmip6_e3sm_NO_surface_1850-2014_1.9x2.5_c20220425.nc +atm/cam/chem/trop_mozart_aero/emis/DMSflux.1850.1deg_latlon_conserv.POPmonthlyClimFromACES4BGC_c20160416.nc +atm/cam/chem/trop_mozart_aero/emis/DECK_ne30/emissions-cmip6_e3sm_SOAG0_surf_1850-2014_1.9x2.5_c20230201.nc +atm/cam/chem/trop_mozart_aero/emis/DECK_ne30/cmip6_mam4_so2_surf_1850-2014_c180205.nc +atm/cam/chem/trop_mozart_aero/emis/DECK_ne30/cmip6_mam4_bc_a4_surf_1850-2014_c180205.nc +atm/cam/chem/trop_mozart_aero/emis/DECK_ne30/cmip6_mam4_num_a1_surf_1850-2014_c180205.nc +atm/cam/chem/trop_mozart_aero/emis/DECK_ne30/cmip6_mam4_num_a2_surf_1850-2014_c180205.nc +atm/cam/chem/trop_mozart_aero/emis/DECK_ne30/cmip6_mam4_num_a4_surf_1850-2014_c180205.nc +atm/cam/chem/trop_mozart_aero/emis/DECK_ne30/cmip6_mam4_pom_a4_surf_1850-2014_c180205.nc +atm/cam/chem/trop_mozart_aero/emis/DECK_ne30/cmip6_mam4_so4_a1_surf_1850-2014_c180205.nc +atm/cam/chem/trop_mozart_aero/emis/DECK_ne30/cmip6_mam4_so4_a2_surf_1850-2014_c180205.nc +atm/cam/chem/trop_mozart_aero/emis/chem_gases/2degrees/emissions_E90_surface_1750-2015_1.9x2.5_c20210408.nc + + + + +CYCLICAL +1849 +oxid_1.9x2.5_L26_1850-2015_c20181106.nc +'' +atm/cam/chem/trop_mozart_aero/oxid +'prsd_O3:O3','prsd_NO3:NO3','prsd_OH:OH' + + +ch4_oxid_1.9x2.5_L26_1990-1999clim.c090804.nc +atm/cam/chem/methane +CYCLICAL +1995 +'' +'prsd_ch4:CH4' + + + + 'A:H2OLNZ:H2O', 'N:O2:O2', 'N:CO2:CO2', + 'A:O3:O3', 'A:N2OLNZ:N2O', 'A:CH4LNZ:CH4', + 'N:CFC11:CFC11', 'N:CFC12:CFC12', + 'M:mam5_mode1:$INPUTDATA_ROOT/atm/cam/physprops/mam4_mode1_rrtmg_aeronetdust_c141106.nc', + 'M:mam5_mode2:$INPUTDATA_ROOT/atm/cam/physprops/mam4_mode2_rrtmg_c130628.nc', + 'M:mam5_mode3:$INPUTDATA_ROOT/atm/cam/physprops/mam4_mode3_rrtmg_aeronetdust_c141106.nc', + 'M:mam5_mode4:$INPUTDATA_ROOT/atm/cam/physprops/mam4_mode4_rrtmg_c130628.nc', + 'M:mam5_mode5:$INPUTDATA_ROOT/atm/cam/physprops/mam5_mode5_rrtmg_sig1.2_dgnl.40_c03072023.nc' + + + +3 +1 +'atm/cam/chem/trop_mam/marine_BGC/' +'CYCLICAL' +'monthly_macromolecules_0.1deg_bilinear_latlon_year01_merge_date.nc' +0 +0 +'chla:CHL1','mpoly:TRUEPOLYC','mprot:TRUEPROTC','mlip:TRUELIPC' + + +atm/cam/chem/trop_mozart/ub/Linoz_Chlorine_Loading_CMIP6_0003-2017_c20171114.nc +18500101 +FIXED +1850 +linv3_1849-2017_CMIP6_Hist_10deg_58km_c20230705.nc +atm/cam/chem/trop_mozart/ub +CYCLICAL + + +SERIAL + + +'xactive_lnd' +'O3','H2O2','CH2O','CH3OOH','NO','NO2','HNO3','HO2NO2','PAN','CO','CH3COCH3','C2H5OOH','CH3CHO','H2SO4','SO2','NO3','N2O5','SOAG0','SOAG15','SOAG24','SOAG35','SOAG34','SOAG33','SOAG32','SOAG31' +'NEU' +'C2H5OOH','CH2O','CH3CHO','CH3OOH','H2O2','H2SO4','HNO3','HO2NO2','SO2','SOAG0','SOAG15','SOAG24','SOAG35','SOAG34','SOAG33','SOAG32','SOAG31' +'CH2O', 'CH3O2', 'CH3OOH', 'PAN', 'CO', 'C2H6', 'C3H8', 'C2H4', 'ROHO2', 'CH3COCH3', 'C2H5O2', 'C2H5OOH', 'CH3CHO', 'CH3CO3', 'ISOP', 'ISOPO2', 'MVKMACR', 'MVKO2' +'' + diff --git a/components/eam/bld/namelist_files/use_cases/20TR_eam_CMIP6-aer_chemUCI-Linoz-mam5-vbs.xml b/components/eam/bld/namelist_files/use_cases/20TR_eam_CMIP6-aer_chemUCI-Linoz-mam5-vbs.xml new file mode 100644 index 000000000000..8aedc762728b --- /dev/null +++ b/components/eam/bld/namelist_files/use_cases/20TR_eam_CMIP6-aer_chemUCI-Linoz-mam5-vbs.xml @@ -0,0 +1,119 @@ + + + + +.true. + + +.true. +.true. +.true. + + +atm/cam/solar/Solar_1850control_input4MIPS_c20181106.nc +18500101 +FIXED + + + +808.249e-9 +273.0211e-9 +32.1102e-12 +0.0 + + +INTERP_MISSING_MONTHS +atm/cam/chem/trop_mozart_aero/emis/chem_gases/2degrees/emissions-cmip6_NO2_aircraft_vertical_1750-2015_1.9x2.5_c20170608.nc +atm/cam/chem/trop_mozart_aero/emis/DECK_ne30/cmip6_mam4_so2_elev_1850-2014_c180205_hist-aero_1850-volcano.nc +atm/cam/chem/trop_mozart_aero/emis/DECK_ne30/emissions-cmip6_e3sm_SOAG0_elev_1850-2014_1.9x2.5_c20230201.nc +atm/cam/chem/trop_mozart_aero/emis/DECK_ne30/cmip6_mam4_bc_a4_elev_1850-2014_c180205.nc +atm/cam/chem/trop_mozart_aero/emis/DECK_ne30/cmip6_mam4_num_a1_elev_1850-2014_c180205.nc +atm/cam/chem/trop_mozart_aero/emis/DECK_ne30/cmip6_mam4_num_a2_elev_1850-2014_c180205.nc +atm/cam/chem/trop_mozart_aero/emis/DECK_ne30/cmip6_mam4_num_a4_elev_1850-2014_c180205.nc +atm/cam/chem/trop_mozart_aero/emis/DECK_ne30/cmip6_mam4_pom_a4_elev_1850-2014_c180205.nc +atm/cam/chem/trop_mozart_aero/emis/DECK_ne30/cmip6_mam4_so4_a1_elev_1850-2014_c180205.nc +atm/cam/chem/trop_mozart_aero/emis/DECK_ne30/cmip6_mam4_so4_a2_elev_1850-2014_c180205.nc + + +INTERP_MISSING_MONTHS +atm/cam/chem/trop_mozart_aero/emis/chem_gases/2degrees/emissions-cmip6_e3sm_C2H4_surface_1850-2014_1.9x2.5_c20210323.nc +atm/cam/chem/trop_mozart_aero/emis/chem_gases/2degrees/emissions-cmip6_e3sm_C2H6_surface_1850-2014_1.9x2.5_c20210323.nc +atm/cam/chem/trop_mozart_aero/emis/chem_gases/2degrees/emissions-cmip6_e3sm_C3H8_surface_1850-2014_1.9x2.5_c20210323.nc +atm/cam/chem/trop_mozart_aero/emis/chem_gases/2degrees/emissions-cmip6_e3sm_CH2O_surface_1850-2014_1.9x2.5_c20210323.nc +atm/cam/chem/trop_mozart_aero/emis/chem_gases/2degrees/emissions-cmip6_e3sm_CH3CHO_surface_1850-2014_1.9x2.5_c20210323.nc +atm/cam/chem/trop_mozart_aero/emis/chem_gases/2degrees/emissions-cmip6_e3sm_CH3COCH3_surface_1850-2014_1.9x2.5_c20210323.nc +atm/cam/chem/trop_mozart_aero/emis/chem_gases/2degrees/emissions-cmip6_e3sm_CO_surface_1850-2014_1.9x2.5_c20210323.nc +atm/cam/chem/trop_mozart_aero/emis/chem_gases/2degrees/emissions-cmip6_e3sm_ISOP_surface_1850-2014_1.9x2.5_c20210323.nc +atm/cam/chem/trop_mozart_aero/emis/chem_gases/2degrees/emissions-cmip6_e3sm_ISOP_surface_1850-2014_1.9x2.5_c20210323.nc +atm/cam/chem/trop_mozart_aero/emis/chem_gases/2degrees/emissions-cmip6_e3sm_MTERP_surface_1850-2014_1.9x2.5_c20230126.nc +atm/cam/chem/trop_mozart_aero/emis/chem_gases/2degrees/emissions-cmip6_e3sm_NO_surface_1850-2014_1.9x2.5_c20220425.nc +atm/cam/chem/trop_mozart_aero/emis/DMSflux.1850-2100.1deg_latlon_conserv.POPmonthlyClimFromACES4BGC_c20160727.nc +atm/cam/chem/trop_mozart_aero/emis/DECK_ne30/emissions-cmip6_e3sm_SOAG0_surf_1850-2014_1.9x2.5_c20230201.nc +atm/cam/chem/trop_mozart_aero/emis/DECK_ne30/cmip6_mam4_so2_surf_1850-2014_c180205.nc +atm/cam/chem/trop_mozart_aero/emis/DECK_ne30/cmip6_mam4_bc_a4_surf_1850-2014_c180205.nc +atm/cam/chem/trop_mozart_aero/emis/DECK_ne30/cmip6_mam4_num_a1_surf_1850-2014_c180205.nc +atm/cam/chem/trop_mozart_aero/emis/DECK_ne30/cmip6_mam4_num_a2_surf_1850-2014_c180205.nc +atm/cam/chem/trop_mozart_aero/emis/DECK_ne30/cmip6_mam4_num_a4_surf_1850-2014_c180205.nc +atm/cam/chem/trop_mozart_aero/emis/DECK_ne30/cmip6_mam4_pom_a4_surf_1850-2014_c180205.nc +atm/cam/chem/trop_mozart_aero/emis/DECK_ne30/cmip6_mam4_so4_a1_surf_1850-2014_c180205.nc +atm/cam/chem/trop_mozart_aero/emis/DECK_ne30/cmip6_mam4_so4_a2_surf_1850-2014_c180205.nc +atm/cam/chem/trop_mozart_aero/emis/chem_gases/2degrees/emissions_E90_surface_1750-2015_1.9x2.5_c20210408.nc + + + + +INTERP_MISSING_MONTHS +oxid_1.9x2.5_L26_1850-2015_c20181106.nc +'' +atm/cam/chem/trop_mozart_aero/oxid +'prsd_O3:O3','prsd_NO3:NO3','prsd_OH:OH' + + +ch4_oxid_1.9x2.5_L26_1990-1999clim.c090804.nc +atm/cam/chem/methane +CYCLICAL +1995 +'' +'prsd_ch4:CH4' + + + + 'A:H2OLNZ:H2O', 'N:O2:O2', 'N:CO2:CO2', + 'A:O3:O3', 'A:N2OLNZ:N2O', 'A:CH4LNZ:CH4', + 'N:CFC11:CFC11', 'N:CFC12:CFC12', + 'M:mam5_mode1:$INPUTDATA_ROOT/atm/cam/physprops/mam4_mode1_rrtmg_aeronetdust_c141106.nc', + 'M:mam5_mode2:$INPUTDATA_ROOT/atm/cam/physprops/mam4_mode2_rrtmg_c130628.nc', + 'M:mam5_mode3:$INPUTDATA_ROOT/atm/cam/physprops/mam4_mode3_rrtmg_aeronetdust_c141106.nc', + 'M:mam5_mode4:$INPUTDATA_ROOT/atm/cam/physprops/mam4_mode4_rrtmg_c130628.nc', + 'M:mam5_mode5:$INPUTDATA_ROOT/atm/cam/physprops/mam5_mode5_rrtmg_sig1.2_dgnl.40_c03072023.nc' + + + +3 +1 +'atm/cam/chem/trop_mam/marine_BGC/' +'CYCLICAL' +'monthly_macromolecules_0.1deg_bilinear_latlon_year01_merge_date.nc' +0 +0 +'chla:CHL1','mpoly:TRUEPOLYC','mprot:TRUEPROTC','mlip:TRUELIPC' + +atm/cam/chem/trop_mozart/ub/Linoz_Chlorine_Loading_CMIP6_0003-2017_c20171114.nc +18500101 +FIXED +1850 +linv3_1849-2017_CMIP6_Hist_10deg_58km_c20230705.nc +atm/cam/chem/trop_mozart/ub +CYCLICAL + + +SERIAL + + +'xactive_lnd' +'O3','H2O2','CH2O','CH3OOH','NO','NO2','HNO3','HO2NO2','PAN','CO','CH3COCH3','C2H5OOH','CH3CHO','H2SO4','SO2','NO3','N2O5','SOAG0','SOAG15','SOAG24','SOAG35','SOAG34','SOAG33','SOAG32','SOAG31' +'NEU' +'C2H5OOH','CH2O','CH3CHO','CH3OOH','H2O2','H2SO4','HNO3','HO2NO2','SO2','SOAG0','SOAG15','SOAG24','SOAG35','SOAG34','SOAG33','SOAG32','SOAG31' +'CH2O', 'CH3O2', 'CH3OOH', 'PAN', 'CO', 'C2H6', 'C3H8', 'C2H4', 'ROHO2', 'CH3COCH3', 'C2H5O2', 'C2H5OOH', 'CH3CHO', 'CH3CO3', 'ISOP', 'ISOPO2', 'MVKMACR', 'MVKO2' +'' + diff --git a/components/eam/bld/namelist_files/use_cases/20TR_eam_CMIP6-nat_chemUCI-Linoz-mam5-vbs.xml b/components/eam/bld/namelist_files/use_cases/20TR_eam_CMIP6-nat_chemUCI-Linoz-mam5-vbs.xml new file mode 100644 index 000000000000..8f3a2644527d --- /dev/null +++ b/components/eam/bld/namelist_files/use_cases/20TR_eam_CMIP6-nat_chemUCI-Linoz-mam5-vbs.xml @@ -0,0 +1,122 @@ + + + + +.true. + + +.true. +.true. +.true. + + +atm/cam/solar/Solar_1850-2299_input4MIPS_c20181106.nc +SERIAL + + + +808.249e-9 +273.0211e-9 +32.1102e-12 +0.0 + + + +CYCLICAL +1850 +atm/cam/chem/trop_mozart_aero/emis/chem_gases/2degrees/emissions-cmip6_NO2_aircraft_vertical_1750-2015_1.9x2.5_c20170608.nc +atm/cam/chem/trop_mozart_aero/emis/DECK_ne30/cmip6_mam4_so2_elev_1850-2014_c180205_1850-aero_hist-volcano.nc +atm/cam/chem/trop_mozart_aero/emis/DECK_ne30/emissions-cmip6_e3sm_SOAG0_elev_1850-2014_1.9x2.5_c20230201.nc +atm/cam/chem/trop_mozart_aero/emis/DECK_ne30/cmip6_mam4_bc_a4_elev_1850-2014_c180205.nc +atm/cam/chem/trop_mozart_aero/emis/DECK_ne30/cmip6_mam4_num_a1_elev_1850-2014_c180205.nc +atm/cam/chem/trop_mozart_aero/emis/DECK_ne30/cmip6_mam4_num_a2_elev_1850-2014_c180205.nc +atm/cam/chem/trop_mozart_aero/emis/DECK_ne30/cmip6_mam4_num_a4_elev_1850-2014_c180205.nc +atm/cam/chem/trop_mozart_aero/emis/DECK_ne30/cmip6_mam4_pom_a4_elev_1850-2014_c180205.nc +atm/cam/chem/trop_mozart_aero/emis/DECK_ne30/cmip6_mam4_so4_a1_elev_1850-2014_c180205.nc +atm/cam/chem/trop_mozart_aero/emis/DECK_ne30/cmip6_mam4_so4_a2_elev_1850-2014_c180205.nc + + +CYCLICAL +1850 +atm/cam/chem/trop_mozart_aero/emis/chem_gases/2degrees/emissions-cmip6_e3sm_C2H4_surface_1850-2014_1.9x2.5_c20210323.nc +atm/cam/chem/trop_mozart_aero/emis/chem_gases/2degrees/emissions-cmip6_e3sm_C2H6_surface_1850-2014_1.9x2.5_c20210323.nc +atm/cam/chem/trop_mozart_aero/emis/chem_gases/2degrees/emissions-cmip6_e3sm_C3H8_surface_1850-2014_1.9x2.5_c20210323.nc +atm/cam/chem/trop_mozart_aero/emis/chem_gases/2degrees/emissions-cmip6_e3sm_CH2O_surface_1850-2014_1.9x2.5_c20210323.nc +atm/cam/chem/trop_mozart_aero/emis/chem_gases/2degrees/emissions-cmip6_e3sm_CH3CHO_surface_1850-2014_1.9x2.5_c20210323.nc +atm/cam/chem/trop_mozart_aero/emis/chem_gases/2degrees/emissions-cmip6_e3sm_CH3COCH3_surface_1850-2014_1.9x2.5_c20210323.nc +atm/cam/chem/trop_mozart_aero/emis/chem_gases/2degrees/emissions-cmip6_e3sm_CO_surface_1850-2014_1.9x2.5_c20210323.nc +atm/cam/chem/trop_mozart_aero/emis/chem_gases/2degrees/emissions-cmip6_e3sm_ISOP_surface_1850-2014_1.9x2.5_c20210323.nc +atm/cam/chem/trop_mozart_aero/emis/chem_gases/2degrees/emissions-cmip6_e3sm_ISOP_surface_1850-2014_1.9x2.5_c20210323.nc +atm/cam/chem/trop_mozart_aero/emis/chem_gases/2degrees/emissions-cmip6_e3sm_MTERP_surface_1850-2014_1.9x2.5_c20230126.nc +atm/cam/chem/trop_mozart_aero/emis/chem_gases/2degrees/emissions-cmip6_e3sm_NO_surface_1850-2014_1.9x2.5_c20220425.nc +atm/cam/chem/trop_mozart_aero/emis/DMSflux.1850.1deg_latlon_conserv.POPmonthlyClimFromACES4BGC_c20160416.nc +atm/cam/chem/trop_mozart_aero/emis/DECK_ne30/emissions-cmip6_e3sm_SOAG0_surf_1850-2014_1.9x2.5_c20230201.nc +atm/cam/chem/trop_mozart_aero/emis/DECK_ne30/cmip6_mam4_so2_surf_1850-2014_c180205.nc +atm/cam/chem/trop_mozart_aero/emis/DECK_ne30/cmip6_mam4_bc_a4_surf_1850-2014_c180205.nc +atm/cam/chem/trop_mozart_aero/emis/DECK_ne30/cmip6_mam4_num_a1_surf_1850-2014_c180205.nc +atm/cam/chem/trop_mozart_aero/emis/DECK_ne30/cmip6_mam4_num_a2_surf_1850-2014_c180205.nc +atm/cam/chem/trop_mozart_aero/emis/DECK_ne30/cmip6_mam4_num_a4_surf_1850-2014_c180205.nc +atm/cam/chem/trop_mozart_aero/emis/DECK_ne30/cmip6_mam4_pom_a4_surf_1850-2014_c180205.nc +atm/cam/chem/trop_mozart_aero/emis/DECK_ne30/cmip6_mam4_so4_a1_surf_1850-2014_c180205.nc +atm/cam/chem/trop_mozart_aero/emis/DECK_ne30/cmip6_mam4_so4_a2_surf_1850-2014_c180205.nc +atm/cam/chem/trop_mozart_aero/emis/chem_gases/2degrees/emissions_E90_surface_1750-2015_1.9x2.5_c20210408.nc + + + + +CYCLICAL +1849 +oxid_1.9x2.5_L26_1850-2015_c20181106.nc +'' +atm/cam/chem/trop_mozart_aero/oxid +'prsd_O3:O3','prsd_NO3:NO3','prsd_OH:OH' + + +ch4_oxid_1.9x2.5_L26_1990-1999clim.c090804.nc +atm/cam/chem/methane +CYCLICAL +1995 +'' +'prsd_ch4:CH4' + + + + 'A:H2OLNZ:H2O', 'N:O2:O2', 'N:CO2:CO2', + 'A:O3:O3', 'A:N2OLNZ:N2O', 'A:CH4LNZ:CH4', + 'N:CFC11:CFC11', 'N:CFC12:CFC12', + 'M:mam5_mode1:$INPUTDATA_ROOT/atm/cam/physprops/mam4_mode1_rrtmg_aeronetdust_c141106.nc', + 'M:mam5_mode2:$INPUTDATA_ROOT/atm/cam/physprops/mam4_mode2_rrtmg_c130628.nc', + 'M:mam5_mode3:$INPUTDATA_ROOT/atm/cam/physprops/mam4_mode3_rrtmg_aeronetdust_c141106.nc', + 'M:mam5_mode4:$INPUTDATA_ROOT/atm/cam/physprops/mam4_mode4_rrtmg_c130628.nc', + 'M:mam5_mode5:$INPUTDATA_ROOT/atm/cam/physprops/mam5_mode5_rrtmg_sig1.2_dgnl.40_c03072023.nc' + + + +3 +1 +'atm/cam/chem/trop_mam/marine_BGC/' +'CYCLICAL' +'monthly_macromolecules_0.1deg_bilinear_latlon_year01_merge_date.nc' +0 +0 +'chla:CHL1','mpoly:TRUEPOLYC','mprot:TRUEPROTC','mlip:TRUELIPC' + +atm/cam/chem/trop_mozart/ub/Linoz_Chlorine_Loading_CMIP6_0003-2017_c20171114.nc +18500101 +FIXED +1850 +linv3_1849-2017_CMIP6_Hist_10deg_58km_c20230705.nc +atm/cam/chem/trop_mozart/ub +INTERP_MISSING_MONTHS + + +SERIAL + + +'xactive_lnd' +'O3','H2O2','CH2O','CH3OOH','NO','NO2','HNO3','HO2NO2','PAN','CO','CH3COCH3','C2H5OOH','CH3CHO','H2SO4','SO2','NO3','N2O5','SOAG0','SOAG15','SOAG24','SOAG35','SOAG34','SOAG33','SOAG32','SOAG31' +'NEU' +'C2H5OOH','CH2O','CH3CHO','CH3OOH','H2O2','H2SO4','HNO3','HO2NO2','SO2','SOAG0','SOAG15','SOAG24','SOAG35','SOAG34','SOAG33','SOAG32','SOAG31' +'CH2O', 'CH3O2', 'CH3OOH', 'PAN', 'CO', 'C2H6', 'C3H8', 'C2H4', 'ROHO2', 'CH3COCH3', 'C2H5O2', 'C2H5OOH', 'CH3CHO', 'CH3CO3', 'ISOP', 'ISOPO2', 'MVKMACR', 'MVKO2' +'' + diff --git a/components/eam/bld/namelist_files/use_cases/20TR_eam_CMIP6-ozone_chemUCI-Linoz-mam5-vbs.xml b/components/eam/bld/namelist_files/use_cases/20TR_eam_CMIP6-ozone_chemUCI-Linoz-mam5-vbs.xml new file mode 100644 index 000000000000..58f69d8fe97f --- /dev/null +++ b/components/eam/bld/namelist_files/use_cases/20TR_eam_CMIP6-ozone_chemUCI-Linoz-mam5-vbs.xml @@ -0,0 +1,121 @@ + + + + +.true. + + +.true. +.true. +.true. + + +atm/cam/solar/Solar_1850control_input4MIPS_c20181106.nc +18500101 +FIXED + + + +808.249e-9 +273.0211e-9 +32.1102e-12 +0.0 + + + +CYCLICAL +1850 +atm/cam/chem/trop_mozart_aero/emis/chem_gases/2degrees/emissions-cmip6_NO2_aircraft_vertical_1750-2015_1.9x2.5_c20170608.nc +atm/cam/chem/trop_mozart_aero/emis/DECK_ne30/cmip6_1850_2014_avg_so2_elev_strat_1850.nc +atm/cam/chem/trop_mozart_aero/emis/DECK_ne30/emissions-cmip6_e3sm_SOAG0_elev_1850-2014_1.9x2.5_c20230201.nc +atm/cam/chem/trop_mozart_aero/emis/DECK_ne30/cmip6_mam4_bc_a4_elev_1850-2014_c180205.nc +atm/cam/chem/trop_mozart_aero/emis/DECK_ne30/cmip6_mam4_num_a1_elev_1850-2014_c180205.nc +atm/cam/chem/trop_mozart_aero/emis/DECK_ne30/cmip6_mam4_num_a2_elev_1850-2014_c180205.nc +atm/cam/chem/trop_mozart_aero/emis/DECK_ne30/cmip6_mam4_num_a4_elev_1850-2014_c180205.nc +atm/cam/chem/trop_mozart_aero/emis/DECK_ne30/cmip6_mam4_pom_a4_elev_1850-2014_c180205.nc +atm/cam/chem/trop_mozart_aero/emis/DECK_ne30/cmip6_mam4_so4_a1_elev_1850-2014_c180205.nc +atm/cam/chem/trop_mozart_aero/emis/DECK_ne30/cmip6_mam4_so4_a2_elev_1850-2014_c180205.nc + + +CYCLICAL +1850 +atm/cam/chem/trop_mozart_aero/emis/chem_gases/2degrees/emissions-cmip6_e3sm_C2H4_surface_1850-2014_1.9x2.5_c20210323.nc +atm/cam/chem/trop_mozart_aero/emis/chem_gases/2degrees/emissions-cmip6_e3sm_C2H6_surface_1850-2014_1.9x2.5_c20210323.nc +atm/cam/chem/trop_mozart_aero/emis/chem_gases/2degrees/emissions-cmip6_e3sm_C3H8_surface_1850-2014_1.9x2.5_c20210323.nc +atm/cam/chem/trop_mozart_aero/emis/chem_gases/2degrees/emissions-cmip6_e3sm_CH2O_surface_1850-2014_1.9x2.5_c20210323.nc +atm/cam/chem/trop_mozart_aero/emis/chem_gases/2degrees/emissions-cmip6_e3sm_CH3CHO_surface_1850-2014_1.9x2.5_c20210323.nc +atm/cam/chem/trop_mozart_aero/emis/chem_gases/2degrees/emissions-cmip6_e3sm_CH3COCH3_surface_1850-2014_1.9x2.5_c20210323.nc +atm/cam/chem/trop_mozart_aero/emis/chem_gases/2degrees/emissions-cmip6_e3sm_CO_surface_1850-2014_1.9x2.5_c20210323.nc +atm/cam/chem/trop_mozart_aero/emis/chem_gases/2degrees/emissions-cmip6_e3sm_ISOP_surface_1850-2014_1.9x2.5_c20210323.nc +atm/cam/chem/trop_mozart_aero/emis/chem_gases/2degrees/emissions-cmip6_e3sm_ISOP_surface_1850-2014_1.9x2.5_c20210323.nc +atm/cam/chem/trop_mozart_aero/emis/chem_gases/2degrees/emissions-cmip6_e3sm_MTERP_surface_1850-2014_1.9x2.5_c20230126.nc +atm/cam/chem/trop_mozart_aero/emis/chem_gases/2degrees/emissions-cmip6_e3sm_NO_surface_1850-2014_1.9x2.5_c20220425.nc +atm/cam/chem/trop_mozart_aero/emis/DMSflux.1850.1deg_latlon_conserv.POPmonthlyClimFromACES4BGC_c20160416.nc +atm/cam/chem/trop_mozart_aero/emis/DECK_ne30/emissions-cmip6_e3sm_SOAG0_surf_1850-2014_1.9x2.5_c20230201.nc +atm/cam/chem/trop_mozart_aero/emis/DECK_ne30/cmip6_mam4_so2_surf_1850-2014_c180205.nc +atm/cam/chem/trop_mozart_aero/emis/DECK_ne30/cmip6_mam4_bc_a4_surf_1850-2014_c180205.nc +atm/cam/chem/trop_mozart_aero/emis/DECK_ne30/cmip6_mam4_num_a1_surf_1850-2014_c180205.nc +atm/cam/chem/trop_mozart_aero/emis/DECK_ne30/cmip6_mam4_num_a2_surf_1850-2014_c180205.nc +atm/cam/chem/trop_mozart_aero/emis/DECK_ne30/cmip6_mam4_num_a4_surf_1850-2014_c180205.nc +atm/cam/chem/trop_mozart_aero/emis/DECK_ne30/cmip6_mam4_pom_a4_surf_1850-2014_c180205.nc +atm/cam/chem/trop_mozart_aero/emis/DECK_ne30/cmip6_mam4_so4_a1_surf_1850-2014_c180205.nc +atm/cam/chem/trop_mozart_aero/emis/DECK_ne30/cmip6_mam4_so4_a2_surf_1850-2014_c180205.nc +atm/cam/chem/trop_mozart_aero/emis/chem_gases/2degrees/emissions_E90_surface_1750-2015_1.9x2.5_c20210408.nc + + + + +CYCLICAL +1849 +oxid_1.9x2.5_L26_1850-2015_c20181106.nc +'' +atm/cam/chem/trop_mozart_aero/oxid +'prsd_O3:O3','prsd_NO3:NO3','prsd_OH:OH' + + +ch4_oxid_1.9x2.5_L26_1990-1999clim.c090804.nc +atm/cam/chem/methane +CYCLICAL +1995 +'' +'prsd_ch4:CH4' + + + + 'A:H2OLNZ:H2O', 'N:O2:O2', 'N:CO2:CO2', + 'A:O3:O3', 'A:N2OLNZ:N2O', 'A:CH4LNZ:CH4', + 'N:CFC11:CFC11', 'N:CFC12:CFC12', + 'M:mam5_mode1:$INPUTDATA_ROOT/atm/cam/physprops/mam4_mode1_rrtmg_aeronetdust_c141106.nc', + 'M:mam5_mode2:$INPUTDATA_ROOT/atm/cam/physprops/mam4_mode2_rrtmg_c130628.nc', + 'M:mam5_mode3:$INPUTDATA_ROOT/atm/cam/physprops/mam4_mode3_rrtmg_aeronetdust_c141106.nc', + 'M:mam5_mode4:$INPUTDATA_ROOT/atm/cam/physprops/mam4_mode4_rrtmg_c130628.nc', + 'M:mam5_mode5:$INPUTDATA_ROOT/atm/cam/physprops/mam5_mode5_rrtmg_sig1.2_dgnl.40_c03072023.nc' + + + +3 +1 +'atm/cam/chem/trop_mam/marine_BGC/' +'CYCLICAL' +'monthly_macromolecules_0.1deg_bilinear_latlon_year01_merge_date.nc' +0 +0 +'chla:CHL1','mpoly:TRUEPOLYC','mprot:TRUEPROTC','mlip:TRUELIPC' + +atm/cam/chem/trop_mozart/ub/Linoz_Chlorine_Loading_CMIP6_0003-2017_c20171114.nc +SERIAL +linv3_1849-2017_CMIP6_Hist_10deg_58km_c20230705.nc +atm/cam/chem/trop_mozart/ub +INTERP_MISSING_MONTHS + + +SERIAL + + +'xactive_lnd' +'O3','H2O2','CH2O','CH3OOH','NO','NO2','HNO3','HO2NO2','PAN','CO','CH3COCH3','C2H5OOH','CH3CHO','H2SO4','SO2','NO3','N2O5','SOAG0','SOAG15','SOAG24','SOAG35','SOAG34','SOAG33','SOAG32','SOAG31' +'NEU' +'C2H5OOH','CH2O','CH3CHO','CH3OOH','H2O2','H2SO4','HNO3','HO2NO2','SO2','SOAG0','SOAG15','SOAG24','SOAG35','SOAG34','SOAG33','SOAG32','SOAG31' +'CH2O', 'CH3O2', 'CH3OOH', 'PAN', 'CO', 'C2H6', 'C3H8', 'C2H4', 'ROHO2', 'CH3COCH3', 'C2H5O2', 'C2H5OOH', 'CH3CHO', 'CH3CO3', 'ISOP', 'ISOPO2', 'MVKMACR', 'MVKO2' +'' + diff --git a/components/eam/bld/namelist_files/use_cases/20TR_eam_CMIP6-volc_chemUCI-Linoz-mam5-vbs.xml b/components/eam/bld/namelist_files/use_cases/20TR_eam_CMIP6-volc_chemUCI-Linoz-mam5-vbs.xml new file mode 100644 index 000000000000..6f0754423592 --- /dev/null +++ b/components/eam/bld/namelist_files/use_cases/20TR_eam_CMIP6-volc_chemUCI-Linoz-mam5-vbs.xml @@ -0,0 +1,123 @@ + + + + +.true. + + +.true. +.true. +.true. + + +atm/cam/solar/Solar_1850control_input4MIPS_c20181106.nc +18500101 +FIXED + + + +808.249e-9 +273.0211e-9 +32.1102e-12 +0.0 + + + +CYCLICAL +1850 +atm/cam/chem/trop_mozart_aero/emis/chem_gases/2degrees/emissions-cmip6_NO2_aircraft_vertical_1750-2015_1.9x2.5_c20170608.nc +atm/cam/chem/trop_mozart_aero/emis/DECK_ne30/cmip6_mam4_so2_elev_1850-2014_c180205_1850-aero_hist-volcano.nc +atm/cam/chem/trop_mozart_aero/emis/DECK_ne30/emissions-cmip6_e3sm_SOAG0_elev_1850-2014_1.9x2.5_c20230201.nc +atm/cam/chem/trop_mozart_aero/emis/DECK_ne30/cmip6_mam4_bc_a4_elev_1850-2014_c180205.nc +atm/cam/chem/trop_mozart_aero/emis/DECK_ne30/cmip6_mam4_num_a1_elev_1850-2014_c180205.nc +atm/cam/chem/trop_mozart_aero/emis/DECK_ne30/cmip6_mam4_num_a2_elev_1850-2014_c180205.nc +atm/cam/chem/trop_mozart_aero/emis/DECK_ne30/cmip6_mam4_num_a4_elev_1850-2014_c180205.nc +atm/cam/chem/trop_mozart_aero/emis/DECK_ne30/cmip6_mam4_pom_a4_elev_1850-2014_c180205.nc +atm/cam/chem/trop_mozart_aero/emis/DECK_ne30/cmip6_mam4_so4_a1_elev_1850-2014_c180205.nc +atm/cam/chem/trop_mozart_aero/emis/DECK_ne30/cmip6_mam4_so4_a2_elev_1850-2014_c180205.nc + + +CYCLICAL +1850 +atm/cam/chem/trop_mozart_aero/emis/chem_gases/2degrees/emissions-cmip6_e3sm_C2H4_surface_1850-2014_1.9x2.5_c20210323.nc +atm/cam/chem/trop_mozart_aero/emis/chem_gases/2degrees/emissions-cmip6_e3sm_C2H6_surface_1850-2014_1.9x2.5_c20210323.nc +atm/cam/chem/trop_mozart_aero/emis/chem_gases/2degrees/emissions-cmip6_e3sm_C3H8_surface_1850-2014_1.9x2.5_c20210323.nc +atm/cam/chem/trop_mozart_aero/emis/chem_gases/2degrees/emissions-cmip6_e3sm_CH2O_surface_1850-2014_1.9x2.5_c20210323.nc +atm/cam/chem/trop_mozart_aero/emis/chem_gases/2degrees/emissions-cmip6_e3sm_CH3CHO_surface_1850-2014_1.9x2.5_c20210323.nc +atm/cam/chem/trop_mozart_aero/emis/chem_gases/2degrees/emissions-cmip6_e3sm_CH3COCH3_surface_1850-2014_1.9x2.5_c20210323.nc +atm/cam/chem/trop_mozart_aero/emis/chem_gases/2degrees/emissions-cmip6_e3sm_CO_surface_1850-2014_1.9x2.5_c20210323.nc +atm/cam/chem/trop_mozart_aero/emis/chem_gases/2degrees/emissions-cmip6_e3sm_ISOP_surface_1850-2014_1.9x2.5_c20210323.nc +atm/cam/chem/trop_mozart_aero/emis/chem_gases/2degrees/emissions-cmip6_e3sm_ISOP_surface_1850-2014_1.9x2.5_c20210323.nc +atm/cam/chem/trop_mozart_aero/emis/chem_gases/2degrees/emissions-cmip6_e3sm_MTERP_surface_1850-2014_1.9x2.5_c20230126.nc +atm/cam/chem/trop_mozart_aero/emis/chem_gases/2degrees/emissions-cmip6_e3sm_NO_surface_1850-2014_1.9x2.5_c20220425.nc +atm/cam/chem/trop_mozart_aero/emis/DMSflux.1850.1deg_latlon_conserv.POPmonthlyClimFromACES4BGC_c20160416.nc +atm/cam/chem/trop_mozart_aero/emis/DECK_ne30/emissions-cmip6_e3sm_SOAG0_surf_1850-2014_1.9x2.5_c20230201.nc +atm/cam/chem/trop_mozart_aero/emis/DECK_ne30/cmip6_mam4_so2_surf_1850-2014_c180205.nc +atm/cam/chem/trop_mozart_aero/emis/DECK_ne30/cmip6_mam4_bc_a4_surf_1850-2014_c180205.nc +atm/cam/chem/trop_mozart_aero/emis/DECK_ne30/cmip6_mam4_num_a1_surf_1850-2014_c180205.nc +atm/cam/chem/trop_mozart_aero/emis/DECK_ne30/cmip6_mam4_num_a2_surf_1850-2014_c180205.nc +atm/cam/chem/trop_mozart_aero/emis/DECK_ne30/cmip6_mam4_num_a4_surf_1850-2014_c180205.nc +atm/cam/chem/trop_mozart_aero/emis/DECK_ne30/cmip6_mam4_pom_a4_surf_1850-2014_c180205.nc +atm/cam/chem/trop_mozart_aero/emis/DECK_ne30/cmip6_mam4_so4_a1_surf_1850-2014_c180205.nc +atm/cam/chem/trop_mozart_aero/emis/DECK_ne30/cmip6_mam4_so4_a2_surf_1850-2014_c180205.nc +atm/cam/chem/trop_mozart_aero/emis/chem_gases/2degrees/emissions_E90_surface_1750-2015_1.9x2.5_c20210408.nc + + + + +CYCLICAL +1849 +oxid_1.9x2.5_L26_1850-2015_c20181106.nc +'' +atm/cam/chem/trop_mozart_aero/oxid +'prsd_O3:O3','prsd_NO3:NO3','prsd_OH:OH' + + +ch4_oxid_1.9x2.5_L26_1990-1999clim.c090804.nc +atm/cam/chem/methane +CYCLICAL +1995 +'' +'prsd_ch4:CH4' + + + + 'A:H2OLNZ:H2O', 'N:O2:O2', 'N:CO2:CO2', + 'A:O3:O3', 'A:N2OLNZ:N2O', 'A:CH4LNZ:CH4', + 'N:CFC11:CFC11', 'N:CFC12:CFC12', + 'M:mam5_mode1:$INPUTDATA_ROOT/atm/cam/physprops/mam4_mode1_rrtmg_aeronetdust_c141106.nc', + 'M:mam5_mode2:$INPUTDATA_ROOT/atm/cam/physprops/mam4_mode2_rrtmg_c130628.nc', + 'M:mam5_mode3:$INPUTDATA_ROOT/atm/cam/physprops/mam4_mode3_rrtmg_aeronetdust_c141106.nc', + 'M:mam5_mode4:$INPUTDATA_ROOT/atm/cam/physprops/mam4_mode4_rrtmg_c130628.nc', + 'M:mam5_mode5:$INPUTDATA_ROOT/atm/cam/physprops/mam5_mode5_rrtmg_sig1.2_dgnl.40_c03072023.nc' + + + +3 +1 +'atm/cam/chem/trop_mam/marine_BGC/' +'CYCLICAL' +'monthly_macromolecules_0.1deg_bilinear_latlon_year01_merge_date.nc' +0 +0 +'chla:CHL1','mpoly:TRUEPOLYC','mprot:TRUEPROTC','mlip:TRUELIPC' + +atm/cam/chem/trop_mozart/ub/Linoz_Chlorine_Loading_CMIP6_0003-2017_c20171114.nc +18500101 +FIXED +1850 +linv3_1849-2017_CMIP6_Hist_10deg_58km_c20230705.nc +atm/cam/chem/trop_mozart/ub +CYCLICAL + + +SERIAL + + +'xactive_lnd' +'O3','H2O2','CH2O','CH3OOH','NO','NO2','HNO3','HO2NO2','PAN','CO','CH3COCH3','C2H5OOH','CH3CHO','H2SO4','SO2','NO3','N2O5','SOAG0','SOAG15','SOAG24','SOAG35','SOAG34','SOAG33','SOAG32','SOAG31' +'NEU' +'C2H5OOH','CH2O','CH3CHO','CH3OOH','H2O2','H2SO4','HNO3','HO2NO2','SO2','SOAG0','SOAG15','SOAG24','SOAG35','SOAG34','SOAG33','SOAG32','SOAG31' +'CH2O', 'CH3O2', 'CH3OOH', 'PAN', 'CO', 'C2H6', 'C3H8', 'C2H4', 'ROHO2', 'CH3COCH3', 'C2H5O2', 'C2H5OOH', 'CH3CHO', 'CH3CO3', 'ISOP', 'ISOPO2', 'MVKMACR', 'MVKO2' +'' + diff --git a/components/eam/bld/namelist_files/use_cases/20TR_eam_CMIP6-xGHG-xaer_chemUCI-Linoz-mam5-vbs.xml b/components/eam/bld/namelist_files/use_cases/20TR_eam_CMIP6-xGHG-xaer_chemUCI-Linoz-mam5-vbs.xml new file mode 100644 index 000000000000..f70010a82c44 --- /dev/null +++ b/components/eam/bld/namelist_files/use_cases/20TR_eam_CMIP6-xGHG-xaer_chemUCI-Linoz-mam5-vbs.xml @@ -0,0 +1,120 @@ + + + + +.true. + + +.true. +.true. +.true. + + +atm/cam/solar/Solar_1850-2299_input4MIPS_c20181106.nc +SERIAL + + + +808.249e-9 +273.0211e-9 +32.1102e-12 +0.0 + + + +CYCLICAL +1850 +atm/cam/chem/trop_mozart_aero/emis/chem_gases/2degrees/emissions-cmip6_NO2_aircraft_vertical_1750-2015_1.9x2.5_c20170608.nc +atm/cam/chem/trop_mozart_aero/emis/DECK_ne30/cmip6_mam4_so2_elev_1850-2014_c180205_1850-aero_hist-volcano.nc +atm/cam/chem/trop_mozart_aero/emis/DECK_ne30/emissions-cmip6_e3sm_SOAG0_elev_1850-2014_1.9x2.5_c20230201.nc +atm/cam/chem/trop_mozart_aero/emis/DECK_ne30/cmip6_mam4_bc_a4_elev_1850-2014_c180205.nc +atm/cam/chem/trop_mozart_aero/emis/DECK_ne30/cmip6_mam4_num_a1_elev_1850-2014_c180205.nc +atm/cam/chem/trop_mozart_aero/emis/DECK_ne30/cmip6_mam4_num_a2_elev_1850-2014_c180205.nc +atm/cam/chem/trop_mozart_aero/emis/DECK_ne30/cmip6_mam4_num_a4_elev_1850-2014_c180205.nc +atm/cam/chem/trop_mozart_aero/emis/DECK_ne30/cmip6_mam4_pom_a4_elev_1850-2014_c180205.nc +atm/cam/chem/trop_mozart_aero/emis/DECK_ne30/cmip6_mam4_so4_a1_elev_1850-2014_c180205.nc +atm/cam/chem/trop_mozart_aero/emis/DECK_ne30/cmip6_mam4_so4_a2_elev_1850-2014_c180205.nc + + +CYCLICAL +1850 +atm/cam/chem/trop_mozart_aero/emis/chem_gases/2degrees/emissions-cmip6_e3sm_C2H4_surface_1850-2014_1.9x2.5_c20210323.nc +atm/cam/chem/trop_mozart_aero/emis/chem_gases/2degrees/emissions-cmip6_e3sm_C2H6_surface_1850-2014_1.9x2.5_c20210323.nc +atm/cam/chem/trop_mozart_aero/emis/chem_gases/2degrees/emissions-cmip6_e3sm_C3H8_surface_1850-2014_1.9x2.5_c20210323.nc +atm/cam/chem/trop_mozart_aero/emis/chem_gases/2degrees/emissions-cmip6_e3sm_CH2O_surface_1850-2014_1.9x2.5_c20210323.nc +atm/cam/chem/trop_mozart_aero/emis/chem_gases/2degrees/emissions-cmip6_e3sm_CH3CHO_surface_1850-2014_1.9x2.5_c20210323.nc +atm/cam/chem/trop_mozart_aero/emis/chem_gases/2degrees/emissions-cmip6_e3sm_CH3COCH3_surface_1850-2014_1.9x2.5_c20210323.nc +atm/cam/chem/trop_mozart_aero/emis/chem_gases/2degrees/emissions-cmip6_e3sm_CO_surface_1850-2014_1.9x2.5_c20210323.nc +atm/cam/chem/trop_mozart_aero/emis/chem_gases/2degrees/emissions-cmip6_e3sm_ISOP_surface_1850-2014_1.9x2.5_c20210323.nc +atm/cam/chem/trop_mozart_aero/emis/chem_gases/2degrees/emissions-cmip6_e3sm_ISOP_surface_1850-2014_1.9x2.5_c20210323.nc +atm/cam/chem/trop_mozart_aero/emis/chem_gases/2degrees/emissions-cmip6_e3sm_MTERP_surface_1850-2014_1.9x2.5_c20230126.nc +atm/cam/chem/trop_mozart_aero/emis/chem_gases/2degrees/emissions-cmip6_e3sm_NO_surface_1850-2014_1.9x2.5_c20220425.nc +atm/cam/chem/trop_mozart_aero/emis/DMSflux.1850.1deg_latlon_conserv.POPmonthlyClimFromACES4BGC_c20160416.nc +atm/cam/chem/trop_mozart_aero/emis/DECK_ne30/emissions-cmip6_e3sm_SOAG0_surf_1850-2014_1.9x2.5_c20230201.nc +atm/cam/chem/trop_mozart_aero/emis/DECK_ne30/cmip6_mam4_so2_surf_1850-2014_c180205.nc +atm/cam/chem/trop_mozart_aero/emis/DECK_ne30/cmip6_mam4_bc_a4_surf_1850-2014_c180205.nc +atm/cam/chem/trop_mozart_aero/emis/DECK_ne30/cmip6_mam4_num_a1_surf_1850-2014_c180205.nc +atm/cam/chem/trop_mozart_aero/emis/DECK_ne30/cmip6_mam4_num_a2_surf_1850-2014_c180205.nc +atm/cam/chem/trop_mozart_aero/emis/DECK_ne30/cmip6_mam4_num_a4_surf_1850-2014_c180205.nc +atm/cam/chem/trop_mozart_aero/emis/DECK_ne30/cmip6_mam4_pom_a4_surf_1850-2014_c180205.nc +atm/cam/chem/trop_mozart_aero/emis/DECK_ne30/cmip6_mam4_so4_a1_surf_1850-2014_c180205.nc +atm/cam/chem/trop_mozart_aero/emis/DECK_ne30/cmip6_mam4_so4_a2_surf_1850-2014_c180205.nc +atm/cam/chem/trop_mozart_aero/emis/chem_gases/2degrees/emissions_E90_surface_1750-2015_1.9x2.5_c20210408.nc + + + + +CYCLICAL +1849 +oxid_1.9x2.5_L26_1850-2015_c20181106.nc +'' +atm/cam/chem/trop_mozart_aero/oxid +'prsd_O3:O3','prsd_NO3:NO3','prsd_OH:OH' + + +ch4_oxid_1.9x2.5_L26_1990-1999clim.c090804.nc +atm/cam/chem/methane +CYCLICAL +1995 +'' +'prsd_ch4:CH4' + + + + 'A:H2OLNZ:H2O', 'N:O2:O2', 'N:CO2:CO2', + 'A:O3:O3', 'A:N2OLNZ:N2O', 'A:CH4LNZ:CH4', + 'N:CFC11:CFC11', 'N:CFC12:CFC12', + 'M:mam5_mode1:$INPUTDATA_ROOT/atm/cam/physprops/mam4_mode1_rrtmg_aeronetdust_c141106.nc', + 'M:mam5_mode2:$INPUTDATA_ROOT/atm/cam/physprops/mam4_mode2_rrtmg_c130628.nc', + 'M:mam5_mode3:$INPUTDATA_ROOT/atm/cam/physprops/mam4_mode3_rrtmg_aeronetdust_c141106.nc', + 'M:mam5_mode4:$INPUTDATA_ROOT/atm/cam/physprops/mam4_mode4_rrtmg_c130628.nc', + 'M:mam5_mode5:$INPUTDATA_ROOT/atm/cam/physprops/mam5_mode5_rrtmg_sig1.2_dgnl.40_c03072023.nc' + + + +3 +1 +'atm/cam/chem/trop_mam/marine_BGC/' +'CYCLICAL' +'monthly_macromolecules_0.1deg_bilinear_latlon_year01_merge_date.nc' +0 +0 +'chla:CHL1','mpoly:TRUEPOLYC','mprot:TRUEPROTC','mlip:TRUELIPC' + +atm/cam/chem/trop_mozart/ub/Linoz_Chlorine_Loading_CMIP6_0003-2017_c20171114.nc +SERIAL +linv3_1849-2017_CMIP6_Hist_10deg_58km_c20230705.nc +atm/cam/chem/trop_mozart/ub +INTERP_MISSING_MONTHS + + +SERIAL + + +'xactive_lnd' +'O3','H2O2','CH2O','CH3OOH','NO','NO2','HNO3','HO2NO2','PAN','CO','CH3COCH3','C2H5OOH','CH3CHO','H2SO4','SO2','NO3','N2O5','SOAG0','SOAG15','SOAG24','SOAG35','SOAG34','SOAG33','SOAG32','SOAG31' +'NEU' +'C2H5OOH','CH2O','CH3CHO','CH3OOH','H2O2','H2SO4','HNO3','HO2NO2','SO2','SOAG0','SOAG15','SOAG24','SOAG35','SOAG34','SOAG33','SOAG32','SOAG31' +'CH2O', 'CH3O2', 'CH3OOH', 'PAN', 'CO', 'C2H6', 'C3H8', 'C2H4', 'ROHO2', 'CH3COCH3', 'C2H5O2', 'C2H5OOH', 'CH3CHO', 'CH3CO3', 'ISOP', 'ISOPO2', 'MVKMACR', 'MVKO2' +'' + diff --git a/components/eam/cime_config/config_component.xml b/components/eam/cime_config/config_component.xml index 1a961b84affe..8f1e68161cb7 100755 --- a/components/eam/cime_config/config_component.xml +++ b/components/eam/cime_config/config_component.xml @@ -53,6 +53,7 @@ -phys default &eamv3_phys_defaults; &eamv3_chem_defaults; &eamv3_phys_defaults; &eamv3_chem_defaults; + &eamv3_phys_defaults; &eamv3_chem_defaults; &eamv3_phys_defaults; &eamv3_chem_defaults; -bc_dep_to_snow_updates -co2_cycle @@ -125,6 +126,14 @@ 1850_E3SMv1_superfast_ar5-emis 1850S_E3SMv1_superfast_ar5-emis 20TR_eam_CMIP6_chemUCI-Linoz-mam5-vbs + 20TR_eam_CMIP6_chemUCI-Linoz-mam5-vbs + 20TR_eam_CMIP6-GHG_chemUCI-Linoz-mam5-vbs + 20TR_eam_CMIP6-aer_chemUCI-Linoz-mam5-vbs + 20TR_eam_CMIP6-nat_chemUCI-Linoz-mam5-vbs + 20TR_eam_CMIP6-xGHG-xaer_chemUCI-Linoz-mam5-vbs + 20TR_eam_CMIP6-ozone_chemUCI-Linoz-mam5-vbs + 20TR_eam_CMIP6-lulc_chemUCI-Linoz-mam5-vbs + 20TR_eam_CMIP6-volc_chemUCI-Linoz-mam5-vbs 20TR_eam_CMIP6_chemUCI-Linoz-mam5-vbs SSP585_eam_CMIP6_chemUCI-Linoz-mam5-vbs SSP370_eam_CMIP6_chemUCI-Linoz-mam5-vbs diff --git a/components/elm/bld/namelist_files/use_cases/20thC_CMIP6xLULC_transient.xml b/components/elm/bld/namelist_files/use_cases/20thC_CMIP6xLULC_transient.xml new file mode 100644 index 000000000000..7a6247bbe27f --- /dev/null +++ b/components/elm/bld/namelist_files/use_cases/20thC_CMIP6xLULC_transient.xml @@ -0,0 +1,48 @@ + + + + +Historical single forcing simulation with land held at 1850 condition +Simulate transient land-use, aerosol deposition, and Nitrogen deposition changes from 1850 to 2005 +Simulate transient land-use, aerosol deposition, and Nitrogen deposition changes from 1850 to 2005 +Simulate transient land-use, aerosol deposition, and Nitrogen deposition changes from 1850 to 2005 + +1850 + +1850-2000 + +arb_ic + + +1850 +1850 +1850 + + +2000 +2000 +2000 + +1850 +1850 +1850 + + + + +lnd/clm2/surfdata_map/surfdata_ne30np4_simyr1850_2015_c171018.nc +lnd/clm2/surfdata_map/landuse.timeseries_ne30np4_hist_simyr1850_2015_c20171018.nc +lnd/clm2/initdata_map/20180316.DECKv1b_A1.ne30_oEC.edison.clm2.r.1980-01-01-00000.8575c3f_c20190904.nc + +lnd/clm2/surfdata_map/surfdata_0.125x0.125_simyr1850_c190730.nc + +lnd/clm2/surfdata_map/surfdata_0.5x0.5_simyr1850_c200609_with_TOP.nc + + +lnd/clm2/surfdata_map/surfdata_ne1024pg2_simyr2010_c211021.nc + +.false. +.false. + + + diff --git a/components/elm/cime_config/config_component.xml b/components/elm/cime_config/config_component.xml index da060584cfb8..b191a0a2248d 100755 --- a/components/elm/cime_config/config_component.xml +++ b/components/elm/cime_config/config_component.xml @@ -72,7 +72,14 @@ 1850_CMIP6bgc_control 1850_SCMIP6_control 1850_SCMIP6_control - 20thC_CMIP6_transient + 20thC_CMIP6_transient + 20thC_CMIP6xLULC_transient + 20thC_CMIP6xLULC_transient + 20thC_CMIP6xLULC_transient + 20thC_CMIP6xLULC_transient + 20thC_CMIP6xLULC_transient + 20thC_CMIP6_transient + 20thC_CMIP6_transient 20thC_CMIP6bgc_transient 20thC_CMIP6bgc_transient 20thC_bgc_transient diff --git a/driver-mct/cime_config/config_component_e3sm.xml b/driver-mct/cime_config/config_component_e3sm.xml index 08758f935313..acdca60ae2a6 100755 --- a/driver-mct/cime_config/config_component_e3sm.xml +++ b/driver-mct/cime_config/config_component_e3sm.xml @@ -753,6 +753,12 @@ 312.821 388.717 388.717 + 284.317 + 284.317 + 284.317 + 284.317 + 284.317 + 284.317 0.000001 0.000001 284.317 From 82fd0061a9b32bdf209b4a173ecb47d3f7d09587 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 26 Aug 2024 11:00:22 +0000 Subject: [PATCH 328/451] Bump tj-actions/changed-files from 44 to 45 Bumps [tj-actions/changed-files](https://github.com/tj-actions/changed-files) from 44 to 45. - [Release notes](https://github.com/tj-actions/changed-files/releases) - [Changelog](https://github.com/tj-actions/changed-files/blob/main/HISTORY.md) - [Commits](https://github.com/tj-actions/changed-files/compare/v44...v45) --- updated-dependencies: - dependency-name: tj-actions/changed-files dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] --- .github/workflows/e3sm-gh-md-linter.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/e3sm-gh-md-linter.yml b/.github/workflows/e3sm-gh-md-linter.yml index 8ee8b7a7f13c..507c2c3745ea 100644 --- a/.github/workflows/e3sm-gh-md-linter.yml +++ b/.github/workflows/e3sm-gh-md-linter.yml @@ -17,7 +17,7 @@ jobs: - uses: actions/checkout@v4 with: fetch-depth: 0 - - uses: tj-actions/changed-files@v44 + - uses: tj-actions/changed-files@v45 id: changed-files with: files: '**/*.md' From 624d9ac5757e18db32477702dba04f442e24d247 Mon Sep 17 00:00:00 2001 From: Xylar Asay-Davis Date: Mon, 26 Aug 2024 06:07:59 -0500 Subject: [PATCH 329/451] Revert changes to .gitignore --- .gitignore | 13 ------------- 1 file changed, 13 deletions(-) diff --git a/.gitignore b/.gitignore index d2fcc80bbb71..d7a1fabfd6bc 100644 --- a/.gitignore +++ b/.gitignore @@ -51,16 +51,3 @@ components/eamxx/docs/common/eamxx_params.md components/eamxx/src/python/build components/eamxx/src/python/build_src components/eamxx/src/python/dist - -# OS generated files # -###################### -.DS_Store -.DS_Store? -._* -.Spotlight-V100 -.Trashes -ehthumbs.db -Thumbs.db - -# idea folder -.idea/ From a7ec7e67c6793b500dc83106995bf6038ae90e96 Mon Sep 17 00:00:00 2001 From: James Foucar Date: Mon, 26 Aug 2024 12:28:59 -0600 Subject: [PATCH 330/451] Update CIME submodule ... to af3eab5b8a213e79923551e7f9d9f56edb944c0f Changes: 1) Generalize _hists_match for mom6 files 2) support append in config_pes.xml overrides field 3) Add case git: Adds a case interface to git. It creates a local git repository when case.setup is run and updates that repository with each action that triggers an update of the CaseStatus file. Optionally a remote repository can be attached by setting CASE_GIT_REPOSITORY to the name of the remote repository. 4) xmlchange: Add documentation for setting values with commas 5) Remove mct for cesm 6) remove load_balancing_tool, broken and unsupported Fixes 1) Fix/rest n in tests: move the computation of REST_N into the python 2) cprnc: need to make sure the directory exists before linking to it 3) check_lockedfiles call in xmlchange needs quiet=True 4) fixes detection of pfunit_path by making sure it exists 5) Fixes handling cprnc output 6) Fixes creating new environment with specific python version 7) Fixes `query_config` tool. - Adds longname to `--grids` - Fixes duplicate and empty choices 8) Fixes check_lockedfiles call in xmlchange 9) Fix list_e3sm_tests tool [BFB] --- cime | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cime b/cime index f903115718eb..af3eab5b8a21 160000 --- a/cime +++ b/cime @@ -1 +1 @@ -Subproject commit f903115718ebc30669ce557f511abaef231a1d88 +Subproject commit af3eab5b8a213e79923551e7f9d9f56edb944c0f From aa08e0c2b115604f79f6b87ae321689504caaa33 Mon Sep 17 00:00:00 2001 From: James Foucar Date: Mon, 26 Aug 2024 13:10:55 -0600 Subject: [PATCH 331/451] Disable git interface --- cime | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cime b/cime index af3eab5b8a21..eacb1b7f5ed9 160000 --- a/cime +++ b/cime @@ -1 +1 @@ -Subproject commit af3eab5b8a213e79923551e7f9d9f56edb944c0f +Subproject commit eacb1b7f5ed984f0c124076c78fd1e80dbd9b7a1 From dabae5c6e1d2c36dc32a75bbbae33f709a55d0f1 Mon Sep 17 00:00:00 2001 From: "Yuan, Fengming" Date: Mon, 13 Nov 2023 11:59:09 -0500 Subject: [PATCH 332/451] 3 initial tests added into 'e3sm_lnd_developer' for user-defined PFT codes, but NOT YET fully work. Two tests are actually similary as 'elm_usrdat' test, but with 42_FLUXNETSITES, so those 2 shall produce same outputs. The 3rd one, usrpft_arctic_I1850CNPRDCTCBC, is for testing an actual Arctic Site (See Sulman et al. 2021), however which would not produce same results as the paper because ELM developments in arctic PFT physiology not yet included. NOTE: there are a few needed inputs are included in each tests, which if not in $DIN_LOC_ROOT user can copy them into to allow it work. --- cime_config/tests.py | 3 ++- .../clm_params_c180524-sub12_updated20240201.nc | Bin 0 -> 82964 bytes .../shell_commands | 11 +++++++++++ .../usrpft_arctic_I1850CNPRDCTCBC/user_nl_elm | 7 +++++++ .../clm_params_c211124vpft.nc | Bin 0 -> 93128 bytes .../shell_commands | 10 ++++++++++ .../usrpft_codetest_I1850CNPRDCTCBC/user_nl_elm | 10 ++++++++++ .../shell_commands | 11 +++++++++++ .../usrpft_default_I1850CNPRDCTCBC/user_nl_elm | 2 ++ 9 files changed, 53 insertions(+), 1 deletion(-) create mode 100644 components/elm/cime_config/testdefs/testmods_dirs/elm/usrpft_arctic_I1850CNPRDCTCBC/clm_params_c180524-sub12_updated20240201.nc create mode 100644 components/elm/cime_config/testdefs/testmods_dirs/elm/usrpft_arctic_I1850CNPRDCTCBC/shell_commands create mode 100644 components/elm/cime_config/testdefs/testmods_dirs/elm/usrpft_arctic_I1850CNPRDCTCBC/user_nl_elm create mode 100644 components/elm/cime_config/testdefs/testmods_dirs/elm/usrpft_codetest_I1850CNPRDCTCBC/clm_params_c211124vpft.nc create mode 100644 components/elm/cime_config/testdefs/testmods_dirs/elm/usrpft_codetest_I1850CNPRDCTCBC/shell_commands create mode 100644 components/elm/cime_config/testdefs/testmods_dirs/elm/usrpft_codetest_I1850CNPRDCTCBC/user_nl_elm create mode 100644 components/elm/cime_config/testdefs/testmods_dirs/elm/usrpft_default_I1850CNPRDCTCBC/shell_commands create mode 100644 components/elm/cime_config/testdefs/testmods_dirs/elm/usrpft_default_I1850CNPRDCTCBC/user_nl_elm diff --git a/cime_config/tests.py b/cime_config/tests.py index 556f80ec9702..d6512d88ede1 100644 --- a/cime_config/tests.py +++ b/cime_config/tests.py @@ -76,7 +76,6 @@ ) }, - "e3sm_land_developer" : { "share" : True, "time" : "0:45:00", @@ -95,6 +94,8 @@ "SMS.r05_r05.IELM.elm-topounit", "ERS.ELM_USRDAT.I1850ELM.elm-usrdat", "ERS.r05_r05.IELM.elm-lnd_rof_2way", + "ERS.ELM_USRDAT.I1850CNPRDCTCBC.elm-usrpft_default_I1850CNPRDCTCBC", + "ERS.ELM_USRDAT.I1850CNPRDCTCBC.elm-usrpft_codetest_I1850CNPRDCTCBC", "ERS.r05_r05.IELM.elm-V2_ELM_MOSART_features", "ERS.ELM_USRDAT.IELM.elm-surface_water_dynamics" ) diff --git a/components/elm/cime_config/testdefs/testmods_dirs/elm/usrpft_arctic_I1850CNPRDCTCBC/clm_params_c180524-sub12_updated20240201.nc b/components/elm/cime_config/testdefs/testmods_dirs/elm/usrpft_arctic_I1850CNPRDCTCBC/clm_params_c180524-sub12_updated20240201.nc new file mode 100644 index 0000000000000000000000000000000000000000..2ec124ef77968589cf6c89b76f65993234444ed6 GIT binary patch literal 82964 zcmeHw3!EH9o&Ro&%GlK8Gk9dj#r)NavQ1lD}ii+_6{_4@w)7vxMvpuun zK4*WDt?r(#s&7^O>Q}$|)vtavuyJ#3jkuZ+)ZzckR3uAp=HmanOg0@&jQV4GVl+EO zZ)<9r@xLLa?;lMk!t{J9{?E=Nqp@TM2jbC0G8%5tqM1+xh_eBdRLdr{psoQ>AQ;oN z1Hi2%^aI-9Wt%p&_NUQoA#LmSRcNfRo@t`$98B)lI@f8)Oy$?v)2pTR)^Jh_hzOan zbS_AZoN3yX(?yJKiqYNKyLt^(K4K(7dox;VYa;0n1VdWu4&2B0`qO&IAC4z9P^3)F z-_e!`neQj3+0|vF8Ax?$tr?2`3jBZN`VMnU%0)oriB3+aBcG5JT$s{q=|H8%{iy&d zGvg0+_H?Z7T4jYtm9$Y05zTdV^>(c7?Osdp)>4rPUO@_LJ9;{LCb)O$s%$Sk-@N@(mGco*WS)`y{maaj4Y9OI+F|fv&ocy zG?okoV)4K@=s1}6$J0o@v!l%}eZn<4S969M`qi4=jy1iVyjjf|BJJ_?dj6MkXj`qf z_E0IaAwRg4p2@5??pAad#i#PB-;D~8FOW?4nhw+iQUU8orq}bo^qN}M7ODMPqrxQq z)xF)5D$Inxn&>@aU)8&6bpd^$cFMv&<(lj0=w02@+qJGRcXVWsaxR{tuFR>~Ov!B> zE4vDbt&qqp#6?+vxNNha-eOBGD=;LO+TBeCtL(~9Mh0erBFw9MSM`*YWFcP8nfi01 zn%1LX(CWg_Wl1ihMbgP+)*nkIM%TymK!o3!QUP~b)3LU*lk?is8RzVcdInrI#f7nCL`!k;EDNa&5pW@m+T+NZM96t@Jq5hkklnfOod?b^OA6bocBdPYOL@6U_qVMvteXfOxK z8wAV+MvWv!qykL5eUWia)KjTE>+$_aP0fjMgr|pfh`ygsWe zjXn6Lr@L|CduyGZ8rDbCx}Nb5=&?*R$NRS(&gSjWL^Pg@V`>w_+$O8VlZotDY(gV; zX7totnyAucS^h})XYCEW)av+;w^2PENG8LgD-^VU1AcR&+hRQKtic_Fex9x-{_>fh zn7~{4711H_Cw}=(h>(eZ{@S(C62;3!>al1!vGOOUJgl@bHK_qY`y`zN%AmK9g$pq}A9gUts$+Z@cr7d0B zrB@+(eC~c=t4~Ct<8n->6fG_VjkHp_T%Csjbx_^6@|?WX+o^+^N=$XX>8`gwEuuCx zG-G(cWv)BoC&hT*8NonWZ|97u9im5yG;Cb(MjR(T;-%gUp2+h9b8x{Er$T#F_K}*J zKaC@-<0?bk;Bs3(%OPFo(t((tWVKW}IhsgjpiT5sUHKzYBka%5J*rt}OBK({ubb>#4Hc284~6uOzc$oVU4Zv!l28o_xc(_wPhp zYuV~MXzok3WZzb8SPKZ|&?O+z(_|?Ii9Ug;yA}zApxe|iqG%k8n5FY{ocf3=%X9d; z0sJAF2&E{ZtFoBpT-LJCd}(xuL$DnKn|NN@K<|*oKXQrlFIVI1#z@>B&Y(qc?+T}f zI$yatiiL`_9;1aO2v_MW=G55MI6AH9U`{@EARs0Kb~3aZ-Zx9}PIvw5`9)MmK_YJ4 z;BwX0;#2wqUt1_18ceMi|9lJJNxdHiTyQD@5oUkRY7$5~3FK8eX z+8hh>5yNd69!8c85h{9!Q?u7HaNaRkyc~1S!-+BJxXuU;E#;7+(GPtg2dZ$l_~vHSYuB@lnCxSi^A z_GQHPsX|43C!BK3`0EjT-UOitiwcVUx$C1P=$B(HLBnfI-O$i#VVx8U(4k}?4f-ZL z+JHu*KfNVnnn=)Pxn7u$ay4QxDl-;H@5jBFE~X-jIq{tpsbm`el!_f0N5fbIr`#c* zpj+}ac0OS8269^t8p!K1@l+DhauSGtod+i{xT4 zG(r+~1?Ui=STZ9NWPs$h9LMl&BXqPeITW~R4^d?P*V-SP+M^q5@i8nks4;-pJ(kx| z0T?<68aH7=OHHCWZ!E*H4H6t}OFCGG3l6zya*So^*K?ZAaA@|0j`*kIRxow9N zR1OT^WL88YhpTenJ9U*ySB#HaCI%Kt>S&ly6ureX5~q>}(20r=nY*&p)(in;V>lCo z?kW()y{odB=*wER`uMB5+D8Q+wWGcEU1RBFZgflw1ro{B1SE@e@;W_4+zU#NfCdpK zn(5WT!`u4X!`u3|QXRT2%MpCb`B;)-c`r)^_!wEaLGloIT$ZDDK0dF@rgCFp5zlLz zsQ7m6p?-6VEd@w(xPd?@;ZFv+{HN0JvhH>ot=P&jc~FCyTvRk-ArHb_u`Jo6w)PnC zsx_c>xOauM0(yn!?UJ)rYz?S(MhEb7x(MI~m#ear=&LGz1?XbNA>gT}!7s{1QFqvQ zDa0QuA8{Ic+qpg}8i#IlvOX%$6Nj+8k;GCApOCtw@fjxosS(V6zl|I*6TdmFY1!51 zC6u1D`jk^fZZ<&6#a-N#A=e%V@g+gG{BGtD;gsu}L>sC-OZLMO>zgy;T}Z`Vr*zgX z((Ng60mA$N%xJ-|>3f&;I`as=ZIZ@Cn3+*jcbH4iu+uzXm1!8Y%mYju$Cw4s zT$X9pe3YRfJ(i3mqI~7vRU4EjPovToAYD5;I-AP|X&uw(5KNpyI?ZVU>DH~JD8%I! zcM9LuM<$|rObjxfaXZ)twWxBDR#oWqvSSeYqZtkQksPF}iTp&SjB*^qw=?z$`wp*V zQ1R{RUH#^=e(O4b%OtyRS%qhnM#=tZq76G7N_O9}%IJ($klkzR4gqgH#6sBh;;ww` zR(|dz7y5>kL6Z=ENfvB|5V%|ekpKjdO(~I)FuHA<6Zp1~t0Thk@d}i!R!nzo`|G)i zWg7N2dJ2Z{R2r-jaq-D5?)o8MZHQ#jwC;slcl1ob*?iJx!w?GX5GHZV zy{$@Z{SjcBtz)#K^&lY*6ksL2kkc4yr5~$3g&pRLHo)#K4V^n|IQSxmfr0B=!C!*h zPRp%cy4dCs?ORw z2^(vMv*}zYyE_#wtF0SSzyq3u@@$%Py2D&g=TWCy+i;9<$0AsxnVxm51zfT~cBJ^q zFK4->m&Oj@ot5$LCly^K#*qs$G0aVg5A6?uMZK2bg%a3o1D21~ip*G)S{8YlY#X&) zJQ>plc632xZO2X+l!TXR5Gqwz#wLghUZq-DoXFWhX* z$tB?;<5&)=S*SeavKHZRiGTJGzQuY4tbW7-jJe&5;-?JcW#xHJbHrw`UP0NJ)Mk0E zXPz9oEyEFDk$i)XY_7^+lIg5va9VRYm5W2N`sK=tORP=vfwevu3?@@tT<}aUs;qXj zqJDFWEk)P@TqxqLtKyfGjro`2kF_41XrXr}E%%rvgXV$Im>3q*rn;u_relCt$G5Hs zoUY1Mf<9FI3e@?W4nUd}3FT;_s?sf4-z9K4%~P*4RkcyQy$0K$fd_LwwNTEdf}=?t zd-#&r;gwEfFu{Znw&_@^n1F7Wv^?3d7K~4EEJ0$IF?~oI^{{J}SF}sIn{xCxtlbdWrI)xkmu7F@*(|aA!vc z?#(nZl{uJGpI^NZlSP^e(4vl9sOCL7qbIo43t(sy&{om!VaztL0-WTM4EiJt)#5^g zIZ{*(vdaqiL)W=2M+u&<=%)f>(Y#~8Qy(DKS4N*Jfz4_Bzm&^Sra{U5 z_|N4$mvw#$^|K}_R(^S`px+gxA5+=v>USQc3F|V`(pbUV%q&N`#d?U^AQD#UBzHJV z(D{rpt^&86OU&c?B-ml`=_NA8b{<$!H-0MbYxN_)8E-Y$Yb?mWm)n09BOn^R-88gy0A{0M-85B+UN7e2l$Oi7I(3Nhg<503et^V+g8Feo zdy~d8(?rj%j)qNLs)(FN)>X8bK~oBUZiCUB8jB?{R0J?Iq*1$wtS3Ta6Y)S9w$-(# z9zhw2SI1sDyqXuUOkO>IKFU!Si^DLDTFraARghQDr><5%ng+R(_Q^XoCtiK_Wn9{a zu%Agq1;dagRy=#RePRAFd_FUhsK~lp1?zJ`2XHlTwVSZ;P-#zfE~et!^-uMiOa8Io z5U@20_Q4gSD*jZl@o{NLw3{8iQ+RLT?4e8>|Jns7^7R;?9K2#x@$GP`-(1$?X;frY zk0d~-_@3%CqA0yn^KyJEhBn0j({8?nMt822Agv&m>umiYfjEf1Xxvq=KnI;*2k{sn=AHgxV z^T~5EO@^La^b?*&cwO7=(fQ&D`l-gekJxS54k20{->=M5@XVh|tv{YK026gsc|hK! zeVRhs6OLlKPfqYe{%&zoiRa4kNf{uT+s2KIYscSDGmS&$NtSv2YYKC$Glqb7Ar{#D zgIn^`7rDl2#%)JaR2KEkBzk%|uI<}5Zp1g%dB&TuorL=y*xfeVrqPZx=uFha1k)Hi z!{{c&{nU(-BBdYdRhp9Y!cS53dL4f!;8QOHF0N1}9n}9q33+ z?U{!W){}lkm@s(9N_$#M$ZCxot60o)iSaBzEiZ4vHKApz?vxiBKTVQ91 zoTKpMNl0AFEN6}2TkPlLldx)IzG$=BYl+n*YENyDwq)+i!PRRhsp*O9C%D5iw{?CL z*lFIINFKnQcN(6idG8_(Sm(m+Y9^VmT_2i??%$35RqLd69*!XpE4tDHI&x`4QOp+W zOuk+bJ{efyRLB_2R4$Ur;7(H;XJ@1N1M2S z%YJk=1MYchoS!D$ZJW~Fc6M;(tqXPSBsppt^tERnM%~nLr>eNY<&{S^@Uf@3UFXGo zZ#Nlqa#@R3(_y(qhU8{-o513-eHYW$+%72=2-3aRGB}M*+9bOqWE_Q$X_KznE%p(C z9V=_oV+VMOY1ct{J}qh&9|hL>_)F5BXNgAjNc$kBOFrQ;lxO*5$wA3M$H(oOgr?*-lLo=XBbMh7q-b&Fv5xChPXR?_nW=b$^9TO7| zyE&D^Ja#yl^E8iLdRVmQwCVh8c9Re}IfSq0?%Cddwe%=JB5Ju~wOt>Wie6#v z=urD8=Tie*SaDm16I2GN|4YdY$dxFAS^qa=GP0PY|D#I7G3=UJdKgOfS}?}RgYxWiQC~juRuPqcf{lt`(a?O zgPRJuWy)Q>B96MO_3B6`N=MCQ&3@XFxRraJ&u<}^ym1Pdxh#)Hxa#8L@E1dO&U8|0 zJz$n}-)Pqcm#T6I4^t$7a<`4p{2RV%4BH*y#LT=k!m&J3=dO*Q472toUt&J0Yqdkb zMQhm8<$tl&*`Cwte$laxrLI~#fwG)p8p8+q&SGcUq4-X|@29f2c<$)nRL1f1X)?h0Urp5Dk}GI z%VJ@FQ$e}sg89J9&ol`BZ#>hW_JS1fgEwdG>`aN@+0rN8tIImpl=8Q@0{mIqmA5B# zaJT4|S6pxmV7R_`ntW5(>WfX@DO`?=7j^(Q{J3#iC-VR^Zzx*#C3u6AjB+9I25CDr zJ`s~fsaW7nXQ^W>S5{MQ@gD+a=_5&X)w0WA$HUA%k}B9&FFXOfe2!wBD_H8jk~Rwe zP++4#76Z|8trYrGX^WKtw_8{}$x1=kBj9t3odQ4CE+d35yZY|pK8B#Bv!C~PwNbce z2=&`Q{_(I>iCcFxQo{b;X)oF(Zv5j(EG}vNqJzLakBptMr6=MKVy_8a;PTpMon-S% zcOp;n=}KAVclWmNS?K_`Dj%d{HeqiBcaoUr!M9RY8q^a$x8*yIZ`HV4QF|lPxLZMc zql+2viv1@B>nXb}?D~S-e`01kllPwxLE~~+w-+DAx3fvjX7m8>bi;Z501~FOZO$p% zV^Xsja~|OrmXMen!iq&&t+}<6pWBn6y}?>|0>_@ggpGe2FgCFAEemeTy^OHcb3e%B zanWU&`Iq94Rkm>ID+6NwYM_O?20MR}N`fxB3EE}5E*k+%zQ)Z@4iuQZ@`Ebc|13KS zh~%eqx_rgE@l(p#15p{Uxvcj~G<@42cTD28px;+xPPK~UCf*Z@?)S9a?rF7GJc;wF zOAex*W=GTM=qQ%N!&Ga9_2y+SHT(qa@*8Pu#vSG1cF(FE4?A1h*=$v?4aX#uGSYTw zQ)A^LRvRC;baxzi)?bGOHR-U_YhPFK?aHoxbBV2)0h^jjq;Rj|d(wBxan26kDW-9~ z%=P`|!@wu%F@QVoSXEi=aH`*2)*~O_Xnj93O>;>b`$N-A(lt+9K7x8Ae-Cndpu6_> zAY;4O%WYVI(5kZA`agwjh{4%_+I#~>+w#(knRnveAaB=&koyi_52LWBpsR;3EY1Q z79~FryswPv32|JU*r6w!d2<|Y@gKz3>O2XO0bJqdIfy^y@<29BnhlfU!+!o>iSr~{ zj{{;|HUM7%0;{=fGx5r)j>;|DdhQ>9mb8WWMsGS0#?j1V#Q}Y?ICPv(QKfYUv3^qO z!{J0koo`Pv$4E_W8$)<1_FZk?Iyk(0=Vt$q>1=VrPG^@9jnTdB`j3hJ?dZHi9j`)g zhcwKcah{Jl%|{+Jo`6pgoP(1~gRW?+O`-i!elHdnq7>qz$<)krvLbElge`B&PBUxlwo8n{tvR@^L5^YW=)9T#oD9aI`*PTq z$@K`TK6|J>v7gBw6K9!vtZA_#fR^% zOt(Kc%6q4GI&@lpK8=njq;^KX^rt=&ntG&S&rxpn8(r1bLoMacA%5r zdOBo|j+V&4RUqaTpiA(5v^dTXqHATWjs(gk4C}V-jbkGsEYL)y8>AQJmE2Iu%Hc zMbSbE80SGA+_-6A$MzvuQm?`bT;*c5Yx8EaEQpk$tAdO1Ae|^1jmL3=DKe)3R@jd7gcG{EDe`)@;IqGRvshw8sHXVft<=^kb}U~1f>rh&+boEhTl8UX3r4ZjzIbV zd*~Eq-LX)P++k>!ZQKa8AO=!wSi`|{&3c5-k0T;L-Bkf`>HgS>&&pb{J^#o3u4PlfvsaL*xGB{a5*xCtK1 zripU#o=Ngbo^>g%MOhp5c^mGVa9%_*-9;OV`ET@xD;*B^Y5mksIF2$f{ z5j0er-w!Niek_+j%Esr+k7*^uEw7u*kBUEXFF{5ksvNR+)Hr= zEtpa=Bc@wiTu`DU4Q8tDzK(msM4b0zVxs&NrenCL`JOy7&@(QlK777m&*yHw_b~7+ zNbBL`I1Uu@tBDO>;__ODrTXoLT{K0ZLyVefpT=?;yZGcC+7{C!nwlBDRpDxh%c{hb zAnKC8eCa4h)$?)ST@1P0ABbi7tPF>w2&IOSFua$iw!|4&>(o4(>t3j2fJn=7p}lA7ceF)9E-x(2#lwS@tbcCR|B|LtflzCTAT4(oSZHW zP%w6J(V5**l554*b*fK=dp_Nh9LPN!l;3B{t=sdI&Z>lG5ru6Lu+^d2D>lz|SkoTb zlZ-(f07(M|ocUwu!#XT7NOY6O42mkw2H@*T17{K%1ry&Ty#j104{&oaRTd3pnG*}d z!vQ~zQWsvF%cTuF{&We^9GBs^1%nsfuXL(s1Al)PF8PehI^Vd<0~9`t88|9O4aK8H1yG#qGo&E`(U0cRa0h z8l)%aqLGO!49pmNB*xe@Vq9j6QR-X@VH&)E0VmhD3YClZ_AjAtZJDHRaj9rWNqhct;V=+8ii6xIzf^2e_VM=-V5`idA<%)NOP{CkHWZ*XRlbD>anCADy-)2 zh8~Jf%T?Wu17Aa2_d_i|J?m22lW;OjIvI>B`Z%@-VZB#sIS2z*)#<<~oaC6%n)7-F z^SYGpATZa_8W7h8d#~T}*MCIDst#{bc%R7U+Y}xy zv7e0g5*aHzhk>UtbRevpHhHZdr~bKYTcL|4BK=Sj?sCO}064iu55n~}Q04i^ow#oR z8;<03zK-t|Bhi$w{IlnIVvjB5W>UOEm!BMN+`5ZnFSkAI<{sx5 zx)Bf*tx*-s=Xo}h^dXkDDc{%eSp(tPyp=?fvfI%P*98WyLY>WE7szNluhS}AH_Q8E zR_%HWcuo@vv2-qh(bhkRvu#B`DYyQtbE8uFunil<8SrF{Z~$7cF->F-o%1+cvvYGz zlVm{hz@SFRsO80{RF#HY^)T+64EaT@sd&X-N`7f^E5Fc6hY9C#+&Auv#7Lb=3sPP& zmYRQV;)dR+FPe3d$ww=0Mxh^-rgf^yn+cDfUeeTaxtgGotxYr}NWrM*CxDsj_PQ#k z+be%8E|d*U0F#^_8x|{G>(yzzDXl;2Qfuj4Xi$CaIpC}hWaC(l#GUuHZ{Ri+#cj}b z_GjZ{^oK>ckVYmG(mD=GNVwnxUC`PcbSp4Gk4CfvOqd`H?vK(jZZJ+G9RQ2KQd;d`4U-(CzqLrm(-om4ut0G7w+TaiS)qUc+*vIUZjQe_L3b zOhN$2WYppsc)76169#2aW(8pv#fxmxd{OySSsUpdHZheNi=F6e&46itGT@5Ce>Jsd zIW$4Nl+cLrTHlw;^L&MQJ}?*PYa?RAiPv^2#dEricFM1}M$)=|Jt-HJ7Oc3gmMsG2 z*+fr%e9WaX?{w7wO?@&E=A6uqwk|L*BTr?4MU$#T6)8C0m-Sn z*$v*sfN3_jF;^03`E+X6Zx&%amD>)RgibYcFw30{EBp9}kGJKwyH%!lqQ@(Ca^V6*$c>(rs*y%3AZq21Xf)j-A@`G3yY4Rmtw4#!4+S86Ijm^GaF!DbuX`WSL<)LdKkR7e7w?#7p{G+Oc5Qw7pmd+aRs4L0&nr;%p+kswhBPu2Y6+Am7DibJ znRjfZbP})7TV-At`q6?MBA-)m^*LBrfke=z4U><2Ftb=7O*^9#<8h3xD!tekkimhxU#6)n9s43(~vpe>Nv=u8TEMtkF$+&MEq85d;=S>RkSri z)^&!#I0o^I{m9}xp4?Am;QN}oAmdf045ikHFPXH~u4K9{KJKZV7=%R8z){?r?UCj5 z*fY=eJU=G3f_(z$j5#_|(v11*c$iD`X!!CA(Oxb*SDQA@Rr7Y4B`hxCDT?++g`_l= zuhV0|W5__Gfp|PX=&O&h5;D-kz&RUzl9s^b_D0WjTS|xAy%N( z^hkB7==V78=VA_pWww}_L{*y>mKUEx4P1o{B^V6FmO>#G8CahHR)a3Wdd%!2(~IrD z(^ydnx;O#s%62%Oi)EwatRrn05aZYC)A!}Zyo&U)YT}K>eLf6gt1%WV!k|O{p#P%L4f%h_0Sa;jM6qsmFSPZlI z;1q3CtvZp~D|k_D>$sVpH3;7$n0=9W3KatQI_1t+Wb!7pNJ7!>MYx|&pQzn-qzJ`3 zukXdTTG#620I6{Zm?*Ep+k(f_(wSV)PusIcW65A3 z1`fqP@`|~VXE`dotAK1)Fl?O1>t+0LvI{<jBO%K3HHjpp>M*p)kD+_k13{>ZHxX zsagy?8*xuQy-2vA_g>r4$@XOVKr#*1LA!UL$sVP{i1>n*AVRfcLW7J!X!1C>(LLYy zD<)Cp;N(|o9fk|Ek80Z;!?=r;(TP|F$Zel2h=f74PX@88`gt$%X~N#UXKSUTL-N@^*Ol5oy`=vG!r%-bs^rlf9mp0Xgax`d@=&=NoIpez6g# z0+=f;YupG-GY^EQ>v*nDr@p`FDme6l!XO^Z!Q~ej`$}Gbyj7dujCdFabn@kXR$dp)o%N^@kn&dT z`C;5!)+PC>v)8tDqBXbcl42D)kN4xi%h!B6r_YAeaUI8Sds1Le-T!G|rM)A>G`-fR zlZ;qu|2pNb+WYf#Pkwolg0XtV<>ZrReOW$vc65RLSY7fM*uPBJG4HCB?VA≧jaH z+B-B;b^0yfBA!S!>a{+d+S!38@lvF=uF26&uB;%Wi(4epC4`#CMI@ zL&yEr;@)fCPJOnk#2z}~JJ)vmoY9U;2`{XLuJ>cmn+CjXILHkoj`eQj$NL9m4mWyS z4`5!jp^tcXF|b|)eDFb_hUTi*ZT{?OGD^>@K>4x-xj)AVRB~xN?*I-M6)m*jKJQ1Z zLb8y9-vpB%HNLZ4?cOiLkJ^S+z&)S)sqxcb?ng^R$?bf#Y5D4%lo8dgT)l#~9I{~x z!%^udj*jE=MVtM>vftHydf6_!ns!d*o`%}677}<{HJx6*iTZQb$ zHf#jGMwsGEWUx9>fjTd>#((i-zYkQ6F?ivFbvbQnmYaf1^|uZ8vn4*U``SBQl)|{o z5hHi;0#x}n-i7-@-5@;LPLpo1yFe!8!l%W&hp$bLhuyH&%r!}7`^F8|0=w9c8seKh zz0#%A__26EkHvD>ux7H%wi{Q&gbU0r*%gaQ_fb>!r|pDko3b|uB+%R8Uo%u_&?a>4 zP`N_7H))ddCJ8DQ4Iw7Fh~d6T%782`zCxsyLbyYc^uU8W^7tUif7f;16< zeHuwpSl8x57CE(r!%BDnqdhP&I_k#k99)fRice*Mr;&JF-o%yTB)Q88r}fO8FYi_d zOHiIT6p`H5W;M7q%wj(yPMzRvp7TQta-(gUwly;OH5q4e=)|BSD1qKWWq{jTI+0gF z6_&^R7@xd>7TMw<)nQ?UD4gS9t^0tE*d5w3c>HX}-v1b+&Hegv`x#ps%57KwLCA%| zYXB6p%6mCU(;8N0gqKHxCOt}|$D-GZjbgNkikd4Li{V&Oz7-4SoP>$Aun&!XOlW$X zOhkzCA$QQYE5s2_D`py2ZT1>`H&S72a^dQ z`~u&e8cwF;aJdgfEtU+#so-Au=&2Pa*cJ~?Ui^~Z1!4P@8k>N0S>%%6=`a@^#a>K!bs0;; zS|fZQkdBz66!{J_vY7cZO@0S!k!UyvS27OiS-*qdxPs)0rRO%^KrD=*#dJx0khg-S zx07#GInon;>_;Lg48o($CBHiWpT#A=LmSiOnjXaGH8pI$xT|!i(x2{-9bEIv`|e49 zlifTVdT8BPj@|T!haX&g!<*QRTONPxs(}scH9z^~```MG!z}f-jsJ3c^Y_>_55NDS z+keE^x+Q;k-7B8`1e^7Z8$bQ7wsXtHebVxc-1EpqHwFL5GRMvv+j{V;Y~TLwhM&Fc z5f&S{dHaL6Zf4=m+QwVsA7oc8KmEezH!NoxzSe$w=gMc;`G;CQJ@cD2zTYmKc+JyC z-&}Ti|CaCH>bV+p^?$AZo}}`s{?4Rxa~2hESf3?aA)kwd%jECY@Uiiu^b4z2_~4tK z?#6ZW7Dn0BR61l&hes&gYK4@x-Nocfx1n7c=65O`AMGUgKXgr3c~w5v@TF4KEO(qk zDHayP$z;Ep6s{F9nA@;OIx1h^uij19dyMdB^4V=@jjx_1y|dTR5*Ye%g~RE>Z>6hB zJuCeGTSInB4~Jf@5Q*2;%)q>Q7UtCTm`^v>%)xA$=F%tSGTQz7H0pJC`+hD%MeoN2 zEcO1RfHYURYc?ap|FS!k^@#Qn6QO%3h+;VO6vk!o46^6dYBm8n3TH~u{ zh27wHs{Ot%+tY2R;#oqK{{Qyy=rH*@hjr} zQ1Y{4;g7#X*SCGe!XojEdaBa+tngPW^!@Rkh1dV=vU{u{BP}~Fx1lw@dKRgm{y&&_ z*IRe|^itm^E)8F^^y7`bx1@ge*ahEA`QCT`l~2Cm-1~j+e0cZYfA8O0eD8QqI`g3g zzxUnNckVwOJGjPo`_dz!SAB4<@!g>x-}tBXL%V%4oUZ!!S>^Meq(1bcruF-LZbNH) z`E1mWl-~`x$MUSca|*5Toxb<_d$sFdm51HHIMhmqs{Cy8N6sZmG{RMaE*ZO($aAM- zXpJwQRr=KqeaA%(l@68r}&-1Zw-A?PIntx<6EDrMW5`ohj~`j3Vm+%7gPL>EhRBC z_2FuT)zS;7bk+F5KAIBkQ0cJB^LK^cO0Sdj9ZFwOW~kDgH2xKtFHD+;sPBr5rz-tw zhsHeon8>M8&kDEiAvs>D(8_TIHp-TUYvVW?uT>L7YHB{;QK1{Rhg|Du3$hbM6 z$|WDNVR7#^%*U+EU8UzCMtUEh>DZOO@ma$kK62)pR?e8~a~oRY%V$-3)$divwERP3fXLMZ?JF`8t-?D1lbh_`3>8A`s&-0z8ly&`M&qRf4H^og#_!nrSMp53oJldZq^pD+9UKksI}zdPlQ+n0n@C}KmN|2_>HANr9Iep%9= z+t34Uyc4gc{wXaXbr(m4IF*;g!7a^$~?`thmI zIuEJvv%>Ebs&;Y;t?8)mS(5ReDjll)eE%->W-1&CZvT&`?t0$mHdOH}VWs58V(Ij4 znt0n|9XIz@D>UlIX*`(f?~)#imCy703q%Q6l|rL_K2NKD*Dm*|@RO3Ss?a*VTAx)s zOK7BTp{q&sI@RA*{i}5+6>gXHW_?!gi-kLn@`y}^3V*p_x$=VB?-dTW-uK2r0~Y?-|)&Kckk?T z8x~2&z%Ti(l5ZxJr^x)%_|6(%@$rXf%i-k9ZNF9DO-`Zk4STbAHtc?__PrO$-;0Gs z#^b_Vs`oUBue+7=)OW`Own^#8cCaEZcb&}|Up=z}hxsjg?Wr$&`nxZC)(Ep5;=S9@ z8ecxEe98?Cx^$x3GJjV%e82U*=C`+wWhx!A4<1!n6ohW)`RcoZ$fgJO56Afv3$w!T zV6%938(QPbXP$`7AK!!B{4(^w-;(mF3co?aIqYVSi^zuFS-qE`P103)#T1`Vb}+Ov z6qmstWxsNIW;_L-Lf z9;;HQ+QE06rgzPMFv5rBv)j-bUp^b@Tj|8@I->f{8ecy5rN8>y=K} ze(!yKZo?w!DExm5OV@z!F3E2z9G1@2`>*{oLR`|RR;Umfqbc&x@{hp-qzw(Lh2?`pl~Eo{x}-ZlE>tH#-?5B>gAf4Sj(tn=|l zKlz>okFb_K-(9-tbNktaJ1>Z)x1`v@dmgy=^p}6g_rmP6AK&=Oe&3^av*3S!rLEkM z?b-Op+a~JHVER*U?Ya1g8(H|gN0P6;{WUC*-4b8EcL{sN2U5FNg#MB3{NbyYeK$Uv zZCnxVjUBj}wQl+89ltuIh0T8PwvohF?7{p@DAU=Es-a%bFW5doucqt*mZ$&5rYqJymvivdVk1=xPJ6=kK$fvYv-{ zJzvbW@p|rIn`J%s@p|rO9lV}D%og!_?(#h=>bcyI4Lbd`_TN1<|AEt3=;fcf>2qKEA{+U7y#8S7A$HBJ!4*Z$jG^R|z^;qPAD!3LgK^}@UB`&r8q54`Ep$U!#y?v4Jg%dRRr zJX!f}yZL|a>iJ|VyY~FQ_V4|dJ?!P*`rXK%{dciFBe%Y)=AT~4uDq{*-^bp$f^Av$ zv6L8rT){?ex$qZT&WW;X*4+Emr$6;ecI8i7KJe!IRs6`Xy}N*1`Rs?|q!bpTF!^ zufF>WZ1i*geaga`PBzjO>e+E$H@kA@wRi4$?>x5dlJ{Spe)K2o%w5m#d}#0sWrrs# z-{AA9544v;mP99f6I4T#=*Y!MZbRIhu95$eIHId zv+MEIeJ@*l?wz0RxxTN*|MvfP{Y`WGx-b81VDERj`&JCLU-jnKf3I(8^N+4*`|?A5 zv(o-|Z(j4l`p1?%|JHdAK3Z&kUF`k(PbR)`$<|-~-tf;O*W1*-PqqKW_py)vY2lY{ z53*$1BJtI3^t~V$>{R?t`DAyiAKO)y7 z77od%9(b@7}k+(BZ%9wX9a?%f#1teLf2w<*%3~e(C$v z-uhoW`^k4IJ65ed(qz2Rj$t>|4CH z=Rdx?^lqiUJ1UaR>w8rB#d1!Kp*OKS`@SRhzr9@IdWS5(vNwL>O0h3a+B;kGQ@D+G zlJWXJ|Au{E9=m@1m*$C$T|T+4VU+jh9S12#LocQFSE_cBVc(LAe)Z^;4>zm&Fus52 zTmpWcDwppWv5wUD>ot!(xpbga)gzPTQaF7w-uk!vA~)x*{`}R0243kuO8KEUD)mkxHsU`i=uFWs-v8P7P5HFQin?X1#4jv;nBS~_ z_zUenx%1X$-#?LM>(Ql7vEG(L@|JfGR2aI@64~#$mg^zam zv_pH@XIl@9?CE9yrO#G))!1PaP$SuL^%0*YGU`=7hKdGqonZ<0)!R+(SZ^X_~1 z-E;1_=bn4+x#!+jzjS$?L;Q*X3h-Cx4hEzCM4ax@vk^$p^;GW?y&-2ZnUt8;&>-AJuxohUs z&aJNTx_$ndxpV#Vi4}z%fp{Vk;}yZXh1D7-#2wbE7iiVh3oGX?tf~YN)pHhVK5rm_ zcG1wBVRs1Z@oV8o!nILw(dX3?k@Op`WZ2gk^?AT6{z7v^OLVvs8k)Dg-51k9bgT@e zfx%v%mhibiDdq7|@ab>B`L(M~6nZK}RJ~hq!g<9C-j#dL@$Q5fb%sg$=Ps=2#V`Z?LrMLhX`i!j&fGqDZ%_MxIagV^aBeNST{`yF zye*TVXw2sk(rlFE^2*uO>B5#SWG3Mv6c8>;6x3TR#bp+>r=i`mK`_Uv4*fu26eyy3 z?!q~>{VFn@-r|;|Pg|U9*R)y<`n?)j-c(#%^T#64sKH3MeGzFaeq|^Hx@BJF{HiLh zBcNt#Dr>-q^0xKa}p$Cfo!FymfMP`%7jJC=`kLlf#6jxe153a_fLL1yM zO{>ws?wYv^=R$o;t-U_3mDSi*pzjQ>YOtS%VaI5g7*#Z$%E6KD(O67&hq6`p*qsaq zlpR6oB1#9LIB`9S+TBGXB@+12^QlXHaj48FH%c(zM!A`ifOW#NP@WO{9FAR0NRBp) zd-PP2Pi2mMPIlv=W`fKT2EDO6H5sJTh)IlogA#1;8;;b_7-qF2nIaLfDHV zsm*1X`R(-;p&BIc16`wcIvkJD^(ayVZZat-mEM*_Q@%-#MpRXVD4!LL$JeiF(5O5z z-gGV!OS#43OGsnfu3aVH_JBsmNKdrG4QP}xE4t`8{jBIx&$7h(Y&Xg&0>43ZHMN}) zH*aqfPsV$F?J=J(?yC0%eqo8uXG88j6Gy9lX+f5zyu2O6==a-DYJr$X@$$2ksfnCFeEub;Vf^(W<;&rUF9PjQ z@#OgqRAsbbPDwS(mM@dkL==iB9@l~a2swEQ4n$u&E)Y&&J|8pAhe3hghbeO?B|^Q% z+kW>qg-5o4>~H@^9+FY|^qaVrJ>PhL!@J;F35=6u%pEM7$SIBhRdCm$AZraMja{lv@why0%K$5ACtYCT?SKyF;V5 zw350-+FY1_WQl0f5Sc03%#OFRPwd@dpqu6xM!E-M_sm}#g@upa4F@9G+6GI9Cp&!F zCU-2PTSQt(ViR0UoO(Ojt?i&|nW(uwzP`{zb%X64Npx^4)L1vGHYuniFC%fmx-H7# z4{b|Aq+#8XVIPEb8^-iX^SeE8E^*Hv$0cS`yc|nfd#-i9e&sPc*C2;%hZm>dx)A+4 z5cWjrMI)`GC(Pp|+4k*JLHw+AMlml-t6$ip@jMF8UZjfrA(xlT99$dm41_1Mmj`0L zvY0POPHT)Qu>|I4i7q2cyl|Rp5}hMUe!R3DwB>thqH*EIPNS3RlF63Lub-pU%Q=so z99h|q+3MsYn>r$iNW2Tiybn4KvzYH}+ z{pHI#qnOiT@qj$qLT1UguLZ(dedFR_Fyavl7UaVA$B=;}9SbgWU%24Oal~n{>o z^EbtRQXXHSxmJFg8!l{d-&jX0dCaR9`K)Aq_7aq%wWQ`$rKw3Mtq1Umx;>udK`+<1 zc6E?6zDgJi{Zw@imqt4pdEaczOy{&!C<Q(?~B8!#I0v zZPhGg?~f0mxMCOu@QNz+WXnTNYacQ=&(Mu@4+s`=e48+2xMPq{!l%`1G&<5Gey+I?0u62m{`21LODFWkvgI>u*on@xd42d!HL zcyp>T>$Mi(&X0$paStx=Gtxn_U>>s$3kf;3>bqslAdsG5BrcpKC_hVn{b@S#7QtT@l&aK7rWcPyUW}D&RJ3%&BFXj+&EpP7qFop{W08ya>N3kH~^Apiz zhc`PqiRbjQ;-`9+CGJ08k8(!y6*^DY6=~!4iLp&H_36XWan+d8s9{MZAefxqhcQ=> zW2bDBx6cPY)rEdQQI_wA(vx zpqv6y{&H+I;Kbt!_f+-NaQ zQoXGBbu#7m#Skh316EFhV-b*#rKf6|PPZj1+#bHXq3nitFC{#3t)&vzc04;QRE=EL z_$RlJ??Vk|Fy=O4#sY;!`3J<8-s>svEk#+ya`jxze~dI+$(Ws;IL9!InCwJDkJhb3 zntX68(XLLif4@HlG#AD?BEfKgukzW^TcqZDc+aYxr}D8c=EF3|gK#yEk8E0ZtZXGY zG4RWluHPbWfxj!@3wrr`M!E)KyOt`t$*UxM9y|;z5Z54$NsRtoDMOZU;}15>UvCCH zY=c-wGtywymh_x{R(w&gL{Jml-mPSiHo}1@f=CwyFnogAKR^)!-PD~w# z#`R8zyN$;bWb4<;+4>d8&Q=Egxe9p;E{0%n2}o~?krwsuO9m?Ixvk5^ z)M(15hFJvhHYZ|9PhxGE`=PC5osV-(qH{ zyzoaNiaaZ=v38NioAFR|`$tRBw+U91}A|5DZ&5Y`2SM0-&b4p?thWu-|5tZaO{J~?+OCL3gGl2cbM^za@R_l5b!DxlH2Fq^06 zURb+Wfr;>u++M#GA`n9Do1?az5haJvY)QR>m0AdK6IvW`uoPh-_o`(pdve?e%*abpI6FN&>-fNzgS9CqmNpS&gm*=7^=u~514#vk(=L27X zn^aHlK4HZpJ6q=zZYLO&diLWZw^Qu&k8IoG6N$e>cFO&o)}KkXtoSpQ-a+(&!S!ug zzcTy2^NQaf9{Ig$I-iEeibscaa2J|2em8#r%mZhA|9pI7(|ml?8qh8H+vUhRViF*HD=rK#JYv9(S9W8|QQT&dz7>>-NCbTX zOn9@D^CNywbS2!$T&>{=x)Rvg6h~Bc?^V1k={oWj&~;d6kgAd<|09t$`wZ=LGN-A6 zPfj8+3ZxMcs5IB7B_3N|SU^BpAj4SG=(n;X`dU9Yx*j2N zSY?F0L;D=WY}XsWbcmM2IR&=#OS-1aLH03Hzp4Nbqa0?ke-Ah4QKJ!T^luw|fePP# z;F|;oxvOzS%KVgT97eoWwr9~f_%$>vU5YZy_8Z9ny-zH>J$!#~J53}P!#zYM=R$164qWWR|6N*DWuoI0EgtD=qYaj)Cvn(_ zxD(}}wwpR|k_U`oZy7S5g2+ZvCz`m6888gx#>mEULBG{}qq;%Hx1`a7k;b$nNNNTv0Q687aAw{gW`M}Re+>0^{7&+N`g$j!Xrm_49nOx)*=N5Yo=T`OIi&H8;=FF!2DfgOsOJh9Nt zS*`(Q@;4vJ{ms4baDHdmPRDLTZqdJ@{5?B4vYS(k;_v4z#nwn2jERUKiY+hj;(Gk zr2TS@nd5R!;(LcEAcv3TwAzG~e+qOnx(fuZEZgt+9%Se1;z4&Cy=f=kcDh^ZwJwf= z1HrUK@hoXOVT+&*p6%Skd5kkeEvh|-S<-T16KE+24a<7+NmGaq6epRh@s*G9gC1W` z+6%fyUR)WbvJGc! zCqByfbzIuYx}B{wHYMv>@B5N=+sQPV@VQO%!85m+*G#7xy5nRa_nLE+B1)S48GdYo z)Y`hVcmS3(LXSFxVQXbe+RQ_mBgsDJAtkkjOBu+UAt93NTAQVIE2g+C@YdNbW0 z(@SOAj&D+~W_m$aft!34eq5!?IL+_+>-$*9?F7R@MD}ZI9KRhu&2w|A2aQ4MC+jtf ze7j@TH7q_`?kFRDY#gg{Iqw_O-c-@f^+Y`%j1>*!(^dYDsN4XP4Gl*BN0VU@u$TXX zDutiKH=F#plW6Vjpwtnd%j}mKkdBaRe#(aAJ`~+oVW%TXH-kroA{HmBwGKO9UzI)% zi9$U-8jUnD*kl}m?EOfxO-uKI-hBAus^{VYKcoCu&HGeeu+p#UnOz@~xXbPYz9N5W z0JOtxH~t-)HvU;}6wi{j@=nl}k8Of7WIBy61JPSm$_K`6oy8RLzmoj5hA6q-fzzPD zj@~TwRRyE^ggUX`78m##d2Lmnk@AQYbNQ4v+jh2+ky8{O#145fu=ueo@J#A^f%Uaz zama!(G?brF2%lhO5$G7XK5~H1Ys;%7UpTE15O@$2j2vKcnnf`ETszbQN~7S;qZ!!6bEM z+kRx8j}Ku?R`o-mXADJ2ZSs2hHE#3BDzX0Ck8!)^8sOvSSGFCD=U3*$Evy0k>dWY9PJIX^miF{2ioaoPwvrHqMp|OGwC1W9_@a} z`g|JRxQ%MI1##b2?+noz-G8O6(b0-opuekhi=#2qDji?9o6FbjjH`5FJr3DT>va6! z`nVYUt@=$h-$M;Ahqc{nw?#L3y5Zy|A+ZIle-VeK~1 zIF^FB5VGrcwIS9NH}EskO7hs>Iq4~DP$r#8L`9}{x0Lc(Lp_grYsA6HI4p)fivT+w zd%F`dppWp&zPz9V*J@no*Lt>LTU^HS87F2nR8#SEgu zPCr}r8G2FvWc^Ovf;3+v;z!?$hsOS5*=|F(zPyOUiq6r=)mePmoTJ0L7fA_lTk@^9 z?Oitoc?)GkKXJ{-vw_&Wb7)-VlA3Wpg5`DuJ2^Ojc5mHY@L^OShL6o)$;eAwN#_g6 zT&A^C?1OG`>F;X#6_sIEN6UC8dXavHcqc1eH&w0^uT*5~8$-qG*{%tj#}xA#wd`-s z?I^b3A~?L|fjUOHvFdB|oPJict7mrnk+@kD~UK!qT%r$7rr&>DaxhN+i>GMtn8vw-SBd zmOQEtAC%H?z$fkXz~;LIKEI{$UEX-tk{^Ub{_OhIVDwJb`d(E-Za*{Y8KW;n%Gojv z^kc0Ep5$1s*xiBHET!CL;l*KFhc9IT8>|zf6VHxsc6?X$*oS%)bab`hC@J0|MtwDq zdd#7iC9>m}iqoN&(s|Le(MR`84(WdN<#$rMQ0#J!*3~Uzm-`=6b6O|p8s*3Q1;-u6 zvOJHjaDBUmQxL1EVXVfclgLj)Wd?$XLgibO+pyLfjbd)h&zw!*b1UR*#m`P&q&%!( z$V>Zf3#{~~8Xv9bQ_r%*y|M_n3ur&MmrfT=*F#pgjs4OJKepE+$d*3oqfx0` z3~AEBj}@(NT)GZ8vZZY|@^Ze2q4q%X<@6f~x1R(D7x)?bs3l));xdk39tj3$pB|UR zc3)T=mo6gU#bIh3PnNtnqZPT;d6zT>8tEH|4q?qS^GwafGR)r&zt4dIx@rX@s zSlQUTcFl5Eli^!RG(Hpm$KWs1SY4@(IHgsZCJplsoO!EGyp^9;3S(a+&YDfez6Sf{twHngjEgpTwF*6F&Rs_K1V?2S!^<6ts;M>m@CV zo0my$rOtV=19`}_#Qtf3P=L_k~vAEBJtd{!L*@8%WRkr9Y5&^bSVZDTZPnByK z-BA?^bkbmmwr^hDK;;shMUK4lI{*tKc-RqWqx)IVR#SoFf+(+*uA8-zO5&dqC2S!d zj<|qDCO6j8DT#>hiF9_Mw^I>19n@a=(G}o2zims0o$uv1j7eOsqASF(--{4|NAZEs z7Hp`hbjiKWc6_kKe{ zRB#i0=hYpSdzS3#YS;Ehr}i|W_lugRJUtw}F8AAz9L>+a$A@C1^xNUjU*E3p9kJr~ z8LR0$eMlQ@UE19vPw}E%K6LgT9W+kIL&k9&1?)4(1@szP1m|E!X>$-st*)?$TGc+= zaXo6iD}+xE$BnTElqZueD}t^7v1POq!HU+p27H0Z?F$CtWeo_1feip` zshyIJcvYO+%!8%l?kYtD$EA4D0~*G{URb)Uesx0=qNyl=06#M=R&7#Zv=w;N zfd19RKq!RIFT%`M+&7Mc`G^?^iSDJ#%r4*@ouZ>@Ks4~3RoT*zW~cBmZa0t?V`534 zU~)yX(`RGZK4(4w~@4ld^1 zU5JOGYcJ>;O=F>_V-EF3BzwtCf9W}r#=}(CR=t{v*7>my*Tpy!G7_t%%_IDoSzh~# zcb;)?l{`3$+AD&`5S@rqydVIQpuW6cs zx$5|U5se4%X==`-Ui`U$aE|bXqXY-rUelK1;CiqCpA`^;fN9{AZE`^oa2fTRbX)eq zZ&lZH{YKu)Y;{X7{dU0w&@pnoiz|A&y60C_AU=+`WIYy6U&@t01Rt~2hd&x^NXwIQ zS9PC)Yr;vIY$$P3`3k3oYqHPfG4Hl`?fSrRdW=F=_W1=Rz&|nO^F})P*`0C$9yjr` z<3V3?zodmsQabpzgkl$Gl1|{0A^LC-YU zaV~c-!L4i@d@3e^YQ(gsx34|-3)H-Z&qaxHkU*|(&wBAGHV~SIkt!7Nh{Fv*o1(K8 z*G06~nP$fpJhbXJvvs>bU!mt3A;T2eVG|JHr)Xff=JtM7_V&J=T#Yr_`(miq z@vQ*9;`J`lFUr)ml^yh1ITN?;vnQzbNY`3vrYq3uG!P5OMvd3R`ABakyLR>M+cwk< zRE|sW{cO-MUW^}n%Z*D8Aa=C$)sN;|j344_M&eLJJu;ZSvlAdYNo@Bq@}?CDJ_qN! zzU=#n9dC|RbMQWPGb)~R0Czr`CF^;Ojc>DQT_lL<6-F`yrKCRX{dj)r!5G`wI@ z!j1js_zIewp&9fJ&C?J+vWYLTD_WzVb#%}j^5Prj0=B0W;?Af*;&|_47EXv!7^3x? zb>n(8^{wi-u2Jk{+D?W}fLWG0EKAJ+`G`!Kl~2HoG;EPH1anBk3`-j19JD%(44oHS zK?nEWh$(0<`RLU?efV!md--p;L`$!Q@-mcw7cv861L;PU~EJxU)B3gTo>W2(+G|_QnAFim2qxh*AI?T_L>_$ zByrv!+-WFY9x9^n?gWm}Bp!UmAP(WQtMiD4CO6S$rL)TPamAoTQy<9V&KNo|BQ=_& zc+i6~$LRBGj5|o%(PGDkKIhe5HFweH)qGl_c(V)m3qw8^+;F+^^EO0q@Dj}#p%;Cf z2wN3jEG4E84y@wPA;dWS9-m51&7+Kd-V1hvrhM|ba_^BnfBNrl6$L9E>{0lnpUAE~ z`j1Z(tnlqs_@phEdwil`g>Rq2$1Sd*;HM~9;d>kSiaeXVY9q5<{p{p>#;Wvf%OqOz z!=1Ee0H>+?+Hl+#u%`Oi2e>YTn(-%nd|k+n25M9JNh`}fFZL}^X$D6c23wCi7VFa7 zFac8E)503og`5_c^f-HpE^YgGK~;qu?W}dqxCZ?*&Sb~)G9|w+EJBLg7&QmN#;8df z+!YNIKtloMZjCEjIBjNrTj|lG^|>1wlzh5r^A%o9ulZU?_ECj*3bGXv-sLOLrZ=*| zd%TV}ea_fejb`jj&56_f$mwSmQyXi*cet2P$C6=adsidAhau$9Oo!RF>1#f{WU2V> z5v@*b!YsN&6UDWS2f5=b)#j+B@=c1crn$J`Q zJgt2OJff*|KGlLIKKHNAe(vA@u^?^ixsU;;oFC{bjCOpn)0chEzpK^S4DU&*ZB~Ge z0(T+=_d2fZ+oq7Op=DlkU$Zz7q96sF!|2gyiA=8cLwVuY6SN!omNEB3P*%XNg|Q?I zV_;*zix$LUJk7B{j9vggteVrM=xsu(2;VP-D=RA-s;}>t#?$3Fq%4?}Nk{$4hg0}r z)#xjMC85wv>;dNOCL#>P0y`$lZQQSqDj8RHGsJY|uv__n;&7<9Z&6UtO!38Yc+9R>&} z#hU_as;#29Hm{FG&GwMn%sK@Eo30d6L?>j6G~xi?$M^cK)p5cj*nvcU%1 zUXz>QPa`jxzFUgy7~U*;-`)zGqj=1hvQT=?Mb5Obi9WP`2iY)gL+&ejN}0uP`i)v}OI%Qnz5LC$yi)=#;dJXm^Wn%0ty zOUWFMaS<6bC>hv}>%+r1dNc-k;m!g+BH?cDb}`#*c5-^g8a}u|2zU^aaz&7~1;#Rt zl7>EhQ7VGhx#XtY7kud#FY-x)qWMnHRuuEN!ZHSbu)I4NZHY-bKS+=8%a4}w#^k)y z!ur={6b(B;!`N8hBG>v@1nWqMJ|vC}o@eu$1EFZpR|bzfK5|2T1Jj2ow35X!cL(3( zx{ja!r&TRjFxTiWxUdIwjNM2JT(DkTDmuWPwqg|rR3QvOtA03nwLaj}yo(}zcqk*) zUGZiYu6c}4b#7v7Y-4GMpbUcU7)6_l)dqTrzg|X%tw-@GDC(p{o07GCxW-%#A6(+$yY$GG zZoAmshIMN1IOnO!hpva+LH3miDFX6vTx|kT+Z!t=3)%1Z`l3(cB^W zAK3BOPRGt$))|F_;D{>N0kEf0w2%f7wL%j>TG@(YWJYh*Y3H~V4?jSv5Ox5hm`{cW zOViO-b^r?Jq3ewtwc>}1QloS|DxM7%fBh01_fY1i=m0$c41-YITC>{fQ&$nu$m49Q zVMAm`V_$0&C-+*bQ8q(0*Xt^Bkub?Na!tUsF`h_HKWt@v(DM)KmWa!PuqWvldLvC! zkQhVr6r8W%q1a)h2itbXsCkbp5)mEPz070e^bfu%o@l_QkHPKkP{@rN_zjkZ9E`!P z63{UUGEYk^GF;u3uD*OsH4XBdJl>tf#5pw|Cq3Cah@E($cvXq(F|dK*h7Kwtc(8n$ znb`)eKMMhtQ0C&B%3@g7X{iM*db{DPTgG!ih~`YOadx^e7wyJ?U&RK6lEFlPHps>F z03jmJwjJ&0JYBbo$*-d(Hdq|uYMj3AZiq%AHgfk5?Q7{3OT_6>ZM*_0qmD4{)1-`< z_*$4-pMa~0a7kHHPP_vqYf?Weo}A5Tk#@Q~f@ZL^I>Fk4$1b1g$r&_VIdLHBxJTZZ@dEa#@0f9$`>EadI5%xS08L*^Q!q@qBOVG+#L0O9%qI3NHz_$EUis{I}UJaqLp-{SsDl+`;WT^|6CX-$By$k_4TuC23O6A&vjdi%Fhz4>}cRqoagOLlI z4A3!cN)|KuKYyIk^-h0xB4MCjv zAU@G*@L#I>Zv)Oz62I8_V&86k(J;f72EKh0SW|7V9oOl;37qbeBi}?#noYxv7t_)& z_bt+CLSC(e&xDP!BdvFWHnCR$A8N+6om|+-^t5_kFqlLzwjnCaYFyY!c%cj;)xiLF ziX%PHezZ!hmAS*{EjSCslOAj!d}(mmz`9er1>qJ*EvKosNJWAUB|AO1E*7@8a!KQk zpp*DyH9nouVsJUbyDQ??$L5cZ6Nj+VQ9cO`JBkyCrN=3UT#a#k043dCu4ya%y>C-s z3nz`#w;vSxN{L1s0YqQ0P^5sP2!Z3rx~3N2DGmaqHj4-kv9T3vF`ImNyHcBh(^*Qe zFDeLYWutGVwZ&bIdRg(e4R(jvQH2&%Cz+A8g-NH(qt2n+&uaX zG*Vr5Ir3Wf0FGQQs>1Cer0wc5UKJblCrHZhN-w?*MV*coL3#>%?@ECV)N6$1$a8PQ z^@U` zV%%n#WeOc+Zskd0D-F6=x}@klZQlzT$55aH*_bYTR~BjFsU2Sn`;e2q=-h3llLi!J z$Wf1nZI*zk8>jy4!@)uPl;n;sZwzPsVla^P;Pd%XEl}<&=b8*bsT6ie=Py|WS%^HM z;lK=1r5lq$3TmRmw%{2MElUSjaYGI2lAk01B4D3kXe;ShuT^Lr>zR>NrCL=v4ZyPB zt#@GShfA7!*gl^O`#Ph1Ify!xX847DK5x)RAKGyF5PH*&eFI_s{cRAG@VQVAk=-(1 z8v+;I!Bi%cYsiPy$$&SBZK*Dcd~LCa8;H}<^4&w}1zP5lW1)dOEtM~YR_sQ~RGuMU zmgQMg!+DtDpGnvLE!+vdeGW^ZjpKx{bx2zVL!gyKZFXop4(ezn19tYmc0M{-;PVX%VN)$KXiZREiCl=2UeVW z%&(aDynof+`(%Kv{nfc&xo<{@IdAp6b;;hpu<280es%r6i~3z(|5x%S-?aJ>wsEOz zZ}p0GEV2Ia3znVqNw(qMnJu6G<@+o+>b}BTUpt$5j=ug)ZRyjjWn=eWg25eZ(GS}{ zdsaz=O>^)3XX2dxqIIzUwE7O0Jp1o>_QWl1e`E38$9Amjewc08SX21Isn4=t>opAz zUbmcitMZDj3w@KFHS-fE>|ZjIE%`;o%~iACW5;bRy=TNP9nLo=bzS;y&(-~HVD_Je zw|m|z_udivCA+5C^VEWlB-`@WJr7R1>@#fhidSDet9}W)^!Zo5{<-V7vFPWQ{?E-N zzh>v|`TB`BKf~C9qyBmMdGCLZjeKPDJvWpe({DZ}?oNFAq(81=S4e)*F4RiHuM6`2u}$89%0=nvbaT6#3i?)pIkPA@iG| z`TfDBU+nB5OzcpH4}Rv|8vJ-=P@f*g@IUG$@3RV?bm;9R(>*enpyyh~GpPLL`|7#6 zua~FF&lP;v+e(D6LmYBu;y*R-9w=n8ATyM=4;aWq{{bW5KNOLf@Bg7}=y$cvd{gOu z7j%fcpz1eJsH(}X(fB31qDR2wUJliN>w^)BQ~44D!BWjq~@9((f_nUU5f<>b@O(;VbmJ$!UhK$@?}?(J@e{& z75r?sNM9~iDcR<2BCYtQ?yIzVuI?XT$ce*$S+~d2e*SYRsM^Wg4k~Ta4o>-8(J@e{ z+T%b$MW-2`y04)5xm{YlH{8(qBiWAz2#1?~g`a8SNN3mlxqHxAK#yQ42CO9TK4tIRQG0Aa+<4DJ3$CU0o zj_@G(kF69$3>2y=IG?1MWKE3@ACWTtB)^@y-_Nuv|33xl{Oc#5)O(6g4~*A(=-L*J zKAXStfEi9Zwwu3ih7)$}<@bje5{`r6=X_h*QUip{aqamf@Bi#t=UbnAy#DmBPISKQ zEBeEqPW}$Ty?NueJAZxJ9g{A8VFiDF;iC3lX_fC)X&acJDu1YI)!QG z(4o3-2Q$g_0kUOOJ%$^yNrD0$D&J=&C<$gJ!kzWE&8l2m?bhMhUrhYuqEG$9dHTE; zU!PuIro+~@hTpt%+kU4Bnu;5?WY612bKJJ@g~=kH8NOHFO%Hm^@GlcZ{vn2oi$u7= zp$^$H&MpUA_HGURScA|ztYIn*=r^&YWBA;Xt$mn3V9R^>3v9W}zmmUJ!&a;k`4-Ff z>t(rSd*k#Oq8uHs%s1Gyngh-g<@E^QP*9)qR}-0!KBlLYk6Y%~@5}Pk`@MYH3SX|_ zJJ)kc*dY!jJBJ+%)Xvr48?L!Zn~*%Fpl2`VB~!3%n@DF1)!GZ~a=?!b6q?5|nHHrU zxc__2{r3vo&eu9(cWMva-0S(<^0|aeB=xlyl|E2VqIc-NALRp5Q2B!FV5a=){t(0A zn#((17vqi&P3^1SH|NWcR_$@1pz}5{UpC{*bl;pWQ`-4AnqHiChx3(h{IciMheuf9 zb<`n#uAuXQ*RMQg=b3M)=jOD^$7n|gerBkbukZ{J6xiWQ-AuKabcwTD+Os!Gdv}Wo zer@NOR5Pa;s(j}A*`{SXsdjPRCHa>n9IpOh#_JU3T8$3h5O$C=6a2f7Pp5=>dps-e z|Bl4y^(&nUs{3~E`RKQvDPFX}X@<(jZ37h@gN5etL6w*3zIv{p%BRx*sgR8nHCIrV zFSER<^gfZ_DWO?Thb_%N9|nD=pbYC~nP4m96=4!8d0<;R#C;hx%r2ApzR)A?U!w`A z<_({TinPk7o}2Hh=jy(KIbP%9#Na&KpAt<1tos1v$7LWNfdXTTj2j^#NlF zjwS{124mNe!d#=n<=+*HGep>n^%Rkh#Kkh#YUM{(Cq(EX}jktUnaOf;u$D>aEqY- zK*5(X;LCJBOS%LXhW~%3S#F+`a+L}06*Q}UtjAmyiTj6YTD62(|JmJF&lObft8{;% zdVio$;Zrdc!vz%`2MQ{FWx|)~xw@YTW-9McyRXj!GtA%3^>IG(75d$zpn9GuCdB;Q zoL29t`@;>LJv5z*-r{^v>N^G1eFc9c`JkY>|8uM^!k%=Rp^0ybe`Yw?`aA#3mut^I zVDL4`2Q%JG_s#h-qzB7~gXMk3x;ZJVR#3ziO1MD-$#o#MSUx|k zn_sYMnO3k=rWM{CK~XB^QK}xp1Qi_vh356JVM}j_iFHFA9wyTYw#l@D>G@UtmHr$s z+$%~_cAF|km2U?#jgQ&hSLGk-dY64_8?VZt4pki1u*2O#GW7VIex})UF^(VV@KBG( zQ1mN(z`i5>gNG_S#N!xL9ERQ=nfx(>ysz}S9n}3y1H`AwKh*aqsCxXnz=7)RgXKNd z4$2BHJ_RHxx@B!W=sPu&xxI`ozjb+vL&*H^8Kvyzdb-aHt(^; z-MnC?d@*Y6sZQWy3aa~NX!qQlKgVf7CHVi4)QP!%8>M>zsGDwC?c!>;vbIe$jR74@QsI;f~JW z@g1X{a{jMa>vulT`P+ZJd+%}`sxeNLr_v91|M$u>uh`-I4I<3KH+)Wq&#@nN&j~&3 z%of_n+i=T!w)jd+F)UpI6N@l@q3`#r)(kh>NZoaRctNRLWs1)z#2=c=4pR-BE4CWfD{xZaH*nF+mGSMCiZn#_eRu#NL zrX^JQ6x{Hld@f+!vaZj+Sb5FDLmldJwOd>rEOW1Z(;@ZlK_g#EZu$$47wy0f6r7L& zU#9z6(xuB)rkG+i?%F~1zB%7dlg4vxGZb4t22MaXE&Gbq?$=x>k zxe;|&eDxozX8qqc>(2bvUH9Glqi@#LPk-{;oq2EQaLuMy{pY{ir9U^PRsL0P?|QJ{ zc2Auds`7^zvTs!KCSdoRpMMO+L;q;cDvCeV;a#J*zYo_YyY0!hX$6km66X7N*zMEH z>6`#P-{#xCg5OQd1T(d-j#uFyB+P`TfA>echHvB;{_@IjlnVYvHi$n_n)4O8M`XZI z`ifr}9>~U!D-vydsKepf`)a~#mNDJ`r2J4OXwHAIr1i5OezEYw@3D{S z8n!kb`PZVy0oVNE^@kp=Yi@qbH~X%3JTF>%`fnEZN~?UEpS(0OdD1g=o1eVwf;)Gt z(V;4Th@of=w1?VfF;J-DB+XFT?8=9g2`V}U3fWVa@>kgl=iS0}{9Dg#CT}uR@Rwgd zj`pjvXP!KQkN3}=yp@mZ&wQzyUexoM#&I>S^TI9u)A1_&gMFFHrZ*UwWKYi^(t#PQh)l5+3lTcM-$b6OuYQ81=p}y}?`G|7_6`$g8BhQAS4!j8vZ-uvQDU>L4FG79hD>nZE;=Tp4rVu{)L7A>Pq z`CHoNvkXFFmdD%XR0sBz%)r;X2|@1$&jN%E=96-|XQPVOuT| ze)#_?PKTTLp(2m5%dQi1%1!^|lW)DxsQji_2`1B-_^jhq_y-IBYp%Lsn=gRHky-(l9Cz32NOFX~gP8y0guekpp_oQrBb6VYhMCLO=#ixIFsBCpr z&w-{@4EmuCRs9e77<&0>OLmAuT`u>K$GhaO&RoO2vfLqtdOg%0R<-9F~_*(fejR z{UtpA=3Te?^6JcKmA`BBRqvnj>#x4s}R%pr76j1LVhWzb|Sr{Qomaf`WE@>9sC8x0P zFW>*?WnW`euReFzO%tDGrR$!UzU;>v*$Hco55!hP*`zyucK0XF`Ihs;QBz-Cdck7n zb30huAAernU&z)i{o9RQ`A0C{JD;mPY2Rk%J@(niB{yHn+=&&Tnd^^Y=Y1o(c9!Q0 zY|Yb`%y=R+iY=YxT^QVSHY;24hg)A8SIS0xbYpAy;amF+*L?o*7Vopyv9^_Gj6C*+ zLe~28xz(qh^<8$s%P0^ zrHl5vS>tQFx8M8RYQ{eM_0#;3l0V{zd`c46B|AO1by zV&^^I68rlb4eab$&qW@r`Wb81KK$s#rGH_kAF*QGxhrbeDX+h|sAlI|?8N0K-tmpI zZ)JHO?OgJ+J*)Z+*9PwX@K2jxWWK4Nd}qSX4riWozQ5(izqp^Z?g|xjN1tNnUe`A3 za@TIQ=4i)~-<|LptM@#8)n87`XQd@uPTM=##fm<<`TQTP*xhe9TzJ% z&gAd0^OpC#bMp^xWovHy&Xu41Xf>eJ5ZHykd! ztFC$Lw%WVO*!jo(Yw`O3S;x+K^v|vTaNWk%wO)6jU-z1`s2QH#xZyAWwUp! zFR6~a&Wd)dIPcO&Zs<4kX!|Ejtr*K<&#tZcbiq+(Uo@)GQzu|Dm(S>-etrTR&=LXI3pM4!(Ff ztNq*7`))2gfgL$(&6@e+kLWiXF8%y5-UBiY)>TaT(^cPMm(|tX5`M4c)wy-2PCI7% zJ+&9t)w;g;tBbdcsjE5tKKJ^^YwBh-R-AS9r+-~Hz2uoQ${%{FZe+~$mF4q3T=e3M z{hu5A;B)=;1T4BM{K&~GU-=7D`+nvAHGQ4DNR;UO?(Kh{^uWz+Y=%s~%EL4K`dRo) z?z{aBgb}3e;N|!4`jYzIwO+nDXW=bb zpK_63#rCQEiaysKDDzW?idPsAtG z{YieKP|~4)TS3M^I^}zdKKpWV^lgzpF(Lv#b(YYgm;d`aFS#FI<^1KbXYc;U!`(W) z>iw65JoQL^insB;jQ`Nj)RwV``g8f7Ga>lP)ET3(Z9L1OJwL5@e*1ML&M(txA}jAx z_0`YfD&9fAR;SuuxmT2|^F#7W<#*nVFI0W?+b^*fuICx`v%{r4*ZsWQ7oPIsYV-TL z{H=TMgvTEE`sZ|cc%O$stx)|yfA8J;&iz0APPJNR)#X8u=U8&sHkXELXOp*m>gLAGLyS#eQ`#(Ox`Kybrt2HB9t_{?2H4OMOG*2;bEhba8G9tT(Z{kydX8!yMb zLlmm^__!ViM?3zzw8sO7t?s6}JfM|s<8TU&bi?m~$yMDPj@vBYgo}H4dQwk%T7HZ8 m0sXzlM83%qs{BI@Kdy)1`^W7e Date: Mon, 26 Mar 2018 10:06:23 -0400 Subject: [PATCH 333/451] Allow namelist 'maxpft' workable for natural-PFT parameter data read. --- components/elm/bld/ELMBuildNamelist.pm | 20 +++++++++++++------- 1 file changed, 13 insertions(+), 7 deletions(-) diff --git a/components/elm/bld/ELMBuildNamelist.pm b/components/elm/bld/ELMBuildNamelist.pm index 68afd92e132d..cbf067e67607 100755 --- a/components/elm/bld/ELMBuildNamelist.pm +++ b/components/elm/bld/ELMBuildNamelist.pm @@ -1552,13 +1552,19 @@ sub setup_cmdl_maxpft { $nl_flags->{'maxpft'} = $val; if ( ($nl_flags->{'bgc_mode'} ne "sp") && ($nl_flags->{'maxpft'} != $maxpatchpft{$nl_flags->{'use_crop'}}) ) { - fatal_error("** For CN or BGC mode you MUST set max patch PFT's to $maxpatchpft{$nl_flags->{'use_crop'}}\n" . - "**\n" . - "** When the crop model is on then it must be set to $maxpatchpft{'crop'} otherwise to $maxpatchpft{'nocrop'}\n" . - "** Set the bgc mode, crop and maxpft by the following means from highest to lowest precedence:\n" . - "** * by the command-line options -bgc, -crop and -maxpft\n" . - "** * by a default configuration file, specified by -defaults\n" . - "**\n"); + if ($opts->{$var} eq "default") { + fatal_error("** For CN or BGC mode you MUST set max patch PFT $val to $maxpatchpft{$nl_flags->{'use_crop'}}\n" . + "**\n" . + "** When the crop model is on then it must be set to $maxpatchpft{'crop'} otherwise to $maxpatchpft{'nocrop'}\n" . + "** Set the bgc mode, crop and maxpft by the following means from highest to lowest precedence:\n" . + "** * by the command-line options -bgc, -crop and -maxpft\n" . + "** * by a default configuration file, specified by -defaults\n" . + "**\n"); + } else { + message("running with maxpft NOT equal to $maxpatchpft{$nl_flags->{'use_crop'}} is " . + "NOT validated / scientifically supported.\n"); + + } } if ( $nl_flags->{'maxpft'} > $maxpatchpft{$nl_flags->{'use_crop'}} ) { fatal_error("** Max patch PFT's can NOT exceed $maxpatchpft{$nl_flags->{'use_crop'}}\n" . From 98be2ae3c832a825c764ca2bea9a0770f1140dc2 Mon Sep 17 00:00:00 2001 From: Fengming Yuan Date: Mon, 26 Mar 2018 10:06:23 -0400 Subject: [PATCH 334/451] Allow read flexible-length PFT parameters and names, if user-defined. NOTES for when user-defined: (1) explicitly define a few PFT properties (flags) as following: nonvasular (0, 1=moss, or 2=lichen); woody (0, 1=tree, or 2=shrub); needleleaf ( 0=broadleaf, or 1=needleleaf); graminoid ( 0=woody/crop/nonvascular, or 1=graminoid); generic_crop ( 0=non-crop/prognostic crop, 1=generic_crop. NOTE that this is for not having conflicts with crop module development). climatezone (0=not-specific, 1=tropical, 2=temperate, 3=boreal, or 4=arctic) (2) in case's env_run.xml, add ' -maxpft 12' in which 12 is an example number of pfts, in "ELM_BLDNML_OPTS'" like the following: char CLM build-namelist options --- .../elm/src/data_types/VegetationType.F90 | 5 + components/elm/src/main/elm_varpar.F90 | 9 +- components/elm/src/main/pftvarcon.F90 | 354 +++++++++++++++++- 3 files changed, 352 insertions(+), 16 deletions(-) diff --git a/components/elm/src/data_types/VegetationType.F90 b/components/elm/src/data_types/VegetationType.F90 index a3711f7c117b..dd8bd7d842d4 100644 --- a/components/elm/src/data_types/VegetationType.F90 +++ b/components/elm/src/data_types/VegetationType.F90 @@ -33,6 +33,11 @@ module VegetationType ! 24 => irrigated soybean ! -------------------------------------------------------- ! + + ! ----------------------user-defined parameter file --------------------------------------------------------------------- + ! NOTE: if user provides own parameter file, with different 'pft_name' or order, + ! the above ilist of default PFTs will be replaced, and arrays of sizes as below will be changed as well. + use shr_kind_mod , only : r8 => shr_kind_r8 use elm_varcon , only : ispval, spval diff --git a/components/elm/src/main/elm_varpar.F90 b/components/elm/src/main/elm_varpar.F90 index 21e8f659210f..1f82d65ec7eb 100644 --- a/components/elm/src/main/elm_varpar.F90 +++ b/components/elm/src/main/elm_varpar.F90 @@ -48,20 +48,23 @@ module elm_varpar integer, parameter :: ndst = 4 ! number of dust size classes (BGC only) integer, parameter :: dst_src_nbr = 3 ! number of size distns in src soil (BGC only) integer, parameter :: sz_nbr = 200 ! number of sub-grid bins in large bin of dust size distribution (BGC only) - integer, parameter :: mxpft = 50 ! maximum number of PFT's for any mode; + !integer, parameter :: mxpft = 50 ! maximum number of PFT's for any mode; + integer :: mxpft = 50 ! maximum number of PFT's for any mode; + ! can be modified from reading pft-physiology in 'main/pftvarcon.F90:pftconrd' ! FIX(RF,032414) might we set some of these automatically from reading pft-physiology? integer, parameter :: numveg = 16 ! number of veg types (without specific crop) integer, parameter :: nlayer = 3 ! number of VIC soil layer --Added by AWang integer :: nlayert ! number of VIC soil layer + 3 lower thermal layers - integer :: numpft = mxpft ! actual # of patches (without bare), a total that spans LUs + integer :: numpft = 50 ! actual # of patches (without bare), a total that spans LUs integer :: numcft = 36 ! actual # of crops logical :: crop_prog = .true. ! If prognostic crops is turned on integer :: maxpatch_urb= 5 ! max number of urban patches (columns) in urban landunit integer :: mxpft_nc ! maximum number of PFT's when use_crop=False; - integer :: maxpatch_pft ! max number of plant functional types in naturally vegetated landunit (namelist setting) + integer :: maxpatch_pft ! max number of plant functional types in naturally vegetated landunit (namelist setting: maxpft) + ! This number must be exactly matched with 'natpft' in surfdata.nc integer, parameter :: nsoilorder = 15 ! number of soil orders diff --git a/components/elm/src/main/pftvarcon.F90 b/components/elm/src/main/pftvarcon.F90 index 2e2a00f4b4ec..cbd5946bb4e6 100644 --- a/components/elm/src/main/pftvarcon.F90 +++ b/components/elm/src/main/pftvarcon.F90 @@ -9,11 +9,19 @@ module pftvarcon use shr_kind_mod, only : r8 => shr_kind_r8 use shr_log_mod , only : errMsg => shr_log_errMsg use abortutils , only : endrun - use elm_varpar , only : mxpft, numrad, ivis, inir, cft_lb, cft_ub + use elm_varpar , only : mxpft, numrad, ivis, inir use elm_varpar , only: mxpft_nc use elm_varctl , only : iulog, use_vertsoilc use elm_varpar , only : nlevdecomp_full, nsoilorder use elm_varctl , only : nu_com + !------------------------------------------------------------------------------------------- + use elm_varpar , only : crop_prog + use elm_varpar , only : natpft_size, natpft_lb, natpft_ub + use elm_varpar , only : cft_size, cft_lb, cft_ub + use elm_varpar , only : surfpft_size, surfpft_lb, surfpft_ub + use elm_varpar , only : numpft, numcft, maxpatch_pft, max_patch_per_col, maxpatch_urb + use elm_varctl , only : create_crop_landunit + !------------------------------------------------------------------------------------------- ! ! !PUBLIC TYPES: implicit none @@ -116,6 +124,7 @@ module pftvarcon real(r8), allocatable :: grpnow(:) !growth respiration parameter real(r8), allocatable :: rootprof_beta(:) !CLM rooting distribution parameter for C and N inputs [unitless] + ! add pft dependent parameters for phosphorus -X.YANG real(r8), allocatable :: leafcp(:) !leaf C:P [gC/gP] real(r8), allocatable :: lflitcp(:) !leaf litter C:P (gC/gP) @@ -303,6 +312,16 @@ module pftvarcon real(r8), allocatable :: gcbr_p(:) !effectiveness of roots in reducing rainfall-driven erosion real(r8), allocatable :: gcbr_q(:) !effectiveness of roots in reducing runoff-driven erosion + ! new pft properties, together with woody, crop, percrop, evergreen, stress_decid, season_decid, defined above, + ! are introduced to define vegetation properties. This will be well defineing a pft so that no indices needed for codes. + real(r8), allocatable :: climatezone(:) ! distributed climate zone (0 = any zone, 1 = tropical, 2 = temperate, 3 = boreal, 4 = arctic) + real(r8), allocatable :: nonvascular(:) ! nonvascular lifeform flag (0 = vascular, 1 = moss, 2 = lichen) + real(r8), allocatable :: needleleaf(:) ! needleleaf lifeform flag (0 = broadleaf, 1 = needleleaf) + real(r8), allocatable :: graminoid(:) ! graminoid lifeform flag (0 = nonvascular+woody+crop+percrop, 1 = graminoid) + real(r8), allocatable :: generic_crop(:) ! generic_crop (0 = non_crop or prognostic crop, 1 = generic crop, i.e. crop when use_crop=false) + real(r8), allocatable :: nfixer(:) ! nitrogen fixer flag (0 = inable, 1 = able to nitrogen fixation from atm. N2) + + ! ! !PUBLIC MEMBER FUNCTIONS: public :: pftconrd ! Read and initialize vegetation (PFT) constants @@ -347,6 +366,9 @@ subroutine pftconrd integer :: dimid ! netCDF dimension id integer :: npft ! number of pfts on pft-physiology file logical :: readv ! read variable in or not + logical :: PFT_DEFAULT ! pft names are default, i.e. NOT user-defined + integer :: ncft0, ncft ! crop pft index of first/last when 'create_crop_landunit' is true + integer :: noncropmax ! max non-crop pft index (to check when 'create_crop_landunit' is true) character(len=32) :: subname = 'pftconrd' ! subroutine name ! ! Expected PFT names: The names expected on the paramfile file and the order they are expected to be in. @@ -410,6 +432,24 @@ subroutine pftconrd expected_pftnames(49) = 'willow ' expected_pftnames(50) = 'irrigated_willow ' + ! read actual 'npft' from parameter file + if (masterproc) then + write(iulog,*) 'Attempting to read PFT physiological data .....' + end if + call getfil (paramfile, locfn, 0) + call ncd_pio_openfile (ncid, trim(locfn), 0) + call ncd_inqdid(ncid,'pft',dimid) + call ncd_inqdlen(ncid,dimid,npft) + + ! now 'mxpft' in 'elm_varpar' updated by npft here + mxpft = npft - 1 + mxpft_nc = npft - 1 ! when .not.use_crop, so here temporarily set and may be changed after read-through PFT-physiology + + ! NOTES: + ! In parameter file, 'npft' (mxpft) [number of pfts in parameter file] can be greater than 'maxpatch_pft' [number of pfts in surfdata file] which also set by namelist 'maxpft', + ! but cannot be less, i.e. there cannot be more pfts in the surface file than there are set of pft parameters, if running the non-crop version of model. + if (npft=1 .or. percrop(i)>=1) .and. generic_crop(i)==0) then + ! at this moment, read-in 'generic_crop' is actually 'iscft' (i.e. crop as CFT or not) + ! So must re-assign + generic_crop(i) = 1 + else + generic_crop(i) = 0 + end if + end do + end if + + ! woody=2 for shrub NOT YET ready in rest of ELM code + do i = 0, npft-1 + if (woody(i)>1) woody(i) == 1 + end do call ncd_pio_closefile(ncid) + + if ( PFT_DEFAULT ) then + ! if still reading in default PFT physiology file, + ! pft indexing will be as old way + do i = 0, mxpft if(.not. use_crop .and. i > mxpft_nc) EXIT ! exit the do loop @@ -1032,13 +1167,13 @@ subroutine pftconrd ! on non-fates columns. For now, they are incompatible, and this check is warranted (rgk 04-2017) ! avd - this should be independent of FATES because it fails for non-crop config otherwise - - if(.not. use_crop .and. i > mxpft_nc) EXIT ! exit the do loop + if(.not. use_fates)then if ( trim(adjustl(pftname(i))) /= trim(expected_pftnames(i)) )then write(iulog,*)'pftconrd: pftname is NOT what is expected, name = ', & trim(pftname(i)), ', expected name = ', trim(expected_pftnames(i)) call endrun(msg='pftconrd: bad name for pft on paramfile dataset'//errMsg(__FILE__, __LINE__)) end if + end if if ( trim(pftname(i)) == 'not_vegetated' ) noveg = i if ( trim(pftname(i)) == 'needleleaf_evergreen_temperate_tree' ) ndllf_evr_tmp_tree = i @@ -1103,12 +1238,204 @@ subroutine pftconrd nppercropmax = nwillowirrig ! last prognostic perennial crop in list end if + !------------------------------------------------------------------------------------------- + ! the following is initialized as 0 above for all PFT. + ! here the hard-coded values (or flags) for default ELM PFT physiology will be working as original + ! when not using those indexing of PFT orders anymore in other codes than here. + needleleaf(noveg+1:ndllf_dcd_brl_tree) = 1 + graminoid(nc3_arctic_grass:nc4_grass) = 1 + generic_crop(nc3crop:nc3irrig) = 1 + nfixer(nsoybean) = 1 + nfixer(nsoybeanirrig) = 1 + + climatezone(ndllf_evr_tmp_tree) = 2 + climatezone(ndllf_evr_brl_tree) = 3 + climatezone(ndllf_dcd_brl_tree) = 3 + climatezone(nbrdlf_evr_trp_tree) = 1 + climatezone(nbrdlf_evr_tmp_tree) = 2 + climatezone(nbrdlf_dcd_trp_tree) = 1 + climatezone(nbrdlf_dcd_tmp_tree) = 2 + climatezone(nbrdlf_dcd_brl_tree) = 3 + climatezone(nbrdlf_dcd_tmp_shrub)= 2 + climatezone(nbrdlf_dcd_brl_shrub)= 3 + climatezone(nc3_arctic_grass) = 4 + !------------------------------------------------------------------------------------------- + + + + ! NOT default PFT file + else + + ! not vegetated checking + noveg = -1 + + ! when user-defined PFTs, if crop included, it must be the default way: + ! cropts must be in one block and after nat-pft if 'create_crop_landunit' or 'use_crop' is true + npcropmin = -1 ! first prognostic crop + npcropmax = -1 ! last prognostic crop in list + nppercropmin = -1 ! first prognostic perennial crop + nppercropmax = -1 ! last prognostic perennial crop in list + + numcft = 0 + ncft = -1 + ncft0 = -1 + noncropmax = 0 + do i = 0, npft-1 + if (crop(i)>=1 .or. percrop(i)>=1 .or. generic_crop(i)>=1) then + numcft = numcft + 1 + + if(use_crop) then + ! if 'generic_crop' specifically defined, + ! 'crop' will not be counted into prognostic + if (crop(i)>=1 .and. generic_crop(i)==0) then + npcropmax = i + if(npcropmin<=0) npcropmin = i + end if + + ! NOTE: there is a misunderstanding in pft physiology parameter file: 'perennial crop' IS NOT 'crop', + ! but still counted into 'numcft' + if(percrop(i)==1) then + nppercropmax = i + if(nppercropmin<=0) nppercropmin = i + end if + + else + if(crop(i)>=1 .or. generic_crop(i)>=1) then + ! in case either 'crop' or 'generic_crop' or both defined when not use_crop=.true. + generic_crop(i) = 1 + else + generic_crop(i) = 0 + end if + end if + + ! + if (create_crop_landunit) then + ! make sure all crop-pft are in one block and following nat-pft SO THAT creating crop landunit is possible + ncft = ncft + 1 + if (ncft0<0) ncft0=i + end if + + ! + else if (create_crop_landunit) then + noncropmax = i + + end if + + ! need to check 'noveg' + if ( woody(i)<=0 .and. graminoid(i)<=0 .and. nonvascular(i)<=0 .and. & + generic_crop(i)<=0 .and. crop(i)<=0 .and. percrop(i)<=0) then + if (noveg>=0) then + ! not yet support multiple non-vegetated PFT + ! this also will catch error of no actual PFT if npft>1 + call endrun(msg=' ERROR: more than 1 not vegetated in physiology parameter nc file.'//errMsg(__FILE__, __LINE__)) + else + noveg = i + end if + end if + + ! + end do + + ! make sure non-generic crop indices always beyond natural-pft, even if not available - used in filterMod.F90) + if (npcropmin < 0 .and. npcropmax < 0) then + npcropmin = npft + npcropmax = npft + end if + + ! MUST re-do some constants which already set in 'elm_varpar.F90:elm_varpar_init()' + mxpft_nc = min(maxpatch_pft,npft) - 1 ! user-defined is what max. + numpft = min(maxpatch_pft,npft) - 1 ! actual # of patches (without bare) + + if (create_crop_landunit) then + if (ncft0 /= noncropmax+1) then + call endrun(msg=' ERROR: when create_crop_landunit is true, crop must be following non-crop PFT .'//errMsg(__FILE__, __LINE__)) + end if + if (ncft /= npft-1) then + call endrun(msg=' ERROR: when create_crop_landunit is true, last crop must be the last one of all PFTs .'//errMsg(__FILE__, __LINE__)) + end if + + natpft_size = (numpft + 1) - numcft ! note that numpft doesn't include bare ground -- thus we add 1 + cft_size = numcft + else + natpft_size = numpft + 1 ! note that numpft doesn't include bare ground -- thus we add 1 + cft_size = 0 + end if + natpft_lb = 0 + natpft_ub = natpft_lb + natpft_size - 1 + cft_lb = natpft_ub + 1 + cft_ub = max(cft_lb, cft_lb + cft_size - 1) ! NOTE: if cft_size is ZERO, could be issue (but so far so good) + surfpft_lb = natpft_lb + surfpft_ub = natpft_ub + surfpft_size = natpft_size + max_patch_per_col= max(numpft+1, numcft, maxpatch_urb) + + + end if ! end if 'PFT_DEFAULT' + + ! checking of pft flags' conflict + if ( .not. use_fates ) then + do i = 0, mxpft + if (i == noveg) then + if ( (nonvascular(i)+woody(i)+graminoid(i)+generic_crop(i)+crop(i)+percrop(i)) >= 1 .or. & + (needleleaf(i)+evergreen(i)+stress_decid(i)+season_decid(i)+nfixer(i)) >= 1 ) then + print *, 'ERROR: Incorrect not-vegetated PFT flags: ', i, ' ', trim(pftname(i)) + call endrun(msg=' ERROR: not_vegetated has at least one positive PFT flag '//errMsg(__FILE__, __LINE__)) + end if + + else if ( (nonvascular(i)+woody(i)+graminoid(i)+generic_crop(i)+crop(i)+percrop(i)) >= 1) then + if (nonvascular(i) >= 1 .and. (woody(i)+graminoid(i)+generic_crop(i)+crop(i)+percrop(i)) >= 1) then + print *, 'ERROR: Incorrect nonvasculr PFT flags: ', i, ' ', trim(pftname(i)) + call endrun(msg=' ERROR: nonvascular PFT cannot be any of woody/graminoid/crop type '//errMsg(__FILE__, __LINE__)) + else if (woody(i) >= 1 .and. (nonvascular(i)+graminoid(i)+generic_crop(i)+crop(i)+percrop(i)) >= 1) then + print *, 'ERROR: Incorrect woody PFT flags: ', i, ' ', trim(pftname(i)) + call endrun(msg=' ERROR: woody PFT cannot be any of nonvascular/graminoid/crop type - '//errMsg(__FILE__, __LINE__)) + else if (graminoid(i) >= 1 .and. (nonvascular(i)+woody(i)+generic_crop(i)+crop(i)+percrop(i)) >=1 ) then + print *, 'ERROR: Incorrect graminoid PFT flags: ', i, ' ', trim(pftname(i)) + call endrun(msg=' ERROR: graminoid PFT cannot be any of nonvascular/woody/crop type - '//errMsg(__FILE__, __LINE__)) + else if ( (generic_crop(i)+crop(i)+percrop(i)) >= 1 .and. (nonvascular(i)+woody(i)+graminoid(i)) >= 1) then + print *, 'ERROR: Incorrect crop PFT flags: ', i, ' ', trim(pftname(i)) + call endrun(msg=' ERROR: crop PFT cannot be any of nonvascular/woody/graminoid type - '//errMsg(__FILE__, __LINE__)) + end if + + if( (stress_decid(i)*season_decid(i)) >= 1 ) then + print *, 'ERROR: Incorrect stress_decid or season_decid flags: ', i, ' ', trim(pftname(i)) + call endrun(msg=' ERROR: stress_decid AND season_decid cannot be both 1 - '//errMsg(__FILE__, __LINE__)) + elseif( (evergreen(i)*(stress_decid(i)+season_decid(i)) ) >= 1 ) then + print *, 'ERROR: Incorrect evergreen AND season_/stress_decid flags: ', i, ' ', trim(pftname(i)) + call endrun(msg=' ERROR: evergreen AND (stress_decid OR season_decid) cannot be both 1 - '//errMsg(__FILE__, __LINE__)) + end if + + else + + call endrun(msg=' ERROR: not_vegetated AND none of vegetation type for PFT - '//errMsg(__FILE__, __LINE__)) + + end if + + end do + end if + + ! information + if (masterproc) then + write(iulog,*) + write(iulog,*) 'Using PFT physiological parameters from: ', paramfile + write(iulog,*) ' -- index -- name -- climate zone -- -- woody -- -- needleleaf -- -- evergreen -- -- stress_decid -- -- season_decid -- -- graminoid-- -- generic_crop -- -- crop -- -- perennial crop -- -- nfixer --' + do i = 0, npft-1 + write(iulog,*) i, pftname(i), int(climatezone(i)), int(woody(i)), int(needleleaf(i)), & + int(evergreen(i)), int(stress_decid(i)), int(season_decid(i)), & + int(graminoid(i)), int(generic_crop(i)), int(crop(i)), int(percrop(i)), int(nfixer(i)) + end do + write(iulog,*) + end if + + + !------------------------------------------------------------------------------------------- + call set_is_pft_known_to_model() - call set_num_cfts_known_to_model() + if (cft_size>0) call set_num_cfts_known_to_model() if( .not. use_fates ) then if( .not. use_crop) then - if ( npcropmax /= mxpft_nc )then + if ( npcropmax /= mxpft_nc .and. crop_prog)then call endrun(msg=' ERROR: npcropmax is NOT the last value'//errMsg(__FILE__, __LINE__)) end if else @@ -1118,6 +1445,7 @@ subroutine pftconrd end if do i = 0, mxpft if(.not. use_crop .and. i > mxpft_nc) EXIT ! exit the do loop + if(.not.PFT_DEFAULT) EXIT ! no checking of indexing PFTs for user-defined if( .not. use_crop) then if ( irrigated(i) == 1.0_r8 .and. (i == nc3irrig .or. & i == ncornirrig .or. & From a8b486bc426d5f69971230ed8312fdb45b97c489 Mon Sep 17 00:00:00 2001 From: "Yuan, Fengming" Date: Tue, 31 Oct 2023 14:41:12 -0400 Subject: [PATCH 335/451] Distinguish woody types between tree (1) and shrub (2). --- .../elm/src/biogeochem/AllocationMod.F90 | 26 +++++++-------- .../src/biogeochem/CNAllocationBetrMod.F90 | 22 ++++++------- .../elm/src/biogeochem/CNCarbonStateType.F90 | 2 +- .../src/biogeochem/CNNStateUpdate1BeTRMod.F90 | 8 ++--- .../src/biogeochem/CNNitrogenStateType.F90 | 2 +- .../elm/src/biogeochem/CNPhenologyBeTRMod.F90 | 32 +++++++++---------- .../src/biogeochem/CarbonStateUpdate1Mod.F90 | 18 +++++------ .../elm/src/biogeochem/ComputeSeedMod.F90 | 2 +- .../elm/src/biogeochem/GrowthRespMod.F90 | 2 +- .../elm/src/biogeochem/MaintenanceRespMod.F90 | 2 +- .../biogeochem/NitrogenStateUpdate1Mod.F90 | 8 ++--- .../src/biogeochem/PhenologyFluxLimitMod.F90 | 22 ++++++------- .../elm/src/biogeochem/PhenologyMod.F90 | 32 +++++++++---------- .../biogeochem/PhosphorusStateUpdate1Mod.F90 | 8 ++--- .../elm/src/biogeochem/VegStructUpdateMod.F90 | 2 +- .../elm/src/data_types/VegetationDataType.F90 | 6 ++-- .../data_types/VegetationPropertiesType.F90 | 17 +++++----- components/elm/src/main/pftvarcon.F90 | 11 +++---- 18 files changed, 111 insertions(+), 111 deletions(-) diff --git a/components/elm/src/biogeochem/AllocationMod.F90 b/components/elm/src/biogeochem/AllocationMod.F90 index 2795fd42c8ed..a31a07cd8f6c 100644 --- a/components/elm/src/biogeochem/AllocationMod.F90 +++ b/components/elm/src/biogeochem/AllocationMod.F90 @@ -583,7 +583,7 @@ subroutine Allocation1_PlantNPDemand (bounds, num_soilc, filter_soilc, num_soilp ! These fluxes should already be in gC/m2/s mr = leaf_mr(p) + froot_mr(p) - if (woody(ivt(p)) == 1.0_r8) then + if (woody(ivt(p)) >= 1.0_r8) then mr = mr + livestem_mr(p) + livecroot_mr(p) else if (ivt(p) >= npcropmin) then if (croplive(p)) mr = mr + livestem_mr(p) + grain_mr(p) @@ -815,7 +815,7 @@ subroutine Allocation1_PlantNPDemand (bounds, num_soilc, filter_soilc, num_soilp ! determine N requirements ! determine P requirements -X. YANG - if (woody(ivt(p)) == 1.0_r8) then + if (woody(ivt(p)) >= 1.0_r8) then c_allometry(p) = (1._r8+g1)*(1._r8+f1+f3*(1._r8+f2)) n_allometry(p) = 1._r8/cnl + f1/cnfr + (f3*f4*(1._r8+f2))/cnlw + & (f3*(1._r8-f4)*(1._r8+f2))/cndw @@ -2372,7 +2372,7 @@ subroutine Allocation3_PlantCNPAlloc (bounds , & endif mr = leaf_mr(p) + froot_mr(p) - if (woody(ivt(p)) == 1.0_r8) then + if (woody(ivt(p)) >= 1.0_r8) then mr = mr + livestem_mr(p) + livecroot_mr(p) else if (ivt(p) >= npcropmin) then if (croplive(p)) mr = mr + livestem_mr(p) + grain_mr(p) @@ -2466,7 +2466,7 @@ subroutine Allocation3_PlantCNPAlloc (bounds , & plant_calloc(p) = availc(p) ! here no down-regulation on allocatable C here, NP limitation is implemented in leaf-level NP control on GPP - if (woody(ivt(p)) == 1.0_r8) then + if (woody(ivt(p)) >= 1.0_r8) then c_allometry(p) = (1._r8+g1)*(1._r8+f1+f3*(1._r8+f2)) n_allometry(p) = 1._r8/cnl + f1/cnfr + (f3*f4*(1._r8+f2))/cnlw + & (f3*(1._r8-f4)*(1._r8+f2))/cndw @@ -2549,7 +2549,7 @@ subroutine Allocation3_PlantCNPAlloc (bounds , & cpool_to_xsmrpool(p) = cpool_to_xsmrpool(p) + nlc * (1._r8 - fcur) * (1 + g1) cpool_to_xsmrpool(p) = cpool_to_xsmrpool(p) + nlc * f1 * fcur * (1 + g1) cpool_to_xsmrpool(p) = cpool_to_xsmrpool(p) + nlc * f1 * (1._r8 - fcur) * (1 + g1) - if (woody(ivt(p)) == 1._r8) then + if (woody(ivt(p)) >= 1.0_r8) then cpool_to_xsmrpool(p) = cpool_to_xsmrpool(p) + nlc * f3 * f4 * fcur * (1 + g1) cpool_to_xsmrpool(p) = cpool_to_xsmrpool(p) + nlc * f3 * f4 * (1._r8 - fcur) * (1 + g1) cpool_to_xsmrpool(p) = cpool_to_xsmrpool(p) + nlc * f3 * (1._r8 - f4) * fcur * (1 + g1) @@ -2580,7 +2580,7 @@ subroutine Allocation3_PlantCNPAlloc (bounds , & cpool_to_leafc_storage(p) = nlc * (1._r8 - fcur) cpool_to_frootc(p) = nlc * f1 * fcur cpool_to_frootc_storage(p) = nlc * f1 * (1._r8 - fcur) - if (woody(ivt(p)) == 1._r8) then + if (woody(ivt(p)) >= 1.0_r8) then cpool_to_livestemc(p) = nlc * f3 * f4 * fcur cpool_to_livestemc_storage(p) = nlc * f3 * f4 * (1._r8 - fcur) cpool_to_deadstemc(p) = nlc * f3 * (1._r8 - f4) * fcur @@ -2633,7 +2633,7 @@ subroutine Allocation3_PlantCNPAlloc (bounds , & npool_to_leafn_storage(p) = (nlc / cnl) * (1._r8 - fcur) npool_to_frootn(p) = (nlc * f1 / cnfr) * fcur npool_to_frootn_storage(p) = (nlc * f1 / cnfr) * (1._r8 - fcur) - if (woody(ivt(p)) == 1._r8) then + if (woody(ivt(p)) >= 1.0_r8) then npool_to_livestemn(p) = (nlc * f3 * f4 / cnlw) * fcur npool_to_livestemn_storage(p) = (nlc * f3 * f4 / cnlw) * (1._r8 - fcur) npool_to_deadstemn(p) = (nlc * f3 * (1._r8 - f4) / cndw) * fcur @@ -2677,7 +2677,7 @@ subroutine Allocation3_PlantCNPAlloc (bounds , & ppool_to_leafp_storage(p) = (nlc / cpl) * (1._r8 - fcur) ppool_to_frootp(p) = (nlc * f1 / cpfr) * fcur ppool_to_frootp_storage(p) = (nlc * f1 / cpfr) * (1._r8 - fcur) - if (woody(ivt(p)) == 1._r8) then + if (woody(ivt(p)) >= 1.0_r8) then ppool_to_livestemp(p) = (nlc * f3 * f4 / cplw) * fcur ppool_to_livestemp_storage(p) = (nlc * f3 * f4 / cplw) * (1._r8 -fcur) ppool_to_deadstemp(p) = (nlc * f3 * (1._r8 - f4) / cpdw) *fcur @@ -2711,7 +2711,7 @@ subroutine Allocation3_PlantCNPAlloc (bounds , & ! growth is assigned here. gresp_storage = cpool_to_leafc_storage(p) + cpool_to_frootc_storage(p) - if (woody(ivt(p)) == 1._r8) then + if (woody(ivt(p)) >= 1.0_r8) then gresp_storage = gresp_storage + cpool_to_livestemc_storage(p) gresp_storage = gresp_storage + cpool_to_deadstemc_storage(p) gresp_storage = gresp_storage + cpool_to_livecrootc_storage(p) @@ -2748,7 +2748,7 @@ subroutine Allocation3_PlantCNPAlloc (bounds , & npool_to_frootn(p) = cpool_to_frootc(p) / cnfr npool_to_frootn_storage(p) = cpool_to_frootc_storage(p) / cnfr - if (woody(ivt(p)) == 1._r8) then + if (woody(ivt(p)) >= 1.0_r8) then supplement_to_plantn(p) = supplement_to_plantn(p) + cpool_to_livestemc(p) / cnlw - npool_to_livestemn(p) supplement_to_plantn(p) = supplement_to_plantn(p) + cpool_to_livestemc_storage(p) / cnlw & - npool_to_livestemn_storage(p) @@ -2815,7 +2815,7 @@ subroutine Allocation3_PlantCNPAlloc (bounds , & ppool_to_frootp(p) = cpool_to_frootc(p) / cpfr ppool_to_frootp_storage(p) = cpool_to_frootc_storage(p) / cpfr - if (woody(ivt(p)) == 1._r8) then + if (woody(ivt(p)) >= 1.0_r8) then supplement_to_plantp(p) = supplement_to_plantp(p) + max(cpool_to_livestemc(p) / cplw & - ppool_to_livestemp(p),0._r8) @@ -3891,7 +3891,7 @@ subroutine dynamic_plant_alloc( nutrient_scalar, water_scalar, laindex, alloc_le alloc_froot = min(alloc_froot, 0.4_r8) ! stem allocation - if (woody == 1.0_r8) then + if (woody >= 1.0_r8) then alloc_stem = alloc_s0 * 3.0_r8 * min(nu_scalar,w_scalar) / (2.0_r8 * light_scalar + min(nu_scalar,w_scalar)) else alloc_stem = 0.0_r8 @@ -3908,7 +3908,7 @@ subroutine dynamic_plant_alloc( nutrient_scalar, water_scalar, laindex, alloc_le ! if lai greater than laimax then no allocation to leaf; leaf allocation goes to stem or fine root if (laindex > laimax) then - if (woody == 1.0_r8) then + if (woody >= 1.0_r8) then alloc_stem = alloc_stem + alloc_leaf/2._r8 - 0.005_r8 alloc_froot = alloc_froot + alloc_leaf/2._r8 - 0.005_r8 else diff --git a/components/elm/src/biogeochem/CNAllocationBetrMod.F90 b/components/elm/src/biogeochem/CNAllocationBetrMod.F90 index 9701eebda607..42fad84a9d1d 100644 --- a/components/elm/src/biogeochem/CNAllocationBetrMod.F90 +++ b/components/elm/src/biogeochem/CNAllocationBetrMod.F90 @@ -643,7 +643,7 @@ subroutine Allocation1_PlantNPDemand (bounds, num_soilc, filter_soilc, num_soilp ! These fluxes should already be in gC/m2/s mr = leaf_mr(p) + froot_mr(p) - if (woody(ivt(p)) == 1.0_r8) then + if (woody(ivt(p)) >= 1.0_r8) then mr = mr + livestem_mr(p) + livecroot_mr(p) else if (ivt(p) >= npcropmin) then if (croplive(p)) mr = mr + livestem_mr(p) + grain_mr(p) @@ -852,7 +852,7 @@ subroutine Allocation1_PlantNPDemand (bounds, num_soilc, filter_soilc, num_soilp ! based on available C, use constant allometric relationships to ! determine N requirements - if (woody(ivt(p)) == 1.0_r8) then + if (woody(ivt(p)) >= 1.0_r8) then c_allometry(p) = (1._r8+g1)*(1._r8+f1+f3*(1._r8+f2)) n_allometry(p) = 1._r8/cnl + f1/cnfr + (f3*f4*(1._r8+f2))/cnlw + & (f3*(1._r8-f4)*(1._r8+f2))/cndw @@ -1434,7 +1434,7 @@ subroutine Allocation3_PlantCNPAlloc (bounds , & plant_palloc(p) = sminp_to_ppool(p) + retransp_to_ppool(p) mr = leaf_mr(p) + froot_mr(p) - if (woody(ivt(p)) == 1.0_r8) then + if (woody(ivt(p)) >= 1.0_r8) then mr = mr + livestem_mr(p) + livecroot_mr(p) else if (ivt(p) >= npcropmin) then if (croplive(p)) mr = mr + livestem_mr(p) + grain_mr(p) @@ -1523,7 +1523,7 @@ subroutine Allocation3_PlantCNPAlloc (bounds , & plant_calloc(p) = availc(p) ! here no down-regulation on allocatable C here, NP limitation is implemented in leaf-level NP control on GPP - if (woody(ivt(p)) == 1.0_r8) then + if (woody(ivt(p)) >= 1.0_r8) then c_allometry(p) = (1._r8+g1)*(1._r8+f1+f3*(1._r8+f2)) n_allometry(p) = 1._r8/cnl + f1/cnfr + (f3*f4*(1._r8+f2))/cnlw + & (f3*(1._r8-f4)*(1._r8+f2))/cndw @@ -1604,7 +1604,7 @@ subroutine Allocation3_PlantCNPAlloc (bounds , & cpool_to_xsmrpool(p) = cpool_to_xsmrpool(p) + nlc * (1._r8 - fcur) * (1 + g1) cpool_to_xsmrpool(p) = cpool_to_xsmrpool(p) + nlc * f1 * fcur * (1 + g1) cpool_to_xsmrpool(p) = cpool_to_xsmrpool(p) + nlc * f1 * (1._r8 - fcur) * (1 + g1) - if (woody(ivt(p)) == 1._r8) then + if (woody(ivt(p)) >= 1.0_r8) then cpool_to_xsmrpool(p) = cpool_to_xsmrpool(p) + nlc * f3 * f4 * fcur * (1 + g1) cpool_to_xsmrpool(p) = cpool_to_xsmrpool(p) + nlc * f3 * f4 * (1._r8 - fcur) * (1 + g1) cpool_to_xsmrpool(p) = cpool_to_xsmrpool(p) + nlc * f3 * (1._r8 - f4) * fcur * (1 + g1) @@ -1635,7 +1635,7 @@ subroutine Allocation3_PlantCNPAlloc (bounds , & cpool_to_leafc_storage(p) = nlc * (1._r8 - fcur) cpool_to_frootc(p) = nlc * f1 * fcur cpool_to_frootc_storage(p) = nlc * f1 * (1._r8 - fcur) - if (woody(ivt(p)) == 1._r8) then + if (woody(ivt(p)) >= 1.0_r8) then cpool_to_livestemc(p) = nlc * f3 * f4 * fcur cpool_to_livestemc_storage(p) = nlc * f3 * f4 * (1._r8 - fcur) cpool_to_deadstemc(p) = nlc * f3 * (1._r8 - f4) * fcur @@ -1688,7 +1688,7 @@ subroutine Allocation3_PlantCNPAlloc (bounds , & npool_to_leafn_storage(p) = (nlc / cnl) * (1._r8 - fcur) npool_to_frootn(p) = (nlc * f1 / cnfr) * fcur npool_to_frootn_storage(p) = (nlc * f1 / cnfr) * (1._r8 - fcur) - if (woody(ivt(p)) == 1._r8) then + if (woody(ivt(p)) >= 1.0_r8) then npool_to_livestemn(p) = (nlc * f3 * f4 / cnlw) * fcur npool_to_livestemn_storage(p) = (nlc * f3 * f4 / cnlw) * (1._r8 - fcur) npool_to_deadstemn(p) = (nlc * f3 * (1._r8 - f4) / cndw) * fcur @@ -1732,7 +1732,7 @@ subroutine Allocation3_PlantCNPAlloc (bounds , & ppool_to_leafp_storage(p) = (nlc / cpl) * (1._r8 - fcur) ppool_to_frootp(p) = (nlc * f1 / cpfr) * fcur ppool_to_frootp_storage(p) = (nlc * f1 / cpfr) * (1._r8 - fcur) - if (woody(ivt(p)) == 1._r8) then + if (woody(ivt(p)) >= 1.0_r8) then ppool_to_livestemp(p) = (nlc * f3 * f4 / cplw) * fcur ppool_to_livestemp_storage(p) = (nlc * f3 * f4 / cplw) * (1._r8 -fcur) ppool_to_deadstemp(p) = (nlc * f3 * (1._r8 - f4) / cpdw) *fcur @@ -1766,7 +1766,7 @@ subroutine Allocation3_PlantCNPAlloc (bounds , & ! growth is assigned here. gresp_storage = cpool_to_leafc_storage(p) + cpool_to_frootc_storage(p) - if (woody(ivt(p)) == 1._r8) then + if (woody(ivt(p)) >= 1.0_r8) then gresp_storage = gresp_storage + cpool_to_livestemc_storage(p) gresp_storage = gresp_storage + cpool_to_deadstemc_storage(p) gresp_storage = gresp_storage + cpool_to_livecrootc_storage(p) @@ -1797,7 +1797,7 @@ subroutine Allocation3_PlantCNPAlloc (bounds , & npool_to_frootn(p) = cpool_to_frootc(p) / cnfr npool_to_frootn_storage(p) = cpool_to_frootc_storage(p) / cnfr - if (woody(ivt(p)) == 1._r8) then + if (woody(ivt(p)) >= 1.0_r8) then supplement_to_sminn_vr(c,1) = supplement_to_sminn_vr(c,1) + cpool_to_livestemc(p) / cnlw - npool_to_livestemn(p) supplement_to_sminn_vr(c,1) = supplement_to_sminn_vr(c,1) + cpool_to_livestemc_storage(p) / cnlw & - npool_to_livestemn_storage(p) @@ -1864,7 +1864,7 @@ subroutine Allocation3_PlantCNPAlloc (bounds , & ppool_to_frootp(p) = cpool_to_frootc(p) / cpfr ppool_to_frootp_storage(p) = cpool_to_frootc_storage(p) / cpfr - if (woody(ivt(p)) == 1._r8) then + if (woody(ivt(p)) >= 1.0_r8) then supplement_to_sminp_vr(c,1) = supplement_to_sminp_vr(c,1) + max(cpool_to_livestemc(p) / cplw & - ppool_to_livestemp(p),0._r8) supplement_to_sminp_vr(c,1) = supplement_to_sminp_vr(c,1) + max(cpool_to_livestemc_storage(p) / cplw & diff --git a/components/elm/src/biogeochem/CNCarbonStateType.F90 b/components/elm/src/biogeochem/CNCarbonStateType.F90 index 2ed04f03231c..8f258bbb6a9a 100644 --- a/components/elm/src/biogeochem/CNCarbonStateType.F90 +++ b/components/elm/src/biogeochem/CNCarbonStateType.F90 @@ -477,7 +477,7 @@ subroutine InitCold(this, bounds, ratio, c12_carbonstate_vars) this%livestemc_storage_patch(p) = 0._r8 this%livestemc_xfer_patch(p) = 0._r8 - if (veg_vp%woody(veg_pp%itype(p)) == 1._r8) then + if (veg_vp%woody(veg_pp%itype(p)) >= 1.0_r8) then this%deadstemc_patch(p) = 0.1_r8 * ratio else this%deadstemc_patch(p) = 0._r8 diff --git a/components/elm/src/biogeochem/CNNStateUpdate1BeTRMod.F90 b/components/elm/src/biogeochem/CNNStateUpdate1BeTRMod.F90 index 6eee5f923da0..95d884de490f 100644 --- a/components/elm/src/biogeochem/CNNStateUpdate1BeTRMod.F90 +++ b/components/elm/src/biogeochem/CNNStateUpdate1BeTRMod.F90 @@ -90,7 +90,7 @@ subroutine NStateUpdate1(num_soilc, filter_soilc, num_soilp, filter_soilp, & veg_ns%frootn(p) = veg_ns%frootn(p) + veg_nf%frootn_xfer_to_frootn(p)*dt veg_ns%frootn_xfer(p) = veg_ns%frootn_xfer(p) - veg_nf%frootn_xfer_to_frootn(p)*dt - if (woody(ivt(p)) == 1.0_r8) then + if (woody(ivt(p)) >= 1.0_r8) then veg_ns%livestemn(p) = veg_ns%livestemn(p) + veg_nf%livestemn_xfer_to_livestemn(p)*dt veg_ns%livestemn_xfer(p) = veg_ns%livestemn_xfer(p) - veg_nf%livestemn_xfer_to_livestemn(p)*dt veg_ns%deadstemn(p) = veg_ns%deadstemn(p) + veg_nf%deadstemn_xfer_to_deadstemn(p)*dt @@ -116,7 +116,7 @@ subroutine NStateUpdate1(num_soilc, filter_soilc, num_soilp, filter_soilp, & veg_ns%retransn(p) = veg_ns%retransn(p) + veg_nf%leafn_to_retransn(p)*dt ! live wood turnover and retranslocation fluxes - if (woody(ivt(p)) == 1._r8) then + if (woody(ivt(p)) >= 1.0_r8) then veg_ns%livestemn(p) = veg_ns%livestemn(p) - veg_nf%livestemn_to_deadstemn(p)*dt veg_ns%deadstemn(p) = veg_ns%deadstemn(p) + veg_nf%livestemn_to_deadstemn(p)*dt veg_ns%livestemn(p) = veg_ns%livestemn(p) - veg_nf%livestemn_to_retransn(p)*dt @@ -153,7 +153,7 @@ subroutine NStateUpdate1(num_soilc, filter_soilc, num_soilp, filter_soilp, & veg_ns%npool(p) = veg_ns%npool(p) - veg_nf%npool_to_frootn_storage(p)*dt veg_ns%frootn_storage(p) = veg_ns%frootn_storage(p) + veg_nf%npool_to_frootn_storage(p)*dt - if (woody(ivt(p)) == 1._r8) then + if (woody(ivt(p)) >= 1.0_r8) then veg_ns%npool(p) = veg_ns%npool(p) - veg_nf%npool_to_livestemn(p)*dt veg_ns%livestemn(p) = veg_ns%livestemn(p) + veg_nf%npool_to_livestemn(p)*dt veg_ns%npool(p) = veg_ns%npool(p) - veg_nf%npool_to_livestemn_storage(p)*dt @@ -189,7 +189,7 @@ subroutine NStateUpdate1(num_soilc, filter_soilc, num_soilp, filter_soilp, & veg_ns%frootn_storage(p) = veg_ns%frootn_storage(p) - veg_nf%frootn_storage_to_xfer(p)*dt veg_ns%frootn_xfer(p) = veg_ns%frootn_xfer(p) + veg_nf%frootn_storage_to_xfer(p)*dt - if (woody(ivt(p)) == 1._r8) then + if (woody(ivt(p)) >= 1.0_r8) then veg_ns%livestemn_storage(p) = veg_ns%livestemn_storage(p) - veg_nf%livestemn_storage_to_xfer(p)*dt veg_ns%livestemn_xfer(p) = veg_ns%livestemn_xfer(p) + veg_nf%livestemn_storage_to_xfer(p)*dt veg_ns%deadstemn_storage(p) = veg_ns%deadstemn_storage(p) - veg_nf%deadstemn_storage_to_xfer(p)*dt diff --git a/components/elm/src/biogeochem/CNNitrogenStateType.F90 b/components/elm/src/biogeochem/CNNitrogenStateType.F90 index 003e34e132d9..dda6477899a7 100644 --- a/components/elm/src/biogeochem/CNNitrogenStateType.F90 +++ b/components/elm/src/biogeochem/CNNitrogenStateType.F90 @@ -588,7 +588,7 @@ subroutine InitCold(this, bounds, & ! tree types need to be initialized with some stem mass so that ! roughness length is not zero in canopy flux calculation - if (veg_vp%woody(veg_pp%itype(p)) == 1._r8) then + if (veg_vp%woody(veg_pp%itype(p)) >= 1.0_r8) then this%deadstemn_patch(p) = deadstemc_patch(p) / veg_vp%deadwdcn(veg_pp%itype(p)) else this%deadstemn_patch(p) = 0._r8 diff --git a/components/elm/src/biogeochem/CNPhenologyBeTRMod.F90 b/components/elm/src/biogeochem/CNPhenologyBeTRMod.F90 index 4bc23896427c..23f461ad3055 100644 --- a/components/elm/src/biogeochem/CNPhenologyBeTRMod.F90 +++ b/components/elm/src/biogeochem/CNPhenologyBeTRMod.F90 @@ -693,7 +693,7 @@ subroutine CNSeasonDecidPhenology (num_soilp, filter_soilp , & frootn_xfer_to_frootn(p) = 0.0_r8 leafp_xfer_to_leafp(p) = 0.0_r8 frootp_xfer_to_frootp(p) = 0.0_r8 - if (woody(ivt(p)) == 1.0_r8) then + if (woody(ivt(p)) >= 1.0_r8) then livestemc_xfer_to_livestemc(p) = 0.0_r8 deadstemc_xfer_to_deadstemc(p) = 0.0_r8 livecrootc_xfer_to_livecrootc(p) = 0.0_r8 @@ -714,7 +714,7 @@ subroutine CNSeasonDecidPhenology (num_soilp, filter_soilp , & frootc_xfer(p) = 0.0_r8 frootn_xfer(p) = 0.0_r8 frootp_xfer(p) = 0.0_r8 - if (woody(ivt(p)) == 1.0_r8) then + if (woody(ivt(p)) >= 1.0_r8) then livestemc_xfer(p) = 0.0_r8 livestemn_xfer(p) = 0.0_r8 livestemp_xfer(p) = 0.0_r8 @@ -777,7 +777,7 @@ subroutine CNSeasonDecidPhenology (num_soilp, filter_soilp , & ! set carbon fluxes for shifting storage pools to transfer pools leafc_storage_to_xfer(p) = fstor2tran * leafc_storage(p)/dt frootc_storage_to_xfer(p) = fstor2tran * frootc_storage(p)/dt - if (woody(ivt(p)) == 1.0_r8) then + if (woody(ivt(p)) >= 1.0_r8) then livestemc_storage_to_xfer(p) = fstor2tran * livestemc_storage(p)/dt deadstemc_storage_to_xfer(p) = fstor2tran * deadstemc_storage(p)/dt livecrootc_storage_to_xfer(p) = fstor2tran * livecrootc_storage(p)/dt @@ -788,7 +788,7 @@ subroutine CNSeasonDecidPhenology (num_soilp, filter_soilp , & ! set nitrogen fluxes for shifting storage pools to transfer pools leafn_storage_to_xfer(p) = fstor2tran * leafn_storage(p)/dt frootn_storage_to_xfer(p) = fstor2tran * frootn_storage(p)/dt - if (woody(ivt(p)) == 1.0_r8) then + if (woody(ivt(p)) >= 1.0_r8) then livestemn_storage_to_xfer(p) = fstor2tran * livestemn_storage(p)/dt deadstemn_storage_to_xfer(p) = fstor2tran * deadstemn_storage(p)/dt livecrootn_storage_to_xfer(p) = fstor2tran * livecrootn_storage(p)/dt @@ -798,7 +798,7 @@ subroutine CNSeasonDecidPhenology (num_soilp, filter_soilp , & ! set phosphorus fluxes for shifting storage pools to transfer pools leafp_storage_to_xfer(p) = fstor2tran * leafp_storage(p)/dt frootp_storage_to_xfer(p) = fstor2tran * frootp_storage(p)/dt - if (woody(ivt(p)) == 1.0_r8) then + if (woody(ivt(p)) >= 1.0_r8) then livestemp_storage_to_xfer(p) = fstor2tran * livestemp_storage(p)/dt deadstemp_storage_to_xfer(p) = fstor2tran * deadstemp_storage(p)/dt livecrootp_storage_to_xfer(p) = fstor2tran * livecrootp_storage(p)/dt @@ -1040,7 +1040,7 @@ subroutine CNStressDecidPhenology (num_soilp, filter_soilp , & frootn_xfer_to_frootn(p) = 0._r8 leafp_xfer_to_leafp(p) = 0._r8 frootp_xfer_to_frootp(p) = 0._r8 - if (woody(ivt(p)) == 1.0_r8) then + if (woody(ivt(p)) >= 1.0_r8) then livestemc_xfer_to_livestemc(p) = 0._r8 deadstemc_xfer_to_deadstemc(p) = 0._r8 livecrootc_xfer_to_livecrootc(p) = 0._r8 @@ -1061,7 +1061,7 @@ subroutine CNStressDecidPhenology (num_soilp, filter_soilp , & frootc_xfer(p) = 0._r8 frootn_xfer(p) = 0._r8 frootp_xfer(p) = 0._r8 - if (woody(ivt(p)) == 1.0_r8) then + if (woody(ivt(p)) >= 1.0_r8) then livestemc_xfer(p) = 0._r8 livestemn_xfer(p) = 0._r8 livestemp_xfer(p) = 0._r8 @@ -1148,7 +1148,7 @@ subroutine CNStressDecidPhenology (num_soilp, filter_soilp , & ! set carbon fluxes for shifting storage pools to transfer pools leafc_storage_to_xfer(p) = fstor2tran * leafc_storage(p)/dt frootc_storage_to_xfer(p) = fstor2tran * frootc_storage(p)/dt - if (woody(ivt(p)) == 1.0_r8) then + if (woody(ivt(p)) >= 1.0_r8) then livestemc_storage_to_xfer(p) = fstor2tran * livestemc_storage(p)/dt deadstemc_storage_to_xfer(p) = fstor2tran * deadstemc_storage(p)/dt livecrootc_storage_to_xfer(p) = fstor2tran * livecrootc_storage(p)/dt @@ -1159,7 +1159,7 @@ subroutine CNStressDecidPhenology (num_soilp, filter_soilp , & ! set nitrogen fluxes for shifting storage pools to transfer pools leafn_storage_to_xfer(p) = fstor2tran * leafn_storage(p)/dt frootn_storage_to_xfer(p) = fstor2tran * frootn_storage(p)/dt - if (woody(ivt(p)) == 1.0_r8) then + if (woody(ivt(p)) >= 1.0_r8) then livestemn_storage_to_xfer(p) = fstor2tran * livestemn_storage(p)/dt deadstemn_storage_to_xfer(p) = fstor2tran * deadstemn_storage(p)/dt livecrootn_storage_to_xfer(p) = fstor2tran * livecrootn_storage(p)/dt @@ -1169,7 +1169,7 @@ subroutine CNStressDecidPhenology (num_soilp, filter_soilp , & ! set phosphorus fluxes for shifting storage pools to transfer pools leafp_storage_to_xfer(p) = fstor2tran * leafp_storage(p)/dt frootp_storage_to_xfer(p) = fstor2tran * frootp_storage(p)/dt - if (woody(ivt(p)) == 1.0_r8) then + if (woody(ivt(p)) >= 1.0_r8) then livestemp_storage_to_xfer(p) = fstor2tran * livestemp_storage(p)/dt deadstemp_storage_to_xfer(p) = fstor2tran * deadstemp_storage(p)/dt livecrootp_storage_to_xfer(p) = fstor2tran * livecrootp_storage(p)/dt @@ -1268,7 +1268,7 @@ subroutine CNStressDecidPhenology (num_soilp, filter_soilp , & leafc_storage_to_xfer(p) = leafc_storage(p) * bgtr(p) frootc_storage_to_xfer(p) = frootc_storage(p) * bgtr(p) - if (woody(ivt(p)) == 1.0_r8) then + if (woody(ivt(p)) >= 1.0_r8) then livestemc_storage_to_xfer(p) = livestemc_storage(p) * bgtr(p) deadstemc_storage_to_xfer(p) = deadstemc_storage(p) * bgtr(p) livecrootc_storage_to_xfer(p) = livecrootc_storage(p) * bgtr(p) @@ -1279,7 +1279,7 @@ subroutine CNStressDecidPhenology (num_soilp, filter_soilp , & ! set nitrogen fluxes for shifting storage pools to transfer pools leafn_storage_to_xfer(p) = leafn_storage(p) * bgtr(p) frootn_storage_to_xfer(p) = frootn_storage(p) * bgtr(p) - if (woody(ivt(p)) == 1.0_r8) then + if (woody(ivt(p)) >= 1.0_r8) then livestemn_storage_to_xfer(p) = livestemn_storage(p) * bgtr(p) deadstemn_storage_to_xfer(p) = deadstemn_storage(p) * bgtr(p) livecrootn_storage_to_xfer(p) = livecrootn_storage(p) * bgtr(p) @@ -1290,7 +1290,7 @@ subroutine CNStressDecidPhenology (num_soilp, filter_soilp , & ! set phosphorus fluxes for shifting storage pools to transfer pools leafp_storage_to_xfer(p) = leafp_storage(p) * bgtr(p) frootp_storage_to_xfer(p) = frootp_storage(p) * bgtr(p) - if (woody(ivt(p)) == 1.0_r8) then + if (woody(ivt(p)) >= 1.0_r8) then livestemp_storage_to_xfer(p) = livestemp_storage(p) * bgtr(p) deadstemp_storage_to_xfer(p) = deadstemp_storage(p) * bgtr(p) livecrootp_storage_to_xfer(p) = livecrootp_storage(p) * bgtr(p) @@ -2362,7 +2362,7 @@ subroutine CNOnsetGrowth (num_soilp, filter_soilp, & frootn_xfer_to_frootn(p) = t1 * frootn_xfer(p) leafp_xfer_to_leafp(p) = t1 * leafp_xfer(p) frootp_xfer_to_frootp(p) = t1 * frootp_xfer(p) - if (woody(ivt(p)) == 1.0_r8) then + if (woody(ivt(p)) >= 1.0_r8) then livestemc_xfer_to_livestemc(p) = t1 * livestemc_xfer(p) deadstemc_xfer_to_deadstemc(p) = t1 * deadstemc_xfer(p) livecrootc_xfer_to_livecrootc(p) = t1 * livecrootc_xfer(p) @@ -2391,7 +2391,7 @@ subroutine CNOnsetGrowth (num_soilp, filter_soilp, & frootn_xfer_to_frootn(p) = frootn_xfer(p) / dt leafp_xfer_to_leafp(p) = leafp_xfer(p) / dt frootp_xfer_to_frootp(p) = frootp_xfer(p) / dt - if (woody(ivt(p)) == 1.0_r8) then + if (woody(ivt(p)) >= 1.0_r8) then livestemc_xfer_to_livestemc(p) = livestemc_xfer(p) / dt deadstemc_xfer_to_deadstemc(p) = deadstemc_xfer(p) / dt livecrootc_xfer_to_livecrootc(p) = livecrootc_xfer(p) / dt @@ -2909,7 +2909,7 @@ subroutine CNLivewoodTurnover (num_soilp, filter_soilp, & p = filter_soilp(fp) ! only calculate these fluxes for woody types - if (woody(ivt(p)) > 0._r8) then + if (woody(ivt(p)) >= 1.0_r8) then if ( nu_com .eq. 'RD') then ! live stem to dead stem turnover diff --git a/components/elm/src/biogeochem/CarbonStateUpdate1Mod.F90 b/components/elm/src/biogeochem/CarbonStateUpdate1Mod.F90 index 057fd0e56b6e..a371a44c537a 100644 --- a/components/elm/src/biogeochem/CarbonStateUpdate1Mod.F90 +++ b/components/elm/src/biogeochem/CarbonStateUpdate1Mod.F90 @@ -274,7 +274,7 @@ subroutine CarbonStateUpdate1(bounds, & veg_cs%leafc_xfer(p) = veg_cs%leafc_xfer(p) - veg_cf%leafc_xfer_to_leafc(p)*dt veg_cs%frootc(p) = veg_cs%frootc(p) + veg_cf%frootc_xfer_to_frootc(p)*dt veg_cs%frootc_xfer(p) = veg_cs%frootc_xfer(p) - veg_cf%frootc_xfer_to_frootc(p)*dt - if (woody(ivt(p)) == 1._r8) then + if (woody(ivt(p)) >= 1.0_r8) then veg_cs%livestemc(p) = veg_cs%livestemc(p) + veg_cf%livestemc_xfer_to_livestemc(p)*dt veg_cs%livestemc_xfer(p) = veg_cs%livestemc_xfer(p) - veg_cf%livestemc_xfer_to_livestemc(p)*dt veg_cs%deadstemc(p) = veg_cs%deadstemc(p) + veg_cf%deadstemc_xfer_to_deadstemc(p)*dt @@ -297,7 +297,7 @@ subroutine CarbonStateUpdate1(bounds, & veg_cs%frootc(p) = veg_cs%frootc(p) - veg_cf%frootc_to_litter(p)*dt ! livewood turnover fluxes - if (woody(ivt(p)) == 1._r8) then + if (woody(ivt(p)) >= 1.0_r8) then veg_cs%livestemc(p) = veg_cs%livestemc(p) - veg_cf%livestemc_to_deadstemc(p)*dt veg_cs%deadstemc(p) = veg_cs%deadstemc(p) + veg_cf%livestemc_to_deadstemc(p)*dt veg_cs%livecrootc(p) = veg_cs%livecrootc(p) - veg_cf%livecrootc_to_deadcrootc(p)*dt @@ -315,7 +315,7 @@ subroutine CarbonStateUpdate1(bounds, & veg_cs%cpool(p) = veg_cs%cpool(p) - veg_cf%cpool_to_xsmrpool(p)*dt veg_cs%cpool(p) = veg_cs%cpool(p) - veg_cf%leaf_curmr(p)*dt veg_cs%cpool(p) = veg_cs%cpool(p) - veg_cf%froot_curmr(p)*dt - if (woody(ivt(p)) == 1._r8) then + if (woody(ivt(p)) >= 1.0_r8) then veg_cs%cpool(p) = veg_cs%cpool(p) - veg_cf%livestem_curmr(p)*dt veg_cs%cpool(p) = veg_cs%cpool(p) - veg_cf%livecroot_curmr(p)*dt end if @@ -333,7 +333,7 @@ subroutine CarbonStateUpdate1(bounds, & if (nu_com .ne. 'RD') then veg_cs%xsmrpool(p) = veg_cs%xsmrpool(p) - veg_cf%xsmrpool_turnover(p)*dt end if - if (woody(ivt(p)) == 1._r8) then + if (woody(ivt(p)) >= 1.0_r8) then veg_cs%xsmrpool(p) = veg_cs%xsmrpool(p) - veg_cf%livestem_xsmr(p)*dt veg_cs%xsmrpool(p) = veg_cs%xsmrpool(p) - veg_cf%livecroot_xsmr(p)*dt end if @@ -355,7 +355,7 @@ subroutine CarbonStateUpdate1(bounds, & veg_cs%frootc(p) = veg_cs%frootc(p) + veg_cf%cpool_to_frootc(p)*dt veg_cs%cpool(p) = veg_cs%cpool(p) - veg_cf%cpool_to_frootc_storage(p)*dt veg_cs%frootc_storage(p) = veg_cs%frootc_storage(p) + veg_cf%cpool_to_frootc_storage(p)*dt - if (woody(ivt(p)) == 1._r8) then + if (woody(ivt(p)) >= 1.0_r8) then veg_cs%cpool(p) = veg_cs%cpool(p) - veg_cf%cpool_to_livestemc(p)*dt veg_cs%livestemc(p) = veg_cs%livestemc(p) + veg_cf%cpool_to_livestemc(p)*dt veg_cs%cpool(p) = veg_cs%cpool(p) - veg_cf%cpool_to_livestemc_storage(p)*dt @@ -387,7 +387,7 @@ subroutine CarbonStateUpdate1(bounds, & ! growth respiration fluxes for current growth veg_cs%cpool(p) = veg_cs%cpool(p) - veg_cf%cpool_leaf_gr(p)*dt veg_cs%cpool(p) = veg_cs%cpool(p) - veg_cf%cpool_froot_gr(p)*dt - if (woody(ivt(p)) == 1._r8) then + if (woody(ivt(p)) >= 1.0_r8) then veg_cs%cpool(p) = veg_cs%cpool(p) - veg_cf%cpool_livestem_gr(p)*dt veg_cs%cpool(p) = veg_cs%cpool(p) - veg_cf%cpool_deadstem_gr(p)*dt veg_cs%cpool(p) = veg_cs%cpool(p) - veg_cf%cpool_livecroot_gr(p)*dt @@ -401,7 +401,7 @@ subroutine CarbonStateUpdate1(bounds, & ! growth respiration for transfer growth veg_cs%gresp_xfer(p) = veg_cs%gresp_xfer(p) - veg_cf%transfer_leaf_gr(p)*dt veg_cs%gresp_xfer(p) = veg_cs%gresp_xfer(p) - veg_cf%transfer_froot_gr(p)*dt - if (woody(ivt(p)) == 1._r8) then + if (woody(ivt(p)) >= 1.0_r8) then veg_cs%gresp_xfer(p) = veg_cs%gresp_xfer(p) - veg_cf%transfer_livestem_gr(p)*dt veg_cs%gresp_xfer(p) = veg_cs%gresp_xfer(p) - veg_cf%transfer_deadstem_gr(p)*dt veg_cs%gresp_xfer(p) = veg_cs%gresp_xfer(p) - veg_cf%transfer_livecroot_gr(p)*dt @@ -415,7 +415,7 @@ subroutine CarbonStateUpdate1(bounds, & ! growth respiration at time of storage veg_cs%cpool(p) = veg_cs%cpool(p) - veg_cf%cpool_leaf_storage_gr(p)*dt veg_cs%cpool(p) = veg_cs%cpool(p) - veg_cf%cpool_froot_storage_gr(p)*dt - if (woody(ivt(p)) == 1._r8) then + if (woody(ivt(p)) >= 1.0_r8) then veg_cs%cpool(p) = veg_cs%cpool(p) - veg_cf%cpool_livestem_storage_gr(p)*dt veg_cs%cpool(p) = veg_cs%cpool(p) - veg_cf%cpool_deadstem_storage_gr(p)*dt veg_cs%cpool(p) = veg_cs%cpool(p) - veg_cf%cpool_livecroot_storage_gr(p)*dt @@ -435,7 +435,7 @@ subroutine CarbonStateUpdate1(bounds, & veg_cs%leafc_xfer(p) = veg_cs%leafc_xfer(p) + veg_cf%leafc_storage_to_xfer(p)*dt veg_cs%frootc_storage(p) = veg_cs%frootc_storage(p) - veg_cf%frootc_storage_to_xfer(p)*dt veg_cs%frootc_xfer(p) = veg_cs%frootc_xfer(p) + veg_cf%frootc_storage_to_xfer(p)*dt - if (woody(ivt(p)) == 1._r8) then + if (woody(ivt(p)) >= 1.0_r8) then veg_cs%livestemc_storage(p) = veg_cs%livestemc_storage(p) - veg_cf%livestemc_storage_to_xfer(p)*dt veg_cs%livestemc_xfer(p) = veg_cs%livestemc_xfer(p) + veg_cf%livestemc_storage_to_xfer(p)*dt veg_cs%deadstemc_storage(p) = veg_cs%deadstemc_storage(p) - veg_cf%deadstemc_storage_to_xfer(p)*dt diff --git a/components/elm/src/biogeochem/ComputeSeedMod.F90 b/components/elm/src/biogeochem/ComputeSeedMod.F90 index 61b916d64f35..9b7ebf8838dc 100644 --- a/components/elm/src/biogeochem/ComputeSeedMod.F90 +++ b/components/elm/src/biogeochem/ComputeSeedMod.F90 @@ -124,7 +124,7 @@ subroutine ComputeSeedAmounts(p, & if (pft_type /= noveg) then my_leaf_seed = leafc_seed_param * & SpeciesTypeMultiplier(species, pft_type, COMPONENT_LEAF) - if (veg_vp%woody(pft_type) == 1._r8) then + if (veg_vp%woody(pft_type) >= 1.0_r8) then my_deadstem_seed = deadstemc_seed_param * & SpeciesTypeMultiplier(species, pft_type, COMPONENT_DEADWOOD) end if diff --git a/components/elm/src/biogeochem/GrowthRespMod.F90 b/components/elm/src/biogeochem/GrowthRespMod.F90 index f499dedb2e0f..a5002d108e51 100644 --- a/components/elm/src/biogeochem/GrowthRespMod.F90 +++ b/components/elm/src/biogeochem/GrowthRespMod.F90 @@ -133,7 +133,7 @@ subroutine GrowthResp(num_soilp, filter_soilp) transfer_froot_gr(p) = frootc_xfer_to_frootc(p) * grperc(ivt(p)) * & (1._r8 - grpnow(ivt(p))) - if (woody(ivt(p)) == 1._r8) then + if (woody(ivt(p)) >= 1.0_r8) then cpool_livestem_gr(p) = cpool_to_livestemc(p) * grperc(ivt(p)) cpool_livestem_storage_gr(p) = cpool_to_livestemc_storage(p) * & grperc(ivt(p)) * grpnow(ivt(p)) diff --git a/components/elm/src/biogeochem/MaintenanceRespMod.F90 b/components/elm/src/biogeochem/MaintenanceRespMod.F90 index ef83ca92ff60..eab60926ab60 100644 --- a/components/elm/src/biogeochem/MaintenanceRespMod.F90 +++ b/components/elm/src/biogeochem/MaintenanceRespMod.F90 @@ -182,7 +182,7 @@ subroutine MaintenanceResp(bounds, & end if - if (woody(ivt(p)) == 1) then + if (woody(ivt(p)) >= 1.0_r8) then livestem_mr(p) = livestemn(p)*br_mr*tc livecroot_mr(p) = livecrootn(p)*br_mr*tc else if (ivt(p) >= npcropmin .and. livestemn(p) .gt. 0._r8) then diff --git a/components/elm/src/biogeochem/NitrogenStateUpdate1Mod.F90 b/components/elm/src/biogeochem/NitrogenStateUpdate1Mod.F90 index 1eefadd7bead..14d834245f5a 100644 --- a/components/elm/src/biogeochem/NitrogenStateUpdate1Mod.F90 +++ b/components/elm/src/biogeochem/NitrogenStateUpdate1Mod.F90 @@ -286,7 +286,7 @@ subroutine NitrogenStateUpdate1(num_soilc, filter_soilc, num_soilp, filter_soilp veg_ns%frootn(p) = veg_ns%frootn(p) + veg_nf%frootn_xfer_to_frootn(p)*dt veg_ns%frootn_xfer(p) = veg_ns%frootn_xfer(p) - veg_nf%frootn_xfer_to_frootn(p)*dt - if (woody(ivt(p)) == 1.0_r8) then + if (woody(ivt(p)) >= 1.0_r8) then veg_ns%livestemn(p) = veg_ns%livestemn(p) + veg_nf%livestemn_xfer_to_livestemn(p)*dt veg_ns%livestemn_xfer(p) = veg_ns%livestemn_xfer(p) - veg_nf%livestemn_xfer_to_livestemn(p)*dt veg_ns%deadstemn(p) = veg_ns%deadstemn(p) + veg_nf%deadstemn_xfer_to_deadstemn(p)*dt @@ -312,7 +312,7 @@ subroutine NitrogenStateUpdate1(num_soilc, filter_soilc, num_soilp, filter_soilp veg_ns%retransn(p) = veg_ns%retransn(p) + veg_nf%leafn_to_retransn(p)*dt ! live wood turnover and retranslocation fluxes - if (woody(ivt(p)) == 1._r8) then + if (woody(ivt(p)) >= 1.0_r8) then veg_ns%livestemn(p) = veg_ns%livestemn(p) - veg_nf%livestemn_to_deadstemn(p)*dt veg_ns%deadstemn(p) = veg_ns%deadstemn(p) + veg_nf%livestemn_to_deadstemn(p)*dt veg_ns%livestemn(p) = veg_ns%livestemn(p) - veg_nf%livestemn_to_retransn(p)*dt @@ -354,7 +354,7 @@ subroutine NitrogenStateUpdate1(num_soilc, filter_soilc, num_soilp, filter_soilp veg_ns%npool(p) = veg_ns%npool(p) - veg_nf%npool_to_frootn_storage(p)*dt veg_ns%frootn_storage(p) = veg_ns%frootn_storage(p) + veg_nf%npool_to_frootn_storage(p)*dt - if (woody(ivt(p)) == 1._r8) then + if (woody(ivt(p)) >= 1.0_r8) then veg_ns%npool(p) = veg_ns%npool(p) - veg_nf%npool_to_livestemn(p)*dt veg_ns%livestemn(p) = veg_ns%livestemn(p) + veg_nf%npool_to_livestemn(p)*dt veg_ns%npool(p) = veg_ns%npool(p) - veg_nf%npool_to_livestemn_storage(p)*dt @@ -390,7 +390,7 @@ subroutine NitrogenStateUpdate1(num_soilc, filter_soilc, num_soilp, filter_soilp veg_ns%frootn_storage(p) = veg_ns%frootn_storage(p) - veg_nf%frootn_storage_to_xfer(p)*dt veg_ns%frootn_xfer(p) = veg_ns%frootn_xfer(p) + veg_nf%frootn_storage_to_xfer(p)*dt - if (woody(ivt(p)) == 1._r8) then + if (woody(ivt(p)) >= 1.0_r8) then veg_ns%livestemn_storage(p) = veg_ns%livestemn_storage(p) - veg_nf%livestemn_storage_to_xfer(p)*dt veg_ns%livestemn_xfer(p) = veg_ns%livestemn_xfer(p) + veg_nf%livestemn_storage_to_xfer(p)*dt veg_ns%deadstemn_storage(p) = veg_ns%deadstemn_storage(p) - veg_nf%deadstemn_storage_to_xfer(p)*dt diff --git a/components/elm/src/biogeochem/PhenologyFluxLimitMod.F90 b/components/elm/src/biogeochem/PhenologyFluxLimitMod.F90 index b6d05460c0bb..786efbe6323a 100644 --- a/components/elm/src/biogeochem/PhenologyFluxLimitMod.F90 +++ b/components/elm/src/biogeochem/PhenologyFluxLimitMod.F90 @@ -630,7 +630,7 @@ subroutine carbon_flux_limiter(bounds, num_soilc, filter_soilc,& ystates(s_frootc) = veg_cs%frootc(p) ystates(s_frootc_xfer) = veg_cs%frootc_xfer(p) ystates(s_frootc_storage) = veg_cs%frootc_storage(p) - if (woody(ivt(p)) == 1._r8) then + if (woody(ivt(p)) >= 1.0_r8) then ystates(s_livestemc) = veg_cs%livestemc(p) ystates(s_livestemc_xfer) = veg_cs%livestemc_xfer(p) ystates(s_livestemc_storage) = veg_cs%livestemc_storage(p) @@ -662,7 +662,7 @@ subroutine carbon_flux_limiter(bounds, num_soilc, filter_soilc,& + veg_cf%cpool_froot_gr(p) & + veg_cf%cpool_leaf_storage_gr(p) & + veg_cf%cpool_froot_storage_gr(p) - if (woody(ivt(p)) == 1._r8) then + if (woody(ivt(p)) >= 1.0_r8) then ar_p = ar_p & + veg_cf%livestem_curmr(p) & + veg_cf%livecroot_curmr(p) & @@ -692,7 +692,7 @@ subroutine carbon_flux_limiter(bounds, num_soilc, filter_soilc,& rfluxes(f_cpool_to_xsmrpool) = veg_cf%cpool_to_xsmrpool(p) rfluxes(f_cpool_to_gresp_storage) = veg_cf%cpool_to_gresp_storage(p) rfluxes(f_cpool_to_ar) = ar_p - if (woody(ivt(p)) == 1._r8) then + if (woody(ivt(p)) >= 1.0_r8) then rfluxes(f_cpool_to_livestemc) = veg_cf%cpool_to_livestemc(p) rfluxes(f_cpool_to_livestemc_storage) = veg_cf%cpool_to_livestemc_storage(p) rfluxes(f_cpool_to_deadstemc) = veg_cf%cpool_to_deadstemc(p) @@ -746,7 +746,7 @@ subroutine carbon_flux_limiter(bounds, num_soilc, filter_soilc,& call fpmax(rfluxes(f_cpool_to_xsmrpool) , veg_cf%cpool_to_xsmrpool(p)) call fpmax(rfluxes(f_cpool_to_gresp_storage) , veg_cf%cpool_to_gresp_storage(p)) - if (woody(ivt(p)) == 1._r8) then + if (woody(ivt(p)) >= 1.0_r8) then call fpmax(rfluxes(f_cpool_to_livestemc) , veg_cf%cpool_to_livestemc(p)) call fpmax(rfluxes(f_cpool_to_livestemc_storage) , veg_cf%cpool_to_livestemc_storage(p)) call fpmax(rfluxes(f_cpool_to_deadstemc) , veg_cf%cpool_to_deadstemc(p)) @@ -794,7 +794,7 @@ subroutine carbon_flux_limiter(bounds, num_soilc, filter_soilc,& call ascal(veg_cf%cpool_froot_gr(p) , rscal) call ascal(veg_cf%cpool_leaf_storage_gr(p) , rscal) call ascal(veg_cf%cpool_froot_storage_gr(p) , rscal) - if (woody(ivt(p)) == 1._r8) then + if (woody(ivt(p)) >= 1.0_r8) then call ascal(veg_cf%livestem_curmr(p) , rscal) call ascal(veg_cf%livecroot_curmr(p) , rscal) call ascal(veg_cf%cpool_livestem_gr(p) , rscal) @@ -864,7 +864,7 @@ subroutine nitrogen_flux_limiter(bounds, num_soilc, filter_soilc,& ystates(s_frootn) = veg_ns%frootn(p) ystates(s_frootn_xfer) = veg_ns%frootn_xfer(p) ystates(s_frootn_storage) = veg_ns%frootn_storage(p) - if (woody(ivt(p)) == 1.0_r8) then + if (woody(ivt(p)) >= 1.0_r8) then ystates(s_livestemn) = veg_ns%livestemn(p) ystates(s_livestemn_xfer) = veg_ns%livestemn_xfer(p) ystates(s_livestemn_storage) = veg_ns%livestemn_storage(p) @@ -894,7 +894,7 @@ subroutine nitrogen_flux_limiter(bounds, num_soilc, filter_soilc,& rfluxes(f_npool_to_leafn_storage) = veg_nf%npool_to_leafn_storage(p) rfluxes(f_npool_to_frootn) = veg_nf%npool_to_frootn(p) rfluxes(f_npool_to_frootn_storage) = veg_nf%npool_to_frootn_storage(p) - if (woody(ivt(p)) == 1.0_r8) then + if (woody(ivt(p)) >= 1.0_r8) then rfluxes(f_npool_to_livestemn) = veg_nf%npool_to_livestemn(p) rfluxes(f_npool_to_livestemn_storage) = veg_nf%npool_to_livestemn_storage(p) rfluxes(f_npool_to_livecrootn) = veg_nf%npool_to_livecrootn(p) @@ -950,7 +950,7 @@ subroutine nitrogen_flux_limiter(bounds, num_soilc, filter_soilc,& call fpmax(rfluxes(f_npool_to_leafn_storage) , veg_nf%npool_to_leafn_storage(p)) call fpmax(rfluxes(f_npool_to_frootn) , veg_nf%npool_to_frootn(p)) call fpmax(rfluxes(f_npool_to_frootn_storage) , veg_nf%npool_to_frootn_storage(p)) - if (woody(ivt(p)) == 1.0_r8) then + if (woody(ivt(p)) >= 1.0_r8) then call fpmax(rfluxes(f_npool_to_livestemn) , veg_nf%npool_to_livestemn(p)) call fpmax(rfluxes(f_npool_to_livestemn_storage) , veg_nf%npool_to_livestemn_storage(p)) call fpmax(rfluxes(f_npool_to_livecrootn) , veg_nf%npool_to_livecrootn(p)) @@ -1049,7 +1049,7 @@ subroutine phosphorus_flux_limiter(bounds, num_soilc, filter_soilc,& ystates(s_frootn) = veg_ps%frootp(p) ystates(s_frootn_xfer) = veg_ps%frootp_xfer(p) ystates(s_frootn_storage) = veg_ps%frootp_storage(p) - if (woody(ivt(p)) == 1.0_r8) then + if (woody(ivt(p)) >= 1.0_r8) then ystates(s_livestemn) = veg_ps%livestemp(p) ystates(s_livestemn_xfer) = veg_ps%livestemp_xfer(p) ystates(s_livestemn_storage) = veg_ps%livestemp_storage(p) @@ -1079,7 +1079,7 @@ subroutine phosphorus_flux_limiter(bounds, num_soilc, filter_soilc,& rfluxes(f_npool_to_leafn_storage) = veg_pf%ppool_to_leafp_storage(p) rfluxes(f_npool_to_frootn) = veg_pf%ppool_to_frootp(p) rfluxes(f_npool_to_frootn_storage) = veg_pf%ppool_to_frootp_storage(p) - if (woody(ivt(p)) == 1._r8) then + if (woody(ivt(p)) >= 1.0_r8) then rfluxes(f_npool_to_livestemn) = veg_pf%ppool_to_livestemp(p) rfluxes(f_npool_to_livestemn_storage) = veg_pf%ppool_to_livestemp_storage(p) rfluxes(f_npool_to_livecrootn) = veg_pf%ppool_to_livecrootp(p) @@ -1135,7 +1135,7 @@ subroutine phosphorus_flux_limiter(bounds, num_soilc, filter_soilc,& call fpmax(rfluxes(f_npool_to_leafn_storage) , veg_pf%ppool_to_leafp_storage(p)) call fpmax(rfluxes(f_npool_to_frootn) , veg_pf%ppool_to_frootp(p)) call fpmax(rfluxes(f_npool_to_frootn_storage) , veg_pf%ppool_to_frootp_storage(p)) - if (woody(ivt(p)) == 1._r8) then + if (woody(ivt(p)) >= 1.0_r8) then call fpmax(rfluxes(f_npool_to_livestemn) , veg_pf%ppool_to_livestemp(p)) call fpmax(rfluxes(f_npool_to_livestemn_storage) , veg_pf%ppool_to_livestemp_storage(p)) call fpmax(rfluxes(f_npool_to_livecrootn) , veg_pf%ppool_to_livecrootp(p)) diff --git a/components/elm/src/biogeochem/PhenologyMod.F90 b/components/elm/src/biogeochem/PhenologyMod.F90 index 9f51301acb74..d5ddfc2f44ed 100644 --- a/components/elm/src/biogeochem/PhenologyMod.F90 +++ b/components/elm/src/biogeochem/PhenologyMod.F90 @@ -771,7 +771,7 @@ subroutine CNSeasonDecidPhenology (num_soilp, filter_soilp, cnstate_vars) frootn_xfer_to_frootn(p) = 0.0_r8 leafp_xfer_to_leafp(p) = 0.0_r8 frootp_xfer_to_frootp(p) = 0.0_r8 - if (woody(ivt(p)) == 1.0_r8) then + if (woody(ivt(p)) >= 1.0_r8) then livestemc_xfer_to_livestemc(p) = 0.0_r8 deadstemc_xfer_to_deadstemc(p) = 0.0_r8 livecrootc_xfer_to_livecrootc(p) = 0.0_r8 @@ -792,7 +792,7 @@ subroutine CNSeasonDecidPhenology (num_soilp, filter_soilp, cnstate_vars) frootc_xfer(p) = 0.0_r8 frootn_xfer(p) = 0.0_r8 frootp_xfer(p) = 0.0_r8 - if (woody(ivt(p)) == 1.0_r8) then + if (woody(ivt(p)) >= 1.0_r8) then livestemc_xfer(p) = 0.0_r8 livestemn_xfer(p) = 0.0_r8 livestemp_xfer(p) = 0.0_r8 @@ -855,7 +855,7 @@ subroutine CNSeasonDecidPhenology (num_soilp, filter_soilp, cnstate_vars) ! set carbon fluxes for shifting storage pools to transfer pools leafc_storage_to_xfer(p) = PhenolParamsInst%fstor2tran * leafc_storage(p)/dt frootc_storage_to_xfer(p) = PhenolParamsInst%fstor2tran * frootc_storage(p)/dt - if (woody(ivt(p)) == 1.0_r8) then + if (woody(ivt(p)) >= 1.0_r8) then livestemc_storage_to_xfer(p) = PhenolParamsInst%fstor2tran * livestemc_storage(p)/dt deadstemc_storage_to_xfer(p) = PhenolParamsInst%fstor2tran * deadstemc_storage(p)/dt livecrootc_storage_to_xfer(p) = PhenolParamsInst%fstor2tran * livecrootc_storage(p)/dt @@ -866,7 +866,7 @@ subroutine CNSeasonDecidPhenology (num_soilp, filter_soilp, cnstate_vars) ! set nitrogen fluxes for shifting storage pools to transfer pools leafn_storage_to_xfer(p) = PhenolParamsInst%fstor2tran * leafn_storage(p)/dt frootn_storage_to_xfer(p) = PhenolParamsInst%fstor2tran * frootn_storage(p)/dt - if (woody(ivt(p)) == 1.0_r8) then + if (woody(ivt(p)) >= 1.0_r8) then livestemn_storage_to_xfer(p) = PhenolParamsInst%fstor2tran * livestemn_storage(p)/dt deadstemn_storage_to_xfer(p) = PhenolParamsInst%fstor2tran * deadstemn_storage(p)/dt livecrootn_storage_to_xfer(p) = PhenolParamsInst%fstor2tran * livecrootn_storage(p)/dt @@ -876,7 +876,7 @@ subroutine CNSeasonDecidPhenology (num_soilp, filter_soilp, cnstate_vars) ! set phosphorus fluxes for shifting storage pools to transfer pools leafp_storage_to_xfer(p) = PhenolParamsInst%fstor2tran * leafp_storage(p)/dt frootp_storage_to_xfer(p) = PhenolParamsInst%fstor2tran * frootp_storage(p)/dt - if (woody(ivt(p)) == 1.0_r8) then + if (woody(ivt(p)) >= 1.0_r8) then livestemp_storage_to_xfer(p) = PhenolParamsInst%fstor2tran * livestemp_storage(p)/dt deadstemp_storage_to_xfer(p) = PhenolParamsInst%fstor2tran * deadstemp_storage(p)/dt livecrootp_storage_to_xfer(p) = PhenolParamsInst%fstor2tran * livecrootp_storage(p)/dt @@ -1116,7 +1116,7 @@ subroutine CNStressDecidPhenology (num_soilp, filter_soilp , & frootn_xfer_to_frootn(p) = 0._r8 leafp_xfer_to_leafp(p) = 0._r8 frootp_xfer_to_frootp(p) = 0._r8 - if (woody(ivt(p)) == 1.0_r8) then + if (woody(ivt(p)) >= 1.0_r8) then livestemc_xfer_to_livestemc(p) = 0._r8 deadstemc_xfer_to_deadstemc(p) = 0._r8 livecrootc_xfer_to_livecrootc(p) = 0._r8 @@ -1137,7 +1137,7 @@ subroutine CNStressDecidPhenology (num_soilp, filter_soilp , & frootc_xfer(p) = 0._r8 frootn_xfer(p) = 0._r8 frootp_xfer(p) = 0._r8 - if (woody(ivt(p)) == 1.0_r8) then + if (woody(ivt(p)) >= 1.0_r8) then livestemc_xfer(p) = 0._r8 livestemn_xfer(p) = 0._r8 livestemp_xfer(p) = 0._r8 @@ -1229,7 +1229,7 @@ subroutine CNStressDecidPhenology (num_soilp, filter_soilp , & ! set carbon fluxes for shifting storage pools to transfer pools leafc_storage_to_xfer(p) = PhenolParamsInst%fstor2tran * leafc_storage(p)/dt frootc_storage_to_xfer(p) = PhenolParamsInst%fstor2tran * frootc_storage(p)/dt - if (woody(ivt(p)) == 1.0_r8) then + if (woody(ivt(p)) >= 1.0_r8) then livestemc_storage_to_xfer(p) = PhenolParamsInst%fstor2tran * livestemc_storage(p)/dt deadstemc_storage_to_xfer(p) = PhenolParamsInst%fstor2tran * deadstemc_storage(p)/dt livecrootc_storage_to_xfer(p) = PhenolParamsInst%fstor2tran * livecrootc_storage(p)/dt @@ -1240,7 +1240,7 @@ subroutine CNStressDecidPhenology (num_soilp, filter_soilp , & ! set nitrogen fluxes for shifting storage pools to transfer pools leafn_storage_to_xfer(p) = PhenolParamsInst%fstor2tran * leafn_storage(p)/dt frootn_storage_to_xfer(p) = PhenolParamsInst%fstor2tran * frootn_storage(p)/dt - if (woody(ivt(p)) == 1.0_r8) then + if (woody(ivt(p)) >= 1.0_r8) then livestemn_storage_to_xfer(p) = PhenolParamsInst%fstor2tran * livestemn_storage(p)/dt deadstemn_storage_to_xfer(p) = PhenolParamsInst%fstor2tran * deadstemn_storage(p)/dt livecrootn_storage_to_xfer(p) = PhenolParamsInst%fstor2tran * livecrootn_storage(p)/dt @@ -1250,7 +1250,7 @@ subroutine CNStressDecidPhenology (num_soilp, filter_soilp , & ! set phosphorus fluxes for shifting storage pools to transfer pools leafp_storage_to_xfer(p) = PhenolParamsInst%fstor2tran * leafp_storage(p)/dt frootp_storage_to_xfer(p) = PhenolParamsInst%fstor2tran * frootp_storage(p)/dt - if (woody(ivt(p)) == 1.0_r8) then + if (woody(ivt(p)) >= 1.0_r8) then livestemp_storage_to_xfer(p) = PhenolParamsInst%fstor2tran * livestemp_storage(p)/dt deadstemp_storage_to_xfer(p) = PhenolParamsInst%fstor2tran * deadstemp_storage(p)/dt livecrootp_storage_to_xfer(p) = PhenolParamsInst%fstor2tran * livecrootp_storage(p)/dt @@ -1352,7 +1352,7 @@ subroutine CNStressDecidPhenology (num_soilp, filter_soilp , & leafc_storage_to_xfer(p) = leafc_storage(p) * bgtr(p) frootc_storage_to_xfer(p) = frootc_storage(p) * bgtr(p) - if (woody(ivt(p)) == 1.0_r8) then + if (woody(ivt(p)) >= 1.0_r8) then livestemc_storage_to_xfer(p) = livestemc_storage(p) * bgtr(p) deadstemc_storage_to_xfer(p) = deadstemc_storage(p) * bgtr(p) livecrootc_storage_to_xfer(p) = livecrootc_storage(p) * bgtr(p) @@ -1363,7 +1363,7 @@ subroutine CNStressDecidPhenology (num_soilp, filter_soilp , & ! set nitrogen fluxes for shifting storage pools to transfer pools leafn_storage_to_xfer(p) = leafn_storage(p) * bgtr(p) frootn_storage_to_xfer(p) = frootn_storage(p) * bgtr(p) - if (woody(ivt(p)) == 1.0_r8) then + if (woody(ivt(p)) >= 1.0_r8) then livestemn_storage_to_xfer(p) = livestemn_storage(p) * bgtr(p) deadstemn_storage_to_xfer(p) = deadstemn_storage(p) * bgtr(p) livecrootn_storage_to_xfer(p) = livecrootn_storage(p) * bgtr(p) @@ -1374,7 +1374,7 @@ subroutine CNStressDecidPhenology (num_soilp, filter_soilp , & ! set phosphorus fluxes for shifting storage pools to transfer pools leafp_storage_to_xfer(p) = leafp_storage(p) * bgtr(p) frootp_storage_to_xfer(p) = frootp_storage(p) * bgtr(p) - if (woody(ivt(p)) == 1.0_r8) then + if (woody(ivt(p)) >= 1.0_r8) then livestemp_storage_to_xfer(p) = livestemp_storage(p) * bgtr(p) deadstemp_storage_to_xfer(p) = deadstemp_storage(p) * bgtr(p) livecrootp_storage_to_xfer(p) = livecrootp_storage(p) * bgtr(p) @@ -2694,7 +2694,7 @@ subroutine CNOnsetGrowth (num_soilp, filter_soilp, & frootn_xfer_to_frootn(p) = t1 * frootn_xfer(p) leafp_xfer_to_leafp(p) = t1 * leafp_xfer(p) frootp_xfer_to_frootp(p) = t1 * frootp_xfer(p) - if (woody(ivt(p)) == 1.0_r8) then + if (woody(ivt(p)) >= 1.0_r8) then livestemc_xfer_to_livestemc(p) = t1 * livestemc_xfer(p) deadstemc_xfer_to_deadstemc(p) = t1 * deadstemc_xfer(p) livecrootc_xfer_to_livecrootc(p) = t1 * livecrootc_xfer(p) @@ -2723,7 +2723,7 @@ subroutine CNOnsetGrowth (num_soilp, filter_soilp, & frootn_xfer_to_frootn(p) = frootn_xfer(p) / dt leafp_xfer_to_leafp(p) = leafp_xfer(p) / dt frootp_xfer_to_frootp(p) = frootp_xfer(p) / dt - if (woody(ivt(p)) == 1.0_r8) then + if (woody(ivt(p)) >= 1.0_r8) then livestemc_xfer_to_livestemc(p) = livestemc_xfer(p) / dt deadstemc_xfer_to_deadstemc(p) = deadstemc_xfer(p) / dt livecrootc_xfer_to_livecrootc(p) = livecrootc_xfer(p) / dt @@ -3315,7 +3315,7 @@ subroutine CNLivewoodTurnover (num_soilp, filter_soilp) p = filter_soilp(fp) ! only calculate these fluxes for woody types - if (woody(ivt(p)) > 0._r8) then + if (woody(ivt(p)) >= 1.0_r8) then if ( nu_com .eq. 'RD') then ! live stem to dead stem turnover diff --git a/components/elm/src/biogeochem/PhosphorusStateUpdate1Mod.F90 b/components/elm/src/biogeochem/PhosphorusStateUpdate1Mod.F90 index 63390dc419e2..feea9fd86fb3 100644 --- a/components/elm/src/biogeochem/PhosphorusStateUpdate1Mod.F90 +++ b/components/elm/src/biogeochem/PhosphorusStateUpdate1Mod.F90 @@ -244,7 +244,7 @@ subroutine PhosphorusStateUpdate1(num_soilc, filter_soilc, num_soilp, filter_soi veg_ps%frootp(p) = veg_ps%frootp(p) + veg_pf%frootp_xfer_to_frootp(p)*dt veg_ps%frootp_xfer(p) = veg_ps%frootp_xfer(p) - veg_pf%frootp_xfer_to_frootp(p)*dt - if (woody(ivt(p)) == 1.0_r8) then + if (woody(ivt(p)) >= 1.0_r8) then veg_ps%livestemp(p) = veg_ps%livestemp(p) + veg_pf%livestemp_xfer_to_livestemp(p)*dt veg_ps%livestemp_xfer(p) = veg_ps%livestemp_xfer(p) - veg_pf%livestemp_xfer_to_livestemp(p)*dt veg_ps%deadstemp(p) = veg_ps%deadstemp(p) + veg_pf%deadstemp_xfer_to_deadstemp(p)*dt @@ -270,7 +270,7 @@ subroutine PhosphorusStateUpdate1(num_soilc, filter_soilc, num_soilp, filter_soi veg_ps%retransp(p) = veg_ps%retransp(p) + veg_pf%leafp_to_retransp(p)*dt ! live wood turnover and retranslocation fluxes - if (woody(ivt(p)) == 1._r8) then + if (woody(ivt(p)) >= 1.0_r8) then veg_ps%livestemp(p) = veg_ps%livestemp(p) - veg_pf%livestemp_to_deadstemp(p)*dt veg_ps%deadstemp(p) = veg_ps%deadstemp(p) + veg_pf%livestemp_to_deadstemp(p)*dt veg_ps%livestemp(p) = veg_ps%livestemp(p) - veg_pf%livestemp_to_retransp(p)*dt @@ -312,7 +312,7 @@ subroutine PhosphorusStateUpdate1(num_soilc, filter_soilc, num_soilp, filter_soi veg_ps%ppool(p) = veg_ps%ppool(p) - veg_pf%ppool_to_frootp_storage(p)*dt veg_ps%frootp_storage(p) = veg_ps%frootp_storage(p) + veg_pf%ppool_to_frootp_storage(p)*dt - if (woody(ivt(p)) == 1._r8) then + if (woody(ivt(p)) >= 1.0_r8) then veg_ps%ppool(p) = veg_ps%ppool(p) - veg_pf%ppool_to_livestemp(p)*dt veg_ps%livestemp(p) = veg_ps%livestemp(p) + veg_pf%ppool_to_livestemp(p)*dt veg_ps%ppool(p) = veg_ps%ppool(p) - veg_pf%ppool_to_livestemp_storage(p)*dt @@ -348,7 +348,7 @@ subroutine PhosphorusStateUpdate1(num_soilc, filter_soilc, num_soilp, filter_soi veg_ps%frootp_storage(p) = veg_ps%frootp_storage(p) - veg_pf%frootp_storage_to_xfer(p)*dt veg_ps%frootp_xfer(p) = veg_ps%frootp_xfer(p) + veg_pf%frootp_storage_to_xfer(p)*dt - if (woody(ivt(p)) == 1._r8) then + if (woody(ivt(p)) >= 1.0_r8) then veg_ps%livestemp_storage(p) = veg_ps%livestemp_storage(p) - veg_pf%livestemp_storage_to_xfer(p)*dt veg_ps%livestemp_xfer(p) = veg_ps%livestemp_xfer(p) + veg_pf%livestemp_storage_to_xfer(p)*dt veg_ps%deadstemp_storage(p) = veg_ps%deadstemp_storage(p) - veg_pf%deadstemp_storage_to_xfer(p)*dt diff --git a/components/elm/src/biogeochem/VegStructUpdateMod.F90 b/components/elm/src/biogeochem/VegStructUpdateMod.F90 index 6796ab1993ad..9a7db79154b4 100644 --- a/components/elm/src/biogeochem/VegStructUpdateMod.F90 +++ b/components/elm/src/biogeochem/VegStructUpdateMod.F90 @@ -159,7 +159,7 @@ subroutine VegStructUpdate(num_soilp, filter_soilp, & tsai_min = tsai_min * 0.5_r8 tsai(p) = max(tsai_alpha*tsai_old+max(tlai_old-tlai(p),0._r8),tsai_min) - if (woody(ivt(p)) == 1._r8) then + if (woody(ivt(p)) >= 1.0_r8) then ! trees and shrubs diff --git a/components/elm/src/data_types/VegetationDataType.F90 b/components/elm/src/data_types/VegetationDataType.F90 index 45dc063b8533..eea30fc55fef 100644 --- a/components/elm/src/data_types/VegetationDataType.F90 +++ b/components/elm/src/data_types/VegetationDataType.F90 @@ -2465,7 +2465,7 @@ subroutine veg_cs_init(this, begp, endp, carbon_type, ratio) this%livestemc_storage(p) = 0._r8 this%livestemc_xfer(p) = 0._r8 - if (veg_vp%woody(veg_pp%itype(p)) == 1._r8) then + if (veg_vp%woody(veg_pp%itype(p)) >= 1.0_r8) then this%deadstemc(p) = 0.1_r8 * ratio else this%deadstemc(p) = 0._r8 @@ -3937,7 +3937,7 @@ subroutine veg_ns_init(this, begp, endp, veg_cs) ! tree types need to be initialized with some stem mass so that ! roughness length is not zero in canopy flux calculation - if (veg_vp%woody(veg_pp%itype(p)) == 1._r8) then + if (veg_vp%woody(veg_pp%itype(p)) >= 1.0_r8) then this%deadstemn(p) = veg_cs%deadstemc(p) / veg_vp%deadwdcn(veg_pp%itype(p)) else this%deadstemn(p) = 0._r8 @@ -4621,7 +4621,7 @@ subroutine veg_ps_init(this, begp, endp, veg_cs) ! tree types need to be initialized with some stem mass so that ! roughness length is not zero in canopy flux calculation - if (veg_vp%woody(veg_pp%itype(p)) == 1._r8) then + if (veg_vp%woody(veg_pp%itype(p)) >= 1.0_r8) then this%deadstemp(p) = veg_cs%deadstemc(p) / veg_vp%deadwdcp(veg_pp%itype(p)) else this%deadstemp(p) = 0._r8 diff --git a/components/elm/src/data_types/VegetationPropertiesType.F90 b/components/elm/src/data_types/VegetationPropertiesType.F90 index 205477791956..2cb4e01c8a46 100644 --- a/components/elm/src/data_types/VegetationPropertiesType.F90 +++ b/components/elm/src/data_types/VegetationPropertiesType.F90 @@ -17,7 +17,7 @@ module VegetationPropertiesType ! !PUBLIC TYPES: type, public :: vegetation_properties_type integer , pointer :: noveg (:) => null() ! value for not vegetated - integer , pointer :: tree (:) => null() ! tree or not? + !integer , pointer :: tree (:) => null() ! tree or not? real(r8), pointer :: smpso (:) => null() ! soil water potential at full stomatal opening (mm) real(r8), pointer :: smpsc (:) => null() ! soil water potential at full stomatal closure (mm) real(r8), pointer :: fnitr (:) => null() ! foliage nitrogen limitation factor (-) @@ -159,7 +159,7 @@ subroutine veg_vp_init(this) ! ! !USES: use elm_varpar, only : numrad, numpft - use pftvarcon , only : ntree, smpso, smpsc, fnitr + use pftvarcon , only : smpso, smpsc, fnitr use pftvarcon , only : z0mr, displar, dleaf, rhol, rhos, taul, taus, xl use pftvarcon , only : c3psn, slatop, dsladlai, leafcn, flnr, woody use pftvarcon , only : lflitcn, frootcn, livewdcn, deadwdcn, froot_leaf, stem_leaf, croot_stem @@ -190,7 +190,7 @@ subroutine veg_vp_init(this) !------------------------------------------------------------------------ allocate(this%noveg (0:numpft)) ; this%noveg (:) =huge(1) - allocate(this%tree (0:numpft)) ; this%tree (:) =huge(1) + !allocate(this%tree (0:numpft)) ; this%tree (:) =huge(1) allocate(this%smpso (0:numpft)) ; this%smpso (:) =spval allocate(this%smpsc (0:numpft)) ; this%smpsc (:) =spval allocate(this%fnitr (0:numpft)) ; this%fnitr (:) =spval @@ -308,11 +308,12 @@ subroutine veg_vp_init(this) do m = 0,numpft - if (m <= ntree) then - this%tree(m) = 1 - else - this%tree(m) = 0 - end if + ! not needed anymore: woody(m)=1 for tree, 2 for shrub, or 0 for any other + !if (woody(m) == 1) then + ! this%tree(m) = 1 + !else + ! this%tree(m) = 0 + !end if do ib = 1,numrad this%rhol(m,ib) = rhol(m,ib) diff --git a/components/elm/src/main/pftvarcon.F90 b/components/elm/src/main/pftvarcon.F90 index cbd5946bb4e6..1b06a49cf2f6 100644 --- a/components/elm/src/main/pftvarcon.F90 +++ b/components/elm/src/main/pftvarcon.F90 @@ -115,7 +115,7 @@ module pftvarcon real(r8), allocatable :: dsladlai(:) !dSLA/dLAI [m^2/gC] real(r8), allocatable :: leafcn(:) !leaf C:N [gC/gN] real(r8), allocatable :: flnr(:) !fraction of leaf N in Rubisco [no units] - real(r8), allocatable :: woody(:) !woody lifeform flag (0 or 1) + real(r8), allocatable :: woody(:) !woody lifeform flag (0 = non-woody, 1 = tree, 2 = shrub) real(r8), allocatable :: lflitcn(:) !leaf litter C:N (gC/gN) real(r8), allocatable :: frootcn(:) !fine root C:N (gC/gN) real(r8), allocatable :: livewdcn(:) !live wood (phloem and ray parenchyma) C:N (gC/gN) @@ -1146,11 +1146,6 @@ subroutine pftconrd end do end if - ! woody=2 for shrub NOT YET ready in rest of ELM code - do i = 0, npft-1 - if (woody(i)>1) woody(i) == 1 - end do - call ncd_pio_closefile(ncid) @@ -1239,6 +1234,10 @@ subroutine pftconrd end if !------------------------------------------------------------------------------------------- + ! default: for tree and shrub always 1, now hard-coded as following + woody(ndllf_evr_tmp_tree:nbrdlf_dcd_brl_tree) = 1 + woody(nbrdlf_evr_shrub:nbrdlf_dcd_brl_shrub) = 2 + ! the following is initialized as 0 above for all PFT. ! here the hard-coded values (or flags) for default ELM PFT physiology will be working as original ! when not using those indexing of PFT orders anymore in other codes than here. From 475eac8d4a33bb80cefd0537e1925ee0d8a4000e Mon Sep 17 00:00:00 2001 From: "Yuan, Fengming" Date: Mon, 29 Jan 2024 12:03:52 -0500 Subject: [PATCH 336/451] avoid using hard coded PFT total number and indices in PFT physiology parameter file. --- components/elm/src/biogeochem/CH4Mod.F90 | 5 +- .../src/biogeochem/CNNStateUpdate1BeTRMod.F90 | 10 +-- .../src/biogeochem/CarbonStateUpdate1Mod.F90 | 31 ++++++---- .../elm/src/biogeochem/DryDepVelocity.F90 | 56 +++++++++-------- components/elm/src/biogeochem/FireMod.F90 | 61 ++++++++++++++----- .../elm/src/biogeochem/GapMortalityMod.F90 | 7 ++- .../biogeochem/NitrogenStateUpdate1Mod.F90 | 14 +++-- .../biogeochem/PhosphorusStateUpdate1Mod.F90 | 14 +++-- .../src/biogeochem/PrecisionControlMod.F90 | 10 ++- .../src/biogeochem/SatellitePhenologyMod.F90 | 4 +- .../elm/src/biogeochem/VOCEmissionMod.F90 | 38 ++++++------ .../elm/src/biogeochem/VegStructUpdateMod.F90 | 13 ++-- .../elm/src/biogeophys/CanopyFluxesMod.F90 | 8 ++- .../elm/src/biogeophys/PhotosynthesisMod.F90 | 2 - components/elm/src/biogeophys/SedYieldMod.F90 | 10 ++- .../elm/src/dyn_subgrid/dynHarvestMod.F90 | 5 +- components/elm/src/main/surfrdUtilsMod.F90 | 32 +++++----- 17 files changed, 192 insertions(+), 128 deletions(-) diff --git a/components/elm/src/biogeochem/CH4Mod.F90 b/components/elm/src/biogeochem/CH4Mod.F90 index ce2378049fd5..3b3c1fa80611 100644 --- a/components/elm/src/biogeochem/CH4Mod.F90 +++ b/components/elm/src/biogeochem/CH4Mod.F90 @@ -2426,7 +2426,7 @@ subroutine ch4_aere (bounds, & ! !USES: !$acc routine seq use elm_varcon , only : rpi - use pftvarcon , only : nc3_arctic_grass, crop, nc3_nonarctic_grass, nc4_grass, noveg + use pftvarcon , only : graminoid, crop, noveg use CH4varcon , only : transpirationloss, usefrootc, use_aereoxid_prog ! ! !ARGUMENTS: @@ -2563,8 +2563,7 @@ subroutine ch4_aere (bounds, & is_vegetated = .false. end if - if (veg_pp%itype(p) == nc3_arctic_grass .or. crop(veg_pp%itype(p)) == 1 .or. & - veg_pp%itype(p) == nc3_nonarctic_grass .or. veg_pp%itype(p) == nc4_grass) then + if (graminoid(veg_pp%itype(p)) == 1 .or. crop(veg_pp%itype(p)) == 1) then poros_tiller = 0.3_r8 ! Colmer 2003 else poros_tiller = 0.3_r8 * CH4ParamsInst%nongrassporosratio diff --git a/components/elm/src/biogeochem/CNNStateUpdate1BeTRMod.F90 b/components/elm/src/biogeochem/CNNStateUpdate1BeTRMod.F90 index 95d884de490f..4c7fd83d2108 100644 --- a/components/elm/src/biogeochem/CNNStateUpdate1BeTRMod.F90 +++ b/components/elm/src/biogeochem/CNNStateUpdate1BeTRMod.F90 @@ -10,7 +10,7 @@ module CNNStateUpdate1BeTRMod use elm_varpar , only : crop_prog, i_met_lit, i_cel_lit, i_lig_lit, i_cwd use elm_varctl , only : iulog use elm_varcon , only : nitrif_n2o_loss_frac - use pftvarcon , only : npcropmin, nc3crop + use pftvarcon , only : crop, generic_crop use VegetationPropertiesType , only : veg_vp use CNDecompCascadeConType , only : decomp_cascade_con use CNStateType , only : cnstate_type @@ -101,7 +101,7 @@ subroutine NStateUpdate1(num_soilc, filter_soilc, num_soilp, filter_soilp, & veg_ns%deadcrootn_xfer(p) = veg_ns%deadcrootn_xfer(p) - veg_nf%deadcrootn_xfer_to_deadcrootn(p)*dt end if - if (ivt(p) >= npcropmin) then ! skip 2 generic crops + if (crop(ivt(p)) >= 1 .and. generic_crop(ivt(p)) < 1) then ! skip 2 generic crops ! lines here for consistency; the transfer terms are zero veg_ns%livestemn(p) = veg_ns%livestemn(p) + veg_nf%livestemn_xfer_to_livestemn(p)*dt veg_ns%livestemn_xfer(p) = veg_ns%livestemn_xfer(p) - veg_nf%livestemn_xfer_to_livestemn(p)*dt @@ -126,7 +126,7 @@ subroutine NStateUpdate1(num_soilc, filter_soilc, num_soilp, filter_soilp, & veg_ns%livecrootn(p) = veg_ns%livecrootn(p) - veg_nf%livecrootn_to_retransn(p)*dt veg_ns%retransn(p) = veg_ns%retransn(p) + veg_nf%livecrootn_to_retransn(p)*dt end if - if (ivt(p) >= npcropmin) then ! Beth adds retrans from froot + if (crop(ivt(p)) >= 1 .and. generic_crop(ivt(p)) < 1) then ! Beth adds retrans from froot veg_ns%frootn(p) = veg_ns%frootn(p) - veg_nf%frootn_to_retransn(p)*dt veg_ns%retransn(p) = veg_ns%retransn(p) + veg_nf%frootn_to_retransn(p)*dt veg_ns%livestemn(p) = veg_ns%livestemn(p) - veg_nf%livestemn_to_litter(p)*dt @@ -172,7 +172,7 @@ subroutine NStateUpdate1(num_soilc, filter_soilc, num_soilp, filter_soilp, & veg_ns%deadcrootn_storage(p) = veg_ns%deadcrootn_storage(p) + veg_nf%npool_to_deadcrootn_storage(p)*dt end if - if (ivt(p) >= npcropmin) then ! skip 2 generic crops + if (crop(ivt(p)) >= 1 .and. generic_crop(ivt(p)) < 1) then ! skip 2 generic crops veg_ns%npool(p) = veg_ns%npool(p) - veg_nf%npool_to_livestemn(p)*dt veg_ns%livestemn(p) = veg_ns%livestemn(p) + veg_nf%npool_to_livestemn(p)*dt veg_ns%npool(p) = veg_ns%npool(p) - veg_nf%npool_to_livestemn_storage(p)*dt @@ -200,7 +200,7 @@ subroutine NStateUpdate1(num_soilc, filter_soilc, num_soilp, filter_soilp, & veg_ns%deadcrootn_xfer(p) = veg_ns%deadcrootn_xfer(p) + veg_nf%deadcrootn_storage_to_xfer(p)*dt end if - if (ivt(p) >= npcropmin) then ! skip 2 generic crops + if (crop(ivt(p)) >= 1 .and. generic_crop(ivt(p)) < 1) then ! skip 2 generic crops ! lines here for consistency; the transfer terms are zero veg_ns%livestemn_storage(p) = veg_ns%livestemn_storage(p) - veg_nf%livestemn_storage_to_xfer(p)*dt veg_ns%livestemn_xfer(p) = veg_ns%livestemn_xfer(p) + veg_nf%livestemn_storage_to_xfer(p)*dt diff --git a/components/elm/src/biogeochem/CarbonStateUpdate1Mod.F90 b/components/elm/src/biogeochem/CarbonStateUpdate1Mod.F90 index a371a44c537a..25455dbbb20e 100644 --- a/components/elm/src/biogeochem/CarbonStateUpdate1Mod.F90 +++ b/components/elm/src/biogeochem/CarbonStateUpdate1Mod.F90 @@ -11,7 +11,7 @@ module CarbonStateUpdate1Mod use elm_varcon , only : dzsoi_decomp use elm_varctl , only : nu_com, use_c13, use_c14 use elm_varctl , only : use_pflotran, pf_cmode, use_fates - use pftvarcon , only : npcropmin, nc3crop + use pftvarcon , only : crop, generic_crop, percrop use CNDecompCascadeConType , only : decomp_cascade_type use CNStateType , only : cnstate_type use CNDecompCascadeConType , only : decomp_cascade_con @@ -274,7 +274,7 @@ subroutine CarbonStateUpdate1(bounds, & veg_cs%leafc_xfer(p) = veg_cs%leafc_xfer(p) - veg_cf%leafc_xfer_to_leafc(p)*dt veg_cs%frootc(p) = veg_cs%frootc(p) + veg_cf%frootc_xfer_to_frootc(p)*dt veg_cs%frootc_xfer(p) = veg_cs%frootc_xfer(p) - veg_cf%frootc_xfer_to_frootc(p)*dt - if (woody(ivt(p)) >= 1.0_r8) then + if (woody(ivt(p)) >= 1.0_r8) then veg_cs%livestemc(p) = veg_cs%livestemc(p) + veg_cf%livestemc_xfer_to_livestemc(p)*dt veg_cs%livestemc_xfer(p) = veg_cs%livestemc_xfer(p) - veg_cf%livestemc_xfer_to_livestemc(p)*dt veg_cs%deadstemc(p) = veg_cs%deadstemc(p) + veg_cf%deadstemc_xfer_to_deadstemc(p)*dt @@ -284,7 +284,8 @@ subroutine CarbonStateUpdate1(bounds, & veg_cs%deadcrootc(p) = veg_cs%deadcrootc(p) + veg_cf%deadcrootc_xfer_to_deadcrootc(p)*dt veg_cs%deadcrootc_xfer(p) = veg_cs%deadcrootc_xfer(p) - veg_cf%deadcrootc_xfer_to_deadcrootc(p)*dt end if - if (ivt(p) >= npcropmin) then ! skip 2 generic crops + if ( (crop(ivt(p)) >= 1 .or. percrop(ivt(p)) >= 1) .and. & + generic_crop(ivt(p)) == 0 ) then ! skip 2 generic crops ! lines here for consistency; the transfer terms are zero veg_cs%livestemc(p) = veg_cs%livestemc(p) + veg_cf%livestemc_xfer_to_livestemc(p)*dt veg_cs%livestemc_xfer(p) = veg_cs%livestemc_xfer(p) - veg_cf%livestemc_xfer_to_livestemc(p)*dt @@ -303,7 +304,8 @@ subroutine CarbonStateUpdate1(bounds, & veg_cs%livecrootc(p) = veg_cs%livecrootc(p) - veg_cf%livecrootc_to_deadcrootc(p)*dt veg_cs%deadcrootc(p) = veg_cs%deadcrootc(p) + veg_cf%livecrootc_to_deadcrootc(p)*dt end if - if (ivt(p) >= npcropmin) then ! skip 2 generic crops + if ( (crop(ivt(p)) >= 1 .or. percrop(ivt(p)) >= 1) .and. & + generic_crop(ivt(p)) == 0 ) then ! skip 2 generic crops veg_cs%livestemc(p) = veg_cs%livestemc(p) - veg_cf%livestemc_to_litter(p)*dt veg_cs%grainc(p) = veg_cs%grainc(p) - veg_cf%grainc_to_food(p)*dt @@ -319,7 +321,8 @@ subroutine CarbonStateUpdate1(bounds, & veg_cs%cpool(p) = veg_cs%cpool(p) - veg_cf%livestem_curmr(p)*dt veg_cs%cpool(p) = veg_cs%cpool(p) - veg_cf%livecroot_curmr(p)*dt end if - if (ivt(p) >= npcropmin) then ! skip 2 generic crops + if ( (crop(ivt(p)) >= 1 .or. percrop(ivt(p)) >= 1) .and. & + generic_crop(ivt(p)) == 0 ) then ! skip 2 generic crops veg_cs%cpool(p) = veg_cs%cpool(p) - veg_cf%livestem_curmr(p)*dt veg_cs%cpool(p) = veg_cs%cpool(p) - veg_cf%grain_curmr(p)*dt end if @@ -337,7 +340,8 @@ subroutine CarbonStateUpdate1(bounds, & veg_cs%xsmrpool(p) = veg_cs%xsmrpool(p) - veg_cf%livestem_xsmr(p)*dt veg_cs%xsmrpool(p) = veg_cs%xsmrpool(p) - veg_cf%livecroot_xsmr(p)*dt end if - if (ivt(p) >= npcropmin) then ! skip 2 generic crops + if ( (crop(ivt(p)) >= 1 .or. percrop(ivt(p)) >= 1) .and. & + generic_crop(ivt(p)) == 0 ) then ! skip 2 generic crops veg_cs%xsmrpool(p) = veg_cs%xsmrpool(p) - veg_cf%livestem_xsmr(p)*dt veg_cs%xsmrpool(p) = veg_cs%xsmrpool(p) - veg_cf%grain_xsmr(p)*dt if (harvdate(p) < 999) then ! beginning at harvest, send to atm @@ -373,7 +377,8 @@ subroutine CarbonStateUpdate1(bounds, & veg_cs%cpool(p) = veg_cs%cpool(p) - veg_cf%cpool_to_deadcrootc_storage(p)*dt veg_cs%deadcrootc_storage(p) = veg_cs%deadcrootc_storage(p) + veg_cf%cpool_to_deadcrootc_storage(p)*dt end if - if (ivt(p) >= npcropmin) then ! skip 2 generic crops + if ( (crop(ivt(p)) >= 1 .or. percrop(ivt(p)) >= 1) .and. & + generic_crop(ivt(p)) == 0 ) then ! skip 2 generic crops veg_cs%cpool(p) = veg_cs%cpool(p) - veg_cf%cpool_to_livestemc(p)*dt veg_cs%livestemc(p) = veg_cs%livestemc(p) + veg_cf%cpool_to_livestemc(p)*dt veg_cs%cpool(p) = veg_cs%cpool(p) - veg_cf%cpool_to_livestemc_storage(p)*dt @@ -393,7 +398,8 @@ subroutine CarbonStateUpdate1(bounds, & veg_cs%cpool(p) = veg_cs%cpool(p) - veg_cf%cpool_livecroot_gr(p)*dt veg_cs%cpool(p) = veg_cs%cpool(p) - veg_cf%cpool_deadcroot_gr(p)*dt end if - if (ivt(p) >= npcropmin) then ! skip 2 generic crops + if ( (crop(ivt(p)) >= 1 .or. percrop(ivt(p)) >= 1) .and. & + generic_crop(ivt(p)) == 0 ) then ! skip 2 generic crops veg_cs%cpool(p) = veg_cs%cpool(p) - veg_cf%cpool_livestem_gr(p)*dt veg_cs%cpool(p) = veg_cs%cpool(p) - veg_cf%cpool_grain_gr(p)*dt end if @@ -407,7 +413,8 @@ subroutine CarbonStateUpdate1(bounds, & veg_cs%gresp_xfer(p) = veg_cs%gresp_xfer(p) - veg_cf%transfer_livecroot_gr(p)*dt veg_cs%gresp_xfer(p) = veg_cs%gresp_xfer(p) - veg_cf%transfer_deadcroot_gr(p)*dt end if - if (ivt(p) >= npcropmin) then ! skip 2 generic crops + if ( (crop(ivt(p)) >= 1 .or. percrop(ivt(p)) >= 1) .and. & + generic_crop(ivt(p)) == 0 ) then ! skip 2 generic crops veg_cs%gresp_xfer(p) = veg_cs%gresp_xfer(p) - veg_cf%transfer_livestem_gr(p)*dt veg_cs%gresp_xfer(p) = veg_cs%gresp_xfer(p) - veg_cf%transfer_grain_gr(p)*dt end if @@ -421,7 +428,8 @@ subroutine CarbonStateUpdate1(bounds, & veg_cs%cpool(p) = veg_cs%cpool(p) - veg_cf%cpool_livecroot_storage_gr(p)*dt veg_cs%cpool(p) = veg_cs%cpool(p) - veg_cf%cpool_deadcroot_storage_gr(p)*dt end if - if (ivt(p) >= npcropmin) then ! skip 2 generic crops + if ( (crop(ivt(p)) >= 1 .or. percrop(ivt(p)) >= 1) .and. & + generic_crop(ivt(p)) == 0 ) then ! skip 2 generic crops veg_cs%cpool(p) = veg_cs%cpool(p) - veg_cf%cpool_livestem_storage_gr(p)*dt veg_cs%cpool(p) = veg_cs%cpool(p) - veg_cf%cpool_grain_storage_gr(p)*dt end if @@ -447,7 +455,8 @@ subroutine CarbonStateUpdate1(bounds, & veg_cs%gresp_storage(p) = veg_cs%gresp_storage(p) - veg_cf%gresp_storage_to_xfer(p)*dt veg_cs%gresp_xfer(p) = veg_cs%gresp_xfer(p) + veg_cf%gresp_storage_to_xfer(p)*dt end if - if (ivt(p) >= npcropmin) then ! skip 2 generic crops + if ( (crop(ivt(p)) >= 1 .or. percrop(ivt(p)) >= 1) .and. & + generic_crop(ivt(p)) == 0 ) then ! skip 2 generic crops ! lines here for consistency; the transfer terms are zero veg_cs%livestemc_storage(p) = veg_cs%livestemc_storage(p) - veg_cf%livestemc_storage_to_xfer(p)*dt veg_cs%livestemc_xfer(p) = veg_cs%livestemc_xfer(p) + veg_cf%livestemc_storage_to_xfer(p)*dt diff --git a/components/elm/src/biogeochem/DryDepVelocity.F90 b/components/elm/src/biogeochem/DryDepVelocity.F90 index 009de700b455..293713da54a7 100644 --- a/components/elm/src/biogeochem/DryDepVelocity.F90 +++ b/components/elm/src/biogeochem/DryDepVelocity.F90 @@ -145,14 +145,9 @@ subroutine depvel_compute( bounds, & use seq_drydep_mod , only : rcls, h2_a, h2_b, h2_c, ri, rac, rclo, rlu, rgss, rgso use landunit_varcon, only : istsoil, istice, istice_mec, istdlak, istwet use elm_varctl , only : iulog - use pftvarcon , only : noveg, ndllf_evr_tmp_tree, ndllf_evr_brl_tree - use pftvarcon , only : ndllf_dcd_brl_tree, nbrdlf_evr_trp_tree - use pftvarcon , only : nbrdlf_evr_tmp_tree, nbrdlf_dcd_trp_tree - use pftvarcon , only : nbrdlf_dcd_tmp_tree, nbrdlf_dcd_brl_tree - use pftvarcon , only : nbrdlf_evr_shrub, nbrdlf_dcd_tmp_shrub - use pftvarcon , only : nbrdlf_dcd_brl_shrub,nc3_arctic_grass - use pftvarcon , only : nc3_nonarctic_grass, nc4_grass, nc3crop - use pftvarcon , only : nc3irrig, npcropmin, npcropmax + use pftvarcon , only : noveg, nonvascular + use pftvarcon , only : woody, graminoid, generic_crop, crop, percrop + use pftvarcon , only : needleleaf ! ! !ARGUMENTS: type(bounds_type) , intent(in) :: bounds @@ -275,24 +270,33 @@ subroutine depvel_compute( bounds, & !map ELM veg type into Wesely veg type wesveg = wveg_unset - if (elmveg == noveg ) wesveg = 8 - if (elmveg == ndllf_evr_tmp_tree ) wesveg = 5 - if (elmveg == ndllf_evr_brl_tree ) wesveg = 5 - if (elmveg == ndllf_dcd_brl_tree ) wesveg = 5 - if (elmveg == nbrdlf_evr_trp_tree ) wesveg = 4 - if (elmveg == nbrdlf_evr_tmp_tree ) wesveg = 4 - if (elmveg == nbrdlf_dcd_trp_tree ) wesveg = 4 - if (elmveg == nbrdlf_dcd_tmp_tree ) wesveg = 4 - if (elmveg == nbrdlf_dcd_brl_tree ) wesveg = 4 - if (elmveg == nbrdlf_evr_shrub ) wesveg = 11 - if (elmveg == nbrdlf_dcd_tmp_shrub ) wesveg = 11 - if (elmveg == nbrdlf_dcd_brl_shrub ) wesveg = 11 - if (elmveg == nc3_arctic_grass ) wesveg = 3 - if (elmveg == nc3_nonarctic_grass ) wesveg = 3 - if (elmveg == nc4_grass ) wesveg = 3 - if (elmveg == nc3crop ) wesveg = 2 - if (elmveg == nc3irrig ) wesveg = 2 - if (elmveg >= npcropmin .and. elmveg <= npcropmax ) wesveg = 2 + if (elmveg == noveg ) wesveg = 8 + if (nonvascular(elmveg) == 2.0_r8 ) wesveg = 8 ! assuming lichen like bare-ground + !if (elmveg == ndllf_evr_tmp_tree ) wesveg = 5 + !if (elmveg == ndllf_evr_brl_tree ) wesveg = 5 + !if (elmveg == ndllf_dcd_brl_tree ) wesveg = 5 + if (woody(elmveg) == 1.0_r8 .and. needleleaf(elmveg) == 1) wesveg = 5 + !if (elmveg == nbrdlf_evr_trp_tree ) wesveg = 4 + !if (elmveg == nbrdlf_evr_tmp_tree ) wesveg = 4 + !if (elmveg == nbrdlf_dcd_trp_tree ) wesveg = 4 + !if (elmveg == nbrdlf_dcd_tmp_tree ) wesveg = 4 + !if (elmveg == nbrdlf_dcd_brl_tree ) wesveg = 4 + if (woody(elmveg) == 1.0_r8 .and. needleleaf(elmveg) == 0) wesveg = 4 + !if (elmveg == nbrdlf_evr_shrub ) wesveg = 11 + !if (elmveg == nbrdlf_dcd_tmp_shrub ) wesveg = 11 + !if (elmveg == nbrdlf_dcd_brl_shrub ) wesveg = 11 + if (woody(elmveg) == 2.0_r8 ) wesveg = 11 + !if (elmveg == nc3_arctic_grass ) wesveg = 3 + !if (elmveg == nc3_nonarctic_grass ) wesveg = 3 + !if (elmveg == nc4_grass ) wesveg = 3 + if (graminoid(elmveg) == 1.0_r8 ) wesveg = 3 + if (nonvascular(elmveg) == 1.0_r8 ) wesveg = 3 ! assuming moss like grass + !if (elmveg == nc3crop ) wesveg = 2 + !if (elmveg == nc3irrig ) wesveg = 2 + if (generic_crop(elmveg) == 1.0_r8 ) wesveg = 2 + if (crop(elmveg) == 1.0_r8 ) wesveg = 2 + if (percrop(elmveg) == 1.0_r8 ) wesveg = 2 + !if (elmveg >= npcropmin .and. elmveg <= npcropmax ) wesveg = 2 #ifndef _OPENACC if (wesveg == wveg_unset )then write(iulog,*) 'elmveg = ', elmveg, 'lun_pp%itype = ', lun_pp%itype(l) diff --git a/components/elm/src/biogeochem/FireMod.F90 b/components/elm/src/biogeochem/FireMod.F90 index 0dec0c08a50b..743141b20182 100644 --- a/components/elm/src/biogeochem/FireMod.F90 +++ b/components/elm/src/biogeochem/FireMod.F90 @@ -126,8 +126,8 @@ subroutine FireArea (bounds, & use elm_varcon , only: secspday, spval use elm_varctl , only: use_nofire, spinup_state, spinup_mortality_factor use dynSubgridControlMod , only: run_has_transient_landcover - use pftvarcon , only: nc4_grass, nc3crop, ndllf_evr_tmp_tree - use pftvarcon , only: nbrdlf_evr_trp_tree, nbrdlf_dcd_trp_tree, nbrdlf_evr_shrub + use pftvarcon , only: noveg, woody, graminoid, generic_crop, crop, percrop + use pftvarcon , only: climatezone, needleleaf, evergreen ! ! !ARGUMENTS: type(bounds_type) , intent(in) :: bounds @@ -305,11 +305,16 @@ subroutine FireArea (bounds, & if (pi <= col_pp%npfts(c)) then p = col_pp%pfti(c) + pi - 1 ! For crop veg types - if( veg_pp%itype(p) > nc4_grass )then + if( generic_crop(veg_pp%itype(p)) == 1 .or. & + crop(veg_pp%itype(p)) == 1 .or. & + percrop(veg_pp%itype(p)) == 1 )then cropf_col(c) = cropf_col(c) + veg_pp%wtcol(p) end if ! For natural vegetation (non-crop and non-bare-soil) - if( veg_pp%itype(p) >= ndllf_evr_tmp_tree .and. veg_pp%itype(p) <= nc4_grass )then + if( veg_pp%itype(p) /= noveg .and. & + (generic_crop(veg_pp%itype(p)) == 0 .and. & + crop(veg_pp%itype(p)) == 0 .and. & + percrop(veg_pp%itype(p)) == 0) )then lfwt(c) = lfwt(c) + veg_pp%wtcol(p) end if end if @@ -331,7 +336,10 @@ subroutine FireArea (bounds, & ! column-level litter carbon ! is available, so we use leaf carbon to estimate the ! litter carbon for crop PFTs - if( veg_pp%itype(p) > nc4_grass .and. veg_pp%wtcol(p) > 0._r8 .and. leafc_col(c) > 0._r8 )then + if( (generic_crop(veg_pp%itype(p)) == 1 .or. & + crop(veg_pp%itype(p)) == 1 .or. & + percrop(veg_pp%itype(p)) == 1) .and. & + veg_pp%wtcol(p) > 0._r8 .and. leafc_col(c) > 0._r8 )then fuelc_crop(c)=fuelc_crop(c) + (leafc(p) + leafc_storage(p) + & leafc_xfer(p))*veg_pp%wtcol(p)/cropf_col(c) + & totlitc(c)*leafc(p)/leafc_col(c)*veg_pp%wtcol(p)/cropf_col(c) @@ -368,21 +376,37 @@ subroutine FireArea (bounds, & p = col_pp%pfti(c) + pi - 1 ! For non-crop -- natural vegetation and bare-soil - if( veg_pp%itype(p) < nc3crop .and. cropf_col(c) < 1.0_r8 )then + if( (generic_crop(veg_pp%itype(p)) == 0 .and. & + crop(veg_pp%itype(p)) == 0 .and. & + percrop(veg_pp%itype(p)) == 0) .and. & + cropf_col(c) < 1.0_r8 ) then if( btran2(p) .ne. spval) then if (btran2(p) <= 1._r8 ) then btran_col(c) = btran_col(c)+btran2(p)*veg_pp%wtcol(p) wtlf(c) = wtlf(c)+veg_pp%wtcol(p) end if end if - if( veg_pp%itype(p) == nbrdlf_evr_trp_tree .and. veg_pp%wtcol(p) > 0._r8 )then + ! broadleaf evergreen tropical tree + if( (needleleaf(veg_pp%itype(p)) == 0 .and. & + evergreen(veg_pp%itype(p)) == 1 .and. & + climatezone(veg_pp%itype(p)) == 1 .and. & + woody(veg_pp%itype(p)) == 1.0_r8) .and. & + veg_pp%wtcol(p) > 0._r8 )then trotr1_col(c)=trotr1_col(c)+veg_pp%wtcol(p)*col_pp%wttopounit(c) end if - if( veg_pp%itype(p) == nbrdlf_dcd_trp_tree .and. veg_pp%wtcol(p) > 0._r8 )then + ! broadleaf deciduous tropical tree + if( (needleleaf(veg_pp%itype(p)) == 0 .and. & + evergreen(veg_pp%itype(p)) == 0 .and. & + climatezone(veg_pp%itype(p)) == 1 .and. & + woody(veg_pp%itype(p)) == 1.0_r8) .and. & + veg_pp%wtcol(p) > 0._r8 ) then trotr2_col(c)=trotr2_col(c)+veg_pp%wtcol(p)*col_pp%wttopounit(c) end if if (transient_landcover) then !true when landuse data is used - if( veg_pp%itype(p) == nbrdlf_evr_trp_tree .or. veg_pp%itype(p) == nbrdlf_dcd_trp_tree )then + ! broadleaf tropical tree + if(needleleaf(veg_pp%itype(p)) == 0 .and. & + climatezone(veg_pp%itype(p)) == 1 .and. & + woody(veg_pp%itype(p)) == 1.0_r8)then if(lfpftd(p) > 0._r8)then dtrotr_col(c)=dtrotr_col(c)+lfpftd(p)*col_pp%wttopounit(c) end if @@ -405,7 +429,8 @@ subroutine FireArea (bounds, & ! For NOT bare-soil if( veg_pp%itype(p) /= noveg )then ! For shrub and grass (crop already excluded above) - if( veg_pp%itype(p) >= nbrdlf_evr_shrub )then !for shurb and grass + if( woody(veg_pp%itype(p)) == 2.0_r8 .or. & + graminoid(veg_pp%itype(p)) == 1 )then !for shurb and grass lgdp_col(c) = lgdp_col(c) + (0.1_r8 + 0.9_r8* & exp(-1._r8*SHR_CONST_PI* & (gdp_lf(c)/8._r8)**0.5_r8))*veg_pp%wtcol(p) & @@ -416,7 +441,7 @@ subroutine FireArea (bounds, & lpop_col(c) = lpop_col(c) + (0.2_r8 + 0.8_r8* & exp(-1._r8*SHR_CONST_PI* & (hdmlf/450._r8)**0.5_r8))*veg_pp%wtcol(p)/lfwt(c) - else ! for trees + else if (woody(veg_pp%itype(p)) == 1.0_r8) then ! for trees if( gdp_lf(c) > 20._r8 )then lgdp_col(c) =lgdp_col(c)+0.39_r8*veg_pp%wtcol(p)/(1.0_r8 - cropf_col(c)) else @@ -491,7 +516,10 @@ subroutine FireArea (bounds, & if (pi <= col_pp%npfts(c)) then p = col_pp%pfti(c) + pi - 1 ! For crop - if( forc_t(t) >= SHR_CONST_TKFRZ .and. veg_pp%itype(p) > nc4_grass .and. & + if( forc_t(t) >= SHR_CONST_TKFRZ .and. & + (generic_crop(veg_pp%itype(p))>=1 .or. & + crop(veg_pp%itype(p))>=1 .or. & + percrop(veg_pp%itype(p))>=1) .and. & kmo == abm_lf(c) .and. forc_rain(t)+forc_snow(t) == 0._r8 .and. & burndate(p) >= 999 .and. veg_pp%wtcol(p) > 0._r8 )then ! catch crop burn time @@ -661,7 +689,8 @@ subroutine FireFluxes (num_soilc, filter_soilc, num_soilp, filter_soilp, & ! !USES: !$acc routine seq use pftvarcon , only: cc_leaf,cc_lstem,cc_dstem,cc_other,fm_leaf,fm_lstem,fm_other,fm_root,fm_lroot,fm_droot - use pftvarcon , only: nc3crop,lf_flab,lf_fcel,lf_flig,fr_flab,fr_fcel,fr_flig + use pftvarcon , only: lf_flab,lf_fcel,lf_flig,fr_flab,fr_fcel,fr_flig + use pftvarcon , only: generic_crop, crop, percrop use elm_varpar , only: max_patch_per_col use elm_varctl , only: spinup_state, spinup_mortality_factor use dynSubgridControlMod , only: get_flanduse_timeseries @@ -706,7 +735,7 @@ subroutine FireFluxes (num_soilc, filter_soilc, num_soilp, filter_soilp, & is_cwd => decomp_cascade_con%is_cwd , & ! Input: [logical (:) ] TRUE => pool is a cwd pool is_litter => decomp_cascade_con%is_litter , & ! Input: [logical (:) ] TRUE => pool is a litter pool - woody => veg_vp%woody , & ! Input: [real(r8) (:) ] woody lifeform (1=woody, 0=not woody) + !woody => veg_vp%woody , & ! Input: [real(r8) (:) ] woody lifeform (1=woody, 0=not woody) cropf_col => cnstate_vars%cropf_col , & ! Input: [real(r8) (:) ] cropland fraction in veg column croot_prof => cnstate_vars%croot_prof_patch , & ! Input: [real(r8) (:,:) ] (1/m) profile of coarse roots @@ -965,7 +994,9 @@ subroutine FireFluxes (num_soilc, filter_soilc, num_soilp, filter_soilp, & c = veg_pp%column(p) itype = veg_pp%itype(p) - if( itype < nc3crop .and. cropf_col(c) < 1.0_r8)then + if( (generic_crop(veg_pp%itype(p)) == 0 .and. crop(veg_pp%itype(p)) == 0 .and. & + percrop(veg_pp%itype(p)) == 0 ) .and. & + cropf_col(c) < 1.0_r8)then ! For non-crop (bare-soil and natural vegetation) if (transient_landcover) then !true when landuse data is used f = (fbac(c)-baf_crop(c))/(1.0_r8-cropf_col(c)) diff --git a/components/elm/src/biogeochem/GapMortalityMod.F90 b/components/elm/src/biogeochem/GapMortalityMod.F90 index 495c46ed0dfc..31cd45814d62 100644 --- a/components/elm/src/biogeochem/GapMortalityMod.F90 +++ b/components/elm/src/biogeochem/GapMortalityMod.F90 @@ -564,7 +564,7 @@ subroutine mortality_rate_soilorder(& ! USES !$acc routine seq - use pftvarcon , only: nbrdlf_evr_trp_tree, nbrdlf_dcd_trp_tree + use pftvarcon , only: woody, needleleaf, climatezone use soilorder_varcon, only: r_mort_soilorder ! @@ -586,7 +586,10 @@ subroutine mortality_rate_soilorder(& do fp = 1,num_soilp p = filter_soilp(fp) c = veg_pp%column(p) - if( veg_pp%itype(p) == nbrdlf_evr_trp_tree .or. veg_pp%itype(p) == nbrdlf_dcd_trp_tree )then + ! broadleaf tropical trees + if( woody(veg_pp%itype(p)) == 1.0_r8 .and. & + needleleaf(veg_pp%itype(p)) == 0 .and. & + climatezone(veg_pp%itype(p)) == 1 )then r_mort_cal(p) = r_mort_soilorder( isoilorder(c) ) else r_mort_cal(p) = 0.02_r8 ! Default mortality rate diff --git a/components/elm/src/biogeochem/NitrogenStateUpdate1Mod.F90 b/components/elm/src/biogeochem/NitrogenStateUpdate1Mod.F90 index 14d834245f5a..d72dc4dc598e 100644 --- a/components/elm/src/biogeochem/NitrogenStateUpdate1Mod.F90 +++ b/components/elm/src/biogeochem/NitrogenStateUpdate1Mod.F90 @@ -9,7 +9,7 @@ module NitrogenStateUpdate1Mod use elm_varpar , only : crop_prog, i_met_lit, i_cel_lit, i_lig_lit, i_cwd use elm_varctl , only : iulog use elm_varcon , only : nitrif_n2o_loss_frac - use pftvarcon , only : npcropmin, nc3crop + use pftvarcon , only : crop, generic_crop, percrop use VegetationPropertiesType , only : veg_vp use CNDecompCascadeConType , only : decomp_cascade_con use CNStateType , only : cnstate_type @@ -297,7 +297,8 @@ subroutine NitrogenStateUpdate1(num_soilc, filter_soilc, num_soilp, filter_soilp veg_ns%deadcrootn_xfer(p) = veg_ns%deadcrootn_xfer(p) - veg_nf%deadcrootn_xfer_to_deadcrootn(p)*dt end if - if (ivt(p) >= npcropmin) then ! skip 2 generic crops + if ( (crop(ivt(p)) >= 1 .or. percrop(ivt(p)) >= 1) .and. & + generic_crop(ivt(p)) == 0 ) then ! skip 2 generic crops ! lines here for consistency; the transfer terms are zero veg_ns%livestemn(p) = veg_ns%livestemn(p) + veg_nf%livestemn_xfer_to_livestemn(p)*dt veg_ns%livestemn_xfer(p) = veg_ns%livestemn_xfer(p) - veg_nf%livestemn_xfer_to_livestemn(p)*dt @@ -322,7 +323,8 @@ subroutine NitrogenStateUpdate1(num_soilc, filter_soilc, num_soilp, filter_soilp veg_ns%livecrootn(p) = veg_ns%livecrootn(p) - veg_nf%livecrootn_to_retransn(p)*dt veg_ns%retransn(p) = veg_ns%retransn(p) + veg_nf%livecrootn_to_retransn(p)*dt end if - if (ivt(p) >= npcropmin) then ! Beth adds retrans from froot + if ( (crop(ivt(p)) >= 1 .or. percrop(ivt(p)) >= 1) .and. & + generic_crop(ivt(p)) == 0 ) then ! Beth adds retrans from froot veg_ns%frootn(p) = veg_ns%frootn(p) - veg_nf%frootn_to_retransn(p)*dt veg_ns%retransn(p) = veg_ns%retransn(p) + veg_nf%frootn_to_retransn(p)*dt veg_ns%livestemn(p) = veg_ns%livestemn(p) - veg_nf%livestemn_to_litter(p)*dt @@ -373,7 +375,8 @@ subroutine NitrogenStateUpdate1(num_soilc, filter_soilc, num_soilp, filter_soilp veg_ns%deadcrootn_storage(p) = veg_ns%deadcrootn_storage(p) + veg_nf%npool_to_deadcrootn_storage(p)*dt end if - if (ivt(p) >= npcropmin) then ! skip 2 generic crops + if ( (crop(ivt(p)) >= 1 .or. percrop(ivt(p)) >= 1) .and. & + generic_crop(ivt(p)) == 0 ) then ! skip 2 generic crops veg_ns%npool(p) = veg_ns%npool(p) - veg_nf%npool_to_livestemn(p)*dt veg_ns%livestemn(p) = veg_ns%livestemn(p) + veg_nf%npool_to_livestemn(p)*dt veg_ns%npool(p) = veg_ns%npool(p) - veg_nf%npool_to_livestemn_storage(p)*dt @@ -401,7 +404,8 @@ subroutine NitrogenStateUpdate1(num_soilc, filter_soilc, num_soilp, filter_soilp veg_ns%deadcrootn_xfer(p) = veg_ns%deadcrootn_xfer(p) + veg_nf%deadcrootn_storage_to_xfer(p)*dt end if - if (ivt(p) >= npcropmin) then ! skip 2 generic crops + if ( (crop(ivt(p)) >= 1 .or. percrop(ivt(p)) >= 1) .and. & + generic_crop(ivt(p)) == 0 ) then ! skip 2 generic crops ! lines here for consistency; the transfer terms are zero veg_ns%livestemn_storage(p) = veg_ns%livestemn_storage(p) - veg_nf%livestemn_storage_to_xfer(p)*dt veg_ns%livestemn_xfer(p) = veg_ns%livestemn_xfer(p) + veg_nf%livestemn_storage_to_xfer(p)*dt diff --git a/components/elm/src/biogeochem/PhosphorusStateUpdate1Mod.F90 b/components/elm/src/biogeochem/PhosphorusStateUpdate1Mod.F90 index feea9fd86fb3..e29074eb332f 100644 --- a/components/elm/src/biogeochem/PhosphorusStateUpdate1Mod.F90 +++ b/components/elm/src/biogeochem/PhosphorusStateUpdate1Mod.F90 @@ -8,7 +8,7 @@ module PhosphorusStateUpdate1Mod use elm_varpar , only : nlevdecomp, ndecomp_pools, ndecomp_cascade_transitions use elm_varpar , only : crop_prog, i_met_lit, i_cel_lit, i_lig_lit, i_cwd use elm_varctl , only : iulog - use pftvarcon , only : npcropmin, nc3crop + use pftvarcon , only : crop, generic_crop, percrop use soilorder_varcon , only : smax,ks_sorption use VegetationPropertiesType , only : veg_vp use CNDecompCascadeConType , only : decomp_cascade_con @@ -255,7 +255,8 @@ subroutine PhosphorusStateUpdate1(num_soilc, filter_soilc, num_soilp, filter_soi veg_ps%deadcrootp_xfer(p) = veg_ps%deadcrootp_xfer(p) - veg_pf%deadcrootp_xfer_to_deadcrootp(p)*dt end if - if (ivt(p) >= npcropmin) then ! skip 2 generic crops + if ( (crop(ivt(p)) >= 1 .or. percrop(ivt(p)) >= 1) .and. & + generic_crop(ivt(p)) == 0 ) then ! skip 2 generic crops ! lines here for consistency; the transfer terms are zero veg_ps%livestemp(p) = veg_ps%livestemp(p) + veg_pf%livestemp_xfer_to_livestemp(p)*dt veg_ps%livestemp_xfer(p) = veg_ps%livestemp_xfer(p) - veg_pf%livestemp_xfer_to_livestemp(p)*dt @@ -280,7 +281,8 @@ subroutine PhosphorusStateUpdate1(num_soilc, filter_soilc, num_soilp, filter_soi veg_ps%livecrootp(p) = veg_ps%livecrootp(p) - veg_pf%livecrootp_to_retransp(p)*dt veg_ps%retransp(p) = veg_ps%retransp(p) + veg_pf%livecrootp_to_retransp(p)*dt end if - if (ivt(p) >= npcropmin) then ! Beth adds retrans from froot + if ( (crop(ivt(p)) >= 1 .or. percrop(ivt(p)) >= 1) .and. & + generic_crop(ivt(p)) == 0 ) then ! Beth adds retrans from froot veg_ps%frootp(p) = veg_ps%frootp(p) - veg_pf%frootp_to_retransp(p)*dt veg_ps%retransp(p) = veg_ps%retransp(p) + veg_pf%frootp_to_retransp(p)*dt veg_ps%livestemp(p) = veg_ps%livestemp(p) - veg_pf%livestemp_to_litter(p)*dt @@ -331,7 +333,8 @@ subroutine PhosphorusStateUpdate1(num_soilc, filter_soilc, num_soilp, filter_soi veg_ps%deadcrootp_storage(p) = veg_ps%deadcrootp_storage(p) + veg_pf%ppool_to_deadcrootp_storage(p)*dt end if - if (ivt(p) >= npcropmin) then ! skip 2 generic crops + if ( (crop(ivt(p)) >= 1 .or. percrop(ivt(p)) >= 1) .and. & + generic_crop(ivt(p)) == 0 ) then ! skip 2 generic crops veg_ps%ppool(p) = veg_ps%ppool(p) - veg_pf%ppool_to_livestemp(p)*dt veg_ps%livestemp(p) = veg_ps%livestemp(p) + veg_pf%ppool_to_livestemp(p)*dt veg_ps%ppool(p) = veg_ps%ppool(p) - veg_pf%ppool_to_livestemp_storage(p)*dt @@ -359,7 +362,8 @@ subroutine PhosphorusStateUpdate1(num_soilc, filter_soilc, num_soilp, filter_soi veg_ps%deadcrootp_xfer(p) = veg_ps%deadcrootp_xfer(p) + veg_pf%deadcrootp_storage_to_xfer(p)*dt end if - if (ivt(p) >= npcropmin) then ! skip 2 generic crops + if ( (crop(ivt(p)) >= 1 .or. percrop(ivt(p)) >= 1) .and. & + generic_crop(ivt(p)) == 0 ) then ! skip 2 generic crops ! lines here for consistency; the transfer terms are zero veg_ps%livestemp_storage(p) = veg_ps%livestemp_storage(p) - veg_pf%livestemp_storage_to_xfer(p)*dt veg_ps%livestemp_xfer(p) = veg_ps%livestemp_xfer(p) + veg_pf%livestemp_storage_to_xfer(p)*dt diff --git a/components/elm/src/biogeochem/PrecisionControlMod.F90 b/components/elm/src/biogeochem/PrecisionControlMod.F90 index 89e30c83fd1e..8767d300b244 100644 --- a/components/elm/src/biogeochem/PrecisionControlMod.F90 +++ b/components/elm/src/biogeochem/PrecisionControlMod.F90 @@ -39,7 +39,7 @@ subroutine PrecisionControl(num_soilc, filter_soilc, num_soilp, filter_soilp) !$acc routine seq use elm_varctl , only : iulog, use_c13, use_c14, use_fates use elm_varpar , only : nlevdecomp_full, crop_prog - use pftvarcon , only : nc3crop + use pftvarcon , only : crop, generic_crop, percrop use tracer_varcon , only : is_active_betr_bgc use CNDecompCascadeConType , only : decomp_cascade_con ! @@ -211,7 +211,9 @@ subroutine PrecisionControl(num_soilc, filter_soilc, num_soilp, filter_soilp) veg_ps%frootp_xfer(p) = 0._r8 end if - if ( crop_prog .and. veg_pp%itype(p) >= nc3crop )then + if ( crop_prog .and. & + (crop(veg_pp%itype(p)) >= 1 .or. & + percrop(veg_pp%itype(p)) >= 1) )then ! grain C and N if (abs(veg_cs%grainc(p)) < ccrit) then pc = pc + veg_cs%grainc(p) @@ -513,7 +515,9 @@ subroutine PrecisionControl(num_soilc, filter_soilc, num_soilp, filter_soilp) endif end if - if ( crop_prog .and. veg_pp%itype(p) >= nc3crop )then + if ( crop_prog .and. & + (crop(veg_pp%itype(p)) >= 1 .or. & + percrop(veg_pp%itype(p)) >= 1) )then ! xsmrpool (C only) if (abs(veg_cs%xsmrpool(p)) < ccrit) then pc = pc + veg_cs%xsmrpool(p) diff --git a/components/elm/src/biogeochem/SatellitePhenologyMod.F90 b/components/elm/src/biogeochem/SatellitePhenologyMod.F90 index b5d9b1bd3a4b..688b254bd839 100644 --- a/components/elm/src/biogeochem/SatellitePhenologyMod.F90 +++ b/components/elm/src/biogeochem/SatellitePhenologyMod.F90 @@ -304,7 +304,7 @@ subroutine SatellitePhenology(bounds, num_filter, filter, & ! Calculates leaf areas (tlai, elai), stem areas (tsai, esai) and height (htop). ! ! !USES: - use pftvarcon, only : noveg, nbrdlf_dcd_brl_shrub + use pftvarcon, only : woody use elm_varctl, only : use_fates_sp ! ! !ARGUMENTS: @@ -371,7 +371,7 @@ subroutine SatellitePhenology(bounds, num_filter, filter, & ! snow burial fraction for short vegetation (e.g. grasses) as in ! Wang and Zeng, 2007. - if (veg_pp%itype(p) > noveg .and. veg_pp%itype(p) <= nbrdlf_dcd_brl_shrub ) then + if (woody(veg_pp%itype(p)) >= 1.0_r8) then ol = min( max(snow_depth(c)-hbot(p), 0._r8), htop(p)-hbot(p)) fb = 1._r8 - ol / max(1.e-06_r8, htop(p)-hbot(p)) else diff --git a/components/elm/src/biogeochem/VOCEmissionMod.F90 b/components/elm/src/biogeochem/VOCEmissionMod.F90 index cb58227b5235..64a72fe78b8e 100644 --- a/components/elm/src/biogeochem/VOCEmissionMod.F90 +++ b/components/elm/src/biogeochem/VOCEmissionMod.F90 @@ -9,13 +9,9 @@ module VOCEmissionMod use shr_log_mod , only : errMsg => shr_log_errMsg use elm_varctl , only : iulog use elm_varpar , only : numpft, nlevcan - use pftvarcon , only : ndllf_evr_tmp_tree, ndllf_evr_brl_tree - use pftvarcon , only : ndllf_dcd_brl_tree, nbrdlf_evr_trp_tree - use pftvarcon , only : nbrdlf_evr_tmp_tree, nbrdlf_dcd_brl_shrub - use pftvarcon , only : nbrdlf_dcd_trp_tree, nbrdlf_dcd_tmp_tree - use pftvarcon , only : nbrdlf_dcd_brl_tree, nbrdlf_evr_shrub - use pftvarcon , only : nc3_arctic_grass , nc3crop - use pftvarcon , only : nc4_grass, noveg + use elm_varpar , only : numveg ! fixed as 16, while numpft above may be variable + use pftvarcon , only : woody, graminoid, generic_crop, crop, percrop + use pftvarcon , only : needleleaf, evergreen use shr_megan_mod , only : shr_megan_megcomps_n, shr_megan_megcomp_t, shr_megan_linkedlist use shr_megan_mod , only : shr_megan_mechcomps_n, shr_megan_mechcomps, shr_megan_mapped_emisfctrs use MEGANFactorsMod , only : Agro, Amat, Anew, Aold, betaT, ct1, ct2, LDF, Ceo @@ -114,7 +110,7 @@ subroutine InitAllocate(this, bounds) ! !LOCAL VARIABLES: integer :: i, imeg integer :: class_num - real(r8) :: factors(numpft) + real(r8) :: factors(numveg) real(r8) :: molec_wght integer :: begg, endg integer :: begp, endp @@ -128,7 +124,8 @@ subroutine InitAllocate(this, bounds) meg_cmp => shr_megan_linkedlist do while(associated(meg_cmp)) - allocate(meg_cmp%emis_factors(numpft)) + !allocate(meg_cmp%emis_factors(numpft)) + allocate(meg_cmp%emis_factors(numveg)) ! TODO: VOCEmission input is with a hard-wired num of pft (16) call megan_factors_get( trim(meg_cmp%name), factors, class_num, molec_wght ) meg_cmp%emis_factors = factors meg_cmp%class_number = class_num @@ -693,21 +690,21 @@ function get_map_EF(ivt_in, g_in, ti_in, vocemis_vars) get_map_EF = 0._r8 - if ( ivt_in == ndllf_evr_tmp_tree & - .or. ivt_in == ndllf_evr_brl_tree) then !fineleaf evergreen + if (woody(ivt_in) == 1.0_r8 .and. evergreen(ivt_in) == 1 & + .and. needleleaf(ivt_in) == 1) then !fineleaf evergreen trees get_map_EF = vocemis_vars%efisop_grc(2,g_in, ti_in) - else if (ivt_in == ndllf_dcd_brl_tree) then !fineleaf deciduous + else if (woody(ivt_in) == 1.0_r8 .and. evergreen(ivt_in) == 0 & + .and. needleleaf(ivt_in) == 1) then !fineleaf deciduous trees get_map_EF = vocemis_vars%efisop_grc(3,g_in, ti_in) - else if (ivt_in >= nbrdlf_evr_trp_tree & - .and. ivt_in <= nbrdlf_dcd_brl_tree) then !broadleaf trees + else if (woody(ivt_in) == 1.0_r8 & + .and. needleleaf(ivt_in) == 0) then !broadleaf trees get_map_EF = vocemis_vars%efisop_grc(1,g_in,ti_in) - else if (ivt_in >= nbrdlf_evr_shrub & - .and. ivt_in <= nbrdlf_dcd_brl_shrub) then !shrubs + else if (woody(ivt_in) == 2.0_r8) then !shrubs get_map_EF = vocemis_vars%efisop_grc(4,g_in, ti_in) - else if (ivt_in >= nc3_arctic_grass & - .and. ivt_in <= nc4_grass) then !grass + else if (graminoid(ivt_in) == 1) then !grass get_map_EF = vocemis_vars%efisop_grc(5,g_in, ti_in) - else if (ivt_in >= nc3crop) then !crops + else if (generic_crop(ivt_in) == 1 .or. crop(ivt_in) == 1 & + .or. percrop(ivt_in) == 1) then !crops get_map_EF = vocemis_vars%efisop_grc(6,g_in, ti_in) end if @@ -970,7 +967,8 @@ function get_gamma_A(ivt_in, elai240_in,elai_in,nclass_in) real(r8) :: elai_prev ! lai for previous timestep real(r8) :: fnew, fgro, fmat, fold ! fractions of leaves at different phenological stages !----------------------------------------------------------------------- - if ( (ivt_in == ndllf_dcd_brl_tree) .or. (ivt_in >= nbrdlf_dcd_trp_tree) ) then ! non-evergreen + !if ( (ivt_in == ndllf_dcd_brl_tree) .or. (ivt_in >= nbrdlf_dcd_trp_tree) ) then ! non-evergreen + if ( (woody(ivt_in) == 1.0_r8) .and. (evergreen(ivt_in) <= 0) ) then ! non-evergreen tree if ( (elai240_in > 0.0_r8) .and. (elai240_in < 1.e30_r8) )then elai_prev = 2._r8*elai240_in-elai_in ! have accumulated average lai over last timestep diff --git a/components/elm/src/biogeochem/VegStructUpdateMod.F90 b/components/elm/src/biogeochem/VegStructUpdateMod.F90 index 9a7db79154b4..cd982139eef4 100644 --- a/components/elm/src/biogeochem/VegStructUpdateMod.F90 +++ b/components/elm/src/biogeochem/VegStructUpdateMod.F90 @@ -37,8 +37,8 @@ subroutine VegStructUpdate(num_soilp, filter_soilp, & ! vegetation structure (LAI, SAI, height) ! ! !USES: - use pftvarcon , only : noveg, nc3crop, nc3irrig, nbrdlf_evr_shrub, nbrdlf_dcd_brl_shrub - use pftvarcon , only : ncorn, ncornirrig, npcropmin, ztopmx, laimx + use pftvarcon , only : noveg, woody, generic_crop, crop, percrop + use pftvarcon , only : ncorn, ncornirrig, ztopmx, laimx use pftvarcon , only : nmiscanthus, nmiscanthusirrig, nswitchgrass, nswitchgrassirrig use elm_time_manager , only : get_rad_step_size use elm_varctl , only : spinup_state, spinup_mortality_factor @@ -148,7 +148,7 @@ subroutine VegStructUpdate(num_soilp, filter_soilp, & ! alpha are set by PFT, and alpha is scaled to CLM time step by multiplying by ! dt and dividing by dtsmonth (seconds in average 30 day month) ! tsai_min scaled by 0.5 to match MODIS satellite derived values - if (ivt(p) == nc3crop .or. ivt(p) == nc3irrig) then ! generic crops + if (generic_crop(ivt(p)) == 1) then ! generic crops tsai_alpha = 1.0_r8-1.0_r8*dt/dtsmonth tsai_min = 0.1_r8 @@ -164,7 +164,7 @@ subroutine VegStructUpdate(num_soilp, filter_soilp, & ! trees and shrubs ! if shrubs have a squat taper - if (ivt(p) >= nbrdlf_evr_shrub .and. ivt(p) <= nbrdlf_dcd_brl_shrub) then + if (woody(ivt(p)) == 2.0_r8) then taper = 10._r8 ! otherwise have a tall taper else @@ -194,7 +194,8 @@ subroutine VegStructUpdate(num_soilp, filter_soilp, & hbot(p) = max(0._r8, min(3._r8, htop(p)-1._r8)) - else if (ivt(p) >= npcropmin) then ! prognostic crops + else if ( generic_crop(ivt(p)) <1 .and. & + (crop(ivt(p)) >= 1 .or. percrop(ivt(p)) >= 1) ) then ! prognostic crops if (tlai(p) >= laimx(ivt(p))) peaklai(p) = 1 ! used in CNAllocation @@ -248,7 +249,7 @@ subroutine VegStructUpdate(num_soilp, filter_soilp, & ! adjust lai and sai for burying by snow. ! snow burial fraction for short vegetation (e.g. grasses) as in ! Wang and Zeng, 2007. - if (ivt(p) > noveg .and. ivt(p) <= nbrdlf_dcd_brl_shrub ) then + if (woody(ivt(p)) >= 1.0_r8 ) then ol = min( max(snow_depth(c)-hbot(p), 0._r8), htop(p)-hbot(p)) fb = 1._r8 - ol / max(1.e-06_r8, htop(p)-hbot(p)) else diff --git a/components/elm/src/biogeophys/CanopyFluxesMod.F90 b/components/elm/src/biogeophys/CanopyFluxesMod.F90 index 6c96e70e172d..fd6cd3ab163e 100755 --- a/components/elm/src/biogeophys/CanopyFluxesMod.F90 +++ b/components/elm/src/biogeophys/CanopyFluxesMod.F90 @@ -17,7 +17,7 @@ module CanopyFluxesMod use elm_varctl , only : use_hydrstress use elm_varpar , only : nlevgrnd, nlevsno use elm_varcon , only : namep - use pftvarcon , only : nbrdlf_dcd_tmp_shrub, nsoybean , nsoybeanirrig + use pftvarcon , only : crop, nfixer use decompMod , only : bounds_type use PhotosynthesisMod , only : Photosynthesis, PhotosynthesisTotal, Fractionation, PhotoSynthesisHydraulicStress use SoilMoistStressMod , only : calc_effective_soilporosity, calc_volumetric_h2oliq @@ -869,7 +869,8 @@ subroutine CanopyFluxes(bounds, num_nolakeurbanp, filter_nolakeurbanp, & p = filterp(f) c = veg_pp%column(p) if(.not.veg_pp%is_fates(p)) then - if (veg_pp%itype(p) == nsoybean .or. veg_pp%itype(p) == nsoybeanirrig) then + ! soybean (crop with N fixation) + if (crop(veg_pp%itype(p)) >= 1 .and. nfixer(veg_pp%itype(p)) == 1) then btran(p) = min(1._r8, btran(p) * 1.25_r8) end if @@ -909,7 +910,8 @@ subroutine CanopyFluxes(bounds, num_nolakeurbanp, filter_nolakeurbanp, & do f = 1, fn p = filterp(f) c = veg_pp%column(p) - if (veg_pp%itype(p) == nsoybean .or. veg_pp%itype(p) == nsoybeanirrig) then + ! soybean (crop with N fixation) + if (crop(veg_pp%itype(p)) >= 1 .and. nfixer(veg_pp%itype(p)) == 1) then btran(p) = min(1._r8, btran(p) * 1.25_r8) end if end do diff --git a/components/elm/src/biogeophys/PhotosynthesisMod.F90 b/components/elm/src/biogeophys/PhotosynthesisMod.F90 index 65ddbbb71553..f080c457fa3c 100644 --- a/components/elm/src/biogeophys/PhotosynthesisMod.F90 +++ b/components/elm/src/biogeophys/PhotosynthesisMod.F90 @@ -225,7 +225,6 @@ subroutine Photosynthesis ( bounds, fn, filterp, & !$acc routine seq use elm_varcon , only : rgas, tfrz use elm_varctl , only : carbon_only - use pftvarcon , only : nbrdlf_dcd_tmp_shrub, nsoybean, nsoybeanirrig, npcropmin use pftvarcon , only : vcmax_np1, vcmax_np2, vcmax_np3, vcmax_np4, jmax_np1, jmax_np2, jmax_np3 ! ! !ARGUMENTS: @@ -1594,7 +1593,6 @@ subroutine PhotosynthesisHydraulicStress ( bounds, fn, filterp, & use elm_varctl , only : carbon_only !use elm_varctl , only : lnc_opt, reduce_dayl_factor, vcmax_opt use elm_varpar , only : nlevsoi - use pftvarcon , only : nbrdlf_dcd_tmp_shrub, npcropmin use pftvarcon , only : vcmax_np1, vcmax_np2, vcmax_np3, vcmax_np4, jmax_np1, jmax_np2, jmax_np3 use ColumnType , only : col_pp diff --git a/components/elm/src/biogeophys/SedYieldMod.F90 b/components/elm/src/biogeophys/SedYieldMod.F90 index 10b0db728149..e50544edde6c 100644 --- a/components/elm/src/biogeophys/SedYieldMod.F90 +++ b/components/elm/src/biogeophys/SedYieldMod.F90 @@ -63,7 +63,7 @@ subroutine SoilErosion (bounds, num_soilc, filter_soilc, & use elm_time_manager, only : get_step_size use landunit_varcon , only : istcrop, istsoil, istice use pftvarcon , only : gcbc_p, gcbc_q, gcbr_p, gcbr_q - use pftvarcon , only : nc4_grass + use pftvarcon , only : generic_crop, crop, percrop ! ! !ARGUMENTS: type(bounds_type) , intent(in) :: bounds @@ -218,7 +218,9 @@ subroutine SoilErosion (bounds, num_soilc, filter_soilc, & (veg_cs%livecrootc(p)+veg_cs%deadcrootc(p))*croot_prof(p,1) ) fgndcov = exp( -gcbc_p(veg_pp%itype(p))*PCT_gnd - & gcbr_p(veg_pp%itype(p))*Broot ) - if( veg_pp%itype(p) > nc4_grass )then + if( generic_crop(veg_pp%itype(p)) >= 1 .or. & + crop(veg_pp%itype(p)) >= 1 .or. & + percrop(veg_pp%itype(p)) >=1 )then Es_Pcrp = Es_Pcrp + pfactor(c) * ftillage * flitho * & fgndcov * veg_pp%wtcol(p) * K * (KE_DT+KE_LD) @@ -266,7 +268,9 @@ subroutine SoilErosion (bounds, num_soilc, filter_soilc, & nh = 0.03_r8 + 0.05_r8*max(Crsd,Clai) fsr = fsr + veg_pp%wtcol(p) * (0.03_r8/nh)**0.6_r8 - if ( veg_pp%itype(p) > nc4_grass ) then + if ( generic_crop(veg_pp%itype(p)) >= 1 .or. & + crop(veg_pp%itype(p)) >= 1 .or. & + percrop(veg_pp%itype(p)) >=1 ) then ftillage_tc = ftillage_tc + ftillage * veg_pp%wtcol(p) Es_Q = Es_Q + 19.1_r8 * qfactor(c) * 2._r8/COH * flitho * fslp * & diff --git a/components/elm/src/dyn_subgrid/dynHarvestMod.F90 b/components/elm/src/dyn_subgrid/dynHarvestMod.F90 index 5256f415efe2..07455f77ec6e 100644 --- a/components/elm/src/dyn_subgrid/dynHarvestMod.F90 +++ b/components/elm/src/dyn_subgrid/dynHarvestMod.F90 @@ -202,7 +202,8 @@ subroutine CNHarvest (num_soilc, filter_soilc, num_soilp, filter_soilp, cnstate_ ! Harvest mortality routine for coupled carbon-nitrogen code (CN) ! !USES: - use pftvarcon , only : noveg, nbrdlf_evr_shrub, pprodharv10 + use pftvarcon , only : pprodharv10 + use pftvarcon , only : woody use elm_varcon , only : secspday use elm_time_manager, only : get_days_per_year use GridcellType , only : grc_pp @@ -377,7 +378,7 @@ subroutine CNHarvest (num_soilc, filter_soilc, num_soilp, filter_soilp, cnstate_ ! If this is a tree pft, then ! get the annual harvest "mortality" rate (am) from harvest array ! and convert to rate per second - if (ivt(p) > noveg .and. ivt(p) < nbrdlf_evr_shrub) then + if (woody(ivt(p)) == 1.0_r8) then if (do_harvest) then am = 0._r8 diff --git a/components/elm/src/main/surfrdUtilsMod.F90 b/components/elm/src/main/surfrdUtilsMod.F90 index a32570c15a29..1e58b5174afa 100644 --- a/components/elm/src/main/surfrdUtilsMod.F90 +++ b/components/elm/src/main/surfrdUtilsMod.F90 @@ -20,7 +20,7 @@ module surfrdUtilsMod ! !PUBLIC MEMBER FUNCTIONS: public :: check_sums_equal_1_3d ! Confirm that sum(arr(n,t,:)) == 1 for all n public :: check_sums_equal_1_2d ! Confirm that sum(arr(n,:)) == 1 for all n - public :: convert_cft_to_pft ! Conversion of crop CFT to natural veg PFT:w + public :: convert_cft_to_pft ! Conversion of crop CFT to natural veg PFT public :: collapse_crop_types ! Collapse unused crop types into types used in this run public :: collapse_crop_var ! Collapse crop variables according to cft weights determined in previous "collapse" subroutines public :: convert_pft_to_cft ! Conversion of crops from natural veg to CFT @@ -124,20 +124,21 @@ subroutine convert_cft_to_pft( begg, endg, cftsize, wt_cft ) ! !USES: use elm_varsur , only : wt_lunit, wt_nat_patch use elm_varpar , only : cft_size, surfpft_size - use pftvarcon , only : nc3crop + use elm_varpar , only : natpft_size use landunit_varcon , only : istsoil, istcrop use topounit_varcon , only : max_topounits ! !ARGUMENTS: implicit none integer , intent(in) :: begg, endg - integer , intent(in) :: cftsize ! CFT size + integer , intent(in) :: cftsize ! CFT size ! this could be wrong if by input real(r8) , intent(inout) :: wt_cft(begg:,:,:) ! CFT weights ! ! !LOCAL VARIABLES: integer :: g, t ! index !----------------------------------------------------------------------- - SHR_ASSERT_ALL((ubound(wt_cft ) == (/endg,max_topounits, cftsize /)), errMsg(__FILE__, __LINE__)) - SHR_ASSERT_ALL((ubound(wt_nat_patch) == (/endg,max_topounits, nc3crop+cftsize-1/)), errMsg(__FILE__, __LINE__)) + ! note (01-29-2024 by fmyuan@ornl.gov, cftsize --> elm_varpar:cft_size) + SHR_ASSERT_ALL((ubound(wt_cft ) == (/endg,max_topounits, cft_size /)), errMsg(__FILE__, __LINE__)) + SHR_ASSERT_ALL((ubound(wt_nat_patch) == (/endg,max_topounits, natpft_size+cft_size/)), errMsg(__FILE__, __LINE__)) do g = begg, endg do t = 1, max_topounits @@ -145,12 +146,12 @@ subroutine convert_cft_to_pft( begg, endg, cftsize, wt_cft ) ! Move CFT over to PFT and do weighted average of the crop and soil parts wt_nat_patch(g,t,:) = wt_nat_patch(g,t,:) * wt_lunit(g,t,istsoil) wt_cft(g,t,:) = wt_cft(g,t,:) * wt_lunit(g,t,istcrop) - wt_nat_patch(g,t,nc3crop:) = wt_cft(g,t,:) ! Add crop CFT's to end of natural veg PFT's - wt_lunit(g,t,istsoil) = (wt_lunit(g,t,istsoil) + wt_lunit(g,t,istcrop)) ! Add crop landunit to soil landunit + wt_nat_patch(g,t,natpft_size:) = wt_cft(g,t,:) ! Add crop CFT's to end of natural veg PFT's + wt_lunit(g,t,istsoil) = (wt_lunit(g,t,istsoil) + wt_lunit(g,t,istcrop)) ! Add crop landunit to soil landunit wt_nat_patch(g,t,:) = wt_nat_patch(g,t,:) / wt_lunit(g,t,istsoil) - wt_lunit(g,t,istcrop) = 0.0_r8 ! Zero out crop CFT's + wt_lunit(g,t,istcrop) = 0.0_r8 ! Zero out crop CFT's else - wt_nat_patch(g,t,nc3crop:) = 0.0_r8 ! Make sure generic crops are zeroed out + wt_nat_patch(g,t,natpft_size:) = 0.0_r8 ! Make sure generic crops are zeroed out end if end do end do @@ -171,7 +172,6 @@ subroutine convert_pft_to_cft( begg, endg ) use elm_varsur , only : wt_lunit, wt_nat_patch, wt_cft use elm_varpar , only : cft_size, surfpft_size use elm_varpar , only : cft_size, cft_lb, cft_ub, surfpft_lb, surfpft_ub - use pftvarcon , only : nc3crop use landunit_varcon , only : istsoil, istcrop use topounit_varcon , only : max_topounits ! !ARGUMENTS: @@ -309,8 +309,8 @@ subroutine collapse_crop_types(wt_cft, fert_cft, fert_p_cft, begg, endg, verbose ! !USES: use elm_varctl , only : irrigate use elm_varpar , only : cft_lb, cft_ub, cft_size - use pftvarcon , only : nc3crop, nc3irrig, npcropmax, mergetoelmpft use pftvarcon , only: is_pft_known_to_model + use pftvarcon , only : npcropmax, mergetoelmpft, npcropmin use topounit_varcon , only : max_topounits ! TKT use GridcellType , only : grc_pp ! TKT ! @@ -369,10 +369,12 @@ subroutine collapse_crop_types(wt_cft, fert_cft, fert_p_cft, begg, endg, verbose ! stride 2 ! where stride 2 means "every other" - do t = 1,max_topounits - wt_cft(g,t, nc3crop:npcropmax-1:2) = & - wt_cft(g,t, nc3crop:npcropmax-1:2) + wt_cft(g,t, nc3irrig:npcropmax:2) ! TKT - wt_cft(g,t, nc3irrig:npcropmax:2) = 0._r8 + do t = grc_pp%topi(g), grc_pp%topf(g) ! TKT + t2 = t - grc_pp%topi(g) + 1 + + wt_cft(g,t2, cft_lb:cft_ub-1:2) = & + wt_cft(g,t2, cft_lb:cft_ub-1:2) + wt_cft(g,t2, cft_lb+1:cft_ub:2) ! TKT + wt_cft(g,t2, cft_lb+1:cft_ub:2) = 0._r8 end do ! TKT end do From 4314a504beed21046772e05080cdbd9ddbb84a5c Mon Sep 17 00:00:00 2001 From: "Yuan, Fengming" Date: Tue, 30 Jan 2024 10:00:41 -0500 Subject: [PATCH 337/451] All PFT read-in constants are passed into VegetationProperties, i.e. veg_pp. Only difference may be actual number of PFTs due to surface data 'natpft' length less than physiology parameter length ('npft'). So it's shall be exactly same by 'use pftvarcon, only: ', or by 'veg_pp%'. This commit try to use either in one code file of .F90. --- components/elm/src/biogeochem/FireMod.F90 | 2 -- .../elm/src/biogeochem/GapMortalityMod.F90 | 1 - .../elm/src/biogeochem/VegStructUpdateMod.F90 | 1 - .../data_types/VegetationPropertiesType.F90 | 24 +++++++++++++++++++ 4 files changed, 24 insertions(+), 4 deletions(-) diff --git a/components/elm/src/biogeochem/FireMod.F90 b/components/elm/src/biogeochem/FireMod.F90 index 743141b20182..24e34e37c555 100644 --- a/components/elm/src/biogeochem/FireMod.F90 +++ b/components/elm/src/biogeochem/FireMod.F90 @@ -735,8 +735,6 @@ subroutine FireFluxes (num_soilc, filter_soilc, num_soilp, filter_soilp, & is_cwd => decomp_cascade_con%is_cwd , & ! Input: [logical (:) ] TRUE => pool is a cwd pool is_litter => decomp_cascade_con%is_litter , & ! Input: [logical (:) ] TRUE => pool is a litter pool - !woody => veg_vp%woody , & ! Input: [real(r8) (:) ] woody lifeform (1=woody, 0=not woody) - cropf_col => cnstate_vars%cropf_col , & ! Input: [real(r8) (:) ] cropland fraction in veg column croot_prof => cnstate_vars%croot_prof_patch , & ! Input: [real(r8) (:,:) ] (1/m) profile of coarse roots stem_prof => cnstate_vars%stem_prof_patch , & ! Input: [real(r8) (:,:) ] (1/m) profile of stems diff --git a/components/elm/src/biogeochem/GapMortalityMod.F90 b/components/elm/src/biogeochem/GapMortalityMod.F90 index 31cd45814d62..3257a6365b65 100644 --- a/components/elm/src/biogeochem/GapMortalityMod.F90 +++ b/components/elm/src/biogeochem/GapMortalityMod.F90 @@ -110,7 +110,6 @@ subroutine GapMortality (num_soilc, filter_soilc, num_soilp, filter_soilp, & associate( & ivt => veg_pp%itype , & ! Input: [integer (:) ] pft vegetation type - woody => veg_vp%woody , & ! Input: [real(r8) (:) ] binary flag for woody lifeform croplive => crop_vars%croplive_patch & ! Input: [logical (:) ] flag, true if planted, not harvested ) diff --git a/components/elm/src/biogeochem/VegStructUpdateMod.F90 b/components/elm/src/biogeochem/VegStructUpdateMod.F90 index cd982139eef4..de7062b810d5 100644 --- a/components/elm/src/biogeochem/VegStructUpdateMod.F90 +++ b/components/elm/src/biogeochem/VegStructUpdateMod.F90 @@ -83,7 +83,6 @@ subroutine VegStructUpdate(num_soilp, filter_soilp, & associate( & ivt => veg_pp%itype , & ! Input: [integer (:) ] pft vegetation type - woody => veg_vp%woody , & ! Input: [real(r8) (:) ] binary flag for woody lifeform (1=woody, 0=not woody) slatop => veg_vp%slatop , & ! Input: [real(r8) (:) ] specific leaf area at top of canopy, projected area basis [m^2/gC] dsladlai => veg_vp%dsladlai , & ! Input: [real(r8) (:) ] dSLA/dLAI, projected area basis [m^2/gC] z0mr => veg_vp%z0mr , & ! Input: [real(r8) (:) ] ratio of momentum roughness length to canopy top height (-) diff --git a/components/elm/src/data_types/VegetationPropertiesType.F90 b/components/elm/src/data_types/VegetationPropertiesType.F90 index 2cb4e01c8a46..21d7ed671f31 100644 --- a/components/elm/src/data_types/VegetationPropertiesType.F90 +++ b/components/elm/src/data_types/VegetationPropertiesType.F90 @@ -143,6 +143,13 @@ module VegetationPropertiesType real(r8), pointer :: nstor(:) => null() !Nitrogen storage pool timescale real(r8), pointer :: br_xr(:) => null() !Base rate for excess respiration real(r8), pointer :: tc_stress => null() !Critial temperature for moisture stress + ! new properties for flexible PFT + real(r8), pointer :: climatezone(:) => null() !climate zone adapted + real(r8), pointer :: nonvascular(:) => null() !nonvascular type or vascular + real(r8), pointer :: graminoid(:) => null() !graminoid or not + real(r8), pointer :: generic_crop(:) => null() !generic crop or not for prognostic crop modules (?) + real(r8), pointer :: needleleaf(:) => null() !needleleaf or broadleaf + real(r8), pointer :: nfixer(:) => null() !cablity of nitrogen fixation from atm. N2 contains @@ -181,6 +188,8 @@ subroutine veg_vp_init(this) use pftvarcon , only : fnr, act25, kcha, koha, cpha, vcmaxha, jmaxha, tpuha use pftvarcon , only : lmrha, vcmaxhd, jmaxhd, tpuhd, lmrse, qe, theta_cj use pftvarcon , only : bbbopt, mbbopt, nstor, br_xr, tc_stress, lmrhd + ! new properties for flexible PFT + use pftvarcon , only : climatezone, nonvascular, graminoid, generic_crop,needleleaf, nfixer ! class (vegetation_properties_type) :: this @@ -305,6 +314,14 @@ subroutine veg_vp_init(this) allocate(this%tc_stress ) !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + ! new properties for flexible PFT + allocate( this%climatezone(0:numpft)) ; this%climatezone(:) =spval + allocate( this%nonvascular(0:numpft)) ; this%nonvascular(:) =spval + allocate( this%graminoid(0:numpft)) ; this%graminoid(:) =spval + allocate( this%generic_crop(0:numpft)) ; this%generic_crop(:) =spval + allocate( this%needleleaf(0:numpft)) ; this%needleleaf(:) =spval + allocate( this%nfixer(0:numpft)) ; this%nfixer(:) =spval + ! ----------------------------------------------------------------------------------------------------------- do m = 0,numpft @@ -393,6 +410,13 @@ subroutine veg_vp_init(this) this%mbbopt(m) = mbbopt(m) this%nstor(m) = nstor(m) this%br_xr(m) = br_xr(m) + ! new properties for flexible PFT + this%climatezone(m) = climatezone(m) + this%nonvascular(m) = nonvascular(m) + this%graminoid(m) = graminoid(m) + this%generic_crop(m) = generic_crop(m) + this%needleleaf(m) = needleleaf(m) + this%nfixer(m) = nfixer(m) end do From a0765f2dd4f96669d82fc1cf2b78b2449f086447 Mon Sep 17 00:00:00 2001 From: "Yuan, Fengming" Date: Tue, 31 Oct 2023 17:07:41 -0400 Subject: [PATCH 338/451] Fix of possible bugs in surfrdMod.F90 --- components/elm/src/main/surfrdMod.F90 | 2 ++ 1 file changed, 2 insertions(+) diff --git a/components/elm/src/main/surfrdMod.F90 b/components/elm/src/main/surfrdMod.F90 index 9cbcd4b2b8e0..1a957e8cd38a 100755 --- a/components/elm/src/main/surfrdMod.F90 +++ b/components/elm/src/main/surfrdMod.F90 @@ -1105,6 +1105,8 @@ subroutine surfrd_pftformat( begg, endg, ncid ) end if fert_p_cft = 0.0_r8 + wt_nat_patch(begg:endg, :, :) = 0.0_r8 + wt_cft(begg:endg, :, :) = 0.0_r8 if (.not. create_crop_landunit) then call ncd_io(ncid=ncid, varname='PCT_NAT_PFT', flag='read', data=wt_nat_patch, & dim1name=grlnd, readvar=readvar) From c5afb348b306b6bebc60389201a6d50340b2d37e Mon Sep 17 00:00:00 2001 From: "Yuan, Fengming" Date: Tue, 3 Jan 2023 16:06:50 -0500 Subject: [PATCH 339/451] Make natpft patch and croppft patch are merged correctly, especially when flexible length pfts are user-provided, and/or surfdata 'lsmpft' dimension is less than 'pft' dimension in parameter file. --- components/elm/src/main/elm_initializeMod.F90 | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/components/elm/src/main/elm_initializeMod.F90 b/components/elm/src/main/elm_initializeMod.F90 index 86e72030b946..9fe4959c241d 100755 --- a/components/elm/src/main/elm_initializeMod.F90 +++ b/components/elm/src/main/elm_initializeMod.F90 @@ -59,6 +59,7 @@ subroutine initialize1( ) ! !USES: use elm_varpar , only: elm_varpar_init, natpft_lb, natpft_ub use elm_varpar , only: cft_lb, cft_ub, maxpatch_glcmec + use elm_varpar , only: mxpft, numveg, mxpft_nc, numpft use elm_varpar , only: update_pft_array_bounds use elm_varpar , only: surfpft_lb, surfpft_ub use elm_varcon , only: elm_varcon_init @@ -293,6 +294,17 @@ subroutine initialize1( ) ! Independent of model resolution, Needs to stay before surfrd_get_data call pftconrd() + ! by user-defined PFT (numbers and names), 'numpft/mxpft_nc' changed and other indices + ! a few arrays had been allocated in elm_initializedMod.F90:L266-268 and require redo after this 'pftconrd' call + if ((numpft/=mxpft .or. numpft/=numveg) .or. (mxpft_nc/=24 .or. mxpft_nc/=numveg)) then + if (associated(wt_nat_patch)) deallocate(wt_nat_patch) + allocate (wt_nat_patch (begg:endg,1:max_topounits, surfpft_lb:surfpft_ub )) + if (associated(wt_cft)) deallocate(wt_cft) + allocate (wt_cft (begg:endg,1:max_topounits, cft_lb:cft_ub )) + if (associated(fert_cft)) deallocate(fert_cft) + allocate (fert_cft (begg:endg,1:max_topounits, cft_lb:cft_ub )) + endif + call soilorder_conrd() ! Read in FATES parameter values early in the call sequence as well From d01128e7e34b798cb175cdacfa057f0d913075c4 Mon Sep 17 00:00:00 2001 From: "Yuan, Fengming" Date: Tue, 30 Jan 2024 11:58:45 -0500 Subject: [PATCH 340/451] Edit added 'usrpft_codetest_I1850CNPRDCTCBC' test for e3sm_land_developer in effect. --- .../elm/usrpft_codetest_I1850CNPRDCTCBC/user_nl_elm | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/components/elm/cime_config/testdefs/testmods_dirs/elm/usrpft_codetest_I1850CNPRDCTCBC/user_nl_elm b/components/elm/cime_config/testdefs/testmods_dirs/elm/usrpft_codetest_I1850CNPRDCTCBC/user_nl_elm index b2fef61a4be1..921f5d7714b2 100644 --- a/components/elm/cime_config/testdefs/testmods_dirs/elm/usrpft_codetest_I1850CNPRDCTCBC/user_nl_elm +++ b/components/elm/cime_config/testdefs/testmods_dirs/elm/usrpft_codetest_I1850CNPRDCTCBC/user_nl_elm @@ -1,5 +1,5 @@ fsurdat = '$DIN_LOC_ROOT/lnd/clm2/surfdata_map/surfdata_42_FLUXNETSITES_simyr1850_c170912.nc' -paramfile = '$DIN_LOC_ROOT/lnd/clm2/paramdata/clm_params_c211124.nc' +! paramfile = '$DIN_LOC_ROOT/lnd/clm2/paramdata/clm_params_c211124.nc' ! ! When 'user-pft' codes ready, comment out the above line while let the following in. ! @@ -7,4 +7,4 @@ paramfile = '$DIN_LOC_ROOT/lnd/clm2/paramdata/clm_params_c211124.nc' ! woody=1 for tree, or =2 for shrub, and defined other pft flags: ! climatezone(0-4), nonvascular(0/1), graminoid(0/1), generic_crop(0/1), nfixer(0/1), needleleaf(0/1) ! for not going by default, changing one PFT name by appending '_unexpected'. -! paramfile = '$DIN_LOC_ROOT/lnd/clm2/paramdata/clm_params_c211124vpft.nc' + paramfile = '$DIN_LOC_ROOT/lnd/clm2/paramdata/clm_params_c211124vpft.nc' From 1cd6dff299d2200e983911605dc2561d61ea9d67 Mon Sep 17 00:00:00 2001 From: "Yuan, Fengming" Date: Wed, 4 Jan 2023 14:42:50 -0500 Subject: [PATCH 341/451] (optional) Vcmax25 at top canopy for each PFT is as an output variable. --- components/elm/src/biogeophys/PhotosynthesisMod.F90 | 4 ++++ components/elm/src/biogeophys/PhotosynthesisType.F90 | 10 ++++++++++ 2 files changed, 14 insertions(+) diff --git a/components/elm/src/biogeophys/PhotosynthesisMod.F90 b/components/elm/src/biogeophys/PhotosynthesisMod.F90 index f080c457fa3c..aee433610da7 100644 --- a/components/elm/src/biogeophys/PhotosynthesisMod.F90 +++ b/components/elm/src/biogeophys/PhotosynthesisMod.F90 @@ -387,6 +387,7 @@ subroutine Photosynthesis ( bounds, fn, filterp, & gb_mol => photosyns_vars%gb_mol_patch , & ! Output: [real(r8) (:) ] leaf boundary layer conductance (umol H2O/m**2/s) gs_mol => photosyns_vars%gs_mol_patch , & ! Output: [real(r8) (:,:) ] leaf stomatal conductance (umol H2O/m**2/s) vcmax_z => photosyns_vars%vcmax_z_patch , & ! Output: [real(r8) (:,:) ] maximum rate of carboxylation (umol co2/m**2/s) + vcmax25_top => photosyns_vars%vcmax25_top_patch , & ! Output: [real(r8) (:) ] maximum rate of carboxylation at top canopy at 25oC (umol co2/m**2/s) cp => photosyns_vars%cp_patch , & ! Output: [real(r8) (:) ] CO2 compensation point (Pa) kc => photosyns_vars%kc_patch , & ! Output: [real(r8) (:) ] Michaelis-Menten constant for CO2 (Pa) ko => photosyns_vars%ko_patch , & ! Output: [real(r8) (:) ] Michaelis-Menten constant for O2 (Pa) @@ -788,6 +789,9 @@ subroutine Photosynthesis ( bounds, fn, filterp, & vcmax_z(p,iv) = vcmax_z(p,iv) * btran(p) lmr_z(p,iv) = lmr_z(p,iv) * btran(p) + + ! output variable + vcmax25_top(p) = vcmax25top end do ! canopy layer loop end do ! patch loop diff --git a/components/elm/src/biogeophys/PhotosynthesisType.F90 b/components/elm/src/biogeophys/PhotosynthesisType.F90 index 59ae928c23a5..5cb94628d8d2 100644 --- a/components/elm/src/biogeophys/PhotosynthesisType.F90 +++ b/components/elm/src/biogeophys/PhotosynthesisType.F90 @@ -26,6 +26,7 @@ module PhotosynthesisType real(r8), pointer :: ag_patch (:,:) => null()! patch co-limited gross leaf photosynthesis (umol CO2/m**2/s) real(r8), pointer :: an_patch (:,:) => null()! patch net leaf photosynthesis (umol CO2/m**2/s) real(r8), pointer :: vcmax_z_patch (:,:) => null()! patch maximum rate of carboxylation (umol co2/m**2/s) + real(r8), pointer :: vcmax25_top_patch (:) => null()! patch maximum rate of carboxylation at top canopy at 25oC (umol co2/m**2/s) real(r8), pointer :: cp_patch (:) => null()! patch CO2 compensation point (Pa) real(r8), pointer :: kc_patch (:) => null()! patch Michaelis-Menten constant for CO2 (Pa) real(r8), pointer :: ko_patch (:) => null()! patch Michaelis-Menten constant for O2 (Pa) @@ -143,6 +144,7 @@ subroutine InitAllocate(this, bounds) allocate(this%ag_patch (begp:endp,1:nlevcan)) ; this%ag_patch (:,:) = spval allocate(this%an_patch (begp:endp,1:nlevcan)) ; this%an_patch (:,:) = spval allocate(this%vcmax_z_patch (begp:endp,1:nlevcan)) ; this%vcmax_z_patch (:,:) = spval + allocate(this%vcmax25_top_patch (begp:endp)) ; this%vcmax25_top_patch (:) = spval allocate(this%cp_patch (begp:endp)) ; this%cp_patch (:) = spval allocate(this%kc_patch (begp:endp)) ; this%kc_patch (:) = spval allocate(this%ko_patch (begp:endp)) ; this%ko_patch (:) = spval @@ -263,6 +265,12 @@ subroutine InitHistory(this, bounds) call hist_addfld1d (fname='PSNSHA', units='umolCO2/m^2/s', & avgflag='A', long_name='shaded leaf photosynthesis', & ptr_patch=this%psnsha_patch) + + this%vcmax25_top_patch(begp:endp) = spval + call hist_addfld1d (fname='VCMAX25TOP', units='umolCO2/m^2/s', & + avgflag='A', long_name='vcmax at top canopy at 25oC', & + ptr_patch=this%vcmax25_top_patch, default='inactive') + end if if ( use_c13 ) then @@ -423,6 +431,8 @@ subroutine TimeStepInit (this, bounds) this%psnsun_wj_patch(p) = 0._r8 this%psnsun_wp_patch(p) = 0._r8 + this%vcmax25_top_patch(p) = 0._r8 + this%psnsha_patch(p) = 0._r8 this%psnsha_wc_patch(p) = 0._r8 this%psnsha_wj_patch(p) = 0._r8 From 92077c1d238d3ebfc7a00aee1422d6e0ccbf601f Mon Sep 17 00:00:00 2001 From: "Yuan, Fengming" Date: Tue, 12 Mar 2024 14:36:02 -0400 Subject: [PATCH 342/451] crop and perenial crop pft flag, 'iscft', is added so that crop pft indexing may be not in need anymore. --- .../elm/src/biogeochem/AllocationMod.F90 | 40 ++++++------- .../src/biogeochem/CNAllocationBetrMod.F90 | 40 ++++++------- .../elm/src/biogeochem/CNCarbonFluxType.F90 | 16 +++--- .../elm/src/biogeochem/CNCarbonStateType.F90 | 8 +-- .../src/biogeochem/CNGapMortalityBeTRMod.F90 | 6 +- .../src/biogeochem/CNNStateUpdate1BeTRMod.F90 | 10 ++-- .../src/biogeochem/CNNStateUpdate2BeTRMod.F90 | 4 +- .../elm/src/biogeochem/CNNitrogenFluxType.F90 | 2 +- .../src/biogeochem/CNNitrogenStateType.F90 | 6 +- .../elm/src/biogeochem/CNPhenologyBeTRMod.F90 | 11 +++- .../src/biogeochem/CarbonStateUpdate1Mod.F90 | 29 ++++------ .../src/biogeochem/CarbonStateUpdate2Mod.F90 | 4 +- components/elm/src/biogeochem/CropType.F90 | 4 +- .../elm/src/biogeochem/DryDepVelocity.F90 | 6 +- components/elm/src/biogeochem/FireMod.F90 | 27 +++------ .../elm/src/biogeochem/GapMortalityMod.F90 | 12 ++-- .../elm/src/biogeochem/GrowthRespMod.F90 | 4 +- .../elm/src/biogeochem/MaintenanceRespMod.F90 | 4 +- .../biogeochem/NitrogenStateUpdate1Mod.F90 | 14 ++--- .../biogeochem/NitrogenStateUpdate2Mod.F90 | 4 +- .../src/biogeochem/PhenologyFluxLimitMod.F90 | 24 ++++---- .../elm/src/biogeochem/PhenologyMod.F90 | 40 +++++++------ .../elm/src/biogeochem/PhosphorusFluxType.F90 | 1 - .../src/biogeochem/PhosphorusStateType.F90 | 4 +- .../biogeochem/PhosphorusStateUpdate1Mod.F90 | 14 ++--- .../biogeochem/PhosphorusStateUpdate2Mod.F90 | 4 +- .../src/biogeochem/PrecisionControlMod.F90 | 10 +--- .../elm/src/biogeochem/RootDynamicsMod.F90 | 4 +- .../elm/src/biogeochem/VOCEmissionMod.F90 | 5 +- .../elm/src/biogeochem/VegStructUpdateMod.F90 | 7 +-- components/elm/src/biogeophys/SedYieldMod.F90 | 10 +--- .../elm/src/data_types/VegetationDataType.F90 | 29 +++++----- .../data_types/VegetationPropertiesType.F90 | 8 +-- components/elm/src/main/filterMod.F90 | 8 +-- components/elm/src/main/pftvarcon.F90 | 57 ++++++++----------- components/elm/src/main/surfrdMod.F90 | 2 + components/elm/src/main/surfrdUtilsMod.F90 | 2 +- 37 files changed, 221 insertions(+), 259 deletions(-) diff --git a/components/elm/src/biogeochem/AllocationMod.F90 b/components/elm/src/biogeochem/AllocationMod.F90 index a31a07cd8f6c..0110367f59ce 100644 --- a/components/elm/src/biogeochem/AllocationMod.F90 +++ b/components/elm/src/biogeochem/AllocationMod.F90 @@ -386,7 +386,7 @@ subroutine Allocation1_PlantNPDemand (bounds, num_soilc, filter_soilc, num_soilp use elm_varctl , only : carbonphosphorus_only! use pftvarcon , only: npcropmin, declfact, bfact, aleaff, arootf, astemf, noveg use pftvarcon , only: arooti, fleafi, allconsl, allconss, grperc, grpnow, nsoybean - use pftvarcon , only: percrop + use pftvarcon , only: iscft, percrop use elm_varpar , only: nlevdecomp use elm_varcon , only: nitrif_n2o_loss_frac, secspday ! @@ -585,7 +585,7 @@ subroutine Allocation1_PlantNPDemand (bounds, num_soilc, filter_soilc, num_soilp mr = leaf_mr(p) + froot_mr(p) if (woody(ivt(p)) >= 1.0_r8) then mr = mr + livestem_mr(p) + livecroot_mr(p) - else if (ivt(p) >= npcropmin) then + else if (iscft(ivt(p)) >= 1) then if (croplive(p)) mr = mr + livestem_mr(p) + grain_mr(p) end if @@ -672,7 +672,7 @@ subroutine Allocation1_PlantNPDemand (bounds, num_soilc, filter_soilc, num_soilp f5 = 0._r8 ! continued intializations from above - if (ivt(p) >= npcropmin) then ! skip 2 generic crops + if (iscft(ivt(p)) >= 1) then ! skip 2 generic crops if (croplive(p) .and. percrop(ivt(p)) == 0.0_r8 ) then ! same phases appear in subroutine CropPhenology @@ -822,7 +822,7 @@ subroutine Allocation1_PlantNPDemand (bounds, num_soilc, filter_soilc, num_soilp p_allometry(p) = 1._r8/cpl + f1/cpfr + (f3*f4*(1._r8+f2))/cplw + & (f3*(1._r8-f4)*(1._r8+f2))/cpdw - else if (ivt(p) >= npcropmin) then ! skip generic crops + else if (iscft(ivt(p)) >= 1) then ! skip generic crops cng = graincn(ivt(p)) cpg = graincp(ivt(p)) c_allometry(p) = (1._r8+g1)*(1._r8+f1+f5+f3*(1._r8+f2)) @@ -852,10 +852,10 @@ subroutine Allocation1_PlantNPDemand (bounds, num_soilc, filter_soilc, num_soilp ! retransn pool has N from leaves, stems, and roots for ! retranslocation - if (ivt(p) >= npcropmin .and. grain_flag(p) == 1._r8) then + if (iscft(ivt(p)) >= 1 .and. grain_flag(p) == 1._r8) then avail_retransn(p) = plant_ndemand(p) avail_retransp(p) = plant_pdemand(p) - else if (ivt(p) < npcropmin .and. annsum_potential_gpp(p) > 0._r8) then + else if (iscft(ivt(p)) < 1 .and. annsum_potential_gpp(p) > 0._r8) then avail_retransn(p) = (annmax_retransn(p)/2._r8)*(gpp(p)/annsum_potential_gpp(p))/dt avail_retransp(p) = (annmax_retransp(p)/2._r8)*(gpp(p)/annsum_potential_gpp(p))/dt else @@ -1859,7 +1859,7 @@ subroutine Allocation3_PlantCNPAlloc (bounds , & !$acc routine seq use elm_varctl , only: iulog use pftvarcon , only: noveg - use pftvarcon , only: npcropmin, grperc, grpnow + use pftvarcon , only: iscft, grperc, grpnow use elm_varpar , only: nlevdecomp use elm_varcon , only: nitrif_n2o_loss_frac, secspday ! @@ -2142,7 +2142,7 @@ subroutine Allocation3_PlantCNPAlloc (bounds , & fcur = fcur2(ivt(p)) - if (ivt(p) >= npcropmin) then ! skip 2 generic crops + if (iscft(ivt(p)) >= 1) then ! skip 2 generic crops if (croplive(p)) then f1 = aroot(p) / aleaf(p) f3 = astem(p) / aleaf(p) @@ -2328,7 +2328,7 @@ subroutine Allocation3_PlantCNPAlloc (bounds , & fcur = fcur2(ivt(p)) - if (ivt(p) >= npcropmin) then ! skip 2 generic crops + if (iscft(ivt(p)) >= 1) then ! skip 2 generic crops if (croplive(p)) then f1 = aroot(p) / aleaf(p) f3 = astem(p) / aleaf(p) @@ -2345,10 +2345,10 @@ subroutine Allocation3_PlantCNPAlloc (bounds , & sminn_to_npool(p) = sminn_to_plant_patch(p) sminp_to_ppool(p) = sminp_to_plant_patch(p) - if (ivt(p) >= npcropmin .and. grain_flag(p) == 1._r8) then + if (iscft(ivt(p)) >= 1 .and. grain_flag(p) == 1._r8) then avail_retransn(p) = retransn(p)/dt avail_retransp(p) = retransp(p)/dt - else if (ivt(p) < npcropmin .and. annsum_potential_gpp(p) > 0._r8) then + else if (iscft(ivt(p)) < 1 .and. annsum_potential_gpp(p) > 0._r8) then avail_retransn(p) = (annmax_retransn(p)/2._r8)*(gpp(p)/annsum_potential_gpp(p))/dt avail_retransp(p) = (annmax_retransp(p)/2._r8)*(gpp(p)/annsum_potential_gpp(p))/dt else @@ -2374,7 +2374,7 @@ subroutine Allocation3_PlantCNPAlloc (bounds , & mr = leaf_mr(p) + froot_mr(p) if (woody(ivt(p)) >= 1.0_r8) then mr = mr + livestem_mr(p) + livecroot_mr(p) - else if (ivt(p) >= npcropmin) then + else if (iscft(ivt(p)) >= 1) then if (croplive(p)) mr = mr + livestem_mr(p) + grain_mr(p) end if @@ -2473,7 +2473,7 @@ subroutine Allocation3_PlantCNPAlloc (bounds , & p_allometry(p) = 1._r8/cpl + f1/cpfr + (f3*f4*(1._r8+f2))/cplw + & (f3*(1._r8-f4)*(1._r8+f2))/cpdw - else if (ivt(p) >= npcropmin) then ! skip generic crops + else if (iscft(ivt(p)) >= 1) then ! skip generic crops cng = graincn(ivt(p)) cpg = graincp(ivt(p)) c_allometry(p) = (1._r8+g1)*(1._r8+f1+f5+f3*(1._r8+f2)) @@ -2559,7 +2559,7 @@ subroutine Allocation3_PlantCNPAlloc (bounds , & cpool_to_xsmrpool(p) = cpool_to_xsmrpool(p) + nlc * f2 * f3 * (1._r8 - f4) * fcur * (1 + g1) cpool_to_xsmrpool(p) = cpool_to_xsmrpool(p) + nlc * f2 * f3 * (1._r8 - f4) * (1._r8 - fcur) * (1 + g1) end if - if (ivt(p) >= npcropmin) then ! skip 2 generic crops + if (iscft(ivt(p)) >= 1) then ! skip 2 generic crops cpool_to_xsmrpool(p) = cpool_to_xsmrpool(p) + nlc * f3 * f4 * fcur * (1 + g1) cpool_to_xsmrpool(p) = cpool_to_xsmrpool(p) + nlc * f3 * f4 * (1._r8 - fcur) * (1 + g1) cpool_to_xsmrpool(p) = cpool_to_xsmrpool(p) + nlc * f3 * (1._r8 - f4) * fcur * (1 + g1) @@ -2590,7 +2590,7 @@ subroutine Allocation3_PlantCNPAlloc (bounds , & cpool_to_deadcrootc(p) = nlc * f2 * f3 * (1._r8 - f4) * fcur cpool_to_deadcrootc_storage(p) = nlc * f2 * f3 * (1._r8 - f4) * (1._r8 - fcur) end if - if (ivt(p) >= npcropmin) then ! skip 2 generic crops + if (iscft(ivt(p)) >= 1) then ! skip 2 generic crops cpool_to_livestemc(p) = nlc * f3 * f4 * fcur cpool_to_livestemc_storage(p) = nlc * f3 * f4 * (1._r8 - fcur) cpool_to_deadstemc(p) = nlc * f3 * (1._r8 - f4) * fcur @@ -2643,7 +2643,7 @@ subroutine Allocation3_PlantCNPAlloc (bounds , & npool_to_deadcrootn(p) = (nlc * f2 * f3 * (1._r8 - f4) / cndw) * fcur npool_to_deadcrootn_storage(p) = (nlc * f2 * f3 * (1._r8 - f4) / cndw) * (1._r8 - fcur) end if - if (ivt(p) >= npcropmin) then ! skip 2 generic crops + if (iscft(ivt(p)) >= 1) then ! skip 2 generic crops cng = graincn(ivt(p)) npool_to_livestemn(p) = (nlc * f3 * f4 / cnlw) * fcur npool_to_livestemn_storage(p) = (nlc * f3 * f4 / cnlw) * (1._r8 - fcur) @@ -2687,7 +2687,7 @@ subroutine Allocation3_PlantCNPAlloc (bounds , & ppool_to_deadcrootp(p) = (nlc * f2 * f3 * (1._r8 - f4) / cpdw)* fcur ppool_to_deadcrootp_storage(p) = (nlc * f2 * f3 * (1._r8 - f4) / cpdw)* (1._r8 - fcur) end if - if (ivt(p) >= npcropmin) then ! skip 2 generic crops + if (iscft(ivt(p)) >= 1) then ! skip 2 generic crops cpg = graincp(ivt(p)) ppool_to_livestemp(p) = (nlc * f3 * f4 / cplw) * fcur ppool_to_livestemp_storage(p) = (nlc * f3 * f4 / cplw) * (1._r8 -fcur) @@ -2717,7 +2717,7 @@ subroutine Allocation3_PlantCNPAlloc (bounds , & gresp_storage = gresp_storage + cpool_to_livecrootc_storage(p) gresp_storage = gresp_storage + cpool_to_deadcrootc_storage(p) end if - if (ivt(p) >= npcropmin) then ! skip 2 generic crops + if (iscft(ivt(p)) >= 1) then ! skip 2 generic crops gresp_storage = gresp_storage + cpool_to_livestemc_storage(p) gresp_storage = gresp_storage + cpool_to_grainc_storage(p) end if @@ -2771,7 +2771,7 @@ subroutine Allocation3_PlantCNPAlloc (bounds , & npool_to_deadcrootn(p) = cpool_to_deadcrootc(p) / cndw npool_to_deadcrootn_storage(p) = cpool_to_deadcrootc_storage(p) / cndw end if - if (ivt(p) >= npcropmin) then ! skip 2 generic crops + if (iscft(ivt(p)) >= 1) then ! skip 2 generic crops cng = graincn(ivt(p)) supplement_to_plantn(p) = supplement_to_plantn(p) + cpool_to_livestemc(p) / cnlw - npool_to_livestemn(p) supplement_to_plantn(p) = supplement_to_plantn(p) + cpool_to_livestemc_storage(p) / cnlw & @@ -2843,7 +2843,7 @@ subroutine Allocation3_PlantCNPAlloc (bounds , & ppool_to_deadcrootp(p) = cpool_to_deadcrootc(p) / cpdw ppool_to_deadcrootp_storage(p) = cpool_to_deadcrootc_storage(p) / cpdw end if - if (ivt(p) >= npcropmin) then ! skip 2 generic crops + if (iscft(ivt(p)) >= 1) then ! skip 2 generic crops cpg = graincp(ivt(p)) supplement_to_plantp(p) = supplement_to_plantp(p) + max(cpool_to_livestemc(p) / cplw & - ppool_to_livestemp(p),0._r8) diff --git a/components/elm/src/biogeochem/CNAllocationBetrMod.F90 b/components/elm/src/biogeochem/CNAllocationBetrMod.F90 index 42fad84a9d1d..cc8b72046a17 100644 --- a/components/elm/src/biogeochem/CNAllocationBetrMod.F90 +++ b/components/elm/src/biogeochem/CNAllocationBetrMod.F90 @@ -246,7 +246,7 @@ subroutine Allocation1_PlantNPDemand (bounds, num_soilc, filter_soilc, num_soilp use shr_sys_mod , only: shr_sys_flush use elm_varctl , only: iulog,cnallocate_carbon_only,cnallocate_carbonnitrogen_only,& cnallocate_carbonphosphorus_only - use pftvarcon , only: npcropmin, declfact, bfact, aleaff, arootf, astemf, noveg + use pftvarcon , only: iscft, declfact, bfact, aleaff, arootf, astemf, noveg use pftvarcon , only: arooti, fleafi, allconsl, allconss, grperc, grpnow, nsoybean use elm_varpar , only: nlevdecomp use elm_varcon , only: nitrif_n2o_loss_frac, secspday @@ -645,7 +645,7 @@ subroutine Allocation1_PlantNPDemand (bounds, num_soilc, filter_soilc, num_soilp mr = leaf_mr(p) + froot_mr(p) if (woody(ivt(p)) >= 1.0_r8) then mr = mr + livestem_mr(p) + livecroot_mr(p) - else if (ivt(p) >= npcropmin) then + else if (iscft(ivt(p)) >= 1) then if (croplive(p)) mr = mr + livestem_mr(p) + grain_mr(p) end if @@ -726,7 +726,7 @@ subroutine Allocation1_PlantNPDemand (bounds, num_soilc, filter_soilc, num_soilp f5 = 0._r8 ! continued intializations from above - if (ivt(p) >= npcropmin) then ! skip 2 generic crops + if (iscft(ivt(p)) >= 1) then ! skip 2 generic crops if (croplive(p)) then ! same phases appear in subroutine CropPhenology @@ -859,7 +859,7 @@ subroutine Allocation1_PlantNPDemand (bounds, num_soilc, filter_soilc, num_soilp p_allometry(p) = 1._r8/cpl + f1/cpfr + (f3*f4*(1._r8+f2))/cplw + & (f3*(1._r8-f4)*(1._r8+f2))/cpdw - else if (ivt(p) >= npcropmin) then ! skip generic crops + else if (iscft(ivt(p)) >= 1) then ! skip generic crops cng = graincn(ivt(p)) cpg = graincp(ivt(p)) c_allometry(p) = (1._r8+g1)*(1._r8+f1+f5+f3*(1._r8+f2)) @@ -889,10 +889,10 @@ subroutine Allocation1_PlantNPDemand (bounds, num_soilc, filter_soilc, num_soilp ! retransn pool has N from leaves, stems, and roots for ! retranslocation - if (ivt(p) >= npcropmin .and. grain_flag(p) == 1._r8) then + if (iscft(ivt(p)) >= 1 .and. grain_flag(p) == 1._r8) then avail_retransn(p) = plant_ndemand(p) avail_retransp(p) = plant_pdemand(p) - else if (ivt(p) < npcropmin .and. annsum_potential_gpp(p) > 0._r8) then + else if (iscft(ivt(p)) < 1 .and. annsum_potential_gpp(p) > 0._r8) then avail_retransn(p) = (annmax_retransn(p)/2._r8)*(gpp(p)/annsum_potential_gpp(p))/dt avail_retransp(p) = (annmax_retransp(p)/2._r8)*(gpp(p)/annsum_potential_gpp(p))/dt else @@ -1105,10 +1105,10 @@ subroutine Allocation3_PlantCNPAlloc (bounds , & use shr_sys_mod , only: shr_sys_flush use elm_varctl , only: iulog,cnallocate_carbon_only,cnallocate_carbonnitrogen_only,& cnallocate_carbonphosphorus_only -! use pftvarcon , only: npcropmin, declfact, bfact, aleaff, arootf, astemf +! use pftvarcon , only: iscft, declfact, bfact, aleaff, arootf, astemf ! use pftvarcon , only: arooti, fleafi, allconsl, allconss, grperc, grpnow, nsoybean use pftvarcon , only: noveg - use pftvarcon , only: npcropmin, grperc, grpnow + use pftvarcon , only: iscft, grperc, grpnow use elm_varpar , only: nlevdecomp !!nlevsoi, use elm_varcon , only: nitrif_n2o_loss_frac, secspday ! use landunit_varcon , only: istsoil, istcrop @@ -1393,7 +1393,7 @@ subroutine Allocation3_PlantCNPAlloc (bounds , & fcur = fcur2(ivt(p)) - if (ivt(p) >= npcropmin) then ! skip 2 generic crops + if (iscft(ivt(p)) >= 1) then ! skip 2 generic crops if (croplive(p)) then f1 = aroot(p) / aleaf(p) f3 = astem(p) / aleaf(p) @@ -1412,10 +1412,10 @@ subroutine Allocation3_PlantCNPAlloc (bounds , & plant_n_buffer_patch(p) = plant_n_buffer_patch(p) * (1._r8-dt/taun) plant_p_buffer_patch(p) = plant_p_buffer_patch(p) * (1._r8-dt/taun) - if (ivt(p) >= npcropmin .and. grain_flag(p) == 1._r8) then + if (iscft(ivt(p)) >= 1 .and. grain_flag(p) == 1._r8) then avail_retransn(p) = retransn(p)/dt avail_retransp(p) = retransp(p)/dt - else if (ivt(p) < npcropmin .and. annsum_potential_gpp(p) > 0._r8) then + else if (iscft(ivt(p)) < 1 .and. annsum_potential_gpp(p) > 0._r8) then avail_retransn(p) = (annmax_retransn(p)/2._r8)*(gpp(p)/annsum_potential_gpp(p))/dt avail_retransp(p) = (annmax_retransp(p)/2._r8)*(gpp(p)/annsum_potential_gpp(p))/dt else @@ -1436,7 +1436,7 @@ subroutine Allocation3_PlantCNPAlloc (bounds , & mr = leaf_mr(p) + froot_mr(p) if (woody(ivt(p)) >= 1.0_r8) then mr = mr + livestem_mr(p) + livecroot_mr(p) - else if (ivt(p) >= npcropmin) then + else if (iscft(ivt(p)) >= 1) then if (croplive(p)) mr = mr + livestem_mr(p) + grain_mr(p) end if ! try to take mr from xsmr storage pool first @@ -1530,7 +1530,7 @@ subroutine Allocation3_PlantCNPAlloc (bounds , & p_allometry(p) = 1._r8/cpl + f1/cpfr + (f3*f4*(1._r8+f2))/cplw + & (f3*(1._r8-f4)*(1._r8+f2))/cpdw - else if (ivt(p) >= npcropmin) then ! skip generic crops + else if (iscft(ivt(p)) >= 1) then ! skip generic crops cng = graincn(ivt(p)) cpg = graincp(ivt(p)) c_allometry(p) = (1._r8+g1)*(1._r8+f1+f5+f3*(1._r8+f2)) @@ -1614,7 +1614,7 @@ subroutine Allocation3_PlantCNPAlloc (bounds , & cpool_to_xsmrpool(p) = cpool_to_xsmrpool(p) + nlc * f2 * f3 * (1._r8 - f4) * fcur * (1 + g1) cpool_to_xsmrpool(p) = cpool_to_xsmrpool(p) + nlc * f2 * f3 * (1._r8 - f4) * (1._r8 - fcur) * (1 + g1) end if - if (ivt(p) >= npcropmin) then ! skip 2 generic crops + if (iscft(ivt(p)) >= 1) then ! skip 2 generic crops cpool_to_xsmrpool(p) = cpool_to_xsmrpool(p) + nlc * f3 * f4 * fcur * (1 + g1) cpool_to_xsmrpool(p) = cpool_to_xsmrpool(p) + nlc * f3 * f4 * (1._r8 - fcur) * (1 + g1) cpool_to_xsmrpool(p) = cpool_to_xsmrpool(p) + nlc * f3 * (1._r8 - f4) * fcur * (1 + g1) @@ -1645,7 +1645,7 @@ subroutine Allocation3_PlantCNPAlloc (bounds , & cpool_to_deadcrootc(p) = nlc * f2 * f3 * (1._r8 - f4) * fcur cpool_to_deadcrootc_storage(p) = nlc * f2 * f3 * (1._r8 - f4) * (1._r8 - fcur) end if - if (ivt(p) >= npcropmin) then ! skip 2 generic crops + if (iscft(ivt(p)) >= 1) then ! skip 2 generic crops cpool_to_livestemc(p) = nlc * f3 * f4 * fcur cpool_to_livestemc_storage(p) = nlc * f3 * f4 * (1._r8 - fcur) cpool_to_deadstemc(p) = nlc * f3 * (1._r8 - f4) * fcur @@ -1698,7 +1698,7 @@ subroutine Allocation3_PlantCNPAlloc (bounds , & npool_to_deadcrootn(p) = (nlc * f2 * f3 * (1._r8 - f4) / cndw) * fcur npool_to_deadcrootn_storage(p) = (nlc * f2 * f3 * (1._r8 - f4) / cndw) * (1._r8 - fcur) end if - if (ivt(p) >= npcropmin) then ! skip 2 generic crops + if (iscft(ivt(p)) >= 1) then ! skip 2 generic crops cng = graincn(ivt(p)) npool_to_livestemn(p) = (nlc * f3 * f4 / cnlw) * fcur npool_to_livestemn_storage(p) = (nlc * f3 * f4 / cnlw) * (1._r8 - fcur) @@ -1742,7 +1742,7 @@ subroutine Allocation3_PlantCNPAlloc (bounds , & ppool_to_deadcrootp(p) = (nlc * f2 * f3 * (1._r8 - f4) / cpdw)* fcur ppool_to_deadcrootp_storage(p) = (nlc * f2 * f3 * (1._r8 - f4) / cpdw)* (1._r8 - fcur) end if - if (ivt(p) >= npcropmin) then ! skip 2 generic crops + if (iscft(ivt(p)) >= 1) then ! skip 2 generic crops cpg = graincp(ivt(p)) ppool_to_livestemp(p) = (nlc * f3 * f4 / cplw) * fcur ppool_to_livestemp_storage(p) = (nlc * f3 * f4 / cplw) * (1._r8 -fcur) @@ -1772,7 +1772,7 @@ subroutine Allocation3_PlantCNPAlloc (bounds , & gresp_storage = gresp_storage + cpool_to_livecrootc_storage(p) gresp_storage = gresp_storage + cpool_to_deadcrootc_storage(p) end if - if (ivt(p) >= npcropmin) then ! skip 2 generic crops + if (iscft(ivt(p)) >= 1) then ! skip 2 generic crops gresp_storage = gresp_storage + cpool_to_livestemc_storage(p) gresp_storage = gresp_storage + cpool_to_grainc_storage(p) end if @@ -1820,7 +1820,7 @@ subroutine Allocation3_PlantCNPAlloc (bounds , & npool_to_deadcrootn(p) = cpool_to_deadcrootc(p) / cndw npool_to_deadcrootn_storage(p) = cpool_to_deadcrootc_storage(p) / cndw end if - if (ivt(p) >= npcropmin) then ! skip 2 generic crops + if (iscft(ivt(p)) >= 1) then ! skip 2 generic crops cng = graincn(ivt(p)) supplement_to_sminn_vr(c,1) = supplement_to_sminn_vr(c,1) + cpool_to_livestemc(p) / cnlw - npool_to_livestemn(p) supplement_to_sminn_vr(c,1) = supplement_to_sminn_vr(c,1) + cpool_to_livestemc_storage(p) / cnlw & @@ -1891,7 +1891,7 @@ subroutine Allocation3_PlantCNPAlloc (bounds , & ppool_to_deadcrootp(p) = cpool_to_deadcrootc(p) / cpdw ppool_to_deadcrootp_storage(p) = cpool_to_deadcrootc_storage(p) / cpdw end if - if (ivt(p) >= npcropmin) then ! skip 2 generic crops + if (iscft(ivt(p)) >= 1) then ! skip 2 generic crops cpg = graincp(ivt(p)) supplement_to_sminp_vr(c,1) = supplement_to_sminp_vr(c,1) + max(cpool_to_livestemc(p) / cplw & - ppool_to_livestemp(p),0._r8) diff --git a/components/elm/src/biogeochem/CNCarbonFluxType.F90 b/components/elm/src/biogeochem/CNCarbonFluxType.F90 index 092af4fa66bf..61a3f736f621 100644 --- a/components/elm/src/biogeochem/CNCarbonFluxType.F90 +++ b/components/elm/src/biogeochem/CNCarbonFluxType.F90 @@ -10,7 +10,7 @@ module CNCarbonFluxType use landunit_varcon , only : istsoil, istcrop, istdlak use elm_varctl , only : use_c13, use_fates use CH4varcon , only : allowlakeprod - use pftvarcon , only : npcropmin + use pftvarcon , only : iscft use CNDecompCascadeConType , only : decomp_cascade_con use VegetationType , only : veg_pp use ColumnType , only : col_pp @@ -1675,7 +1675,7 @@ subroutine Summary(this, bounds, num_soilc, filter_soilc, num_soilp, filter_soil this%cpool_livecroot_storage_gr_patch(p) + & this%cpool_deadcroot_storage_gr_patch(p) - if ( crop_prog .and. veg_pp%itype(p) >= npcropmin )then + if ( crop_prog .and. iscft(veg_pp%itype(p)) >= 1 )then this%mr_patch(p) = & this%mr_patch(p) + & this%grain_mr_patch(p) @@ -1700,7 +1700,7 @@ subroutine Summary(this, bounds, num_soilc, filter_soilc, num_soilp, filter_soil this%storage_gr_patch(p) ! autotrophic respiration (AR) - if ( crop_prog .and. veg_pp%itype(p) >= npcropmin )then + if ( crop_prog .and. iscft(veg_pp%itype(p)) >= 1 )then this%ar_patch(p) = & this%mr_patch(p) + & this%gr_patch(p) + & @@ -1812,7 +1812,7 @@ subroutine Summary(this, bounds, num_soilc, filter_soilc, num_soilp, filter_soil this%wood_harvestc_patch(p) = & this%hrv_deadstemc_to_prod10c_patch(p) + & this%hrv_deadstemc_to_prod100c_patch(p) - if ( crop_prog .and. veg_pp%itype(p) >= npcropmin )then + if ( crop_prog .and. iscft(veg_pp%itype(p)) >= 1 )then this%wood_harvestc_patch(p) = & this%wood_harvestc_patch(p) + & this%hrv_cropc_to_prod1c_patch(p) @@ -1842,7 +1842,7 @@ subroutine Summary(this, bounds, num_soilc, filter_soilc, num_soilp, filter_soil this%m_gresp_xfer_to_fire_patch(p) + & this%m_cpool_to_fire_patch(p) - if ( crop_prog .and. veg_pp%itype(p) >= npcropmin )then + if ( crop_prog .and. iscft(veg_pp%itype(p)) >= 1 )then this%litfall_patch(p) = & this%litfall_patch(p) + & @@ -1878,7 +1878,7 @@ subroutine Summary(this, bounds, num_soilc, filter_soilc, num_soilp, filter_soil this%hrv_leafc_to_litter_patch(p) + & this%leafc_to_litter_patch(p) - if ( crop_prog .and. veg_pp%itype(p) >= npcropmin )then + if ( crop_prog .and. iscft(veg_pp%itype(p)) >= 1 )then this%leafc_loss_patch(p) = & this%leafc_loss_patch(p) + & this%hrv_leafc_to_prod1c_patch(p) @@ -1920,7 +1920,7 @@ subroutine Summary(this, bounds, num_soilc, filter_soilc, num_soilp, filter_soil this%hrv_deadcrootc_storage_to_litter_patch(p) + & this%hrv_deadcrootc_xfer_to_litter_patch(p) ! putting the harvested crop stem and grain in the wood loss bdrewniak - if ( crop_prog .and. veg_pp%itype(p) >= npcropmin )then + if ( crop_prog .and. iscft(veg_pp%itype(p)) >= 1 )then this%woodc_loss_patch(p) = & this%woodc_loss_patch(p) + & this%hrv_grainc_to_prod1c_patch(p) + & @@ -2592,7 +2592,7 @@ subroutine summary_cflux_for_ch4( this, bounds, num_soilp, filter_soilp, num_soi this%cpool_to_deadstemc_patch(p) + & this%deadstemc_xfer_to_deadstemc_patch(p) - if ( crop_prog .and. veg_pp%itype(p) >= npcropmin )then + if ( crop_prog .and. iscft(veg_pp%itype(p)) >= 1 )then this%agnpp_patch(p) = & this%agnpp_patch(p) + & this%cpool_to_grainc_patch(p) + & diff --git a/components/elm/src/biogeochem/CNCarbonStateType.F90 b/components/elm/src/biogeochem/CNCarbonStateType.F90 index 8f258bbb6a9a..46440bee2355 100644 --- a/components/elm/src/biogeochem/CNCarbonStateType.F90 +++ b/components/elm/src/biogeochem/CNCarbonStateType.F90 @@ -12,7 +12,7 @@ module CNCarbonStateType use elm_varctl , only : iulog, use_vertsoilc, spinup_state use decompMod , only : bounds_type use CNStateType , only : cnstate_type - use pftvarcon , only : npcropmin + use pftvarcon , only : iscft use CNDecompCascadeConType , only : decomp_cascade_con use VegetationPropertiesType , only : veg_vp use abortutils , only : endrun @@ -400,7 +400,7 @@ subroutine InitCold(this, bounds, ratio, c12_carbonstate_vars) ! ! !USES: use landunit_varcon , only: istsoil - use pftvarcon , only: noveg, npcropmin + use pftvarcon , only: noveg ! ! !ARGUMENTS: class(carbonstate_type) :: this @@ -459,7 +459,7 @@ subroutine InitCold(this, bounds, ratio, c12_carbonstate_vars) if (veg_vp%evergreen(veg_pp%itype(p)) == 1._r8) then this%leafc_patch(p) = 1._r8 * ratio this%leafc_storage_patch(p) = 0._r8 - else if (veg_pp%itype(p) >= npcropmin) then ! prognostic crop types + else if (iscft(veg_pp%itype(p)) >= 1) then ! prognostic crop types this%leafc_patch(p) = 0._r8 this%leafc_storage_patch(p) = 0._r8 else @@ -866,7 +866,7 @@ subroutine Summary(this, bounds, num_soilc, filter_soilc, num_soilp, filter_soil this%gresp_storage_patch(p) + & this%gresp_xfer_patch(p) - if ( crop_prog .and. veg_pp%itype(p) >= npcropmin )then + if ( crop_prog .and. iscft(veg_pp%itype(p)) >= 1 )then this%storvegc_patch(p) = & this%storvegc_patch(p) + & this%grainc_storage_patch(p) + & diff --git a/components/elm/src/biogeochem/CNGapMortalityBeTRMod.F90 b/components/elm/src/biogeochem/CNGapMortalityBeTRMod.F90 index e3965d6eea3a..370e82ab7ff5 100644 --- a/components/elm/src/biogeochem/CNGapMortalityBeTRMod.F90 +++ b/components/elm/src/biogeochem/CNGapMortalityBeTRMod.F90 @@ -91,7 +91,7 @@ subroutine CNGapMortality (& ! !USES: use elm_time_manager , only: get_days_per_year use elm_varcon , only: secspday - use pftvarcon , only: npcropmin + use pftvarcon , only: iscft use elm_varctl , only: spinup_state, spinup_mortality_factor ! ! !ARGUMENTS: @@ -188,7 +188,7 @@ subroutine CNGapMortality (& * gap_indicator(gid_m_deadcrootn_to_litter) - if (ivt(p) < npcropmin) then + if (iscft(veg_pp%itype(p)) < 1) then veg_nf%m_retransn_to_litter(p) = veg_ns%retransn(p) * m & * gap_indicator(gid_m_retransn_to_litter) end if @@ -239,7 +239,7 @@ subroutine CNGapMortality (& veg_pf%m_deadstemp_to_litter(p) = veg_ps%deadstemp(p) * m veg_pf%m_livecrootp_to_litter(p) = veg_ps%livecrootp(p) * m veg_pf%m_deadcrootp_to_litter(p) = veg_ps%deadcrootp(p) * m - if (ivt(p) < npcropmin) then + if (iscft(veg_pp%itype(p)) < 1) then veg_pf%m_retransp_to_litter(p) = veg_ps%retransp(p) * m end if diff --git a/components/elm/src/biogeochem/CNNStateUpdate1BeTRMod.F90 b/components/elm/src/biogeochem/CNNStateUpdate1BeTRMod.F90 index 4c7fd83d2108..f2a431e7283c 100644 --- a/components/elm/src/biogeochem/CNNStateUpdate1BeTRMod.F90 +++ b/components/elm/src/biogeochem/CNNStateUpdate1BeTRMod.F90 @@ -10,7 +10,7 @@ module CNNStateUpdate1BeTRMod use elm_varpar , only : crop_prog, i_met_lit, i_cel_lit, i_lig_lit, i_cwd use elm_varctl , only : iulog use elm_varcon , only : nitrif_n2o_loss_frac - use pftvarcon , only : crop, generic_crop + use pftvarcon , only : iscft use VegetationPropertiesType , only : veg_vp use CNDecompCascadeConType , only : decomp_cascade_con use CNStateType , only : cnstate_type @@ -101,7 +101,7 @@ subroutine NStateUpdate1(num_soilc, filter_soilc, num_soilp, filter_soilp, & veg_ns%deadcrootn_xfer(p) = veg_ns%deadcrootn_xfer(p) - veg_nf%deadcrootn_xfer_to_deadcrootn(p)*dt end if - if (crop(ivt(p)) >= 1 .and. generic_crop(ivt(p)) < 1) then ! skip 2 generic crops + if (iscft(ivt(p)) >= 1) then ! skip 2 generic crops ! lines here for consistency; the transfer terms are zero veg_ns%livestemn(p) = veg_ns%livestemn(p) + veg_nf%livestemn_xfer_to_livestemn(p)*dt veg_ns%livestemn_xfer(p) = veg_ns%livestemn_xfer(p) - veg_nf%livestemn_xfer_to_livestemn(p)*dt @@ -126,7 +126,7 @@ subroutine NStateUpdate1(num_soilc, filter_soilc, num_soilp, filter_soilp, & veg_ns%livecrootn(p) = veg_ns%livecrootn(p) - veg_nf%livecrootn_to_retransn(p)*dt veg_ns%retransn(p) = veg_ns%retransn(p) + veg_nf%livecrootn_to_retransn(p)*dt end if - if (crop(ivt(p)) >= 1 .and. generic_crop(ivt(p)) < 1) then ! Beth adds retrans from froot + if (iscft(ivt(p)) >= 1) then ! Beth adds retrans from froot veg_ns%frootn(p) = veg_ns%frootn(p) - veg_nf%frootn_to_retransn(p)*dt veg_ns%retransn(p) = veg_ns%retransn(p) + veg_nf%frootn_to_retransn(p)*dt veg_ns%livestemn(p) = veg_ns%livestemn(p) - veg_nf%livestemn_to_litter(p)*dt @@ -172,7 +172,7 @@ subroutine NStateUpdate1(num_soilc, filter_soilc, num_soilp, filter_soilp, & veg_ns%deadcrootn_storage(p) = veg_ns%deadcrootn_storage(p) + veg_nf%npool_to_deadcrootn_storage(p)*dt end if - if (crop(ivt(p)) >= 1 .and. generic_crop(ivt(p)) < 1) then ! skip 2 generic crops + if (iscft(ivt(p)) >= 1) then ! skip 2 generic crops veg_ns%npool(p) = veg_ns%npool(p) - veg_nf%npool_to_livestemn(p)*dt veg_ns%livestemn(p) = veg_ns%livestemn(p) + veg_nf%npool_to_livestemn(p)*dt veg_ns%npool(p) = veg_ns%npool(p) - veg_nf%npool_to_livestemn_storage(p)*dt @@ -200,7 +200,7 @@ subroutine NStateUpdate1(num_soilc, filter_soilc, num_soilp, filter_soilp, & veg_ns%deadcrootn_xfer(p) = veg_ns%deadcrootn_xfer(p) + veg_nf%deadcrootn_storage_to_xfer(p)*dt end if - if (crop(ivt(p)) >= 1 .and. generic_crop(ivt(p)) < 1) then ! skip 2 generic crops + if (iscft(ivt(p)) >= 1) then ! skip 2 generic crops ! lines here for consistency; the transfer terms are zero veg_ns%livestemn_storage(p) = veg_ns%livestemn_storage(p) - veg_nf%livestemn_storage_to_xfer(p)*dt veg_ns%livestemn_xfer(p) = veg_ns%livestemn_xfer(p) + veg_nf%livestemn_storage_to_xfer(p)*dt diff --git a/components/elm/src/biogeochem/CNNStateUpdate2BeTRMod.F90 b/components/elm/src/biogeochem/CNNStateUpdate2BeTRMod.F90 index 60100b657aef..fbfa6110d77f 100644 --- a/components/elm/src/biogeochem/CNNStateUpdate2BeTRMod.F90 +++ b/components/elm/src/biogeochem/CNNStateUpdate2BeTRMod.F90 @@ -14,7 +14,7 @@ module CNNStateUpdate2BeTRMod use CNNitrogenFLuxType , only : nitrogenflux_type use VegetationType , only : veg_pp use VegetationDataType , only : veg_ns, veg_nf - use pftvarcon , only : npcropmin + use pftvarcon , only : iscft !! bgc interface & pflotran: use elm_varctl , only : use_pflotran, pf_cmode ! @@ -147,7 +147,7 @@ subroutine NStateUpdate2h(num_soilc, filter_soilc, num_soilp, filter_soilp, & veg_ns%deadcrootn(p) = veg_ns%deadcrootn(p) - veg_nf%hrv_deadcrootn_to_litter(p) * dt veg_ns%retransn(p) = veg_ns%retransn(p) - veg_nf%hrv_retransn_to_litter(p) * dt - if (ivt(p) >= npcropmin) then ! skip 2 generic crops + if (iscft(ivt(p)) >=1) then ! skip 2 generic crops veg_ns%livestemn(p)= veg_ns%livestemn(p) - veg_nf%hrv_livestemn_to_prod1n(p) * dt veg_ns%leafn(p) = veg_ns%leafn(p) - veg_nf%hrv_leafn_to_prod1n(p) * dt veg_ns%grainn(p) = veg_ns%grainn(p) - veg_nf%hrv_grainn_to_prod1n(p) * dt diff --git a/components/elm/src/biogeochem/CNNitrogenFluxType.F90 b/components/elm/src/biogeochem/CNNitrogenFluxType.F90 index d0b76c195afa..b6f02ce91f82 100644 --- a/components/elm/src/biogeochem/CNNitrogenFluxType.F90 +++ b/components/elm/src/biogeochem/CNNitrogenFluxType.F90 @@ -1078,7 +1078,7 @@ subroutine Summary(this, bounds, num_soilc, filter_soilc, num_soilp, filter_soil ! !USES: use elm_varpar , only: nlevdecomp,ndecomp_cascade_transitions,ndecomp_pools use subgridAveMod , only: p2c - use pftvarcon , only : npcropmin + use pftvarcon , only : iscft use tracer_varcon , only: is_active_betr_bgc use elm_varpar , only: nlevdecomp_full ! diff --git a/components/elm/src/biogeochem/CNNitrogenStateType.F90 b/components/elm/src/biogeochem/CNNitrogenStateType.F90 index dda6477899a7..041c757ae598 100644 --- a/components/elm/src/biogeochem/CNNitrogenStateType.F90 +++ b/components/elm/src/biogeochem/CNNitrogenStateType.F90 @@ -12,7 +12,7 @@ module CNNitrogenStateType use elm_varctl , only : use_vertsoilc, use_century_decomp, use_fan use elm_varctl , only : iulog, override_bgc_restart_mismatch_dump, spinup_state use decompMod , only : bounds_type - use pftvarcon , only : npcropmin, nstor + use pftvarcon , only : iscft, nstor use CNDecompCascadeConType , only : decomp_cascade_con use VegetationPropertiesType , only : veg_vp use abortutils , only : endrun @@ -502,7 +502,7 @@ subroutine InitCold(this, bounds, & ! !USES: use elm_varpar , only : crop_prog use decompMod , only : bounds_type - use pftvarcon , only : noveg, npcropmin + use pftvarcon , only : noveg, iscft ! ! !ARGUMENTS: class(nitrogenstate_type) :: this @@ -1007,7 +1007,7 @@ subroutine Summary(this, bounds, num_soilc, filter_soilc, num_soilp, filter_soil this%npool_patch(p) + & this%retransn_patch(p) - if ( crop_prog .and. veg_pp%itype(p) >= npcropmin )then + if ( crop_prog .and. iscft(veg_pp%itype(p)) >= 1 )then this%dispvegn_patch(p) = & this%dispvegn_patch(p) + & this%grainn_patch(p) diff --git a/components/elm/src/biogeochem/CNPhenologyBeTRMod.F90 b/components/elm/src/biogeochem/CNPhenologyBeTRMod.F90 index 23f461ad3055..aaeb58d9ee91 100644 --- a/components/elm/src/biogeochem/CNPhenologyBeTRMod.F90 +++ b/components/elm/src/biogeochem/CNPhenologyBeTRMod.F90 @@ -1868,7 +1868,8 @@ subroutine CropPhenologyInit(bounds) ! initialized, and after ecophyscon file is read in. ! ! !USES: - use pftvarcon , only: npcropmin, npcropmax, mnNHplantdate + use elm_varpar , only : mxpft + use pftvarcon , only: iscft, crop, mnNHplantdate use pftvarcon , only: mnSHplantdate, mxNHplantdate use pftvarcon , only: mxSHplantdate use elm_time_manager, only: get_calday @@ -1893,13 +1894,17 @@ subroutine CropPhenologyInit(bounds) ! Convert planting dates into julian day minplantjday(:,:) = huge(1) maxplantjday(:,:) = huge(1) - do n = npcropmin, npcropmax + do n = 0, mxpft + if (iscft(n)>=1) then minplantjday(n,inNH) = int( get_calday( mnNHplantdate(n), 0 ) ) maxplantjday(n,inNH) = int( get_calday( mxNHplantdate(n), 0 ) ) + end if end do - do n = npcropmin, npcropmax + do n = 0, mxpft + if (iscft(n)>=1) then minplantjday(n,inSH) = int( get_calday( mnSHplantdate(n), 0 ) ) maxplantjday(n,inSH) = int( get_calday( mxSHplantdate(n), 0 ) ) + end if end do ! Figure out what hemisphere each PFT is in diff --git a/components/elm/src/biogeochem/CarbonStateUpdate1Mod.F90 b/components/elm/src/biogeochem/CarbonStateUpdate1Mod.F90 index 25455dbbb20e..7513662f4670 100644 --- a/components/elm/src/biogeochem/CarbonStateUpdate1Mod.F90 +++ b/components/elm/src/biogeochem/CarbonStateUpdate1Mod.F90 @@ -11,7 +11,7 @@ module CarbonStateUpdate1Mod use elm_varcon , only : dzsoi_decomp use elm_varctl , only : nu_com, use_c13, use_c14 use elm_varctl , only : use_pflotran, pf_cmode, use_fates - use pftvarcon , only : crop, generic_crop, percrop + use pftvarcon , only : iscft use CNDecompCascadeConType , only : decomp_cascade_type use CNStateType , only : cnstate_type use CNDecompCascadeConType , only : decomp_cascade_con @@ -284,8 +284,7 @@ subroutine CarbonStateUpdate1(bounds, & veg_cs%deadcrootc(p) = veg_cs%deadcrootc(p) + veg_cf%deadcrootc_xfer_to_deadcrootc(p)*dt veg_cs%deadcrootc_xfer(p) = veg_cs%deadcrootc_xfer(p) - veg_cf%deadcrootc_xfer_to_deadcrootc(p)*dt end if - if ( (crop(ivt(p)) >= 1 .or. percrop(ivt(p)) >= 1) .and. & - generic_crop(ivt(p)) == 0 ) then ! skip 2 generic crops + if (iscft(ivt(p)) >= 1) then ! skip 2 generic crops ! lines here for consistency; the transfer terms are zero veg_cs%livestemc(p) = veg_cs%livestemc(p) + veg_cf%livestemc_xfer_to_livestemc(p)*dt veg_cs%livestemc_xfer(p) = veg_cs%livestemc_xfer(p) - veg_cf%livestemc_xfer_to_livestemc(p)*dt @@ -304,8 +303,7 @@ subroutine CarbonStateUpdate1(bounds, & veg_cs%livecrootc(p) = veg_cs%livecrootc(p) - veg_cf%livecrootc_to_deadcrootc(p)*dt veg_cs%deadcrootc(p) = veg_cs%deadcrootc(p) + veg_cf%livecrootc_to_deadcrootc(p)*dt end if - if ( (crop(ivt(p)) >= 1 .or. percrop(ivt(p)) >= 1) .and. & - generic_crop(ivt(p)) == 0 ) then ! skip 2 generic crops + if (iscft(ivt(p)) >= 1) then ! skip 2 generic crops veg_cs%livestemc(p) = veg_cs%livestemc(p) - veg_cf%livestemc_to_litter(p)*dt veg_cs%grainc(p) = veg_cs%grainc(p) - veg_cf%grainc_to_food(p)*dt @@ -321,8 +319,7 @@ subroutine CarbonStateUpdate1(bounds, & veg_cs%cpool(p) = veg_cs%cpool(p) - veg_cf%livestem_curmr(p)*dt veg_cs%cpool(p) = veg_cs%cpool(p) - veg_cf%livecroot_curmr(p)*dt end if - if ( (crop(ivt(p)) >= 1 .or. percrop(ivt(p)) >= 1) .and. & - generic_crop(ivt(p)) == 0 ) then ! skip 2 generic crops + if (iscft(ivt(p)) >= 1) then ! skip 2 generic crops veg_cs%cpool(p) = veg_cs%cpool(p) - veg_cf%livestem_curmr(p)*dt veg_cs%cpool(p) = veg_cs%cpool(p) - veg_cf%grain_curmr(p)*dt end if @@ -340,8 +337,7 @@ subroutine CarbonStateUpdate1(bounds, & veg_cs%xsmrpool(p) = veg_cs%xsmrpool(p) - veg_cf%livestem_xsmr(p)*dt veg_cs%xsmrpool(p) = veg_cs%xsmrpool(p) - veg_cf%livecroot_xsmr(p)*dt end if - if ( (crop(ivt(p)) >= 1 .or. percrop(ivt(p)) >= 1) .and. & - generic_crop(ivt(p)) == 0 ) then ! skip 2 generic crops + if (iscft(ivt(p)) >= 1) then ! skip 2 generic crops veg_cs%xsmrpool(p) = veg_cs%xsmrpool(p) - veg_cf%livestem_xsmr(p)*dt veg_cs%xsmrpool(p) = veg_cs%xsmrpool(p) - veg_cf%grain_xsmr(p)*dt if (harvdate(p) < 999) then ! beginning at harvest, send to atm @@ -377,8 +373,7 @@ subroutine CarbonStateUpdate1(bounds, & veg_cs%cpool(p) = veg_cs%cpool(p) - veg_cf%cpool_to_deadcrootc_storage(p)*dt veg_cs%deadcrootc_storage(p) = veg_cs%deadcrootc_storage(p) + veg_cf%cpool_to_deadcrootc_storage(p)*dt end if - if ( (crop(ivt(p)) >= 1 .or. percrop(ivt(p)) >= 1) .and. & - generic_crop(ivt(p)) == 0 ) then ! skip 2 generic crops + if ( iscft(ivt(p)) >= 1 ) then ! skip 2 generic crops veg_cs%cpool(p) = veg_cs%cpool(p) - veg_cf%cpool_to_livestemc(p)*dt veg_cs%livestemc(p) = veg_cs%livestemc(p) + veg_cf%cpool_to_livestemc(p)*dt veg_cs%cpool(p) = veg_cs%cpool(p) - veg_cf%cpool_to_livestemc_storage(p)*dt @@ -398,8 +393,7 @@ subroutine CarbonStateUpdate1(bounds, & veg_cs%cpool(p) = veg_cs%cpool(p) - veg_cf%cpool_livecroot_gr(p)*dt veg_cs%cpool(p) = veg_cs%cpool(p) - veg_cf%cpool_deadcroot_gr(p)*dt end if - if ( (crop(ivt(p)) >= 1 .or. percrop(ivt(p)) >= 1) .and. & - generic_crop(ivt(p)) == 0 ) then ! skip 2 generic crops + if (iscft(ivt(p)) >= 1) then ! skip 2 generic crops veg_cs%cpool(p) = veg_cs%cpool(p) - veg_cf%cpool_livestem_gr(p)*dt veg_cs%cpool(p) = veg_cs%cpool(p) - veg_cf%cpool_grain_gr(p)*dt end if @@ -413,8 +407,7 @@ subroutine CarbonStateUpdate1(bounds, & veg_cs%gresp_xfer(p) = veg_cs%gresp_xfer(p) - veg_cf%transfer_livecroot_gr(p)*dt veg_cs%gresp_xfer(p) = veg_cs%gresp_xfer(p) - veg_cf%transfer_deadcroot_gr(p)*dt end if - if ( (crop(ivt(p)) >= 1 .or. percrop(ivt(p)) >= 1) .and. & - generic_crop(ivt(p)) == 0 ) then ! skip 2 generic crops + if (iscft(ivt(p)) >= 1) then ! skip 2 generic crops veg_cs%gresp_xfer(p) = veg_cs%gresp_xfer(p) - veg_cf%transfer_livestem_gr(p)*dt veg_cs%gresp_xfer(p) = veg_cs%gresp_xfer(p) - veg_cf%transfer_grain_gr(p)*dt end if @@ -428,8 +421,7 @@ subroutine CarbonStateUpdate1(bounds, & veg_cs%cpool(p) = veg_cs%cpool(p) - veg_cf%cpool_livecroot_storage_gr(p)*dt veg_cs%cpool(p) = veg_cs%cpool(p) - veg_cf%cpool_deadcroot_storage_gr(p)*dt end if - if ( (crop(ivt(p)) >= 1 .or. percrop(ivt(p)) >= 1) .and. & - generic_crop(ivt(p)) == 0 ) then ! skip 2 generic crops + if ( iscft(ivt(p)) >= 1 ) then ! skip 2 generic crops veg_cs%cpool(p) = veg_cs%cpool(p) - veg_cf%cpool_livestem_storage_gr(p)*dt veg_cs%cpool(p) = veg_cs%cpool(p) - veg_cf%cpool_grain_storage_gr(p)*dt end if @@ -455,8 +447,7 @@ subroutine CarbonStateUpdate1(bounds, & veg_cs%gresp_storage(p) = veg_cs%gresp_storage(p) - veg_cf%gresp_storage_to_xfer(p)*dt veg_cs%gresp_xfer(p) = veg_cs%gresp_xfer(p) + veg_cf%gresp_storage_to_xfer(p)*dt end if - if ( (crop(ivt(p)) >= 1 .or. percrop(ivt(p)) >= 1) .and. & - generic_crop(ivt(p)) == 0 ) then ! skip 2 generic crops + if ( iscft(ivt(p)) >= 1 ) then ! skip 2 generic crops ! lines here for consistency; the transfer terms are zero veg_cs%livestemc_storage(p) = veg_cs%livestemc_storage(p) - veg_cf%livestemc_storage_to_xfer(p)*dt veg_cs%livestemc_xfer(p) = veg_cs%livestemc_xfer(p) + veg_cf%livestemc_storage_to_xfer(p)*dt diff --git a/components/elm/src/biogeochem/CarbonStateUpdate2Mod.F90 b/components/elm/src/biogeochem/CarbonStateUpdate2Mod.F90 index 48174fb8ddfc..985c544d29ff 100644 --- a/components/elm/src/biogeochem/CarbonStateUpdate2Mod.F90 +++ b/components/elm/src/biogeochem/CarbonStateUpdate2Mod.F90 @@ -9,7 +9,7 @@ module CarbonStateUpdate2Mod use shr_log_mod , only : errMsg => shr_log_errMsg use abortutils , only : endrun use elm_varpar , only : nlevdecomp, i_met_lit, i_cel_lit, i_lig_lit, i_cwd - use pftvarcon , only : npcropmin + use pftvarcon , only : iscft use elm_varctl , only : use_pflotran, pf_cmode use VegetationType , only : veg_pp use tracer_varcon , only : is_active_betr_bgc @@ -186,7 +186,7 @@ subroutine CarbonStateUpdate2h(num_soilc, filter_soilc, num_soilp, filter_soilp, veg_cs%deadcrootc(p) = veg_cs%deadcrootc(p) - veg_cf%hrv_deadcrootc_to_litter(p) * dt ! crops - if (ivt(p) >= npcropmin) then ! skip 2 generic crops + if (iscft(ivt(p)) >= 1) then ! skip 2 generic crops veg_cs%livestemc(p) = veg_cs%livestemc(p) - veg_cf%hrv_livestemc_to_prod1c(p) *dt veg_cs%leafc(p) = veg_cs%leafc(p) - veg_cf%hrv_leafc_to_prod1c(p) *dt veg_cs%grainc(p) = veg_cs%grainc(p) - veg_cf%hrv_grainc_to_prod1c(p) *dt diff --git a/components/elm/src/biogeochem/CropType.F90 b/components/elm/src/biogeochem/CropType.F90 index bc3d8c44ff41..58f7757e5fcb 100644 --- a/components/elm/src/biogeochem/CropType.F90 +++ b/components/elm/src/biogeochem/CropType.F90 @@ -417,7 +417,7 @@ subroutine Restart(this, bounds, ncid, flag) use restUtilMod use ncdio_pio use VegetationType , only : veg_pp - use pftvarcon , only : npcropmin, npcropmax + use pftvarcon , only : iscft ! ! !ARGUMENTS: class(crop_type), intent(inout) :: this @@ -454,7 +454,7 @@ subroutine Restart(this, bounds, ncid, flag) interpinic_flag='copy', readvar=readvar, data=restyear) if (readvar) then do p = bounds%begp, bounds%endp - if (veg_pp%itype(p) >= npcropmin .and. veg_pp%itype(p) <= npcropmax .and. & + if (iscft(veg_pp%itype(p)) >= 1 .and. & veg_pp%active(p)) then this%nyrs_crop_active_patch(p) = restyear end if diff --git a/components/elm/src/biogeochem/DryDepVelocity.F90 b/components/elm/src/biogeochem/DryDepVelocity.F90 index 293713da54a7..a79792b4e858 100644 --- a/components/elm/src/biogeochem/DryDepVelocity.F90 +++ b/components/elm/src/biogeochem/DryDepVelocity.F90 @@ -146,7 +146,7 @@ subroutine depvel_compute( bounds, & use landunit_varcon, only : istsoil, istice, istice_mec, istdlak, istwet use elm_varctl , only : iulog use pftvarcon , only : noveg, nonvascular - use pftvarcon , only : woody, graminoid, generic_crop, crop, percrop + use pftvarcon , only : woody, graminoid, iscft, crop use pftvarcon , only : needleleaf ! ! !ARGUMENTS: @@ -293,10 +293,8 @@ subroutine depvel_compute( bounds, & if (nonvascular(elmveg) == 1.0_r8 ) wesveg = 3 ! assuming moss like grass !if (elmveg == nc3crop ) wesveg = 2 !if (elmveg == nc3irrig ) wesveg = 2 - if (generic_crop(elmveg) == 1.0_r8 ) wesveg = 2 - if (crop(elmveg) == 1.0_r8 ) wesveg = 2 - if (percrop(elmveg) == 1.0_r8 ) wesveg = 2 !if (elmveg >= npcropmin .and. elmveg <= npcropmax ) wesveg = 2 + if (crop(elmveg) == 1.0_r8 .or. iscft(elmveg) == 1.0_r8 ) wesveg = 2 #ifndef _OPENACC if (wesveg == wveg_unset )then write(iulog,*) 'elmveg = ', elmveg, 'lun_pp%itype = ', lun_pp%itype(l) diff --git a/components/elm/src/biogeochem/FireMod.F90 b/components/elm/src/biogeochem/FireMod.F90 index 24e34e37c555..7aa4e6a50f9e 100644 --- a/components/elm/src/biogeochem/FireMod.F90 +++ b/components/elm/src/biogeochem/FireMod.F90 @@ -126,7 +126,7 @@ subroutine FireArea (bounds, & use elm_varcon , only: secspday, spval use elm_varctl , only: use_nofire, spinup_state, spinup_mortality_factor use dynSubgridControlMod , only: run_has_transient_landcover - use pftvarcon , only: noveg, woody, graminoid, generic_crop, crop, percrop + use pftvarcon , only: noveg, woody, graminoid, iscft, crop use pftvarcon , only: climatezone, needleleaf, evergreen ! ! !ARGUMENTS: @@ -305,16 +305,12 @@ subroutine FireArea (bounds, & if (pi <= col_pp%npfts(c)) then p = col_pp%pfti(c) + pi - 1 ! For crop veg types - if( generic_crop(veg_pp%itype(p)) == 1 .or. & - crop(veg_pp%itype(p)) == 1 .or. & - percrop(veg_pp%itype(p)) == 1 )then + if( crop(veg_pp%itype(p)) == 1 .or. iscft(veg_pp%itype(p)) == 1 )then cropf_col(c) = cropf_col(c) + veg_pp%wtcol(p) end if ! For natural vegetation (non-crop and non-bare-soil) if( veg_pp%itype(p) /= noveg .and. & - (generic_crop(veg_pp%itype(p)) == 0 .and. & - crop(veg_pp%itype(p)) == 0 .and. & - percrop(veg_pp%itype(p)) == 0) )then + (crop(veg_pp%itype(p)) == 0 .and. iscft(veg_pp%itype(p)) == 0) )then lfwt(c) = lfwt(c) + veg_pp%wtcol(p) end if end if @@ -336,9 +332,7 @@ subroutine FireArea (bounds, & ! column-level litter carbon ! is available, so we use leaf carbon to estimate the ! litter carbon for crop PFTs - if( (generic_crop(veg_pp%itype(p)) == 1 .or. & - crop(veg_pp%itype(p)) == 1 .or. & - percrop(veg_pp%itype(p)) == 1) .and. & + if( (crop(veg_pp%itype(p)) == 1 .or. iscft(veg_pp%itype(p)) == 1) .and. & veg_pp%wtcol(p) > 0._r8 .and. leafc_col(c) > 0._r8 )then fuelc_crop(c)=fuelc_crop(c) + (leafc(p) + leafc_storage(p) + & leafc_xfer(p))*veg_pp%wtcol(p)/cropf_col(c) + & @@ -376,9 +370,7 @@ subroutine FireArea (bounds, & p = col_pp%pfti(c) + pi - 1 ! For non-crop -- natural vegetation and bare-soil - if( (generic_crop(veg_pp%itype(p)) == 0 .and. & - crop(veg_pp%itype(p)) == 0 .and. & - percrop(veg_pp%itype(p)) == 0) .and. & + if( (crop(veg_pp%itype(p)) == 0 .and. iscft(veg_pp%itype(p)) == 0) .and. & cropf_col(c) < 1.0_r8 ) then if( btran2(p) .ne. spval) then if (btran2(p) <= 1._r8 ) then @@ -517,9 +509,7 @@ subroutine FireArea (bounds, & p = col_pp%pfti(c) + pi - 1 ! For crop if( forc_t(t) >= SHR_CONST_TKFRZ .and. & - (generic_crop(veg_pp%itype(p))>=1 .or. & - crop(veg_pp%itype(p))>=1 .or. & - percrop(veg_pp%itype(p))>=1) .and. & + (crop(veg_pp%itype(p)) == 1 .or. iscft(veg_pp%itype(p)) == 1) .and. & kmo == abm_lf(c) .and. forc_rain(t)+forc_snow(t) == 0._r8 .and. & burndate(p) >= 999 .and. veg_pp%wtcol(p) > 0._r8 )then ! catch crop burn time @@ -690,7 +680,7 @@ subroutine FireFluxes (num_soilc, filter_soilc, num_soilp, filter_soilp, & !$acc routine seq use pftvarcon , only: cc_leaf,cc_lstem,cc_dstem,cc_other,fm_leaf,fm_lstem,fm_other,fm_root,fm_lroot,fm_droot use pftvarcon , only: lf_flab,lf_fcel,lf_flig,fr_flab,fr_fcel,fr_flig - use pftvarcon , only: generic_crop, crop, percrop + use pftvarcon , only: iscft, crop use elm_varpar , only: max_patch_per_col use elm_varctl , only: spinup_state, spinup_mortality_factor use dynSubgridControlMod , only: get_flanduse_timeseries @@ -992,8 +982,7 @@ subroutine FireFluxes (num_soilc, filter_soilc, num_soilp, filter_soilp, & c = veg_pp%column(p) itype = veg_pp%itype(p) - if( (generic_crop(veg_pp%itype(p)) == 0 .and. crop(veg_pp%itype(p)) == 0 .and. & - percrop(veg_pp%itype(p)) == 0 ) .and. & + if( (crop(veg_pp%itype(p)) == 0 .and. iscft(veg_pp%itype(p)) == 0) .and. & cropf_col(c) < 1.0_r8)then ! For non-crop (bare-soil and natural vegetation) if (transient_landcover) then !true when landuse data is used diff --git a/components/elm/src/biogeochem/GapMortalityMod.F90 b/components/elm/src/biogeochem/GapMortalityMod.F90 index 3257a6365b65..734be187805f 100644 --- a/components/elm/src/biogeochem/GapMortalityMod.F90 +++ b/components/elm/src/biogeochem/GapMortalityMod.F90 @@ -87,7 +87,7 @@ subroutine GapMortality (num_soilc, filter_soilc, num_soilp, filter_soilp, & ! !USES: !$acc routine seq use elm_varcon , only: secspday - use pftvarcon , only: npcropmin + use pftvarcon , only: iscft use elm_varctl , only: spinup_state, spinup_mortality_factor ! ! !ARGUMENTS: @@ -142,7 +142,7 @@ subroutine GapMortality (num_soilc, filter_soilc, num_soilp, filter_soilp, & ! displayed pools veg_cf%m_leafc_to_litter(p) = 0._r8 veg_cf%m_livestemc_to_litter(p) = 0._r8 - if(ivt(p) < npcropmin .or. (ivt(p) >= npcropmin .and. croplive(p))) then + if(iscft(ivt(p)) < 1 .or. (iscft(ivt(p)) >= 1 .and. croplive(p))) then veg_cf%m_leafc_to_litter(p) = veg_cs%leafc(p) * m veg_cf%m_livestemc_to_litter(p) = veg_cs%livestemc(p) * m end if @@ -181,7 +181,7 @@ subroutine GapMortality (num_soilc, filter_soilc, num_soilp, filter_soilp, & ! displayed pools veg_nf%m_leafn_to_litter(p) = 0._r8 veg_nf%m_livestemn_to_litter(p) = 0._r8 - if(ivt(p) < npcropmin .or. (ivt(p) >= npcropmin .and. croplive(p))) then + if(iscft(ivt(p)) < 1 .or. (iscft(ivt(p)) >= 1 .and. croplive(p))) then veg_nf%m_leafn_to_litter(p) = veg_ns%leafn(p) * m veg_nf%m_livestemn_to_litter(p) = veg_ns%livestemn(p) * m end if @@ -190,7 +190,7 @@ subroutine GapMortality (num_soilc, filter_soilc, num_soilp, filter_soilp, & veg_nf%m_livecrootn_to_litter(p) = veg_ns%livecrootn(p) * m veg_nf%m_deadcrootn_to_litter(p) = veg_ns%deadcrootn(p) * m veg_nf%m_retransn_to_litter(p) = 0._r8 - if (ivt(p) < npcropmin) then + if (iscft(ivt(p)) < 1) then veg_nf%m_retransn_to_litter(p) = veg_ns%retransn(p) * m end if veg_nf%m_npool_to_litter(p) = veg_ns%npool(p) * m @@ -225,7 +225,7 @@ subroutine GapMortality (num_soilc, filter_soilc, num_soilp, filter_soilp, & ! displayed pools veg_pf%m_leafp_to_litter(p) = 0._r8 veg_pf%m_livestemp_to_litter(p) = 0._r8 - if(ivt(p) < npcropmin .or. (ivt(p) >= npcropmin .and. croplive(p))) then + if(iscft(ivt(p)) < 1 .or. (iscft(ivt(p)) >= 1 .and. croplive(p))) then veg_pf%m_leafp_to_litter(p) = veg_ps%leafp(p) * m veg_pf%m_livestemp_to_litter(p) = veg_ps%livestemp(p) * m endif @@ -235,7 +235,7 @@ subroutine GapMortality (num_soilc, filter_soilc, num_soilp, filter_soilp, & veg_pf%m_deadcrootp_to_litter(p) = veg_ps%deadcrootp(p) * m veg_pf%m_retransp_to_litter(p) = 0._r8 - if (ivt(p) < npcropmin) then + if (iscft(ivt(p)) < 1) then veg_pf%m_retransp_to_litter(p) = veg_ps%retransp(p) * m end if veg_pf%m_ppool_to_litter(p) = veg_ps%ppool(p) * m diff --git a/components/elm/src/biogeochem/GrowthRespMod.F90 b/components/elm/src/biogeochem/GrowthRespMod.F90 index a5002d108e51..34a9a64c56c9 100644 --- a/components/elm/src/biogeochem/GrowthRespMod.F90 +++ b/components/elm/src/biogeochem/GrowthRespMod.F90 @@ -7,7 +7,7 @@ module GrowthRespMod ! ! !USES: use shr_kind_mod , only : r8 => shr_kind_r8 - use pftvarcon , only : grperc, grpnow, npcropmin + use pftvarcon , only : grperc, grpnow, iscft use VegetationPropertiesType , only : veg_vp use VegetationType , only : veg_pp use VegetationDataType , only : veg_cf @@ -102,7 +102,7 @@ subroutine GrowthResp(num_soilp, filter_soilp) do fp = 1,num_soilp p = filter_soilp(fp) - if (ivt(p) >= npcropmin) then ! skip 2 generic crops + if (iscft(ivt(p)) >= 1) then ! skip 2 generic crops cpool_livestem_gr(p) = cpool_to_livestemc(p) * grperc(ivt(p)) diff --git a/components/elm/src/biogeochem/MaintenanceRespMod.F90 b/components/elm/src/biogeochem/MaintenanceRespMod.F90 index eab60926ab60..48d179f97d1f 100644 --- a/components/elm/src/biogeochem/MaintenanceRespMod.F90 +++ b/components/elm/src/biogeochem/MaintenanceRespMod.F90 @@ -12,7 +12,7 @@ module MaintenanceRespMod use decompMod , only : bounds_type use abortutils , only : endrun use shr_log_mod , only : errMsg => shr_log_errMsg - use pftvarcon , only : npcropmin + use pftvarcon , only : iscft use SharedParamsMod , only : ParamsShareInst use VegetationPropertiesType , only : veg_vp use SoilStateType , only : soilstate_type @@ -185,7 +185,7 @@ subroutine MaintenanceResp(bounds, & if (woody(ivt(p)) >= 1.0_r8) then livestem_mr(p) = livestemn(p)*br_mr*tc livecroot_mr(p) = livecrootn(p)*br_mr*tc - else if (ivt(p) >= npcropmin .and. livestemn(p) .gt. 0._r8) then + else if (iscft(ivt(p)) >= 1 .and. livestemn(p) .gt. 0._r8) then livestem_mr(p) = livestemn(p)*br_mr*tc grain_mr(p) = grainn(p)*br_mr*tc end if diff --git a/components/elm/src/biogeochem/NitrogenStateUpdate1Mod.F90 b/components/elm/src/biogeochem/NitrogenStateUpdate1Mod.F90 index d72dc4dc598e..80fc34e6d0ba 100644 --- a/components/elm/src/biogeochem/NitrogenStateUpdate1Mod.F90 +++ b/components/elm/src/biogeochem/NitrogenStateUpdate1Mod.F90 @@ -9,7 +9,7 @@ module NitrogenStateUpdate1Mod use elm_varpar , only : crop_prog, i_met_lit, i_cel_lit, i_lig_lit, i_cwd use elm_varctl , only : iulog use elm_varcon , only : nitrif_n2o_loss_frac - use pftvarcon , only : crop, generic_crop, percrop + use pftvarcon , only : iscft use VegetationPropertiesType , only : veg_vp use CNDecompCascadeConType , only : decomp_cascade_con use CNStateType , only : cnstate_type @@ -297,8 +297,7 @@ subroutine NitrogenStateUpdate1(num_soilc, filter_soilc, num_soilp, filter_soilp veg_ns%deadcrootn_xfer(p) = veg_ns%deadcrootn_xfer(p) - veg_nf%deadcrootn_xfer_to_deadcrootn(p)*dt end if - if ( (crop(ivt(p)) >= 1 .or. percrop(ivt(p)) >= 1) .and. & - generic_crop(ivt(p)) == 0 ) then ! skip 2 generic crops + if (iscft(ivt(p)) >= 1) then ! skip 2 generic crops ! lines here for consistency; the transfer terms are zero veg_ns%livestemn(p) = veg_ns%livestemn(p) + veg_nf%livestemn_xfer_to_livestemn(p)*dt veg_ns%livestemn_xfer(p) = veg_ns%livestemn_xfer(p) - veg_nf%livestemn_xfer_to_livestemn(p)*dt @@ -323,8 +322,7 @@ subroutine NitrogenStateUpdate1(num_soilc, filter_soilc, num_soilp, filter_soilp veg_ns%livecrootn(p) = veg_ns%livecrootn(p) - veg_nf%livecrootn_to_retransn(p)*dt veg_ns%retransn(p) = veg_ns%retransn(p) + veg_nf%livecrootn_to_retransn(p)*dt end if - if ( (crop(ivt(p)) >= 1 .or. percrop(ivt(p)) >= 1) .and. & - generic_crop(ivt(p)) == 0 ) then ! Beth adds retrans from froot + if (iscft(ivt(p)) >= 1) then ! Beth adds retrans from froot veg_ns%frootn(p) = veg_ns%frootn(p) - veg_nf%frootn_to_retransn(p)*dt veg_ns%retransn(p) = veg_ns%retransn(p) + veg_nf%frootn_to_retransn(p)*dt veg_ns%livestemn(p) = veg_ns%livestemn(p) - veg_nf%livestemn_to_litter(p)*dt @@ -375,8 +373,7 @@ subroutine NitrogenStateUpdate1(num_soilc, filter_soilc, num_soilp, filter_soilp veg_ns%deadcrootn_storage(p) = veg_ns%deadcrootn_storage(p) + veg_nf%npool_to_deadcrootn_storage(p)*dt end if - if ( (crop(ivt(p)) >= 1 .or. percrop(ivt(p)) >= 1) .and. & - generic_crop(ivt(p)) == 0 ) then ! skip 2 generic crops + if (iscft(ivt(p)) >= 1) then ! skip 2 generic crops veg_ns%npool(p) = veg_ns%npool(p) - veg_nf%npool_to_livestemn(p)*dt veg_ns%livestemn(p) = veg_ns%livestemn(p) + veg_nf%npool_to_livestemn(p)*dt veg_ns%npool(p) = veg_ns%npool(p) - veg_nf%npool_to_livestemn_storage(p)*dt @@ -404,8 +401,7 @@ subroutine NitrogenStateUpdate1(num_soilc, filter_soilc, num_soilp, filter_soilp veg_ns%deadcrootn_xfer(p) = veg_ns%deadcrootn_xfer(p) + veg_nf%deadcrootn_storage_to_xfer(p)*dt end if - if ( (crop(ivt(p)) >= 1 .or. percrop(ivt(p)) >= 1) .and. & - generic_crop(ivt(p)) == 0 ) then ! skip 2 generic crops + if (iscft(ivt(p)) >= 1) then ! skip 2 generic crops ! lines here for consistency; the transfer terms are zero veg_ns%livestemn_storage(p) = veg_ns%livestemn_storage(p) - veg_nf%livestemn_storage_to_xfer(p)*dt veg_ns%livestemn_xfer(p) = veg_ns%livestemn_xfer(p) + veg_nf%livestemn_storage_to_xfer(p)*dt diff --git a/components/elm/src/biogeochem/NitrogenStateUpdate2Mod.F90 b/components/elm/src/biogeochem/NitrogenStateUpdate2Mod.F90 index 9121954e6363..5d897c5905a9 100644 --- a/components/elm/src/biogeochem/NitrogenStateUpdate2Mod.F90 +++ b/components/elm/src/biogeochem/NitrogenStateUpdate2Mod.F90 @@ -14,7 +14,7 @@ module NitrogenStateUpdate2Mod use ColumnDataType , only : col_ns, col_nf use VegetationType , only : veg_pp use VegetationDataType , only : veg_ns, veg_nf - use pftvarcon , only : npcropmin + use pftvarcon , only : iscft ! bgc interface & pflotran: use elm_varctl , only : use_pflotran, pf_cmode ! @@ -172,7 +172,7 @@ subroutine NitrogenStateUpdate2h(num_soilc, filter_soilc, num_soilp, filter_soil veg_ns%retransn(p) = veg_ns%retransn(p) - veg_nf%hrv_retransn_to_litter(p) * dt veg_ns%npool(p) = veg_ns%npool(p) - veg_nf%hrv_npool_to_litter(p) * dt - if (ivt(p) >= npcropmin) then ! skip 2 generic crops + if (iscft(ivt(p)) >= 1) then ! skip 2 generic crops veg_ns%livestemn(p)= veg_ns%livestemn(p) - veg_nf%hrv_livestemn_to_prod1n(p) * dt veg_ns%leafn(p) = veg_ns%leafn(p) - veg_nf%hrv_leafn_to_prod1n(p) * dt veg_ns%grainn(p) = veg_ns%grainn(p) - veg_nf%hrv_grainn_to_prod1n(p) * dt diff --git a/components/elm/src/biogeochem/PhenologyFluxLimitMod.F90 b/components/elm/src/biogeochem/PhenologyFluxLimitMod.F90 index 786efbe6323a..49909f54929a 100644 --- a/components/elm/src/biogeochem/PhenologyFluxLimitMod.F90 +++ b/components/elm/src/biogeochem/PhenologyFluxLimitMod.F90 @@ -10,7 +10,7 @@ module PhenologyFLuxLimitMod use VegetationType , only : veg_pp use VegetationPropertiesType , only : veg_vp use elm_time_manager , only : get_step_size - use pftvarcon , only : npcropmin + use pftvarcon , only : iscft use elm_varctl , only : iulog use abortutils , only : endrun implicit none @@ -644,7 +644,7 @@ subroutine carbon_flux_limiter(bounds, num_soilc, filter_soilc,& ystates(s_deadcrootc_xfer) = veg_cs%deadcrootc_xfer(p) ystates(s_deadcrootc_storage) = veg_cs%deadcrootc_storage(p) endif - if (ivt(p) >= npcropmin) then + if (iscft(ivt(p)) >= 1) then ystates(s_livestemc) = veg_cs%livestemc(p) ystates(s_livestemc_xfer) = veg_cs%livestemc_xfer(p) ystates(s_livestemc_storage) = veg_cs%livestemc_storage(p) @@ -675,7 +675,7 @@ subroutine carbon_flux_limiter(bounds, num_soilc, filter_soilc,& + veg_cf%cpool_livecroot_storage_gr(p) & + veg_cf%cpool_deadcroot_storage_gr(p) endif - if (ivt(p) >= npcropmin) then + if (iscft(ivt(p)) >= 1) then ar_p= ar_p & + veg_cf%livestem_curmr(p) & + veg_cf%grain_curmr(p) & @@ -713,7 +713,7 @@ subroutine carbon_flux_limiter(bounds, num_soilc, filter_soilc,& rfluxes(f_deadcrootc_storage_to_xfer) = veg_cf%deadcrootc_storage_to_xfer(p) rfluxes(f_gresp_storage_to_xfer) = veg_cf%gresp_storage_to_xfer(p) endif - if (ivt(p) >= npcropmin) then + if (iscft(ivt(p)) >= 1) then rfluxes(f_cpool_to_livestemc) = veg_cf%cpool_to_livestemc(p) rfluxes(f_cpool_to_livestemc_storage) = veg_cf%cpool_to_livestemc_storage(p) rfluxes(f_cpool_to_grainc) = veg_cf%cpool_to_grainc(p) @@ -767,7 +767,7 @@ subroutine carbon_flux_limiter(bounds, num_soilc, filter_soilc,& call fpmax(rfluxes(f_deadcrootc_storage_to_xfer) , veg_cf%deadcrootc_storage_to_xfer(p)) call fpmax(rfluxes(f_gresp_storage_to_xfer) , veg_cf%gresp_storage_to_xfer(p)) endif - if (ivt(p) >= npcropmin) then + if (iscft(ivt(p)) >= 1) then call fpmax(rfluxes(f_cpool_to_livestemc) , veg_cf%cpool_to_livestemc(p)) call fpmax(rfluxes(f_cpool_to_livestemc_storage) , veg_cf%cpool_to_livestemc_storage(p)) call fpmax(rfluxes(f_cpool_to_grainc) , veg_cf%cpool_to_grainc(p)) @@ -806,7 +806,7 @@ subroutine carbon_flux_limiter(bounds, num_soilc, filter_soilc,& call ascal(veg_cf%cpool_livecroot_storage_gr(p), rscal) call ascal(veg_cf%cpool_deadcroot_storage_gr(p), rscal) endif - if (ivt(p) >= npcropmin) then + if (iscft(ivt(p)) >= 1) then call ascal(veg_cf%livestem_curmr(p) , rscal) call ascal(veg_cf%grain_curmr(p) , rscal) call ascal(veg_cf%cpool_livestem_gr(p) , rscal) @@ -878,7 +878,7 @@ subroutine nitrogen_flux_limiter(bounds, num_soilc, filter_soilc,& ystates(s_deadcrootn_xfer) = veg_ns%deadcrootn_xfer(p) ystates(s_deadcrootn_storage) = veg_ns%deadcrootn_storage(p) endif - if (ivt(p) >= npcropmin) then + if (iscft(ivt(p)) >= 1) then ystates(s_grainn) = veg_ns%grainn(p) ystates(s_grainn_xfer) = veg_ns%grainn_xfer(p) ystates(s_grainn_storage) = veg_ns%grainn_storage(p) @@ -917,7 +917,7 @@ subroutine nitrogen_flux_limiter(bounds, num_soilc, filter_soilc,& rfluxes(f_deadcrootn_xfer_to_deadcrootn) = veg_nf%deadcrootn_xfer_to_deadcrootn(p) endif - if (ivt(p) >= npcropmin) then + if (iscft(ivt(p)) >= 1) then rfluxes(f_npool_to_livestemn) = veg_nf%npool_to_livestemn(p) rfluxes(f_npool_to_livestemn_storage) = veg_nf%npool_to_livestemn_storage(p) rfluxes(f_npool_to_grainn) = veg_nf%npool_to_grainn(p) @@ -973,7 +973,7 @@ subroutine nitrogen_flux_limiter(bounds, num_soilc, filter_soilc,& call fpmax(rfluxes(f_deadcrootn_xfer_to_deadcrootn) , veg_nf%deadcrootn_xfer_to_deadcrootn(p)) endif - if (ivt(p) >= npcropmin) then + if (iscft(ivt(p)) >= 1) then call fpmax(rfluxes(f_npool_to_livestemn) , veg_nf%npool_to_livestemn(p)) call fpmax(rfluxes(f_npool_to_livestemn_storage) , veg_nf%npool_to_livestemn_storage(p)) call fpmax(rfluxes(f_npool_to_grainn) , veg_nf%npool_to_grainn(p)) @@ -1063,7 +1063,7 @@ subroutine phosphorus_flux_limiter(bounds, num_soilc, filter_soilc,& ystates(s_deadcrootn_xfer) = veg_ps%deadcrootp_xfer(p) ystates(s_deadcrootn_storage) = veg_ps%deadcrootp_storage(p) endif - if (ivt(p) >= npcropmin) then + if (iscft(ivt(p)) >= 1) then ystates(s_grainn) = veg_ps%grainp(p) ystates(s_grainn_xfer) = veg_ps%grainp_xfer(p) ystates(s_grainn_storage) = veg_ps%grainp_storage(p) @@ -1102,7 +1102,7 @@ subroutine phosphorus_flux_limiter(bounds, num_soilc, filter_soilc,& rfluxes(f_deadcrootn_xfer_to_deadcrootn) = veg_pf%deadcrootp_xfer_to_deadcrootp(p) endif - if (ivt(p) >= npcropmin) then + if (iscft(ivt(p)) >= 1) then rfluxes(f_npool_to_livestemn) = veg_pf%ppool_to_livestemp(p) rfluxes(f_npool_to_livestemn_storage) = veg_pf%ppool_to_livestemp_storage(p) rfluxes(f_npool_to_grainn) = veg_pf%ppool_to_grainp(p) @@ -1158,7 +1158,7 @@ subroutine phosphorus_flux_limiter(bounds, num_soilc, filter_soilc,& call fpmax(rfluxes(f_deadcrootn_xfer_to_deadcrootn) , veg_pf%deadcrootp_xfer_to_deadcrootp(p)) endif - if (ivt(p) >= npcropmin) then + if (iscft(ivt(p)) >= 1) then call fpmax(rfluxes(f_npool_to_livestemn) , veg_pf%ppool_to_livestemp(p)) call fpmax(rfluxes(f_npool_to_livestemn_storage) , veg_pf%ppool_to_livestemp_storage(p)) call fpmax(rfluxes(f_npool_to_grainn) , veg_pf%ppool_to_grainp(p)) diff --git a/components/elm/src/biogeochem/PhenologyMod.F90 b/components/elm/src/biogeochem/PhenologyMod.F90 index d5ddfc2f44ed..2a52cb928837 100644 --- a/components/elm/src/biogeochem/PhenologyMod.F90 +++ b/components/elm/src/biogeochem/PhenologyMod.F90 @@ -2177,7 +2177,8 @@ subroutine CropPhenologyInit(bounds) ! initialized, and after ecophyscon file is read in. ! ! !USES: - use pftvarcon , only: npcropmin, npcropmax, nppercropmin, nppercropmax, mnNHplantdate + use elm_varpar , only : mxpft + use pftvarcon , only: iscft, mnNHplantdate use pftvarcon , only: mnSHplantdate, mxNHplantdate use pftvarcon , only: mxSHplantdate use elm_time_manager, only: get_calday @@ -2203,23 +2204,28 @@ subroutine CropPhenologyInit(bounds) ! Convert planting dates into julian day minplantjday(:,:) = huge(1) maxplantjday(:,:) = huge(1) - do n = npcropmin, npcropmax + do n = 0, mxpft + if (iscft(n)>=1) then minplantjday(n,inNH) = int( get_calday( mnNHplantdate(n), 0 ) ) maxplantjday(n,inNH) = int( get_calday( mxNHplantdate(n), 0 ) ) + end if end do - do n = npcropmin, npcropmax + do n = 0, mxpft + if (iscft(n)>=1) then minplantjday(n,inSH) = int( get_calday( mnSHplantdate(n), 0 ) ) maxplantjday(n,inSH) = int( get_calday( mxSHplantdate(n), 0 ) ) + end if end do - do n = nppercropmin, nppercropmax - minplantjday(n,inNH) = int( get_calday( mnNHplantdate(n), 0 ) ) - maxplantjday(n,inNH) = int( get_calday( mxNHplantdate(n), 0 ) ) - end do - do n = nppercropmin, nppercropmax - minplantjday(n,inSH) = int( get_calday( mnSHplantdate(n), 0 ) ) - maxplantjday(n,inSH) = int( get_calday( mxSHplantdate(n), 0 ) ) - end do + ! with flag 'iscft', the following is not needed anymore + !do n = nppercropmin, nppercropmax + ! minplantjday(n,inNH) = int( get_calday( mnNHplantdate(n), 0 ) ) + ! maxplantjday(n,inNH) = int( get_calday( mxNHplantdate(n), 0 ) ) + !end do + !do n = nppercropmin, nppercropmax + ! minplantjday(n,inSH) = int( get_calday( mnSHplantdate(n), 0 ) ) + ! maxplantjday(n,inSH) = int( get_calday( mxSHplantdate(n), 0 ) ) + !end do ! Figure out what hemisphere each PFT is in do p = bounds%begp, bounds%endp @@ -2965,7 +2971,7 @@ subroutine CNOffsetLitterfall (num_soilp, filter_soilp, & ! ! !USES: !$acc routine seq - use pftvarcon , only : npcropmin + use pftvarcon , only : iscft ! ! !ARGUMENTS: integer , intent(in) :: num_soilp ! number of soil patches in filter @@ -3062,7 +3068,7 @@ subroutine CNOffsetLitterfall (num_soilp, filter_soilp, & if (offset_counter(p) == dt) then t1 = 1.0_r8 / dt - if (ivt(p) >= npcropmin) then + if (iscft(ivt(p)) >= 1) then ! this assumes that offset_counter == dt for crops ! if this were ever changed, we'd need to add code to the "else" leafc_to_litter(p) = (1.0_r8 - presharv(ivt(p))) * ((t1 * leafc(p)) + cpool_to_leafc(p)) @@ -3079,7 +3085,7 @@ subroutine CNOffsetLitterfall (num_soilp, filter_soilp, & end if if ( nu_com .eq. 'RD') then - if (ivt(p) >= npcropmin) then + if (iscft(ivt(p)) >= 1) then if (offset_counter(p) == dt) then t1 = 1.0_r8 / dt @@ -3113,7 +3119,7 @@ subroutine CNOffsetLitterfall (num_soilp, filter_soilp, & else if (offset_counter(p) == dt) then t1 = 1.0_r8 / dt - if (ivt(p) >= npcropmin) then + if (iscft(ivt(p)) >= 1) then ! this assumes that offset_counter == dt for crops ! if this were ever changed, we'd need to add code to the "else" leafn_to_litter(p) = (1.0_r8 - presharv(ivt(p))) * ((t1 * leafn(p)) + npool_to_leafn(p)) @@ -3387,7 +3393,7 @@ subroutine CNLitterToColumn (num_soilp, filter_soilp, & ! !USES: !$acc routine seq use elm_varpar , only : max_patch_per_col, nlevdecomp - use pftvarcon , only : npcropmin + use pftvarcon , only : iscft ! ! !ARGUMENTS: integer , intent(in) :: num_soilp ! number of soil columns in filter @@ -3497,7 +3503,7 @@ subroutine CNLitterToColumn (num_soilp, filter_soilp, & ! new ones for now (slevis) ! The food is now directed to the product pools (BDrewniak) - if (ivt(p) >= npcropmin) then ! add livestemc to litter + if (iscft(ivt(p)) >= 1) then ! add livestemc to litter ! stem litter carbon fluxes phenology_c_to_litr_met_c(c,j) = phenology_c_to_litr_met_c(c,j) & + livestemc_to_litter(p) * lf_flab(ivt(p)) * wt_col * leaf_prof(p,j) diff --git a/components/elm/src/biogeochem/PhosphorusFluxType.F90 b/components/elm/src/biogeochem/PhosphorusFluxType.F90 index f34d7556f696..52bda3118fd2 100644 --- a/components/elm/src/biogeochem/PhosphorusFluxType.F90 +++ b/components/elm/src/biogeochem/PhosphorusFluxType.F90 @@ -561,7 +561,6 @@ subroutine Summary(this, bounds, num_soilc, filter_soilc, num_soilp, filter_soil ! !USES: use elm_varpar , only: nlevdecomp,ndecomp_cascade_transitions,ndecomp_pools use subgridAveMod , only: p2c - use pftvarcon , only: npcropmin ! pflotran ! use elm_varctl , only: use_pflotran, pf_cmode ! diff --git a/components/elm/src/biogeochem/PhosphorusStateType.F90 b/components/elm/src/biogeochem/PhosphorusStateType.F90 index 0be7dd7f533f..58dbe630c2ef 100644 --- a/components/elm/src/biogeochem/PhosphorusStateType.F90 +++ b/components/elm/src/biogeochem/PhosphorusStateType.F90 @@ -12,7 +12,7 @@ module PhosphorusStateType use elm_varctl , only : use_vertsoilc, use_century_decomp use elm_varctl , only : iulog, override_bgc_restart_mismatch_dump, spinup_state use decompMod , only : bounds_type - use pftvarcon , only : npcropmin, nstor + use pftvarcon , only : iscft, nstor use CNDecompCascadeConType , only : decomp_cascade_con use VegetationPropertiesType , only : veg_vp use abortutils , only : endrun @@ -254,7 +254,7 @@ subroutine InitCold(this, bounds, & ! !USES: use elm_varpar , only : crop_prog use decompMod , only : bounds_type - use pftvarcon , only : noveg, npcropmin + use pftvarcon , only : noveg, iscft ! ! !ARGUMENTS: class(phosphorusstate_type) :: this diff --git a/components/elm/src/biogeochem/PhosphorusStateUpdate1Mod.F90 b/components/elm/src/biogeochem/PhosphorusStateUpdate1Mod.F90 index e29074eb332f..01369ed83fa7 100644 --- a/components/elm/src/biogeochem/PhosphorusStateUpdate1Mod.F90 +++ b/components/elm/src/biogeochem/PhosphorusStateUpdate1Mod.F90 @@ -8,7 +8,7 @@ module PhosphorusStateUpdate1Mod use elm_varpar , only : nlevdecomp, ndecomp_pools, ndecomp_cascade_transitions use elm_varpar , only : crop_prog, i_met_lit, i_cel_lit, i_lig_lit, i_cwd use elm_varctl , only : iulog - use pftvarcon , only : crop, generic_crop, percrop + use pftvarcon , only : iscft use soilorder_varcon , only : smax,ks_sorption use VegetationPropertiesType , only : veg_vp use CNDecompCascadeConType , only : decomp_cascade_con @@ -255,8 +255,7 @@ subroutine PhosphorusStateUpdate1(num_soilc, filter_soilc, num_soilp, filter_soi veg_ps%deadcrootp_xfer(p) = veg_ps%deadcrootp_xfer(p) - veg_pf%deadcrootp_xfer_to_deadcrootp(p)*dt end if - if ( (crop(ivt(p)) >= 1 .or. percrop(ivt(p)) >= 1) .and. & - generic_crop(ivt(p)) == 0 ) then ! skip 2 generic crops + if (iscft(ivt(p)) >= 1) then ! skip 2 generic crops ! lines here for consistency; the transfer terms are zero veg_ps%livestemp(p) = veg_ps%livestemp(p) + veg_pf%livestemp_xfer_to_livestemp(p)*dt veg_ps%livestemp_xfer(p) = veg_ps%livestemp_xfer(p) - veg_pf%livestemp_xfer_to_livestemp(p)*dt @@ -281,8 +280,7 @@ subroutine PhosphorusStateUpdate1(num_soilc, filter_soilc, num_soilp, filter_soi veg_ps%livecrootp(p) = veg_ps%livecrootp(p) - veg_pf%livecrootp_to_retransp(p)*dt veg_ps%retransp(p) = veg_ps%retransp(p) + veg_pf%livecrootp_to_retransp(p)*dt end if - if ( (crop(ivt(p)) >= 1 .or. percrop(ivt(p)) >= 1) .and. & - generic_crop(ivt(p)) == 0 ) then ! Beth adds retrans from froot + if (iscft(ivt(p)) >= 1) then ! Beth adds retrans from froot veg_ps%frootp(p) = veg_ps%frootp(p) - veg_pf%frootp_to_retransp(p)*dt veg_ps%retransp(p) = veg_ps%retransp(p) + veg_pf%frootp_to_retransp(p)*dt veg_ps%livestemp(p) = veg_ps%livestemp(p) - veg_pf%livestemp_to_litter(p)*dt @@ -333,8 +331,7 @@ subroutine PhosphorusStateUpdate1(num_soilc, filter_soilc, num_soilp, filter_soi veg_ps%deadcrootp_storage(p) = veg_ps%deadcrootp_storage(p) + veg_pf%ppool_to_deadcrootp_storage(p)*dt end if - if ( (crop(ivt(p)) >= 1 .or. percrop(ivt(p)) >= 1) .and. & - generic_crop(ivt(p)) == 0 ) then ! skip 2 generic crops + if (iscft(ivt(p)) >= 1) then ! skip 2 generic crops veg_ps%ppool(p) = veg_ps%ppool(p) - veg_pf%ppool_to_livestemp(p)*dt veg_ps%livestemp(p) = veg_ps%livestemp(p) + veg_pf%ppool_to_livestemp(p)*dt veg_ps%ppool(p) = veg_ps%ppool(p) - veg_pf%ppool_to_livestemp_storage(p)*dt @@ -362,8 +359,7 @@ subroutine PhosphorusStateUpdate1(num_soilc, filter_soilc, num_soilp, filter_soi veg_ps%deadcrootp_xfer(p) = veg_ps%deadcrootp_xfer(p) + veg_pf%deadcrootp_storage_to_xfer(p)*dt end if - if ( (crop(ivt(p)) >= 1 .or. percrop(ivt(p)) >= 1) .and. & - generic_crop(ivt(p)) == 0 ) then ! skip 2 generic crops + if (iscft(ivt(p)) >= 1) then ! skip 2 generic crops ! lines here for consistency; the transfer terms are zero veg_ps%livestemp_storage(p) = veg_ps%livestemp_storage(p) - veg_pf%livestemp_storage_to_xfer(p)*dt veg_ps%livestemp_xfer(p) = veg_ps%livestemp_xfer(p) + veg_pf%livestemp_storage_to_xfer(p)*dt diff --git a/components/elm/src/biogeochem/PhosphorusStateUpdate2Mod.F90 b/components/elm/src/biogeochem/PhosphorusStateUpdate2Mod.F90 index 2385083451cc..4aa7563c70f7 100644 --- a/components/elm/src/biogeochem/PhosphorusStateUpdate2Mod.F90 +++ b/components/elm/src/biogeochem/PhosphorusStateUpdate2Mod.F90 @@ -12,7 +12,7 @@ module PhosphorusStateUpdate2Mod !use PhosphorusStateType , only : phosphorusstate_type !use PhosphorusFLuxType , only : phosphorusflux_type use VegetationType , only : veg_pp - use pftvarcon , only : npcropmin + use pftvarcon , only : iscft use tracer_varcon , only : is_active_betr_bgc ! bgc interface & pflotran: use elm_varctl , only : use_pflotran, pf_cmode @@ -182,7 +182,7 @@ subroutine PhosphorusStateUpdate2h(num_soilc, filter_soilc, num_soilp, filter_so veg_ps%retransp(p) = veg_ps%retransp(p) - veg_pf%hrv_retransp_to_litter(p) * dt veg_ps%ppool(p) = veg_ps%ppool(p) - veg_pf%hrv_ppool_to_litter(p) * dt - if (ivt(p) >= npcropmin) then ! skip 2 generic crops + if (iscft(ivt(p)) >= 1) then ! skip 2 generic crops veg_ps%livestemp(p)= veg_ps%livestemp(p) - veg_pf%hrv_livestemp_to_prod1p(p) * dt veg_ps%leafp(p) = veg_ps%leafp(p) - veg_pf%hrv_leafp_to_prod1p(p) * dt veg_ps%grainp(p) = veg_ps%grainp(p) - veg_pf%hrv_grainp_to_prod1p(p) * dt diff --git a/components/elm/src/biogeochem/PrecisionControlMod.F90 b/components/elm/src/biogeochem/PrecisionControlMod.F90 index 8767d300b244..2423592c05c2 100644 --- a/components/elm/src/biogeochem/PrecisionControlMod.F90 +++ b/components/elm/src/biogeochem/PrecisionControlMod.F90 @@ -39,7 +39,7 @@ subroutine PrecisionControl(num_soilc, filter_soilc, num_soilp, filter_soilp) !$acc routine seq use elm_varctl , only : iulog, use_c13, use_c14, use_fates use elm_varpar , only : nlevdecomp_full, crop_prog - use pftvarcon , only : crop, generic_crop, percrop + use pftvarcon , only : iscft use tracer_varcon , only : is_active_betr_bgc use CNDecompCascadeConType , only : decomp_cascade_con ! @@ -211,9 +211,7 @@ subroutine PrecisionControl(num_soilc, filter_soilc, num_soilp, filter_soilp) veg_ps%frootp_xfer(p) = 0._r8 end if - if ( crop_prog .and. & - (crop(veg_pp%itype(p)) >= 1 .or. & - percrop(veg_pp%itype(p)) >= 1) )then + if ( crop_prog .and. iscft(veg_pp%itype(p)) >= 1 )then ! grain C and N if (abs(veg_cs%grainc(p)) < ccrit) then pc = pc + veg_cs%grainc(p) @@ -515,9 +513,7 @@ subroutine PrecisionControl(num_soilc, filter_soilc, num_soilp, filter_soilp) endif end if - if ( crop_prog .and. & - (crop(veg_pp%itype(p)) >= 1 .or. & - percrop(veg_pp%itype(p)) >= 1) )then + if ( crop_prog .and. iscft(veg_pp%itype(p)) >= 1 )then ! xsmrpool (C only) if (abs(veg_cs%xsmrpool(p)) < ccrit) then pc = pc + veg_cs%xsmrpool(p) diff --git a/components/elm/src/biogeochem/RootDynamicsMod.F90 b/components/elm/src/biogeochem/RootDynamicsMod.F90 index 3c78043aa6ac..f5ffc4c67844 100644 --- a/components/elm/src/biogeochem/RootDynamicsMod.F90 +++ b/components/elm/src/biogeochem/RootDynamicsMod.F90 @@ -10,7 +10,7 @@ module RootDynamicsMod use elm_varpar , only : nlevsoi, nlevgrnd use elm_varctl , only : use_vertsoilc use decompMod , only : bounds_type - use pftvarcon , only : noveg, npcropmin, roota_par, rootb_par, root_dmx, evergreen + use pftvarcon , only : noveg, iscft, roota_par, rootb_par, root_dmx, evergreen use CanopyStateType , only: canopystate_type use CNStateType , only : cnstate_type use CNCarbonStateType , only : carbonstate_type @@ -136,7 +136,7 @@ subroutine RootDynamics(bounds, num_soilc, filter_soilc, num_soilp, filter_soilp p = filter_soilp(f) c = pcolumn(p) if (ivt(p) /= noveg) then - if ((ivt(p)) >= npcropmin) then !skip generic crop types + if (iscft(ivt(p)) >= 1) then !skip generic crop types if (huigrain(p) > 0._r8) then root_depth(p) = max(zi(c,2), min(hui(p)/huigrain(p)* root_dmx(ivt(p)), root_dmx(ivt(p)))) end if diff --git a/components/elm/src/biogeochem/VOCEmissionMod.F90 b/components/elm/src/biogeochem/VOCEmissionMod.F90 index 64a72fe78b8e..fb7bd66958db 100644 --- a/components/elm/src/biogeochem/VOCEmissionMod.F90 +++ b/components/elm/src/biogeochem/VOCEmissionMod.F90 @@ -10,7 +10,7 @@ module VOCEmissionMod use elm_varctl , only : iulog use elm_varpar , only : numpft, nlevcan use elm_varpar , only : numveg ! fixed as 16, while numpft above may be variable - use pftvarcon , only : woody, graminoid, generic_crop, crop, percrop + use pftvarcon , only : woody, graminoid, iscft, crop use pftvarcon , only : needleleaf, evergreen use shr_megan_mod , only : shr_megan_megcomps_n, shr_megan_megcomp_t, shr_megan_linkedlist use shr_megan_mod , only : shr_megan_mechcomps_n, shr_megan_mechcomps, shr_megan_mapped_emisfctrs @@ -703,8 +703,7 @@ function get_map_EF(ivt_in, g_in, ti_in, vocemis_vars) get_map_EF = vocemis_vars%efisop_grc(4,g_in, ti_in) else if (graminoid(ivt_in) == 1) then !grass get_map_EF = vocemis_vars%efisop_grc(5,g_in, ti_in) - else if (generic_crop(ivt_in) == 1 .or. crop(ivt_in) == 1 & - .or. percrop(ivt_in) == 1) then !crops + else if (crop(ivt_in) == 1 .or. iscft(ivt_in) == 1) then !crops get_map_EF = vocemis_vars%efisop_grc(6,g_in, ti_in) end if diff --git a/components/elm/src/biogeochem/VegStructUpdateMod.F90 b/components/elm/src/biogeochem/VegStructUpdateMod.F90 index de7062b810d5..c40e0fc0ea0d 100644 --- a/components/elm/src/biogeochem/VegStructUpdateMod.F90 +++ b/components/elm/src/biogeochem/VegStructUpdateMod.F90 @@ -37,7 +37,7 @@ subroutine VegStructUpdate(num_soilp, filter_soilp, & ! vegetation structure (LAI, SAI, height) ! ! !USES: - use pftvarcon , only : noveg, woody, generic_crop, crop, percrop + use pftvarcon , only : noveg, woody, iscft, crop use pftvarcon , only : ncorn, ncornirrig, ztopmx, laimx use pftvarcon , only : nmiscanthus, nmiscanthusirrig, nswitchgrass, nswitchgrassirrig use elm_time_manager , only : get_rad_step_size @@ -147,7 +147,7 @@ subroutine VegStructUpdate(num_soilp, filter_soilp, & ! alpha are set by PFT, and alpha is scaled to CLM time step by multiplying by ! dt and dividing by dtsmonth (seconds in average 30 day month) ! tsai_min scaled by 0.5 to match MODIS satellite derived values - if (generic_crop(ivt(p)) == 1) then ! generic crops + if (crop(ivt(p)) == 1 .and. iscft(ivt(p)) == 0) then ! generic crops tsai_alpha = 1.0_r8-1.0_r8*dt/dtsmonth tsai_min = 0.1_r8 @@ -193,8 +193,7 @@ subroutine VegStructUpdate(num_soilp, filter_soilp, & hbot(p) = max(0._r8, min(3._r8, htop(p)-1._r8)) - else if ( generic_crop(ivt(p)) <1 .and. & - (crop(ivt(p)) >= 1 .or. percrop(ivt(p)) >= 1) ) then ! prognostic crops + else if (iscft(ivt(p)) >= 1) then ! prognostic crops if (tlai(p) >= laimx(ivt(p))) peaklai(p) = 1 ! used in CNAllocation diff --git a/components/elm/src/biogeophys/SedYieldMod.F90 b/components/elm/src/biogeophys/SedYieldMod.F90 index e50544edde6c..e0d63ed063c9 100644 --- a/components/elm/src/biogeophys/SedYieldMod.F90 +++ b/components/elm/src/biogeophys/SedYieldMod.F90 @@ -63,7 +63,7 @@ subroutine SoilErosion (bounds, num_soilc, filter_soilc, & use elm_time_manager, only : get_step_size use landunit_varcon , only : istcrop, istsoil, istice use pftvarcon , only : gcbc_p, gcbc_q, gcbr_p, gcbr_q - use pftvarcon , only : generic_crop, crop, percrop + use pftvarcon , only : crop, iscft ! ! !ARGUMENTS: type(bounds_type) , intent(in) :: bounds @@ -218,9 +218,7 @@ subroutine SoilErosion (bounds, num_soilc, filter_soilc, & (veg_cs%livecrootc(p)+veg_cs%deadcrootc(p))*croot_prof(p,1) ) fgndcov = exp( -gcbc_p(veg_pp%itype(p))*PCT_gnd - & gcbr_p(veg_pp%itype(p))*Broot ) - if( generic_crop(veg_pp%itype(p)) >= 1 .or. & - crop(veg_pp%itype(p)) >= 1 .or. & - percrop(veg_pp%itype(p)) >=1 )then + if( crop(veg_pp%itype(p)) >= 1 .or. iscft(veg_pp%itype(p)) >=1 )then Es_Pcrp = Es_Pcrp + pfactor(c) * ftillage * flitho * & fgndcov * veg_pp%wtcol(p) * K * (KE_DT+KE_LD) @@ -268,9 +266,7 @@ subroutine SoilErosion (bounds, num_soilc, filter_soilc, & nh = 0.03_r8 + 0.05_r8*max(Crsd,Clai) fsr = fsr + veg_pp%wtcol(p) * (0.03_r8/nh)**0.6_r8 - if ( generic_crop(veg_pp%itype(p)) >= 1 .or. & - crop(veg_pp%itype(p)) >= 1 .or. & - percrop(veg_pp%itype(p)) >=1 ) then + if ( crop(veg_pp%itype(p)) >= 1 .or. iscft(veg_pp%itype(p)) >= 1 ) then ftillage_tc = ftillage_tc + ftillage * veg_pp%wtcol(p) Es_Q = Es_Q + 19.1_r8 * qfactor(c) * 2._r8/COH * flitho * fslp * & diff --git a/components/elm/src/data_types/VegetationDataType.F90 b/components/elm/src/data_types/VegetationDataType.F90 index eea30fc55fef..ecbdca64df33 100644 --- a/components/elm/src/data_types/VegetationDataType.F90 +++ b/components/elm/src/data_types/VegetationDataType.F90 @@ -17,7 +17,7 @@ module VegetationDataType use elm_varcon , only : spval, ispval, sb use elm_varcon , only : c13ratio, c14ratio use landunit_varcon , only : istsoil, istcrop - use pftvarcon , only : npcropmin, noveg, nstor + use pftvarcon , only : iscft, noveg, nstor use elm_varctl , only : iulog, use_cn, spinup_state, spinup_mortality_factor, use_fates use elm_varctl , only : nu_com, use_crop, use_c13 use elm_varctl , only : use_lch4, use_betr @@ -2447,7 +2447,7 @@ subroutine veg_cs_init(this, begp, endp, carbon_type, ratio) if (veg_vp%evergreen(veg_pp%itype(p)) == 1._r8) then this%leafc(p) = 1._r8 * ratio this%leafc_storage(p) = 0._r8 - else if (veg_pp%itype(p) >= npcropmin) then ! prognostic crop types + else if (iscft(veg_pp%itype(p)) >= 1) then ! prognostic crop types this%leafc(p) = 0._r8 this%leafc_storage(p) = 0._r8 else @@ -3572,7 +3572,7 @@ subroutine veg_cs_summary(this, bounds, num_soilc, filter_soilc, num_soilp, filt this%gresp_storage(p) + & this%gresp_xfer(p) - if ( crop_prog .and. veg_pp%itype(p) >= npcropmin )then + if ( crop_prog .and. iscft(veg_pp%itype(p)) >= 1 )then this%storvegc(p) = & this%storvegc(p) + & this%grainc_storage(p) + & @@ -4249,7 +4249,7 @@ subroutine veg_ns_summary(this, bounds, num_soilc, filter_soilc, num_soilp, filt this%npool(p) + & this%retransn(p) - if ( crop_prog .and. veg_pp%itype(p) >= npcropmin )then + if ( crop_prog .and. iscft(veg_pp%itype(p)) >= 1 )then this%dispvegn(p) = & this%dispvegn(p) + & this%grainn(p) @@ -4997,7 +4997,7 @@ subroutine veg_ps_summary (this, bounds, num_soilc, filter_soilc, num_soilp, fil this%ppool(p) + & this%retransp(p) - if ( crop_prog .and. veg_pp%itype(p) >= npcropmin )then + if ( crop_prog .and. iscft(veg_pp%itype(p)) >= 1 )then this%dispvegp(p) = & this%dispvegp(p) + & this%grainp(p) @@ -8189,7 +8189,7 @@ subroutine veg_cf_summary(this, bounds, num_soilp, filter_soilp, num_soilc, filt this%cpool_livecroot_storage_gr(p) + & this%cpool_deadcroot_storage_gr(p) - if ( crop_prog .and. veg_pp%itype(p) >= npcropmin )then + if ( crop_prog .and. iscft(veg_pp%itype(p)) >= 1 )then this%mr(p) = & this%mr(p) + & this%grain_mr(p) @@ -8214,7 +8214,7 @@ subroutine veg_cf_summary(this, bounds, num_soilp, filter_soilp, num_soilc, filt this%storage_gr(p) ! autotrophic respiration (AR) - if ( crop_prog .and. veg_pp%itype(p) >= npcropmin )then + if ( crop_prog .and. iscft(veg_pp%itype(p)) >= 1 )then this%ar(p) = & this%mr(p) + & this%gr(p) + & @@ -8324,8 +8324,7 @@ subroutine veg_cf_summary(this, bounds, num_soilp, filter_soilp, num_soilc, filt this%wood_harvestc(p) = & this%hrv_deadstemc_to_prod10c(p) + & this%hrv_deadstemc_to_prod100c(p) - - if ( crop_prog .and. veg_pp%itype(p) >= npcropmin )then + if ( crop_prog .and. iscft(veg_pp%itype(p)) >= 1 )then this%wood_harvestc(p) = & this%wood_harvestc(p) + & this%hrv_cropc_to_prod1c(p) @@ -8355,7 +8354,7 @@ subroutine veg_cf_summary(this, bounds, num_soilp, filter_soilp, num_soilc, filt this%m_gresp_xfer_to_fire(p) + & this%m_cpool_to_fire(p) - if ( crop_prog .and. veg_pp%itype(p) >= npcropmin )then + if ( crop_prog .and. iscft(veg_pp%itype(p)) >= 1 )then this%litfall(p) = & this%litfall(p) + & this%livestemc_to_litter(p) + & @@ -8394,7 +8393,7 @@ subroutine veg_cf_summary(this, bounds, num_soilp, filter_soilp, num_soilc, filt this%leafc_loss(p) = this%leafc_loss(p) + & this%hrv_leafc_to_litter(p) - if ( crop_prog .and. veg_pp%itype(p) >= npcropmin )then + if ( crop_prog .and. iscft(veg_pp%itype(p)) >= 1 )then this%leafc_loss(p) = & this%leafc_loss(p) + & this%hrv_leafc_to_prod1c(p) @@ -8438,7 +8437,7 @@ subroutine veg_cf_summary(this, bounds, num_soilp, filter_soilp, num_soilc, filt this%hrv_deadcrootc_storage_to_litter(p) + & this%hrv_deadcrootc_xfer_to_litter(p) ! putting the harvested crop stem and grain in the wood loss bdrewniak - if ( crop_prog .and. veg_pp%itype(p) >= npcropmin )then + if ( crop_prog .and. iscft(veg_pp%itype(p)) >= 1 )then this%woodc_loss(p) = & this%woodc_loss(p) + & this%hrv_grainc_to_prod1c(p) + & @@ -8563,7 +8562,7 @@ subroutine veg_cf_summary_for_ch4( this, bounds, num_soilp, filter_soilp) this%cpool_to_deadstemc(p) + & this%deadstemc_xfer_to_deadstemc(p) - if ( crop_prog .and. veg_pp%itype(p) >= npcropmin )then + if ( crop_prog .and. iscft(veg_pp%itype(p)) >= 1 )then this%agnpp(p) = & this%agnpp(p) + & this%cpool_to_grainc(p) + & @@ -9721,7 +9720,7 @@ subroutine veg_nf_summary(this, bounds, num_soilc, filter_soilc, num_soilp, filt this%wood_harvestn(p) = & this%hrv_deadstemn_to_prod10n(p) + & this%hrv_deadstemn_to_prod100n(p) - if ( crop_prog .and. veg_pp%itype(p) >= npcropmin )then + if ( crop_prog .and. iscft(veg_pp%itype(p)) >= 1 )then this%wood_harvestn(p) = & this%wood_harvestn(p) + & this%hrv_cropn_to_prod1n(p) @@ -10777,7 +10776,7 @@ subroutine veg_pf_summary(this, bounds, num_soilc, filter_soilc, num_soilp, filt this%wood_harvestp(p) = & this%hrv_deadstemp_to_prod10p(p) + & this%hrv_deadstemp_to_prod100p(p) - if ( crop_prog .and. veg_pp%itype(p) >= npcropmin )then + if ( crop_prog .and. iscft(veg_pp%itype(p)) >= 1 )then this%wood_harvestp(p) = & this%wood_harvestp(p) + & this%hrv_cropp_to_prod1p(p) diff --git a/components/elm/src/data_types/VegetationPropertiesType.F90 b/components/elm/src/data_types/VegetationPropertiesType.F90 index 21d7ed671f31..16f251377a43 100644 --- a/components/elm/src/data_types/VegetationPropertiesType.F90 +++ b/components/elm/src/data_types/VegetationPropertiesType.F90 @@ -147,7 +147,7 @@ module VegetationPropertiesType real(r8), pointer :: climatezone(:) => null() !climate zone adapted real(r8), pointer :: nonvascular(:) => null() !nonvascular type or vascular real(r8), pointer :: graminoid(:) => null() !graminoid or not - real(r8), pointer :: generic_crop(:) => null() !generic crop or not for prognostic crop modules (?) + real(r8), pointer :: iscft(:) => null() !generic crop (0) or (1) crop for prognostic crop modules real(r8), pointer :: needleleaf(:) => null() !needleleaf or broadleaf real(r8), pointer :: nfixer(:) => null() !cablity of nitrogen fixation from atm. N2 @@ -189,7 +189,7 @@ subroutine veg_vp_init(this) use pftvarcon , only : lmrha, vcmaxhd, jmaxhd, tpuhd, lmrse, qe, theta_cj use pftvarcon , only : bbbopt, mbbopt, nstor, br_xr, tc_stress, lmrhd ! new properties for flexible PFT - use pftvarcon , only : climatezone, nonvascular, graminoid, generic_crop,needleleaf, nfixer + use pftvarcon , only : climatezone, nonvascular, graminoid, iscft,needleleaf, nfixer ! class (vegetation_properties_type) :: this @@ -318,7 +318,7 @@ subroutine veg_vp_init(this) allocate( this%climatezone(0:numpft)) ; this%climatezone(:) =spval allocate( this%nonvascular(0:numpft)) ; this%nonvascular(:) =spval allocate( this%graminoid(0:numpft)) ; this%graminoid(:) =spval - allocate( this%generic_crop(0:numpft)) ; this%generic_crop(:) =spval + allocate( this%iscft(0:numpft)) ; this%iscft(:) =spval allocate( this%needleleaf(0:numpft)) ; this%needleleaf(:) =spval allocate( this%nfixer(0:numpft)) ; this%nfixer(:) =spval ! ----------------------------------------------------------------------------------------------------------- @@ -414,7 +414,7 @@ subroutine veg_vp_init(this) this%climatezone(m) = climatezone(m) this%nonvascular(m) = nonvascular(m) this%graminoid(m) = graminoid(m) - this%generic_crop(m) = generic_crop(m) + this%iscft(m) = iscft(m) this%needleleaf(m) = needleleaf(m) this%nfixer(m) = nfixer(m) diff --git a/components/elm/src/main/filterMod.F90 b/components/elm/src/main/filterMod.F90 index 768235bea40a..eb3f2f2ef1d0 100644 --- a/components/elm/src/main/filterMod.F90 +++ b/components/elm/src/main/filterMod.F90 @@ -272,7 +272,7 @@ subroutine setFiltersOneGroup(bounds, this_filter, include_inactive, icemask_grc ! ! !USES: use decompMod , only : BOUNDS_LEVEL_CLUMP - use pftvarcon , only : npcropmin, nppercropmin + use pftvarcon , only : iscft, crop, percrop use landunit_varcon, only : istsoil, istcrop, istice_mec use column_varcon, only : icol_road_perv ! @@ -420,17 +420,17 @@ subroutine setFiltersOneGroup(bounds, this_filter, include_inactive, icemask_grc t =veg_pp%topounit(p) if (top_pp%active(t)) then if (veg_pp%active(p) .or. include_inactive) then - if (veg_pp%itype(p) < npcropmin) then + if (iscft(veg_pp%itype(p)) < 1) then l =veg_pp%landunit(p) if (lun_pp%itype(l) == istsoil .or. lun_pp%itype(l) == istcrop) then fnc = fnc + 1 this_filter(nc)%soilnopcropp(fnc) = p end if else - if (veg_pp%itype(p) < nppercropmin) then + if (percrop(veg_pp%itype(p)) < 1) then fc = fc + 1 this_filter(nc)%pcropp(fc) = p - else if (veg_pp%itype(p) >= nppercropmin) then + else if (percrop(veg_pp%itype(p)) >= 1) then fpc = fpc + 1 this_filter(nc)%ppercropp(fpc) = p end if diff --git a/components/elm/src/main/pftvarcon.F90 b/components/elm/src/main/pftvarcon.F90 index 1b06a49cf2f6..dc5d837472ae 100644 --- a/components/elm/src/main/pftvarcon.F90 +++ b/components/elm/src/main/pftvarcon.F90 @@ -318,7 +318,7 @@ module pftvarcon real(r8), allocatable :: nonvascular(:) ! nonvascular lifeform flag (0 = vascular, 1 = moss, 2 = lichen) real(r8), allocatable :: needleleaf(:) ! needleleaf lifeform flag (0 = broadleaf, 1 = needleleaf) real(r8), allocatable :: graminoid(:) ! graminoid lifeform flag (0 = nonvascular+woody+crop+percrop, 1 = graminoid) - real(r8), allocatable :: generic_crop(:) ! generic_crop (0 = non_crop or prognostic crop, 1 = generic crop, i.e. crop when use_crop=false) + real(r8), allocatable :: iscft(:) ! crop function type flag (0 = non_crop or generic crop, i.e. crop when use_crop=false, 1 = prognostic crop with cft created) real(r8), allocatable :: nfixer(:) ! nitrogen fixer flag (0 = inable, 1 = able to nitrogen fixation from atm. N2) @@ -641,7 +641,7 @@ subroutine pftconrd allocate( climatezone (0:mxpft) ) allocate( nonvascular (0:mxpft) ) allocate( graminoid (0:mxpft) ) - allocate( generic_crop (0:mxpft) ) + allocate( iscft (0:mxpft) ) allocate( needleleaf (0:mxpft) ) allocate( nfixer (0:mxpft) ) @@ -1127,23 +1127,13 @@ subroutine pftconrd end if end if - call ncd_io('iscft', generic_crop, 'read', ncid, readvar=readv) ! read-in is 'CFT' or not for crop type + call ncd_io('iscft', iscft, 'read', ncid, readvar=readv) ! read-in is 'CFT' or not for crop type if ( .not. readv ) then if (PFT_DEFAULT) then - generic_crop(:) = 0 ! will assign a value below + iscft(:) = 0 ! will assign a value below else call endrun(msg='ERROR: error in reading in user-defined pft data'//errMsg(__FILE__,__LINE__)) end if - else - do i = 0, npft-1 - if ((crop(i)>=1 .or. percrop(i)>=1) .and. generic_crop(i)==0) then - ! at this moment, read-in 'generic_crop' is actually 'iscft' (i.e. crop as CFT or not) - ! So must re-assign - generic_crop(i) = 1 - else - generic_crop(i) = 0 - end if - end do end if call ncd_pio_closefile(ncid) @@ -1243,7 +1233,7 @@ subroutine pftconrd ! when not using those indexing of PFT orders anymore in other codes than here. needleleaf(noveg+1:ndllf_dcd_brl_tree) = 1 graminoid(nc3_arctic_grass:nc4_grass) = 1 - generic_crop(nc3crop:nc3irrig) = 1 + iscft(npcropmin:max(npcropmax,nppercropmax)) = 1 nfixer(nsoybean) = 1 nfixer(nsoybeanirrig) = 1 @@ -1280,13 +1270,16 @@ subroutine pftconrd ncft0 = -1 noncropmax = 0 do i = 0, npft-1 - if (crop(i)>=1 .or. percrop(i)>=1 .or. generic_crop(i)>=1) then - numcft = numcft + 1 + if (crop(i)>=1 .or. percrop(i)>=1 .or. iscft(i)>=1) then + numcft = numcft + 1 ! includes generic_crop, while cft_size NOT (???? todo checking) if(use_crop) then - ! if 'generic_crop' specifically defined, + + ! the following assumes that all crop pfts are in a block + + ! if 'generic crop' (crop=1) specifically flagged by iscft=0 ! 'crop' will not be counted into prognostic - if (crop(i)>=1 .and. generic_crop(i)==0) then + if (crop(i)>=1 .and. iscft(i)==1) then npcropmax = i if(npcropmin<=0) npcropmin = i end if @@ -1299,11 +1292,9 @@ subroutine pftconrd end if else - if(crop(i)>=1 .or. generic_crop(i)>=1) then - ! in case either 'crop' or 'generic_crop' or both defined when not use_crop=.true. - generic_crop(i) = 1 - else - generic_crop(i) = 0 + if(crop(i)>=1 .or. percrop(i)>=1) then + ! in case either 'crop' or 'generic crop' or both defined, it must be generic, when not use_crop=.true. + iscft(i) = 0 end if end if @@ -1322,7 +1313,7 @@ subroutine pftconrd ! need to check 'noveg' if ( woody(i)<=0 .and. graminoid(i)<=0 .and. nonvascular(i)<=0 .and. & - generic_crop(i)<=0 .and. crop(i)<=0 .and. percrop(i)<=0) then + iscft(i)<=0 .and. crop(i)<=0 .and. percrop(i)<=0) then if (noveg>=0) then ! not yet support multiple non-vegetated PFT ! this also will catch error of no actual PFT if npft>1 @@ -1375,23 +1366,23 @@ subroutine pftconrd if ( .not. use_fates ) then do i = 0, mxpft if (i == noveg) then - if ( (nonvascular(i)+woody(i)+graminoid(i)+generic_crop(i)+crop(i)+percrop(i)) >= 1 .or. & + if ( (nonvascular(i)+woody(i)+graminoid(i)+max(iscft(i),crop(i)+percrop(i))) >= 1 .or. & (needleleaf(i)+evergreen(i)+stress_decid(i)+season_decid(i)+nfixer(i)) >= 1 ) then print *, 'ERROR: Incorrect not-vegetated PFT flags: ', i, ' ', trim(pftname(i)) call endrun(msg=' ERROR: not_vegetated has at least one positive PFT flag '//errMsg(__FILE__, __LINE__)) end if - else if ( (nonvascular(i)+woody(i)+graminoid(i)+generic_crop(i)+crop(i)+percrop(i)) >= 1) then - if (nonvascular(i) >= 1 .and. (woody(i)+graminoid(i)+generic_crop(i)+crop(i)+percrop(i)) >= 1) then + else if ( (nonvascular(i)+woody(i)+graminoid(i)+max(iscft(i),crop(i)+percrop(i))) >= 1) then + if (nonvascular(i) >= 1 .and. (woody(i)+graminoid(i)+max(iscft(i),crop(i)+percrop(i))) >= 1) then print *, 'ERROR: Incorrect nonvasculr PFT flags: ', i, ' ', trim(pftname(i)) call endrun(msg=' ERROR: nonvascular PFT cannot be any of woody/graminoid/crop type '//errMsg(__FILE__, __LINE__)) - else if (woody(i) >= 1 .and. (nonvascular(i)+graminoid(i)+generic_crop(i)+crop(i)+percrop(i)) >= 1) then + else if (woody(i) >= 1 .and. (nonvascular(i)+graminoid(i)+max(iscft(i),crop(i)+percrop(i))) >= 1) then print *, 'ERROR: Incorrect woody PFT flags: ', i, ' ', trim(pftname(i)) call endrun(msg=' ERROR: woody PFT cannot be any of nonvascular/graminoid/crop type - '//errMsg(__FILE__, __LINE__)) - else if (graminoid(i) >= 1 .and. (nonvascular(i)+woody(i)+generic_crop(i)+crop(i)+percrop(i)) >=1 ) then + else if (graminoid(i) >= 1 .and. (nonvascular(i)+woody(i)+max(iscft(i),crop(i)+percrop(i))) >=1 ) then print *, 'ERROR: Incorrect graminoid PFT flags: ', i, ' ', trim(pftname(i)) call endrun(msg=' ERROR: graminoid PFT cannot be any of nonvascular/woody/crop type - '//errMsg(__FILE__, __LINE__)) - else if ( (generic_crop(i)+crop(i)+percrop(i)) >= 1 .and. (nonvascular(i)+woody(i)+graminoid(i)) >= 1) then + else if ( (max(iscft(i),crop(i)+percrop(i))) >= 1 .and. (nonvascular(i)+woody(i)+graminoid(i)) >= 1) then print *, 'ERROR: Incorrect crop PFT flags: ', i, ' ', trim(pftname(i)) call endrun(msg=' ERROR: crop PFT cannot be any of nonvascular/woody/graminoid type - '//errMsg(__FILE__, __LINE__)) end if @@ -1417,11 +1408,11 @@ subroutine pftconrd if (masterproc) then write(iulog,*) write(iulog,*) 'Using PFT physiological parameters from: ', paramfile - write(iulog,*) ' -- index -- name -- climate zone -- -- woody -- -- needleleaf -- -- evergreen -- -- stress_decid -- -- season_decid -- -- graminoid-- -- generic_crop -- -- crop -- -- perennial crop -- -- nfixer --' + write(iulog,*) ' -- index -- name -- climate zone -- -- woody -- -- needleleaf -- -- evergreen -- -- stress_decid -- -- season_decid -- -- graminoid-- -- iscft -- -- crop -- -- perennial crop -- -- nfixer --' do i = 0, npft-1 write(iulog,*) i, pftname(i), int(climatezone(i)), int(woody(i)), int(needleleaf(i)), & int(evergreen(i)), int(stress_decid(i)), int(season_decid(i)), & - int(graminoid(i)), int(generic_crop(i)), int(crop(i)), int(percrop(i)), int(nfixer(i)) + int(graminoid(i)), int(iscft(i)), int(crop(i)), int(percrop(i)), int(nfixer(i)) end do write(iulog,*) end if diff --git a/components/elm/src/main/surfrdMod.F90 b/components/elm/src/main/surfrdMod.F90 index 1a957e8cd38a..d61ac41e38e4 100755 --- a/components/elm/src/main/surfrdMod.F90 +++ b/components/elm/src/main/surfrdMod.F90 @@ -1265,6 +1265,8 @@ subroutine surfrd_veg_all(begg, endg, ncid, ns,ntpu) do nl = begg,endg do t = 1, max_topounits + ! (TODO) the following assumes that rainfed/irrigated crop are ordered side by side + ! indexing is fixed wt_cft(nl,t,nc3crop) = wt_cft(nl,t,nc3crop) + wt_cft(nl,t,nc3irrig) wt_cft(nl,t,nc3irrig) = 0._r8 wt_cft(nl,t,ncorn) = wt_cft(nl,t,ncorn) + wt_cft(nl,t,ncornirrig) diff --git a/components/elm/src/main/surfrdUtilsMod.F90 b/components/elm/src/main/surfrdUtilsMod.F90 index 1e58b5174afa..c581f968aaf6 100644 --- a/components/elm/src/main/surfrdUtilsMod.F90 +++ b/components/elm/src/main/surfrdUtilsMod.F90 @@ -310,7 +310,7 @@ subroutine collapse_crop_types(wt_cft, fert_cft, fert_p_cft, begg, endg, verbose use elm_varctl , only : irrigate use elm_varpar , only : cft_lb, cft_ub, cft_size use pftvarcon , only: is_pft_known_to_model - use pftvarcon , only : npcropmax, mergetoelmpft, npcropmin + use pftvarcon , only : npcropmax, mergetoelmpft use topounit_varcon , only : max_topounits ! TKT use GridcellType , only : grc_pp ! TKT ! From 0dcb1658da7ecc13c83e3a0b09026151b69ba77e Mon Sep 17 00:00:00 2001 From: Peter Thornton Date: Sun, 19 May 2024 13:04:00 -0400 Subject: [PATCH 343/451] Bug fix to remove topi, topf and use max_topounits, plus cleanup --- components/elm/src/main/surfrdUtilsMod.F90 | 33 ++++++++-------------- 1 file changed, 12 insertions(+), 21 deletions(-) diff --git a/components/elm/src/main/surfrdUtilsMod.F90 b/components/elm/src/main/surfrdUtilsMod.F90 index c581f968aaf6..2c1e42559dac 100644 --- a/components/elm/src/main/surfrdUtilsMod.F90 +++ b/components/elm/src/main/surfrdUtilsMod.F90 @@ -36,7 +36,7 @@ subroutine check_sums_equal_1_3d(arr, lb, name, caller) ! Confirm that sum(arr(n,:)) == 1 for all n. If this isn't true for any n, abort with a message. ! ! Uses - use topounit_varcon, only : max_topounits, has_topounit + use topounit_varcon, only : max_topounits ! !ARGUMENTS: integer , intent(in) :: lb ! lower bound of the first dimension of arr @@ -123,7 +123,7 @@ subroutine convert_cft_to_pft( begg, endg, cftsize, wt_cft ) ! a crop landunit, and put them on the vegetated landunit. ! !USES: use elm_varsur , only : wt_lunit, wt_nat_patch - use elm_varpar , only : cft_size, surfpft_size + use elm_varpar , only : cft_size use elm_varpar , only : natpft_size use landunit_varcon , only : istsoil, istcrop use topounit_varcon , only : max_topounits @@ -170,7 +170,6 @@ subroutine convert_pft_to_cft( begg, endg ) ! the new crop landunit ! !USES: use elm_varsur , only : wt_lunit, wt_nat_patch, wt_cft - use elm_varpar , only : cft_size, surfpft_size use elm_varpar , only : cft_size, cft_lb, cft_ub, surfpft_lb, surfpft_ub use landunit_varcon , only : istsoil, istcrop use topounit_varcon , only : max_topounits @@ -261,7 +260,6 @@ subroutine collapse_crop_var(crop_var, begg, endg) use elm_varpar, only: cft_lb, cft_ub, cft_size use pftvarcon , only: is_pft_known_to_model use topounit_varcon , only : max_topounits ! TKT - use GridcellType, only : grc_pp ! ! !ARGUMENTS: ! Use begg and endg rather than 'bounds', because bounds may not be @@ -311,8 +309,7 @@ subroutine collapse_crop_types(wt_cft, fert_cft, fert_p_cft, begg, endg, verbose use elm_varpar , only : cft_lb, cft_ub, cft_size use pftvarcon , only: is_pft_known_to_model use pftvarcon , only : npcropmax, mergetoelmpft - use topounit_varcon , only : max_topounits ! TKT - use GridcellType , only : grc_pp ! TKT + use topounit_varcon , only : max_topounits ! ! !ARGUMENTS: @@ -323,16 +320,15 @@ subroutine collapse_crop_types(wt_cft, fert_cft, fert_p_cft, begg, endg, verbose ! Weight and fertilizer of each CFT in each grid cell; dimensioned [g, cft_lb:cft_ub] ! This array is modified in-place - real(r8), intent(inout) :: wt_cft(begg:,1:, cft_lb:) !TKT - real(r8), intent(inout) :: fert_cft(begg:,1:, cft_lb:) !TKT + real(r8), intent(inout) :: wt_cft(begg:,1:, cft_lb:) + real(r8), intent(inout) :: fert_cft(begg:,1:, cft_lb:) real(r8), intent(inout) :: fert_p_cft(begg:, 1:, cft_lb:) logical, intent(in) :: verbose ! If true, print some extra information ! ! !LOCAL VARIABLES: - integer :: g, t,t2 ! TKT + integer :: g, t,t2 integer :: m - !integer, allocatable :: ntpu(:) ! To store number of topounits per grid TKT real(r8) :: wt_cft_to real(r8) :: wt_cft_from real(r8) :: wt_cft_merge @@ -340,7 +336,7 @@ subroutine collapse_crop_types(wt_cft, fert_cft, fert_p_cft, begg, endg, verbose character(len=*), parameter :: subname = 'collapse_crop_types' !----------------------------------------------------------------------- - SHR_ASSERT_ALL((ubound(wt_cft) == (/endg,max_topounits, cft_ub/)), errMsg(__FILE__, __LINE__)) ! TKT + SHR_ASSERT_ALL((ubound(wt_cft) == (/endg,max_topounits, cft_ub/)), errMsg(__FILE__, __LINE__)) SHR_ASSERT_ALL((ubound(fert_cft) == (/endg,max_topounits, cft_ub/)), errMsg(__FILE__, __LINE__)) SHR_ASSERT_ALL((ubound(fert_p_cft) == (/endg,max_topounits, cft_ub/)), errMsg(__FILE__, __LINE__)) @@ -353,14 +349,12 @@ subroutine collapse_crop_types(wt_cft, fert_cft, fert_p_cft, begg, endg, verbose ! ------------------------------------------------------------------------ ! If not using irrigation, merge irrigated CFTs into rainfed CFTs ! ------------------------------------------------------------------------ - !allocate(ntpu(begg:endg)) if (.not. irrigate) then if (verbose .and. masterproc) then write(iulog,*) trim(subname)//' crop=.T. and irrigate=.F., so merging irrigated pfts with rainfed' end if do g = begg, endg - !ntpu(g) = grc_pp%ntopounits(g) ! Left Hand Side: merged rainfed+irrigated crop pfts from nc3crop to ! npcropmax-1, stride 2 ! Right Hand Side: rainfed crop pfts from nc3crop to npcropmax-1, @@ -369,16 +363,14 @@ subroutine collapse_crop_types(wt_cft, fert_cft, fert_p_cft, begg, endg, verbose ! stride 2 ! where stride 2 means "every other" - do t = grc_pp%topi(g), grc_pp%topf(g) ! TKT - t2 = t - grc_pp%topi(g) + 1 - + do t2 = 1, max_topounits wt_cft(g,t2, cft_lb:cft_ub-1:2) = & - wt_cft(g,t2, cft_lb:cft_ub-1:2) + wt_cft(g,t2, cft_lb+1:cft_ub:2) ! TKT + wt_cft(g,t2, cft_lb:cft_ub-1:2) + wt_cft(g,t2, cft_lb+1:cft_ub:2) wt_cft(g,t2, cft_lb+1:cft_ub:2) = 0._r8 - end do ! TKT + end do end do - call check_sums_equal_1_3d(wt_cft, begg, 'wt_cft', subname//': irrigation') ! TKT + call check_sums_equal_1_3d(wt_cft, begg, 'wt_cft', subname//': irrigation') end if ! ------------------------------------------------------------------------ @@ -412,8 +404,7 @@ subroutine collapse_crop_types(wt_cft, fert_cft, fert_p_cft, begg, endg, verbose end do end do - call check_sums_equal_1_3d(wt_cft, begg, 'wt_cft', subname//': mergetoelmpft') ! TKT - !deallocate(ntpu) + call check_sums_equal_1_3d(wt_cft, begg, 'wt_cft', subname//': mergetoelmpft') end subroutine collapse_crop_types end module surfrdUtilsMod From ee819167f2d14b08f6046050902ce30a299e7518 Mon Sep 17 00:00:00 2001 From: Fengming Yuan Date: Sun, 21 Jul 2024 13:02:28 -0400 Subject: [PATCH 344/451] Move a few array allocations to after pftconrd(). (#6) --- components/elm/src/main/elm_initializeMod.F90 | 25 ++++++++----------- 1 file changed, 11 insertions(+), 14 deletions(-) diff --git a/components/elm/src/main/elm_initializeMod.F90 b/components/elm/src/main/elm_initializeMod.F90 index 9fe4959c241d..b7fe36f24ed9 100755 --- a/components/elm/src/main/elm_initializeMod.F90 +++ b/components/elm/src/main/elm_initializeMod.F90 @@ -269,10 +269,10 @@ subroutine initialize1( ) allocate (wt_lunit (begg:endg,1:max_topounits, max_lunit )) allocate (urban_valid (begg:endg,1:max_topounits )) - allocate (wt_nat_patch (begg:endg,1:max_topounits, surfpft_lb:surfpft_ub )) - allocate (wt_cft (begg:endg,1:max_topounits, cft_lb:cft_ub )) - allocate (fert_cft (begg:endg,1:max_topounits, cft_lb:cft_ub )) - allocate (fert_p_cft (begg:endg,1:max_topounits, cft_lb:cft_ub )) + !allocate (wt_nat_patch (begg:endg,1:max_topounits, surfpft_lb:surfpft_ub )) + !allocate (wt_cft (begg:endg,1:max_topounits, cft_lb:cft_ub )) + !allocate (fert_cft (begg:endg,1:max_topounits, cft_lb:cft_ub )) + !allocate (fert_p_cft (begg:endg,1:max_topounits, cft_lb:cft_ub )) if (create_glacier_mec_landunit) then allocate (wt_glc_mec (begg:endg,1:max_topounits, maxpatch_glcmec)) allocate (topo_glc_mec(begg:endg,1:max_topounits, maxpatch_glcmec)) @@ -294,16 +294,13 @@ subroutine initialize1( ) ! Independent of model resolution, Needs to stay before surfrd_get_data call pftconrd() - ! by user-defined PFT (numbers and names), 'numpft/mxpft_nc' changed and other indices - ! a few arrays had been allocated in elm_initializedMod.F90:L266-268 and require redo after this 'pftconrd' call - if ((numpft/=mxpft .or. numpft/=numveg) .or. (mxpft_nc/=24 .or. mxpft_nc/=numveg)) then - if (associated(wt_nat_patch)) deallocate(wt_nat_patch) - allocate (wt_nat_patch (begg:endg,1:max_topounits, surfpft_lb:surfpft_ub )) - if (associated(wt_cft)) deallocate(wt_cft) - allocate (wt_cft (begg:endg,1:max_topounits, cft_lb:cft_ub )) - if (associated(fert_cft)) deallocate(fert_cft) - allocate (fert_cft (begg:endg,1:max_topounits, cft_lb:cft_ub )) - endif + ! if by user-defined PFT (numbers and names), 'numpft/mxpft_nc' may be changed including other derived indices + ! + ! a few arrays allocation previously done above is moved here i.e. after this 'pftconrd' call + allocate (wt_nat_patch (begg:endg,1:max_topounits, surfpft_lb:surfpft_ub )) + allocate (wt_cft (begg:endg,1:max_topounits, cft_lb:cft_ub )) + allocate (fert_cft (begg:endg,1:max_topounits, cft_lb:cft_ub )) + allocate (fert_p_cft (begg:endg,1:max_topounits, cft_lb:cft_ub )) call soilorder_conrd() From d2164819c243e6760e60d1d3d11961a4215a7e9e Mon Sep 17 00:00:00 2001 From: Peter Thornton Date: Sun, 21 Jul 2024 22:07:12 -0400 Subject: [PATCH 345/451] Convert iscft() from real(r8) to logical. This is a demonstration of how the same approach could be used for other flags that are used as logicals but allocated as reals or integers. [BFB] --- .../elm/src/biogeochem/AllocationMod.F90 | 36 +++++++-------- .../src/biogeochem/CNAllocationBetrMod.F90 | 38 +++++++--------- .../elm/src/biogeochem/CNCarbonFluxType.F90 | 14 +++--- .../elm/src/biogeochem/CNCarbonStateType.F90 | 4 +- .../src/biogeochem/CNGapMortalityBeTRMod.F90 | 4 +- .../src/biogeochem/CNNStateUpdate1BeTRMod.F90 | 8 ++-- .../src/biogeochem/CNNStateUpdate2BeTRMod.F90 | 2 +- .../elm/src/biogeochem/CNNitrogenFluxType.F90 | 1 - .../src/biogeochem/CNNitrogenStateType.F90 | 2 +- .../elm/src/biogeochem/CNPhenologyBeTRMod.F90 | 4 +- .../src/biogeochem/CarbonStateUpdate1Mod.F90 | 18 ++++---- .../src/biogeochem/CarbonStateUpdate2Mod.F90 | 2 +- components/elm/src/biogeochem/CropType.F90 | 2 +- .../elm/src/biogeochem/DryDepVelocity.F90 | 2 +- components/elm/src/biogeochem/FireMod.F90 | 12 ++--- .../elm/src/biogeochem/GapMortalityMod.F90 | 10 ++--- .../elm/src/biogeochem/GrowthRespMod.F90 | 2 +- .../elm/src/biogeochem/MaintenanceRespMod.F90 | 2 +- .../biogeochem/NitrogenStateUpdate1Mod.F90 | 8 ++-- .../biogeochem/NitrogenStateUpdate2Mod.F90 | 2 +- .../src/biogeochem/PhenologyFluxLimitMod.F90 | 22 ++++----- .../elm/src/biogeochem/PhenologyMod.F90 | 22 +++------ .../biogeochem/PhosphorusStateUpdate1Mod.F90 | 8 ++-- .../biogeochem/PhosphorusStateUpdate2Mod.F90 | 2 +- .../src/biogeochem/PrecisionControlMod.F90 | 4 +- .../elm/src/biogeochem/RootDynamicsMod.F90 | 2 +- .../elm/src/biogeochem/VOCEmissionMod.F90 | 2 +- .../elm/src/biogeochem/VegStructUpdateMod.F90 | 4 +- components/elm/src/biogeophys/SedYieldMod.F90 | 4 +- .../elm/src/data_types/VegetationDataType.F90 | 26 +++++------ .../data_types/VegetationPropertiesType.F90 | 4 +- components/elm/src/main/filterMod.F90 | 2 +- components/elm/src/main/pftvarcon.F90 | 45 +++++++++++-------- 33 files changed, 157 insertions(+), 163 deletions(-) diff --git a/components/elm/src/biogeochem/AllocationMod.F90 b/components/elm/src/biogeochem/AllocationMod.F90 index 0110367f59ce..141194397fb0 100644 --- a/components/elm/src/biogeochem/AllocationMod.F90 +++ b/components/elm/src/biogeochem/AllocationMod.F90 @@ -585,7 +585,7 @@ subroutine Allocation1_PlantNPDemand (bounds, num_soilc, filter_soilc, num_soilp mr = leaf_mr(p) + froot_mr(p) if (woody(ivt(p)) >= 1.0_r8) then mr = mr + livestem_mr(p) + livecroot_mr(p) - else if (iscft(ivt(p)) >= 1) then + else if (iscft(ivt(p))) then if (croplive(p)) mr = mr + livestem_mr(p) + grain_mr(p) end if @@ -672,7 +672,7 @@ subroutine Allocation1_PlantNPDemand (bounds, num_soilc, filter_soilc, num_soilp f5 = 0._r8 ! continued intializations from above - if (iscft(ivt(p)) >= 1) then ! skip 2 generic crops + if (iscft(ivt(p))) then ! skip 2 generic crops if (croplive(p) .and. percrop(ivt(p)) == 0.0_r8 ) then ! same phases appear in subroutine CropPhenology @@ -822,7 +822,7 @@ subroutine Allocation1_PlantNPDemand (bounds, num_soilc, filter_soilc, num_soilp p_allometry(p) = 1._r8/cpl + f1/cpfr + (f3*f4*(1._r8+f2))/cplw + & (f3*(1._r8-f4)*(1._r8+f2))/cpdw - else if (iscft(ivt(p)) >= 1) then ! skip generic crops + else if (iscft(ivt(p))) then ! skip generic crops cng = graincn(ivt(p)) cpg = graincp(ivt(p)) c_allometry(p) = (1._r8+g1)*(1._r8+f1+f5+f3*(1._r8+f2)) @@ -852,10 +852,10 @@ subroutine Allocation1_PlantNPDemand (bounds, num_soilc, filter_soilc, num_soilp ! retransn pool has N from leaves, stems, and roots for ! retranslocation - if (iscft(ivt(p)) >= 1 .and. grain_flag(p) == 1._r8) then + if (iscft(ivt(p)) .and. grain_flag(p) == 1._r8) then avail_retransn(p) = plant_ndemand(p) avail_retransp(p) = plant_pdemand(p) - else if (iscft(ivt(p)) < 1 .and. annsum_potential_gpp(p) > 0._r8) then + else if ((.not. iscft(ivt(p))) .and. annsum_potential_gpp(p) > 0._r8) then avail_retransn(p) = (annmax_retransn(p)/2._r8)*(gpp(p)/annsum_potential_gpp(p))/dt avail_retransp(p) = (annmax_retransp(p)/2._r8)*(gpp(p)/annsum_potential_gpp(p))/dt else @@ -2142,7 +2142,7 @@ subroutine Allocation3_PlantCNPAlloc (bounds , & fcur = fcur2(ivt(p)) - if (iscft(ivt(p)) >= 1) then ! skip 2 generic crops + if (iscft(ivt(p))) then ! skip 2 generic crops if (croplive(p)) then f1 = aroot(p) / aleaf(p) f3 = astem(p) / aleaf(p) @@ -2328,7 +2328,7 @@ subroutine Allocation3_PlantCNPAlloc (bounds , & fcur = fcur2(ivt(p)) - if (iscft(ivt(p)) >= 1) then ! skip 2 generic crops + if (iscft(ivt(p))) then ! skip 2 generic crops if (croplive(p)) then f1 = aroot(p) / aleaf(p) f3 = astem(p) / aleaf(p) @@ -2345,10 +2345,10 @@ subroutine Allocation3_PlantCNPAlloc (bounds , & sminn_to_npool(p) = sminn_to_plant_patch(p) sminp_to_ppool(p) = sminp_to_plant_patch(p) - if (iscft(ivt(p)) >= 1 .and. grain_flag(p) == 1._r8) then + if (iscft(ivt(p)) .and. grain_flag(p) == 1._r8) then avail_retransn(p) = retransn(p)/dt avail_retransp(p) = retransp(p)/dt - else if (iscft(ivt(p)) < 1 .and. annsum_potential_gpp(p) > 0._r8) then + else if ((.not. iscft(ivt(p))) .and. annsum_potential_gpp(p) > 0._r8) then avail_retransn(p) = (annmax_retransn(p)/2._r8)*(gpp(p)/annsum_potential_gpp(p))/dt avail_retransp(p) = (annmax_retransp(p)/2._r8)*(gpp(p)/annsum_potential_gpp(p))/dt else @@ -2374,7 +2374,7 @@ subroutine Allocation3_PlantCNPAlloc (bounds , & mr = leaf_mr(p) + froot_mr(p) if (woody(ivt(p)) >= 1.0_r8) then mr = mr + livestem_mr(p) + livecroot_mr(p) - else if (iscft(ivt(p)) >= 1) then + else if (iscft(ivt(p))) then if (croplive(p)) mr = mr + livestem_mr(p) + grain_mr(p) end if @@ -2473,7 +2473,7 @@ subroutine Allocation3_PlantCNPAlloc (bounds , & p_allometry(p) = 1._r8/cpl + f1/cpfr + (f3*f4*(1._r8+f2))/cplw + & (f3*(1._r8-f4)*(1._r8+f2))/cpdw - else if (iscft(ivt(p)) >= 1) then ! skip generic crops + else if (iscft(ivt(p))) then ! skip generic crops cng = graincn(ivt(p)) cpg = graincp(ivt(p)) c_allometry(p) = (1._r8+g1)*(1._r8+f1+f5+f3*(1._r8+f2)) @@ -2559,7 +2559,7 @@ subroutine Allocation3_PlantCNPAlloc (bounds , & cpool_to_xsmrpool(p) = cpool_to_xsmrpool(p) + nlc * f2 * f3 * (1._r8 - f4) * fcur * (1 + g1) cpool_to_xsmrpool(p) = cpool_to_xsmrpool(p) + nlc * f2 * f3 * (1._r8 - f4) * (1._r8 - fcur) * (1 + g1) end if - if (iscft(ivt(p)) >= 1) then ! skip 2 generic crops + if (iscft(ivt(p))) then ! skip 2 generic crops cpool_to_xsmrpool(p) = cpool_to_xsmrpool(p) + nlc * f3 * f4 * fcur * (1 + g1) cpool_to_xsmrpool(p) = cpool_to_xsmrpool(p) + nlc * f3 * f4 * (1._r8 - fcur) * (1 + g1) cpool_to_xsmrpool(p) = cpool_to_xsmrpool(p) + nlc * f3 * (1._r8 - f4) * fcur * (1 + g1) @@ -2590,7 +2590,7 @@ subroutine Allocation3_PlantCNPAlloc (bounds , & cpool_to_deadcrootc(p) = nlc * f2 * f3 * (1._r8 - f4) * fcur cpool_to_deadcrootc_storage(p) = nlc * f2 * f3 * (1._r8 - f4) * (1._r8 - fcur) end if - if (iscft(ivt(p)) >= 1) then ! skip 2 generic crops + if (iscft(ivt(p))) then ! skip 2 generic crops cpool_to_livestemc(p) = nlc * f3 * f4 * fcur cpool_to_livestemc_storage(p) = nlc * f3 * f4 * (1._r8 - fcur) cpool_to_deadstemc(p) = nlc * f3 * (1._r8 - f4) * fcur @@ -2643,7 +2643,7 @@ subroutine Allocation3_PlantCNPAlloc (bounds , & npool_to_deadcrootn(p) = (nlc * f2 * f3 * (1._r8 - f4) / cndw) * fcur npool_to_deadcrootn_storage(p) = (nlc * f2 * f3 * (1._r8 - f4) / cndw) * (1._r8 - fcur) end if - if (iscft(ivt(p)) >= 1) then ! skip 2 generic crops + if (iscft(ivt(p))) then ! skip 2 generic crops cng = graincn(ivt(p)) npool_to_livestemn(p) = (nlc * f3 * f4 / cnlw) * fcur npool_to_livestemn_storage(p) = (nlc * f3 * f4 / cnlw) * (1._r8 - fcur) @@ -2687,7 +2687,7 @@ subroutine Allocation3_PlantCNPAlloc (bounds , & ppool_to_deadcrootp(p) = (nlc * f2 * f3 * (1._r8 - f4) / cpdw)* fcur ppool_to_deadcrootp_storage(p) = (nlc * f2 * f3 * (1._r8 - f4) / cpdw)* (1._r8 - fcur) end if - if (iscft(ivt(p)) >= 1) then ! skip 2 generic crops + if (iscft(ivt(p))) then ! skip 2 generic crops cpg = graincp(ivt(p)) ppool_to_livestemp(p) = (nlc * f3 * f4 / cplw) * fcur ppool_to_livestemp_storage(p) = (nlc * f3 * f4 / cplw) * (1._r8 -fcur) @@ -2717,7 +2717,7 @@ subroutine Allocation3_PlantCNPAlloc (bounds , & gresp_storage = gresp_storage + cpool_to_livecrootc_storage(p) gresp_storage = gresp_storage + cpool_to_deadcrootc_storage(p) end if - if (iscft(ivt(p)) >= 1) then ! skip 2 generic crops + if (iscft(ivt(p))) then ! skip 2 generic crops gresp_storage = gresp_storage + cpool_to_livestemc_storage(p) gresp_storage = gresp_storage + cpool_to_grainc_storage(p) end if @@ -2771,7 +2771,7 @@ subroutine Allocation3_PlantCNPAlloc (bounds , & npool_to_deadcrootn(p) = cpool_to_deadcrootc(p) / cndw npool_to_deadcrootn_storage(p) = cpool_to_deadcrootc_storage(p) / cndw end if - if (iscft(ivt(p)) >= 1) then ! skip 2 generic crops + if (iscft(ivt(p))) then ! skip 2 generic crops cng = graincn(ivt(p)) supplement_to_plantn(p) = supplement_to_plantn(p) + cpool_to_livestemc(p) / cnlw - npool_to_livestemn(p) supplement_to_plantn(p) = supplement_to_plantn(p) + cpool_to_livestemc_storage(p) / cnlw & @@ -2843,7 +2843,7 @@ subroutine Allocation3_PlantCNPAlloc (bounds , & ppool_to_deadcrootp(p) = cpool_to_deadcrootc(p) / cpdw ppool_to_deadcrootp_storage(p) = cpool_to_deadcrootc_storage(p) / cpdw end if - if (iscft(ivt(p)) >= 1) then ! skip 2 generic crops + if (iscft(ivt(p))) then ! skip 2 generic crops cpg = graincp(ivt(p)) supplement_to_plantp(p) = supplement_to_plantp(p) + max(cpool_to_livestemc(p) / cplw & - ppool_to_livestemp(p),0._r8) diff --git a/components/elm/src/biogeochem/CNAllocationBetrMod.F90 b/components/elm/src/biogeochem/CNAllocationBetrMod.F90 index cc8b72046a17..8cfc342bb404 100644 --- a/components/elm/src/biogeochem/CNAllocationBetrMod.F90 +++ b/components/elm/src/biogeochem/CNAllocationBetrMod.F90 @@ -645,7 +645,7 @@ subroutine Allocation1_PlantNPDemand (bounds, num_soilc, filter_soilc, num_soilp mr = leaf_mr(p) + froot_mr(p) if (woody(ivt(p)) >= 1.0_r8) then mr = mr + livestem_mr(p) + livecroot_mr(p) - else if (iscft(ivt(p)) >= 1) then + else if (iscft(ivt(p))) then if (croplive(p)) mr = mr + livestem_mr(p) + grain_mr(p) end if @@ -726,7 +726,7 @@ subroutine Allocation1_PlantNPDemand (bounds, num_soilc, filter_soilc, num_soilp f5 = 0._r8 ! continued intializations from above - if (iscft(ivt(p)) >= 1) then ! skip 2 generic crops + if (iscft(ivt(p))) then ! skip 2 generic crops if (croplive(p)) then ! same phases appear in subroutine CropPhenology @@ -859,7 +859,7 @@ subroutine Allocation1_PlantNPDemand (bounds, num_soilc, filter_soilc, num_soilp p_allometry(p) = 1._r8/cpl + f1/cpfr + (f3*f4*(1._r8+f2))/cplw + & (f3*(1._r8-f4)*(1._r8+f2))/cpdw - else if (iscft(ivt(p)) >= 1) then ! skip generic crops + else if (iscft(ivt(p))) then ! skip generic crops cng = graincn(ivt(p)) cpg = graincp(ivt(p)) c_allometry(p) = (1._r8+g1)*(1._r8+f1+f5+f3*(1._r8+f2)) @@ -889,10 +889,10 @@ subroutine Allocation1_PlantNPDemand (bounds, num_soilc, filter_soilc, num_soilp ! retransn pool has N from leaves, stems, and roots for ! retranslocation - if (iscft(ivt(p)) >= 1 .and. grain_flag(p) == 1._r8) then + if (iscft(ivt(p)) .and. grain_flag(p) == 1._r8) then avail_retransn(p) = plant_ndemand(p) avail_retransp(p) = plant_pdemand(p) - else if (iscft(ivt(p)) < 1 .and. annsum_potential_gpp(p) > 0._r8) then + else if ((.not. iscft(ivt(p))) .and. annsum_potential_gpp(p) > 0._r8) then avail_retransn(p) = (annmax_retransn(p)/2._r8)*(gpp(p)/annsum_potential_gpp(p))/dt avail_retransp(p) = (annmax_retransp(p)/2._r8)*(gpp(p)/annsum_potential_gpp(p))/dt else @@ -1105,14 +1105,10 @@ subroutine Allocation3_PlantCNPAlloc (bounds , & use shr_sys_mod , only: shr_sys_flush use elm_varctl , only: iulog,cnallocate_carbon_only,cnallocate_carbonnitrogen_only,& cnallocate_carbonphosphorus_only -! use pftvarcon , only: iscft, declfact, bfact, aleaff, arootf, astemf -! use pftvarcon , only: arooti, fleafi, allconsl, allconss, grperc, grpnow, nsoybean use pftvarcon , only: noveg use pftvarcon , only: iscft, grperc, grpnow use elm_varpar , only: nlevdecomp !!nlevsoi, use elm_varcon , only: nitrif_n2o_loss_frac, secspday -! use landunit_varcon , only: istsoil, istcrop -! use elm_time_manager , only: get_step_size ! ! !ARGUMENTS: type(bounds_type) , intent(in) :: bounds @@ -1393,7 +1389,7 @@ subroutine Allocation3_PlantCNPAlloc (bounds , & fcur = fcur2(ivt(p)) - if (iscft(ivt(p)) >= 1) then ! skip 2 generic crops + if (iscft(ivt(p))) then ! skip 2 generic crops if (croplive(p)) then f1 = aroot(p) / aleaf(p) f3 = astem(p) / aleaf(p) @@ -1412,10 +1408,10 @@ subroutine Allocation3_PlantCNPAlloc (bounds , & plant_n_buffer_patch(p) = plant_n_buffer_patch(p) * (1._r8-dt/taun) plant_p_buffer_patch(p) = plant_p_buffer_patch(p) * (1._r8-dt/taun) - if (iscft(ivt(p)) >= 1 .and. grain_flag(p) == 1._r8) then + if (iscft(ivt(p)) .and. grain_flag(p) == 1._r8) then avail_retransn(p) = retransn(p)/dt avail_retransp(p) = retransp(p)/dt - else if (iscft(ivt(p)) < 1 .and. annsum_potential_gpp(p) > 0._r8) then + else if ((.not. iscft(ivt(p))) .and. annsum_potential_gpp(p) > 0._r8) then avail_retransn(p) = (annmax_retransn(p)/2._r8)*(gpp(p)/annsum_potential_gpp(p))/dt avail_retransp(p) = (annmax_retransp(p)/2._r8)*(gpp(p)/annsum_potential_gpp(p))/dt else @@ -1436,7 +1432,7 @@ subroutine Allocation3_PlantCNPAlloc (bounds , & mr = leaf_mr(p) + froot_mr(p) if (woody(ivt(p)) >= 1.0_r8) then mr = mr + livestem_mr(p) + livecroot_mr(p) - else if (iscft(ivt(p)) >= 1) then + else if (iscft(ivt(p))) then if (croplive(p)) mr = mr + livestem_mr(p) + grain_mr(p) end if ! try to take mr from xsmr storage pool first @@ -1530,7 +1526,7 @@ subroutine Allocation3_PlantCNPAlloc (bounds , & p_allometry(p) = 1._r8/cpl + f1/cpfr + (f3*f4*(1._r8+f2))/cplw + & (f3*(1._r8-f4)*(1._r8+f2))/cpdw - else if (iscft(ivt(p)) >= 1) then ! skip generic crops + else if (iscft(ivt(p))) then ! skip generic crops cng = graincn(ivt(p)) cpg = graincp(ivt(p)) c_allometry(p) = (1._r8+g1)*(1._r8+f1+f5+f3*(1._r8+f2)) @@ -1614,7 +1610,7 @@ subroutine Allocation3_PlantCNPAlloc (bounds , & cpool_to_xsmrpool(p) = cpool_to_xsmrpool(p) + nlc * f2 * f3 * (1._r8 - f4) * fcur * (1 + g1) cpool_to_xsmrpool(p) = cpool_to_xsmrpool(p) + nlc * f2 * f3 * (1._r8 - f4) * (1._r8 - fcur) * (1 + g1) end if - if (iscft(ivt(p)) >= 1) then ! skip 2 generic crops + if (iscft(ivt(p))) then ! skip 2 generic crops cpool_to_xsmrpool(p) = cpool_to_xsmrpool(p) + nlc * f3 * f4 * fcur * (1 + g1) cpool_to_xsmrpool(p) = cpool_to_xsmrpool(p) + nlc * f3 * f4 * (1._r8 - fcur) * (1 + g1) cpool_to_xsmrpool(p) = cpool_to_xsmrpool(p) + nlc * f3 * (1._r8 - f4) * fcur * (1 + g1) @@ -1645,7 +1641,7 @@ subroutine Allocation3_PlantCNPAlloc (bounds , & cpool_to_deadcrootc(p) = nlc * f2 * f3 * (1._r8 - f4) * fcur cpool_to_deadcrootc_storage(p) = nlc * f2 * f3 * (1._r8 - f4) * (1._r8 - fcur) end if - if (iscft(ivt(p)) >= 1) then ! skip 2 generic crops + if (iscft(ivt(p))) then ! skip 2 generic crops cpool_to_livestemc(p) = nlc * f3 * f4 * fcur cpool_to_livestemc_storage(p) = nlc * f3 * f4 * (1._r8 - fcur) cpool_to_deadstemc(p) = nlc * f3 * (1._r8 - f4) * fcur @@ -1698,7 +1694,7 @@ subroutine Allocation3_PlantCNPAlloc (bounds , & npool_to_deadcrootn(p) = (nlc * f2 * f3 * (1._r8 - f4) / cndw) * fcur npool_to_deadcrootn_storage(p) = (nlc * f2 * f3 * (1._r8 - f4) / cndw) * (1._r8 - fcur) end if - if (iscft(ivt(p)) >= 1) then ! skip 2 generic crops + if (iscft(ivt(p))) then ! skip 2 generic crops cng = graincn(ivt(p)) npool_to_livestemn(p) = (nlc * f3 * f4 / cnlw) * fcur npool_to_livestemn_storage(p) = (nlc * f3 * f4 / cnlw) * (1._r8 - fcur) @@ -1742,7 +1738,7 @@ subroutine Allocation3_PlantCNPAlloc (bounds , & ppool_to_deadcrootp(p) = (nlc * f2 * f3 * (1._r8 - f4) / cpdw)* fcur ppool_to_deadcrootp_storage(p) = (nlc * f2 * f3 * (1._r8 - f4) / cpdw)* (1._r8 - fcur) end if - if (iscft(ivt(p)) >= 1) then ! skip 2 generic crops + if (iscft(ivt(p))) then ! skip 2 generic crops cpg = graincp(ivt(p)) ppool_to_livestemp(p) = (nlc * f3 * f4 / cplw) * fcur ppool_to_livestemp_storage(p) = (nlc * f3 * f4 / cplw) * (1._r8 -fcur) @@ -1772,7 +1768,7 @@ subroutine Allocation3_PlantCNPAlloc (bounds , & gresp_storage = gresp_storage + cpool_to_livecrootc_storage(p) gresp_storage = gresp_storage + cpool_to_deadcrootc_storage(p) end if - if (iscft(ivt(p)) >= 1) then ! skip 2 generic crops + if (iscft(ivt(p))) then ! skip 2 generic crops gresp_storage = gresp_storage + cpool_to_livestemc_storage(p) gresp_storage = gresp_storage + cpool_to_grainc_storage(p) end if @@ -1820,7 +1816,7 @@ subroutine Allocation3_PlantCNPAlloc (bounds , & npool_to_deadcrootn(p) = cpool_to_deadcrootc(p) / cndw npool_to_deadcrootn_storage(p) = cpool_to_deadcrootc_storage(p) / cndw end if - if (iscft(ivt(p)) >= 1) then ! skip 2 generic crops + if (iscft(ivt(p))) then ! skip 2 generic crops cng = graincn(ivt(p)) supplement_to_sminn_vr(c,1) = supplement_to_sminn_vr(c,1) + cpool_to_livestemc(p) / cnlw - npool_to_livestemn(p) supplement_to_sminn_vr(c,1) = supplement_to_sminn_vr(c,1) + cpool_to_livestemc_storage(p) / cnlw & @@ -1891,7 +1887,7 @@ subroutine Allocation3_PlantCNPAlloc (bounds , & ppool_to_deadcrootp(p) = cpool_to_deadcrootc(p) / cpdw ppool_to_deadcrootp_storage(p) = cpool_to_deadcrootc_storage(p) / cpdw end if - if (iscft(ivt(p)) >= 1) then ! skip 2 generic crops + if (iscft(ivt(p))) then ! skip 2 generic crops cpg = graincp(ivt(p)) supplement_to_sminp_vr(c,1) = supplement_to_sminp_vr(c,1) + max(cpool_to_livestemc(p) / cplw & - ppool_to_livestemp(p),0._r8) diff --git a/components/elm/src/biogeochem/CNCarbonFluxType.F90 b/components/elm/src/biogeochem/CNCarbonFluxType.F90 index 61a3f736f621..a6c56a935f05 100644 --- a/components/elm/src/biogeochem/CNCarbonFluxType.F90 +++ b/components/elm/src/biogeochem/CNCarbonFluxType.F90 @@ -1675,7 +1675,7 @@ subroutine Summary(this, bounds, num_soilc, filter_soilc, num_soilp, filter_soil this%cpool_livecroot_storage_gr_patch(p) + & this%cpool_deadcroot_storage_gr_patch(p) - if ( crop_prog .and. iscft(veg_pp%itype(p)) >= 1 )then + if ( crop_prog .and. iscft(veg_pp%itype(p)))then this%mr_patch(p) = & this%mr_patch(p) + & this%grain_mr_patch(p) @@ -1700,7 +1700,7 @@ subroutine Summary(this, bounds, num_soilc, filter_soilc, num_soilp, filter_soil this%storage_gr_patch(p) ! autotrophic respiration (AR) - if ( crop_prog .and. iscft(veg_pp%itype(p)) >= 1 )then + if ( crop_prog .and. iscft(veg_pp%itype(p)))then this%ar_patch(p) = & this%mr_patch(p) + & this%gr_patch(p) + & @@ -1812,7 +1812,7 @@ subroutine Summary(this, bounds, num_soilc, filter_soilc, num_soilp, filter_soil this%wood_harvestc_patch(p) = & this%hrv_deadstemc_to_prod10c_patch(p) + & this%hrv_deadstemc_to_prod100c_patch(p) - if ( crop_prog .and. iscft(veg_pp%itype(p)) >= 1 )then + if ( crop_prog .and. iscft(veg_pp%itype(p)))then this%wood_harvestc_patch(p) = & this%wood_harvestc_patch(p) + & this%hrv_cropc_to_prod1c_patch(p) @@ -1842,7 +1842,7 @@ subroutine Summary(this, bounds, num_soilc, filter_soilc, num_soilp, filter_soil this%m_gresp_xfer_to_fire_patch(p) + & this%m_cpool_to_fire_patch(p) - if ( crop_prog .and. iscft(veg_pp%itype(p)) >= 1 )then + if ( crop_prog .and. iscft(veg_pp%itype(p)))then this%litfall_patch(p) = & this%litfall_patch(p) + & @@ -1878,7 +1878,7 @@ subroutine Summary(this, bounds, num_soilc, filter_soilc, num_soilp, filter_soil this%hrv_leafc_to_litter_patch(p) + & this%leafc_to_litter_patch(p) - if ( crop_prog .and. iscft(veg_pp%itype(p)) >= 1 )then + if ( crop_prog .and. iscft(veg_pp%itype(p)))then this%leafc_loss_patch(p) = & this%leafc_loss_patch(p) + & this%hrv_leafc_to_prod1c_patch(p) @@ -1920,7 +1920,7 @@ subroutine Summary(this, bounds, num_soilc, filter_soilc, num_soilp, filter_soil this%hrv_deadcrootc_storage_to_litter_patch(p) + & this%hrv_deadcrootc_xfer_to_litter_patch(p) ! putting the harvested crop stem and grain in the wood loss bdrewniak - if ( crop_prog .and. iscft(veg_pp%itype(p)) >= 1 )then + if ( crop_prog .and. iscft(veg_pp%itype(p)))then this%woodc_loss_patch(p) = & this%woodc_loss_patch(p) + & this%hrv_grainc_to_prod1c_patch(p) + & @@ -2592,7 +2592,7 @@ subroutine summary_cflux_for_ch4( this, bounds, num_soilp, filter_soilp, num_soi this%cpool_to_deadstemc_patch(p) + & this%deadstemc_xfer_to_deadstemc_patch(p) - if ( crop_prog .and. iscft(veg_pp%itype(p)) >= 1 )then + if ( crop_prog .and. iscft(veg_pp%itype(p)))then this%agnpp_patch(p) = & this%agnpp_patch(p) + & this%cpool_to_grainc_patch(p) + & diff --git a/components/elm/src/biogeochem/CNCarbonStateType.F90 b/components/elm/src/biogeochem/CNCarbonStateType.F90 index 46440bee2355..b733773fb20d 100644 --- a/components/elm/src/biogeochem/CNCarbonStateType.F90 +++ b/components/elm/src/biogeochem/CNCarbonStateType.F90 @@ -459,7 +459,7 @@ subroutine InitCold(this, bounds, ratio, c12_carbonstate_vars) if (veg_vp%evergreen(veg_pp%itype(p)) == 1._r8) then this%leafc_patch(p) = 1._r8 * ratio this%leafc_storage_patch(p) = 0._r8 - else if (iscft(veg_pp%itype(p)) >= 1) then ! prognostic crop types + else if (iscft(veg_pp%itype(p))) then ! prognostic crop types this%leafc_patch(p) = 0._r8 this%leafc_storage_patch(p) = 0._r8 else @@ -866,7 +866,7 @@ subroutine Summary(this, bounds, num_soilc, filter_soilc, num_soilp, filter_soil this%gresp_storage_patch(p) + & this%gresp_xfer_patch(p) - if ( crop_prog .and. iscft(veg_pp%itype(p)) >= 1 )then + if ( crop_prog .and. iscft(veg_pp%itype(p)))then this%storvegc_patch(p) = & this%storvegc_patch(p) + & this%grainc_storage_patch(p) + & diff --git a/components/elm/src/biogeochem/CNGapMortalityBeTRMod.F90 b/components/elm/src/biogeochem/CNGapMortalityBeTRMod.F90 index 370e82ab7ff5..3bbbf1db1f60 100644 --- a/components/elm/src/biogeochem/CNGapMortalityBeTRMod.F90 +++ b/components/elm/src/biogeochem/CNGapMortalityBeTRMod.F90 @@ -188,7 +188,7 @@ subroutine CNGapMortality (& * gap_indicator(gid_m_deadcrootn_to_litter) - if (iscft(veg_pp%itype(p)) < 1) then + if (.not. iscft(veg_pp%itype(p))) then veg_nf%m_retransn_to_litter(p) = veg_ns%retransn(p) * m & * gap_indicator(gid_m_retransn_to_litter) end if @@ -239,7 +239,7 @@ subroutine CNGapMortality (& veg_pf%m_deadstemp_to_litter(p) = veg_ps%deadstemp(p) * m veg_pf%m_livecrootp_to_litter(p) = veg_ps%livecrootp(p) * m veg_pf%m_deadcrootp_to_litter(p) = veg_ps%deadcrootp(p) * m - if (iscft(veg_pp%itype(p)) < 1) then + if (.not. iscft(veg_pp%itype(p))) then veg_pf%m_retransp_to_litter(p) = veg_ps%retransp(p) * m end if diff --git a/components/elm/src/biogeochem/CNNStateUpdate1BeTRMod.F90 b/components/elm/src/biogeochem/CNNStateUpdate1BeTRMod.F90 index f2a431e7283c..465c92f82b4c 100644 --- a/components/elm/src/biogeochem/CNNStateUpdate1BeTRMod.F90 +++ b/components/elm/src/biogeochem/CNNStateUpdate1BeTRMod.F90 @@ -101,7 +101,7 @@ subroutine NStateUpdate1(num_soilc, filter_soilc, num_soilp, filter_soilp, & veg_ns%deadcrootn_xfer(p) = veg_ns%deadcrootn_xfer(p) - veg_nf%deadcrootn_xfer_to_deadcrootn(p)*dt end if - if (iscft(ivt(p)) >= 1) then ! skip 2 generic crops + if (iscft(ivt(p))) then ! skip 2 generic crops ! lines here for consistency; the transfer terms are zero veg_ns%livestemn(p) = veg_ns%livestemn(p) + veg_nf%livestemn_xfer_to_livestemn(p)*dt veg_ns%livestemn_xfer(p) = veg_ns%livestemn_xfer(p) - veg_nf%livestemn_xfer_to_livestemn(p)*dt @@ -126,7 +126,7 @@ subroutine NStateUpdate1(num_soilc, filter_soilc, num_soilp, filter_soilp, & veg_ns%livecrootn(p) = veg_ns%livecrootn(p) - veg_nf%livecrootn_to_retransn(p)*dt veg_ns%retransn(p) = veg_ns%retransn(p) + veg_nf%livecrootn_to_retransn(p)*dt end if - if (iscft(ivt(p)) >= 1) then ! Beth adds retrans from froot + if (iscft(ivt(p))) then ! Beth adds retrans from froot veg_ns%frootn(p) = veg_ns%frootn(p) - veg_nf%frootn_to_retransn(p)*dt veg_ns%retransn(p) = veg_ns%retransn(p) + veg_nf%frootn_to_retransn(p)*dt veg_ns%livestemn(p) = veg_ns%livestemn(p) - veg_nf%livestemn_to_litter(p)*dt @@ -172,7 +172,7 @@ subroutine NStateUpdate1(num_soilc, filter_soilc, num_soilp, filter_soilp, & veg_ns%deadcrootn_storage(p) = veg_ns%deadcrootn_storage(p) + veg_nf%npool_to_deadcrootn_storage(p)*dt end if - if (iscft(ivt(p)) >= 1) then ! skip 2 generic crops + if (iscft(ivt(p))) then ! skip 2 generic crops veg_ns%npool(p) = veg_ns%npool(p) - veg_nf%npool_to_livestemn(p)*dt veg_ns%livestemn(p) = veg_ns%livestemn(p) + veg_nf%npool_to_livestemn(p)*dt veg_ns%npool(p) = veg_ns%npool(p) - veg_nf%npool_to_livestemn_storage(p)*dt @@ -200,7 +200,7 @@ subroutine NStateUpdate1(num_soilc, filter_soilc, num_soilp, filter_soilp, & veg_ns%deadcrootn_xfer(p) = veg_ns%deadcrootn_xfer(p) + veg_nf%deadcrootn_storage_to_xfer(p)*dt end if - if (iscft(ivt(p)) >= 1) then ! skip 2 generic crops + if (iscft(ivt(p))) then ! skip 2 generic crops ! lines here for consistency; the transfer terms are zero veg_ns%livestemn_storage(p) = veg_ns%livestemn_storage(p) - veg_nf%livestemn_storage_to_xfer(p)*dt veg_ns%livestemn_xfer(p) = veg_ns%livestemn_xfer(p) + veg_nf%livestemn_storage_to_xfer(p)*dt diff --git a/components/elm/src/biogeochem/CNNStateUpdate2BeTRMod.F90 b/components/elm/src/biogeochem/CNNStateUpdate2BeTRMod.F90 index fbfa6110d77f..70b56142c882 100644 --- a/components/elm/src/biogeochem/CNNStateUpdate2BeTRMod.F90 +++ b/components/elm/src/biogeochem/CNNStateUpdate2BeTRMod.F90 @@ -147,7 +147,7 @@ subroutine NStateUpdate2h(num_soilc, filter_soilc, num_soilp, filter_soilp, & veg_ns%deadcrootn(p) = veg_ns%deadcrootn(p) - veg_nf%hrv_deadcrootn_to_litter(p) * dt veg_ns%retransn(p) = veg_ns%retransn(p) - veg_nf%hrv_retransn_to_litter(p) * dt - if (iscft(ivt(p)) >=1) then ! skip 2 generic crops + if (iscft(ivt(p))) then ! skip 2 generic crops veg_ns%livestemn(p)= veg_ns%livestemn(p) - veg_nf%hrv_livestemn_to_prod1n(p) * dt veg_ns%leafn(p) = veg_ns%leafn(p) - veg_nf%hrv_leafn_to_prod1n(p) * dt veg_ns%grainn(p) = veg_ns%grainn(p) - veg_nf%hrv_grainn_to_prod1n(p) * dt diff --git a/components/elm/src/biogeochem/CNNitrogenFluxType.F90 b/components/elm/src/biogeochem/CNNitrogenFluxType.F90 index b6f02ce91f82..5394e0d05fa1 100644 --- a/components/elm/src/biogeochem/CNNitrogenFluxType.F90 +++ b/components/elm/src/biogeochem/CNNitrogenFluxType.F90 @@ -1078,7 +1078,6 @@ subroutine Summary(this, bounds, num_soilc, filter_soilc, num_soilp, filter_soil ! !USES: use elm_varpar , only: nlevdecomp,ndecomp_cascade_transitions,ndecomp_pools use subgridAveMod , only: p2c - use pftvarcon , only : iscft use tracer_varcon , only: is_active_betr_bgc use elm_varpar , only: nlevdecomp_full ! diff --git a/components/elm/src/biogeochem/CNNitrogenStateType.F90 b/components/elm/src/biogeochem/CNNitrogenStateType.F90 index 041c757ae598..a7f7315c6c83 100644 --- a/components/elm/src/biogeochem/CNNitrogenStateType.F90 +++ b/components/elm/src/biogeochem/CNNitrogenStateType.F90 @@ -1007,7 +1007,7 @@ subroutine Summary(this, bounds, num_soilc, filter_soilc, num_soilp, filter_soil this%npool_patch(p) + & this%retransn_patch(p) - if ( crop_prog .and. iscft(veg_pp%itype(p)) >= 1 )then + if ( crop_prog .and. iscft(veg_pp%itype(p)))then this%dispvegn_patch(p) = & this%dispvegn_patch(p) + & this%grainn_patch(p) diff --git a/components/elm/src/biogeochem/CNPhenologyBeTRMod.F90 b/components/elm/src/biogeochem/CNPhenologyBeTRMod.F90 index aaeb58d9ee91..ac3b58538e8f 100644 --- a/components/elm/src/biogeochem/CNPhenologyBeTRMod.F90 +++ b/components/elm/src/biogeochem/CNPhenologyBeTRMod.F90 @@ -1895,13 +1895,13 @@ subroutine CropPhenologyInit(bounds) minplantjday(:,:) = huge(1) maxplantjday(:,:) = huge(1) do n = 0, mxpft - if (iscft(n)>=1) then + if (iscft(n)) then minplantjday(n,inNH) = int( get_calday( mnNHplantdate(n), 0 ) ) maxplantjday(n,inNH) = int( get_calday( mxNHplantdate(n), 0 ) ) end if end do do n = 0, mxpft - if (iscft(n)>=1) then + if (iscft(n)) then minplantjday(n,inSH) = int( get_calday( mnSHplantdate(n), 0 ) ) maxplantjday(n,inSH) = int( get_calday( mxSHplantdate(n), 0 ) ) end if diff --git a/components/elm/src/biogeochem/CarbonStateUpdate1Mod.F90 b/components/elm/src/biogeochem/CarbonStateUpdate1Mod.F90 index 7513662f4670..1eb7f64d025a 100644 --- a/components/elm/src/biogeochem/CarbonStateUpdate1Mod.F90 +++ b/components/elm/src/biogeochem/CarbonStateUpdate1Mod.F90 @@ -284,7 +284,7 @@ subroutine CarbonStateUpdate1(bounds, & veg_cs%deadcrootc(p) = veg_cs%deadcrootc(p) + veg_cf%deadcrootc_xfer_to_deadcrootc(p)*dt veg_cs%deadcrootc_xfer(p) = veg_cs%deadcrootc_xfer(p) - veg_cf%deadcrootc_xfer_to_deadcrootc(p)*dt end if - if (iscft(ivt(p)) >= 1) then ! skip 2 generic crops + if (iscft(ivt(p))) then ! skip 2 generic crops ! lines here for consistency; the transfer terms are zero veg_cs%livestemc(p) = veg_cs%livestemc(p) + veg_cf%livestemc_xfer_to_livestemc(p)*dt veg_cs%livestemc_xfer(p) = veg_cs%livestemc_xfer(p) - veg_cf%livestemc_xfer_to_livestemc(p)*dt @@ -303,7 +303,7 @@ subroutine CarbonStateUpdate1(bounds, & veg_cs%livecrootc(p) = veg_cs%livecrootc(p) - veg_cf%livecrootc_to_deadcrootc(p)*dt veg_cs%deadcrootc(p) = veg_cs%deadcrootc(p) + veg_cf%livecrootc_to_deadcrootc(p)*dt end if - if (iscft(ivt(p)) >= 1) then ! skip 2 generic crops + if (iscft(ivt(p))) then ! skip 2 generic crops veg_cs%livestemc(p) = veg_cs%livestemc(p) - veg_cf%livestemc_to_litter(p)*dt veg_cs%grainc(p) = veg_cs%grainc(p) - veg_cf%grainc_to_food(p)*dt @@ -319,7 +319,7 @@ subroutine CarbonStateUpdate1(bounds, & veg_cs%cpool(p) = veg_cs%cpool(p) - veg_cf%livestem_curmr(p)*dt veg_cs%cpool(p) = veg_cs%cpool(p) - veg_cf%livecroot_curmr(p)*dt end if - if (iscft(ivt(p)) >= 1) then ! skip 2 generic crops + if (iscft(ivt(p))) then ! skip 2 generic crops veg_cs%cpool(p) = veg_cs%cpool(p) - veg_cf%livestem_curmr(p)*dt veg_cs%cpool(p) = veg_cs%cpool(p) - veg_cf%grain_curmr(p)*dt end if @@ -337,7 +337,7 @@ subroutine CarbonStateUpdate1(bounds, & veg_cs%xsmrpool(p) = veg_cs%xsmrpool(p) - veg_cf%livestem_xsmr(p)*dt veg_cs%xsmrpool(p) = veg_cs%xsmrpool(p) - veg_cf%livecroot_xsmr(p)*dt end if - if (iscft(ivt(p)) >= 1) then ! skip 2 generic crops + if (iscft(ivt(p))) then ! skip 2 generic crops veg_cs%xsmrpool(p) = veg_cs%xsmrpool(p) - veg_cf%livestem_xsmr(p)*dt veg_cs%xsmrpool(p) = veg_cs%xsmrpool(p) - veg_cf%grain_xsmr(p)*dt if (harvdate(p) < 999) then ! beginning at harvest, send to atm @@ -373,7 +373,7 @@ subroutine CarbonStateUpdate1(bounds, & veg_cs%cpool(p) = veg_cs%cpool(p) - veg_cf%cpool_to_deadcrootc_storage(p)*dt veg_cs%deadcrootc_storage(p) = veg_cs%deadcrootc_storage(p) + veg_cf%cpool_to_deadcrootc_storage(p)*dt end if - if ( iscft(ivt(p)) >= 1 ) then ! skip 2 generic crops + if ( iscft(ivt(p))) then ! skip 2 generic crops veg_cs%cpool(p) = veg_cs%cpool(p) - veg_cf%cpool_to_livestemc(p)*dt veg_cs%livestemc(p) = veg_cs%livestemc(p) + veg_cf%cpool_to_livestemc(p)*dt veg_cs%cpool(p) = veg_cs%cpool(p) - veg_cf%cpool_to_livestemc_storage(p)*dt @@ -393,7 +393,7 @@ subroutine CarbonStateUpdate1(bounds, & veg_cs%cpool(p) = veg_cs%cpool(p) - veg_cf%cpool_livecroot_gr(p)*dt veg_cs%cpool(p) = veg_cs%cpool(p) - veg_cf%cpool_deadcroot_gr(p)*dt end if - if (iscft(ivt(p)) >= 1) then ! skip 2 generic crops + if (iscft(ivt(p))) then ! skip 2 generic crops veg_cs%cpool(p) = veg_cs%cpool(p) - veg_cf%cpool_livestem_gr(p)*dt veg_cs%cpool(p) = veg_cs%cpool(p) - veg_cf%cpool_grain_gr(p)*dt end if @@ -407,7 +407,7 @@ subroutine CarbonStateUpdate1(bounds, & veg_cs%gresp_xfer(p) = veg_cs%gresp_xfer(p) - veg_cf%transfer_livecroot_gr(p)*dt veg_cs%gresp_xfer(p) = veg_cs%gresp_xfer(p) - veg_cf%transfer_deadcroot_gr(p)*dt end if - if (iscft(ivt(p)) >= 1) then ! skip 2 generic crops + if (iscft(ivt(p))) then ! skip 2 generic crops veg_cs%gresp_xfer(p) = veg_cs%gresp_xfer(p) - veg_cf%transfer_livestem_gr(p)*dt veg_cs%gresp_xfer(p) = veg_cs%gresp_xfer(p) - veg_cf%transfer_grain_gr(p)*dt end if @@ -421,7 +421,7 @@ subroutine CarbonStateUpdate1(bounds, & veg_cs%cpool(p) = veg_cs%cpool(p) - veg_cf%cpool_livecroot_storage_gr(p)*dt veg_cs%cpool(p) = veg_cs%cpool(p) - veg_cf%cpool_deadcroot_storage_gr(p)*dt end if - if ( iscft(ivt(p)) >= 1 ) then ! skip 2 generic crops + if ( iscft(ivt(p))) then ! skip 2 generic crops veg_cs%cpool(p) = veg_cs%cpool(p) - veg_cf%cpool_livestem_storage_gr(p)*dt veg_cs%cpool(p) = veg_cs%cpool(p) - veg_cf%cpool_grain_storage_gr(p)*dt end if @@ -447,7 +447,7 @@ subroutine CarbonStateUpdate1(bounds, & veg_cs%gresp_storage(p) = veg_cs%gresp_storage(p) - veg_cf%gresp_storage_to_xfer(p)*dt veg_cs%gresp_xfer(p) = veg_cs%gresp_xfer(p) + veg_cf%gresp_storage_to_xfer(p)*dt end if - if ( iscft(ivt(p)) >= 1 ) then ! skip 2 generic crops + if ( iscft(ivt(p))) then ! skip 2 generic crops ! lines here for consistency; the transfer terms are zero veg_cs%livestemc_storage(p) = veg_cs%livestemc_storage(p) - veg_cf%livestemc_storage_to_xfer(p)*dt veg_cs%livestemc_xfer(p) = veg_cs%livestemc_xfer(p) + veg_cf%livestemc_storage_to_xfer(p)*dt diff --git a/components/elm/src/biogeochem/CarbonStateUpdate2Mod.F90 b/components/elm/src/biogeochem/CarbonStateUpdate2Mod.F90 index 985c544d29ff..4676a1e351d1 100644 --- a/components/elm/src/biogeochem/CarbonStateUpdate2Mod.F90 +++ b/components/elm/src/biogeochem/CarbonStateUpdate2Mod.F90 @@ -186,7 +186,7 @@ subroutine CarbonStateUpdate2h(num_soilc, filter_soilc, num_soilp, filter_soilp, veg_cs%deadcrootc(p) = veg_cs%deadcrootc(p) - veg_cf%hrv_deadcrootc_to_litter(p) * dt ! crops - if (iscft(ivt(p)) >= 1) then ! skip 2 generic crops + if (iscft(ivt(p))) then ! skip 2 generic crops veg_cs%livestemc(p) = veg_cs%livestemc(p) - veg_cf%hrv_livestemc_to_prod1c(p) *dt veg_cs%leafc(p) = veg_cs%leafc(p) - veg_cf%hrv_leafc_to_prod1c(p) *dt veg_cs%grainc(p) = veg_cs%grainc(p) - veg_cf%hrv_grainc_to_prod1c(p) *dt diff --git a/components/elm/src/biogeochem/CropType.F90 b/components/elm/src/biogeochem/CropType.F90 index 58f7757e5fcb..8394d21ca348 100644 --- a/components/elm/src/biogeochem/CropType.F90 +++ b/components/elm/src/biogeochem/CropType.F90 @@ -454,7 +454,7 @@ subroutine Restart(this, bounds, ncid, flag) interpinic_flag='copy', readvar=readvar, data=restyear) if (readvar) then do p = bounds%begp, bounds%endp - if (iscft(veg_pp%itype(p)) >= 1 .and. & + if (iscft(veg_pp%itype(p)) .and. & veg_pp%active(p)) then this%nyrs_crop_active_patch(p) = restyear end if diff --git a/components/elm/src/biogeochem/DryDepVelocity.F90 b/components/elm/src/biogeochem/DryDepVelocity.F90 index a79792b4e858..b6ef82a632ef 100644 --- a/components/elm/src/biogeochem/DryDepVelocity.F90 +++ b/components/elm/src/biogeochem/DryDepVelocity.F90 @@ -294,7 +294,7 @@ subroutine depvel_compute( bounds, & !if (elmveg == nc3crop ) wesveg = 2 !if (elmveg == nc3irrig ) wesveg = 2 !if (elmveg >= npcropmin .and. elmveg <= npcropmax ) wesveg = 2 - if (crop(elmveg) == 1.0_r8 .or. iscft(elmveg) == 1.0_r8 ) wesveg = 2 + if (crop(elmveg) == 1.0_r8 .or. iscft(elmveg)) wesveg = 2 #ifndef _OPENACC if (wesveg == wveg_unset )then write(iulog,*) 'elmveg = ', elmveg, 'lun_pp%itype = ', lun_pp%itype(l) diff --git a/components/elm/src/biogeochem/FireMod.F90 b/components/elm/src/biogeochem/FireMod.F90 index 7aa4e6a50f9e..b84aa2c3ab6e 100644 --- a/components/elm/src/biogeochem/FireMod.F90 +++ b/components/elm/src/biogeochem/FireMod.F90 @@ -305,12 +305,12 @@ subroutine FireArea (bounds, & if (pi <= col_pp%npfts(c)) then p = col_pp%pfti(c) + pi - 1 ! For crop veg types - if( crop(veg_pp%itype(p)) == 1 .or. iscft(veg_pp%itype(p)) == 1 )then + if( crop(veg_pp%itype(p)) == 1 .or. iscft(veg_pp%itype(p)))then cropf_col(c) = cropf_col(c) + veg_pp%wtcol(p) end if ! For natural vegetation (non-crop and non-bare-soil) if( veg_pp%itype(p) /= noveg .and. & - (crop(veg_pp%itype(p)) == 0 .and. iscft(veg_pp%itype(p)) == 0) )then + (crop(veg_pp%itype(p)) == 0 .and. .not. iscft(veg_pp%itype(p))) )then lfwt(c) = lfwt(c) + veg_pp%wtcol(p) end if end if @@ -332,7 +332,7 @@ subroutine FireArea (bounds, & ! column-level litter carbon ! is available, so we use leaf carbon to estimate the ! litter carbon for crop PFTs - if( (crop(veg_pp%itype(p)) == 1 .or. iscft(veg_pp%itype(p)) == 1) .and. & + if( (crop(veg_pp%itype(p)) == 1 .or. iscft(veg_pp%itype(p))) .and. & veg_pp%wtcol(p) > 0._r8 .and. leafc_col(c) > 0._r8 )then fuelc_crop(c)=fuelc_crop(c) + (leafc(p) + leafc_storage(p) + & leafc_xfer(p))*veg_pp%wtcol(p)/cropf_col(c) + & @@ -370,7 +370,7 @@ subroutine FireArea (bounds, & p = col_pp%pfti(c) + pi - 1 ! For non-crop -- natural vegetation and bare-soil - if( (crop(veg_pp%itype(p)) == 0 .and. iscft(veg_pp%itype(p)) == 0) .and. & + if( (crop(veg_pp%itype(p)) == 0 .and. .not. iscft(veg_pp%itype(p))) .and. & cropf_col(c) < 1.0_r8 ) then if( btran2(p) .ne. spval) then if (btran2(p) <= 1._r8 ) then @@ -509,7 +509,7 @@ subroutine FireArea (bounds, & p = col_pp%pfti(c) + pi - 1 ! For crop if( forc_t(t) >= SHR_CONST_TKFRZ .and. & - (crop(veg_pp%itype(p)) == 1 .or. iscft(veg_pp%itype(p)) == 1) .and. & + (crop(veg_pp%itype(p)) == 1 .or. iscft(veg_pp%itype(p))) .and. & kmo == abm_lf(c) .and. forc_rain(t)+forc_snow(t) == 0._r8 .and. & burndate(p) >= 999 .and. veg_pp%wtcol(p) > 0._r8 )then ! catch crop burn time @@ -982,7 +982,7 @@ subroutine FireFluxes (num_soilc, filter_soilc, num_soilp, filter_soilp, & c = veg_pp%column(p) itype = veg_pp%itype(p) - if( (crop(veg_pp%itype(p)) == 0 .and. iscft(veg_pp%itype(p)) == 0) .and. & + if( (crop(veg_pp%itype(p)) == 0 .and. .not. iscft(veg_pp%itype(p))) .and. & cropf_col(c) < 1.0_r8)then ! For non-crop (bare-soil and natural vegetation) if (transient_landcover) then !true when landuse data is used diff --git a/components/elm/src/biogeochem/GapMortalityMod.F90 b/components/elm/src/biogeochem/GapMortalityMod.F90 index 734be187805f..3a58551ae076 100644 --- a/components/elm/src/biogeochem/GapMortalityMod.F90 +++ b/components/elm/src/biogeochem/GapMortalityMod.F90 @@ -142,7 +142,7 @@ subroutine GapMortality (num_soilc, filter_soilc, num_soilp, filter_soilp, & ! displayed pools veg_cf%m_leafc_to_litter(p) = 0._r8 veg_cf%m_livestemc_to_litter(p) = 0._r8 - if(iscft(ivt(p)) < 1 .or. (iscft(ivt(p)) >= 1 .and. croplive(p))) then + if((.not. iscft(ivt(p))) .or. (iscft(ivt(p)) .and. croplive(p))) then veg_cf%m_leafc_to_litter(p) = veg_cs%leafc(p) * m veg_cf%m_livestemc_to_litter(p) = veg_cs%livestemc(p) * m end if @@ -181,7 +181,7 @@ subroutine GapMortality (num_soilc, filter_soilc, num_soilp, filter_soilp, & ! displayed pools veg_nf%m_leafn_to_litter(p) = 0._r8 veg_nf%m_livestemn_to_litter(p) = 0._r8 - if(iscft(ivt(p)) < 1 .or. (iscft(ivt(p)) >= 1 .and. croplive(p))) then + if((.not. iscft(ivt(p))) .or. (iscft(ivt(p)) .and. croplive(p))) then veg_nf%m_leafn_to_litter(p) = veg_ns%leafn(p) * m veg_nf%m_livestemn_to_litter(p) = veg_ns%livestemn(p) * m end if @@ -190,7 +190,7 @@ subroutine GapMortality (num_soilc, filter_soilc, num_soilp, filter_soilp, & veg_nf%m_livecrootn_to_litter(p) = veg_ns%livecrootn(p) * m veg_nf%m_deadcrootn_to_litter(p) = veg_ns%deadcrootn(p) * m veg_nf%m_retransn_to_litter(p) = 0._r8 - if (iscft(ivt(p)) < 1) then + if (.not. iscft(ivt(p))) then veg_nf%m_retransn_to_litter(p) = veg_ns%retransn(p) * m end if veg_nf%m_npool_to_litter(p) = veg_ns%npool(p) * m @@ -225,7 +225,7 @@ subroutine GapMortality (num_soilc, filter_soilc, num_soilp, filter_soilp, & ! displayed pools veg_pf%m_leafp_to_litter(p) = 0._r8 veg_pf%m_livestemp_to_litter(p) = 0._r8 - if(iscft(ivt(p)) < 1 .or. (iscft(ivt(p)) >= 1 .and. croplive(p))) then + if((.not. iscft(ivt(p))) .or. (iscft(ivt(p)) .and. croplive(p))) then veg_pf%m_leafp_to_litter(p) = veg_ps%leafp(p) * m veg_pf%m_livestemp_to_litter(p) = veg_ps%livestemp(p) * m endif @@ -235,7 +235,7 @@ subroutine GapMortality (num_soilc, filter_soilc, num_soilp, filter_soilp, & veg_pf%m_deadcrootp_to_litter(p) = veg_ps%deadcrootp(p) * m veg_pf%m_retransp_to_litter(p) = 0._r8 - if (iscft(ivt(p)) < 1) then + if (.not. iscft(ivt(p))) then veg_pf%m_retransp_to_litter(p) = veg_ps%retransp(p) * m end if veg_pf%m_ppool_to_litter(p) = veg_ps%ppool(p) * m diff --git a/components/elm/src/biogeochem/GrowthRespMod.F90 b/components/elm/src/biogeochem/GrowthRespMod.F90 index 34a9a64c56c9..cb7ad522265f 100644 --- a/components/elm/src/biogeochem/GrowthRespMod.F90 +++ b/components/elm/src/biogeochem/GrowthRespMod.F90 @@ -102,7 +102,7 @@ subroutine GrowthResp(num_soilp, filter_soilp) do fp = 1,num_soilp p = filter_soilp(fp) - if (iscft(ivt(p)) >= 1) then ! skip 2 generic crops + if (iscft(ivt(p))) then ! skip 2 generic crops cpool_livestem_gr(p) = cpool_to_livestemc(p) * grperc(ivt(p)) diff --git a/components/elm/src/biogeochem/MaintenanceRespMod.F90 b/components/elm/src/biogeochem/MaintenanceRespMod.F90 index 48d179f97d1f..54005275b296 100644 --- a/components/elm/src/biogeochem/MaintenanceRespMod.F90 +++ b/components/elm/src/biogeochem/MaintenanceRespMod.F90 @@ -185,7 +185,7 @@ subroutine MaintenanceResp(bounds, & if (woody(ivt(p)) >= 1.0_r8) then livestem_mr(p) = livestemn(p)*br_mr*tc livecroot_mr(p) = livecrootn(p)*br_mr*tc - else if (iscft(ivt(p)) >= 1 .and. livestemn(p) .gt. 0._r8) then + else if (iscft(ivt(p)) .and. livestemn(p) .gt. 0._r8) then livestem_mr(p) = livestemn(p)*br_mr*tc grain_mr(p) = grainn(p)*br_mr*tc end if diff --git a/components/elm/src/biogeochem/NitrogenStateUpdate1Mod.F90 b/components/elm/src/biogeochem/NitrogenStateUpdate1Mod.F90 index 80fc34e6d0ba..c1b2bfc5d65a 100644 --- a/components/elm/src/biogeochem/NitrogenStateUpdate1Mod.F90 +++ b/components/elm/src/biogeochem/NitrogenStateUpdate1Mod.F90 @@ -297,7 +297,7 @@ subroutine NitrogenStateUpdate1(num_soilc, filter_soilc, num_soilp, filter_soilp veg_ns%deadcrootn_xfer(p) = veg_ns%deadcrootn_xfer(p) - veg_nf%deadcrootn_xfer_to_deadcrootn(p)*dt end if - if (iscft(ivt(p)) >= 1) then ! skip 2 generic crops + if (iscft(ivt(p))) then ! skip 2 generic crops ! lines here for consistency; the transfer terms are zero veg_ns%livestemn(p) = veg_ns%livestemn(p) + veg_nf%livestemn_xfer_to_livestemn(p)*dt veg_ns%livestemn_xfer(p) = veg_ns%livestemn_xfer(p) - veg_nf%livestemn_xfer_to_livestemn(p)*dt @@ -322,7 +322,7 @@ subroutine NitrogenStateUpdate1(num_soilc, filter_soilc, num_soilp, filter_soilp veg_ns%livecrootn(p) = veg_ns%livecrootn(p) - veg_nf%livecrootn_to_retransn(p)*dt veg_ns%retransn(p) = veg_ns%retransn(p) + veg_nf%livecrootn_to_retransn(p)*dt end if - if (iscft(ivt(p)) >= 1) then ! Beth adds retrans from froot + if (iscft(ivt(p))) then ! Beth adds retrans from froot veg_ns%frootn(p) = veg_ns%frootn(p) - veg_nf%frootn_to_retransn(p)*dt veg_ns%retransn(p) = veg_ns%retransn(p) + veg_nf%frootn_to_retransn(p)*dt veg_ns%livestemn(p) = veg_ns%livestemn(p) - veg_nf%livestemn_to_litter(p)*dt @@ -373,7 +373,7 @@ subroutine NitrogenStateUpdate1(num_soilc, filter_soilc, num_soilp, filter_soilp veg_ns%deadcrootn_storage(p) = veg_ns%deadcrootn_storage(p) + veg_nf%npool_to_deadcrootn_storage(p)*dt end if - if (iscft(ivt(p)) >= 1) then ! skip 2 generic crops + if (iscft(ivt(p))) then ! skip 2 generic crops veg_ns%npool(p) = veg_ns%npool(p) - veg_nf%npool_to_livestemn(p)*dt veg_ns%livestemn(p) = veg_ns%livestemn(p) + veg_nf%npool_to_livestemn(p)*dt veg_ns%npool(p) = veg_ns%npool(p) - veg_nf%npool_to_livestemn_storage(p)*dt @@ -401,7 +401,7 @@ subroutine NitrogenStateUpdate1(num_soilc, filter_soilc, num_soilp, filter_soilp veg_ns%deadcrootn_xfer(p) = veg_ns%deadcrootn_xfer(p) + veg_nf%deadcrootn_storage_to_xfer(p)*dt end if - if (iscft(ivt(p)) >= 1) then ! skip 2 generic crops + if (iscft(ivt(p))) then ! skip 2 generic crops ! lines here for consistency; the transfer terms are zero veg_ns%livestemn_storage(p) = veg_ns%livestemn_storage(p) - veg_nf%livestemn_storage_to_xfer(p)*dt veg_ns%livestemn_xfer(p) = veg_ns%livestemn_xfer(p) + veg_nf%livestemn_storage_to_xfer(p)*dt diff --git a/components/elm/src/biogeochem/NitrogenStateUpdate2Mod.F90 b/components/elm/src/biogeochem/NitrogenStateUpdate2Mod.F90 index 5d897c5905a9..d8e6785e52cb 100644 --- a/components/elm/src/biogeochem/NitrogenStateUpdate2Mod.F90 +++ b/components/elm/src/biogeochem/NitrogenStateUpdate2Mod.F90 @@ -172,7 +172,7 @@ subroutine NitrogenStateUpdate2h(num_soilc, filter_soilc, num_soilp, filter_soil veg_ns%retransn(p) = veg_ns%retransn(p) - veg_nf%hrv_retransn_to_litter(p) * dt veg_ns%npool(p) = veg_ns%npool(p) - veg_nf%hrv_npool_to_litter(p) * dt - if (iscft(ivt(p)) >= 1) then ! skip 2 generic crops + if (iscft(ivt(p))) then ! skip 2 generic crops veg_ns%livestemn(p)= veg_ns%livestemn(p) - veg_nf%hrv_livestemn_to_prod1n(p) * dt veg_ns%leafn(p) = veg_ns%leafn(p) - veg_nf%hrv_leafn_to_prod1n(p) * dt veg_ns%grainn(p) = veg_ns%grainn(p) - veg_nf%hrv_grainn_to_prod1n(p) * dt diff --git a/components/elm/src/biogeochem/PhenologyFluxLimitMod.F90 b/components/elm/src/biogeochem/PhenologyFluxLimitMod.F90 index 49909f54929a..87b9637d5512 100644 --- a/components/elm/src/biogeochem/PhenologyFluxLimitMod.F90 +++ b/components/elm/src/biogeochem/PhenologyFluxLimitMod.F90 @@ -644,7 +644,7 @@ subroutine carbon_flux_limiter(bounds, num_soilc, filter_soilc,& ystates(s_deadcrootc_xfer) = veg_cs%deadcrootc_xfer(p) ystates(s_deadcrootc_storage) = veg_cs%deadcrootc_storage(p) endif - if (iscft(ivt(p)) >= 1) then + if (iscft(ivt(p))) then ystates(s_livestemc) = veg_cs%livestemc(p) ystates(s_livestemc_xfer) = veg_cs%livestemc_xfer(p) ystates(s_livestemc_storage) = veg_cs%livestemc_storage(p) @@ -675,7 +675,7 @@ subroutine carbon_flux_limiter(bounds, num_soilc, filter_soilc,& + veg_cf%cpool_livecroot_storage_gr(p) & + veg_cf%cpool_deadcroot_storage_gr(p) endif - if (iscft(ivt(p)) >= 1) then + if (iscft(ivt(p))) then ar_p= ar_p & + veg_cf%livestem_curmr(p) & + veg_cf%grain_curmr(p) & @@ -713,7 +713,7 @@ subroutine carbon_flux_limiter(bounds, num_soilc, filter_soilc,& rfluxes(f_deadcrootc_storage_to_xfer) = veg_cf%deadcrootc_storage_to_xfer(p) rfluxes(f_gresp_storage_to_xfer) = veg_cf%gresp_storage_to_xfer(p) endif - if (iscft(ivt(p)) >= 1) then + if (iscft(ivt(p))) then rfluxes(f_cpool_to_livestemc) = veg_cf%cpool_to_livestemc(p) rfluxes(f_cpool_to_livestemc_storage) = veg_cf%cpool_to_livestemc_storage(p) rfluxes(f_cpool_to_grainc) = veg_cf%cpool_to_grainc(p) @@ -767,7 +767,7 @@ subroutine carbon_flux_limiter(bounds, num_soilc, filter_soilc,& call fpmax(rfluxes(f_deadcrootc_storage_to_xfer) , veg_cf%deadcrootc_storage_to_xfer(p)) call fpmax(rfluxes(f_gresp_storage_to_xfer) , veg_cf%gresp_storage_to_xfer(p)) endif - if (iscft(ivt(p)) >= 1) then + if (iscft(ivt(p))) then call fpmax(rfluxes(f_cpool_to_livestemc) , veg_cf%cpool_to_livestemc(p)) call fpmax(rfluxes(f_cpool_to_livestemc_storage) , veg_cf%cpool_to_livestemc_storage(p)) call fpmax(rfluxes(f_cpool_to_grainc) , veg_cf%cpool_to_grainc(p)) @@ -806,7 +806,7 @@ subroutine carbon_flux_limiter(bounds, num_soilc, filter_soilc,& call ascal(veg_cf%cpool_livecroot_storage_gr(p), rscal) call ascal(veg_cf%cpool_deadcroot_storage_gr(p), rscal) endif - if (iscft(ivt(p)) >= 1) then + if (iscft(ivt(p))) then call ascal(veg_cf%livestem_curmr(p) , rscal) call ascal(veg_cf%grain_curmr(p) , rscal) call ascal(veg_cf%cpool_livestem_gr(p) , rscal) @@ -878,7 +878,7 @@ subroutine nitrogen_flux_limiter(bounds, num_soilc, filter_soilc,& ystates(s_deadcrootn_xfer) = veg_ns%deadcrootn_xfer(p) ystates(s_deadcrootn_storage) = veg_ns%deadcrootn_storage(p) endif - if (iscft(ivt(p)) >= 1) then + if (iscft(ivt(p))) then ystates(s_grainn) = veg_ns%grainn(p) ystates(s_grainn_xfer) = veg_ns%grainn_xfer(p) ystates(s_grainn_storage) = veg_ns%grainn_storage(p) @@ -917,7 +917,7 @@ subroutine nitrogen_flux_limiter(bounds, num_soilc, filter_soilc,& rfluxes(f_deadcrootn_xfer_to_deadcrootn) = veg_nf%deadcrootn_xfer_to_deadcrootn(p) endif - if (iscft(ivt(p)) >= 1) then + if (iscft(ivt(p))) then rfluxes(f_npool_to_livestemn) = veg_nf%npool_to_livestemn(p) rfluxes(f_npool_to_livestemn_storage) = veg_nf%npool_to_livestemn_storage(p) rfluxes(f_npool_to_grainn) = veg_nf%npool_to_grainn(p) @@ -973,7 +973,7 @@ subroutine nitrogen_flux_limiter(bounds, num_soilc, filter_soilc,& call fpmax(rfluxes(f_deadcrootn_xfer_to_deadcrootn) , veg_nf%deadcrootn_xfer_to_deadcrootn(p)) endif - if (iscft(ivt(p)) >= 1) then + if (iscft(ivt(p))) then call fpmax(rfluxes(f_npool_to_livestemn) , veg_nf%npool_to_livestemn(p)) call fpmax(rfluxes(f_npool_to_livestemn_storage) , veg_nf%npool_to_livestemn_storage(p)) call fpmax(rfluxes(f_npool_to_grainn) , veg_nf%npool_to_grainn(p)) @@ -1063,7 +1063,7 @@ subroutine phosphorus_flux_limiter(bounds, num_soilc, filter_soilc,& ystates(s_deadcrootn_xfer) = veg_ps%deadcrootp_xfer(p) ystates(s_deadcrootn_storage) = veg_ps%deadcrootp_storage(p) endif - if (iscft(ivt(p)) >= 1) then + if (iscft(ivt(p))) then ystates(s_grainn) = veg_ps%grainp(p) ystates(s_grainn_xfer) = veg_ps%grainp_xfer(p) ystates(s_grainn_storage) = veg_ps%grainp_storage(p) @@ -1102,7 +1102,7 @@ subroutine phosphorus_flux_limiter(bounds, num_soilc, filter_soilc,& rfluxes(f_deadcrootn_xfer_to_deadcrootn) = veg_pf%deadcrootp_xfer_to_deadcrootp(p) endif - if (iscft(ivt(p)) >= 1) then + if (iscft(ivt(p))) then rfluxes(f_npool_to_livestemn) = veg_pf%ppool_to_livestemp(p) rfluxes(f_npool_to_livestemn_storage) = veg_pf%ppool_to_livestemp_storage(p) rfluxes(f_npool_to_grainn) = veg_pf%ppool_to_grainp(p) @@ -1158,7 +1158,7 @@ subroutine phosphorus_flux_limiter(bounds, num_soilc, filter_soilc,& call fpmax(rfluxes(f_deadcrootn_xfer_to_deadcrootn) , veg_pf%deadcrootp_xfer_to_deadcrootp(p)) endif - if (iscft(ivt(p)) >= 1) then + if (iscft(ivt(p))) then call fpmax(rfluxes(f_npool_to_livestemn) , veg_pf%ppool_to_livestemp(p)) call fpmax(rfluxes(f_npool_to_livestemn_storage) , veg_pf%ppool_to_livestemp_storage(p)) call fpmax(rfluxes(f_npool_to_grainn) , veg_pf%ppool_to_grainp(p)) diff --git a/components/elm/src/biogeochem/PhenologyMod.F90 b/components/elm/src/biogeochem/PhenologyMod.F90 index 2a52cb928837..08e9b94da524 100644 --- a/components/elm/src/biogeochem/PhenologyMod.F90 +++ b/components/elm/src/biogeochem/PhenologyMod.F90 @@ -2205,28 +2205,18 @@ subroutine CropPhenologyInit(bounds) minplantjday(:,:) = huge(1) maxplantjday(:,:) = huge(1) do n = 0, mxpft - if (iscft(n)>=1) then + if (iscft(n)) then minplantjday(n,inNH) = int( get_calday( mnNHplantdate(n), 0 ) ) maxplantjday(n,inNH) = int( get_calday( mxNHplantdate(n), 0 ) ) end if end do do n = 0, mxpft - if (iscft(n)>=1) then + if (iscft(n)) then minplantjday(n,inSH) = int( get_calday( mnSHplantdate(n), 0 ) ) maxplantjday(n,inSH) = int( get_calday( mxSHplantdate(n), 0 ) ) end if end do - ! with flag 'iscft', the following is not needed anymore - !do n = nppercropmin, nppercropmax - ! minplantjday(n,inNH) = int( get_calday( mnNHplantdate(n), 0 ) ) - ! maxplantjday(n,inNH) = int( get_calday( mxNHplantdate(n), 0 ) ) - !end do - !do n = nppercropmin, nppercropmax - ! minplantjday(n,inSH) = int( get_calday( mnSHplantdate(n), 0 ) ) - ! maxplantjday(n,inSH) = int( get_calday( mxSHplantdate(n), 0 ) ) - !end do - ! Figure out what hemisphere each PFT is in do p = bounds%begp, bounds%endp g = veg_pp%gridcell(p) @@ -3068,7 +3058,7 @@ subroutine CNOffsetLitterfall (num_soilp, filter_soilp, & if (offset_counter(p) == dt) then t1 = 1.0_r8 / dt - if (iscft(ivt(p)) >= 1) then + if (iscft(ivt(p))) then ! this assumes that offset_counter == dt for crops ! if this were ever changed, we'd need to add code to the "else" leafc_to_litter(p) = (1.0_r8 - presharv(ivt(p))) * ((t1 * leafc(p)) + cpool_to_leafc(p)) @@ -3085,7 +3075,7 @@ subroutine CNOffsetLitterfall (num_soilp, filter_soilp, & end if if ( nu_com .eq. 'RD') then - if (iscft(ivt(p)) >= 1) then + if (iscft(ivt(p))) then if (offset_counter(p) == dt) then t1 = 1.0_r8 / dt @@ -3119,7 +3109,7 @@ subroutine CNOffsetLitterfall (num_soilp, filter_soilp, & else if (offset_counter(p) == dt) then t1 = 1.0_r8 / dt - if (iscft(ivt(p)) >= 1) then + if (iscft(ivt(p))) then ! this assumes that offset_counter == dt for crops ! if this were ever changed, we'd need to add code to the "else" leafn_to_litter(p) = (1.0_r8 - presharv(ivt(p))) * ((t1 * leafn(p)) + npool_to_leafn(p)) @@ -3503,7 +3493,7 @@ subroutine CNLitterToColumn (num_soilp, filter_soilp, & ! new ones for now (slevis) ! The food is now directed to the product pools (BDrewniak) - if (iscft(ivt(p)) >= 1) then ! add livestemc to litter + if (iscft(ivt(p))) then ! add livestemc to litter ! stem litter carbon fluxes phenology_c_to_litr_met_c(c,j) = phenology_c_to_litr_met_c(c,j) & + livestemc_to_litter(p) * lf_flab(ivt(p)) * wt_col * leaf_prof(p,j) diff --git a/components/elm/src/biogeochem/PhosphorusStateUpdate1Mod.F90 b/components/elm/src/biogeochem/PhosphorusStateUpdate1Mod.F90 index 01369ed83fa7..6e1111169221 100644 --- a/components/elm/src/biogeochem/PhosphorusStateUpdate1Mod.F90 +++ b/components/elm/src/biogeochem/PhosphorusStateUpdate1Mod.F90 @@ -255,7 +255,7 @@ subroutine PhosphorusStateUpdate1(num_soilc, filter_soilc, num_soilp, filter_soi veg_ps%deadcrootp_xfer(p) = veg_ps%deadcrootp_xfer(p) - veg_pf%deadcrootp_xfer_to_deadcrootp(p)*dt end if - if (iscft(ivt(p)) >= 1) then ! skip 2 generic crops + if (iscft(ivt(p))) then ! skip 2 generic crops ! lines here for consistency; the transfer terms are zero veg_ps%livestemp(p) = veg_ps%livestemp(p) + veg_pf%livestemp_xfer_to_livestemp(p)*dt veg_ps%livestemp_xfer(p) = veg_ps%livestemp_xfer(p) - veg_pf%livestemp_xfer_to_livestemp(p)*dt @@ -280,7 +280,7 @@ subroutine PhosphorusStateUpdate1(num_soilc, filter_soilc, num_soilp, filter_soi veg_ps%livecrootp(p) = veg_ps%livecrootp(p) - veg_pf%livecrootp_to_retransp(p)*dt veg_ps%retransp(p) = veg_ps%retransp(p) + veg_pf%livecrootp_to_retransp(p)*dt end if - if (iscft(ivt(p)) >= 1) then ! Beth adds retrans from froot + if (iscft(ivt(p))) then ! Beth adds retrans from froot veg_ps%frootp(p) = veg_ps%frootp(p) - veg_pf%frootp_to_retransp(p)*dt veg_ps%retransp(p) = veg_ps%retransp(p) + veg_pf%frootp_to_retransp(p)*dt veg_ps%livestemp(p) = veg_ps%livestemp(p) - veg_pf%livestemp_to_litter(p)*dt @@ -331,7 +331,7 @@ subroutine PhosphorusStateUpdate1(num_soilc, filter_soilc, num_soilp, filter_soi veg_ps%deadcrootp_storage(p) = veg_ps%deadcrootp_storage(p) + veg_pf%ppool_to_deadcrootp_storage(p)*dt end if - if (iscft(ivt(p)) >= 1) then ! skip 2 generic crops + if (iscft(ivt(p))) then ! skip 2 generic crops veg_ps%ppool(p) = veg_ps%ppool(p) - veg_pf%ppool_to_livestemp(p)*dt veg_ps%livestemp(p) = veg_ps%livestemp(p) + veg_pf%ppool_to_livestemp(p)*dt veg_ps%ppool(p) = veg_ps%ppool(p) - veg_pf%ppool_to_livestemp_storage(p)*dt @@ -359,7 +359,7 @@ subroutine PhosphorusStateUpdate1(num_soilc, filter_soilc, num_soilp, filter_soi veg_ps%deadcrootp_xfer(p) = veg_ps%deadcrootp_xfer(p) + veg_pf%deadcrootp_storage_to_xfer(p)*dt end if - if (iscft(ivt(p)) >= 1) then ! skip 2 generic crops + if (iscft(ivt(p))) then ! skip 2 generic crops ! lines here for consistency; the transfer terms are zero veg_ps%livestemp_storage(p) = veg_ps%livestemp_storage(p) - veg_pf%livestemp_storage_to_xfer(p)*dt veg_ps%livestemp_xfer(p) = veg_ps%livestemp_xfer(p) + veg_pf%livestemp_storage_to_xfer(p)*dt diff --git a/components/elm/src/biogeochem/PhosphorusStateUpdate2Mod.F90 b/components/elm/src/biogeochem/PhosphorusStateUpdate2Mod.F90 index 4aa7563c70f7..c6b6cd8ee6d3 100644 --- a/components/elm/src/biogeochem/PhosphorusStateUpdate2Mod.F90 +++ b/components/elm/src/biogeochem/PhosphorusStateUpdate2Mod.F90 @@ -182,7 +182,7 @@ subroutine PhosphorusStateUpdate2h(num_soilc, filter_soilc, num_soilp, filter_so veg_ps%retransp(p) = veg_ps%retransp(p) - veg_pf%hrv_retransp_to_litter(p) * dt veg_ps%ppool(p) = veg_ps%ppool(p) - veg_pf%hrv_ppool_to_litter(p) * dt - if (iscft(ivt(p)) >= 1) then ! skip 2 generic crops + if (iscft(ivt(p))) then ! skip 2 generic crops veg_ps%livestemp(p)= veg_ps%livestemp(p) - veg_pf%hrv_livestemp_to_prod1p(p) * dt veg_ps%leafp(p) = veg_ps%leafp(p) - veg_pf%hrv_leafp_to_prod1p(p) * dt veg_ps%grainp(p) = veg_ps%grainp(p) - veg_pf%hrv_grainp_to_prod1p(p) * dt diff --git a/components/elm/src/biogeochem/PrecisionControlMod.F90 b/components/elm/src/biogeochem/PrecisionControlMod.F90 index 2423592c05c2..10f601487cda 100644 --- a/components/elm/src/biogeochem/PrecisionControlMod.F90 +++ b/components/elm/src/biogeochem/PrecisionControlMod.F90 @@ -211,7 +211,7 @@ subroutine PrecisionControl(num_soilc, filter_soilc, num_soilp, filter_soilp) veg_ps%frootp_xfer(p) = 0._r8 end if - if ( crop_prog .and. iscft(veg_pp%itype(p)) >= 1 )then + if ( crop_prog .and. iscft(veg_pp%itype(p)))then ! grain C and N if (abs(veg_cs%grainc(p)) < ccrit) then pc = pc + veg_cs%grainc(p) @@ -513,7 +513,7 @@ subroutine PrecisionControl(num_soilc, filter_soilc, num_soilp, filter_soilp) endif end if - if ( crop_prog .and. iscft(veg_pp%itype(p)) >= 1 )then + if ( crop_prog .and. iscft(veg_pp%itype(p)))then ! xsmrpool (C only) if (abs(veg_cs%xsmrpool(p)) < ccrit) then pc = pc + veg_cs%xsmrpool(p) diff --git a/components/elm/src/biogeochem/RootDynamicsMod.F90 b/components/elm/src/biogeochem/RootDynamicsMod.F90 index f5ffc4c67844..9ea6a9812b0a 100644 --- a/components/elm/src/biogeochem/RootDynamicsMod.F90 +++ b/components/elm/src/biogeochem/RootDynamicsMod.F90 @@ -136,7 +136,7 @@ subroutine RootDynamics(bounds, num_soilc, filter_soilc, num_soilp, filter_soilp p = filter_soilp(f) c = pcolumn(p) if (ivt(p) /= noveg) then - if (iscft(ivt(p)) >= 1) then !skip generic crop types + if (iscft(ivt(p))) then !skip generic crop types if (huigrain(p) > 0._r8) then root_depth(p) = max(zi(c,2), min(hui(p)/huigrain(p)* root_dmx(ivt(p)), root_dmx(ivt(p)))) end if diff --git a/components/elm/src/biogeochem/VOCEmissionMod.F90 b/components/elm/src/biogeochem/VOCEmissionMod.F90 index fb7bd66958db..0a17f8803e73 100644 --- a/components/elm/src/biogeochem/VOCEmissionMod.F90 +++ b/components/elm/src/biogeochem/VOCEmissionMod.F90 @@ -703,7 +703,7 @@ function get_map_EF(ivt_in, g_in, ti_in, vocemis_vars) get_map_EF = vocemis_vars%efisop_grc(4,g_in, ti_in) else if (graminoid(ivt_in) == 1) then !grass get_map_EF = vocemis_vars%efisop_grc(5,g_in, ti_in) - else if (crop(ivt_in) == 1 .or. iscft(ivt_in) == 1) then !crops + else if (crop(ivt_in) == 1 .or. iscft(ivt_in)) then !crops get_map_EF = vocemis_vars%efisop_grc(6,g_in, ti_in) end if diff --git a/components/elm/src/biogeochem/VegStructUpdateMod.F90 b/components/elm/src/biogeochem/VegStructUpdateMod.F90 index c40e0fc0ea0d..5943da355a04 100644 --- a/components/elm/src/biogeochem/VegStructUpdateMod.F90 +++ b/components/elm/src/biogeochem/VegStructUpdateMod.F90 @@ -147,7 +147,7 @@ subroutine VegStructUpdate(num_soilp, filter_soilp, & ! alpha are set by PFT, and alpha is scaled to CLM time step by multiplying by ! dt and dividing by dtsmonth (seconds in average 30 day month) ! tsai_min scaled by 0.5 to match MODIS satellite derived values - if (crop(ivt(p)) == 1 .and. iscft(ivt(p)) == 0) then ! generic crops + if (crop(ivt(p)) == 1 .and. .not. iscft(ivt(p))) then ! generic crops tsai_alpha = 1.0_r8-1.0_r8*dt/dtsmonth tsai_min = 0.1_r8 @@ -193,7 +193,7 @@ subroutine VegStructUpdate(num_soilp, filter_soilp, & hbot(p) = max(0._r8, min(3._r8, htop(p)-1._r8)) - else if (iscft(ivt(p)) >= 1) then ! prognostic crops + else if (iscft(ivt(p))) then ! prognostic crops if (tlai(p) >= laimx(ivt(p))) peaklai(p) = 1 ! used in CNAllocation diff --git a/components/elm/src/biogeophys/SedYieldMod.F90 b/components/elm/src/biogeophys/SedYieldMod.F90 index e0d63ed063c9..250929f4a423 100644 --- a/components/elm/src/biogeophys/SedYieldMod.F90 +++ b/components/elm/src/biogeophys/SedYieldMod.F90 @@ -218,7 +218,7 @@ subroutine SoilErosion (bounds, num_soilc, filter_soilc, & (veg_cs%livecrootc(p)+veg_cs%deadcrootc(p))*croot_prof(p,1) ) fgndcov = exp( -gcbc_p(veg_pp%itype(p))*PCT_gnd - & gcbr_p(veg_pp%itype(p))*Broot ) - if( crop(veg_pp%itype(p)) >= 1 .or. iscft(veg_pp%itype(p)) >=1 )then + if( crop(veg_pp%itype(p)) >= 1 .or. iscft(veg_pp%itype(p)))then Es_Pcrp = Es_Pcrp + pfactor(c) * ftillage * flitho * & fgndcov * veg_pp%wtcol(p) * K * (KE_DT+KE_LD) @@ -266,7 +266,7 @@ subroutine SoilErosion (bounds, num_soilc, filter_soilc, & nh = 0.03_r8 + 0.05_r8*max(Crsd,Clai) fsr = fsr + veg_pp%wtcol(p) * (0.03_r8/nh)**0.6_r8 - if ( crop(veg_pp%itype(p)) >= 1 .or. iscft(veg_pp%itype(p)) >= 1 ) then + if ( crop(veg_pp%itype(p)) >= 1 .or. iscft(veg_pp%itype(p))) then ftillage_tc = ftillage_tc + ftillage * veg_pp%wtcol(p) Es_Q = Es_Q + 19.1_r8 * qfactor(c) * 2._r8/COH * flitho * fslp * & diff --git a/components/elm/src/data_types/VegetationDataType.F90 b/components/elm/src/data_types/VegetationDataType.F90 index ecbdca64df33..3bc7021f1509 100644 --- a/components/elm/src/data_types/VegetationDataType.F90 +++ b/components/elm/src/data_types/VegetationDataType.F90 @@ -2447,7 +2447,7 @@ subroutine veg_cs_init(this, begp, endp, carbon_type, ratio) if (veg_vp%evergreen(veg_pp%itype(p)) == 1._r8) then this%leafc(p) = 1._r8 * ratio this%leafc_storage(p) = 0._r8 - else if (iscft(veg_pp%itype(p)) >= 1) then ! prognostic crop types + else if (iscft(veg_pp%itype(p))) then ! prognostic crop types this%leafc(p) = 0._r8 this%leafc_storage(p) = 0._r8 else @@ -3572,7 +3572,7 @@ subroutine veg_cs_summary(this, bounds, num_soilc, filter_soilc, num_soilp, filt this%gresp_storage(p) + & this%gresp_xfer(p) - if ( crop_prog .and. iscft(veg_pp%itype(p)) >= 1 )then + if ( crop_prog .and. iscft(veg_pp%itype(p)))then this%storvegc(p) = & this%storvegc(p) + & this%grainc_storage(p) + & @@ -4249,7 +4249,7 @@ subroutine veg_ns_summary(this, bounds, num_soilc, filter_soilc, num_soilp, filt this%npool(p) + & this%retransn(p) - if ( crop_prog .and. iscft(veg_pp%itype(p)) >= 1 )then + if ( crop_prog .and. iscft(veg_pp%itype(p)))then this%dispvegn(p) = & this%dispvegn(p) + & this%grainn(p) @@ -4997,7 +4997,7 @@ subroutine veg_ps_summary (this, bounds, num_soilc, filter_soilc, num_soilp, fil this%ppool(p) + & this%retransp(p) - if ( crop_prog .and. iscft(veg_pp%itype(p)) >= 1 )then + if ( crop_prog .and. iscft(veg_pp%itype(p)))then this%dispvegp(p) = & this%dispvegp(p) + & this%grainp(p) @@ -8189,7 +8189,7 @@ subroutine veg_cf_summary(this, bounds, num_soilp, filter_soilp, num_soilc, filt this%cpool_livecroot_storage_gr(p) + & this%cpool_deadcroot_storage_gr(p) - if ( crop_prog .and. iscft(veg_pp%itype(p)) >= 1 )then + if ( crop_prog .and. iscft(veg_pp%itype(p)))then this%mr(p) = & this%mr(p) + & this%grain_mr(p) @@ -8214,7 +8214,7 @@ subroutine veg_cf_summary(this, bounds, num_soilp, filter_soilp, num_soilc, filt this%storage_gr(p) ! autotrophic respiration (AR) - if ( crop_prog .and. iscft(veg_pp%itype(p)) >= 1 )then + if ( crop_prog .and. iscft(veg_pp%itype(p)))then this%ar(p) = & this%mr(p) + & this%gr(p) + & @@ -8324,7 +8324,7 @@ subroutine veg_cf_summary(this, bounds, num_soilp, filter_soilp, num_soilc, filt this%wood_harvestc(p) = & this%hrv_deadstemc_to_prod10c(p) + & this%hrv_deadstemc_to_prod100c(p) - if ( crop_prog .and. iscft(veg_pp%itype(p)) >= 1 )then + if ( crop_prog .and. iscft(veg_pp%itype(p)))then this%wood_harvestc(p) = & this%wood_harvestc(p) + & this%hrv_cropc_to_prod1c(p) @@ -8354,7 +8354,7 @@ subroutine veg_cf_summary(this, bounds, num_soilp, filter_soilp, num_soilc, filt this%m_gresp_xfer_to_fire(p) + & this%m_cpool_to_fire(p) - if ( crop_prog .and. iscft(veg_pp%itype(p)) >= 1 )then + if ( crop_prog .and. iscft(veg_pp%itype(p)))then this%litfall(p) = & this%litfall(p) + & this%livestemc_to_litter(p) + & @@ -8393,7 +8393,7 @@ subroutine veg_cf_summary(this, bounds, num_soilp, filter_soilp, num_soilc, filt this%leafc_loss(p) = this%leafc_loss(p) + & this%hrv_leafc_to_litter(p) - if ( crop_prog .and. iscft(veg_pp%itype(p)) >= 1 )then + if ( crop_prog .and. iscft(veg_pp%itype(p)))then this%leafc_loss(p) = & this%leafc_loss(p) + & this%hrv_leafc_to_prod1c(p) @@ -8437,7 +8437,7 @@ subroutine veg_cf_summary(this, bounds, num_soilp, filter_soilp, num_soilc, filt this%hrv_deadcrootc_storage_to_litter(p) + & this%hrv_deadcrootc_xfer_to_litter(p) ! putting the harvested crop stem and grain in the wood loss bdrewniak - if ( crop_prog .and. iscft(veg_pp%itype(p)) >= 1 )then + if ( crop_prog .and. iscft(veg_pp%itype(p)))then this%woodc_loss(p) = & this%woodc_loss(p) + & this%hrv_grainc_to_prod1c(p) + & @@ -8562,7 +8562,7 @@ subroutine veg_cf_summary_for_ch4( this, bounds, num_soilp, filter_soilp) this%cpool_to_deadstemc(p) + & this%deadstemc_xfer_to_deadstemc(p) - if ( crop_prog .and. iscft(veg_pp%itype(p)) >= 1 )then + if ( crop_prog .and. iscft(veg_pp%itype(p)))then this%agnpp(p) = & this%agnpp(p) + & this%cpool_to_grainc(p) + & @@ -9720,7 +9720,7 @@ subroutine veg_nf_summary(this, bounds, num_soilc, filter_soilc, num_soilp, filt this%wood_harvestn(p) = & this%hrv_deadstemn_to_prod10n(p) + & this%hrv_deadstemn_to_prod100n(p) - if ( crop_prog .and. iscft(veg_pp%itype(p)) >= 1 )then + if ( crop_prog .and. iscft(veg_pp%itype(p)))then this%wood_harvestn(p) = & this%wood_harvestn(p) + & this%hrv_cropn_to_prod1n(p) @@ -10776,7 +10776,7 @@ subroutine veg_pf_summary(this, bounds, num_soilc, filter_soilc, num_soilp, filt this%wood_harvestp(p) = & this%hrv_deadstemp_to_prod10p(p) + & this%hrv_deadstemp_to_prod100p(p) - if ( crop_prog .and. iscft(veg_pp%itype(p)) >= 1 )then + if ( crop_prog .and. iscft(veg_pp%itype(p)))then this%wood_harvestp(p) = & this%wood_harvestp(p) + & this%hrv_cropp_to_prod1p(p) diff --git a/components/elm/src/data_types/VegetationPropertiesType.F90 b/components/elm/src/data_types/VegetationPropertiesType.F90 index 16f251377a43..12f9a7b22ffa 100644 --- a/components/elm/src/data_types/VegetationPropertiesType.F90 +++ b/components/elm/src/data_types/VegetationPropertiesType.F90 @@ -147,7 +147,7 @@ module VegetationPropertiesType real(r8), pointer :: climatezone(:) => null() !climate zone adapted real(r8), pointer :: nonvascular(:) => null() !nonvascular type or vascular real(r8), pointer :: graminoid(:) => null() !graminoid or not - real(r8), pointer :: iscft(:) => null() !generic crop (0) or (1) crop for prognostic crop modules + logical, pointer :: iscft(:) => null() !.false. = generic crop, .true. = prognostic crop real(r8), pointer :: needleleaf(:) => null() !needleleaf or broadleaf real(r8), pointer :: nfixer(:) => null() !cablity of nitrogen fixation from atm. N2 @@ -318,7 +318,7 @@ subroutine veg_vp_init(this) allocate( this%climatezone(0:numpft)) ; this%climatezone(:) =spval allocate( this%nonvascular(0:numpft)) ; this%nonvascular(:) =spval allocate( this%graminoid(0:numpft)) ; this%graminoid(:) =spval - allocate( this%iscft(0:numpft)) ; this%iscft(:) =spval + allocate( this%iscft(0:numpft)) ; this%iscft(:) =.false. allocate( this%needleleaf(0:numpft)) ; this%needleleaf(:) =spval allocate( this%nfixer(0:numpft)) ; this%nfixer(:) =spval ! ----------------------------------------------------------------------------------------------------------- diff --git a/components/elm/src/main/filterMod.F90 b/components/elm/src/main/filterMod.F90 index eb3f2f2ef1d0..e1dde9445598 100644 --- a/components/elm/src/main/filterMod.F90 +++ b/components/elm/src/main/filterMod.F90 @@ -420,7 +420,7 @@ subroutine setFiltersOneGroup(bounds, this_filter, include_inactive, icemask_grc t =veg_pp%topounit(p) if (top_pp%active(t)) then if (veg_pp%active(p) .or. include_inactive) then - if (iscft(veg_pp%itype(p)) < 1) then + if (.not. iscft(veg_pp%itype(p))) then l =veg_pp%landunit(p) if (lun_pp%itype(l) == istsoil .or. lun_pp%itype(l) == istcrop) then fnc = fnc + 1 diff --git a/components/elm/src/main/pftvarcon.F90 b/components/elm/src/main/pftvarcon.F90 index dc5d837472ae..9dcbb3cd6da6 100644 --- a/components/elm/src/main/pftvarcon.F90 +++ b/components/elm/src/main/pftvarcon.F90 @@ -318,7 +318,8 @@ module pftvarcon real(r8), allocatable :: nonvascular(:) ! nonvascular lifeform flag (0 = vascular, 1 = moss, 2 = lichen) real(r8), allocatable :: needleleaf(:) ! needleleaf lifeform flag (0 = broadleaf, 1 = needleleaf) real(r8), allocatable :: graminoid(:) ! graminoid lifeform flag (0 = nonvascular+woody+crop+percrop, 1 = graminoid) - real(r8), allocatable :: iscft(:) ! crop function type flag (0 = non_crop or generic crop, i.e. crop when use_crop=false, 1 = prognostic crop with cft created) + logical , allocatable :: iscft(:) ! crop function type flag (.false. = non_crop or generic crop, i.e. crop when use_crop=false, .true. = prognostic crop with cft created) + real(r8), allocatable :: temp_iscft(:) ! for file read, translated to logical afterwards real(r8), allocatable :: nfixer(:) ! nitrogen fixer flag (0 = inable, 1 = able to nitrogen fixation from atm. N2) @@ -369,6 +370,7 @@ subroutine pftconrd logical :: PFT_DEFAULT ! pft names are default, i.e. NOT user-defined integer :: ncft0, ncft ! crop pft index of first/last when 'create_crop_landunit' is true integer :: noncropmax ! max non-crop pft index (to check when 'create_crop_landunit' is true) + real(r8) :: local_iscft ! a local transfer of iscft from logical to integer for use in error checks character(len=32) :: subname = 'pftconrd' ! subroutine name ! ! Expected PFT names: The names expected on the paramfile file and the order they are expected to be in. @@ -642,6 +644,7 @@ subroutine pftconrd allocate( nonvascular (0:mxpft) ) allocate( graminoid (0:mxpft) ) allocate( iscft (0:mxpft) ) + allocate( temp_iscft (0:mxpft) ) allocate( needleleaf (0:mxpft) ) allocate( nfixer (0:mxpft) ) @@ -1127,17 +1130,22 @@ subroutine pftconrd end if end if - call ncd_io('iscft', iscft, 'read', ncid, readvar=readv) ! read-in is 'CFT' or not for crop type + call ncd_io('iscft', temp_iscft, 'read', ncid, readvar=readv) ! read-in is 'CFT' or not for crop type if ( .not. readv ) then if (PFT_DEFAULT) then - iscft(:) = 0 ! will assign a value below + temp_iscft(:) = 0._r8 ! will assign a value below else call endrun(msg='ERROR: error in reading in user-defined pft data'//errMsg(__FILE__,__LINE__)) end if end if call ncd_pio_closefile(ncid) - + + ! transfer the temporary real to logical + do i=0, mxpft + if (temp_iscft(i) == 1._r8) iscft(i) = .true. + if (temp_iscft(i) == 0._r8) iscft(i) = .false. + end do if ( PFT_DEFAULT ) then ! if still reading in default PFT physiology file, @@ -1233,7 +1241,7 @@ subroutine pftconrd ! when not using those indexing of PFT orders anymore in other codes than here. needleleaf(noveg+1:ndllf_dcd_brl_tree) = 1 graminoid(nc3_arctic_grass:nc4_grass) = 1 - iscft(npcropmin:max(npcropmax,nppercropmax)) = 1 + iscft(npcropmin:max(npcropmax,nppercropmax)) = .true. nfixer(nsoybean) = 1 nfixer(nsoybeanirrig) = 1 @@ -1251,7 +1259,6 @@ subroutine pftconrd !------------------------------------------------------------------------------------------- - ! NOT default PFT file else @@ -1270,16 +1277,16 @@ subroutine pftconrd ncft0 = -1 noncropmax = 0 do i = 0, npft-1 - if (crop(i)>=1 .or. percrop(i)>=1 .or. iscft(i)>=1) then + if (crop(i)>=1 .or. percrop(i)>=1 .or. iscft(i)) then numcft = numcft + 1 ! includes generic_crop, while cft_size NOT (???? todo checking) if(use_crop) then ! the following assumes that all crop pfts are in a block - ! if 'generic crop' (crop=1) specifically flagged by iscft=0 + ! if 'generic crop' (crop=1) specifically flagged by iscft=.false. ! 'crop' will not be counted into prognostic - if (crop(i)>=1 .and. iscft(i)==1) then + if (crop(i)>=1 .and. iscft(i)) then npcropmax = i if(npcropmin<=0) npcropmin = i end if @@ -1294,7 +1301,7 @@ subroutine pftconrd else if(crop(i)>=1 .or. percrop(i)>=1) then ! in case either 'crop' or 'generic crop' or both defined, it must be generic, when not use_crop=.true. - iscft(i) = 0 + iscft(i) = .false. end if end if @@ -1313,7 +1320,7 @@ subroutine pftconrd ! need to check 'noveg' if ( woody(i)<=0 .and. graminoid(i)<=0 .and. nonvascular(i)<=0 .and. & - iscft(i)<=0 .and. crop(i)<=0 .and. percrop(i)<=0) then + .not. iscft(i) .and. crop(i)<=0 .and. percrop(i)<=0) then if (noveg>=0) then ! not yet support multiple non-vegetated PFT ! this also will catch error of no actual PFT if npft>1 @@ -1365,24 +1372,26 @@ subroutine pftconrd ! checking of pft flags' conflict if ( .not. use_fates ) then do i = 0, mxpft + if (iscft(i)) local_iscft = 1._r8 + if (.not. iscft(i)) local_iscft = 0._r8 if (i == noveg) then - if ( (nonvascular(i)+woody(i)+graminoid(i)+max(iscft(i),crop(i)+percrop(i))) >= 1 .or. & + if ( (nonvascular(i)+woody(i)+graminoid(i)+max(local_iscft,crop(i)+percrop(i))) >= 1 .or. & (needleleaf(i)+evergreen(i)+stress_decid(i)+season_decid(i)+nfixer(i)) >= 1 ) then print *, 'ERROR: Incorrect not-vegetated PFT flags: ', i, ' ', trim(pftname(i)) call endrun(msg=' ERROR: not_vegetated has at least one positive PFT flag '//errMsg(__FILE__, __LINE__)) end if - else if ( (nonvascular(i)+woody(i)+graminoid(i)+max(iscft(i),crop(i)+percrop(i))) >= 1) then - if (nonvascular(i) >= 1 .and. (woody(i)+graminoid(i)+max(iscft(i),crop(i)+percrop(i))) >= 1) then + else if ( (nonvascular(i)+woody(i)+graminoid(i)+max(local_iscft,crop(i)+percrop(i))) >= 1) then + if (nonvascular(i) >= 1 .and. (woody(i)+graminoid(i)+max(local_iscft,crop(i)+percrop(i))) >= 1) then print *, 'ERROR: Incorrect nonvasculr PFT flags: ', i, ' ', trim(pftname(i)) call endrun(msg=' ERROR: nonvascular PFT cannot be any of woody/graminoid/crop type '//errMsg(__FILE__, __LINE__)) - else if (woody(i) >= 1 .and. (nonvascular(i)+graminoid(i)+max(iscft(i),crop(i)+percrop(i))) >= 1) then + else if (woody(i) >= 1 .and. (nonvascular(i)+graminoid(i)+max(local_iscft,crop(i)+percrop(i))) >= 1) then print *, 'ERROR: Incorrect woody PFT flags: ', i, ' ', trim(pftname(i)) call endrun(msg=' ERROR: woody PFT cannot be any of nonvascular/graminoid/crop type - '//errMsg(__FILE__, __LINE__)) - else if (graminoid(i) >= 1 .and. (nonvascular(i)+woody(i)+max(iscft(i),crop(i)+percrop(i))) >=1 ) then + else if (graminoid(i) >= 1 .and. (nonvascular(i)+woody(i)+max(local_iscft,crop(i)+percrop(i))) >=1 ) then print *, 'ERROR: Incorrect graminoid PFT flags: ', i, ' ', trim(pftname(i)) call endrun(msg=' ERROR: graminoid PFT cannot be any of nonvascular/woody/crop type - '//errMsg(__FILE__, __LINE__)) - else if ( (max(iscft(i),crop(i)+percrop(i))) >= 1 .and. (nonvascular(i)+woody(i)+graminoid(i)) >= 1) then + else if ( (max(local_iscft,crop(i)+percrop(i))) >= 1 .and. (nonvascular(i)+woody(i)+graminoid(i)) >= 1) then print *, 'ERROR: Incorrect crop PFT flags: ', i, ' ', trim(pftname(i)) call endrun(msg=' ERROR: crop PFT cannot be any of nonvascular/woody/graminoid type - '//errMsg(__FILE__, __LINE__)) end if @@ -1412,7 +1421,7 @@ subroutine pftconrd do i = 0, npft-1 write(iulog,*) i, pftname(i), int(climatezone(i)), int(woody(i)), int(needleleaf(i)), & int(evergreen(i)), int(stress_decid(i)), int(season_decid(i)), & - int(graminoid(i)), int(iscft(i)), int(crop(i)), int(percrop(i)), int(nfixer(i)) + int(graminoid(i)), int(local_iscft), int(crop(i)), int(percrop(i)), int(nfixer(i)) end do write(iulog,*) end if From 0f841e67a2a152cd35c85043783459057b891c78 Mon Sep 17 00:00:00 2001 From: Peter Thornton Date: Mon, 26 Aug 2024 22:26:27 -0400 Subject: [PATCH 346/451] Fixes a bug, uninitialized variable in pftvarcon --- components/elm/src/main/pftvarcon.F90 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/components/elm/src/main/pftvarcon.F90 b/components/elm/src/main/pftvarcon.F90 index 9dcbb3cd6da6..fc5bfd54e7d3 100644 --- a/components/elm/src/main/pftvarcon.F90 +++ b/components/elm/src/main/pftvarcon.F90 @@ -1421,7 +1421,7 @@ subroutine pftconrd do i = 0, npft-1 write(iulog,*) i, pftname(i), int(climatezone(i)), int(woody(i)), int(needleleaf(i)), & int(evergreen(i)), int(stress_decid(i)), int(season_decid(i)), & - int(graminoid(i)), int(local_iscft), int(crop(i)), int(percrop(i)), int(nfixer(i)) + int(graminoid(i)), int(temp_iscft(i)), int(crop(i)), int(percrop(i)), int(nfixer(i)) end do write(iulog,*) end if From 485ca5850eb05cade08a12ccd3506b76a176ecbb Mon Sep 17 00:00:00 2001 From: Wuyin Lin Date: Tue, 27 Aug 2024 13:44:42 -0500 Subject: [PATCH 347/451] Correct linoz_data_type for hist-nat --- .../use_cases/20TR_eam_CMIP6-nat_chemUCI-Linoz-mam5-vbs.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/components/eam/bld/namelist_files/use_cases/20TR_eam_CMIP6-nat_chemUCI-Linoz-mam5-vbs.xml b/components/eam/bld/namelist_files/use_cases/20TR_eam_CMIP6-nat_chemUCI-Linoz-mam5-vbs.xml index 8f3a2644527d..94cdfc6d000d 100644 --- a/components/eam/bld/namelist_files/use_cases/20TR_eam_CMIP6-nat_chemUCI-Linoz-mam5-vbs.xml +++ b/components/eam/bld/namelist_files/use_cases/20TR_eam_CMIP6-nat_chemUCI-Linoz-mam5-vbs.xml @@ -107,7 +107,7 @@ 1850 linv3_1849-2017_CMIP6_Hist_10deg_58km_c20230705.nc atm/cam/chem/trop_mozart/ub -INTERP_MISSING_MONTHS +CYCLICAL SERIAL From ffb3b6103bc182b235a0c9392e56be41c801dc85 Mon Sep 17 00:00:00 2001 From: Iulian Grindeanu Date: Tue, 27 Aug 2024 15:10:10 -0500 Subject: [PATCH 348/451] initialize factors in area correction computations to 1.0 only intel on chrysalis complained about it It could be a cause for trouble later on --- driver-moab/main/component_mod.F90 | 1 + 1 file changed, 1 insertion(+) diff --git a/driver-moab/main/component_mod.F90 b/driver-moab/main/component_mod.F90 index 88d152a95685..3e8ba9042a58 100644 --- a/driver-moab/main/component_mod.F90 +++ b/driver-moab/main/component_mod.F90 @@ -748,6 +748,7 @@ subroutine component_init_areacor_moab (comp, mbccid, mbcxid, seq_flds_c2x_fluxe lsize = comp(1)%mblsize allocate(areas (lsize, 3)) ! lsize is along grid; read mask too allocate(factors (lsize, 2)) + factors = 1.0 ! initialize with 1.0 all factors; then maybe correct them ! get areas tagname='area:aream:mask'//C_NULL_CHAR arrsize = 3 * lsize From e9c56ec7fcf812f3e92fc9bac1341fc68716deba Mon Sep 17 00:00:00 2001 From: Matthew Hoffman Date: Tue, 27 Aug 2024 17:04:21 -0500 Subject: [PATCH 349/451] Turn on depth-int solver for 1km GIS; add more output vars --- .../bld/namelist_files/albany_input.gis_1to10km_r01.yaml | 3 +++ .../bld/namelist_files/albany_input.gis_1to10km_r02.yaml | 2 ++ components/mpas-albany-landice/cime_config/buildnml | 2 ++ 3 files changed, 7 insertions(+) diff --git a/components/mpas-albany-landice/bld/namelist_files/albany_input.gis_1to10km_r01.yaml b/components/mpas-albany-landice/bld/namelist_files/albany_input.gis_1to10km_r01.yaml index 589e163bba7f..c1b2e310f323 100644 --- a/components/mpas-albany-landice/bld/namelist_files/albany_input.gis_1to10km_r01.yaml +++ b/components/mpas-albany-landice/bld/namelist_files/albany_input.gis_1to10km_r01.yaml @@ -2,6 +2,9 @@ --- ANONYMOUS: + Problem: + Depth Integrated Model: true + # Discretization Description Discretization: #Exodus Output File Name: albany_output.exo diff --git a/components/mpas-albany-landice/bld/namelist_files/albany_input.gis_1to10km_r02.yaml b/components/mpas-albany-landice/bld/namelist_files/albany_input.gis_1to10km_r02.yaml index 2b70fd9b30fa..45539411756a 100644 --- a/components/mpas-albany-landice/bld/namelist_files/albany_input.gis_1to10km_r02.yaml +++ b/components/mpas-albany-landice/bld/namelist_files/albany_input.gis_1to10km_r02.yaml @@ -1,7 +1,9 @@ %YAML 1.1 --- ANONYMOUS: + Problem: + Depth Integrated Model: true Basal Cubature Degree: 4 LandIce Field Norm: sliding_velocity_basalside: diff --git a/components/mpas-albany-landice/cime_config/buildnml b/components/mpas-albany-landice/cime_config/buildnml index a42011e54073..9489b6dfa8fd 100755 --- a/components/mpas-albany-landice/cime_config/buildnml +++ b/components/mpas-albany-landice/cime_config/buildnml @@ -238,8 +238,10 @@ def buildnml(case, caseroot, compname): lines.append(' ') lines.append(' ') lines.append(' ') + lines.append(' ') lines.append(' ') lines.append(' ') + lines.append(' ') lines.append(' ') lines.append(' ') lines.append(' ') From 383f137c1e79ea37664cc72ac41a1956fbd0dbd7 Mon Sep 17 00:00:00 2001 From: Wuyin Lin Date: Tue, 27 Aug 2024 22:00:20 -0500 Subject: [PATCH 350/451] Add compset hist-all-xaer --- cime_config/allactive/config_compsets.xml | 10 ++ ..._eam_CMIP6-xaer_chemUCI-Linoz-mam5-vbs.xml | 117 ++++++++++++++++++ .../eam/cime_config/config_component.xml | 1 + .../elm/cime_config/config_component.xml | 1 + 4 files changed, 129 insertions(+) create mode 100644 components/eam/bld/namelist_files/use_cases/20TR_eam_CMIP6-xaer_chemUCI-Linoz-mam5-vbs.xml diff --git a/cime_config/allactive/config_compsets.xml b/cime_config/allactive/config_compsets.xml index 63883bff15d9..28eefc45b765 100755 --- a/cime_config/allactive/config_compsets.xml +++ b/cime_config/allactive/config_compsets.xml @@ -158,6 +158,16 @@ 20TRSOI_EAM%CMIP6-VOLC_ELM%CNPRDCTCBCTOP_MPASSI_MPASO_MOSART_SGLC_SWAV + + WCYCL20TR-xaer + 20TRSOI_EAM%CMIP6-xAER_ELM%CNPRDCTCBCTOP_MPASSI_MPASO_MOSART_SGLC_SWAV + + + + hist-all-xaer + 20TRSOI_EAM%CMIP6-xAER_ELM%CNPRDCTCBCTOP_MPASSI_MPASO_MOSART_SGLC_SWAV + + diff --git a/components/eam/bld/namelist_files/use_cases/20TR_eam_CMIP6-xaer_chemUCI-Linoz-mam5-vbs.xml b/components/eam/bld/namelist_files/use_cases/20TR_eam_CMIP6-xaer_chemUCI-Linoz-mam5-vbs.xml new file mode 100644 index 000000000000..359a292e9e12 --- /dev/null +++ b/components/eam/bld/namelist_files/use_cases/20TR_eam_CMIP6-xaer_chemUCI-Linoz-mam5-vbs.xml @@ -0,0 +1,117 @@ + + + + +.true. + + +.true. +.true. +.true. + + +atm/cam/solar/Solar_1850-2299_input4MIPS_c20181106.nc +SERIAL + + +atm/cam/ggas/GHG_CMIP-1-2-0_Annual_Global_0000-2014_c20180105.nc +RAMPED + + + +CYCLICAL +1850 +atm/cam/chem/trop_mozart_aero/emis/chem_gases/2degrees/emissions-cmip6_NO2_aircraft_vertical_1750-2015_1.9x2.5_c20170608.nc +atm/cam/chem/trop_mozart_aero/emis/DECK_ne30/cmip6_mam4_so2_elev_1850-2014_c180205_1850-aero_hist-volcano.nc +atm/cam/chem/trop_mozart_aero/emis/DECK_ne30/emissions-cmip6_e3sm_SOAG0_elev_1850-2014_1.9x2.5_c20230201.nc +atm/cam/chem/trop_mozart_aero/emis/DECK_ne30/cmip6_mam4_bc_a4_elev_1850-2014_c180205.nc +atm/cam/chem/trop_mozart_aero/emis/DECK_ne30/cmip6_mam4_num_a1_elev_1850-2014_c180205.nc +atm/cam/chem/trop_mozart_aero/emis/DECK_ne30/cmip6_mam4_num_a2_elev_1850-2014_c180205.nc +atm/cam/chem/trop_mozart_aero/emis/DECK_ne30/cmip6_mam4_num_a4_elev_1850-2014_c180205.nc +atm/cam/chem/trop_mozart_aero/emis/DECK_ne30/cmip6_mam4_pom_a4_elev_1850-2014_c180205.nc +atm/cam/chem/trop_mozart_aero/emis/DECK_ne30/cmip6_mam4_so4_a1_elev_1850-2014_c180205.nc +atm/cam/chem/trop_mozart_aero/emis/DECK_ne30/cmip6_mam4_so4_a2_elev_1850-2014_c180205.nc + + +CYCLICAL +1850 +atm/cam/chem/trop_mozart_aero/emis/chem_gases/2degrees/emissions-cmip6_e3sm_C2H4_surface_1850-2014_1.9x2.5_c20210323.nc +atm/cam/chem/trop_mozart_aero/emis/chem_gases/2degrees/emissions-cmip6_e3sm_C2H6_surface_1850-2014_1.9x2.5_c20210323.nc +atm/cam/chem/trop_mozart_aero/emis/chem_gases/2degrees/emissions-cmip6_e3sm_C3H8_surface_1850-2014_1.9x2.5_c20210323.nc +atm/cam/chem/trop_mozart_aero/emis/chem_gases/2degrees/emissions-cmip6_e3sm_CH2O_surface_1850-2014_1.9x2.5_c20210323.nc +atm/cam/chem/trop_mozart_aero/emis/chem_gases/2degrees/emissions-cmip6_e3sm_CH3CHO_surface_1850-2014_1.9x2.5_c20210323.nc +atm/cam/chem/trop_mozart_aero/emis/chem_gases/2degrees/emissions-cmip6_e3sm_CH3COCH3_surface_1850-2014_1.9x2.5_c20210323.nc +atm/cam/chem/trop_mozart_aero/emis/chem_gases/2degrees/emissions-cmip6_e3sm_CO_surface_1850-2014_1.9x2.5_c20210323.nc +atm/cam/chem/trop_mozart_aero/emis/chem_gases/2degrees/emissions-cmip6_e3sm_ISOP_surface_1850-2014_1.9x2.5_c20210323.nc +atm/cam/chem/trop_mozart_aero/emis/chem_gases/2degrees/emissions-cmip6_e3sm_ISOP_surface_1850-2014_1.9x2.5_c20210323.nc +atm/cam/chem/trop_mozart_aero/emis/chem_gases/2degrees/emissions-cmip6_e3sm_MTERP_surface_1850-2014_1.9x2.5_c20230126.nc +atm/cam/chem/trop_mozart_aero/emis/chem_gases/2degrees/emissions-cmip6_e3sm_NO_surface_1850-2014_1.9x2.5_c20220425.nc +atm/cam/chem/trop_mozart_aero/emis/DMSflux.1850.1deg_latlon_conserv.POPmonthlyClimFromACES4BGC_c20160416.nc +atm/cam/chem/trop_mozart_aero/emis/DECK_ne30/emissions-cmip6_e3sm_SOAG0_surf_1850-2014_1.9x2.5_c20230201.nc +atm/cam/chem/trop_mozart_aero/emis/DECK_ne30/cmip6_mam4_so2_surf_1850-2014_c180205.nc +atm/cam/chem/trop_mozart_aero/emis/DECK_ne30/cmip6_mam4_bc_a4_surf_1850-2014_c180205.nc +atm/cam/chem/trop_mozart_aero/emis/DECK_ne30/cmip6_mam4_num_a1_surf_1850-2014_c180205.nc +atm/cam/chem/trop_mozart_aero/emis/DECK_ne30/cmip6_mam4_num_a2_surf_1850-2014_c180205.nc +atm/cam/chem/trop_mozart_aero/emis/DECK_ne30/cmip6_mam4_num_a4_surf_1850-2014_c180205.nc +atm/cam/chem/trop_mozart_aero/emis/DECK_ne30/cmip6_mam4_pom_a4_surf_1850-2014_c180205.nc +atm/cam/chem/trop_mozart_aero/emis/DECK_ne30/cmip6_mam4_so4_a1_surf_1850-2014_c180205.nc +atm/cam/chem/trop_mozart_aero/emis/DECK_ne30/cmip6_mam4_so4_a2_surf_1850-2014_c180205.nc +atm/cam/chem/trop_mozart_aero/emis/chem_gases/2degrees/emissions_E90_surface_1750-2015_1.9x2.5_c20210408.nc + + + + +CYCLICAL +1849 +oxid_1.9x2.5_L26_1850-2015_c20181106.nc +'' +atm/cam/chem/trop_mozart_aero/oxid +'prsd_O3:O3','prsd_NO3:NO3','prsd_OH:OH' + + +ch4_oxid_1.9x2.5_L26_1990-1999clim.c090804.nc +atm/cam/chem/methane +CYCLICAL +1995 +'' +'prsd_ch4:CH4' + + + + 'A:H2OLNZ:H2O', 'N:O2:O2', 'N:CO2:CO2', + 'A:O3:O3', 'A:N2OLNZ:N2O', 'A:CH4LNZ:CH4', + 'N:CFC11:CFC11', 'N:CFC12:CFC12', + 'M:mam5_mode1:$INPUTDATA_ROOT/atm/cam/physprops/mam4_mode1_rrtmg_aeronetdust_c141106.nc', + 'M:mam5_mode2:$INPUTDATA_ROOT/atm/cam/physprops/mam4_mode2_rrtmg_c130628.nc', + 'M:mam5_mode3:$INPUTDATA_ROOT/atm/cam/physprops/mam4_mode3_rrtmg_aeronetdust_c141106.nc', + 'M:mam5_mode4:$INPUTDATA_ROOT/atm/cam/physprops/mam4_mode4_rrtmg_c130628.nc', + 'M:mam5_mode5:$INPUTDATA_ROOT/atm/cam/physprops/mam5_mode5_rrtmg_sig1.2_dgnl.40_c03072023.nc' + + + +3 +1 +'atm/cam/chem/trop_mam/marine_BGC/' +'CYCLICAL' +'monthly_macromolecules_0.1deg_bilinear_latlon_year01_merge_date.nc' +0 +0 +'chla:CHL1','mpoly:TRUEPOLYC','mprot:TRUEPROTC','mlip:TRUELIPC' + +atm/cam/chem/trop_mozart/ub/Linoz_Chlorine_Loading_CMIP6_0003-2017_c20171114.nc +SERIAL +linv3_1849-2017_CMIP6_Hist_10deg_58km_c20230705.nc +atm/cam/chem/trop_mozart/ub +INTERP_MISSING_MONTHS + + +SERIAL + + +'xactive_lnd' +'O3','H2O2','CH2O','CH3OOH','NO','NO2','HNO3','HO2NO2','PAN','CO','CH3COCH3','C2H5OOH','CH3CHO','H2SO4','SO2','NO3','N2O5','SOAG0','SOAG15','SOAG24','SOAG35','SOAG34','SOAG33','SOAG32','SOAG31' +'NEU' +'C2H5OOH','CH2O','CH3CHO','CH3OOH','H2O2','H2SO4','HNO3','HO2NO2','SO2','SOAG0','SOAG15','SOAG24','SOAG35','SOAG34','SOAG33','SOAG32','SOAG31' +'CH2O', 'CH3O2', 'CH3OOH', 'PAN', 'CO', 'C2H6', 'C3H8', 'C2H4', 'ROHO2', 'CH3COCH3', 'C2H5O2', 'C2H5OOH', 'CH3CHO', 'CH3CO3', 'ISOP', 'ISOPO2', 'MVKMACR', 'MVKO2' +'' + diff --git a/components/eam/cime_config/config_component.xml b/components/eam/cime_config/config_component.xml index 8f1e68161cb7..655d7be5503c 100755 --- a/components/eam/cime_config/config_component.xml +++ b/components/eam/cime_config/config_component.xml @@ -131,6 +131,7 @@ 20TR_eam_CMIP6-aer_chemUCI-Linoz-mam5-vbs 20TR_eam_CMIP6-nat_chemUCI-Linoz-mam5-vbs 20TR_eam_CMIP6-xGHG-xaer_chemUCI-Linoz-mam5-vbs + 20TR_eam_CMIP6-xaer_chemUCI-Linoz-mam5-vbs 20TR_eam_CMIP6-ozone_chemUCI-Linoz-mam5-vbs 20TR_eam_CMIP6-lulc_chemUCI-Linoz-mam5-vbs 20TR_eam_CMIP6-volc_chemUCI-Linoz-mam5-vbs diff --git a/components/elm/cime_config/config_component.xml b/components/elm/cime_config/config_component.xml index b191a0a2248d..00518b5dc780 100755 --- a/components/elm/cime_config/config_component.xml +++ b/components/elm/cime_config/config_component.xml @@ -79,6 +79,7 @@ 20thC_CMIP6xLULC_transient 20thC_CMIP6xLULC_transient 20thC_CMIP6_transient + 20thC_CMIP6_transient 20thC_CMIP6_transient 20thC_CMIP6bgc_transient 20thC_CMIP6bgc_transient From 58b4220130cd4c5eea4908dee0c56bbef97f7347 Mon Sep 17 00:00:00 2001 From: James Foucar Date: Wed, 28 Aug 2024 13:54:27 -0600 Subject: [PATCH 351/451] Revert ers change --- cime | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cime b/cime index eacb1b7f5ed9..3dfad8399b80 160000 --- a/cime +++ b/cime @@ -1 +1 @@ -Subproject commit eacb1b7f5ed984f0c124076c78fd1e80dbd9b7a1 +Subproject commit 3dfad8399b803d724365c559c5b84e5546049e0c From bd79ca9ce10bafa8ec2d2f170bec5863d73b860e Mon Sep 17 00:00:00 2001 From: Azamat Mametjanov Date: Wed, 28 Aug 2024 20:35:07 +0000 Subject: [PATCH 352/451] Run in 4-CCS mode --- cime_config/machines/config_machines.xml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/cime_config/machines/config_machines.xml b/cime_config/machines/config_machines.xml index b6ac815f58f6..fed0110bc32b 100644 --- a/cime_config/machines/config_machines.xml +++ b/cime_config/machines/config_machines.xml @@ -3385,7 +3385,7 @@ 104 104 104 - 12 + 48 FALSE mpiexec @@ -3444,6 +3444,7 @@ 20 $ENV{KOKKOS_ROOT} 1 + 0:4,1:4,2:4,3:4:4:4,5:4,6:4,7:4 0 From 6ae05889a8664d227995f661cdbeae13e3b9136d Mon Sep 17 00:00:00 2001 From: Azamat Mametjanov Date: Wed, 28 Aug 2024 20:43:22 +0000 Subject: [PATCH 353/451] Disable openmp-offload --- cime_config/machines/Depends.oneapi-ifxgpu.cmake | 15 +++------------ 1 file changed, 3 insertions(+), 12 deletions(-) diff --git a/cime_config/machines/Depends.oneapi-ifxgpu.cmake b/cime_config/machines/Depends.oneapi-ifxgpu.cmake index 0dd35e56bcc9..5a958df26eba 100644 --- a/cime_config/machines/Depends.oneapi-ifxgpu.cmake +++ b/cime_config/machines/Depends.oneapi-ifxgpu.cmake @@ -1,14 +1,5 @@ -set(CPPDEFS "${CPPDEFS} -DMPAS_OPENMP_OFFLOAD") -list(APPEND MPAS_ADD_ACC_FLAGS - ${CMAKE_BINARY_DIR}/core_seaice/shared/mpas_seaice_mesh_pool.f90 - ${CMAKE_BINARY_DIR}/core_seaice/shared/mpas_seaice_velocity_solver_variational.f90 - ${CMAKE_BINARY_DIR}/core_seaice/shared/mpas_seaice_velocity_solver.f90 -) - -foreach(ITEM IN LISTS MPAS_ADD_ACC_FLAGS) - e3sm_add_flags("${ITEM}" "-fiopenmp -fopenmp-targets=spir64") -endforeach() - # compile mpas_seaice_core_interface.f90 with ifort, not ifx -e3sm_add_flags("${CMAKE_BINARY_DIR}/core_seaice/model_forward/mpas_seaice_core_interface.f90" "-fc=ifort") +if (NOT MPILIB STREQUAL "openmpi") + e3sm_add_flags("${CMAKE_BINARY_DIR}/core_seaice/model_forward/mpas_seaice_core_interface.f90" "-fc=ifort") +endif() From c9d94bbdfdf1a622e74bc001dbd126f78fc1d11c Mon Sep 17 00:00:00 2001 From: Wuyin Lin Date: Wed, 28 Aug 2024 22:25:14 -0500 Subject: [PATCH 354/451] Put modified tracer_data.F90 on the correct path --- components/eam/src/chemistry/utils/tracer_data.F90 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/components/eam/src/chemistry/utils/tracer_data.F90 b/components/eam/src/chemistry/utils/tracer_data.F90 index 073aacff6e47..62ccbcef8a25 100644 --- a/components/eam/src/chemistry/utils/tracer_data.F90 +++ b/components/eam/src/chemistry/utils/tracer_data.F90 @@ -660,7 +660,7 @@ subroutine advance_trcdata( flds, file, state, pbuf2d ) call t_startf('read_next_trcdata') call read_next_trcdata(state, flds, file ) call t_stopf('read_next_trcdata') - if(masterproc) write(iulog,*) 'READ_NEXT_TRCDATA ', flds%fldnam + if(masterproc) write(iulog,*) 'READ_NEXT_TRCDATA ', flds%fldnam,data_time end if endif From c5eb35f37c838964d732226c8a5b659b6387a5a8 Mon Sep 17 00:00:00 2001 From: Wuyin Lin Date: Wed, 28 Aug 2024 22:27:03 -0500 Subject: [PATCH 355/451] Remove the mis-placed tracer_data.F90 --- .../eam/src/chemistry/mozart/tracer_data.F90 | 2884 ----------------- 1 file changed, 2884 deletions(-) delete mode 100644 components/eam/src/chemistry/mozart/tracer_data.F90 diff --git a/components/eam/src/chemistry/mozart/tracer_data.F90 b/components/eam/src/chemistry/mozart/tracer_data.F90 deleted file mode 100644 index 62ccbcef8a25..000000000000 --- a/components/eam/src/chemistry/mozart/tracer_data.F90 +++ /dev/null @@ -1,2884 +0,0 @@ -module tracer_data -!----------------------------------------------------------------------- -! module used to read (and interpolate) offline tracer data (sources and -! mixing ratios) -! Created by: Francis Vitt -- 2 May 2006 -! Modified by : Jim Edwards -- 10 March 2009 -! Modified by : Cheryl Craig and Chih-Chieh (Jack) Chen -- February 2010 -! Modified by : Jinbo Xie --March 2023 -! Added a new option in interpolate_trcdata to work on linoz -! inputdata. A new UCI interpolation that better conserves -! mass in implemented and added a new function. It is called -! when linoz data are used in interpolate_trcdata. -! -!----------------------------------------------------------------------- - - use perf_mod, only : t_startf, t_stopf - use shr_kind_mod, only : r8 => shr_kind_r8,r4 => shr_kind_r4, shr_kind_cl, SHR_KIND_CS - use time_manager, only : get_curr_date, get_step_size, get_curr_calday - use spmd_utils, only : masterproc - use ppgrid, only : pcols, pver, pverp, begchunk, endchunk - use cam_abortutils, only : endrun - use cam_logfile, only : iulog - - use physics_buffer, only : physics_buffer_desc, pbuf_get_field, pbuf_get_index - use time_manager, only : set_time_float_from_date, set_date_from_time_float - use pio, only : file_desc_t, var_desc_t, & - pio_seterrorhandling, pio_internal_error, pio_bcast_error, & - pio_setdebuglevel, & - pio_char, pio_noerr, & - pio_inq_dimid, pio_inq_varid, & - pio_def_dim, pio_def_var, & - pio_put_att, pio_put_var, & - pio_get_var, pio_get_att, pio_nowrite, pio_inq_dimlen, & - pio_inq_vardimid, pio_inq_dimlen, pio_closefile, & - pio_inquire_variable - - implicit none - - private ! all unless made public - save - - public :: trfld, input3d, input2d, trfile - public :: trcdata_init - public :: advance_trcdata - public :: get_fld_data - public :: put_fld_data - public :: get_fld_ndx - public :: write_trc_restart - public :: read_trc_restart - public :: init_trc_restart - public :: incr_filename - !added public for linoz new function diagnostic - public :: read_next_trcdata - public :: interpolate_trcdata - public :: get_model_time - !!PUBLIC MEMBERS - - type input3d - real(r8), dimension(:,:,:), pointer :: data => null() - endtype input3d - - type input2d - real(r8), dimension(:,:), pointer :: data => null() - endtype input2d - - type trfld - real(r8), dimension(:,:,:), pointer :: data => null() - type(input3d), dimension(4) :: input - character(len=32) :: srcnam - character(len=32) :: fldnam - character(len=32) :: units - type(var_desc_t) :: var_id - integer :: coords(4) ! LATDIM | LONDIM | LEVDIM | TIMDIM - integer :: order(4) ! LATDIM | LONDIM | LEVDIM | TIMDIM - logical :: srf_fld = .false. - integer :: pbuf_ndx = -1 - endtype trfld - - type trfile - type(input2d), dimension(4) :: ps_in - character(len=shr_kind_cl) :: pathname = ' ' - character(len=shr_kind_cl) :: curr_filename = ' ' - character(len=shr_kind_cl) :: next_filename = ' ' - type(file_desc_t) :: curr_fileid - type(file_desc_t) :: next_fileid - - type(var_desc_t), pointer :: currfnameid => null() ! pio restart file var id - type(var_desc_t), pointer :: nextfnameid => null() ! pio restart file var id - - character(len=shr_kind_cl) :: filenames_list = '' - real(r8) :: datatimem = -1.e36_r8 ! time of prv. values read in - real(r8) :: datatimep = -1.e36_r8 ! time of nxt. values read in - real(r8) :: datatimes(4) - integer :: interp_recs - real(r8), pointer, dimension(:) :: curr_data_times => null() - real(r8), pointer, dimension(:) :: next_data_times => null() - logical :: remove_trc_file = .false. ! delete file when finished with it - real(r8) :: offset_time - integer :: cyc_ndx_beg - integer :: cyc_ndx_end - integer :: cyc_yr = 0 - real(r8) :: one_yr = 0 - real(r8) :: curr_mod_time ! model time - calendar day - real(r8) :: next_mod_time ! model time - calendar day - next time step - integer :: nlon - integer :: nlat - integer :: nlev - integer :: nilev - integer :: ps_coords(3) ! LATDIM | LONDIM | TIMDIM - integer :: ps_order(3) ! LATDIM | LONDIM | TIMDIM - real(r8), pointer, dimension(:) :: lons => null() - real(r8), pointer, dimension(:) :: lats => null() - real(r8), pointer, dimension(:) :: levs => null() - real(r8), pointer, dimension(:) :: ilevs => null() - real(r8), pointer, dimension(:) :: hyam => null() - real(r8), pointer, dimension(:) :: hybm => null() - real(r8), pointer, dimension(:,:) :: ps => null() - real(r8), pointer, dimension(:) :: hyai => null() - real(r8), pointer, dimension(:) :: hybi => null() - real(r8), pointer, dimension(:,:) :: weight_x => null(), weight_y => null() - integer, pointer, dimension(:) :: count_x => null(), count_y => null() - integer, pointer, dimension(:,:) :: index_x => null(), index_y => null() - real(r8) :: p0 - type(var_desc_t) :: ps_id - logical, allocatable, dimension(:) :: in_pbuf - logical :: has_ps = .false. - logical :: zonal_ave = .false. - logical :: alt_data = .false. - logical :: cyclical = .false. - logical :: cyclical_list = .false. - logical :: weight_by_lat = .false. - logical :: conserve_column = .false. - logical :: fill_in_months = .false. - logical :: fixed = .false. - logical :: initialized = .false. - logical :: top_bndry = .false. - logical :: stepTime = .false. ! Do not interpolate in time, but use stepwise times - logical :: linoz_v3 = .false. !set for linoz_v3 interpolation only - logical :: linoz_v2 = .false. !set for linoz_v2 interpolation only - endtype trfile - - integer, public, parameter :: MAXTRCRS = 100 - - integer, parameter :: LONDIM = 1 - integer, parameter :: LATDIM = 2 - integer, parameter :: LEVDIM = 3 - integer, parameter :: TIMDIM = 4 - - integer, parameter :: PS_TIMDIM = 3 - - integer, parameter :: ZA_LATDIM = 1 - integer, parameter :: ZA_LEVDIM = 2 - integer, parameter :: ZA_TIMDIM = 3 - - integer, parameter :: nm=1 ! array index for previous (minus) data - integer, parameter :: np=2 ! array index for next (plus) data - - integer :: plon, plat - -contains - -!-------------------------------------------------------------------------- -!-------------------------------------------------------------------------- - subroutine trcdata_init( specifier, filename, filelist, datapath, flds, file, & - rmv_file, data_cycle_yr, data_fixed_ymd, data_fixed_tod, data_type ) - - use mo_constants, only : d2r - use cam_control_mod, only : nsrest - use dyn_grid, only : get_dyn_grid_parm - use string_utils, only : to_upper - use horizontal_interpolate, only : xy_interp_init -#if ( defined SPMD ) - use mpishorthand, only: mpicom, mpir8, mpiint -#endif - - implicit none - - character(len=*), intent(in) :: specifier(:) - character(len=*), intent(in) :: filename - character(len=*), intent(in) :: filelist - character(len=*), intent(in) :: datapath - type(trfld), dimension(:), pointer :: flds - type(trfile), intent(inout) :: file - logical, intent(in) :: rmv_file - integer, intent(in) :: data_cycle_yr - integer, intent(in) :: data_fixed_ymd - integer, intent(in) :: data_fixed_tod - character(len=*), intent(in) :: data_type - - integer :: f, mxnflds, astat - integer :: str_yr, str_mon, str_day - integer :: lon_dimid, lat_dimid, lev_dimid, tim_dimid, old_dimid - integer :: dimids(4), did - type(var_desc_t) :: varid - integer :: idx - integer :: ierr - integer :: errcode - real(r8) :: start_time, time1, time2 - integer :: i1,i2,j1,j2 - integer :: nvardims, vardimids(4) - - character(len=80) :: data_units - - call specify_fields( specifier, flds ) - - file%datatimep=-1.e36_r8 - file%datatimem=-1.e36_r8 - - mxnflds = 0 - if (associated(flds)) mxnflds = size( flds ) - - if (mxnflds < 1) return - - file%remove_trc_file = rmv_file - file%pathname = trim(datapath) - file%filenames_list = trim(filelist) - - file%fill_in_months = .false. - file%cyclical = .false. - file%cyclical_list = .false. - -! does not work when compiled with pathf90 -! select case ( to_upper(data_type) ) - select case ( data_type ) - case( 'FIXED' ) - file%fixed = .true. - case( 'INTERP_MISSING_MONTHS' ) - file%fill_in_months = .true. - case( 'CYCLICAL' ) - file%cyclical = .true. - file%cyc_yr = data_cycle_yr - case( 'CYCLICAL_LIST' ) - file%cyclical_list = .true. - file%cyc_yr = data_cycle_yr - case( 'SERIAL' ) - case default - write(iulog,*) 'trcdata_init: invalid data type: '//trim(data_type)//' file: '//trim(filename) - write(iulog,*) 'trcdata_init: valid data types: SERIAL | CYCLICAL | CYCLICAL_LIST | FIXED | INTERP_MISSING_MONTHS ' - call endrun('trcdata_init: invalid data type: '//trim(data_type)//' file: '//trim(filename)) - endselect - - if ( (.not.file%fixed) .and. ((data_fixed_ymd>0._r8) .or.(data_fixed_tod>0._r8))) then - call endrun('trcdata_init: Cannot specify data_fixed_ymd or data_fixed_tod if data type is not FIXED') - endif - if ( (.not.file%cyclical) .and. (data_cycle_yr>0._r8) ) then - call endrun('trcdata_init: Cannot specify data_cycle_yr if data type is not CYCLICAL') - endif - - if (masterproc) then - write(iulog,*) 'trcdata_init: data type: '//trim(data_type)//' file: '//trim(filename) - endif - - ! if there is no list of files (len_trim(file%filenames_list)<1) then - ! -> set curr_filename from namelist rather from restart data - if ( len_trim(file%curr_filename)<1 .or. len_trim(file%filenames_list)<1 .or. file%fixed ) then ! initial run - file%curr_filename = trim(filename) - - call get_model_time(file) - - if ( file%fixed ) then - str_yr = data_fixed_ymd/10000 - str_mon = (data_fixed_ymd - str_yr*10000)/100 - str_day = data_fixed_ymd - str_yr*10000 - str_mon*100 - call set_time_float_from_date( start_time, str_yr, str_mon, str_day, data_fixed_tod ) - file%offset_time = start_time - file%curr_mod_time - else - file%offset_time = 0 - endif - endif - - call set_time_float_from_date( time2, 2, 1, 1, 0 ) - call set_time_float_from_date( time1, 1, 1, 1, 0 ) - file%one_yr = time2-time1 - - if ( file%cyclical .or. file%cyclical_list) then - file%cyc_ndx_beg = -1 - file%cyc_ndx_end = -1 - if ( file%cyc_yr /= 0 ) then - call set_time_float_from_date( time1, file%cyc_yr , 1, 1, 0 ) - call set_time_float_from_date( time2, file%cyc_yr+1, 1, 1, 0 ) - file%one_yr = time2-time1 - endif - - call open_trc_datafile( file%curr_filename, file%pathname, file%curr_fileid, file%curr_data_times, & - cyc_ndx_beg=file%cyc_ndx_beg, cyc_ndx_end=file%cyc_ndx_end, cyc_yr=file%cyc_yr ) - else - call open_trc_datafile( file%curr_filename, file%pathname, file%curr_fileid, file%curr_data_times ) - file%curr_data_times = file%curr_data_times - file%offset_time - endif - - call pio_seterrorhandling(File%curr_fileid, PIO_BCAST_ERROR) - ierr = pio_inq_dimid( file%curr_fileid, 'lon', idx ) - call pio_seterrorhandling(File%curr_fileid, PIO_INTERNAL_ERROR) - - file%zonal_ave = (ierr/=PIO_NOERR) - - plon = get_dyn_grid_parm('plon') - plat = get_dyn_grid_parm('plat') - - if ( .not. file%zonal_ave ) then - - call get_dimension( file%curr_fileid, 'lon', file%nlon, dimid=old_dimid, data=file%lons ) - - file%lons = file%lons * d2r - - lon_dimid = old_dimid - - endif - - ierr = pio_inq_dimid( file%curr_fileid, 'time', old_dimid) - - ! Hack to work with weird netCDF and old gcc or NAG bug. - tim_dimid = old_dimid - - call get_dimension( file%curr_fileid, 'lat', file%nlat, dimid=old_dimid, data=file%lats ) - file%lats = file%lats * d2r - - lat_dimid = old_dimid - - allocate( file%ps(file%nlon,file%nlat), stat=astat ) - if( astat /= 0 ) then - write(iulog,*) 'trcdata_init: file%ps allocation error = ',astat - call endrun('trcdata_init: failed to allocate x array') - end if - - call pio_seterrorhandling(File%curr_fileid, PIO_BCAST_ERROR) - ierr = pio_inq_varid( file%curr_fileid, 'PS', file%ps_id ) - file%has_ps = (ierr==PIO_NOERR) - ierr = pio_inq_dimid( file%curr_fileid, 'altitude', idx ) - file%alt_data = (ierr==PIO_NOERR) - - call pio_seterrorhandling(File%curr_fileid, PIO_INTERNAL_ERROR) - - if ( file%has_ps) then - ierr = pio_inq_vardimid (file%curr_fileid, file%ps_id, dimids(1:3)) - do did = 1,3 - if ( dimids(did) == lon_dimid ) then - file%ps_coords(LONDIM) = did - file%ps_order(did) = LONDIM - else if ( dimids(did) == lat_dimid ) then - file%ps_coords(LATDIM) = did - file%ps_order(did) = LATDIM - else if ( dimids(did) == tim_dimid ) then - file%ps_coords(PS_TIMDIM) = did - file%ps_order(did) = PS_TIMDIM - endif - enddo - endif - - if (masterproc) then - write(iulog,*) 'trcdata_init: file%has_ps = ' , file%has_ps - endif ! masterproc - - if (file%alt_data) then - call get_dimension( file%curr_fileid, 'altitude_int', file%nilev, data=file%ilevs ) - call get_dimension( file%curr_fileid, 'altitude', file%nlev, dimid=old_dimid, data=file%levs ) - else - call get_dimension( file%curr_fileid, 'lev', file%nlev, dimid=old_dimid, data=file%levs ) - !!added for Linoz_v3 - call get_dimension( file%curr_fileid, 'ilev', file%nilev, data=file%ilevs ) - if (old_dimid>0) then - file%levs = file%levs*100._r8 ! mbar->pascals - endif - endif - - ! For some bizarre reason, netCDF with older gcc is keeping a pointer to the dimid, and overwriting it later! - ! Hackish workaround is to make a copy... - lev_dimid = old_dimid - - if (file%has_ps) then - - allocate( file%hyam(file%nlev), file%hybm(file%nlev), stat=astat ) - if( astat /= 0 ) then - write(iulog,*) 'trcdata_init: file%hyam,file%hybm allocation error = ',astat - call endrun('trcdata_init: failed to allocate file%hyam and file%hybm arrays') - end if - - allocate( file%hyai(file%nlev+1), file%hybi(file%nlev+1), stat=astat ) - if( astat /= 0 ) then - write(iulog,*) 'trcdata_init: file%hyai,file%hybi allocation error = ',astat - call endrun('trcdata_init: failed to allocate file%hyai and file%hybi arrays') - end if - - call pio_seterrorhandling(File%curr_fileid, PIO_BCAST_ERROR) - ierr = pio_inq_varid( file%curr_fileid, 'P0', varid) - call pio_seterrorhandling(File%curr_fileid, PIO_INTERNAL_ERROR) - - if ( ierr == PIO_NOERR ) then - ierr = pio_get_var( file%curr_fileid, varid, file%p0 ) - else - file%p0 = 100000._r8 - endif - ierr = pio_inq_varid( file%curr_fileid, 'hyam', varid ) - ierr = pio_get_var( file%curr_fileid, varid, file%hyam ) - ierr = pio_inq_varid( file%curr_fileid, 'hybm', varid ) - ierr = pio_get_var( file%curr_fileid, varid, file%hybm ) - if (file%conserve_column) then - ierr = pio_inq_varid( file%curr_fileid, 'hyai', varid ) - ierr = pio_get_var( file%curr_fileid, varid, file%hyai ) - ierr = pio_inq_varid( file%curr_fileid, 'hybi', varid ) - ierr = pio_get_var( file%curr_fileid, varid, file%hybi ) - endif - - allocate( file %ps (pcols,begchunk:endchunk), stat=astat ) - if( astat/= 0 ) then - write(iulog,*) 'trcdata_init: failed to allocate file%ps array; error = ',astat - call endrun - end if - allocate( file%ps_in(1)%data(pcols,begchunk:endchunk), stat=astat ) - if( astat/= 0 ) then - write(iulog,*) 'trcdata_init: failed to allocate file%ps_in(1)%data array; error = ',astat - call endrun - end if - allocate( file%ps_in(2)%data(pcols,begchunk:endchunk), stat=astat ) - if( astat/= 0 ) then - write(iulog,*) 'trcdata_init: failed to allocate file%ps_in(2)%data array; error = ',astat - call endrun - end if - if( file%fill_in_months ) then - allocate( file%ps_in(3)%data(pcols,begchunk:endchunk), stat=astat ) - if( astat/= 0 ) then - write(iulog,*) 'trcdata_init: failed to allocate file%ps_in(3)%data array; error = ',astat - call endrun - end if - allocate( file%ps_in(4)%data(pcols,begchunk:endchunk), stat=astat ) - if( astat/= 0 ) then - write(iulog,*) 'trcdata_init: failed to allocate file%ps_in(4)%data array; error = ',astat - call endrun - end if - end if - endif - - flds_loop: do f = 1,mxnflds - - ! initialize the coordinate values to -1, - ! to defend against fields that do not have certain dimension, e.g., zonal average surface fields - ! and check against it when assigning value to cnt3 for that dimension - - do did = 1,4 - flds(f)%coords(did) = -1 - end do - - ! get netcdf variable id for the field - ierr = pio_inq_varid( file%curr_fileid, flds(f)%srcnam, flds(f)%var_id ) - - ! determine if the field has a vertical dimension - if (lev_dimid>0) then - ierr = pio_inquire_variable( file%curr_fileid, flds(f)%var_id, ndims=nvardims ) - ierr = pio_inquire_variable( file%curr_fileid, flds(f)%var_id, dimids=vardimids(:nvardims) ) - flds(f)%srf_fld = .not.any(vardimids(:nvardims)==lev_dimid) - else - flds(f)%srf_fld = .true. - endif - - ! allocate memory only if not already in pbuf2d - - if ( .not. file%in_pbuf(f) ) then - if ( flds(f)%srf_fld .or. file%top_bndry ) then - allocate( flds(f) %data(pcols,1,begchunk:endchunk), stat=astat ) - else - allocate( flds(f) %data(pcols,pver,begchunk:endchunk), stat=astat ) - endif - if( astat/= 0 ) then - write(iulog,*) 'trcdata_init: failed to allocate flds(f)%data array; error = ',astat - call endrun - end if - else - flds(f)%pbuf_ndx = pbuf_get_index(flds(f)%fldnam,errcode) - endif - - if (flds(f)%srf_fld) then - allocate( flds(f)%input(1)%data(pcols,1,begchunk:endchunk), stat=astat ) - else - allocate( flds(f)%input(1)%data(pcols,file%nlev,begchunk:endchunk), stat=astat ) - endif - if( astat/= 0 ) then - write(iulog,*) 'trcdata_init: failed to allocate flds(f)%input(1)%data array; error = ',astat - call endrun - end if - if (flds(f)%srf_fld) then - allocate( flds(f)%input(2)%data(pcols,1,begchunk:endchunk), stat=astat ) - else - allocate( flds(f)%input(2)%data(pcols,file%nlev,begchunk:endchunk), stat=astat ) - endif - if( astat/= 0 ) then - write(iulog,*) 'trcdata_init: failed to allocate flds(f)%input(2)%data array; error = ',astat - call endrun - end if - - if( file%fill_in_months ) then - if (flds(f)%srf_fld) then - allocate( flds(f)%input(3)%data(pcols,1,begchunk:endchunk), stat=astat ) - else - allocate( flds(f)%input(3)%data(pcols,file%nlev,begchunk:endchunk), stat=astat ) - endif - if( astat/= 0 ) then - write(iulog,*) 'trcdata_init: failed to allocate flds(f)%input(3)%data array; error = ',astat - call endrun - end if - if (flds(f)%srf_fld) then - allocate( flds(f)%input(4)%data(pcols,1,begchunk:endchunk), stat=astat ) - else - allocate( flds(f)%input(4)%data(pcols,file%nlev,begchunk:endchunk), stat=astat ) - endif - if( astat/= 0 ) then - write(iulog,*) 'trcdata_init: failed to allocate flds(f)%input(4)%data array; error = ',astat - call endrun - end if - endif - - if ( file%zonal_ave ) then - ierr = pio_inq_vardimid (file%curr_fileid, flds(f)%var_id, dimids(1:3)) - do did = 1,3 - if ( dimids(did) == lat_dimid ) then - flds(f)%coords(ZA_LATDIM) = did - flds(f)%order(did) = ZA_LATDIM - else if ( dimids(did) == lev_dimid ) then - flds(f)%coords(ZA_LEVDIM) = did - flds(f)%order(did) = ZA_LEVDIM - else if ( dimids(did) == tim_dimid ) then - flds(f)%coords(ZA_TIMDIM) = did - flds(f)%order(did) = ZA_TIMDIM - endif - enddo - else if ( flds(f)%srf_fld ) then - ierr = pio_inq_vardimid (file%curr_fileid, flds(f)%var_id, dimids(1:3)) - do did = 1,3 - if ( dimids(did) == lon_dimid ) then - flds(f)%coords(LONDIM) = did - flds(f)%order(did) = LONDIM - else if ( dimids(did) == lat_dimid ) then - flds(f)%coords(LATDIM) = did - flds(f)%order(did) = LATDIM - else if ( dimids(did) == tim_dimid ) then - flds(f)%coords(PS_TIMDIM) = did - flds(f)%order(did) = PS_TIMDIM - endif - enddo - else - ierr = pio_inq_vardimid (file%curr_fileid, flds(f)%var_id, dimids) - do did = 1,4 - if ( dimids(did) == lon_dimid ) then - flds(f)%coords(LONDIM) = did - flds(f)%order(did) = LONDIM - else if ( dimids(did) == lat_dimid ) then - flds(f)%coords(LATDIM) = did - flds(f)%order(did) = LATDIM - else if ( dimids(did) == lev_dimid ) then - flds(f)%coords(LEVDIM) = did - flds(f)%order(did) = LEVDIM - else if ( dimids(did) == tim_dimid ) then - flds(f)%coords(TIMDIM) = did - flds(f)%order(did) = TIMDIM - endif - enddo - endif - - ierr = pio_get_att( file%curr_fileid, flds(f)%var_id, 'units', data_units) - data_units = trim(data_units) - flds(f)%units = data_units(1:32) - - enddo flds_loop - -! if weighting by latitude, compute weighting for horizontal interpolation - if( file%weight_by_lat ) then -! get dimensions of CAM resolution - plon = get_dyn_grid_parm('plon') - plat = get_dyn_grid_parm('plat') - -! weight_x & weight_y are weighting function for x & y interpolation - allocate(file%weight_x(plon,file%nlon)) - allocate(file%weight_y(plat,file%nlat)) - allocate(file%count_x(plon)) - allocate(file%count_y(plat)) - allocate(file%index_x(plon,file%nlon)) - allocate(file%index_y(plat,file%nlat)) - file%weight_x(:,:) = 0.0_r8 - file%weight_y(:,:) = 0.0_r8 - file%count_x(:) = 0 - file%count_y(:) = 0 - file%index_x(:,:) = 0 - file%index_y(:,:) = 0 - - if(masterproc) then -! compute weighting - call xy_interp_init(file%nlon,file%nlat,file%lons,file%lats,plon,plat,file%weight_x,file%weight_y) - - do i2=1,plon - file%count_x(i2) = 0 - do i1=1,file%nlon - if(file%weight_x(i2,i1).gt.0.0_r8 ) then - file%count_x(i2) = file%count_x(i2) + 1 - file%index_x(i2,file%count_x(i2)) = i1 - endif - enddo - enddo - - do j2=1,plat - file%count_y(j2) = 0 - do j1=1,file%nlat - if(file%weight_y(j2,j1).gt.0.0_r8 ) then - file%count_y(j2) = file%count_y(j2) + 1 - file%index_y(j2,file%count_y(j2)) = j1 - endif - enddo - enddo - endif - -#if ( defined SPMD) - call mpibcast(file%weight_x, plon*file%nlon, mpir8 , 0, mpicom) - call mpibcast(file%weight_y, plat*file%nlat, mpir8 , 0, mpicom) - call mpibcast(file%count_x, plon, mpiint , 0, mpicom) - call mpibcast(file%count_y, plat, mpiint , 0, mpicom) - call mpibcast(file%index_x, plon*file%nlon, mpiint , 0, mpicom) - call mpibcast(file%index_y, plat*file%nlat, mpiint , 0, mpicom) -#endif - endif - - end subroutine trcdata_init - -!----------------------------------------------------------------------- -! Reads more data if needed and interpolates data to current model time -!----------------------------------------------------------------------- - subroutine advance_trcdata( flds, file, state, pbuf2d ) - use physics_types,only : physics_state - use physics_buffer, only : physics_buffer_desc - use ppgrid, only : pver,pcols - - implicit none - - type(trfile), intent(inout) :: file - type(trfld), intent(inout) :: flds(:) - type(physics_state), intent(in) :: state(begchunk:endchunk) - - type(physics_buffer_desc), optional, pointer :: pbuf2d(:,:) - integer :: ncol - real(r8) :: data_time - real(r8) :: t(pcols,pver) ! input temperature (K) - real(r8) :: rho(pcols,pver) ! input temperature (K) - real(r8) :: pmid(pcols,pver) ! pressure at layer midpoints (pa) -!--------------------------------------BLH----------------------------------- - - call t_startf('advance_trcdata') - if ( .not.( file%fixed .and. file%initialized ) ) then - - call get_model_time(file) - - data_time = file%datatimep - - if ( file%cyclical .or. file%cyclical_list ) then - ! wrap around - if ( (file%datatimepfile%datatimem) ) then - data_time = data_time + file%one_yr - endif - endif - - ! For stepTime need to advance if the times are equal - ! Should not impact other runs? - if ( file%curr_mod_time >= data_time ) then - call t_startf('read_next_trcdata') - call read_next_trcdata(state, flds, file ) - call t_stopf('read_next_trcdata') - if(masterproc) write(iulog,*) 'READ_NEXT_TRCDATA ', flds%fldnam,data_time - end if - - endif - - ! need to interpolate the data, regardless - ! each mpi task needs to interpolate - call t_startf('interpolate_trcdata') - if(present(pbuf2d)) then - call interpolate_trcdata( state, flds, file, pbuf2d ) - else - call interpolate_trcdata( state, flds, file ) - endif - call t_stopf('interpolate_trcdata') - - file%initialized = .true. - - call t_stopf('advance_trcdata') - - end subroutine advance_trcdata - -!------------------------------------------------------------------- -!------------------------------------------------------------------- - subroutine get_fld_data( flds, field_name, data, ncol, lchnk, pbuf ) - - use physics_buffer, only : physics_buffer_desc, pbuf_get_field - - implicit none - - type(trfld), intent(inout) :: flds(:) - character(len=*), intent(in) :: field_name - real(r8), intent(out) :: data(:,:) - integer, intent(in) :: lchnk - integer, intent(in) :: ncol - type(physics_buffer_desc), pointer :: pbuf(:) - - - integer :: f, nflds - real(r8),pointer :: tmpptr(:,:) - - data(:,:) = 0._r8 - nflds = size(flds) - - do f = 1, nflds - if ( trim(flds(f)%fldnam) == trim(field_name) ) then - if ( flds(f)%pbuf_ndx>0 ) then - call pbuf_get_field(pbuf, flds(f)%pbuf_ndx, tmpptr) - data(:ncol,:) = tmpptr(:ncol,:) - else - data(:ncol,:) = flds(f)%data(:ncol,:,lchnk) - endif - endif - enddo - - end subroutine get_fld_data - -!------------------------------------------------------------------- -!------------------------------------------------------------------- - subroutine put_fld_data( flds, field_name, data, ncol, lchnk, pbuf ) - - use physics_buffer, only : physics_buffer_desc, pbuf_get_field - - implicit none - - type(trfld), intent(inout) :: flds(:) - character(len=*), intent(in) :: field_name - real(r8), intent(in) :: data(:,:) - integer, intent(in) :: lchnk - integer, intent(in) :: ncol - type(physics_buffer_desc), pointer :: pbuf(:) - - - integer :: f, nflds - real(r8),pointer :: tmpptr(:,:) - - nflds = size(flds) - - do f = 1, nflds - if ( trim(flds(f)%fldnam) == trim(field_name) ) then - if ( flds(f)%pbuf_ndx>0 ) then - call pbuf_get_field(pbuf, flds(f)%pbuf_ndx, tmpptr) - tmpptr(:ncol,:) = data(:ncol,:) - else - flds(f)%data(:ncol,:,lchnk) = data(:ncol,:) - endif - endif - enddo - - end subroutine put_fld_data - -!------------------------------------------------------------------- -!------------------------------------------------------------------- - subroutine get_fld_ndx( flds, field_name, idx ) - - implicit none - - type(trfld), intent(in) :: flds(:) - character(len=*), intent(in) :: field_name - integer, intent(out) :: idx - integer :: f, nflds - - idx = -1 - nflds = size(flds) - - do f = 1, nflds - if ( trim(flds(f)%fldnam) == trim(field_name) ) then - idx = f - return - endif - enddo - - end subroutine get_fld_ndx - -!------------------------------------------------------------------------------ -!------------------------------------------------------------------------------ - subroutine get_model_time(file) - implicit none - type(trfile), intent(inout) :: file - - integer yr, mon, day, ncsec ! components of a date - - call get_curr_date(yr, mon, day, ncsec) - - if ( file%cyclical .or. file%cyclical_list) yr = file%cyc_yr - call set_time_float_from_date( file%curr_mod_time, yr, mon, day, ncsec ) - file%next_mod_time = file%curr_mod_time + get_step_size()/86400._r8 - - end subroutine get_model_time - -!------------------------------------------------------------------------------ -!------------------------------------------------------------------------------ - subroutine check_files( file, fids, itms, times_found) - - implicit none - - type(trfile), intent(inout) :: file - type(file_desc_t), intent(out) :: fids(2) ! ids of files that contains these recs - integer, optional, intent(out) :: itms(2) - logical, optional, intent(inout) :: times_found - - !----------------------------------------------------------------------- - ! ... local variables - !----------------------------------------------------------------------- - logical :: list_cycled - - list_cycled = .false. - - !----------------------------------------------------------------------- - ! If next time beyond the end of the time list, - ! then increment the filename and move on to the next file - !----------------------------------------------------------------------- - if ((file%next_mod_time > file%curr_data_times(size(file%curr_data_times))).or.file%cyclical_list) then - if (file%cyclical_list) then - if ( associated(file%next_data_times) ) then - if ((file%curr_mod_time > file%datatimep)) then - - call advance_file(file) - - endif - endif - - endif - if ( .not. associated(file%next_data_times) ) then - ! open next file if not already opened... - if (file%cyclical_list) then - file%next_filename = incr_filename( file%curr_filename, filenames_list=file%filenames_list, datapath=file%pathname ,& - cyclical_list=file%cyclical_list, list_cycled=list_cycled) - else - file%next_filename = incr_filename( file%curr_filename, filenames_list=file%filenames_list, datapath=file%pathname) - endif - call open_trc_datafile( file%next_filename, file%pathname, file%next_fileid, file%next_data_times ) - file%next_data_times = file%next_data_times - file%offset_time - endif - endif - - !----------------------------------------------------------------------- - ! If using next_data_times and the current is greater than or equal to the next, then - ! close the current file, and set up for next file. - !----------------------------------------------------------------------- - if ( associated(file%next_data_times) ) then - if (file%cyclical_list .and. list_cycled) then ! special case - list cycled - - file%datatimem = file%curr_data_times(size(file%curr_data_times)) - itms(1)=size(file%curr_data_times) - fids(1)=file%curr_fileid - - file%datatimep = file%next_data_times(1) - itms(2)=1 - fids(2) = file%next_fileid - - times_found = .true. - - else if (file%curr_mod_time >= file%next_data_times(1)) then - - call advance_file(file) - - endif - endif - - end subroutine check_files - -!----------------------------------------------------------------------- -!----------------------------------------------------------------------- - function incr_filename( filename, filenames_list, datapath, cyclical_list, list_cycled ) - - !----------------------------------------------------------------------- - ! ... Increment or decrement a date string withing a filename - ! the filename date section is assumed to be of the form - ! yyyy-dd-mm - !----------------------------------------------------------------------- - - use string_utils, only : incstr - use shr_file_mod, only : shr_file_getunit, shr_file_freeunit - - implicit none - - - character(len=*), intent(in) :: filename ! present dynamical dataset filename - character(len=*), optional, intent(in) :: filenames_list - character(len=*), optional, intent(in) :: datapath - logical , optional, intent(in) :: cyclical_list ! If true, allow list to cycle - logical , optional, intent(out) :: list_cycled - character(len=shr_kind_cl) :: incr_filename ! next filename in the sequence - - - ! set new next_filename ... - - !----------------------------------------------------------------------- - ! ... local variables - !----------------------------------------------------------------------- - integer :: pos, pos1, istat - character(len=shr_kind_cl) :: fn_new, line, filepath - character(len=6) :: seconds - character(len=5) :: num - integer :: ios,unitnumber - - if (present(list_cycled)) list_cycled = .false. - - if (( .not. present(filenames_list)) .or.(len_trim(filenames_list) == 0)) then - !----------------------------------------------------------------------- - ! ... ccm type filename - !----------------------------------------------------------------------- - pos = len_trim( filename ) - fn_new = filename(:pos) - if ( masterproc ) write(iulog,*) 'incr_flnm: old filename = ',trim(fn_new) - if( fn_new(pos-2:) == '.nc' ) then - pos = pos - 3 - end if - istat = incstr( fn_new(:pos), 1 ) - if( istat /= 0 ) then - write(iulog,*) 'incr_flnm: incstr returned ', istat - write(iulog,*) ' while trying to decrement ',trim( fn_new ) - call endrun - end if - - else - - !------------------------------------------------------------------- - ! ... open filenames_list - !------------------------------------------------------------------- - if ( masterproc ) write(iulog,*) 'incr_flnm: old filename = ',trim(filename) - if ( masterproc ) write(iulog,*) 'incr_flnm: open filenames_list : ',trim(filenames_list) - unitnumber = shr_file_getUnit() - if ( present(datapath) ) then - filepath = trim(datapath) //'/'// trim(filenames_list) - else - filepath = trim(datapath) - endif - - open( unit=unitnumber, file=filepath, iostat=ios, status="OLD") - if (ios /= 0) then - call endrun('not able to open filenames_list file: '//trim(filepath)) - endif - - !------------------------------------------------------------------- - ! ... read file names - !------------------------------------------------------------------- - read( unit=unitnumber, fmt='(A)', iostat=ios ) line - if (ios /= 0) then - call endrun('not able to increment file name from filenames_list file: '//trim(filenames_list)) - endif - - !------------------------------------------------------------------- - ! If current filename is '', then initialize with the first filename read in - ! and skip this section. - !------------------------------------------------------------------- - if (filename /= '') then - - !------------------------------------------------------------------- - ! otherwise read until find current filename - !------------------------------------------------------------------- - do while( trim(line) /= trim(filename) ) - read( unit=unitnumber, fmt='(A)', iostat=ios ) line - if (ios /= 0) then - call endrun('not able to increment file name from filenames_list file: '//trim(filenames_list)) - endif - enddo - - !------------------------------------------------------------------- - ! Read next filename - !------------------------------------------------------------------- - read( unit=unitnumber, fmt='(A)', iostat=ios ) line - - !--------------------------------------------------------------------------------- - ! If cyclical_list, then an end of file is not an error, but rather - ! a signal to rewind and start over - !--------------------------------------------------------------------------------- - - if (ios /= 0) then - if (present(cyclical_list)) then - if (cyclical_list) then - list_cycled=.true. - rewind(unitnumber) - read( unit=unitnumber, fmt='(A)', iostat=ios ) line - ! Error here should never happen, but check just in case - if (ios /= 0) then - call endrun('not able to increment file name from filenames_list file: '//trim(filenames_list)) - endif - else - call endrun('not able to increment file name from filenames_list file: '//trim(filenames_list)) - endif - else - call endrun('not able to increment file name from filenames_list file: '//trim(filenames_list)) - endif - endif - - endif - - !--------------------------------------------------------------------------------- - ! Assign the current filename and close the filelist - !--------------------------------------------------------------------------------- - fn_new = trim(line) - - close(unit=unitnumber) - call shr_file_freeUnit(unitnumber) - endif - - !--------------------------------------------------------------------------------- - ! return the current filename - !--------------------------------------------------------------------------------- - incr_filename = trim(fn_new) - if ( masterproc ) write(iulog,*) 'incr_flnm: new filename = ',trim(incr_filename) - - end function incr_filename - -!------------------------------------------------------------------------------ -!------------------------------------------------------------------------------ - subroutine find_times( itms, fids, time, file, datatimem, datatimep, times_found ) - - implicit none - - type(trfile), intent(in) :: file - real(r8), intent(out) :: datatimem, datatimep - - integer, intent(out) :: itms(2) ! record numbers that bracket time - type(file_desc_t), intent(out) :: fids(2) ! ids of files that contains these recs - - real(r8), intent(in) :: time ! time of interest - logical, intent(inout) :: times_found - - integer :: np1 ! current forward time index of dataset - integer :: n,i ! - integer :: curr_tsize, next_tsize, all_tsize - integer :: astat - integer :: cyc_tsize - - real(r8), allocatable, dimension(:):: all_data_times - - curr_tsize = size(file%curr_data_times) - next_tsize = 0 - if ( associated(file%next_data_times)) next_tsize = size(file%next_data_times) - - all_tsize = curr_tsize + next_tsize - - allocate( all_data_times( all_tsize ), stat=astat ) - if( astat/= 0 ) then - write(iulog,*) 'find_times: failed to allocate all_data_times array; error = ',astat - call endrun - end if - - all_data_times(:curr_tsize) = file%curr_data_times(:) - if (next_tsize > 0) all_data_times(curr_tsize+1:all_tsize) = file%next_data_times(:) - - if ( .not. file%cyclical ) then - if ( all( all_data_times(:) > time ) ) then - write(iulog,*) 'FIND_TIMES: ALL data times are after ', time - write(iulog,*) 'FIND_TIMES: data times: ',all_data_times(:) - write(iulog,*) 'FIND_TIMES: time: ',time - call endrun('find_times: all(all_data_times(:) > time) '// trim(file%curr_filename) ) - endif - - ! find bracketing times - find_times_loop : do n=1, all_tsize-1 - np1 = n + 1 - datatimem = all_data_times(n) !+ file%offset_time - datatimep = all_data_times(np1) !+ file%offset_time - ! When stepTime, datatimep may not equal the time (as only datatimem is used) - ! Should not break other runs? - if ( (time .ge. datatimem) .and. (time .lt. datatimep) ) then - times_found = .true. - exit find_times_loop - endif - enddo find_times_loop - - else ! file%cyclical - - cyc_tsize = file%cyc_ndx_end - file%cyc_ndx_beg + 1 - - if ( cyc_tsize > 1 ) then - - call findplb(all_data_times(file%cyc_ndx_beg:file%cyc_ndx_end),cyc_tsize, time, n ) - - if (n == cyc_tsize) then - np1 = 1 - else - np1 = n+1 - endif - - datatimem = all_data_times(n +file%cyc_ndx_beg-1) - datatimep = all_data_times(np1+file%cyc_ndx_beg-1) - times_found = .true. - - endif - endif - - if ( .not. times_found ) then - if (masterproc) then - write(iulog,*)'FIND_TIMES: Failed to find dates bracketing desired time =', time - write(iulog,*)' datatimem = ',file%datatimem - write(iulog,*)' datatimep = ',file%datatimep - write(iulog,*)' all_data_times = ',all_data_times - !call endrun() - return - endif - endif - - deallocate( all_data_times, stat=astat ) - if( astat/= 0 ) then - write(iulog,*) 'find_times: failed to deallocate all_data_times array; error = ',astat - call endrun - end if - - if ( .not. file%cyclical ) then - itms(1) = n - itms(2) = np1 - else - itms(1) = n +file%cyc_ndx_beg-1 - itms(2) = np1 +file%cyc_ndx_beg-1 - endif - - fids(:) = file%curr_fileid - - do i=1,2 - if ( itms(i) > curr_tsize ) then - itms(i) = itms(i) - curr_tsize - fids(i) = file%next_fileid - endif - enddo - - end subroutine find_times - -!------------------------------------------------------------------------ -!------------------------------------------------------------------------ - subroutine read_next_trcdata(state, flds, file ) - - use shr_const_mod, only:pi => shr_const_pi - use physics_types,only : physics_state - use ppgrid, only: pcols, pver, pverp,begchunk,endchunk - use physconst, only: rair - use iop_data_mod - use rad_constituents, only: rad_cnst_get_info, rad_cnst_get_aer_props, & - rad_cnst_get_mode_props, rad_cnst_get_mode_num - - implicit none - - type (trfile), intent(inout) :: file - type (trfld),intent(inout) :: flds(:) - type(physics_state), intent(in) :: state(begchunk:endchunk) - - integer :: recnos(4),i,f,nflds ! - integer :: cnt4(4) ! array of counts for each dimension - integer :: strt4(4) ! array of starting indices - integer :: cnt3(3) ! array of counts for each dimension - integer :: strt3(3) ! array of starting indices - type(file_desc_t) :: fids(4) - logical :: times_found - - integer :: cur_yr, cur_mon, cur_day, cur_sec, yr1, yr2, mon, date, sec - real(r8) :: series1_time, series2_time - type(file_desc_t) :: fid1, fid2 - - integer :: nspec,nmodes,n,ii,kk,l1,k,lchnk - real(r8) :: profile_p(pver),pp(pver),meanP,meanO,sumii,volfrac,specdens,aero_den(6) - real(r8) :: q_a(3,6) - real(r8) :: rho(pcols,pver) ! air density (kg m-3) - character(len=20) :: aername - character(len=3) :: arnam(7) = (/'so4','pom','soa','bc ','dst','ncl','num'/) - - nflds = size(flds) - times_found = .false. - - if(single_column .and. scm_observed_aero) then - - call ver_profile_aero(pp) - ! The following do loop gets the species properties and calculates the aerosol - ! mass mixing ratio of each species from observed total number and size distribution - ! properties in the unit kg/m^3 for the 3 modes. Data is read from the forcing file. - ! For mode 1 (accumulation mode) q_a(1,1)=q(so4),q_a(1,2)=q(pom),q_a(1,3)=q(soa), - ! q_a(1,4)=q(bc),q_a(1,5)=q(dst),q_a(1,6)=q(ncl). - ! For mode 2 (aitken mode) q_a(2,1)=q(so4),q_a(2,2)=q(soa),q_a(2,3)=q(ncl). - ! For mode 3 (coarse mode) q_a(3,1)=q(dst),q_a(3,2)=q(ncl),q_a(3,3)=q(so4). - - call rad_cnst_get_info(0, nmodes=nmodes) - do n=1, nmodes - call rad_cnst_get_info(0, n, nspec=nspec) - do l1 = 1, nspec - call rad_cnst_get_aer_props(0, n,l1,density_aer=specdens) - call rad_cnst_get_aer_props(0, n, l1, aername=aername) - aero_den(l1)=specdens - q_a(n,l1) = specdens*scm_div(n,l1)*scm_num(n)*((pi/6.0_r8)*( & - scm_dgnum(n)**3)*exp(4.5_r8*(log(scm_std(n))**2) )) - enddo - enddo - - do k = 1, pver - do ii = 1, state(begchunk)%ncol - rho(ii,k) = state(begchunk)%pmid(ii,k)/(rair*state(begchunk)%t(ii,k)) - enddo - enddo - end if - - do while( .not. times_found ) - call find_times( recnos, fids, file%curr_mod_time,file,file%datatimem,file%datatimep, times_found ) - if ( .not. times_found ) then - call check_files( file, fids, recnos, times_found ) - endif - enddo - - ! If single column do not interpolate aerosol data, just use the step function. - ! The exception is if we are trying to "replay" a column from the full model - if(single_column .and. .not. use_replay) then - file%stepTime = .true. - endif - - if (file%stepTime) then - file%interp_recs = 1 - else - file%interp_recs = 2 - end if - - if ( file%fill_in_months ) then - - if( file%datatimep-file%datatimem > file%one_yr ) then - - call get_curr_date(cur_yr, cur_mon, cur_day, cur_sec) - - call set_date_from_time_float(file%datatimem, yr1, mon, date, sec ) - call set_date_from_time_float(file%datatimep, yr2, mon, date, sec ) - - call set_time_float_from_date( series1_time, yr1, cur_mon, cur_day, cur_sec ) - call set_time_float_from_date( series2_time, yr2, cur_mon, cur_day, cur_sec ) - - fid1 = fids(1) - fid2 = fids(2) - file%cyclical = .true. - call set_cycle_indices( fid1, file%cyc_ndx_beg, file%cyc_ndx_end, yr1) - call find_times( recnos(1:2), fids(1:2), series1_time, file, file%datatimes(1), file%datatimes(2), times_found ) - - if ( .not. times_found ) then - call endrun('read_next_trcdata: time not found for series1_time') - endif - call set_cycle_indices( fid2, file%cyc_ndx_beg, file%cyc_ndx_end, yr2) - - if ( fid1%fh /= fid2%fh ) then - file%cyc_ndx_beg = file%cyc_ndx_beg + size(file%curr_data_times) - file%cyc_ndx_end = file%cyc_ndx_end + size(file%curr_data_times) - endif - call find_times( recnos(3:4), fids(3:4), series2_time, file, file%datatimes(3), file%datatimes(4), times_found ) - if ( .not. times_found ) then - call endrun('read_next_trcdata: time not found for series2_time') - endif - file%cyclical = .false. - file%interp_recs = 4 - - call set_date_from_time_float( file%datatimes(1), yr1, mon, date, sec ) - call set_time_float_from_date( file%datatimem, cur_yr, mon, date, sec ) - if (file%datatimes(1) > file%datatimes(2) ) then ! wrap around - if ( cur_mon == 1 ) then - call set_time_float_from_date( file%datatimem, cur_yr-1, mon, date, sec ) - endif - endif - - call set_date_from_time_float( file%datatimes(2), yr1, mon, date, sec ) - call set_time_float_from_date( file%datatimep, cur_yr, mon, date, sec ) - if (file%datatimes(1) > file%datatimes(2) ) then ! wrap around - if ( cur_mon == 12 ) then - call set_time_float_from_date( file%datatimep, cur_yr+1, mon, date, sec ) - endif - endif - - endif - - endif - - ! - ! Set up hyperslab corners - ! - strt4(:) = 1 - strt3(:) = 1 - - do i=1,file%interp_recs - - do f = 1,nflds - if ( file%zonal_ave ) then - ! Defend against zonal mean surface fields that do not set the value via dimension match - if (flds(f)%coords(ZA_LATDIM) .gt. 0) cnt3(flds(f)%coords(ZA_LATDIM)) = file%nlat - if (flds(f)%srf_fld) then - ! Defend against zonal mean surface fields that do not set the value via dimension match - if (flds(f)%coords(ZA_LEVDIM) .gt. 0) cnt3(flds(f)%coords(ZA_LEVDIM)) = 1 - else - cnt3(flds(f)%coords(ZA_LEVDIM)) = file%nlev - endif - cnt3(flds(f)%coords(ZA_TIMDIM)) = 1 - strt3(flds(f)%coords(ZA_TIMDIM)) = recnos(i) - !! - if (file%linoz_v3 .or. file%linoz_v2) then - !!check if these are the surface variables - !!no need to do interpolate since only used - !!in preprocessing, - !!clim +57 is the correspondent srf variable - if (index(flds(f)%fldnam,"_clim") .gt.0.and.& - index(flds(f)%fldnam,"P_clim") .le.0.and.& - index(flds(f)%fldnam,"L_clim") .le.0.and.& - index(flds(f)%fldnam,"_srf") .le.0)then - call read_za_trc_linoz( fids(i), flds(f)%var_id, flds(f)%input(i)%data, strt3, cnt3, file, & - (/ flds(f)%order(ZA_LATDIM),flds(f)%order(ZA_LEVDIM)/), & - vid_srf=flds(f+57)%var_id ) - elseif (index(flds(f)%fldnam,"_srf").gt.0) then - if (index(flds(f)%fldnam,"ch4_avg_srf").gt.0) then - cnt3(1)=1!set 1st dim since no ZA_LATDIM - endif - call read_zasrf_trc_linoz(fids(i), flds(f)%var_id, flds(f)%input(i)%data, strt3, cnt3, file) - else - call read_za_trc_linoz( fids(i), flds(f)%var_id, flds(f)%input(i)%data, strt3, cnt3, file, & - (/ flds(f)%order(ZA_LATDIM),flds(f)%order(ZA_LEVDIM) /) ) - endif - else - call read_za_trc( fids(i), flds(f)%var_id, flds(f)%input(i)%data, strt3, cnt3, file, & - (/ flds(f)%order(ZA_LATDIM),flds(f)%order(ZA_LEVDIM) /) ) - endif - else if ( flds(f)%srf_fld ) then - cnt3( flds(f)%coords(LONDIM)) = file%nlon - cnt3( flds(f)%coords(LATDIM)) = file%nlat - cnt3( flds(f)%coords(PS_TIMDIM)) = 1 - strt3(flds(f)%coords(PS_TIMDIM)) = recnos(i) - call read_2d_trc( fids(i), flds(f)%var_id, flds(f)%input(i)%data(:,1,:), strt3, cnt3, file, & - (/ flds(f)%order(LONDIM),flds(f)%order(LATDIM) /) ) - else - cnt4(flds(f)%coords(LONDIM)) = file%nlon - cnt4(flds(f)%coords(LATDIM)) = file%nlat - cnt4(flds(f)%coords(LEVDIM)) = file%nlev - cnt4(flds(f)%coords(TIMDIM)) = 1 - strt4(flds(f)%coords(TIMDIM)) = recnos(i) - call read_3d_trc( fids(i), flds(f)%var_id, flds(f)%input(i)%data, strt4, cnt4, file, & - (/ flds(f)%order(LONDIM),flds(f)%order(LATDIM),flds(f)%order(LEVDIM) /)) - - ! - ! This section sets the observed aersol mass and number mixing ratios in the - ! appropriate variables. The observed aerosol inforamtion is read from the - ! forcing file as total number and size distribution parameters. Then the total - ! volume is calculated.Using the desnsity of each species, the mass is calculated. - ! Finally the number is partition among the each species using the species fraction - ! data read from the forcing file. - ! - if(single_column .and. scm_observed_aero) then - kk=index(trim(flds(f)%fldnam),'_')-1 - if(index(trim(flds(f)%fldnam),'1') > 0 .and.index(trim(flds(f)%fldnam),'log') < 1) then - if(flds(f)%fldnam(1:kk).eq.arnam(1).and.index(trim(flds(f)%fldnam),'log') < 1) then - call replace_aero_data(flds(f)%fldnam,arnam(1),flds(f)%input(i)%data, & - rho,pp,q_a(1,1),state(begchunk)%ncol) - elseif(flds(f)%fldnam(1:kk).eq.arnam(2).and.index(trim(flds(f)%fldnam),'log') < 1) then - call replace_aero_data(flds(f)%fldnam,arnam(2),flds(f)%input(i)%data, & - rho,pp,q_a(1,2),state(begchunk)%ncol) - elseif(flds(f)%fldnam(1:kk).eq.arnam(3).and.index(trim(flds(f)%fldnam),'log') < 1) then - call replace_aero_data(flds(f)%fldnam,arnam(3),flds(f)%input(i)%data, & - rho,pp,q_a(1,3),state(begchunk)%ncol) - elseif(flds(f)%fldnam(1:kk).eq.arnam(4).and.index(trim(flds(f)%fldnam),'log') < 1) then - call replace_aero_data(flds(f)%fldnam,arnam(4),flds(f)%input(i)%data, & - rho,pp,q_a(1,4),state(begchunk)%ncol) - elseif(flds(f)%fldnam(1:kk).eq.arnam(5).and.index(trim(flds(f)%fldnam),'log') < 1) then - call replace_aero_data(flds(f)%fldnam,arnam(5),flds(f)%input(i)%data, & - rho,pp,q_a(1,5),state(begchunk)%ncol) - elseif(flds(f)%fldnam(1:kk).eq.arnam(6).and.index(trim(flds(f)%fldnam),'log') < 1) then - call replace_aero_data(flds(f)%fldnam,arnam(6),flds(f)%input(i)%data, & - rho,pp,q_a(1,6),state(begchunk)%ncol) - elseif(flds(f)%fldnam(1:kk).eq.arnam(7).and.index(trim(flds(f)%fldnam),'log') < 1) then - call replace_aero_data(flds(f)%fldnam,arnam(7),flds(f)%input(i)%data, & - rho,pp,scm_num(1),state(begchunk)%ncol) - endif - elseif(index(trim(flds(f)%fldnam),'2') > 0 .and.index(trim(flds(f)%fldnam),'log') < 1) then - if(flds(f)%fldnam(1:kk).eq.arnam(1).and.index(trim(flds(f)%fldnam),'log') < 1) then - call replace_aero_data(flds(f)%fldnam,arnam(1),flds(f)%input(i)%data, & - rho,pp,q_a(2,1),state(begchunk)%ncol) - elseif(flds(f)%fldnam(1:kk).eq.arnam(3).and.index(trim(flds(f)%fldnam),'log') < 1) then - call replace_aero_data(flds(f)%fldnam,arnam(3),flds(f)%input(i)%data, & - rho,pp,q_a(2,2),state(begchunk)%ncol) - elseif(flds(f)%fldnam(1:kk).eq.arnam(6).and.index(trim(flds(f)%fldnam),'log') < 1) then - call replace_aero_data(flds(f)%fldnam,arnam(6),flds(f)%input(i)%data, & - rho,pp,q_a(2,3),state(begchunk)%ncol) - elseif(flds(f)%fldnam(1:kk).eq.arnam(7).and.index(trim(flds(f)%fldnam),'log') < 1) then - call replace_aero_data(flds(f)%fldnam,arnam(7),flds(f)%input(i)%data, & - rho,pp,scm_num(2),state(begchunk)%ncol) - endif - elseif(index(trim(flds(f)%fldnam),'3') > 0 .and.index(trim(flds(f)%fldnam),'log') < 1) then - if(flds(f)%fldnam(1:kk).eq.arnam(1).and.index(trim(flds(f)%fldnam),'log') < 1) then - call replace_aero_data(flds(f)%fldnam,arnam(1),flds(f)%input(i)%data, & - rho,pp,q_a(3,3),state(begchunk)%ncol) - elseif(flds(f)%fldnam(1:kk).eq.arnam(5).and.index(trim(flds(f)%fldnam),'log') < 1) then - call replace_aero_data(flds(f)%fldnam,arnam(5),flds(f)%input(i)%data, & - rho,pp,q_a(3,1),state(begchunk)%ncol) - elseif(flds(f)%fldnam(1:kk).eq.arnam(6).and.index(trim(flds(f)%fldnam),'log') < 1) then - call replace_aero_data(flds(f)%fldnam,arnam(6),flds(f)%input(i)%data, & - rho,pp,q_a(3,2),state(begchunk)%ncol) - elseif(flds(f)%fldnam(1:kk).eq.arnam(7).and.index(trim(flds(f)%fldnam),'log') < 1) then - call replace_aero_data(flds(f)%fldnam,arnam(7),flds(f)%input(i)%data, & - rho,pp,scm_num(3),state(begchunk)%ncol) - endif - endif - endif !scm_observed_aero - endif - - enddo - - if ( file%has_ps ) then - cnt3(file%ps_coords(LONDIM)) = file%nlon - cnt3(file%ps_coords(LATDIM)) = file%nlat - cnt3(file%ps_coords(PS_TIMDIM)) = 1 - strt3(file%ps_coords(PS_TIMDIM)) = recnos(i) - call read_2d_trc( fids(i), file%ps_id, file%ps_in(i)%data, strt3, cnt3, file, & - (/ file%ps_order(LONDIM),file%ps_order(LATDIM) /) ) - endif - - enddo - - end subroutine read_next_trcdata - -!-------------------------------------------------------------------------------- -!This subroutine replaces the climatological aerosol information by the observed -!once after they are read -! - subroutine replace_aero_data(aerofulnam,spnam,aero_q_data,rho,pp,q_mix,ncoli) - use ppgrid, only: pcols,pver,begchunk,endchunk - - implicit none - real(r8), intent(inout) :: aero_q_data(pcols,pver,begchunk:endchunk) - real(r8), intent(in) :: rho(pcols,pver),pp(pver) - real(r8) :: sumii,meanO - real(r8), intent(in) :: q_mix - character(len=32),intent(in) ::aerofulnam - character(len=3),intent(in) :: spnam - character(len=32) ::aerosubnam - integer, intent(in) :: ncoli - integer :: ii,k,countj - - if(trim(aerofulnam(1:2)).eq.'bc') then - aerosubnam=aerofulnam(1:4) - else - aerosubnam=aerofulnam(1:5) - endif - - if((trim(aerosubnam).eq.(trim(spnam)//'_a').or.trim(aerosubnam).eq.(trim(spnam)//'_c')) & - .and.index(trim(aerofulnam),'log') < 1) then - - aero_q_data=q_mix - sumii=0._r8 - countj =0 - do ii = 1, ncoli - do k = 1, pver - if(pp(k).gt.0._r8) then - countj=countj+1 - endif - if(trim(spnam).ne.'num') then - aero_q_data(ii,k,begchunk)=(aero_q_data(ii,k,begchunk)*pp(k)) /rho(ii,k) - endif - sumii=sumii + aero_q_data(ii,k,begchunk) - enddo - enddo - meanO=sumii/countj - do k = 1, pver - if(meanO.ne.0.) then - aero_q_data(1,k,begchunk)=pp(k)*meanO - else - aero_q_data(1,k,begchunk)=0._r8 - endif - enddo - endif - - end subroutine replace_aero_data - -!--------------------------------------------------------------------------- -!This subroutine generates a heavyside type profiles for the observed aerosol. -!This setting is constant profile in the lower atmosphere and then exponentially -!decreasing to zero at the top of the atmosphere. The level of initial decay is -!controlled by "initial_val". Larger than -3.5 pushes the decay point up and smaller -!brings it closer to the surface. -! - subroutine ver_profile_aero(vertprof_aero) - use mo_constants, only : pi - use ppgrid, only: pcols,pver - - implicit none - real(r8), intent(inout) :: vertprof_aero(pver) - real(r8) :: initial_val = -3.5_r8 - integer :: k - - do k=1,pver - if(k==1) then - vertprof_aero(k)=0._r8 - elseif(k==2) then - vertprof_aero(k)=1._r8/(1._r8 + exp(-2._r8*initial_val * pi)) - else - vertprof_aero(k)=1._r8/(1._r8 + exp(-2._r8*(initial_val * pi + pi/4._r8*(k-2)))) - endif - enddo - end subroutine ver_profile_aero - -!------------------------------------------------------------------------ - - - subroutine read_2d_trc( fid, vid, loc_arr, strt, cnt, file, order ) - use interpolate_data, only : lininterp_init, lininterp, interp_type, lininterp_finish - - use phys_grid, only : pcols, begchunk, endchunk, get_ncols_p, get_rlat_all_p, get_rlon_all_p, get_lon_all_p, get_lat_all_p - use mo_constants, only : pi - use dycore, only: dycore_is - use polar_avg, only: polar_average - use horizontal_interpolate, only : xy_interp - - implicit none - type(file_desc_t), intent(in) :: fid - type(var_desc_t), intent(in) :: vid - integer, intent(in) :: strt(:), cnt(:), order(2) - real(r8),intent(out) :: loc_arr(:,:) - type (trfile), intent(in) :: file - - real(r8) :: to_lats(pcols), to_lons(pcols), wrk(pcols) - real(r8), allocatable, target :: wrk2d(:,:) - real(r8), pointer :: wrk2d_in(:,:) - - integer :: tsize, c, i, j, ierr, ncols - real(r8), parameter :: zero=0_r8, twopi=2_r8*pi - type(interp_type) :: lon_wgts, lat_wgts - integer :: lons(pcols), lats(pcols) - - nullify(wrk2d_in) - allocate( wrk2d(cnt(1),cnt(2)), stat=ierr ) - if( ierr /= 0 ) then - write(iulog,*) 'read_2d_trc: wrk2d allocation error = ',ierr - call endrun - end if - - if(order(1)/=1 .or. order(2)/=2 .or. cnt(1)/=file%nlon .or. cnt(2)/=file%nlat) then - allocate( wrk2d_in(file%nlon, file%nlat), stat=ierr ) - if( ierr /= 0 ) then - write(iulog,*) 'read_2d_trc: wrk2d_in allocation error = ',ierr - call endrun - end if - end if - - - - ierr = pio_get_var( fid, vid, strt, cnt, wrk2d ) - if(associated(wrk2d_in)) then - wrk2d_in = reshape( wrk2d(:,:),(/file%nlon,file%nlat/), order=order ) - deallocate(wrk2d) - else - wrk2d_in => wrk2d - end if - - j=1 - -! if weighting by latitude, the perform horizontal interpolation by using weight_x, weight_y - - if(file%weight_by_lat) then - - call t_startf('xy_interp') - - do c = begchunk,endchunk - ncols = get_ncols_p(c) - call get_lon_all_p(c,ncols,lons) - call get_lat_all_p(c,ncols,lats) - - call xy_interp(file%nlon,file%nlat,1,plon,plat,pcols,ncols,file%weight_x,file%weight_y,wrk2d_in,loc_arr(:,c-begchunk+1), & - lons,lats,file%count_x,file%count_y,file%index_x,file%index_y) - enddo - - call t_stopf('xy_interp') - - else - do c=begchunk,endchunk - ncols = get_ncols_p(c) - call get_rlat_all_p(c, pcols, to_lats) - call get_rlon_all_p(c, pcols, to_lons) - - call lininterp_init(file%lons, file%nlon, to_lons, ncols, 2, lon_wgts, zero, twopi) - call lininterp_init(file%lats, file%nlat, to_lats, ncols, 1, lat_wgts) - - call lininterp(wrk2d_in, file%nlon, file%nlat, loc_arr(1:ncols,c-begchunk+1), ncols, lon_wgts, lat_wgts) - - call lininterp_finish(lon_wgts) - call lininterp_finish(lat_wgts) - end do - endif - - if(allocated(wrk2d)) then - deallocate(wrk2d) - else - deallocate(wrk2d_in) - end if - if(dycore_is('LR')) call polar_average(loc_arr) - end subroutine read_2d_trc - -!------------------------------------------------------------------------ - - subroutine read_za_trc( fid, vid, loc_arr, strt, cnt, file, order ) - use interpolate_data, only : lininterp_init, lininterp, interp_type, lininterp_finish - use phys_grid, only : pcols, begchunk, endchunk, get_ncols_p, get_rlat_all_p, get_rlon_all_p - use mo_constants, only : pi - use dycore, only : dycore_is - use polar_avg, only : polar_average - - implicit none - type(file_desc_t), intent(in) :: fid - type(var_desc_t), intent(in) :: vid - integer, intent(in) :: strt(:), cnt(:) - integer, intent(in) :: order(2) - real(r8), intent(out):: loc_arr(:,:,:) - type (trfile), intent(in) :: file - - type(interp_type) :: lat_wgts - real(r8) :: to_lats(pcols), to_lons(pcols), wrk(pcols) - real(r8), allocatable, target :: wrk2d(:,:) - real(r8), pointer :: wrk2d_in(:,:) - integer :: c, k, ierr, ncols - - nullify(wrk2d_in) - allocate( wrk2d(cnt(1),cnt(2)), stat=ierr ) - if( ierr /= 0 ) then - write(iulog,*) 'read_2d_trc: wrk2d allocation error = ',ierr - call endrun - end if - - if(order(1)/=1 .or. order(2)/=2 .or. cnt(1)/=file%nlat .or. cnt(2)/=file%nlev) then - allocate( wrk2d_in(file%nlat, file%nlev), stat=ierr ) - if( ierr /= 0 ) then - write(iulog,*) 'read_2d_trc: wrk2d_in allocation error = ',ierr - call endrun - end if - end if - - - ierr = pio_get_var( fid, vid, strt, cnt, wrk2d ) - if(associated(wrk2d_in)) then - wrk2d_in = reshape( wrk2d(:,:),(/file%nlat,file%nlev/), order=order ) - deallocate(wrk2d) - else - wrk2d_in => wrk2d - end if - - - - do c=begchunk,endchunk - ncols = get_ncols_p(c) - call get_rlat_all_p(c, pcols, to_lats) - - call lininterp_init(file%lats, file%nlat, to_lats, ncols, 1, lat_wgts) - do k=1,file%nlev - call lininterp(wrk2d_in(:,k), file%nlat, wrk(1:ncols), ncols, lat_wgts) - loc_arr(1:ncols,k,c-begchunk+1) = wrk(1:ncols) - end do - call lininterp_finish(lat_wgts) - end do - - if(allocated(wrk2d)) then - deallocate(wrk2d) - else - deallocate(wrk2d_in) - end if -! if(dycore_is('LR')) call polar_average(loc_arr) - end subroutine read_za_trc -!------------------------------------------------------------------------ - subroutine read_za_trc_linoz( fid, vid, loc_arr, strt, cnt, file, order ,vid_srf) - use interpolate_data, only : lininterp_init, lininterp, interp_type, lininterp_finish - use phys_grid, only : pcols, begchunk, endchunk, get_ncols_p, get_rlat_all_p, get_rlon_all_p - use mo_constants, only : pi - use dycore, only : dycore_is - use polar_avg, only : polar_average - - implicit none - type(file_desc_t), intent(in) :: fid - type(var_desc_t), intent(in) :: vid - integer, intent(in) :: strt(:), cnt(:) - integer, intent(in) :: order(2) - real(r8), intent(out):: loc_arr(:,:,:) - type (trfile), intent(in) :: file - !! - type(var_desc_t), intent(in), optional :: vid_srf - integer :: cnt_srf(2) - integer :: strt_srf(2) - !! - type(interp_type) :: lat_wgts - real(r8) :: to_lats(pcols), to_lons(pcols), wrk(pcols) - real(r8), allocatable, target :: wrk2d(:,:) - real(r8), allocatable, target :: wrksrf(:) - real(r8), pointer :: wrk2d_in(:,:) - integer :: c, k, ierr, ncols - - nullify(wrk2d_in) - allocate( wrk2d(cnt(1),cnt(2)), stat=ierr ) - if( ierr /= 0 ) then - write(iulog,*) 'read_2d_trc: wrk2d allocation error = ',ierr - call endrun - end if - - if(order(1)/=1 .or. order(2)/=2 .or. cnt(1)/=file%nlat .or. cnt(2)/=file%nlev) then - allocate( wrk2d_in(file%nlat, file%nlev), stat=ierr ) - if( ierr /= 0 ) then - write(iulog,*) 'read_2d_trc: wrk2d_in allocation error = ',ierr - call endrun - end if - end if - !! - ierr = pio_get_var( fid, vid, strt, cnt, wrk2d ) - !! - if (file%linoz_v3) then - !!since io reads in global data for every thread - !!and interpolate to local chunk, we can do surface, - !!polar, and surface padding preprocessfor every variable - !!before interpolation - !!it is put here rather than the data formation process - !!to prevent forget when producing forcing data - !read in order of 0.1hPa~985hPa, pad top with 2nd layer - wrk2d(:,1)=wrk2d(:,2) - !both N/S poles need to pad by nearest data - wrk2d(1,:)=wrk2d(2,:) - wrk2d(file%nlat,:)=wrk2d(file%nlat-1,:) - !!read in srf data to pad surface - !!they are inputs from CMIP forcing and other references - cnt_srf(1)=cnt(1) - cnt_srf(2)=cnt(3) - strt_srf(1)=strt(1) - strt_srf(2)=strt(3) - !!check if vid_srf is present to determine clim variables - if (present(vid_srf)) then - !!padding for clim terms - allocate(wrksrf(cnt(1)), stat=ierr ) - ierr = pio_get_var( fid, vid_srf, strt_srf, cnt_srf, wrksrf ) - !!surface padding - wrk2d(:,file%nlev)=wrksrf - deallocate(wrksrf) - endif - !! - endif - !! - if(associated(wrk2d_in)) then - wrk2d_in = reshape( wrk2d(:,:),(/file%nlat,file%nlev/), order=order ) - deallocate(wrk2d) - else - wrk2d_in => wrk2d - end if - - do c=begchunk,endchunk - ncols = get_ncols_p(c) - call get_rlat_all_p(c, pcols, to_lats) - call lininterp_init(file%lats, file%nlat, to_lats, ncols, 1, lat_wgts) - do k=1,file%nlev - call lininterp(wrk2d_in(:,k), file%nlat, wrk(1:ncols), ncols, lat_wgts) - loc_arr(1:ncols,k,c-begchunk+1) = wrk(1:ncols) - end do - call lininterp_finish(lat_wgts) - end do - - if(allocated(wrk2d)) then - deallocate(wrk2d) - else - deallocate(wrk2d_in) - end if - !! - if(allocated(wrksrf)) then - deallocate(wrksrf) - end if -! if(dycore_is('LR')) call polar_average(loc_arr) - end subroutine read_za_trc_linoz - -!------------------------------------------------------------------------ - subroutine read_zasrf_trc_linoz( fid, vid, loc_arr, strt, cnt, file) - use interpolate_data, only : lininterp_init, lininterp, interp_type, lininterp_finish - use phys_grid, only : pcols, begchunk, endchunk, get_ncols_p, get_rlat_all_p, get_rlon_all_p - !! - implicit none - type(file_desc_t), intent(in) :: fid - type(var_desc_t), intent(in) :: vid - integer, intent(in) :: strt(:), cnt(:) - real(r8), intent(out):: loc_arr(:,:,:) - type (trfile), intent(in) :: file - !! - real(r8), allocatable, target :: wrk(:) - real(r8), pointer :: wrk_in(:) - real(r8) :: wrk_out(pcols) - type(interp_type) :: lat_wgts - real(r8) :: to_lats(pcols), to_lons(pcols) - integer :: c, k, ierr, ncols - integer :: cnt_srf(2) - integer :: strt_srf(2) - !! - nullify(wrk_in) - allocate( wrk(cnt(1)), stat=ierr ) - if( ierr /= 0 ) then - write(iulog,*) 'read_zasrf_trc_linoz: wrk allocation error = ',ierr - call endrun - end if - !! - cnt_srf(1)=cnt(1) - cnt_srf(2)=cnt(3) - strt_srf(1)=strt(1) - strt_srf(2)=strt(3) - !! - !for surface variable with the dimension of (time,lat) or (time,1) - !for (time) it is also set like (time,1) - ierr = pio_get_var( fid, vid, strt_srf, cnt_srf, wrk ) - !! - if(associated(wrk_in)) then - wrk_in = reshape( wrk(:),(/file%nlat/)) - deallocate(wrk) - else - wrk_in => wrk - end if - !! - do c=begchunk,endchunk - ncols = get_ncols_p(c) - call get_rlat_all_p(c, pcols, to_lats) - call lininterp_init(file%lats, file%nlat, to_lats, ncols, 1, lat_wgts) - !! - if (cnt(1).eq.1) then!!for single timeseries - do k=1,1 - loc_arr(1:ncols,k,c-begchunk+1) = wrk_in(1) - end do - else - do k=1,1 - call lininterp(wrk_in(:), file%nlat, wrk_out(1:ncols), ncols, lat_wgts) - loc_arr(1:ncols,k,c-begchunk+1) = wrk_out(1:ncols) - end do - end if - !! - call lininterp_finish(lat_wgts) - end do - !! - if(allocated(wrk)) then - deallocate(wrk) - else - deallocate(wrk_in) - end if - !! - end subroutine read_zasrf_trc_linoz - -!------------------------------------------------------------------------ - - subroutine read_3d_trc( fid, vid, loc_arr, strt, cnt, file, order) - use interpolate_data, only : lininterp_init, lininterp, interp_type, lininterp_finish - use phys_grid, only : pcols, begchunk, endchunk, get_ncols_p, get_rlat_all_p, get_rlon_all_p, get_lon_all_p,& - get_lat_all_p - use mo_constants, only : pi - use dycore, only : dycore_is - use polar_avg, only : polar_average - use dycore, only : dycore_is - use horizontal_interpolate, only : xy_interp - - implicit none - - type(file_desc_t), intent(in) :: fid - type(var_desc_t), intent(in) :: vid - integer, intent(in) :: strt(:), cnt(:), order(3) - real(r8),intent(out) :: loc_arr(:,:,:) - - type (trfile), intent(in) :: file - - integer :: i,j,k, astat, c, ncols - integer :: lons(pcols), lats(pcols) - - integer :: jlim(2), jl, ju, ierr - integer :: gndx - - real(r8), allocatable, target :: wrk3d(:,:,:) - real(r8), pointer :: wrk3d_in(:,:,:) - real(r8) :: to_lons(pcols), to_lats(pcols) - real(r8), parameter :: zero=0_r8, twopi=2_r8*pi - type(interp_type) :: lon_wgts, lat_wgts - - loc_arr(:,:,:) = 0._r8 - nullify(wrk3d_in) - allocate(wrk3d(cnt(1),cnt(2),cnt(3)), stat=ierr) - if( ierr /= 0 ) then - write(iulog,*) 'read_3d_trc: wrk3d allocation error = ',ierr - call endrun - end if - - ierr = pio_get_var( fid, vid, strt, cnt, wrk3d ) - - if(order(1)/=1 .or. order(2)/=2 .or. order(3)/=3 .or. & - cnt(1)/=file%nlon.or.cnt(2)/=file%nlat.or.cnt(3)/=file%nlev) then - allocate(wrk3d_in(file%nlon,file%nlat,file%nlev),stat=ierr) - if( ierr /= 0 ) then - write(iulog,*) 'read_3d_trc: wrk3d allocation error = ',ierr - call endrun - end if - wrk3d_in = reshape( wrk3d(:,:,:),(/file%nlon,file%nlat,file%nlev/), order=order ) - deallocate(wrk3d) - else - wrk3d_in => wrk3d - end if - - j=1 - -! If weighting by latitude, then perform horizontal interpolation by using weight_x, weight_y - - if(file%weight_by_lat) then - - call t_startf('xy_interp') - - do c = begchunk,endchunk - ncols = get_ncols_p(c) - call get_lon_all_p(c,ncols,lons) - call get_lat_all_p(c,ncols,lats) - - call xy_interp(file%nlon,file%nlat,file%nlev,plon,plat,pcols,ncols,file%weight_x,file%weight_y,wrk3d_in, & - loc_arr(:,:,c-begchunk+1), lons,lats,file%count_x,file%count_y,file%index_x,file%index_y) - enddo - - call t_stopf('xy_interp') - - else - do c=begchunk,endchunk - ncols = get_ncols_p(c) - call get_rlat_all_p(c, pcols, to_lats) - call get_rlon_all_p(c, pcols, to_lons) - - call lininterp_init(file%lons, file%nlon, to_lons(1:ncols), ncols, 2, lon_wgts, zero, twopi) - call lininterp_init(file%lats, file%nlat, to_lats(1:ncols), ncols, 1, lat_wgts) - - - call lininterp(wrk3d_in, file%nlon, file%nlat, file%nlev, loc_arr(:,:,c-begchunk+1), ncols, pcols, lon_wgts, lat_wgts) - - - call lininterp_finish(lon_wgts) - call lininterp_finish(lat_wgts) - end do - endif - - if(allocated(wrk3d)) then - deallocate( wrk3d, stat=astat ) - else - deallocate( wrk3d_in, stat=astat ) - end if - if( astat/= 0 ) then - write(iulog,*) 'read_3d_trc: failed to deallocate wrk3d array; error = ',astat - call endrun - endif - if(dycore_is('LR')) call polar_average(file%nlev, loc_arr) - end subroutine read_3d_trc - -!------------------------------------------------------------------------------ - - subroutine interpolate_trcdata( state, flds, file, pbuf2d ) - use mo_util, only : rebin - use physics_types,only : physics_state - use physconst, only : cday - use physics_buffer, only : physics_buffer_desc, pbuf_get_field - - implicit none - - type(physics_state), intent(in) :: state(begchunk:endchunk) - type (trfld), intent(inout) :: flds(:) - type (trfile), intent(inout) :: file - - type(physics_buffer_desc), optional, pointer :: pbuf2d(:,:) - - - real(r8) :: fact1, fact2 - real(r8) :: deltat - integer :: f,nflds,c,ncol, i,k - real(r8) :: ps(pcols) - real(r8) :: datain(pcols,file%nlev) - real(r8) :: pin(pcols,file%nlev) - real(r8) :: pint(pcols,file%nilev) - - real(r8) :: model_z(pverp) - real(r8), parameter :: m2km = 1.e-3_r8 - real(r8), pointer :: data_out3d(:,:,:) - real(r8), pointer :: data_out(:,:) - integer :: chnk_offset - - nflds = size(flds) - - if ( file%interp_recs == 4 ) then - deltat = file%datatimes(3) - file%datatimes(1) - fact1 = (file%datatimes(3) - file%datatimem)/deltat - fact2 = 1._r8-fact1 -!$OMP PARALLEL DO PRIVATE (C, NCOL, F) - do c = begchunk,endchunk - ncol = state(c)%ncol - if ( file%has_ps ) then - file%ps_in(1)%data(:ncol,c) = fact1*file%ps_in(1)%data(:ncol,c) + fact2*file%ps_in(3)%data(:ncol,c) - endif - do f = 1,nflds - flds(f)%input(1)%data(:ncol,:,c) = fact1*flds(f)%input(1)%data(:ncol,:,c) + fact2*flds(f)%input(3)%data(:ncol,:,c) - enddo - enddo - - deltat = file%datatimes(4) - file%datatimes(2) - fact1 = (file%datatimes(4) - file%datatimep)/deltat - fact2 = 1._r8-fact1 - -!$OMP PARALLEL DO PRIVATE (C, NCOL, F) - do c = begchunk,endchunk - ncol = state(c)%ncol - if ( file%has_ps ) then - file%ps_in(2)%data(:ncol,c) = fact1*file%ps_in(2)%data(:ncol,c) + fact2*file%ps_in(4)%data(:ncol,c) - endif - do f = 1,nflds - flds(f)%input(2)%data(:ncol,:,c) = fact1*flds(f)%input(2)%data(:ncol,:,c) + fact2*flds(f)%input(4)%data(:ncol,:,c) - enddo - enddo - - endif - !------------------------------------------------------------------------- - ! If file%interp_recs=1 then no time interpolation -- set - ! fact1=1 and fact2=0 and will just use first value unmodified - !------------------------------------------------------------------------- - - if (file%interp_recs == 1) then - fact1=1._r8 - fact2=0._r8 - else - file%interp_recs = 2 - - deltat = file%datatimep - file%datatimem - - if ( file%cyclical .and. (deltat < 0._r8) ) then - deltat = deltat+file%one_yr - if ( file%datatimep >= file%curr_mod_time ) then - fact1 = (file%datatimep - file%curr_mod_time)/deltat - else - fact1 = (file%datatimep+file%one_yr - file%curr_mod_time)/deltat - endif - else - fact1 = (file%datatimep - file%curr_mod_time)/deltat - endif - - ! this assures that FIXED data are b4b on restarts - if ( file%fixed ) then - fact1 = dble(int(fact1*cday+.5_r8))/dble(cday) - endif - fact2 = 1._r8-fact1 - endif - - chnk_offset=-begchunk+1 - - fld_loop: do f = 1,nflds - - if (flds(f)%pbuf_ndx<=0) then - data_out3d => flds(f)%data(:,:,:) - endif - -!$OMP PARALLEL DO PRIVATE (C, NCOL, PS, I, K, PIN, DATAIN, MODEL_Z, DATA_OUT) - do c = begchunk,endchunk - if (flds(f)%pbuf_ndx>0) then - if(.not.present(pbuf2d)) then - call endrun ('tracer_data.F90(subr interpolate_trcdata):' // & - 'pbuf2d must be passed as an argument for pbuf_get_field subr call') - endif - call pbuf_get_field(pbuf2d, c, flds(f)%pbuf_ndx, data_out) - else - data_out => data_out3d(:,:,c+chnk_offset) - endif - ncol = state(c)%ncol - if (file%alt_data) then - - if (fact2 == 0) then ! This needed as %data is not set if fact2=0 (and lahey compiler core dumps) - datain(:ncol,:) = fact1*flds(f)%input(nm)%data(:ncol,:,c) - else - datain(:ncol,:) = fact1*flds(f)%input(nm)%data(:ncol,:,c) + fact2*flds(f)%input(np)%data(:ncol,:,c) - end if - do i = 1,ncol - model_z(1:pverp) = m2km * state(c)%zi(i,pverp:1:-1) - call rebin( file%nlev, pver, file%ilevs, model_z, datain(i,:), data_out(i,:) ) - enddo - - else - - if ( file%nlev>1 ) then - if ( file%has_ps ) then - if (fact2 == 0) then ! This needed as %data is not set if fact2=0 (and lahey compiler core dumps) - ps(:ncol) = fact1*file%ps_in(nm)%data(:ncol,c) - else - ps(:ncol) = fact1*file%ps_in(nm)%data(:ncol,c) + fact2*file%ps_in(np)%data(:ncol,c) - end if - do i = 1,ncol - do k = 1,file%nlev - pin(i,k) = file%p0*file%hyam(k) + ps(i)*file%hybm(k) - enddo - enddo - else - do k = 1,file%nlev - pin(:,k) = file%levs(k) - enddo - !!Currently designed for linoz_v2/v3 use - if (file%linoz_v3 .or. file%linoz_v2) then - do k = 1,file%nilev - pint(:,k) = file%ilevs(k) - enddo - endif - endif - endif - - if (flds(f)%srf_fld) then - do i = 1,ncol - if (fact2 == 0) then ! This needed as %data is not set if fact2=0 (and lahey compiler core dumps) - data_out(i,1) = & - fact1*flds(f)%input(nm)%data(i,1,c) - else - data_out(i,1) = & - fact1*flds(f)%input(nm)%data(i,1,c) + fact2*flds(f)%input(np)%data(i,1,c) - endif - enddo - else - if (fact2 == 0) then ! This needed as %data is not set if fact2=0 (and lahey compiler core dumps) - datain(:ncol,:) = fact1*flds(f)%input(nm)%data(:ncol,:,c) - else - datain(:ncol,:) = fact1*flds(f)%input(nm)%data(:ncol,:,c) + fact2*flds(f)%input(np)%data(:ncol,:,c) - end if - if ( file%top_bndry ) then - call vert_interp_ub(ncol, file%nlev, file%levs, datain(:ncol,:), data_out(:ncol,:) ) - else if(file%conserve_column) then - call vert_interp_mixrat(ncol,file%nlev,pver,state(c)%pint, & - datain, data_out(:,:), & - file%p0,ps,file%hyai,file%hybi) - else if(file%linoz_v3 .or. file%linoz_v2) then - !!uci chemistry for linoz that better conserves mass - !!uci interpolation for 55 out of 57 variables in linoz_v3 - !!excluding t_clim, o3col_clim - !!for linoz_v2 it is simiar with less variables - if (flds(f)%fldnam.ne.'t_clim ' & - .and.flds(f)%fldnam.ne.'o3col_clim ') then - !!file ilevs is in hPa, while model level in Pa, so times 100 - call vert_interp_uci(ncol, file%nlev, 100*file%ilevs, state(c)%pint, datain, data_out(:,:) ) - else - call vert_interp(ncol, file%nlev, pin, state(c)%pmid, datain, data_out(:,:) ) - endif - !! - else - call vert_interp(ncol, file%nlev, pin, state(c)%pmid, datain, data_out(:,:) ) - endif - endif - - endif - enddo - - enddo fld_loop - - end subroutine interpolate_trcdata - -!----------------------------------------------------------------------- -!----------------------------------------------------------------------- - subroutine get_dimension( fid, dname, dsize, dimid, data ) - implicit none - type(file_desc_t), intent(inout) :: fid - character(*), intent(in) :: dname - integer, intent(out) :: dsize - - integer, optional, intent(out) :: dimid - real(r8), optional, pointer, dimension(:) :: data - - integer :: vid, ierr, id - - call pio_seterrorhandling( fid, PIO_BCAST_ERROR) - ierr = pio_inq_dimid( fid, dname, id ) - call pio_seterrorhandling( fid, PIO_INTERNAL_ERROR) - - if ( ierr==PIO_NOERR ) then - - ierr = pio_inq_dimlen( fid, id, dsize ) - - if ( present(dimid) ) then - dimid = id - endif - - if ( present(data) ) then - if ( associated(data) ) then - deallocate(data, stat=ierr) - if( ierr /= 0 ) then - write(iulog,*) 'get_dimension: data deallocation error = ',ierr - call endrun('get_dimension: failed to deallocate data array') - end if - endif - allocate( data(dsize), stat=ierr ) - if( ierr /= 0 ) then - write(iulog,*) 'get_dimension: data allocation error = ',ierr - call endrun('get_dimension: failed to allocate data array') - end if - - ierr = pio_inq_varid( fid, dname, vid ) - ierr = pio_get_var( fid, vid, data ) - endif - else - dsize = 1 - if ( present(dimid) ) then - dimid = -1 - endif - endif - - end subroutine get_dimension - -!----------------------------------------------------------------------- -!----------------------------------------------------------------------- - subroutine set_cycle_indices( fileid, cyc_ndx_beg, cyc_ndx_end, cyc_yr ) - - implicit none - - type(file_desc_t), intent(inout) :: fileid - integer, intent(out) :: cyc_ndx_beg - integer, intent(out) :: cyc_ndx_end - integer, intent(in) :: cyc_yr - - integer, allocatable , dimension(:) :: dates, datesecs - integer :: timesize, i, astat, year, ierr - type(var_desc_T) :: dateid - call get_dimension( fileid, 'time', timesize ) - cyc_ndx_beg=-1 - - allocate( dates(timesize), stat=astat ) - if( astat/= 0 ) then - write(*,*) 'set_cycle_indices: failed to allocate dates array; error = ',astat - call endrun - end if - - ierr = pio_inq_varid( fileid, 'date', dateid ) - ierr = pio_get_var( fileid, dateid, dates ) - - do i=1,timesize - year = dates(i) / 10000 - if ( year == cyc_yr ) then - if (cyc_ndx_beg < 0) then - cyc_ndx_beg = i - endif - cyc_ndx_end = i - endif - enddo - deallocate( dates, stat=astat ) - if( astat/= 0 ) then - write(*,*) 'set_cycle_indices: failed to deallocate dates array; error = ',astat - call endrun - end if - if (cyc_ndx_beg < 0) then - write(*,*) 'set_cycle_indices: cycle year not found : ' , cyc_yr - call endrun('set_cycle_indices: cycle year not found') - endif - - end subroutine set_cycle_indices -!----------------------------------------------------------------------- - -!----------------------------------------------------------------------- - subroutine open_trc_datafile( fname, path, piofile, times, cyc_ndx_beg, cyc_ndx_end, cyc_yr ) - - use ioFileMod, only: getfil - use cam_pio_utils, only: cam_pio_openfile - - implicit none - - character(*), intent(in) :: fname - character(*), intent(in) :: path - type(file_desc_t), intent(inout) :: piofile - real(r8), pointer :: times(:) - - integer, optional, intent(out) :: cyc_ndx_beg - integer, optional, intent(out) :: cyc_ndx_end - integer, optional, intent(in) :: cyc_yr - - character(len=shr_kind_cl) :: filen, filepath - integer :: year, month, day, dsize, i, timesize - integer :: dateid,secid - integer, allocatable , dimension(:) :: dates, datesecs - integer :: astat, ierr - logical :: need_first_ndx - - if (len_trim(path) == 0) then - filepath = trim(fname) - else - filepath = trim(path) // '/' // trim(fname) - end if - ! - ! open file and get fileid - ! - call getfil( filepath, filen, 0 ) - call cam_pio_openfile( piofile, filen, PIO_NOWRITE) - if(masterproc) write(iulog,*)'open_trc_datafile: ',trim(filen) - - call get_dimension(piofile, 'time', timesize) - - if ( associated(times) ) then - deallocate(times, stat=ierr) - if( ierr /= 0 ) then - write(iulog,*) 'open_trc_datafile: data deallocation error = ',ierr - call endrun('open_trc_datafile: failed to deallocate data array') - end if - endif - allocate( times(timesize), stat=ierr ) - if( ierr /= 0 ) then - write(iulog,*) 'open_trc_datafile: data allocation error = ',ierr - call endrun('open_trc_datafile: failed to allocate data array') - end if - - allocate( dates(timesize), stat=astat ) - if( astat/= 0 ) then - if(masterproc) write(iulog,*) 'open_trc_datafile: failed to allocate dates array; error = ',astat - call endrun - end if - allocate( datesecs(timesize), stat=astat ) - if( astat/= 0 ) then - if(masterproc) write(iulog,*) 'open_trc_datafile: failed to allocate datesec array; error = ',astat - call endrun - end if - - ierr = pio_inq_varid( piofile, 'date', dateid ) - call pio_seterrorhandling( piofile, PIO_BCAST_ERROR) - ierr = pio_inq_varid( piofile, 'datesec', secid ) - call pio_seterrorhandling( piofile, PIO_INTERNAL_ERROR) - - if(ierr==PIO_NOERR) then - ierr = pio_get_var( piofile, secid, datesecs ) - else - datesecs=0 - end if - - ierr = pio_get_var( piofile, dateid, dates ) - need_first_ndx=.true. - - do i=1,timesize - year = dates(i) / 10000 - month = mod(dates(i),10000)/100 - day = mod(dates(i),100) - call set_time_float_from_date( times(i), year, month, day, datesecs(i) ) - if ( present(cyc_yr) ) then - if ( year == cyc_yr ) then - if ( present(cyc_ndx_beg) .and. need_first_ndx ) then - cyc_ndx_beg = i - need_first_ndx = .false. - endif - if ( present(cyc_ndx_end) ) then - cyc_ndx_end = i - endif - endif - endif - enddo - - deallocate( dates, stat=astat ) - if( astat/= 0 ) then - if(masterproc) write(iulog,*) 'open_trc_datafile: failed to deallocate dates array; error = ',astat - call endrun - end if - deallocate( datesecs, stat=astat ) - if( astat/= 0 ) then - if(masterproc) write(iulog,*) 'open_trc_datafile: failed to deallocate datesec array; error = ',astat - call endrun - end if - - if ( present(cyc_yr) .and. present(cyc_ndx_beg) ) then - if (cyc_ndx_beg < 0) then - write(iulog,*) 'open_trc_datafile: cycle year not found : ' , cyc_yr - call endrun('open_trc_datafile: cycle year not found') - endif - endif - - end subroutine open_trc_datafile - -!-------------------------------------------------------------------------- -!-------------------------------------------------------------------------- - subroutine specify_fields( specifier, fields ) - - implicit none - - character(len=*), intent(in) :: specifier(:) - type(trfld), pointer, dimension(:) :: fields - - integer :: fld_cnt, astat - integer :: i,j - character(len=shr_kind_cl) :: str1, str2 - character(len=32), allocatable, dimension(:) :: fld_name, src_name - integer :: nflds - - nflds = size(specifier) - - allocate(fld_name(nflds), src_name(nflds), stat=astat ) - if( astat/= 0 ) then - write(iulog,*) 'specify_fields: failed to allocate fld_name, src_name arrays; error = ',astat - call endrun - end if - - fld_cnt = 0 - - count_cnst: do i = 1, nflds - - if ( len_trim( specifier(i) ) == 0 ) then - exit count_cnst - endif - - j = scan( specifier(i),':') - - if (j > 0) then - str1 = trim(adjustl( specifier(i)(:j-1) )) - str2 = trim(adjustl( specifier(i)(j+1:) )) - fld_name(i) = trim(adjustl( str1 )) - src_name(i) = trim(adjustl( str2 )) - else - fld_name(i) = trim(adjustl( specifier(i) )) - src_name(i) = trim(adjustl( specifier(i) )) - endif - - fld_cnt = fld_cnt + 1 - - enddo count_cnst - - if( fld_cnt < 1 ) then - nullify(fields) - return - end if - - !----------------------------------------------------------------------- - ! ... allocate field type array - !----------------------------------------------------------------------- - allocate( fields(fld_cnt), stat=astat ) - if( astat/= 0 ) then - write(iulog,*) 'specify_fields: failed to allocate fields array; error = ',astat - call endrun - end if - - do i = 1,fld_cnt - fields(i)%fldnam = fld_name(i) - fields(i)%srcnam = src_name(i) - enddo - - deallocate(fld_name, src_name) - - end subroutine specify_fields - -!------------------------------------------------------------------------------ - - subroutine init_trc_restart( whence, piofile, tr_file ) - - implicit none - character(len=*), intent(in) :: whence - type(file_desc_t), intent(inout) :: piofile - type(trfile), intent(inout) :: tr_file - - character(len=32) :: name - integer :: ioerr, mcdimid, maxlen - - - ! Dimension should already be defined in restart file - call pio_seterrorhandling(pioFile, PIO_BCAST_ERROR) - ioerr = pio_inq_dimid(pioFile,'max_chars', mcdimid) - call pio_seterrorhandling(pioFile, PIO_INTERNAL_ERROR) - ! but define it if nessasary - if(ioerr/= PIO_NOERR) then - ioerr = pio_def_dim(pioFile, 'max_chars', SHR_KIND_CL, mcdimid) - end if - - if(len_trim(tr_file%curr_filename)>1) then - allocate(tr_file%currfnameid) - name = trim(whence)//'_curr_fname' - ioerr = pio_def_var(pioFile, name,pio_char, (/mcdimid/), tr_file%currfnameid) - ioerr = pio_put_att(pioFile, tr_file%currfnameid, 'offset_time', tr_file%offset_time) - maxlen = len_trim(tr_file%curr_filename) - ioerr = pio_put_att(pioFile, tr_file%currfnameid, 'actual_len', maxlen) - else - nullify(tr_file%currfnameid) - end if - - if(len_trim(tr_file%next_filename)>1) then - allocate(tr_file%nextfnameid) - name = trim(whence)//'_next_fname' - ioerr = pio_def_var(pioFile, name,pio_char, (/mcdimid/), tr_file%nextfnameid) - maxlen = len_trim(tr_file%next_filename) - ioerr = pio_put_att(pioFile, tr_file%nextfnameid, 'actual_len', maxlen) - else - nullify(tr_file%nextfnameid) - end if - end subroutine init_trc_restart -!------------------------------------------------------------------------- -! writes file names to restart file -!------------------------------------------------------------------------- - subroutine write_trc_restart( piofile, tr_file ) - - implicit none - - type(file_desc_t), intent(inout) :: piofile - type(trfile), intent(inout) :: tr_file - - integer :: ioerr, slen ! error status - if(associated(tr_file%currfnameid)) then - ioerr = pio_put_var(pioFile, tr_file%currfnameid, tr_file%curr_filename) - deallocate(tr_file%currfnameid) - nullify(tr_file%currfnameid) - end if - if(associated(tr_file%nextfnameid)) then - ioerr = pio_put_var(pioFile, tr_file%nextfnameid, tr_file%next_filename) - deallocate(tr_file%nextfnameid) - nullify(tr_file%nextfnameid) - end if - end subroutine write_trc_restart - -!------------------------------------------------------------------------- -! reads file names from restart file -!------------------------------------------------------------------------- - subroutine read_trc_restart( whence, piofile, tr_file ) - - implicit none - - character(len=*), intent(in) :: whence - type(file_desc_t), intent(inout) :: piofile - type(trfile), intent(inout) :: tr_file - type(var_desc_t) :: vdesc - character(len=64) :: name - integer :: ioerr ! error status - integer :: slen - - call PIO_SetErrorHandling(piofile, PIO_BCAST_ERROR) - name = trim(whence)//'_curr_fname' - ioerr = pio_inq_varid(piofile, name, vdesc) - if(ioerr==PIO_NOERR) then - tr_file%curr_filename=' ' - ioerr = pio_get_att(piofile, vdesc, 'offset_time', tr_file%offset_time) - ioerr = pio_get_att(piofile, vdesc, 'actual_len', slen) - ioerr = pio_get_var(piofile, vdesc, tr_file%curr_filename) - if(slen P2 (decreasing up) -!--- integrates (p-avg) the value F0 from F on the grid P -!--- assumes model pressure increases from top to bottom. -!---NOTE reverse order in P's -!---Assume that the quantity is constant over range halfway to layer above/below -!--- and calculate box edges from model top to model bottom -! -!---For a model level between pressure range P1 > P2 (decreasing up) -!---calculate the SOM Z-moments of the loss freq at std z* (log-p) intervals -!-------- the pressure levels BETWEEN z* values are: -! P(i) < P(i+1) bounds z*(i) -!-------- The MOMENTS for a square-wave or 'bar': F(x)=F0 b<=x<=c, =0.0 else -!----- S0 = f0 (x) [from x=b to x=c] -!----------------------------------------------------------------------- - implicit none - integer, intent(in) :: NL - real(r8), intent(in) :: P1,P2,P(NL+1),F(NL) - real(r8), intent(out):: F0 - integer I - real(r8) XB,XC,PC,PB,SGNF0,PF1,PF2 -!----------------------------------------------------------------------- - F0 = 0._r8 - ! - do I = 1,NL - PF1=P(I) - PF2=P(I+1) - ! - PC = min(P1,PF2) - PB = max(P2,PF1) - ! - if (PC .gt. PB) then -!--- have condition: P1 .ge. PC .gt. PB .ge. P2 -!--- and 0 .le. XB .lt. XC .le. 1 - XC = (PC-P2)/(P1-P2) - XB = (PB-P2)/(P1-P2) -!-------- assume that the quantity, F, is constant over interval [XLO,XUP], -!-------- F0: (c-b), -!-------- calculate its contribution to the moments in the interval [0,1] - F0 = F0 +F(I) *(XC -XB) - endif - enddo -!---limiter on Z-moments: force monotonicity (tables can be + or -) - SGNF0 = sign(1._r8, F0) - F0 = abs(F0) - F0 = SGNF0 * F0 - END SUBROUTINE vert_interp_uci_single -!------------------------------------------------------------------------------ - subroutine vert_interp_ub( ncol, nlevs, plevs, datain, dataout ) - use ref_pres, only : ptop_ref - - - !----------------------------------------------------------------------- - ! - ! Interpolate data from current time-interpolated values to top interface pressure - ! -- from mo_tgcm_ubc.F90 - !-------------------------------------------------------------------------- - implicit none - ! Arguments - ! - integer, intent(in) :: ncol - integer, intent(in) :: nlevs - real(r8), intent(in) :: plevs(nlevs) - real(r8), intent(in) :: datain(ncol,nlevs) - real(r8), intent(out) :: dataout(ncol) - - ! - ! local variables - ! - integer :: i,ku,kl,kk - real(r8) :: pinterp, delp - - pinterp = ptop_ref - - if( pinterp <= plevs(1) ) then - kl = 1 - ku = 1 - delp = 0._r8 - else if( pinterp >= plevs(nlevs) ) then - kl = nlevs - ku = nlevs - delp = 0._r8 - else - - do kk = 2,nlevs - if( pinterp <= plevs(kk) ) then - ku = kk - kl = kk - 1 - delp = log( pinterp/plevs(kk) ) / log( plevs(kk-1)/plevs(kk) ) - exit - end if - end do - - end if - - do i = 1,ncol - dataout(i) = datain(i,kl) + delp * (datain(i,ku) - datain(i,kl)) - end do - - end subroutine vert_interp_ub -!------------------------------------------------------------------------------ - -!------------------------------------------------------------------------------ -!------------------------------------------------------------------------------ - subroutine advance_file(file) - - !------------------------------------------------------------------------------ - ! This routine advances to the next file - !------------------------------------------------------------------------------ - - use shr_sys_mod, only: shr_sys_system - use ioFileMod, only: getfil - - implicit none - - type(trfile), intent(inout) :: file - - !----------------------------------------------------------------------- - ! local variables - !----------------------------------------------------------------------- - character(len=shr_kind_cl) :: ctmp - character(len=shr_kind_cl) :: loc_fname - integer :: istat, astat - - !----------------------------------------------------------------------- - ! close current file ... - !----------------------------------------------------------------------- - call pio_closefile( file%curr_fileid ) - - !----------------------------------------------------------------------- - ! remove if requested - !----------------------------------------------------------------------- - if( file%remove_trc_file ) then - call getfil( file%curr_filename, loc_fname, 0 ) - write(iulog,*) 'advance_file: removing file = ',trim(loc_fname) - ctmp = 'rm -f ' // trim(loc_fname) - write(iulog,*) 'advance_file: fsystem issuing command - ' - write(iulog,*) trim(ctmp) - call shr_sys_system( ctmp, istat ) - end if - - !----------------------------------------------------------------------- - ! Advance the filename and file id - !----------------------------------------------------------------------- - file%curr_filename = file%next_filename - file%curr_fileid = file%next_fileid - - !----------------------------------------------------------------------- - ! Advance the curr_data_times - !----------------------------------------------------------------------- - deallocate( file%curr_data_times, stat=astat ) - if( astat/= 0 ) then - write(iulog,*) 'advance_file: failed to deallocate file%curr_data_times array; error = ',astat - call endrun - end if - allocate( file%curr_data_times( size( file%next_data_times ) ), stat=astat ) - if( astat/= 0 ) then - write(iulog,*) 'advance_file: failed to allocate file%curr_data_times array; error = ',astat - call endrun - end if - file%curr_data_times(:) = file%next_data_times(:) - - !----------------------------------------------------------------------- - ! delete information about next file (as was just assigned to current) - !----------------------------------------------------------------------- - file%next_filename = '' - - deallocate( file%next_data_times, stat=astat ) - if( astat/= 0 ) then - write(iulog,*) 'advance_file: failed to deallocate file%next_data_times array; error = ',astat - call endrun - end if - nullify( file%next_data_times ) - - end subroutine advance_file - -end module tracer_data From 9bb98d766f8cb6e44e40805ad7c856ad6c0861b2 Mon Sep 17 00:00:00 2001 From: Wuyin Lin Date: Wed, 28 Aug 2024 22:45:09 -0500 Subject: [PATCH 356/451] Add ext_frc_volc_type to use_cases having only volcanic SO2 varying over years --- .../use_cases/20TR_eam_CMIP6-nat_chemUCI-Linoz-mam5-vbs.xml | 1 + .../use_cases/20TR_eam_CMIP6-volc_chemUCI-Linoz-mam5-vbs.xml | 1 + .../20TR_eam_CMIP6-xGHG-xaer_chemUCI-Linoz-mam5-vbs.xml | 1 + .../use_cases/20TR_eam_CMIP6-xaer_chemUCI-Linoz-mam5-vbs.xml | 1 + 4 files changed, 4 insertions(+) diff --git a/components/eam/bld/namelist_files/use_cases/20TR_eam_CMIP6-nat_chemUCI-Linoz-mam5-vbs.xml b/components/eam/bld/namelist_files/use_cases/20TR_eam_CMIP6-nat_chemUCI-Linoz-mam5-vbs.xml index 94cdfc6d000d..493affd96414 100644 --- a/components/eam/bld/namelist_files/use_cases/20TR_eam_CMIP6-nat_chemUCI-Linoz-mam5-vbs.xml +++ b/components/eam/bld/namelist_files/use_cases/20TR_eam_CMIP6-nat_chemUCI-Linoz-mam5-vbs.xml @@ -22,6 +22,7 @@ +INTERP_MISSING_MONTHS CYCLICAL 1850 atm/cam/chem/trop_mozart_aero/emis/chem_gases/2degrees/emissions-cmip6_NO2_aircraft_vertical_1750-2015_1.9x2.5_c20170608.nc diff --git a/components/eam/bld/namelist_files/use_cases/20TR_eam_CMIP6-volc_chemUCI-Linoz-mam5-vbs.xml b/components/eam/bld/namelist_files/use_cases/20TR_eam_CMIP6-volc_chemUCI-Linoz-mam5-vbs.xml index 6f0754423592..83d4c4d92717 100644 --- a/components/eam/bld/namelist_files/use_cases/20TR_eam_CMIP6-volc_chemUCI-Linoz-mam5-vbs.xml +++ b/components/eam/bld/namelist_files/use_cases/20TR_eam_CMIP6-volc_chemUCI-Linoz-mam5-vbs.xml @@ -23,6 +23,7 @@ +INTERP_MISSING_MONTHS CYCLICAL 1850 atm/cam/chem/trop_mozart_aero/emis/chem_gases/2degrees/emissions-cmip6_NO2_aircraft_vertical_1750-2015_1.9x2.5_c20170608.nc diff --git a/components/eam/bld/namelist_files/use_cases/20TR_eam_CMIP6-xGHG-xaer_chemUCI-Linoz-mam5-vbs.xml b/components/eam/bld/namelist_files/use_cases/20TR_eam_CMIP6-xGHG-xaer_chemUCI-Linoz-mam5-vbs.xml index f70010a82c44..671eb826ef14 100644 --- a/components/eam/bld/namelist_files/use_cases/20TR_eam_CMIP6-xGHG-xaer_chemUCI-Linoz-mam5-vbs.xml +++ b/components/eam/bld/namelist_files/use_cases/20TR_eam_CMIP6-xGHG-xaer_chemUCI-Linoz-mam5-vbs.xml @@ -22,6 +22,7 @@ +INTERP_MISSING_MONTHS CYCLICAL 1850 atm/cam/chem/trop_mozart_aero/emis/chem_gases/2degrees/emissions-cmip6_NO2_aircraft_vertical_1750-2015_1.9x2.5_c20170608.nc diff --git a/components/eam/bld/namelist_files/use_cases/20TR_eam_CMIP6-xaer_chemUCI-Linoz-mam5-vbs.xml b/components/eam/bld/namelist_files/use_cases/20TR_eam_CMIP6-xaer_chemUCI-Linoz-mam5-vbs.xml index 359a292e9e12..8dd525d7e5d3 100644 --- a/components/eam/bld/namelist_files/use_cases/20TR_eam_CMIP6-xaer_chemUCI-Linoz-mam5-vbs.xml +++ b/components/eam/bld/namelist_files/use_cases/20TR_eam_CMIP6-xaer_chemUCI-Linoz-mam5-vbs.xml @@ -19,6 +19,7 @@ +INTERP_MISSING_MONTHS CYCLICAL 1850 atm/cam/chem/trop_mozart_aero/emis/chem_gases/2degrees/emissions-cmip6_NO2_aircraft_vertical_1750-2015_1.9x2.5_c20170608.nc From 04872f3350c20c5e10faf14785c11d647f6bbe12 Mon Sep 17 00:00:00 2001 From: Azamat Mametjanov Date: Fri, 30 Aug 2024 03:00:57 +0000 Subject: [PATCH 357/451] Update Aurora machine config --- cime_config/allactive/config_pesall.xml | 8 ++-- .../cmake_macros/oneapi-ifxgpu_aurora.cmake | 1 - cime_config/machines/config_batch.xml | 2 +- cime_config/machines/config_machines.xml | 47 +++++++++---------- .../eamxx/cmake/machine-files/aurora.cmake | 14 ++++++ 5 files changed, 41 insertions(+), 31 deletions(-) create mode 100644 components/eamxx/cmake/machine-files/aurora.cmake diff --git a/cime_config/allactive/config_pesall.xml b/cime_config/allactive/config_pesall.xml index 84c0e24d8c9b..3392ad71ca10 100644 --- a/cime_config/allactive/config_pesall.xml +++ b/cime_config/allactive/config_pesall.xml @@ -1472,9 +1472,9 @@ - + - sunspot: --compset BGC* --res ne30pg2_r05_IcoswISC30E3r5 on 2 nodes pure-MPI + sunspot|aurora: --compset BGC* --res ne30pg2_r05_IcoswISC30E3r5 on 2 nodes pure-MPI -2 -2 @@ -1759,9 +1759,9 @@ - + - allactive+sunspot: default, 96 mpi x 1 omp @ root 0 + allactive+sunspot|aurora: default, 96 mpi x 1 omp @ root 0 96 96 diff --git a/cime_config/machines/cmake_macros/oneapi-ifxgpu_aurora.cmake b/cime_config/machines/cmake_macros/oneapi-ifxgpu_aurora.cmake index 16288ce4dee7..6835515164f0 100644 --- a/cime_config/machines/cmake_macros/oneapi-ifxgpu_aurora.cmake +++ b/cime_config/machines/cmake_macros/oneapi-ifxgpu_aurora.cmake @@ -3,6 +3,5 @@ string(APPEND CMAKE_EXE_LINKER_FLAGS " -lmkl_intel_lp64 -lmkl_sequential -lmkl_c if (compile_threaded) string(APPEND CMAKE_EXE_LINKER_FLAGS " -fiopenmp -fopenmp-targets=spir64") endif() -string(APPEND KOKKOS_OPTIONS " -DCMAKE_CXX_STANDARD=17 -DKokkos_ENABLE_SERIAL=On -DKokkos_ARCH_INTEL_PVC=On -DKokkos_ENABLE_SYCL=On -DKokkos_ENABLE_EXPLICIT_INSTANTIATION=Off") string(APPEND SYCL_FLAGS " -\-intel -fsycl -fsycl-targets=spir64_gen -mlong-double-64 -Xsycl-target-backend \"-device 12.60.7\"") string(APPEND CMAKE_CXX_FLAGS " -Xclang -fsycl-allow-virtual-functions") diff --git a/cime_config/machines/config_batch.xml b/cime_config/machines/config_batch.xml index 448eefece216..13cfdfb337b6 100644 --- a/cime_config/machines/config_batch.xml +++ b/cime_config/machines/config_batch.xml @@ -562,7 +562,7 @@ - /lus/gecko/projects/CSC249ADSE15_CNDA/tools/qsub/throttle + /lus/flare/projects/CSC249ADSE15_CNDA/tools/qsub/throttle EarlyAppAccess workq-route diff --git a/cime_config/machines/config_machines.xml b/cime_config/machines/config_machines.xml index fed0110bc32b..f1bed254da48 100644 --- a/cime_config/machines/config_machines.xml +++ b/cime_config/machines/config_machines.xml @@ -3474,14 +3474,14 @@ oneapi-ifx,oneapi-ifxgpu,gnu mpich CSC249ADSE15_CNDA - /lus/gecko/projects/CSC249ADSE15_CNDA/performance_archive + /lus/flare/projects/CSC249ADSE15_CNDA/performance_archive .* - /lus/gecko/projects/CSC249ADSE15_CNDA/$USER/scratch - /lus/gecko/projects/CSC249ADSE15_CNDA/inputdata - /lus/gecko/projects/CSC249ADSE15_CNDA/inputdata/atm/datm7 + /lus/flare/projects/CSC249ADSE15_CNDA/$USER/scratch + /lus/flare/projects/CSC249ADSE15_CNDA/inputdata + /lus/flare/projects/CSC249ADSE15_CNDA/inputdata/atm/datm7 $CIME_OUTPUT_ROOT/archive/$CASE - /lus/gecko/projects/CSC249ADSE15_CNDA/baselines/$COMPILER - /lus/gecko/projects/CSC249ADSE15_CNDA/tools/cprnc/cprnc + /lus/flare/projects/CSC249ADSE15_CNDA/baselines/$COMPILER + /lus/flare/projects/CSC249ADSE15_CNDA/tools/cprnc/cprnc 16 e3sm_developer 4 @@ -3490,7 +3490,7 @@ 208 104 104 - 12 + 48 FALSE mpiexec @@ -3498,46 +3498,40 @@ -np {{ total_tasks }} --label -ppn {{ tasks_per_node }} - --cpu-bind $ENV{RANKS_BIND} -envall + --cpu-bind depth -envall -d $ENV{OMP_NUM_THREADS} $ENV{GPU_TILE_COMPACT} - /lus/gecko/projects/CSC249ADSE15_CNDA/modules/lmod.sh + /lus/flare/projects/CSC249ADSE15_CNDA/modules/lmod.sh /soft/sunspot_migrate/soft/packaging/lmod/lmod/init/csh /soft/sunspot_migrate/soft/packaging/lmod/lmod/init/env_modules_python.py module module /soft/sunspot_migrate/soft/packaging/lmod/lmod/libexec/lmod python - - /soft/modulefiles - /soft/restricted/CNDA/updates/modulefiles - spack-pe-gcc cmake + cmake - oneapi/eng-compiler/2023.05.15.007 + oneapi/eng-compiler/2024.04.15.002 + + + kokkos/git.7ff87a5-omp-sycl spack-pe-gcc cmake gcc/10.3.0 - - cray-pals - libfabric/1.15.2.0 - cray-libpals/1.3.2 - $CIME_OUTPUT_ROOT/$CASE/run $CIME_OUTPUT_ROOT/$CASE/bld - /lus/gecko/projects/CSC249ADSE15_CNDA/software/netcdf-c/4.9.2/oneapi.eng.2023.05.15.007 - /lus/gecko/projects/CSC249ADSE15_CNDA/software/netcdf-fortran/4.6.1/oneapi.eng.2023.05.15.007 - /lus/gecko/projects/CSC249ADSE15_CNDA/software/pnetcdf/1.12.3/oneapi.eng.2023.05.15.007 - /lus/gecko/projects/CSC249ADSE15_CNDA/software/pnetcdf/1.12.3/oneapi.eng.2023.05.15.007/lib:/lus/gecko/projects/CSC249ADSE15_CNDA/software/netcdf-fortran/4.6.1/oneapi.eng.2023.05.15.007/lib:/lus/gecko/projects/CSC249ADSE15_CNDA/software/netcdf-c/4.9.2/oneapi.eng.2023.05.15.007/lib:$ENV{LD_LIBRARY_PATH} - /lus/gecko/projects/CSC249ADSE15_CNDA/software/pnetcdf/1.12.3/oneapi.eng.2023.05.15.007/bin:/lus/gecko/projects/CSC249ADSE15_CNDA/software/netcdf-fortran/4.6.1/oneapi.eng.2023.05.15.007/bin:/lus/gecko/projects/CSC249ADSE15_CNDA/software/netcdf-c/4.9.2/oneapi.eng.2023.05.15.007/bin:$ENV{PATH} - list:0-7,104-111:8-15,112-119:16-23,120-127:24-31,128-135:32-39,136-143:40-47,144-151:52-59,156-163:60-67,164-171:68-75,172-179:76-83,180-187:84-91,188-195:92-99,196-203 + /lus/flare/projects/CSC249ADSE15_CNDA/software/netcdf-c/4.9.2/oneapi.eng.2024.04.15.002 + /lus/flare/projects/CSC249ADSE15_CNDA/software/netcdf-fortran/4.6.1/oneapi.eng.2024.04.15.002 + /lus/flare/projects/CSC249ADSE15_CNDA/software/pnetcdf/1.12.3/oneapi.eng.2024.04.15.002 + /lus/flare/projects/CSC249ADSE15_CNDA/software/pnetcdf/1.12.3/oneapi.eng.2024.04.15.002/lib:/lus/flare/projects/CSC249ADSE15_CNDA/software/netcdf-fortran/4.6.1/oneapi.eng.2024.04.15.002/lib:/lus/flare/projects/CSC249ADSE15_CNDA/software/netcdf-c/4.9.2/oneapi.eng.2024.04.15.002/lib:$ENV{LD_LIBRARY_PATH} + /lus/flare/projects/CSC249ADSE15_CNDA/software/pnetcdf/1.12.3/oneapi.eng.2024.04.15.002/bin:/lus/flare/projects/CSC249ADSE15_CNDA/software/netcdf-fortran/4.6.1/oneapi.eng.2024.04.15.002/bin:/lus/flare/projects/CSC249ADSE15_CNDA/software/netcdf-c/4.9.2/oneapi.eng.2024.04.15.002/bin:$ENV{PATH} 1 @@ -3554,6 +3548,9 @@ /soft/tools/mpi_wrapper_utils/gpu_tile_compact.sh 131072 20 + $ENV{KOKKOS_ROOT} + 1 + 0:4,1:4,2:4,3:4:4:4,5:4,6:4,7:4 0 diff --git a/components/eamxx/cmake/machine-files/aurora.cmake b/components/eamxx/cmake/machine-files/aurora.cmake new file mode 100644 index 000000000000..59157285bab7 --- /dev/null +++ b/components/eamxx/cmake/machine-files/aurora.cmake @@ -0,0 +1,14 @@ +include(${CMAKE_CURRENT_LIST_DIR}/common.cmake) +common_setup() + +include (${EKAT_MACH_FILES_PATH}/kokkos/serial.cmake) +include (${EKAT_MACH_FILES_PATH}/mpi/other.cmake) + +set(EKAT_MPIRUN_EXE "mpiexec" CACHE STRING "" FORCE) +set(EKAT_MPI_NP_FLAG "-np" CACHE STRING "" FORCE) +set(EKAT_MPI_EXTRA_ARGS "--label --cpu-bind depth -envall" CACHE STRING "") +set(EKAT_MPI_THREAD_FLAG "-d" CACHE STRING "") + +set(NETCDF_C_PATH "$ENV{NETCDF_C_PATH}") +set(NETCDF_FORTRAN_PATH "$ENV{NETCDF_FORTRAN_PATH}") +set(PNETCDF_PATH "$ENV{PNETCDF_PATH}") From fd04726e9b49f12b1b9e0e533d1cffece64151ba Mon Sep 17 00:00:00 2001 From: Xylar Asay-Davis Date: Fri, 30 Aug 2024 08:09:18 -0500 Subject: [PATCH 358/451] Remove trailing whitespace --- .../src/framework/mpas_stream_manager.F | 302 +++++++++--------- 1 file changed, 151 insertions(+), 151 deletions(-) diff --git a/components/mpas-framework/src/framework/mpas_stream_manager.F b/components/mpas-framework/src/framework/mpas_stream_manager.F index 9f9b46adae54..e8705c51a6d6 100644 --- a/components/mpas-framework/src/framework/mpas_stream_manager.F +++ b/components/mpas-framework/src/framework/mpas_stream_manager.F @@ -146,7 +146,7 @@ end subroutine seed_random if (err_local /= MPAS_STREAM_LIST_NOERR) then if (present(ierr)) ierr = MPAS_STREAM_MGR_ERROR STREAM_ERROR_WRITE('Problems while creating stream list') - return + return end if ! @@ -156,7 +156,7 @@ end subroutine seed_random if (err_local /= MPAS_STREAM_LIST_NOERR) then if (present(ierr)) ierr = MPAS_STREAM_MGR_ERROR STREAM_ERROR_WRITE('Problems while creating input alarm list') - return + return end if ! @@ -166,7 +166,7 @@ end subroutine seed_random if (err_local /= MPAS_STREAM_LIST_NOERR) then if (present(ierr)) ierr = MPAS_STREAM_MGR_ERROR STREAM_ERROR_WRITE('Problems while creating output alarm list') - return + return end if ! @@ -204,7 +204,7 @@ subroutine MPAS_stream_mgr_finalize(manager, ierr)!{{{ threadNum = mpas_threading_get_thread_num() - STREAM_DEBUG_WRITE('-- Called MPAS_stream_mgr_finalize()') + STREAM_DEBUG_WRITE('-- Called MPAS_stream_mgr_finalize()') if (present(ierr)) ierr = MPAS_STREAM_MGR_NOERR @@ -264,16 +264,16 @@ end subroutine MPAS_stream_mgr_finalize!}}} !> \author Michael Duda, Doug Jacobsen !> \date 13 June 2014 !> \details - !> Creates a new stream within the stream manager. The "direction" - !> argument may be either MPAS_STREAM_INPUT, MPAS_STREAM_OUTPUT, - !> MPAS_STREAM_INPUT_OUTPUT, or MPAS_STREAM_NONE. The "filename" argument - !> is the template of the filenames that are associated with the stream. - !> Knowing the interval between files, and - !> the filename template, a "referenceTime" argument must be provided to - !> specify the first timestamp appearing in any of the files associated with - !> the stream, thereby determining where the "file breaks" will occur between - !> timestamps. If no "referenceTime" is specified, the start time of the - !> clock associated with the stream handler will be used as the reference + !> Creates a new stream within the stream manager. The "direction" + !> argument may be either MPAS_STREAM_INPUT, MPAS_STREAM_OUTPUT, + !> MPAS_STREAM_INPUT_OUTPUT, or MPAS_STREAM_NONE. The "filename" argument + !> is the template of the filenames that are associated with the stream. + !> Knowing the interval between files, and + !> the filename template, a "referenceTime" argument must be provided to + !> specify the first timestamp appearing in any of the files associated with + !> the stream, thereby determining where the "file breaks" will occur between + !> timestamps. If no "referenceTime" is specified, the start time of the + !> clock associated with the stream handler will be used as the reference !> time. Additionally, the interval between records in the file may be !> specified using the optional "recordInterval" argument; if this argument !> is not supplied, the stream manager will assume that this interval is @@ -284,8 +284,8 @@ end subroutine MPAS_stream_mgr_finalize!}}} !> MPAS_IO_DOUBLE_PRECISION, or MPAS_IO_NATIVE_PRECISION; if this argument is !> not supplied, native precision is assumed. !> The optional argument clobberMode determines how the stream manager will - !> deal with existing files; possible options include MPAS_STREAM_CLOBBER_NEVER, - !> MPAS_STREAM_CLOBBER_APPEND, MPAS_STREAM_CLOBBER_TRUNCATE, + !> deal with existing files; possible options include MPAS_STREAM_CLOBBER_NEVER, + !> MPAS_STREAM_CLOBBER_APPEND, MPAS_STREAM_CLOBBER_TRUNCATE, !> and MPAS_STREAM_CLOBBER_OVERWRITE. The default behavior is to never modify !> existing files (MPAS_STREAM_CLOBBER_NEVER). !> The optional argument ioType specifies the I/O type to use for the @@ -398,14 +398,14 @@ subroutine MPAS_stream_mgr_create_stream(manager, streamID, direction, filename, if (present(ierr)) ierr = MPAS_STREAM_MGR_ERROR STREAM_ERROR_WRITE('Problems while creating input alarm list') deallocate(new_stream) - return + return end if call MPAS_stream_list_create(new_stream % alarmList_out, ierr=err_local) if (err_local /= MPAS_STREAM_LIST_NOERR) then if (present(ierr)) ierr = MPAS_STREAM_MGR_ERROR STREAM_ERROR_WRITE('Problems while creating output alarm list') deallocate(new_stream) - return + return end if call mpas_pool_create_pool(new_stream % att_pool) call mpas_pool_clone_pool(manager % defaultAtts, new_stream % att_pool) @@ -424,7 +424,7 @@ subroutine MPAS_stream_mgr_create_stream(manager, streamID, direction, filename, STREAM_ERROR_WRITE('Problems while adding stream to list') return end if - + manager % numStreams = manager % numStreams + 1 end if @@ -635,7 +635,7 @@ subroutine MPAS_stream_mgr_destroy_stream(manager, streamID, ierr)!{{{ deallocate(stream % stream) end if deallocate(stream) - + manager % numStreams = manager % numStreams - 1 end if @@ -649,8 +649,8 @@ end subroutine MPAS_stream_mgr_destroy_stream!}}} !> \author Michael Duda !> \date 22 August 2014 !> \details - !> Returns a pointer to the clock associated with the stream manager, - !> in which any stream alarms should be defined before being added to + !> Returns a pointer to the clock associated with the stream manager, + !> in which any stream alarms should be defined before being added to !> the stream manager via the MPAS_stream_mgr_add_alarm() routine. ! !----------------------------------------------------------------------- @@ -1072,7 +1072,7 @@ end subroutine MPAS_stream_mgr_add_stream_fields!}}} ! !----------------------------------------------------------------------- subroutine MPAS_stream_mgr_remove_field(manager, streamID, fieldName, ierr)!{{{ - + implicit none character (len=*), parameter :: sub = 'MPAS_stream_mgr_remove_field' @@ -1232,7 +1232,7 @@ subroutine MPAS_stream_mgr_add_alarm(manager, streamID, alarmID, direction, ierr ! if ( threadNum == 0 ) then if (direction == MPAS_STREAM_INPUT .or. direction == MPAS_STREAM_INPUT_OUTPUT) then - + ! If alarm is not already defined, we need to create a new alarm node nullify(new_alarm) if (.not. MPAS_stream_list_query(manager % alarms_in, alarmID, new_alarm, ierr=err_local)) then @@ -1242,10 +1242,10 @@ subroutine MPAS_stream_mgr_add_alarm(manager, streamID, alarmID, direction, ierr if (err_local /= MPAS_STREAM_LIST_NOERR) then if (present(ierr)) ierr = MPAS_STREAM_MGR_ERROR STREAM_ERROR_WRITE('Problems while creating stream list for alarm') - return + return end if nullify(new_alarm % next) - + call MPAS_stream_list_insert(manager % alarms_in, new_alarm, ierr=err_local) if (err_local /= MPAS_STREAM_LIST_NOERR) then if (present(ierr)) ierr = MPAS_STREAM_MGR_ERROR @@ -1253,7 +1253,7 @@ subroutine MPAS_stream_mgr_add_alarm(manager, streamID, alarmID, direction, ierr return end if end if - + ! Add specified stream to alarm node stream list allocate(new_xref) new_xref % name = streamID @@ -1264,7 +1264,7 @@ subroutine MPAS_stream_mgr_add_alarm(manager, streamID, alarmID, direction, ierr STREAM_ERROR_WRITE('Problems while adding stream to alarm stream list') return end if - + ! Add alarm to stream alarm list allocate(new_xref) new_xref % name = alarmID @@ -1276,9 +1276,9 @@ subroutine MPAS_stream_mgr_add_alarm(manager, streamID, alarmID, direction, ierr return end if end if - + if (direction == MPAS_STREAM_OUTPUT .or. direction == MPAS_STREAM_INPUT_OUTPUT) then - + ! If alarm is not already defined, we need to create a new alarm node nullify(new_alarm) if (.not. MPAS_stream_list_query(manager % alarms_out, alarmID, new_alarm, ierr=err_local)) then @@ -1288,10 +1288,10 @@ subroutine MPAS_stream_mgr_add_alarm(manager, streamID, alarmID, direction, ierr if (err_local /= MPAS_STREAM_LIST_NOERR) then if (present(ierr)) ierr = MPAS_STREAM_MGR_ERROR STREAM_ERROR_WRITE('Problems while creating stream list for alarm') - return + return end if nullify(new_alarm % next) - + call MPAS_stream_list_insert(manager % alarms_out, new_alarm, ierr=err_local) if (err_local /= MPAS_STREAM_LIST_NOERR) then if (present(ierr)) ierr = MPAS_STREAM_MGR_ERROR @@ -1299,7 +1299,7 @@ subroutine MPAS_stream_mgr_add_alarm(manager, streamID, alarmID, direction, ierr return end if end if - + ! Add specified stream to alarm node stream list allocate(new_xref) new_xref % name = streamID @@ -1310,7 +1310,7 @@ subroutine MPAS_stream_mgr_add_alarm(manager, streamID, alarmID, direction, ierr STREAM_ERROR_WRITE('Problems while adding stream to alarm stream list') return end if - + ! Add alarm to stream alarm list allocate(new_xref) new_xref % name = alarmID @@ -1399,7 +1399,7 @@ subroutine MPAS_stream_mgr_remove_alarm(manager, streamID, alarmID, direction, i STREAM_ERROR_WRITE('Output alarm '//trim(alarmID)//' does not exist on stream '//trim(streamID)) end if return - end if + end if if (.not. associated(streamNode)) then if (present(ierr)) ierr = MPAS_STREAM_MGR_ERROR STREAM_ERROR_WRITE('Alarm '//trim(alarmID)//' does not have stream '//trim(streamID)//' on its stream list.') @@ -1433,7 +1433,7 @@ end subroutine MPAS_stream_mgr_remove_alarm!}}} !> Resets all alarms used by the stream manager. If the optional argument !> 'streamID' is provided, only alarms associated with streams that match !> the 'streamID' regular expression will be - !> reset. If the optional 'direction' argument is provided, only alarms + !> reset. If the optional 'direction' argument is provided, only alarms !> associated with that direction will be reset. ! !----------------------------------------------------------------------- @@ -1453,7 +1453,7 @@ subroutine MPAS_stream_mgr_reset_alarms(manager, streamID, direction, ierr)!{{{ logical :: resetAlarms threadNum = mpas_threading_get_thread_num() - + if (present(streamID)) then STREAM_DEBUG_WRITE('-- Called MPAS_stream_mgr_reset_alarms() for stream ' // trim(streamID)) else @@ -1486,7 +1486,7 @@ subroutine MPAS_stream_mgr_reset_alarms(manager, streamID, direction, ierr)!{{{ alarm_cursor => stream % alarmList_in % head do while (associated(alarm_cursor)) if (mpas_is_alarm_ringing(manager % streamClock, alarm_cursor % name, ierr=local_ierr)) then - call mpas_reset_clock_alarm(manager % streamClock, alarm_cursor % name, ierr=local_ierr) + call mpas_reset_clock_alarm(manager % streamClock, alarm_cursor % name, ierr=local_ierr) end if alarm_cursor => alarm_cursor % next end do @@ -1496,7 +1496,7 @@ subroutine MPAS_stream_mgr_reset_alarms(manager, streamID, direction, ierr)!{{{ alarm_cursor => stream % alarmList_out % head do while (associated(alarm_cursor)) if (mpas_is_alarm_ringing(manager % streamClock, alarm_cursor % name, ierr=local_ierr)) then - call mpas_reset_clock_alarm(manager % streamClock, alarm_cursor % name, ierr=local_ierr) + call mpas_reset_clock_alarm(manager % streamClock, alarm_cursor % name, ierr=local_ierr) end if alarm_cursor => alarm_cursor % next end do @@ -1514,7 +1514,7 @@ subroutine MPAS_stream_mgr_reset_alarms(manager, streamID, direction, ierr)!{{{ alarm_cursor => manager % alarms_in % head do while (associated(alarm_cursor)) if (mpas_is_alarm_ringing(manager % streamClock, alarm_cursor % name, ierr=local_ierr)) then - call mpas_reset_clock_alarm(manager % streamClock, alarm_cursor % name, ierr=local_ierr) + call mpas_reset_clock_alarm(manager % streamClock, alarm_cursor % name, ierr=local_ierr) end if alarm_cursor => alarm_cursor % next end do @@ -1525,7 +1525,7 @@ subroutine MPAS_stream_mgr_reset_alarms(manager, streamID, direction, ierr)!{{{ alarm_cursor => manager % alarms_out % head do while (associated(alarm_cursor)) if (mpas_is_alarm_ringing(manager % streamClock, alarm_cursor % name, ierr=local_ierr)) then - call mpas_reset_clock_alarm(manager % streamClock, alarm_cursor % name, ierr=local_ierr) + call mpas_reset_clock_alarm(manager % streamClock, alarm_cursor % name, ierr=local_ierr) end if alarm_cursor => alarm_cursor % next end do @@ -1543,10 +1543,10 @@ end subroutine MPAS_stream_mgr_reset_alarms!}}} !> \author Michael Duda !> \date 30 September 2014 !> \details - !> Tests whether any I/O alarms in a stream manager are ringing; if the optional - !> 'streamID' argument is given, only alarms for that stream are tested; if - !> the optional argument 'direction' is given, only alarms for the specified - !> direction are tested. If any of the tested alarms is ringing, the function + !> Tests whether any I/O alarms in a stream manager are ringing; if the optional + !> 'streamID' argument is given, only alarms for that stream are tested; if + !> the optional argument 'direction' is given, only alarms for the specified + !> direction are tested. If any of the tested alarms is ringing, the function !> returns .true.; otherwise, it returns .false.. !> Note: This function doesn't support streamID regular expressions ! @@ -1566,7 +1566,7 @@ logical function MPAS_stream_mgr_ringing_alarms(manager, streamID, direction, ie integer :: local_ierr, threadNum threadNum = mpas_threading_get_thread_num() - + STREAM_DEBUG_WRITE('-- Called MPAS_stream_mgr_ringing_alarms()') MPAS_stream_mgr_ringing_alarms = .false. @@ -1784,7 +1784,7 @@ subroutine MPAS_stream_mgr_set_property_int(manager, streamID, propertyName, pro if ( .not. setProperties ) then STREAM_ERROR_WRITE('No stream matching '//trim(streamID)//' exists in call to MPAS_stream_mgr_set_property().') if (present(ierr)) ierr = MPAS_STREAM_MGR_ERROR - return + return end if @@ -1848,7 +1848,7 @@ subroutine MPAS_stream_mgr_set_property_char(manager, streamID, propertyName, pr call mpas_set_time(stream_cursor % referenceTime, dateTimeString=propertyValue) case (MPAS_STREAM_PROPERTY_RECORD_INTV) - + ! The interval between records may not have been allocated if the optional recordInterval ! argument was not provided when the stream was created if (.not. associated(stream_cursor % recordInterval)) then @@ -1869,7 +1869,7 @@ subroutine MPAS_stream_mgr_set_property_char(manager, streamID, propertyName, pr if ( .not. setProperties ) then STREAM_ERROR_WRITE('No stream matching '//trim(streamID)//' exists in call to MPAS_stream_mgr_set_property().') if (present(ierr)) ierr = MPAS_STREAM_MGR_ERROR - return + return end if @@ -1945,7 +1945,7 @@ subroutine MPAS_stream_mgr_set_property_logical(manager, streamID, propertyName, if ( .not. setProperties ) then STREAM_ERROR_WRITE('No stream matching '//trim(streamID)//' exists in call to MPAS_stream_mgr_set_property().') if (present(ierr)) ierr = MPAS_STREAM_MGR_ERROR - return + return end if @@ -1990,7 +1990,7 @@ subroutine MPAS_stream_mgr_get_property_int(manager, streamID, propertyName, pro if (.not. MPAS_stream_list_query(manager % streams, streamID, stream_cursor, ierr=err_local)) then STREAM_ERROR_WRITE('Stream '//trim(streamID)//' does not exist in call to MPAS_stream_mgr_get_property().') if (present(ierr)) ierr = MPAS_STREAM_MGR_ERROR - return + return end if ! @@ -2057,7 +2057,7 @@ subroutine MPAS_stream_mgr_get_property_char(manager, streamID, propertyName, pr if (.not. MPAS_stream_list_query(manager % streams, streamID, stream_cursor, ierr=err_local)) then STREAM_ERROR_WRITE('Stream '//trim(streamID)//' does not exist in call to MPAS_stream_mgr_get_property().') if (present(ierr)) ierr = MPAS_STREAM_MGR_ERROR - return + return end if ! @@ -2081,9 +2081,9 @@ subroutine MPAS_stream_mgr_get_property_char(manager, streamID, propertyName, pr ! assume that the interval is the shortest interval between alarms on the stream; since ! recordInterval is only used for reading, use the input alarm list in this check. if (.not. associated(stream_cursor % recordInterval)) then - + ! - ! If no direction is specified, return the read interval, since this was the only historic + ! If no direction is specified, return the read interval, since this was the only historic ! use of the recordInterval for a stream. ! if (present(direction)) then @@ -2164,7 +2164,7 @@ subroutine MPAS_stream_mgr_get_property_logical(manager, streamID, propertyName, if (.not. MPAS_stream_list_query(manager % streams, streamID, stream_cursor, ierr=err_local)) then STREAM_ERROR_WRITE('Stream '//trim(streamID)//' does not exist in call to MPAS_stream_mgr_get_property().') if (present(ierr)) ierr = MPAS_STREAM_MGR_ERROR - return + return end if ! @@ -2245,14 +2245,14 @@ subroutine MPAS_stream_mgr_add_pkg(manager, streamID, packageName, ierr)!{{{ ! ! Add package to the packages pool for the stream ! - call mpas_pool_add_package(stream_cursor % pkg_pool, packageName, package) + call mpas_pool_add_package(stream_cursor % pkg_pool, packageName, package) end do if ( .not. addedPackages ) then STREAM_ERROR_WRITE('No stream matching '//trim(streamID)//' exists in call to MPAS_stream_mgr_add_pkg().') if (present(ierr)) ierr = MPAS_STREAM_MGR_ERROR - return + return end if @@ -2310,7 +2310,7 @@ subroutine MPAS_stream_mgr_remove_pkg(manager, streamID, packageName, ierr)!{{{ if ( .not. removedPackage ) then STREAM_ERROR_WRITE('No stream matching '//trim(streamID)//' exists in call to MPAS_stream_mgr_remove_pkg().') if (present(ierr)) ierr = MPAS_STREAM_MGR_ERROR - return + return end if @@ -2374,7 +2374,7 @@ subroutine MPAS_stream_mgr_add_att_int(manager, attName, attVal, streamID, ierr) if (mpas_pool_config_type(att_pool, attName) /= MPAS_POOL_FATAL) then STREAM_ERROR_WRITE('Attribute '//trim(attName)//' in stream '//trim(stream_cursor % name)//' is not of type integer.') if (present(ierr)) ierr = MPAS_STREAM_MGR_ERROR - return + return end if call mpas_pool_add_config(att_pool, attName, attVal) else @@ -2385,7 +2385,7 @@ subroutine MPAS_stream_mgr_add_att_int(manager, attName, attVal, streamID, ierr) if ( .not. addedAttribute ) then STREAM_ERROR_WRITE('No stream matching '//trim(streamID)//' exists in call to MPAS_stream_mgr_add_att().') if (present(ierr)) ierr = MPAS_STREAM_MGR_ERROR - return + return end if else @@ -2403,7 +2403,7 @@ subroutine MPAS_stream_mgr_add_att_int(manager, attName, attVal, streamID, ierr) if (mpas_pool_config_type(att_pool, attName) /= MPAS_POOL_FATAL) then STREAM_ERROR_WRITE('Attribute '//trim(attName)//' in streamManager is not of type integer.') if (present(ierr)) ierr = MPAS_STREAM_MGR_ERROR - return + return end if call mpas_pool_add_config(att_pool, attName, attVal) else @@ -2473,7 +2473,7 @@ subroutine MPAS_stream_mgr_add_att_real(manager, attName, attVal, streamID, ierr if (mpas_pool_config_type(att_pool, attName) /= MPAS_POOL_FATAL) then STREAM_ERROR_WRITE('Attribute '//trim(attName)//' in stream '//trim(stream_cursor % name)//' is not of type real.') if (present(ierr)) ierr = MPAS_STREAM_MGR_ERROR - return + return end if call mpas_pool_add_config(att_pool, attName, attVal) else @@ -2484,7 +2484,7 @@ subroutine MPAS_stream_mgr_add_att_real(manager, attName, attVal, streamID, ierr if ( .not. addedAttribute ) then STREAM_ERROR_WRITE('No stream matching '//trim(streamID)//' exists in call to MPAS_stream_mgr_add_att().') if (present(ierr)) ierr = MPAS_STREAM_MGR_ERROR - return + return end if else @@ -2503,7 +2503,7 @@ subroutine MPAS_stream_mgr_add_att_real(manager, attName, attVal, streamID, ierr if (mpas_pool_config_type(att_pool, attName) /= MPAS_POOL_FATAL) then STREAM_ERROR_WRITE('Attribute '//trim(attName)//' in streamManager is not of type real.') if (present(ierr)) ierr = MPAS_STREAM_MGR_ERROR - return + return end if call mpas_pool_add_config(att_pool, attName, attVal) else @@ -2573,7 +2573,7 @@ subroutine MPAS_stream_mgr_add_att_char(manager, attName, attVal, streamID, ierr if (mpas_pool_config_type(att_pool, attName) /= MPAS_POOL_FATAL) then STREAM_ERROR_WRITE('Attribute '//trim(attName)//' in stream '//trim(stream_cursor % name)//' is not of type character.') if (present(ierr)) ierr = MPAS_STREAM_MGR_ERROR - return + return end if call mpas_pool_add_config(att_pool, attName, attVal) else @@ -2584,7 +2584,7 @@ subroutine MPAS_stream_mgr_add_att_char(manager, attName, attVal, streamID, ierr if ( .not. addedAttribute ) then STREAM_ERROR_WRITE('No stream matching '//trim(streamID)//' exists in call to MPAS_stream_mgr_add_att().') if (present(ierr)) ierr = MPAS_STREAM_MGR_ERROR - return + return end if else @@ -2603,7 +2603,7 @@ subroutine MPAS_stream_mgr_add_att_char(manager, attName, attVal, streamID, ierr if (mpas_pool_config_type(att_pool, attName) /= MPAS_POOL_FATAL) then STREAM_ERROR_WRITE('Attribute '//trim(attName)//' in streamManager is not of type character.') if (present(ierr)) ierr = MPAS_STREAM_MGR_ERROR - return + return end if call mpas_pool_add_config(att_pool, attName, attVal) else @@ -2673,7 +2673,7 @@ subroutine MPAS_stream_mgr_add_att_logical(manager, attName, attVal, streamID, i if (mpas_pool_config_type(att_pool, attName) /= MPAS_POOL_FATAL) then STREAM_ERROR_WRITE('Attribute '//trim(attName)//' in stream '//trim(stream_cursor % name)//' is not of type logical.') if (present(ierr)) ierr = MPAS_STREAM_MGR_ERROR - return + return end if call mpas_pool_add_config(att_pool, attName, attVal) else @@ -2684,7 +2684,7 @@ subroutine MPAS_stream_mgr_add_att_logical(manager, attName, attVal, streamID, i if ( .not. addedAttribute ) then STREAM_ERROR_WRITE('No stream matching '//trim(streamID)//' exists in call to MPAS_stream_mgr_add_att().') if (present(ierr)) ierr = MPAS_STREAM_MGR_ERROR - return + return end if else @@ -2703,7 +2703,7 @@ subroutine MPAS_stream_mgr_add_att_logical(manager, attName, attVal, streamID, i if (mpas_pool_config_type(att_pool, attName) /= MPAS_POOL_FATAL) then STREAM_ERROR_WRITE('Attribute '//trim(attName)//' in streamManger is not of type logical.') if (present(ierr)) ierr = MPAS_STREAM_MGR_ERROR - return + return end if call mpas_pool_add_config(att_pool, attName, attVal) else @@ -2727,11 +2727,11 @@ end subroutine MPAS_stream_mgr_add_att_logical!}}} !> stream is only written if any of its alarms are ringing. !> The "timeLevel" argument optionally specifies, for fields with multiple !> time levels, the time level from which fields should be written. - !> The "mgLevel" argument optionally specifies, for fields that exist for + !> The "mgLevel" argument optionally specifies, for fields that exist for !> multiple grid levels, the grid level from which fields should be written. - !> The "forceWriteNow" argument optionally specifies that all streams -- or - !> the stream specified by the "streamID" argument -- should be written by - !> the call regardless of whether any alarms associated with the stream(s) + !> The "forceWriteNow" argument optionally specifies that all streams -- or + !> the stream specified by the "streamID" argument -- should be written by + !> the call regardless of whether any alarms associated with the stream(s) !> are ringing. The "writeTime" argument optionally specifies a time stamp !> to be used for expanding a filename template, when it is not passed in, !> the current time of the streamManager's clock is used to expand filename @@ -2824,7 +2824,7 @@ subroutine MPAS_stream_mgr_write(manager, streamID, timeLevel, mgLevel, forceWri if ( .not. wroteStreams ) then STREAM_ERROR_WRITE('No output stream matching '//trim(streamID)//' exists in call to MPAS_stream_mgr_write().') if (present(ierr)) ierr = MPAS_STREAM_MGR_ERROR - return + return end if else nullify(stream_cursor) @@ -2872,11 +2872,11 @@ end subroutine MPAS_stream_mgr_write !}}} !> stream is only written if any of its alarms are ringing. !> The "timeLevel" argument optionally specifies, for fields with multiple !> time levels, the time level from which fields should be written. - !> The "mgLevel" argument optionally specifies, for fields that exist for + !> The "mgLevel" argument optionally specifies, for fields that exist for !> multiple grid levels, the grid level from which fields should be written. - !> The "forceWriteNow" argument optionally specifies that all streams -- or - !> the stream specified by the "streamID" argument -- should be written by - !> the call regardless of whether any alarms associated with the stream(s) + !> The "forceWriteNow" argument optionally specifies that all streams -- or + !> the stream specified by the "streamID" argument -- should be written by + !> the call regardless of whether any alarms associated with the stream(s) !> are ringing. The "writeTime" argument optionally specifies a time stamp !> to be used for expanding a filename template, when it is not passed in, !> the current time of the streamManager's clock is used to expand filename @@ -3006,7 +3006,7 @@ subroutine MPAS_stream_mgr_block_write(manager, writeBlock, streamID, timeLevel, if ( .not. wroteStreams ) then STREAM_ERROR_WRITE('No output stream matching '//trim(streamID)//' exists in call to MPAS_stream_mgr_block_write().') if (present(ierr)) ierr = MPAS_STREAM_MGR_ERROR - return + return end if else nullify(stream_cursor) @@ -3048,7 +3048,7 @@ subroutine MPAS_stream_mgr_block_write(manager, writeBlock, streamID, timeLevel, call mpas_dmpar_finalize(debugContext % dminfo) deallocate(debugContext % dminfo) - deallocate(debugContext) + deallocate(debugContext) end if call mpas_threading_barrier() @@ -3180,7 +3180,7 @@ subroutine write_stream(manager, stream, blockID, timeLevel, mgLevel, forceWrite ! Based on clobber_mode, determine if it matters if the file exists or not. if ( stream % clobber_mode == MPAS_STREAM_CLOBBER_OVERWRITE .or. stream % clobber_mode == MPAS_STREAM_CLOBBER_APPEND ) then STREAM_DEBUG_WRITE(' -- Cobber mode is overwrite or append...') - + ! Check if the file exists if (manager % ioContext % dminfo % my_proc_id == IO_NODE) then inquire(file=trim(stream % filename), exist=recordSeek) @@ -3217,12 +3217,12 @@ subroutine write_stream(manager, stream, blockID, timeLevel, mgLevel, forceWrite if ( recordSeek ) then STREAM_DEBUG_WRITE(' -- File exists on disk: ' // trim(stream % filename)) call mpas_get_time(writeTime, dateTimeString=now_string) - + ! Look for exact record (in the case of overwriting) ! This also gets the number of records in the file. stream % nRecords = MPAS_seekStream(stream % stream, now_string, MPAS_STREAM_EXACT_TIME, actualWhen, maxRecords, local_ierr) STREAM_DEBUG_WRITE(' -- Seeked record is: $i with current records equal to $i and an error of $i' COMMA intArgs=(/stream % nRecords COMMA maxRecords COMMA local_ierr/)) - + if ( stream % nRecords == 0 ) then ! If we didn't find an exact time, set record to point to the end of the file. ! This might result in non-monotonic timestamps in the output file. @@ -3266,7 +3266,7 @@ subroutine write_stream(manager, stream, blockID, timeLevel, mgLevel, forceWrite ! Based on clobber_mode, determine if it matters if the file exists or not. if ( stream % clobber_mode == MPAS_STREAM_CLOBBER_OVERWRITE .or. stream % clobber_mode == MPAS_STREAM_CLOBBER_APPEND ) then STREAM_DEBUG_WRITE(' -- Cobber mode is overwrite or append...') - + ! Check if the file exists if (manager % ioContext % dminfo % my_proc_id == IO_NODE) then inquire(file=trim(stream % filename), exist=recordSeek) @@ -3305,12 +3305,12 @@ subroutine write_stream(manager, stream, blockID, timeLevel, mgLevel, forceWrite if ( recordSeek ) then STREAM_DEBUG_WRITE(' -- File exists on disk: ' // trim(stream % filename)) call mpas_get_time(writeTime, dateTimeString=now_string) - + ! Look for exact record (in the case of overwriting) ! This also gets the number of records in the file. stream % nRecords = MPAS_seekStream(stream % stream, now_string, MPAS_STREAM_EXACT_TIME, actualWhen, maxRecords, local_ierr) STREAM_DEBUG_WRITE(' -- Seeked record is: $i with current records equal to $i and an error of $i' COMMA intArgs=(/stream % nRecords COMMA maxRecords COMMA local_ierr/)) - + if ( stream % nRecords == 0 ) then ! If we didn't find an exact time, set record to point to the end of the file. ! This might result in non-monotonic timestamps in the output file. @@ -3330,12 +3330,12 @@ subroutine write_stream(manager, stream, blockID, timeLevel, mgLevel, forceWrite stream % nRecords = stream % nRecords + 1 if ( stream % clobber_mode == MPAS_STREAM_CLOBBER_OVERWRITE .or. stream % clobber_mode == MPAS_STREAM_CLOBBER_APPEND ) then call mpas_get_time(writeTime, dateTimeString=now_string) - + ! Look for exact record (in the case of overwriting) ! This also gets the number of records in the file. tempRecord = MPAS_seekStream(stream % stream, now_string, MPAS_STREAM_EXACT_TIME, actualWhen, maxRecords, local_ierr) STREAM_DEBUG_WRITE(' -- Seeked record is: $i with current records equal to $i and an error of $i' COMMA intArgs=(/tempRecord COMMA maxRecords COMMA local_ierr/)) - + if ( tempRecord /= 0 .and. stream % nRecords < maxRecords ) then ! If we found an exact result ! This might result in non-monotonic timestamps in the output file. @@ -3375,9 +3375,9 @@ subroutine write_stream(manager, stream, blockID, timeLevel, mgLevel, forceWrite call prewrite_reindex(manager % allFields, stream % field_pool) end if - ! + ! ! Write the stream - ! + ! STREAM_DEBUG_WRITE(' -- Writing stream ' // trim(stream % name)) call MPAS_writeStream(stream % stream, stream % nRecords, & useMissingValMask, ierr=local_ierr) @@ -3433,16 +3433,16 @@ end subroutine write_stream !}}} !> is only read if any of its alarms are ringing. !> The "timeLevel" argument optionally specifies, for fields with multiple !> time levels, the time level into which fields should be read. - !> The "mgLevel" argument optionally specifies, for fields that exist for + !> The "mgLevel" argument optionally specifies, for fields that exist for !> multiple grid levels, the grid level into which fields should be read. !> The "when" argument optionally specifies the timestamp from which fields !> are to be read. !> The "whence" argument optionally specifies the method for determining !> the timestamp to read from in case an exact match is not found for the !> read timestamp, which is the current time unless the optional "when" - !> argument is given; possible values are MPAS_STREAM_EXACT_TIME, - !> MPAS_STREAM_NEAREST, MPAS_STREAM_LATEST_BEFORE, - !> MPAS_STREAM_LATEST_STRICTLY_BEFORE, MPAS_STREAM_EARLIEST_AFTER, or + !> argument is given; possible values are MPAS_STREAM_EXACT_TIME, + !> MPAS_STREAM_NEAREST, MPAS_STREAM_LATEST_BEFORE, + !> MPAS_STREAM_LATEST_STRICTLY_BEFORE, MPAS_STREAM_EARLIEST_AFTER, or !> MPAS_STREAM_EARLIEST_STRICTLY_AFTER. !> The optional output argument "saveActualWhen" will save the actual time read !> from a stream in case an exact match for the "when" time is not found, @@ -3484,7 +3484,7 @@ subroutine MPAS_stream_mgr_read(manager, streamID, timeLevel, mgLevel, rightNow, integer :: local_whence integer :: local_ierr integer :: temp_ierr - type (MPAS_Time_type) :: now_time + type (MPAS_Time_type) :: now_time character (len=StrKIND) :: actualWhen_local logical :: local_saveActualWhen logical :: local_readInputOutputStreams @@ -3555,7 +3555,7 @@ subroutine MPAS_stream_mgr_read(manager, streamID, timeLevel, mgLevel, rightNow, nullify(stream_cursor) do while (MPAS_stream_list_query(manager % streams, streamID, stream_cursor, ierr=ierr)) STREAM_DEBUG_WRITE('-- Handling read of stream '//trim(stream_cursor % name)) - + ! Verify that the stream is an input stream if (local_readInputOutputStreams) then if (stream_cursor % direction == MPAS_STREAM_INPUT .or. stream_cursor % direction == MPAS_STREAM_INPUT_OUTPUT) then @@ -3590,7 +3590,7 @@ subroutine MPAS_stream_mgr_read(manager, streamID, timeLevel, mgLevel, rightNow, STREAM_ERROR_WRITE(' strictly INPUT direction were requested by this call.') endif if (present(ierr)) ierr = MPAS_STREAM_MGR_ERROR - return + return end if else ! try to read any stream of input direction nullify(stream_cursor) @@ -3631,7 +3631,7 @@ subroutine MPAS_stream_mgr_read(manager, streamID, timeLevel, mgLevel, rightNow, local_ierr = MPAS_STREAM_MGR_ERROR end if end if - + stream_cursor => stream_cursor % next end do end if @@ -3747,7 +3747,7 @@ subroutine read_stream(manager, stream, timeLevel, mgLevel, forceReadNow, when, if ( stream % filename_interval /= 'none' ) then call mpas_set_time(now_time, dateTimeString=when, ierr=local_ierr) call mpas_set_timeInterval(filename_interval, timeString=stream % filename_interval) - + call mpas_build_stream_filename(stream % referenceTime, now_time, filename_interval, stream % filename_template, blockID_local, temp_filename, ierr=local_ierr) else call mpas_expand_string(when, blockID_local, stream % filename_template, temp_filename) @@ -3916,7 +3916,7 @@ subroutine read_stream(manager, stream, timeLevel, mgLevel, forceReadNow, when, call mpas_get_time(filenameTime, dateTimeString=test_when) call mpas_set_timeInterval(filename_interval, timeString=stream % filename_interval) - + call mpas_build_stream_filename(stream % referenceTime, filenameTime, filename_interval, stream % filename_template, blockID_local, test_filename, ierr=local_ierr) STREAM_DEBUG_WRITE(' --- Retesting filename is ' // trim(test_filename)) @@ -4031,9 +4031,9 @@ subroutine read_stream(manager, stream, timeLevel, mgLevel, forceReadNow, when, stream % timeLevel = timeLevel end if - ! + ! ! Read the stream - ! + ! call MPAS_readStream(stream % stream, stream % nRecords, ierr=local_ierr) if (local_ierr /= MPAS_STREAM_NOERR) then ierr = MPAS_STREAM_MGR_ERROR @@ -4068,13 +4068,13 @@ end subroutine read_stream !}}} !----------------------------------------------------------------------- ! routine MPAS_stream_mesg ! - !> \brief Write an error message (if the level requires it) to + !> \brief Write an error message (if the level requires it) to !> \author Michael Duda, Doug Jacobsen !> \date 07/16/2014 - !> \details Using the input error level, + !> \details Using the input error level, !----------------------------------------------------------------------- subroutine MPAS_stream_mesg(level, mesg)!{{{ - + use mpas_dmpar implicit none @@ -4171,7 +4171,7 @@ end subroutine mpas_get_stream_filename !}}} !> \brief Construct the filename that contains a specific time in a stream !> \author Michael Duda, Doug Jacobsen !> \date 21 August 2014 - !> \details + !> \details !> Given a filename template and the information necessary to determine the time !> in the stream that matches a time available in any of the files associated with !> the stream, returns a specific filename that should contain that time. @@ -4182,7 +4182,7 @@ end subroutine mpas_get_stream_filename !}}} !> !> This is a low level subroutine to complement the !> mpas_get_stream_Filename routine - !> + !> !> Return error codes: !> 0 no error !----------------------------------------------------------------------- @@ -4229,7 +4229,7 @@ subroutine mpas_build_stream_filename(ref_time, when, filename_interval, filenam call mpas_get_timeInterval(intv, timeString=temp_string) STREAM_DEBUG_WRITE(' ** intv is: ' // trim(temp_string)) - call mpas_interval_division(ref_time, intv, filename_interval, nrecs, rem) + call mpas_interval_division(ref_time, intv, filename_interval, nrecs, rem) ! STREAM_DEBUG_WRITE(' ** Divisions are: $i' COMMA intArgs=(/nrecs/)) @@ -4260,7 +4260,7 @@ end subroutine mpas_build_stream_filename !}}} !> \brief This is a utility routine to build a stream type from a pool representing a stream. !> \author Michael Duda, Doug Jacobsen !> \date 07/23/2014 - !> \details + !> \details !> This routine will take as input a pool representing a stream. !> It will then generate a stream type based on this pool, and return that. !----------------------------------------------------------------------- @@ -4465,8 +4465,8 @@ end subroutine build_stream !}}} !> \brief Updates the time level for fields in a stream !> \author Michael Duda, Doug Jacobsen !> \date 07/23/2014 - !> \details - !> For an existing stream, updates the time levels for all fields in + !> \details + !> For an existing stream, updates the time levels for all fields in !> the stream so that subsequent reads/writes of the stream will read !> from / write to the specified time level. !----------------------------------------------------------------------- @@ -4581,7 +4581,7 @@ end subroutine update_stream !}}} !> \brief Checks whether a stream has any active packages (or none at all) !> \author Michael Duda !> \date 23 September 2014 - !> \details + !> \details !> This function determines whether a stream has any active packages !> associated with it. If the stream has at least one active package, !> or no packages at all, the function returns true; else, if all packages @@ -4630,32 +4630,32 @@ end function stream_active_pkg_check !}}} !> \brief Parses a semi-colon-separated list of package names, indicating whether any are active !> \author Michael Duda !> \date 19 March 2015 - !> \details - !> This function determines whether any of the named strings in + !> \details + !> This function determines whether any of the named strings in !> the semi-colon-separated list provided in the 'packages' argument are - !> active. + !> active. !> If any of the packages does not exist in the package pool, the optional - !> argument ierr is set to a non-zero value; otherwise, if all packages exist, + !> argument ierr is set to a non-zero value; otherwise, if all packages exist, !> ierr will be set to zero upon return. ! !----------------------------------------------------------------------- logical function parse_package_list(package_pool, packages, ierr) result(active) - + implicit none - + type (mpas_pool_type), intent(in) :: package_pool character (len=*), intent(in) :: packages integer, intent(out), optional :: ierr - + integer :: i, j, slen integer :: err_level logical, pointer :: pkg_val - - + + if (present(ierr)) ierr = 0 - + slen = len_trim(packages) - + ! ! No packages @@ -4664,7 +4664,7 @@ logical function parse_package_list(package_pool, packages, ierr) result(active) active = .true. return end if - + active = .false. err_level = mpas_pool_get_error_level() @@ -4870,8 +4870,8 @@ end subroutine exch_all_halos !}}} !> \brief Determines whether a dimension represents a decomposed dimension or not !> \author Michael Duda !> \date 24 September 2014 - !> \details - !> This function determines whether the name of the input argument is + !> \details + !> This function determines whether the name of the input argument is !> a decompsed dimension or not. Currently in MPAS, the only decomposed !> dimensions are: !> nCells @@ -4906,8 +4906,8 @@ end function is_decomposed_dim !}}} !> \brief Reindex connectivity fields from local to global index space. !> \author Doug Jacobsen, Michael Duda !> \date 24 September 2014 - !> \details - !> For any connectivity fields contained in the stream to be written, + !> \details + !> For any connectivity fields contained in the stream to be written, !> whose fields include those in the streamFields pool, save the locally !> indexed fields in module variables *_save, and allocate new arrays for !> the fields, which are set to contain global indices. @@ -5203,12 +5203,12 @@ end subroutine prewrite_reindex !}}} !> \brief Reindex connectivity fields from global to local index space. !> \author Doug Jacobsen, Michael Duda !> \date 24 September 2014 - !> \details - !> For any connectivity fields contained in the stream to be written, + !> \details + !> For any connectivity fields contained in the stream to be written, !> whose fields include those in the streamFields pool, restore the locally !> indexed fields from module variables *_save. !> This routine should be called immediately after a write of a stream. - !> + !> !> NB: Even if the write of a stream fails, it is important to stil call !> this routine to reset the connectivity fields to contain local indices. ! @@ -5247,35 +5247,35 @@ subroutine postwrite_reindex(allFields, streamFields) !{{{ if (associated(cellsOnCell_save)) then cellsOnCell_ptr => cellsOnCell_save call mpas_pool_get_field(allFields, 'cellsOnCell', cellsOnCell) - end if + end if if (associated(edgesOnCell_save)) then edgesOnCell_ptr => edgesOnCell_save call mpas_pool_get_field(allFields, 'edgesOnCell', edgesOnCell) - end if + end if if (associated(verticesOnCell_save)) then verticesOnCell_ptr => verticesOnCell_save call mpas_pool_get_field(allFields, 'verticesOnCell', verticesOnCell) - end if + end if if (associated(cellsOnEdge_save)) then cellsOnEdge_ptr => cellsOnEdge_save call mpas_pool_get_field(allFields, 'cellsOnEdge', cellsOnEdge) - end if + end if if (associated(verticesOnEdge_save)) then verticesOnEdge_ptr => verticesOnEdge_save call mpas_pool_get_field(allFields, 'verticesOnEdge', verticesOnEdge) - end if + end if if (associated(edgesOnEdge_save)) then edgesOnEdge_ptr => edgesOnEdge_save call mpas_pool_get_field(allFields, 'edgesOnEdge', edgesOnEdge) - end if + end if if (associated(cellsOnVertex_save)) then cellsOnVertex_ptr => cellsOnVertex_save call mpas_pool_get_field(allFields, 'cellsOnVertex', cellsOnVertex) - end if + end if if (associated(edgesOnVertex_save)) then edgesOnVertex_ptr => edgesOnVertex_save call mpas_pool_get_field(allFields, 'edgesOnVertex', edgesOnVertex) - end if + end if ! ! Reset indices for connectivity arrays from global to local index space @@ -5378,8 +5378,8 @@ end subroutine postwrite_reindex !}}} !> \brief Reindex connectivity fields from global to local index space. !> \author Doug Jacobsen, Michael Duda !> \date 24 September 2014 - !> \details - !> For any connectivity fields contained in the stream that was read, + !> \details + !> For any connectivity fields contained in the stream that was read, !> whose fields include those in the streamFields pool, convert the !> globally indexed connectivity fields in the stream to local index space. !> This routine should be called immediately after a read of a stream. @@ -5606,13 +5606,13 @@ end subroutine postread_reindex !}}} !> \author Doug Jacobsen, Michael Duda !> \date 03/03/2015 !> \details - !> If the optional 'streamID' argument is provided, this routine resets - !> the iterator within a stream manager so that streams may subsequently - !> be iterated over using the MPAS_stream_mgr_get_next_stream function. + !> If the optional 'streamID' argument is provided, this routine resets + !> the iterator within a stream manager so that streams may subsequently + !> be iterated over using the MPAS_stream_mgr_get_next_stream function. !> !> If an optional stream name is provided via the 'streamID' argument, this - !> routine will reset the iterator for fields within the specified stream, - !> which may subsequently iterated over using the + !> routine will reset the iterator for fields within the specified stream, + !> which may subsequently iterated over using the !> MPAS_stream_mgr_get_next_field() routine. !> !> NOTE: This routine does not support regular expressions for StreamID @@ -5772,7 +5772,7 @@ end function MPAS_stream_mgr_get_next_stream !}}} !> the stream manager. !> !> This function returns .TRUE. if the stream contains another field, - !> whether active or not, in which case the output argument fieldName + !> whether active or not, in which case the output argument fieldName !> provides the name of this field, and .FALSE. otherwise. If a field name !> is returned, the optional logical argument isActive may be used to !> determine whether the field is currently active in the stream. @@ -5828,7 +5828,7 @@ logical function MPAS_stream_mgr_get_next_field(manager, streamID, fieldName, is else isActive = .true. end if - + call mpas_pool_set_error_level(err_level) end if @@ -5864,7 +5864,7 @@ logical function MPAS_stream_mgr_stream_exists(manager, streamID) result(validSt return end function MPAS_stream_mgr_stream_exists!}}} - + end module mpas_stream_manager @@ -5967,7 +5967,7 @@ subroutine stream_mgr_create_stream_c(manager_c, streamID_c, direction_c, filena end if STREAM_DEBUG_WRITE('Creating stream from c...') - + ! ! For immutable streams, the stream should have already been defined at this point, and ! all we need to do is update the stream's filename template; From 67556b4249d9a78299eb6f4c98870b352012f811 Mon Sep 17 00:00:00 2001 From: James Foucar Date: Fri, 30 Aug 2024 10:25:08 -0600 Subject: [PATCH 359/451] Fix append feature --- cime | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cime b/cime index 3dfad8399b80..52787427846e 160000 --- a/cime +++ b/cime @@ -1 +1 @@ -Subproject commit 3dfad8399b803d724365c559c5b84e5546049e0c +Subproject commit 52787427846eec58038ab59664fd9c2706f23513 From 36bb7c01ad1577d84ebbe18808bed6495400913c Mon Sep 17 00:00:00 2001 From: Elizabeth Hunke Date: Fri, 30 Aug 2024 11:51:59 -0500 Subject: [PATCH 360/451] clean up debugging code and comments --- components/mpas-seaice/src/shared/mpas_seaice_icepack.F | 9 --------- 1 file changed, 9 deletions(-) diff --git a/components/mpas-seaice/src/shared/mpas_seaice_icepack.F b/components/mpas-seaice/src/shared/mpas_seaice_icepack.F index c6386f2c1aa4..36899b4b10d7 100644 --- a/components/mpas-seaice/src/shared/mpas_seaice_icepack.F +++ b/components/mpas-seaice/src/shared/mpas_seaice_icepack.F @@ -10656,15 +10656,6 @@ subroutine init_icepack_package_configs(domain) call seaice_icepack_write_warnings(icepack_warnings_aborted()) -!note that icepack_recompute_constants, called from icepck_init_parameters above, recomputes Lfresh -! - make Lfresh optional for E3SM? - -! tcraig, this will write out icepack parameters to fort.101, need to uncomment 3 lines - if (mpas_log_info % taskID == 0) then - call icepack_write_parameters(101) - endif -! call seaice_icepack_write_warnings(icepack_warnings_aborted()) - call mpas_log_write(" ----- compare values after icepack init -----") ! Lfresh is derived in Icepack, not sent in from driver From 86eb592e18d8ebb59960500959e1862cc8c2b6a3 Mon Sep 17 00:00:00 2001 From: Xylar Asay-Davis Date: Fri, 30 Aug 2024 08:09:41 -0500 Subject: [PATCH 361/451] Warn on failure to clobber record in append mode We do not want this to be an error (even a non-fatal one). --- .../mpas-framework/src/framework/mpas_stream_manager.F | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/components/mpas-framework/src/framework/mpas_stream_manager.F b/components/mpas-framework/src/framework/mpas_stream_manager.F index e8705c51a6d6..fd393908a7de 100644 --- a/components/mpas-framework/src/framework/mpas_stream_manager.F +++ b/components/mpas-framework/src/framework/mpas_stream_manager.F @@ -3398,10 +3398,9 @@ subroutine write_stream(manager, stream, blockID, timeLevel, mgLevel, forceWrite ! write(err_string,'(a,i4,a)') 'Writing to stream '''//trim(stream % name)//''' would overwrite record ', & stream % nRecords, ' in file '''//trim(stream % filename)//''',' - STREAM_ERROR_WRITE(trim(err_string)) + STREAM_WARNING_WRITE(trim(err_string)) write(err_string,'(a)') ' but clobber_mode is set to ''append''.' - STREAM_ERROR_WRITE(trim(err_string)) - ierr = MPAS_STREAM_MGR_ERR_CLOBBER_REC + STREAM_WARNING_WRITE(trim(err_string)) else ierr = MPAS_STREAM_MGR_ERROR end if From 6cbb5b0fc2f46b9d3c56e020ed80288a16ec4d23 Mon Sep 17 00:00:00 2001 From: "Andrew M. Bradley" Date: Fri, 30 Aug 2024 16:48:23 -0500 Subject: [PATCH 362/451] Homme: Fix planar-mode pgN get_latlon routines. Add is_planar block to gfr_f_get_(corner_)latlon. Add unit test for these routines. Clean up and add to some other unit tests. --- components/homme/src/share/gllfvremap_mod.F90 | 97 ++++++++++++++----- 1 file changed, 75 insertions(+), 22 deletions(-) diff --git a/components/homme/src/share/gllfvremap_mod.F90 b/components/homme/src/share/gllfvremap_mod.F90 index e0e0fa6c4daa..e8013df217b1 100644 --- a/components/homme/src/share/gllfvremap_mod.F90 +++ b/components/homme/src/share/gllfvremap_mod.F90 @@ -2088,9 +2088,14 @@ subroutine gfr_f_get_latlon(ie, i, j, lat, lon) type (spherical_polar_t) :: p - p = change_coordinates(gfr%center_f(i,j,ie)) - lat = p%lat - lon = p%lon + if (gfr%is_planar) then + lon = gfr%center_f(i,j,ie)%x + lat = gfr%center_f(i,j,ie)%y + else + p = change_coordinates(gfr%center_f(i,j,ie)) + lat = p%lat + lon = p%lon + end if end subroutine gfr_f_get_latlon subroutine gfr_f_get_corner_latlon(ie, i, j, c, lat, lon) @@ -2103,9 +2108,14 @@ subroutine gfr_f_get_corner_latlon(ie, i, j, c, lat, lon) type (spherical_polar_t) :: p - p = change_coordinates(gfr%corners_f(c,i,j,ie)) - lat = p%lat - lon = p%lon + if (gfr%is_planar) then + lon = gfr%corners_f(c,i,j,ie)%x + lat = gfr%corners_f(c,i,j,ie)%y + else + p = change_coordinates(gfr%corners_f(c,i,j,ie)) + lat = p%lat + lon = p%lon + end if end subroutine gfr_f_get_corner_latlon subroutine gfr_f_get_cartesian3d(ie, i, j, p) @@ -2318,6 +2328,7 @@ subroutine set_ps_Q(elem, nets, nete, timeidx, qidx, nlev) ! Make up a test function for use in unit tests. use coordinate_systems_mod, only: cartesian3D_t, change_coordinates + use physical_constants, only: dd_pi, Lx, Ly type (element_t), intent(inout) :: elem(:) integer, intent(in) :: nets, nete, timeidx, qidx, nlev @@ -2329,7 +2340,13 @@ subroutine set_ps_Q(elem, nets, nete, timeidx, qidx, nlev) do ie = nets, nete do j = 1,np do i = 1,np - p = change_coordinates(elem(ie)%spherep(i,j)) + if (gfr%is_planar) then + p%x = elem(ie)%spherep(i,j)%lon*2*dd_pi/Lx + p%y = elem(ie)%spherep(i,j)%lat*2*dd_pi/Ly + p%z = 0 + else + p = change_coordinates(elem(ie)%spherep(i,j)) + end if elem(ie)%state%ps_v(i,j,timeidx) = & 1.0d3*(1 + 0.05*sin(2*p%x+0.5)*sin(p%y+1.5)*sin(3*p%z+2.5)) q = 0.5*(1 + sin(3*p%x)*sin(3*p%y)*sin(4*p%z)) @@ -2609,7 +2626,8 @@ function check(par, dom_mt, gfr, elem, verbose) result(nerr) logical, intent(in) :: verbose real(kind=real_kind) :: a, b, rd, x, y, f0(np*np), f1(np*np), g(np,np), & - wf(np*np), wg(np,np), qmin, qmax, qmin1, qmax1 + wf(np*np), wg(np,np), qmin, qmax, qmin1, qmax1, lat, lon, latext(2), & + lonext(2), tol integer :: nf, nf2, ie, i, j, k, iremap, info, ilimit, it real(kind=real_kind), allocatable :: Qdp_fv(:,:), ps_v_fv(:,:), & qmins(:,:,:), qmaxs(:,:,:) @@ -2669,6 +2687,31 @@ function check(par, dom_mt, gfr, elem, verbose) result(nerr) nerr = nerr + 1 write(iulog,*) 'gfr> Dinv', ie, rd end if + if (gfr%is_planar) then + lonext(1) = minval(elem(ie)%spherep(:,:)%lon) + lonext(2) = maxval(elem(ie)%spherep(:,:)%lon) + latext(1) = minval(elem(ie)%spherep(:,:)%lat) + latext(2) = maxval(elem(ie)%spherep(:,:)%lat) + tol = max(lonext(2) - lonext(1), latext(2) - latext(1))*1.e4*eps + do i = 1, nf + do j = 1, nf + call gfr_f_get_latlon(ie, i, j, lat, lon) + if ( lon < lonext(1) .or. lon > lonext(2) .or. & + lat < latext(1) .or. lat > latext(2)) then + write(iulog,*) 'gfr> planar latlon ctr', ie, latext, lonext, lat, lon + nerr = nerr + 1 + end if + do k = 1, 4 + call gfr_f_get_corner_latlon(ie, i, j, k, lat, lon) + if ( lon < lonext(1) - tol .or. lon > lonext(2) + tol .or. & + lat < latext(1) - tol .or. lat > latext(2) + tol) then + write(iulog,*) 'gfr> planar latlon crn', ie, latext, lonext, lat, lon + nerr = nerr + 1 + end if + end do + end do + end do + end if ! Check that FV -> GLL -> FV recovers the original FV values exactly ! (with no DSS and no limiter). @@ -2839,8 +2882,8 @@ function test_sphere2ref() result(nerr) use kinds, only: iulog type (cartesian3D_t) :: corners(4), sphere - real (real_kind) :: refin(2), refout(2), err - integer :: i, j, n, nerr + real (real_kind) :: refin(2), refout(2), err, tol + integer :: i, j, n, trial, nerr nerr = 0 @@ -2854,18 +2897,28 @@ function test_sphere2ref() result(nerr) do i = 1,n refin(1) = -1 + (1.0_real_kind/(n-1))*(i-1) do j = 1,n - refin(2) = -1 + (1.0_real_kind/(n-1))*(j-1) - call ref2sphere(corners, refin(1), refin(2), sphere) - call sphere2ref(corners, sphere, refout(1), refout(2)) - err = abs(refin(1) - refout(1)) + abs(refin(2) - refout(2)) - if (err > 15*eps .or. & - maxval(abs(refout)) > 1 + 5*eps .or. & - any(refout /= refout)) then - write(iulog,*) refin(1), refin(2) - write(iulog,*) refout(1), refout(2) - write(iulog,*) err - nerr = nerr + 1 - end if + do trial = 1, 2 + refin(2) = -1 + (1.0_real_kind/(n-1))*(j-1) + call ref2sphere(corners, refin(1), refin(2), sphere) + if (trial == 2) then + sphere%x = 0.9d0*sphere%x + sphere%y = 0.9d0*sphere%y + sphere%z = 0.9d0*sphere%z + end if + call sphere2ref(corners, sphere, refout(1), refout(2)) + err = abs(refin(1) - refout(1)) + abs(refin(2) - refout(2)) + tol = 15*eps + if (trial == 2) tol = 1e-6 + if (err > tol .or. & + maxval(abs(refout)) > 1 + 5*eps .or. & + any(refout /= refout)) then + write(iulog,*) 'gfr> test_sphere2ref trial', trial + write(iulog,*) refin(1), refin(2) + write(iulog,*) refout(1), refout(2) + write(iulog,*) err + nerr = nerr + 1 + end if + end do end do end do if (nerr /= 0) write(iulog,*) 'test_sphere2ref FAILED' From 4b5cf35b729a221770acd1134c720a7f8dff8410 Mon Sep 17 00:00:00 2001 From: Azamat Mametjanov Date: Sat, 31 Aug 2024 02:18:41 +0000 Subject: [PATCH 363/451] Remove "--cpu-bind depth" in Aurora mpiexec --- cime_config/machines/config_machines.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cime_config/machines/config_machines.xml b/cime_config/machines/config_machines.xml index f1bed254da48..e97c93957a8e 100644 --- a/cime_config/machines/config_machines.xml +++ b/cime_config/machines/config_machines.xml @@ -3498,7 +3498,7 @@ -np {{ total_tasks }} --label -ppn {{ tasks_per_node }} - --cpu-bind depth -envall + -envall -d $ENV{OMP_NUM_THREADS} $ENV{GPU_TILE_COMPACT} From 15d891a3b5ae59726c3f84b9306d508e31c204b7 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 2 Sep 2024 10:23:29 +0000 Subject: [PATCH 364/451] Bump actions/setup-python from 5.1.1 to 5.2.0 Bumps [actions/setup-python](https://github.com/actions/setup-python) from 5.1.1 to 5.2.0. - [Release notes](https://github.com/actions/setup-python/releases) - [Commits](https://github.com/actions/setup-python/compare/v5.1.1...v5.2.0) --- updated-dependencies: - dependency-name: actions/setup-python dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- .github/workflows/e3sm-gh-pages.yml | 2 +- .github/workflows/eamxx-gh-pages.yml | 2 +- .github/workflows/eamxx_default_files.yml | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/e3sm-gh-pages.yml b/.github/workflows/e3sm-gh-pages.yml index 9ea25ae1864e..709fecc623ac 100644 --- a/.github/workflows/e3sm-gh-pages.yml +++ b/.github/workflows/e3sm-gh-pages.yml @@ -31,7 +31,7 @@ jobs: - name: Show action trigger run: echo "= The job was automatically triggered by a ${{github.event_name}} event on repo ${{github.event.repository.name}}." - name: Set up Python 3.10 - uses: actions/setup-python@v5.1.1 + uses: actions/setup-python@v5.2.0 with: python-version: "3.10" - name: Install python deps diff --git a/.github/workflows/eamxx-gh-pages.yml b/.github/workflows/eamxx-gh-pages.yml index e6fb53ba29f5..7c9da3264d68 100644 --- a/.github/workflows/eamxx-gh-pages.yml +++ b/.github/workflows/eamxx-gh-pages.yml @@ -54,7 +54,7 @@ jobs: echo "= The job was automatically triggered by a ${{github.event_name}} event." - name: Set up Python 3.11 - uses: actions/setup-python@v5.1.1 + uses: actions/setup-python@v5.2.0 with: python-version: "3.11" diff --git a/.github/workflows/eamxx_default_files.yml b/.github/workflows/eamxx_default_files.yml index e0a8e19f9c01..fa84f9f96f01 100644 --- a/.github/workflows/eamxx_default_files.yml +++ b/.github/workflows/eamxx_default_files.yml @@ -21,7 +21,7 @@ jobs: show-progress: false submodules: false - name: Set up Python 3.11 - uses: actions/setup-python@v5.1.1 + uses: actions/setup-python@v5.2.0 with: python-version: "3.11" - name: Run unit tests From 76c1a9084fa954e3c360a3cbc8a2830ef1d115c1 Mon Sep 17 00:00:00 2001 From: Naser Mahfouz Date: Mon, 2 Sep 2024 13:38:21 -0400 Subject: [PATCH 365/451] rename singularity2 to ghci-oci --- .github/workflows/e3sm-gh-ci-cime-tests.yml | 16 ++++++++-------- .github/workflows/e3sm-gh-ci-w-cime-tests.yml | 16 ++++++++-------- cime_config/machines/config_machines.xml | 6 +++--- 3 files changed, 19 insertions(+), 19 deletions(-) diff --git a/.github/workflows/e3sm-gh-ci-cime-tests.yml b/.github/workflows/e3sm-gh-ci-cime-tests.yml index b90ed2f01198..adaadd68160f 100644 --- a/.github/workflows/e3sm-gh-ci-cime-tests.yml +++ b/.github/workflows/e3sm-gh-ci-cime-tests.yml @@ -27,14 +27,14 @@ jobs: fail-fast: false matrix: test: - - SMS_D_P4.ne4pg2_oQU480.F2010.singularity2_gnu - - SMS_P4.ne4pg2_oQU480.F2010.singularity2_gnu - - REP_P4.ne4pg2_oQU480.F2010.singularity2_gnu - - ERS_P4.ne4pg2_oQU480.F2010.singularity2_gnu - - ERS_P4.ne4pg2_oQU480.F2010.singularity2_gnu.eam-wcprod_F2010 - - ERP_P4.ne4pg2_oQU480.F2010.singularity2_gnu - - PET_P4.ne4pg2_oQU480.F2010.singularity2_gnu - - PEM_P4.ne4pg2_oQU480.F2010.singularity2_gnu + - SMS_D_P4.ne4pg2_oQU480.F2010.ghci-oci_gnu + - SMS_P4.ne4pg2_oQU480.F2010.ghci-oci_gnu + - REP_P4.ne4pg2_oQU480.F2010.ghci-oci_gnu + - ERS_P4.ne4pg2_oQU480.F2010.ghci-oci_gnu + - ERS_P4.ne4pg2_oQU480.F2010.ghci-oci_gnu.eam-wcprod_F2010 + - ERP_P4.ne4pg2_oQU480.F2010.ghci-oci_gnu + - PET_P4.ne4pg2_oQU480.F2010.ghci-oci_gnu + - PEM_P4.ne4pg2_oQU480.F2010.ghci-oci_gnu container: image: ghcr.io/mahf708/e3sm-imgs:v0.0.9 diff --git a/.github/workflows/e3sm-gh-ci-w-cime-tests.yml b/.github/workflows/e3sm-gh-ci-w-cime-tests.yml index c24604d4ad0e..a3ab08ddf696 100644 --- a/.github/workflows/e3sm-gh-ci-w-cime-tests.yml +++ b/.github/workflows/e3sm-gh-ci-w-cime-tests.yml @@ -19,14 +19,14 @@ jobs: fail-fast: false matrix: test: - - SMS_D_P8.ne4pg2_oQU480.WCYCL2010NS.singularity2_gnu - - SMS_P8.ne4pg2_oQU480.WCYCL2010NS.singularity2_gnu - - REP_P8.ne4pg2_oQU480.WCYCL2010NS.singularity2_gnu - - ERS_P8.ne4pg2_oQU480.WCYCL2010NS.singularity2_gnu - - ERS_P8.ne4pg2_oQU480.WCYCL2010NS.singularity2_gnu.allactive-wcprod_1850 - - ERP_P8.ne4pg2_oQU480.WCYCL2010NS.singularity2_gnu - - PET_P8.ne4pg2_oQU480.WCYCL2010NS.singularity2_gnu - - PEM_P8.ne4pg2_oQU480.WCYCL2010NS.singularity2_gnu + - SMS_D_P8.ne4pg2_oQU480.WCYCL2010NS.ghci-oci_gnu + - SMS_P8.ne4pg2_oQU480.WCYCL2010NS.ghci-oci_gnu + - REP_P8.ne4pg2_oQU480.WCYCL2010NS.ghci-oci_gnu + - ERS_P8.ne4pg2_oQU480.WCYCL2010NS.ghci-oci_gnu + - ERS_P8.ne4pg2_oQU480.WCYCL2010NS.ghci-oci_gnu.allactive-wcprod_1850 + - ERP_P8.ne4pg2_oQU480.WCYCL2010NS.ghci-oci_gnu + - PET_P8.ne4pg2_oQU480.WCYCL2010NS.ghci-oci_gnu + - PEM_P8.ne4pg2_oQU480.WCYCL2010NS.ghci-oci_gnu container: image: ghcr.io/mahf708/e3sm-imgs:v0.0.9 diff --git a/cime_config/machines/config_machines.xml b/cime_config/machines/config_machines.xml index 6cd9d585a25b..7f20b1b512b6 100644 --- a/cime_config/machines/config_machines.xml +++ b/cime_config/machines/config_machines.xml @@ -1712,9 +1712,9 @@ - - Singularity container 2.0 - singularity2 + + OCI-based container 2.0 + ghci-oci LINUX gnu mpich From 0e3c779739a04d91c283a5730b9de10f5b56acc3 Mon Sep 17 00:00:00 2001 From: Naser Mahfouz Date: Mon, 2 Sep 2024 13:40:48 -0400 Subject: [PATCH 366/451] reduce gh ci and ci-w burden --- .github/workflows/e3sm-gh-ci-cime-tests.yml | 10 +++------- .github/workflows/e3sm-gh-ci-w-cime-tests.yml | 10 +++------- 2 files changed, 6 insertions(+), 14 deletions(-) diff --git a/.github/workflows/e3sm-gh-ci-cime-tests.yml b/.github/workflows/e3sm-gh-ci-cime-tests.yml index adaadd68160f..0af45e95d4ed 100644 --- a/.github/workflows/e3sm-gh-ci-cime-tests.yml +++ b/.github/workflows/e3sm-gh-ci-cime-tests.yml @@ -5,6 +5,7 @@ on: branches: [ master ] paths: # first, yes to these + - '.github/workflows/e3sm-gh-ci-cime-tests.yml' - 'cime_config/**' - 'components/eam/**' - 'components/elm/**' @@ -26,15 +27,10 @@ jobs: strategy: fail-fast: false matrix: - test: + test: + # format test like usual (TYPE_PX.GRID.COMPSET.MACHINE_COMPILER) - SMS_D_P4.ne4pg2_oQU480.F2010.ghci-oci_gnu - - SMS_P4.ne4pg2_oQU480.F2010.ghci-oci_gnu - - REP_P4.ne4pg2_oQU480.F2010.ghci-oci_gnu - - ERS_P4.ne4pg2_oQU480.F2010.ghci-oci_gnu - ERS_P4.ne4pg2_oQU480.F2010.ghci-oci_gnu.eam-wcprod_F2010 - - ERP_P4.ne4pg2_oQU480.F2010.ghci-oci_gnu - - PET_P4.ne4pg2_oQU480.F2010.ghci-oci_gnu - - PEM_P4.ne4pg2_oQU480.F2010.ghci-oci_gnu container: image: ghcr.io/mahf708/e3sm-imgs:v0.0.9 diff --git a/.github/workflows/e3sm-gh-ci-w-cime-tests.yml b/.github/workflows/e3sm-gh-ci-w-cime-tests.yml index a3ab08ddf696..b481119a85a5 100644 --- a/.github/workflows/e3sm-gh-ci-w-cime-tests.yml +++ b/.github/workflows/e3sm-gh-ci-w-cime-tests.yml @@ -18,15 +18,11 @@ jobs: strategy: fail-fast: false matrix: - test: + test: + # format test like usual (TYPE_PX.GRID.COMPSET.MACHINE_COMPILER) - SMS_D_P8.ne4pg2_oQU480.WCYCL2010NS.ghci-oci_gnu - - SMS_P8.ne4pg2_oQU480.WCYCL2010NS.ghci-oci_gnu - - REP_P8.ne4pg2_oQU480.WCYCL2010NS.ghci-oci_gnu - - ERS_P8.ne4pg2_oQU480.WCYCL2010NS.ghci-oci_gnu - ERS_P8.ne4pg2_oQU480.WCYCL2010NS.ghci-oci_gnu.allactive-wcprod_1850 - - ERP_P8.ne4pg2_oQU480.WCYCL2010NS.ghci-oci_gnu - - PET_P8.ne4pg2_oQU480.WCYCL2010NS.ghci-oci_gnu - - PEM_P8.ne4pg2_oQU480.WCYCL2010NS.ghci-oci_gnu + container: image: ghcr.io/mahf708/e3sm-imgs:v0.0.9 From 22e94c1140a73b1f49bcaa0b98def0e6c890c56c Mon Sep 17 00:00:00 2001 From: Naser Mahfouz Date: Mon, 2 Sep 2024 13:42:53 -0400 Subject: [PATCH 367/451] add a screamv1 SMS test --- .github/workflows/e3sm-gh-ci-cime-tests.yml | 1 + components/eamxx/cmake/machine-files/ghci-oci.cmake | 2 ++ 2 files changed, 3 insertions(+) create mode 100644 components/eamxx/cmake/machine-files/ghci-oci.cmake diff --git a/.github/workflows/e3sm-gh-ci-cime-tests.yml b/.github/workflows/e3sm-gh-ci-cime-tests.yml index 0af45e95d4ed..ed35f82a2a7f 100644 --- a/.github/workflows/e3sm-gh-ci-cime-tests.yml +++ b/.github/workflows/e3sm-gh-ci-cime-tests.yml @@ -31,6 +31,7 @@ jobs: # format test like usual (TYPE_PX.GRID.COMPSET.MACHINE_COMPILER) - SMS_D_P4.ne4pg2_oQU480.F2010.ghci-oci_gnu - ERS_P4.ne4pg2_oQU480.F2010.ghci-oci_gnu.eam-wcprod_F2010 + - SMS_P4.ne4pg2_oQU480.F2010-SCREAMv1.ghci-oci_gnu container: image: ghcr.io/mahf708/e3sm-imgs:v0.0.9 diff --git a/components/eamxx/cmake/machine-files/ghci-oci.cmake b/components/eamxx/cmake/machine-files/ghci-oci.cmake new file mode 100644 index 000000000000..86a2fb1d5302 --- /dev/null +++ b/components/eamxx/cmake/machine-files/ghci-oci.cmake @@ -0,0 +1,2 @@ +include(${CMAKE_CURRENT_LIST_DIR}/common.cmake) +common_setup() From 7d06bcfa09ecd6b0931034f6f8cd6fcb59eb796d Mon Sep 17 00:00:00 2001 From: mahf708 Date: Mon, 2 Sep 2024 18:01:40 -0500 Subject: [PATCH 368/451] add screamv1 prod testmod --- .../scream/v1prod/shell_commands | 97 +++++++++++++++++++ .../testmods_dirs/scream/v1prod/user_nl_cpl | 1 + .../testmods_dirs/scream/v1prod/user_nl_elm | 14 +++ ...cream_output.decadal.1dailyAVG_native.yaml | 16 +++ ...cream_output.decadal.1dailyMAX_native.yaml | 17 ++++ ...cream_output.decadal.1dailyMIN_native.yaml | 16 +++ ...scream_output.decadal.1hourlyINST_arm.yaml | 40 ++++++++ ...eam_output.decadal.1hourlyINST_native.yaml | 19 ++++ ...ream_output.decadal.3hourlyAVG_coarse.yaml | 69 +++++++++++++ ...eam_output.decadal.3hourlyINST_coarse.yaml | 68 +++++++++++++ ...ream_output.decadal.6hourlyAVG_coarse.yaml | 48 +++++++++ ...eam_output.decadal.6hourlyINST_coarse.yaml | 39 ++++++++ ...eam_output.decadal.6hourlyINST_native.yaml | 28 ++++++ ...scream_output.decadal.dailyAVG_coarse.yaml | 95 ++++++++++++++++++ 14 files changed, 567 insertions(+) create mode 100644 components/eamxx/cime_config/testdefs/testmods_dirs/scream/v1prod/shell_commands create mode 100644 components/eamxx/cime_config/testdefs/testmods_dirs/scream/v1prod/user_nl_cpl create mode 100644 components/eamxx/cime_config/testdefs/testmods_dirs/scream/v1prod/user_nl_elm create mode 100644 components/eamxx/cime_config/testdefs/testmods_dirs/scream/v1prod/yaml_outs/scream_output.decadal.1dailyAVG_native.yaml create mode 100644 components/eamxx/cime_config/testdefs/testmods_dirs/scream/v1prod/yaml_outs/scream_output.decadal.1dailyMAX_native.yaml create mode 100644 components/eamxx/cime_config/testdefs/testmods_dirs/scream/v1prod/yaml_outs/scream_output.decadal.1dailyMIN_native.yaml create mode 100644 components/eamxx/cime_config/testdefs/testmods_dirs/scream/v1prod/yaml_outs/scream_output.decadal.1hourlyINST_arm.yaml create mode 100644 components/eamxx/cime_config/testdefs/testmods_dirs/scream/v1prod/yaml_outs/scream_output.decadal.1hourlyINST_native.yaml create mode 100644 components/eamxx/cime_config/testdefs/testmods_dirs/scream/v1prod/yaml_outs/scream_output.decadal.3hourlyAVG_coarse.yaml create mode 100644 components/eamxx/cime_config/testdefs/testmods_dirs/scream/v1prod/yaml_outs/scream_output.decadal.3hourlyINST_coarse.yaml create mode 100644 components/eamxx/cime_config/testdefs/testmods_dirs/scream/v1prod/yaml_outs/scream_output.decadal.6hourlyAVG_coarse.yaml create mode 100644 components/eamxx/cime_config/testdefs/testmods_dirs/scream/v1prod/yaml_outs/scream_output.decadal.6hourlyINST_coarse.yaml create mode 100644 components/eamxx/cime_config/testdefs/testmods_dirs/scream/v1prod/yaml_outs/scream_output.decadal.6hourlyINST_native.yaml create mode 100644 components/eamxx/cime_config/testdefs/testmods_dirs/scream/v1prod/yaml_outs/scream_output.decadal.dailyAVG_coarse.yaml diff --git a/components/eamxx/cime_config/testdefs/testmods_dirs/scream/v1prod/shell_commands b/components/eamxx/cime_config/testdefs/testmods_dirs/scream/v1prod/shell_commands new file mode 100644 index 000000000000..435556401a2b --- /dev/null +++ b/components/eamxx/cime_config/testdefs/testmods_dirs/scream/v1prod/shell_commands @@ -0,0 +1,97 @@ +#!/bin/bash + +cime_root=$(./xmlquery --value CIMEROOT) +input_data_dir=$(./xmlquery --value DIN_LOC_ROOT) +atmchange=$cime_root/../components/eamxx/scripts/atmchange + +# Change run length +./xmlchange RUN_STARTDATE="1994-10-01" + +# Turn on budget reporting +./xmlchange BUDGETS=TRUE + +# For big data +./xmlchange PIO_NETCDF_FORMAT="64bit_data" +./xmlchange PIO_TYPENAME=pnetcdf #adios #,PIO_TYPENAME_ATM=adios +./xmlchange PIO_REARRANGER=1 # use PIO_REARRANGER=3, for ADIOS; PIO_REARRANGER=1 for pnetcdf + +# Turn on cosp and set frequency +$atmchange -b physics::atm_procs_list="mac_aero_mic,rrtmgp,cosp" +$atmchange -b physics::cosp::cosp_frequency_units="hours" +$atmchange -b physics::cosp::cosp_frequency=1 + +# Need to explicitly turn on computing tendencies +$atmchange -b physics::mac_aero_mic::shoc::compute_tendencies=T_mid,qv +$atmchange -b physics::mac_aero_mic::p3::compute_tendencies=T_mid,qv +$atmchange -b physics::rrtmgp::compute_tendencies=T_mid +$atmchange -b homme::compute_tendencies=T_mid,qv + +# Set temperature cut off in dycore threshold to 180K +$atmchange -b vtheta_thresh=180 + +# Change lambda_high +$atmchange -b lambda_high=0.08 + +# use GHG levels more appropriate for sim +# Average from 19940101 - 20150101 +$atmchange -b co2vmr=377.2e-6 +$atmchange -b ch4vmr=1786.6e-9 +$atmchange -b n2ovmr=318.6e-9 +$atmchange -b orbital_year=-9999 +# use CO2 the same in land model +./xmlchange CCSM_CO2_PPMV=377.2 + +# determine grid and set remap files +atm_grid=$(./xmlquery --value ATM_GRID) +if [[ "${atm_grid}" = "ne30np4.pg2" ]]; then + hmapfile="${input_data_dir}/atm/scream/maps/map_ne30pg2_to_ne4pg2_20231201.nc" + armmapfile="${input_data_dir}/atm/scream/maps/map_ne30pg2_to_DecadalSites_c20240130.nc" + # Run with bugfixed SPA file + $atmchange -b spa_data_file="${input_data_dir}/atm/scream/init/spa_v3.LR.F2010.2011-2025.c_20240405.nc" +elif [[ "${atm_grid}" = "ne4np4.pg2" ]]; then + hmapfile="${input_data_dir}/atm/scream/maps/map_ne4pg2_to_ne2pg2_c20240902.nc" + echo "Note: arm remap only works for ne30pg2 atm grids for now" + armmapfile="not-supported-yet" + # Keep default SPA file + # ... (do nothing) +else + echo "Note: horiz/arm remaps only work for ne30pg2 and ne4pg2 atm grids for now" + hmapfile="not-supported-yet" + armmapfile="not-supported-yet" +fi + +# set the output yaml files +output_yaml_files=$(find ${cime_root}/../components/eamxx/cime_config/testdefs/testmods_dirs/scream/v1prod/yaml_outs/ -maxdepth 1 -type f) +for file in ${output_yaml_files[@]}; do + # if the word "coarse" is in the file name, do nothing + if [[ "${file}" == *"_coarse.yaml" && "${hmapfile}" == "not-supported-yet" ]]; then + continue + elif [[ "${file}" == *"_arm.yaml" && "${armmapfile}" == "not-supported-yet" ]]; then + continue + else + # TODO: add remap file replacement for different grids + cp -v ${file} ./ + if [ "${file}" == "${output_yaml_files[0]}" ]; then + # First file, reset output list + $atmchange -b output_yaml_files="./$(basename ${file})" + else + # Append to output list + $atmchange -b output_yaml_files+="./$(basename ${file})" + fi + # Replace remap files + sed -i "s|horiz_remap_file:.*_to_ne30.*|horiz_remap_file: ${hmapfile}|" ./$(basename ${file}) + sed -i "s|horiz_remap_file:.*_to_DecadalSites.*|horiz_remap_file: ${armmapfile}|" ./$(basename ${file}) + fi +done + +# TODO: +# the only thing remaining is to set the SST data, but for some reason, this is proving difficult +# because it is not super important, leave it commented out for now, until a better solution can be found +# ... also, not sure if the below are specific to a given ocn/sea-ice grid? + +# # Point to new SST forcing +# ./xmlchange --file env_run.xml --id SSTICE_DATA_FILENAME --val "${input_data_dir}/atm/cam/sst/sst_ostia_3600x7200_19940930_20151231_c20240125.nc" +# ./xmlchange --file env_run.xml --id SSTICE_GRID_FILENAME --val "${input_data_dir}/ocn/docn7/domain.ocn.3600x7200.230522.nc" +# ./xmlchange --file env_run.xml --id SSTICE_YEAR_ALIGN --val 1994 +# ./xmlchange --file env_run.xml --id SSTICE_YEAR_START --val 1994 +# ./xmlchange --file env_run.xml --id SSTICE_YEAR_END --val 2015 diff --git a/components/eamxx/cime_config/testdefs/testmods_dirs/scream/v1prod/user_nl_cpl b/components/eamxx/cime_config/testdefs/testmods_dirs/scream/v1prod/user_nl_cpl new file mode 100644 index 000000000000..3e3a05807216 --- /dev/null +++ b/components/eamxx/cime_config/testdefs/testmods_dirs/scream/v1prod/user_nl_cpl @@ -0,0 +1 @@ +ocn_surface_flux_scheme = 2 diff --git a/components/eamxx/cime_config/testdefs/testmods_dirs/scream/v1prod/user_nl_elm b/components/eamxx/cime_config/testdefs/testmods_dirs/scream/v1prod/user_nl_elm new file mode 100644 index 000000000000..93b7ec9e277d --- /dev/null +++ b/components/eamxx/cime_config/testdefs/testmods_dirs/scream/v1prod/user_nl_elm @@ -0,0 +1,14 @@ +! Override consistency checks since we know our surface data is inconsistent +check_finidat_fsurdat_consistency = .false. +check_finidat_year_consistency = .false. +check_finidat_pct_consistency = .false. +check_dynpft_consistency = .false. + +hist_dov2xy = .true.,.true. +hist_mfilt = 1,1 +hist_nhtfrq = -24,-24 +hist_avgflag_pertape = 'A','A' +hist_fincl1 = 'FIRE', 'FPSN', 'QDRAI', 'QRUNOFF', 'ZWT', 'FSAT', 'H2OSOI', 'EFLX_LH_TOT', + 'QVEGT', 'QVEGE', 'FSH', 'ALBD', 'ALBI', 'TBOT', 'QBOT', 'RAIN', 'SNOW', + 'FSDS', 'FSDSND', 'FSDSNI', 'FSDSVD', 'FSDSVI', 'FLDS' +hist_fincl2 = 'H2OSNO','SOILWATER_10CM','TG' diff --git a/components/eamxx/cime_config/testdefs/testmods_dirs/scream/v1prod/yaml_outs/scream_output.decadal.1dailyAVG_native.yaml b/components/eamxx/cime_config/testdefs/testmods_dirs/scream/v1prod/yaml_outs/scream_output.decadal.1dailyAVG_native.yaml new file mode 100644 index 000000000000..4e1239b5c33c --- /dev/null +++ b/components/eamxx/cime_config/testdefs/testmods_dirs/scream/v1prod/yaml_outs/scream_output.decadal.1dailyAVG_native.yaml @@ -0,0 +1,16 @@ +%YAML 1.1 +--- +filename_prefix: scream_output.decadal.1dailyAVG_native.h +iotype: pnetcdf +Averaging Type: Average +Max Snapshots Per File: 1 +Fields: + Physics PG2: + Field Names: + - snow_depth_land +output_control: + Frequency: 1 + frequency_units: ndays + MPI Ranks in Filename: false +Restart: + force_new_file: true diff --git a/components/eamxx/cime_config/testdefs/testmods_dirs/scream/v1prod/yaml_outs/scream_output.decadal.1dailyMAX_native.yaml b/components/eamxx/cime_config/testdefs/testmods_dirs/scream/v1prod/yaml_outs/scream_output.decadal.1dailyMAX_native.yaml new file mode 100644 index 000000000000..a7d10efe0707 --- /dev/null +++ b/components/eamxx/cime_config/testdefs/testmods_dirs/scream/v1prod/yaml_outs/scream_output.decadal.1dailyMAX_native.yaml @@ -0,0 +1,17 @@ +%YAML 1.1 +--- +filename_prefix: scream_output.decadal.1dailyMAX_native.h +iotype: pnetcdf +Averaging Type: Max +Max Snapshots Per File: 1 +Fields: + Physics PG2: + Field Names: + - T_2m + - precip_total_surf_mass_flux +output_control: + Frequency: 1 + frequency_units: ndays + MPI Ranks in Filename: false +Restart: + force_new_file: true diff --git a/components/eamxx/cime_config/testdefs/testmods_dirs/scream/v1prod/yaml_outs/scream_output.decadal.1dailyMIN_native.yaml b/components/eamxx/cime_config/testdefs/testmods_dirs/scream/v1prod/yaml_outs/scream_output.decadal.1dailyMIN_native.yaml new file mode 100644 index 000000000000..653e194d278b --- /dev/null +++ b/components/eamxx/cime_config/testdefs/testmods_dirs/scream/v1prod/yaml_outs/scream_output.decadal.1dailyMIN_native.yaml @@ -0,0 +1,16 @@ +%YAML 1.1 +--- +filename_prefix: scream_output.decadal.1dailyMIN_native.h +iotype: pnetcdf +Averaging Type: Min +Max Snapshots Per File: 1 +Fields: + Physics PG2: + Field Names: + - T_2m +output_control: + Frequency: 1 + frequency_units: ndays + MPI Ranks in Filename: false +Restart: + force_new_file: true diff --git a/components/eamxx/cime_config/testdefs/testmods_dirs/scream/v1prod/yaml_outs/scream_output.decadal.1hourlyINST_arm.yaml b/components/eamxx/cime_config/testdefs/testmods_dirs/scream/v1prod/yaml_outs/scream_output.decadal.1hourlyINST_arm.yaml new file mode 100644 index 000000000000..5bb07048aed6 --- /dev/null +++ b/components/eamxx/cime_config/testdefs/testmods_dirs/scream/v1prod/yaml_outs/scream_output.decadal.1hourlyINST_arm.yaml @@ -0,0 +1,40 @@ +%YAML 1.1 +--- +filename_prefix: scream_output.decadal.1hourlyINST_arm.h +iotype: pnetcdf +Averaging Type: Instant +Max Snapshots Per File: 24 # one file per day +horiz_remap_file: ${DIN_LOC_ROOT}/atm/scream/maps/map_ne1024pg2_to_DecadalSites_c20240130.nc +Fields: + Physics PG2: + Field Names: + # 3D + - T_mid + - RelativeHumidity + - qc + - qi + - qr + - qm + - ps + - cldfrac_tot_for_analysis + - cldfrac_liq + - cldfrac_ice_for_analysis + - omega + - tke + - eff_radius_qc + - eff_radius_qi + - nc + - ni + - nr + - bm + - p_mid + - z_mid + - U + - V + - landfrac +output_control: + Frequency: 1 + frequency_units: nhours + MPI Ranks in Filename: false +Restart: + force_new_file: true diff --git a/components/eamxx/cime_config/testdefs/testmods_dirs/scream/v1prod/yaml_outs/scream_output.decadal.1hourlyINST_native.yaml b/components/eamxx/cime_config/testdefs/testmods_dirs/scream/v1prod/yaml_outs/scream_output.decadal.1hourlyINST_native.yaml new file mode 100644 index 000000000000..7a221e89f1c3 --- /dev/null +++ b/components/eamxx/cime_config/testdefs/testmods_dirs/scream/v1prod/yaml_outs/scream_output.decadal.1hourlyINST_native.yaml @@ -0,0 +1,19 @@ +%YAML 1.1 +--- +filename_prefix: scream_output.decadal.1hourlyINST_native.h +iotype: pnetcdf +Averaging Type: Instant +Max Snapshots Per File: 24 +Fields: + Physics PG2: + Field Names: + # For cloud morphology + - SW_flux_up_at_model_top + - LW_flux_up_at_model_top + - precip_total_surf_mass_flux +output_control: + Frequency: 1 + frequency_units: nhours + MPI Ranks in Filename: false +Restart: + force_new_file: true diff --git a/components/eamxx/cime_config/testdefs/testmods_dirs/scream/v1prod/yaml_outs/scream_output.decadal.3hourlyAVG_coarse.yaml b/components/eamxx/cime_config/testdefs/testmods_dirs/scream/v1prod/yaml_outs/scream_output.decadal.3hourlyAVG_coarse.yaml new file mode 100644 index 000000000000..665294c62273 --- /dev/null +++ b/components/eamxx/cime_config/testdefs/testmods_dirs/scream/v1prod/yaml_outs/scream_output.decadal.3hourlyAVG_coarse.yaml @@ -0,0 +1,69 @@ +%YAML 1.1 +--- +filename_prefix: scream_output.decadal.3hourlyAVG_coarse.h +iotype: pnetcdf +Averaging Type: Average +Max Snapshots Per File: 8 # one file per day +horiz_remap_file: ${DIN_LOC_ROOT}/atm/scream/maps/map_ne1024pg2_to_ne30pg2_mono.20230901.nc +Fields: + Physics PG2: + Field Names: + # 3D fields + - T_mid + - qv + - qc + - qr + - qi + - cldfrac_tot + - cldfrac_liq + - omega + - U + - V + - pseudo_density + - z_mid + # Surface + - surf_sens_flux + - surf_evap + - surface_upward_latent_heat_flux + - ps + - precip_liq_surf_mass_flux + - precip_ice_surf_mass_flux + - surf_mom_flux + - surf_radiative_T + - T_2m + - sfc_flux_dir_nir + - sfc_flux_dir_vis + - sfc_flux_dif_nir + - sfc_flux_dif_vis + - sfc_flux_sw_net + - sfc_flux_lw_dn + # Lowest Level + - U_at_model_bot + - V_at_model_bot + - T_mid_at_model_bot + - qv_at_model_bot + - qc_at_model_bot + - qi_at_model_bot + - qr_at_model_bot + - qm_at_model_bot + - bm_at_model_bot + - SW_flux_up_at_model_top + - SW_flux_dn_at_model_top + - LW_flux_up_at_model_top + - SW_clrsky_flux_up_at_model_top + - LW_clrsky_flux_up_at_model_top + - SW_flux_dn_at_model_bot + - SW_clrsky_flux_dn_at_model_bot + - SW_flux_up_at_model_bot + - SW_clrsky_flux_up_at_model_bot + - LW_flux_dn_at_model_bot + - LW_clrsky_flux_dn_at_model_bot + - LW_flux_up_at_model_bot + - LongwaveCloudForcing + - ShortwaveCloudForcing +output_control: + Frequency: 3 + frequency_units: nhours + MPI Ranks in Filename: false +Restart: + force_new_file: true diff --git a/components/eamxx/cime_config/testdefs/testmods_dirs/scream/v1prod/yaml_outs/scream_output.decadal.3hourlyINST_coarse.yaml b/components/eamxx/cime_config/testdefs/testmods_dirs/scream/v1prod/yaml_outs/scream_output.decadal.3hourlyINST_coarse.yaml new file mode 100644 index 000000000000..42c649545088 --- /dev/null +++ b/components/eamxx/cime_config/testdefs/testmods_dirs/scream/v1prod/yaml_outs/scream_output.decadal.3hourlyINST_coarse.yaml @@ -0,0 +1,68 @@ +%YAML 1.1 +--- +filename_prefix: scream_output.decadal.3hourlyINST_coarse.h +iotype: pnetcdf +Averaging Type: Instant +Max Snapshots Per File: 8 # one file per day +horiz_remap_file: ${DIN_LOC_ROOT}/atm/scream/maps/map_ne1024pg2_to_ne30pg2_mono.20230901.nc +Fields: + Physics PG2: + Field Names: + # 2D vars for storm analysis + - SeaLevelPressure + - U_at_model_bot + - V_at_model_bot + - wind_speed_10m + - U_at_925hPa + - V_at_925hPa + - U_at_850hPa + - V_at_850hPa + - U_at_700hPa + - V_at_700hPa + - U_at_500hPa + - V_at_500hPa + - U_at_300hPa + - V_at_300hPa + - ZonalVapFlux + - MeridionalVapFlux + - T_2m + - qv_2m + - T_mid_at_925hPa + - T_mid_at_850hPa + - T_mid_at_700hPa + - T_mid_at_500hPa + - T_mid_at_300hPa + - RelativeHumidity_at_925hPa + - RelativeHumidity_at_850hPa + - RelativeHumidity_at_700hPa + - RelativeHumidity_at_500hPa + - RelativeHumidity_at_300hPa + - z_mid_at_925hPa + - z_mid_at_850hPa + - z_mid_at_700hPa + - z_mid_at_500hPa + - z_mid_at_300hPa + # 2D vars For ACI diagnostics + - SW_clrsky_flux_up_at_model_top + - SW_flux_up_at_model_top + - SW_flux_dn_at_model_top + - LiqWaterPath + - precip_liq_surf_mass_flux + - precip_ice_surf_mass_flux + - IceWaterPath + - cldfrac_tot_for_analysis + - cldfrac_liq + - omega_at_500hPa + - omega_at_700hPa + - omega_at_850hPa + - PotentialTemperature_at_700hPa + - PotentialTemperature_at_1000hPa + # 3D vars for nudging + - U + - V +output_control: + Frequency: 3 + frequency_units: nhours + MPI Ranks in Filename: false +Restart: + force_new_file: true diff --git a/components/eamxx/cime_config/testdefs/testmods_dirs/scream/v1prod/yaml_outs/scream_output.decadal.6hourlyAVG_coarse.yaml b/components/eamxx/cime_config/testdefs/testmods_dirs/scream/v1prod/yaml_outs/scream_output.decadal.6hourlyAVG_coarse.yaml new file mode 100644 index 000000000000..5e4aaed07384 --- /dev/null +++ b/components/eamxx/cime_config/testdefs/testmods_dirs/scream/v1prod/yaml_outs/scream_output.decadal.6hourlyAVG_coarse.yaml @@ -0,0 +1,48 @@ +%YAML 1.1 +--- +filename_prefix: scream_output.decadal.6hourlyAVG_coarse.h +iotype: pnetcdf +Averaging Type: Average +Max Snapshots Per File: 4 # one file per day +horiz_remap_file: ${DIN_LOC_ROOT}/atm/scream/maps/map_ne1024pg2_to_ne30pg2_mono.20230901.nc +Fields: + Physics PG2: + Field Names: + # Full 3D Profile + - p3_T_mid_tend + - shoc_T_mid_tend + - rrtmgp_T_mid_tend + - homme_T_mid_tend + - p3_qv_tend + - shoc_qv_tend + - homme_qv_tend + - SW_flux_dn + - SW_flux_up + - LW_flux_dn + - LW_flux_up + # Surface + - surf_sens_flux + - surf_evap + - surface_upward_latent_heat_flux + - ps + - precip_liq_surf_mass_flux + - precip_ice_surf_mass_flux + - surf_mom_flux + - surf_radiative_T + - T_2m + # Lowest Level + - U_at_model_bot + - V_at_model_bot + - SW_flux_dn_at_model_bot + - SW_flux_up_at_model_bot + - LW_flux_dn_at_model_bot + - LW_flux_up_at_model_bot + - SW_flux_up_at_model_top + - SW_flux_dn_at_model_top + - LW_flux_up_at_model_top +output_control: + Frequency: 6 + frequency_units: nhours + MPI Ranks in Filename: false +Restart: + force_new_file: true diff --git a/components/eamxx/cime_config/testdefs/testmods_dirs/scream/v1prod/yaml_outs/scream_output.decadal.6hourlyINST_coarse.yaml b/components/eamxx/cime_config/testdefs/testmods_dirs/scream/v1prod/yaml_outs/scream_output.decadal.6hourlyINST_coarse.yaml new file mode 100644 index 000000000000..e9e0f34d5e0f --- /dev/null +++ b/components/eamxx/cime_config/testdefs/testmods_dirs/scream/v1prod/yaml_outs/scream_output.decadal.6hourlyINST_coarse.yaml @@ -0,0 +1,39 @@ +%YAML 1.1 +--- +filename_prefix: scream_output.decadal.6hourlyINST_coarse.h +iotype: pnetcdf +Averaging Type: Instant +Max Snapshots Per File: 4 # one file per day +horiz_remap_file: ${DIN_LOC_ROOT}/atm/scream/maps/map_ne1024pg2_to_ne30pg2_mono.20230901.nc +Fields: + Physics PG2: + Field Names: + # 3D fields on model levels + - T_mid + - qv + - RelativeHumidity + - U + - V + - omega + - qc + - nc + - qr + - qi + - tke + - o3_volume_mix_ratio + # 2D fields + - VapWaterPath + - LiqWaterPath + - IceWaterPath + - surf_radiative_T + - ps + - qv_2m + - T_2m + - ocnfrac + - landfrac +output_control: + Frequency: 6 + frequency_units: nhours + MPI Ranks in Filename: false +Restart: + force_new_file: true diff --git a/components/eamxx/cime_config/testdefs/testmods_dirs/scream/v1prod/yaml_outs/scream_output.decadal.6hourlyINST_native.yaml b/components/eamxx/cime_config/testdefs/testmods_dirs/scream/v1prod/yaml_outs/scream_output.decadal.6hourlyINST_native.yaml new file mode 100644 index 000000000000..bb7fd275abf4 --- /dev/null +++ b/components/eamxx/cime_config/testdefs/testmods_dirs/scream/v1prod/yaml_outs/scream_output.decadal.6hourlyINST_native.yaml @@ -0,0 +1,28 @@ +%YAML 1.1 +--- +filename_prefix: scream_output.decadal.6hourlyINST_native.h +iotype: pnetcdf +Averaging Type: Instant +Max Snapshots Per File: 4 # one file per day +Fields: + Physics PG2: + Field Names: + # For storm analysis + - SeaLevelPressure + - wind_speed_10m + - z_mid_at_500hPa + - z_mid_at_200hPa + # For wind turbine study + - wind_speed_at_100m_above_surface + # For atmospheric rivers + - ZonalVapFlux + - MeridionalVapFlux + # Others + - omega_at_500hPa + - omega_at_850hPa +output_control: + Frequency: 6 + frequency_units: nhours + MPI Ranks in Filename: false +Restart: + force_new_file: true diff --git a/components/eamxx/cime_config/testdefs/testmods_dirs/scream/v1prod/yaml_outs/scream_output.decadal.dailyAVG_coarse.yaml b/components/eamxx/cime_config/testdefs/testmods_dirs/scream/v1prod/yaml_outs/scream_output.decadal.dailyAVG_coarse.yaml new file mode 100644 index 000000000000..7c1990a7b56e --- /dev/null +++ b/components/eamxx/cime_config/testdefs/testmods_dirs/scream/v1prod/yaml_outs/scream_output.decadal.dailyAVG_coarse.yaml @@ -0,0 +1,95 @@ +%YAML 1.1 +--- +filename_prefix: scream_output.decadal.dailyAVG_coarse.h +iotype: pnetcdf +Averaging Type: Average +Max Snapshots Per File: 1 +horiz_remap_file: ${DIN_LOC_ROOT}/atm/scream/maps/map_ne1024pg2_to_ne30pg2_mono.20230901.nc +Fields: + Physics PG2: + Field Names: + # 3D fields + - T_mid + - qv + - RelativeHumidity + - qc + - qi + - qr + - qm + - nc + - ni + - nr + - cldfrac_tot_for_analysis + - cldfrac_ice_for_analysis + - cldfrac_liq + - omega + - U + - V + - z_mid + - p_mid + - tke + # 2D fields + - SW_flux_up_at_model_top + - SW_flux_dn_at_model_top + - LW_flux_up_at_model_top + - SW_clrsky_flux_up_at_model_top + - SW_clrsky_flux_dn_at_model_top + - LW_clrsky_flux_up_at_model_top + - SW_flux_up_at_model_bot + - SW_flux_dn_at_model_bot + - LW_flux_up_at_model_bot + - LW_flux_dn_at_model_bot + - SW_clrsky_flux_up_at_model_bot + - SW_clrsky_flux_dn_at_model_bot + - LW_clrsky_flux_dn_at_model_bot + - ShortwaveCloudForcing + - LongwaveCloudForcing + - ps + - SeaLevelPressure + - T_2m + - qv_2m + - surf_radiative_T + - VapWaterPath + - IceWaterPath + - LiqWaterPath + - RainWaterPath + - ZonalVapFlux + - MeridionalVapFlux + - surf_evap + - surf_sens_flux + - surface_upward_latent_heat_flux + - precip_liq_surf_mass_flux + - precip_ice_surf_mass_flux + - landfrac + - ocnfrac + - PotentialTemperature_at_700hPa + - PotentialTemperature_at_850hPa + - PotentialTemperature_at_1000hPa + - PotentialTemperature_at_2m_above_surface + - omega_at_500hPa + - omega_at_700hPa + - omega_at_850hPa + - RelativeHumidity_at_700hPa + - RelativeHumidity_at_1000hPa + - RelativeHumidity_at_2m_above_surface + - wind_speed_10m + - z_mid_at_700hPa + - z_mid_at_1000hPa + - T_mid_at_850hPa + - T_mid_at_700hPa + # For SST advection + - U_at_10m_above_surface + - V_at_10m_above_surface + # COSP + - isccp_ctptau + - modis_ctptau + - misr_cthtau + - cosp_sunlit + - isccp_cldtot + +output_control: + Frequency: 1 + frequency_units: ndays + MPI Ranks in Filename: false +Restart: + force_new_file: true From 7b43a058dd90183f3bca87daa6fea67c358cedd4 Mon Sep 17 00:00:00 2001 From: mahf708 Date: Mon, 2 Sep 2024 19:58:19 -0500 Subject: [PATCH 369/451] add scream-v1prod test to gh/ci --- .github/workflows/e3sm-gh-ci-cime-tests.yml | 4 ++-- .github/workflows/e3sm-gh-ci-w-cime-tests.yml | 3 +-- 2 files changed, 3 insertions(+), 4 deletions(-) diff --git a/.github/workflows/e3sm-gh-ci-cime-tests.yml b/.github/workflows/e3sm-gh-ci-cime-tests.yml index ed35f82a2a7f..62f6c1542e72 100644 --- a/.github/workflows/e3sm-gh-ci-cime-tests.yml +++ b/.github/workflows/e3sm-gh-ci-cime-tests.yml @@ -28,10 +28,10 @@ jobs: fail-fast: false matrix: test: - # format test like usual (TYPE_PX.GRID.COMPSET.MACHINE_COMPILER) - SMS_D_P4.ne4pg2_oQU480.F2010.ghci-oci_gnu - ERS_P4.ne4pg2_oQU480.F2010.ghci-oci_gnu.eam-wcprod_F2010 - - SMS_P4.ne4pg2_oQU480.F2010-SCREAMv1.ghci-oci_gnu + - SMS_D_P4.ne4pg2_oQU480.F2010-SCREAMv1-MPASSI.ghci-oci_gnu + - ERS_P4.ne4pg2_oQU480.F2010-SCREAMv1-MPASSI.ghci-oci_gnu.scream-v1prod container: image: ghcr.io/mahf708/e3sm-imgs:v0.0.9 diff --git a/.github/workflows/e3sm-gh-ci-w-cime-tests.yml b/.github/workflows/e3sm-gh-ci-w-cime-tests.yml index b481119a85a5..178b9a6a4429 100644 --- a/.github/workflows/e3sm-gh-ci-w-cime-tests.yml +++ b/.github/workflows/e3sm-gh-ci-w-cime-tests.yml @@ -14,15 +14,14 @@ on: jobs: ci-w: + if: ${{ github.event.repository.name == 'e3sm' }} runs-on: ubuntu-latest strategy: fail-fast: false matrix: test: - # format test like usual (TYPE_PX.GRID.COMPSET.MACHINE_COMPILER) - SMS_D_P8.ne4pg2_oQU480.WCYCL2010NS.ghci-oci_gnu - ERS_P8.ne4pg2_oQU480.WCYCL2010NS.ghci-oci_gnu.allactive-wcprod_1850 - container: image: ghcr.io/mahf708/e3sm-imgs:v0.0.9 From dd9b28d77a8a1b2c408662864185d7608b82b5fd Mon Sep 17 00:00:00 2001 From: Walter Hannah Date: Tue, 3 Sep 2024 08:36:55 -0600 Subject: [PATCH 370/451] Add white space at end of mkatmsrffile.py --- components/eam/tools/mkatmsrffile/mkatmsrffile.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/components/eam/tools/mkatmsrffile/mkatmsrffile.py b/components/eam/tools/mkatmsrffile/mkatmsrffile.py index 826544feb084..268bd4ddd86e 100644 --- a/components/eam/tools/mkatmsrffile/mkatmsrffile.py +++ b/components/eam/tools/mkatmsrffile/mkatmsrffile.py @@ -301,4 +301,4 @@ def apply_map_2D( data_out, ntime, n_s, wgt, row, col, data_in ): #--------------------------------------------------------------------------------------------------- if __name__ == '__main__': main() -#--------------------------------------------------------------------------------------------------- \ No newline at end of file +#--------------------------------------------------------------------------------------------------- From 47e474c6dc1284e9793c2d346cfcb2a5316a00a9 Mon Sep 17 00:00:00 2001 From: Wuyin Lin Date: Tue, 3 Sep 2024 10:47:43 -0500 Subject: [PATCH 371/451] Remove alternative aliases for v3 single-forcings compsets --- cime_config/allactive/config_compsets.xml | 40 ----------------------- 1 file changed, 40 deletions(-) diff --git a/cime_config/allactive/config_compsets.xml b/cime_config/allactive/config_compsets.xml index 28eefc45b765..ace33ae09172 100755 --- a/cime_config/allactive/config_compsets.xml +++ b/cime_config/allactive/config_compsets.xml @@ -93,81 +93,41 @@ 20TRSOI_EAM%CMIP6-GHG_ELM%CNPRDCTCBCTOP_MPASSI_MPASO_MOSART_SGLC_SWAV - - hist-GHG - 20TRSOI_EAM%CMIP6-GHG_ELM%CNPRDCTCBCTOP_MPASSI_MPASO_MOSART_SGLC_SWAV - - WCYCL20TR-aer 20TRSOI_EAM%CMIP6-AER_ELM%CNPRDCTCBCTOP_MPASSI_MPASO_MOSART_SGLC_SWAV - - hist-aer - 20TRSOI_EAM%CMIP6-AER_ELM%CNPRDCTCBCTOP_MPASSI_MPASO_MOSART_SGLC_SWAV - - WCYCL20TR-xGHG-xaer 20TRSOI_EAM%CMIP6-xGHG-xAER_ELM%CNPRDCTCBCTOP_MPASSI_MPASO_MOSART_SGLC_SWAV - - hist-all-xGHG-xaer - 20TRSOI_EAM%CMIP6-xGHG-xAER_ELM%CNPRDCTCBCTOP_MPASSI_MPASO_MOSART_SGLC_SWAV - - WCYCL20TR-nat 20TRSOI_EAM%CMIP6-NAT_ELM%CNPRDCTCBCTOP_MPASSI_MPASO_MOSART_SGLC_SWAV - - hist-nat - 20TRSOI_EAM%CMIP6-NAT_ELM%CNPRDCTCBCTOP_MPASSI_MPASO_MOSART_SGLC_SWAV - - WCYCL20TR-ozone 20TRSOI_EAM%CMIP6-OZONE_ELM%CNPRDCTCBCTOP_MPASSI_MPASO_MOSART_SGLC_SWAV - - hist-ozone - 20TRSOI_EAM%CMIP6-OZONE_ELM%CNPRDCTCBCTOP_MPASSI_MPASO_MOSART_SGLC_SWAV - - WCYCL20TR-lulc 20TRSOI_EAM%CMIP6-LULC_ELM%CNPRDCTCBCTOP_MPASSI_MPASO_MOSART_SGLC_SWAV - - hist-lulc - 20TRSOI_EAM%CMIP6-LULC_ELM%CNPRDCTCBCTOP_MPASSI_MPASO_MOSART_SGLC_SWAV - - WCYCL20TR-volc 20TRSOI_EAM%CMIP6-VOLC_ELM%CNPRDCTCBCTOP_MPASSI_MPASO_MOSART_SGLC_SWAV - - hist-volc - 20TRSOI_EAM%CMIP6-VOLC_ELM%CNPRDCTCBCTOP_MPASSI_MPASO_MOSART_SGLC_SWAV - - WCYCL20TR-xaer 20TRSOI_EAM%CMIP6-xAER_ELM%CNPRDCTCBCTOP_MPASSI_MPASO_MOSART_SGLC_SWAV - - hist-all-xaer - 20TRSOI_EAM%CMIP6-xAER_ELM%CNPRDCTCBCTOP_MPASSI_MPASO_MOSART_SGLC_SWAV - - From ddc2f2347929d23704ec6582517689eabd120bea Mon Sep 17 00:00:00 2001 From: Walter Hannah Date: Tue, 3 Sep 2024 10:10:49 -0600 Subject: [PATCH 372/451] Delete components/eam/tools/mkatmsrffile/test.md --- components/eam/tools/mkatmsrffile/test.md | 3 --- 1 file changed, 3 deletions(-) delete mode 100644 components/eam/tools/mkatmsrffile/test.md diff --git a/components/eam/tools/mkatmsrffile/test.md b/components/eam/tools/mkatmsrffile/test.md deleted file mode 100644 index bc0ef89536e0..000000000000 --- a/components/eam/tools/mkatmsrffile/test.md +++ /dev/null @@ -1,3 +0,0 @@ -# test - -Some text goes here. From 9034faa5cd2076c85651bf33b3fad4b2bce89f4f Mon Sep 17 00:00:00 2001 From: Gautam Bisht Date: Mon, 17 Jun 2024 12:11:53 -0700 Subject: [PATCH 373/451] Adds LULC for NARRM A LULC file for 1850-2000 at r025 is added. [BFB] --- .../elm/bld/namelist_files/use_cases/20thC_CMIP6_transient.xml | 1 + 1 file changed, 1 insertion(+) diff --git a/components/elm/bld/namelist_files/use_cases/20thC_CMIP6_transient.xml b/components/elm/bld/namelist_files/use_cases/20thC_CMIP6_transient.xml index 4f48bf6326a8..92f186f1a38d 100644 --- a/components/elm/bld/namelist_files/use_cases/20thC_CMIP6_transient.xml +++ b/components/elm/bld/namelist_files/use_cases/20thC_CMIP6_transient.xml @@ -38,6 +38,7 @@ lnd/clm2/initdata_map/20180316.DECKv1b_A1.ne30_oEC.edison.clm2.r.1980-01-01-00000.8575c3f_c20190904.nc lnd/clm2/surfdata_map/landuse.timeseries_0.5x0.5_hist_simyr1850-2015_c240308.nc +lnd/clm2/surfdata_map/landuse.timeseries_0.25x0.25_hist_simyr1850-2015_c240125.nc lnd/clm2/surfdata_map/landuse.timeseries_ne120np4_historical_simyr1850-2015_c190904.nc From 6ca2cfe9d1b7dd00cb2c63d77b9fb23a5e5b1812 Mon Sep 17 00:00:00 2001 From: noel Date: Tue, 3 Sep 2024 11:25:28 -0700 Subject: [PATCH 374/451] For pm-cpu, use 2 nodes for default with tests using l%360x720cru eg SMS.hcru_hcru.IELM --- components/elm/cime_config/config_pes.xml | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/components/elm/cime_config/config_pes.xml b/components/elm/cime_config/config_pes.xml index 4af0da699656..9dbc776bcac4 100644 --- a/components/elm/cime_config/config_pes.xml +++ b/components/elm/cime_config/config_pes.xml @@ -239,14 +239,14 @@ elm: pm-cpu 2 nodes for grid l%360x720cru - 192 - 192 - 192 - 192 - 192 - 192 - 192 - 192 + -2 + -2 + -2 + -2 + -2 + -2 + -2 + -2 @@ -568,7 +568,7 @@ - + GIS 20km (low-res) testing config 128 @@ -606,7 +606,7 @@ - + GIS 1-to-10km (high-res) config 128 From fdb2218352fe267d10317a6598cb8dcdf0669e56 Mon Sep 17 00:00:00 2001 From: "Andrew M. Bradley" Date: Tue, 3 Sep 2024 14:21:37 -0500 Subject: [PATCH 375/451] Hommexx: Use portable PRIx64 instead of lx in printf. --- .../homme/src/share/cxx/utilities/InternalDiagnostics.cpp | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/components/homme/src/share/cxx/utilities/InternalDiagnostics.cpp b/components/homme/src/share/cxx/utilities/InternalDiagnostics.cpp index 3249966c0b5e..ffc9657f4108 100644 --- a/components/homme/src/share/cxx/utilities/InternalDiagnostics.cpp +++ b/components/homme/src/share/cxx/utilities/InternalDiagnostics.cpp @@ -13,6 +13,8 @@ #include "TimeLevel.hpp" #include "mpi/Comm.hpp" +#include + namespace Homme { namespace { @@ -50,10 +52,10 @@ void print_global_state_hash (const std::string& label) { all_reduce_HashType(comm.mpi_comm(), accum, gaccum, 5); if (comm.root()) { for (int i = 0; i < NUM_TIME_LEVELS; ++i) - fprintf(stderr, "hxxhash> %14d %1d %16lx (E %s)\n", + fprintf(stderr, "hxxhash> %14d %1d %16" PRIx64 " (E %s)\n", tl.nstep, i, gaccum[i], label.c_str()); for (int i = 0; i < Q_NUM_TIME_LEVELS; ++i) - fprintf(stderr, "hxxhash> %14d %1d %16lx (T %s)\n", + fprintf(stderr, "hxxhash> %14d %1d %16" PRIx64 " (T %s)\n", tl.nstep, i, gaccum[NUM_TIME_LEVELS+i], label.c_str()); } } From 73a96413bcf2c8d5195313ca2ece05ba47d2ee7f Mon Sep 17 00:00:00 2001 From: Wuyin Lin Date: Tue, 3 Sep 2024 15:03:46 -0500 Subject: [PATCH 376/451] Add to list of the supported coupled compsets --- docs/user-guide/index.md | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/docs/user-guide/index.md b/docs/user-guide/index.md index c2daf519a42d..01890a0d41cd 100644 --- a/docs/user-guide/index.md +++ b/docs/user-guide/index.md @@ -37,6 +37,16 @@ Below list the standard configuration compsets supported in the current version |`WCYCLSSP245` | Standard configuration with prescribed SSP-245 forcings | |`WCYCLSSP370` | Standard configuration with prescribed SSP-370 forcings | |`WCYCLSSP585` | Standard configuration with prescribed SSP-585 forcings | +| | +|Extra Compsets |For single-forcings simulations of the historical period (1850-2014) | +|`WCYCL20TR-GHG` | Greenhouse gases only configuration (`GHGs`)| +|`WCYCL20TR-aer` | Anthropogenic aerosols and precursors only configuration (`aer`)| +|`WCYCL20TR-xGHG-xaer` | All forcings except GHGs and aer (`solar irradiance, stratospheric ozone and volcanic emissions, land use land cover`) | +|`WCYCL20TR-xaer` | All forcings except aer (`GHGs, solar irradiance, stratospheric ozone and volcanic emissions, land use land cover`) | +|`WCYCL20TR-nat` | Natural-only configuration (`solar irradiance, stratospheric volcanic emissions, land use land cover`) | +|`WCYCL20TR-ozone` | Stratospheric ozone only configuration | +|`WCYCL20TR-lulc` | Land use land cover only configuration | +|`WCYCL20TR-volc` | Stratospheric volcanic emissions only configuration | The compsets for the other two science simulation campaigns are being finalized, with additional components and/or features. The compset naming follows the same convention, e.g., `CRYO1850` and `CRYO1850-4xCO2` are with prognostic ice-shelf melt fluxes for the `polar processes` simulation campaign. From 72f544fff76ae812174be4887568a704d14d7337 Mon Sep 17 00:00:00 2001 From: noel Date: Tue, 3 Sep 2024 14:51:44 -0700 Subject: [PATCH 377/451] Use 3 full nodes instead of 2 in last commit to avoid yet a different issue. --- components/elm/cime_config/config_pes.xml | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/components/elm/cime_config/config_pes.xml b/components/elm/cime_config/config_pes.xml index 9dbc776bcac4..39e36221175b 100644 --- a/components/elm/cime_config/config_pes.xml +++ b/components/elm/cime_config/config_pes.xml @@ -237,16 +237,16 @@ - elm: pm-cpu 2 nodes for grid l%360x720cru - - -2 - -2 - -2 - -2 - -2 - -2 - -2 - -2 + elm: pm-cpu 3 nodes for grid l%360x720cru + + -3 + -3 + -3 + -3 + -3 + -3 + -3 + -3 From 846531dc611d44d0d056dae0d0a9f68159c85a63 Mon Sep 17 00:00:00 2001 From: mahf708 Date: Tue, 3 Sep 2024 18:19:51 -0500 Subject: [PATCH 378/451] fix minor bug and add mkatmsrffile workflow --- .../e3sm-gh-tools-mkatmsrffile-test.yml | 86 +++++++++++++++++++ .../eam/tools/mkatmsrffile/mkatmsrffile.py | 14 +-- 2 files changed, 93 insertions(+), 7 deletions(-) create mode 100644 .github/workflows/e3sm-gh-tools-mkatmsrffile-test.yml diff --git a/.github/workflows/e3sm-gh-tools-mkatmsrffile-test.yml b/.github/workflows/e3sm-gh-tools-mkatmsrffile-test.yml new file mode 100644 index 000000000000..13b73e4df3f4 --- /dev/null +++ b/.github/workflows/e3sm-gh-tools-mkatmsrffile-test.yml @@ -0,0 +1,86 @@ +name: mkatmsrffile + +on: + push: + branches: [ master ] + pull_request: + branches: [ master ] + paths: + - 'components/eam/tools/mkatmsrffile/mkatmsrffile.py' + schedule: + - cron: '00 15 * * 2' + workflow_dispatch: + +jobs: + mkatmsrffile-test: + runs-on: ubuntu-latest + defaults: + run: + shell: bash -l {0} + outputs: + event_name: ${{ github.event_name }} + steps: + - + name: Repository checkout + uses: actions/checkout@v4 + with: + show-progress: false + submodules: false + - + name: Conda setup + uses: conda-incubator/setup-miniconda@v3 + with: + activate-environment: "envmkatmsrffile" + miniforge-variant: Mambaforge + miniforge-version: latest + use-mamba: true + mamba-version: "*" + channel-priority: strict + auto-update-conda: true + python-version: 3.11 + - + name: Install dependencies + run: | + echo $CONDA_PREFIX + mamba install -y nco xarray numba numpy netcdf4 + - + name: Run tests + working-directory: components/eam/tools/mkatmsrffile + run: | + echo $CONDA_PREFIX + wget https://web.lcrc.anl.gov/public/e3sm/inputdata/atm/cam/chem/trop_mozart/dvel/clim_soilw.nc + wget https://web.lcrc.anl.gov/public/e3sm/inputdata/atm/cam/chem/trop_mozart/dvel/regrid_vegetation.nc + wget https://web.lcrc.anl.gov/public/e3sm/inputdata/atm/cam/chem/trop_mozart/dvel/map_1x1_to_ne30pg2_traave_c20240903.nc + python mkatmsrffile.py --map_file=map_1x1_to_ne30pg2_traave_c20240903.nc --vegetation_file=regrid_vegetation.nc --soil_water_file=clim_soilw.nc --dst_grid=ne30pg2 + + mkatmsrffile-notify: + needs: mkatmsrffile-test + if: ${{ failure() && needs.mkatmsrffile-test.outputs.event_name != 'pull_request' }} + runs-on: ubuntu-latest + steps: + - name: Create issue + run: | + previous_issue_number=$(gh issue list \ + --label "$LABELS" \ + --json number \ + --jq '.[0].number') + if [[ -n $previous_issue_number ]]; then + gh issue comment "$previous_issue_number" \ + --body "$BODY" + else + gh issue create \ + --title "$TITLE" \ + --assignee "$ASSIGNEES" \ + --label "$LABELS" \ + --body "$BODY" + fi + env: + GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} + GH_REPO: ${{ github.repository }} + TITLE: mkatmsrffile test failure + ASSIGNEES: whannah1 + LABELS: bug + BODY: | + Workflow failed! There's likely an issue in the mkatmsrffile tool! For more information, please see: + - Workflow URL: https://github.com/${{ github.repository }}/actions/runs/${{ github.run_id }} (number ${{ github.run_number }}, attempt ${{ github.run_attempt }}) + - Workflow SHA: ${{ github.sha }} diff --git a/components/eam/tools/mkatmsrffile/mkatmsrffile.py b/components/eam/tools/mkatmsrffile/mkatmsrffile.py index 268bd4ddd86e..101671488f30 100644 --- a/components/eam/tools/mkatmsrffile/mkatmsrffile.py +++ b/components/eam/tools/mkatmsrffile/mkatmsrffile.py @@ -253,13 +253,13 @@ def main(): ds_out['lon'] = ds_map.xc_b.rename({'n_b':'ncol'}) ds_out['lat'] = ds_map.yc_b.rename({'n_b':'ncol'}) - ds.attrs['title'] = 'E3SM atmosphere surface data' - ds.attrs['source_code'] = source_code_meta - ds.attrs['hostname'] = str(host) - ds.attrs['history'] = f'created by {user}, '+datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S') - ds.attrs['input_map_file'] = opts.map_file - ds.attrs['input_vegetation_file'] = opts.vegetation_file - ds.attrs['input_soil_water_file'] = opts.soil_water_file + ds_out.attrs['title'] = 'E3SM atmosphere surface data' + ds_out.attrs['source_code'] = source_code_meta + ds_out.attrs['hostname'] = str(host) + ds_out.attrs['history'] = f'created by {user}, '+datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S') + ds_out.attrs['input_map_file'] = opts.map_file + ds_out.attrs['input_vegetation_file'] = opts.vegetation_file + ds_out.attrs['input_soil_water_file'] = opts.soil_water_file ds_out.to_netcdf(path=output_file,mode='w') From 9c88f0db5b974e40a79e1ee1ca5a5b7c69b6cae8 Mon Sep 17 00:00:00 2001 From: Wuyin Lin Date: Tue, 3 Sep 2024 18:51:45 -0500 Subject: [PATCH 379/451] Update docs for the new compsets --- docs/user-guide/index.md | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/docs/user-guide/index.md b/docs/user-guide/index.md index 01890a0d41cd..d32d6c65b136 100644 --- a/docs/user-guide/index.md +++ b/docs/user-guide/index.md @@ -37,8 +37,7 @@ Below list the standard configuration compsets supported in the current version |`WCYCLSSP245` | Standard configuration with prescribed SSP-245 forcings | |`WCYCLSSP370` | Standard configuration with prescribed SSP-370 forcings | |`WCYCLSSP585` | Standard configuration with prescribed SSP-585 forcings | -| | -|Extra Compsets |For single-forcings simulations of the historical period (1850-2014) | +| |Compsets for single-forcings simulations of the historical period (1850-2014) | |`WCYCL20TR-GHG` | Greenhouse gases only configuration (`GHGs`)| |`WCYCL20TR-aer` | Anthropogenic aerosols and precursors only configuration (`aer`)| |`WCYCL20TR-xGHG-xaer` | All forcings except GHGs and aer (`solar irradiance, stratospheric ozone and volcanic emissions, land use land cover`) | From 5c8c7369208f42ef2df9719d5c449f8cb78519e1 Mon Sep 17 00:00:00 2001 From: Wuyin Lin Date: Tue, 3 Sep 2024 20:40:18 -0500 Subject: [PATCH 380/451] Fix markdown text in user's guide --- docs/user-guide/index.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/user-guide/index.md b/docs/user-guide/index.md index d32d6c65b136..8674926526e9 100644 --- a/docs/user-guide/index.md +++ b/docs/user-guide/index.md @@ -37,7 +37,7 @@ Below list the standard configuration compsets supported in the current version |`WCYCLSSP245` | Standard configuration with prescribed SSP-245 forcings | |`WCYCLSSP370` | Standard configuration with prescribed SSP-370 forcings | |`WCYCLSSP585` | Standard configuration with prescribed SSP-585 forcings | -| |Compsets for single-forcings simulations of the historical period (1850-2014) | +| | #### Compsets for single-forcings simulations of the historical period (1850-2014) | |`WCYCL20TR-GHG` | Greenhouse gases only configuration (`GHGs`)| |`WCYCL20TR-aer` | Anthropogenic aerosols and precursors only configuration (`aer`)| |`WCYCL20TR-xGHG-xaer` | All forcings except GHGs and aer (`solar irradiance, stratospheric ozone and volcanic emissions, land use land cover`) | From e757ed8c6f8bfe1a1acc3de019c8193e1d996dfb Mon Sep 17 00:00:00 2001 From: mahf708 Date: Tue, 3 Sep 2024 17:43:07 -0500 Subject: [PATCH 381/451] rename v1prod to prod, add eamxx to F testing --- .github/workflows/e3sm-gh-ci-cime-tests.yml | 5 ++++- cime_config/config_files.xml | 1 + .../{scream/v1prod => eamxx/prod}/shell_commands | 0 .../testmods_dirs/{scream/v1prod => eamxx/prod}/user_nl_cpl | 0 .../testmods_dirs/{scream/v1prod => eamxx/prod}/user_nl_elm | 0 .../yaml_outs/scream_output.decadal.1dailyAVG_native.yaml | 0 .../yaml_outs/scream_output.decadal.1dailyMAX_native.yaml | 0 .../yaml_outs/scream_output.decadal.1dailyMIN_native.yaml | 0 .../yaml_outs/scream_output.decadal.1hourlyINST_arm.yaml | 0 .../yaml_outs/scream_output.decadal.1hourlyINST_native.yaml | 0 .../yaml_outs/scream_output.decadal.3hourlyAVG_coarse.yaml | 0 .../yaml_outs/scream_output.decadal.3hourlyINST_coarse.yaml | 0 .../yaml_outs/scream_output.decadal.6hourlyAVG_coarse.yaml | 0 .../yaml_outs/scream_output.decadal.6hourlyINST_coarse.yaml | 0 .../yaml_outs/scream_output.decadal.6hourlyINST_native.yaml | 0 .../yaml_outs/scream_output.decadal.dailyAVG_coarse.yaml | 0 16 files changed, 5 insertions(+), 1 deletion(-) rename components/eamxx/cime_config/testdefs/testmods_dirs/{scream/v1prod => eamxx/prod}/shell_commands (100%) rename components/eamxx/cime_config/testdefs/testmods_dirs/{scream/v1prod => eamxx/prod}/user_nl_cpl (100%) rename components/eamxx/cime_config/testdefs/testmods_dirs/{scream/v1prod => eamxx/prod}/user_nl_elm (100%) rename components/eamxx/cime_config/testdefs/testmods_dirs/{scream/v1prod => eamxx/prod}/yaml_outs/scream_output.decadal.1dailyAVG_native.yaml (100%) rename components/eamxx/cime_config/testdefs/testmods_dirs/{scream/v1prod => eamxx/prod}/yaml_outs/scream_output.decadal.1dailyMAX_native.yaml (100%) rename components/eamxx/cime_config/testdefs/testmods_dirs/{scream/v1prod => eamxx/prod}/yaml_outs/scream_output.decadal.1dailyMIN_native.yaml (100%) rename components/eamxx/cime_config/testdefs/testmods_dirs/{scream/v1prod => eamxx/prod}/yaml_outs/scream_output.decadal.1hourlyINST_arm.yaml (100%) rename components/eamxx/cime_config/testdefs/testmods_dirs/{scream/v1prod => eamxx/prod}/yaml_outs/scream_output.decadal.1hourlyINST_native.yaml (100%) rename components/eamxx/cime_config/testdefs/testmods_dirs/{scream/v1prod => eamxx/prod}/yaml_outs/scream_output.decadal.3hourlyAVG_coarse.yaml (100%) rename components/eamxx/cime_config/testdefs/testmods_dirs/{scream/v1prod => eamxx/prod}/yaml_outs/scream_output.decadal.3hourlyINST_coarse.yaml (100%) rename components/eamxx/cime_config/testdefs/testmods_dirs/{scream/v1prod => eamxx/prod}/yaml_outs/scream_output.decadal.6hourlyAVG_coarse.yaml (100%) rename components/eamxx/cime_config/testdefs/testmods_dirs/{scream/v1prod => eamxx/prod}/yaml_outs/scream_output.decadal.6hourlyINST_coarse.yaml (100%) rename components/eamxx/cime_config/testdefs/testmods_dirs/{scream/v1prod => eamxx/prod}/yaml_outs/scream_output.decadal.6hourlyINST_native.yaml (100%) rename components/eamxx/cime_config/testdefs/testmods_dirs/{scream/v1prod => eamxx/prod}/yaml_outs/scream_output.decadal.dailyAVG_coarse.yaml (100%) diff --git a/.github/workflows/e3sm-gh-ci-cime-tests.yml b/.github/workflows/e3sm-gh-ci-cime-tests.yml index 62f6c1542e72..f5c3ffcebf94 100644 --- a/.github/workflows/e3sm-gh-ci-cime-tests.yml +++ b/.github/workflows/e3sm-gh-ci-cime-tests.yml @@ -8,12 +8,15 @@ on: - '.github/workflows/e3sm-gh-ci-cime-tests.yml' - 'cime_config/**' - 'components/eam/**' + - 'components/eamxx/**' - 'components/elm/**' - 'driver-moab/**' - 'driver-mct/**' # second, no to these - '!components/eam/docs/**' - '!components/eam/mkdocs.yml' + - '!components/eamxx/docs/**' + - '!components/eamxx/mkdocs.yml' - '!components/elm/docs/**' - '!components/elm/mkdocs.yml' @@ -31,7 +34,7 @@ jobs: - SMS_D_P4.ne4pg2_oQU480.F2010.ghci-oci_gnu - ERS_P4.ne4pg2_oQU480.F2010.ghci-oci_gnu.eam-wcprod_F2010 - SMS_D_P4.ne4pg2_oQU480.F2010-SCREAMv1-MPASSI.ghci-oci_gnu - - ERS_P4.ne4pg2_oQU480.F2010-SCREAMv1-MPASSI.ghci-oci_gnu.scream-v1prod + - ERS_P4.ne4pg2_oQU480.F2010-SCREAMv1-MPASSI.ghci-oci_gnu.eamxx-prod container: image: ghcr.io/mahf708/e3sm-imgs:v0.0.9 diff --git a/cime_config/config_files.xml b/cime_config/config_files.xml index 281291798dbd..e88a9d68f62a 100644 --- a/cime_config/config_files.xml +++ b/cime_config/config_files.xml @@ -348,6 +348,7 @@ $COMP_ROOT_DIR_ICE/cime_config/testdefs/testmods_dirs $COMP_ROOT_DIR_ROF/cime_config/testdefs/testmods_dirs $COMP_ROOT_DIR_ATM/cime_config/testdefs/testmods_dirs + $COMP_ROOT_DIR_ATM/cime_config/testdefs/testmods_dirs $COMP_ROOT_DIR_OCN/cime_config/testdefs/testmods_dirs $COMP_ROOT_DIR_ICE/cime_config/testdefs/testmods_dirs $COMP_ROOT_DIR_WAV/cime_config/testdefs/testmods_dirs diff --git a/components/eamxx/cime_config/testdefs/testmods_dirs/scream/v1prod/shell_commands b/components/eamxx/cime_config/testdefs/testmods_dirs/eamxx/prod/shell_commands similarity index 100% rename from components/eamxx/cime_config/testdefs/testmods_dirs/scream/v1prod/shell_commands rename to components/eamxx/cime_config/testdefs/testmods_dirs/eamxx/prod/shell_commands diff --git a/components/eamxx/cime_config/testdefs/testmods_dirs/scream/v1prod/user_nl_cpl b/components/eamxx/cime_config/testdefs/testmods_dirs/eamxx/prod/user_nl_cpl similarity index 100% rename from components/eamxx/cime_config/testdefs/testmods_dirs/scream/v1prod/user_nl_cpl rename to components/eamxx/cime_config/testdefs/testmods_dirs/eamxx/prod/user_nl_cpl diff --git a/components/eamxx/cime_config/testdefs/testmods_dirs/scream/v1prod/user_nl_elm b/components/eamxx/cime_config/testdefs/testmods_dirs/eamxx/prod/user_nl_elm similarity index 100% rename from components/eamxx/cime_config/testdefs/testmods_dirs/scream/v1prod/user_nl_elm rename to components/eamxx/cime_config/testdefs/testmods_dirs/eamxx/prod/user_nl_elm diff --git a/components/eamxx/cime_config/testdefs/testmods_dirs/scream/v1prod/yaml_outs/scream_output.decadal.1dailyAVG_native.yaml b/components/eamxx/cime_config/testdefs/testmods_dirs/eamxx/prod/yaml_outs/scream_output.decadal.1dailyAVG_native.yaml similarity index 100% rename from components/eamxx/cime_config/testdefs/testmods_dirs/scream/v1prod/yaml_outs/scream_output.decadal.1dailyAVG_native.yaml rename to components/eamxx/cime_config/testdefs/testmods_dirs/eamxx/prod/yaml_outs/scream_output.decadal.1dailyAVG_native.yaml diff --git a/components/eamxx/cime_config/testdefs/testmods_dirs/scream/v1prod/yaml_outs/scream_output.decadal.1dailyMAX_native.yaml b/components/eamxx/cime_config/testdefs/testmods_dirs/eamxx/prod/yaml_outs/scream_output.decadal.1dailyMAX_native.yaml similarity index 100% rename from components/eamxx/cime_config/testdefs/testmods_dirs/scream/v1prod/yaml_outs/scream_output.decadal.1dailyMAX_native.yaml rename to components/eamxx/cime_config/testdefs/testmods_dirs/eamxx/prod/yaml_outs/scream_output.decadal.1dailyMAX_native.yaml diff --git a/components/eamxx/cime_config/testdefs/testmods_dirs/scream/v1prod/yaml_outs/scream_output.decadal.1dailyMIN_native.yaml b/components/eamxx/cime_config/testdefs/testmods_dirs/eamxx/prod/yaml_outs/scream_output.decadal.1dailyMIN_native.yaml similarity index 100% rename from components/eamxx/cime_config/testdefs/testmods_dirs/scream/v1prod/yaml_outs/scream_output.decadal.1dailyMIN_native.yaml rename to components/eamxx/cime_config/testdefs/testmods_dirs/eamxx/prod/yaml_outs/scream_output.decadal.1dailyMIN_native.yaml diff --git a/components/eamxx/cime_config/testdefs/testmods_dirs/scream/v1prod/yaml_outs/scream_output.decadal.1hourlyINST_arm.yaml b/components/eamxx/cime_config/testdefs/testmods_dirs/eamxx/prod/yaml_outs/scream_output.decadal.1hourlyINST_arm.yaml similarity index 100% rename from components/eamxx/cime_config/testdefs/testmods_dirs/scream/v1prod/yaml_outs/scream_output.decadal.1hourlyINST_arm.yaml rename to components/eamxx/cime_config/testdefs/testmods_dirs/eamxx/prod/yaml_outs/scream_output.decadal.1hourlyINST_arm.yaml diff --git a/components/eamxx/cime_config/testdefs/testmods_dirs/scream/v1prod/yaml_outs/scream_output.decadal.1hourlyINST_native.yaml b/components/eamxx/cime_config/testdefs/testmods_dirs/eamxx/prod/yaml_outs/scream_output.decadal.1hourlyINST_native.yaml similarity index 100% rename from components/eamxx/cime_config/testdefs/testmods_dirs/scream/v1prod/yaml_outs/scream_output.decadal.1hourlyINST_native.yaml rename to components/eamxx/cime_config/testdefs/testmods_dirs/eamxx/prod/yaml_outs/scream_output.decadal.1hourlyINST_native.yaml diff --git a/components/eamxx/cime_config/testdefs/testmods_dirs/scream/v1prod/yaml_outs/scream_output.decadal.3hourlyAVG_coarse.yaml b/components/eamxx/cime_config/testdefs/testmods_dirs/eamxx/prod/yaml_outs/scream_output.decadal.3hourlyAVG_coarse.yaml similarity index 100% rename from components/eamxx/cime_config/testdefs/testmods_dirs/scream/v1prod/yaml_outs/scream_output.decadal.3hourlyAVG_coarse.yaml rename to components/eamxx/cime_config/testdefs/testmods_dirs/eamxx/prod/yaml_outs/scream_output.decadal.3hourlyAVG_coarse.yaml diff --git a/components/eamxx/cime_config/testdefs/testmods_dirs/scream/v1prod/yaml_outs/scream_output.decadal.3hourlyINST_coarse.yaml b/components/eamxx/cime_config/testdefs/testmods_dirs/eamxx/prod/yaml_outs/scream_output.decadal.3hourlyINST_coarse.yaml similarity index 100% rename from components/eamxx/cime_config/testdefs/testmods_dirs/scream/v1prod/yaml_outs/scream_output.decadal.3hourlyINST_coarse.yaml rename to components/eamxx/cime_config/testdefs/testmods_dirs/eamxx/prod/yaml_outs/scream_output.decadal.3hourlyINST_coarse.yaml diff --git a/components/eamxx/cime_config/testdefs/testmods_dirs/scream/v1prod/yaml_outs/scream_output.decadal.6hourlyAVG_coarse.yaml b/components/eamxx/cime_config/testdefs/testmods_dirs/eamxx/prod/yaml_outs/scream_output.decadal.6hourlyAVG_coarse.yaml similarity index 100% rename from components/eamxx/cime_config/testdefs/testmods_dirs/scream/v1prod/yaml_outs/scream_output.decadal.6hourlyAVG_coarse.yaml rename to components/eamxx/cime_config/testdefs/testmods_dirs/eamxx/prod/yaml_outs/scream_output.decadal.6hourlyAVG_coarse.yaml diff --git a/components/eamxx/cime_config/testdefs/testmods_dirs/scream/v1prod/yaml_outs/scream_output.decadal.6hourlyINST_coarse.yaml b/components/eamxx/cime_config/testdefs/testmods_dirs/eamxx/prod/yaml_outs/scream_output.decadal.6hourlyINST_coarse.yaml similarity index 100% rename from components/eamxx/cime_config/testdefs/testmods_dirs/scream/v1prod/yaml_outs/scream_output.decadal.6hourlyINST_coarse.yaml rename to components/eamxx/cime_config/testdefs/testmods_dirs/eamxx/prod/yaml_outs/scream_output.decadal.6hourlyINST_coarse.yaml diff --git a/components/eamxx/cime_config/testdefs/testmods_dirs/scream/v1prod/yaml_outs/scream_output.decadal.6hourlyINST_native.yaml b/components/eamxx/cime_config/testdefs/testmods_dirs/eamxx/prod/yaml_outs/scream_output.decadal.6hourlyINST_native.yaml similarity index 100% rename from components/eamxx/cime_config/testdefs/testmods_dirs/scream/v1prod/yaml_outs/scream_output.decadal.6hourlyINST_native.yaml rename to components/eamxx/cime_config/testdefs/testmods_dirs/eamxx/prod/yaml_outs/scream_output.decadal.6hourlyINST_native.yaml diff --git a/components/eamxx/cime_config/testdefs/testmods_dirs/scream/v1prod/yaml_outs/scream_output.decadal.dailyAVG_coarse.yaml b/components/eamxx/cime_config/testdefs/testmods_dirs/eamxx/prod/yaml_outs/scream_output.decadal.dailyAVG_coarse.yaml similarity index 100% rename from components/eamxx/cime_config/testdefs/testmods_dirs/scream/v1prod/yaml_outs/scream_output.decadal.dailyAVG_coarse.yaml rename to components/eamxx/cime_config/testdefs/testmods_dirs/eamxx/prod/yaml_outs/scream_output.decadal.dailyAVG_coarse.yaml From 71326bde3bebf5569cc050adc65b7ce2cbd69b10 Mon Sep 17 00:00:00 2001 From: James Foucar Date: Wed, 4 Sep 2024 10:14:27 -0600 Subject: [PATCH 382/451] Another fix for CIME mvk and pgn --- cime | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cime b/cime index 52787427846e..2a3142fc14b1 160000 --- a/cime +++ b/cime @@ -1 +1 @@ -Subproject commit 52787427846eec58038ab59664fd9c2706f23513 +Subproject commit 2a3142fc14b18fd58379f98d7d2a9a8b4b0d43a8 From 72cebf6f1c6b70efdada9d7907f49c885d0a2f71 Mon Sep 17 00:00:00 2001 From: noel Date: Wed, 4 Sep 2024 10:26:32 -0700 Subject: [PATCH 383/451] fix white spaces only. see next commit for real change --- components/eam/src/dynamics/se/dyn_grid.F90 | 130 ++++++++++---------- 1 file changed, 65 insertions(+), 65 deletions(-) diff --git a/components/eam/src/dynamics/se/dyn_grid.F90 b/components/eam/src/dynamics/se/dyn_grid.F90 index c39b3aea7301..6294fafe20f1 100644 --- a/components/eam/src/dynamics/se/dyn_grid.F90 +++ b/components/eam/src/dynamics/se/dyn_grid.F90 @@ -1,28 +1,28 @@ module dyn_grid - !------------------------------------------------------------------------------------------------- - ! + !------------------------------------------------------------------------------------------------- + ! ! Purpose: Definition of dynamics computational grid. - ! - ! The grid used by the SE dynamics is called the GLL grid, which is - ! made up up of elements that correspond to "blocks". The columns + ! + ! The grid used by the SE dynamics is called the GLL grid, which is + ! made up up of elements that correspond to "blocks". The columns ! within each element are located at the Gauss-Lobatto-Legendre (GLL) ! quadrature points. The GLL nodes can be used as the physics columns ! as well, but this can lead to grid imprinting. The physics can also - ! be done on a quasi-equal area FV grid when fv_nphys>0, which will + ! be done on a quasi-equal area FV grid when fv_nphys>0, which will ! define fv_nphys^2 cells per element. - ! + ! ! Method: Variables are private; interface routines used to extract ! information for use in user code. Global column index range - ! defined using full (unreduced) grid. - ! + ! defined using full (unreduced) grid. + ! ! Entry points: - ! get_block_bounds_d get first and last indices in global + ! get_block_bounds_d get first and last indices in global ! block ordering ! get_block_gcol_d get column indices for given block ! get_block_gcol_cnt_d get number of columns in given block ! get_block_lvl_cnt_d get number of vertical levels in column ! get_block_levels_d get vertical levels in column - ! get_gcol_block_d get global block indices and local columns + ! get_gcol_block_d get global block indices and local columns ! index for given global column index ! get_gcol_block_cnt_d get number of blocks containing data ! from a given global column index @@ -31,14 +31,14 @@ module dyn_grid ! information ! get_horiz_grid_dim_d get horizontal dimensions of dynamics grid ! dyn_grid_get_pref get reference pressures for the dynamics grid - ! dyn_grid_get_elem_coords get coordinates of a specified block element + ! dyn_grid_get_elem_coords get coordinates of a specified block element ! of the dynamics grid ! dyn_grid_find_gcols finds nearest column for given lat/lon - ! dyn_grid_get_colndx get element block/column and MPI process indices + ! dyn_grid_get_colndx get element block/column and MPI process indices ! corresponding to a specified global column index ! ! Author: Jim Edwards and Patrick Worley - ! + ! !------------------------------------------------------------------------------------------------- use element_mod, only: element_t use cam_logfile, only: iulog @@ -60,7 +60,7 @@ module dyn_grid integer, parameter, public :: physgrid_d = 102 ! FV physics grid resolution (physics on GLL grid if NPG=0) - integer, parameter, public :: fv_nphys = NPG + integer, parameter, public :: fv_nphys = NPG integer :: ngcols_d = 0 ! number of dynamics columns logical :: gblocks_need_initialized = .true. @@ -113,9 +113,9 @@ end subroutine dyn_grid_init !================================================================================================= ! subroutine get_block_bounds_d(block_first,block_last) - !--------------------------------------------------------------------------- + !--------------------------------------------------------------------------- ! Purpose: Return first and last indices used in global block ordering - ! + ! ! Author: Jim Edwards !------------------------------Arguments------------------------------------ integer, intent(out) :: block_first ! first (global) index used for blocks @@ -129,9 +129,9 @@ end subroutine get_block_bounds_d !================================================================================================= ! subroutine get_block_gcol_d(blockid,size,cdex) - !--------------------------------------------------------------------------- + !--------------------------------------------------------------------------- ! Purpose: Return list of dynamics column indices in given block - ! + ! ! Author: Jim Edwards !--------------------------------------------------------------------------- implicit none @@ -160,9 +160,9 @@ end subroutine get_block_gcol_d !================================================================================================= ! integer function get_block_gcol_cnt_d(blockid) - !--------------------------------------------------------------------------- + !--------------------------------------------------------------------------- ! Purpose: Return number of dynamics columns in indicated block - ! + ! ! Author: Jim Edwards !------------------------------Arguments------------------------------------ integer, intent(in) :: blockid @@ -243,11 +243,11 @@ subroutine get_gcol_block_d(gcol, cnt, blockid, bcid, localblockid) use kinds, only: int_kind use cam_abortutils, only: endrun !--------------------------------------------------------------------------- - ! Purpose: Return global block index and local column index for + ! Purpose: Return global block index and local column index for ! global column index. Element array is naturally ordered. - ! + ! ! Author: Jim Edwards - ! Modified: replaced linear search with best guess and binary search + ! Modified: replaced linear search with best guess and binary search ! (Pat Worley, 7/2/09) !--------------------------------------------------------------------------- implicit none @@ -378,7 +378,7 @@ integer function get_gcol_block_cnt_d(gcol) !--------------------------------------------------------------------------- ! Purpose: Return number of blocks contain data for the vertical column ! with the given global column index - ! + ! ! Author: Patrick Worley !--------------------------------------------------------------------------- implicit none @@ -392,9 +392,9 @@ end function get_gcol_block_cnt_d !================================================================================================= ! integer function get_block_owner_d(blockid) - !--------------------------------------------------------------------------- + !--------------------------------------------------------------------------- ! Purpose: Return id of processor that "owns" the indicated block - ! + ! ! Author: Jim Edwards !--------------------------------------------------------------------------- implicit none @@ -402,7 +402,7 @@ integer function get_block_owner_d(blockid) integer, intent(in) :: blockid ! global block id !--------------------------------------------------------------------------- if (gblocks_need_initialized) call gblocks_init() - + if (gblocks(blockid)%Owner>-1) then get_block_owner_d=gblocks(blockid)%Owner else @@ -419,7 +419,7 @@ subroutine get_horiz_grid_dim_d(hdim1_d,hdim2_d) ! Purpose: Returns declared horizontal dimensions of computational grid. ! For non-lon/lat grids, declare grid to be one-dimensional, ! i.e., (ngcols_d x 1) - ! + ! ! Author: Patrick Worley !------------------------------Arguments------------------------------------ integer, intent(out) :: hdim1_d ! first horizontal dimension @@ -430,7 +430,7 @@ subroutine get_horiz_grid_dim_d(hdim1_d,hdim2_d) else hdim1_d = ngcols_d end if ! fv_nphys > 0 - + if (present(hdim2_d)) hdim2_d = 1 return @@ -441,7 +441,7 @@ end subroutine get_horiz_grid_dim_d subroutine set_horiz_grid_cnt_d(NumUniqueCols) !--------------------------------------------------------------------------- ! Purpose: Set number of columns in the dynamics computational grid - ! + ! ! Author: Jim Edwards !--------------------------------------------------------------------------- use dimensions_mod, only: nelem, nelemd, np, npsq @@ -454,7 +454,7 @@ subroutine set_horiz_grid_cnt_d(NumUniqueCols) integer :: ie, i, j, ii logical, save :: local_coords_initialized = .false. real(r8) :: areaw(np, np) - type(index_t), pointer :: idx + type(index_t), pointer :: idx !--------------------------------------------------------------------------- if (.not. local_coords_initialized) then ngcols_d = NumUniqueCols @@ -463,12 +463,12 @@ subroutine set_horiz_grid_cnt_d(NumUniqueCols) call endrun('set_horiz_grid_cnt_d: fdofp_local already defined') end if allocate(fdofp_local(npsq, nelemd)) - fdofp_local =0 + fdofp_local =0 do ie = 1, nelemd idx => elem(ie)%idxP do ii = 1, idx%NumUniquePts i = idx%ia(ii) - j = idx%ja(ii) + j = idx%ja(ii) fdofp_local((np*(j-1))+i,ie) = (idx%UniquePtoffset+ii-1) end do end do @@ -480,7 +480,7 @@ subroutine set_horiz_grid_cnt_d(NumUniqueCols) ! Now, fill in the appropriate values ii = 1 do ie = 1, nelemd - areaw = 1.0_r8 / elem(ie)%rspheremp(:,:) + areaw = 1.0_r8 / elem(ie)%rspheremp(:,:) pearea(ii:ii+npsq-1) = reshape(areaw, (/ np*np /)) pemap(ii:ii+npsq-1) = fdofp_local(:,ie) do j = 1, np @@ -503,14 +503,14 @@ end subroutine set_horiz_grid_cnt_d ! subroutine get_horiz_grid_d(nxy,clat_d_out,clon_d_out,area_d_out, & wght_d_out,lat_d_out,lon_d_out,cost_d_out) - !--------------------------------------------------------------------------- + !--------------------------------------------------------------------------- ! Purpose: Return latitude and longitude (in radians), column surface ! area (in radians squared) and surface integration weights ! for global column indices that will be passed to/from - ! physics. Optionally also return estimated physics - ! computational cost per global column for use in load + ! physics. Optionally also return estimated physics + ! computational cost per global column for use in load ! balancing. - ! + ! ! Author: Jim Edwards !------------------------------Arguments------------------------------------ integer, intent(in ) :: nxy ! array sizes @@ -572,7 +572,7 @@ subroutine get_horiz_grid_d(nxy,clat_d_out,clon_d_out,area_d_out, & end if if ( present(clat_d_out) .or. present(clon_d_out) ) then - + allocate( lat_d_rad_temp(nxy) ) allocate( lon_d_rad_temp(nxy) ) allocate( lat_d_deg_temp(nxy) ) @@ -628,7 +628,7 @@ subroutine define_cam_grids() !--------------------------------------------------------------------------- ! Create grid for data on HOMME GLL nodes !--------------------------------------------------------------------------- - ! When the FV physs grid is used the GLL grid output + ! When the FV physs grid is used the GLL grid output ! variables will use coordinates with the '_d' suffix. gridname = 'GLL' if (fv_nphys > 0) then @@ -670,7 +670,7 @@ subroutine define_cam_grids() call cam_grid_attribute_register(trim(gridname), trim(areaname), & 'gll grid areas', trim(ncolname), pearea, pemap) else - ! if single column model, then this attribute has to be handled + ! if single column model, then this attribute has to be handled ! by assigning just the SCM point. Else, the model will bomb out ! when writing the header information to history output area_scm(1) = 1.0_r8 / elem(1)%rspheremp(1,1) @@ -687,15 +687,15 @@ subroutine define_cam_grids() deallocate(pelon_deg) ! These can be nullified since the grid object has the reference - nullify(grid_map_d) + nullify(grid_map_d) nullify(pearea) nullify(pemap) !--------------------------------------------------------------------------- ! Create grid object for physics grid on the dynamics decomposition !--------------------------------------------------------------------------- - ! Following CAM6-SE the 'physgrid_d' grid is created and used to load the - ! PHIS field (i.e. surface topo) on the FV physics grid and then + ! Following CAM6-SE the 'physgrid_d' grid is created and used to load the + ! PHIS field (i.e. surface topo) on the FV physics grid and then ! interpolated to the GLL grid. This ensures consistent treatment of SGH. if (fv_nphys>0) then @@ -822,13 +822,13 @@ subroutine gblocks_init() end do end if - do ie = 1,nelemdmax + do ie = 1,nelemdmax if (ie<=nelemd) then rdispls(iam+1)=elem(ie)%idxP%UniquePtOffset-1 gid(iam+1)=elem(ie)%GlobalID lid(iam+1)=ie recvcounts(iam+1)=elem(ie)%idxP%NumUniquePts - else + else rdispls(iam+1) = 0 recvcounts(iam+1) = 0 gid(iam+1)=0 @@ -882,7 +882,7 @@ subroutine compute_global_area(area_d) end if if (fv_nphys > 0) then - + ncol_fv_gbl = fv_nphys*fv_nphys*nelem ncol_fv_lcl = fv_nphys*fv_nphys*nelemd allocate(rbuf(ncol_fv_gbl)) @@ -948,14 +948,14 @@ subroutine compute_global_area(area_d) deallocate(col_id_global) else ! physics is on GLL grid - + allocate(rbuf(ngcols_d)) - do ie = 1, nelemdmax + do ie = 1, nelemdmax if(ie <= nelemd) then displace(iam+1) = elem(ie)%idxp%UniquePtOffset-1 recvcnts(iam+1) = elem(ie)%idxP%NumUniquePts eb = displace(iam+1) + elem(ie)%idxp%NumUniquePts - areaw = 1.0_r8 / elem(ie)%rspheremp(:,:) + areaw = 1.0_r8 / elem(ie)%rspheremp(:,:) call UniquePoints(elem(ie)%idxP, areaw, area_d(displace(iam+1)+1:eb)) else displace(iam+1) = 0 @@ -1065,7 +1065,7 @@ subroutine compute_global_coords(clat, clon, lat_out, lon_out, corner_lat_out, c ! Gather global latitudes call mpi_allgatherv( lat_rad_local(:), recvcnts(iam+1), mpi_real8, rbuf, & recvcnts(:), displace(:), mpi_real8, mpicom, ierr) - + ! sort latitude according to global element ID do icol = 1,ncol_fv_gbl clat( col_id_global(icol) ) = rbuf(icol) @@ -1074,7 +1074,7 @@ subroutine compute_global_coords(clat, clon, lat_out, lon_out, corner_lat_out, c ! Gather global longitudes call mpi_allgatherv( lon_rad_local(:), recvcnts(iam+1), mpi_real8, rbuf, & recvcnts(:), displace(:), mpi_real8, mpicom, ierr) - + ! sort longitude according to global element ID do icol = 1,ncol_fv_gbl clon( col_id_global(icol) ) = rbuf(icol) @@ -1107,14 +1107,14 @@ subroutine compute_global_coords(clat, clon, lat_out, lon_out, corner_lat_out, c ! Gather latitude call mpi_allgatherv( corner_lat_rad_local(:,c), recvcnts(iam+1), mpi_real8, rbuf, & recvcnts(:), displace(:), mpi_real8, mpicom, ierr) - ! sort latitude + ! sort latitude do icol = 1,ncol_fv_gbl corner_lat_out( col_id_global(icol), c) = rbuf(icol) * rad2deg end do ! Gather longitude call mpi_allgatherv( corner_lon_rad_local(:,c), recvcnts(iam+1), mpi_real8, rbuf, & recvcnts(:), displace(:), mpi_real8, mpicom, ierr) - ! sort longitude + ! sort longitude do icol = 1,ncol_fv_gbl corner_lon_out( col_id_global(icol), c) = rbuf(icol) * rad2deg end do @@ -1179,7 +1179,7 @@ subroutine compute_global_coords(clat, clon, lat_out, lon_out, corner_lat_out, c call mpi_allgatherv(rbuf, recvcnts(iam+1), mpi_real8, clat, & recvcnts(:), displace(:), mpi_real8, mpicom, ierr) if (present(lat_out)) then - rbuf(1:recvcnts(iam+1)) = lat_out(sb:eb) + rbuf(1:recvcnts(iam+1)) = lat_out(sb:eb) call mpi_allgatherv(rbuf, recvcnts(iam+1), mpi_real8, lat_out, & recvcnts(:), displace(:), mpi_real8, mpicom, ierr) end if @@ -1188,12 +1188,12 @@ subroutine compute_global_coords(clat, clon, lat_out, lon_out, corner_lat_out, c call mpi_allgatherv(rbuf, recvcnts(iam+1), mpi_real8, clon, & recvcnts(:), displace(:), mpi_real8, mpicom, ierr) if (present(lon_out)) then - rbuf(1:recvcnts(iam+1)) = lon_out(sb:eb) + rbuf(1:recvcnts(iam+1)) = lon_out(sb:eb) call mpi_allgatherv(rbuf, recvcnts(iam+1), mpi_real8, lon_out, & recvcnts(:), displace(:), mpi_real8, mpicom, ierr) end if end do - + deallocate(rbuf) end if ! fv_nphys > 0 @@ -1275,7 +1275,7 @@ integer function get_dyn_grid_parm(name) result(ival) ival = fv_nphys*fv_nphys*nelem else ival = ngcols_d - end if + end if else if(name.eq.'plev') then ival = plev else if(name.eq.'plevp') then @@ -1318,10 +1318,10 @@ end subroutine dyn_grid_get_pref ! !================================================================================================= ! - subroutine dyn_grid_find_gcols( lat, lon, nclosest, owners, col, lbk, rlat, rlon, idyn_dists ) + subroutine dyn_grid_find_gcols( lat, lon, nclosest, owners, col, lbk, rlat, rlon, idyn_dists ) !--------------------------------------------------------------------------- - ! This returns the lat/lon information (and corresponding MPI task - ! numbers (owners)) of the global model grid columns nearest to the + ! This returns the lat/lon information (and corresponding MPI task + ! numbers (owners)) of the global model grid columns nearest to the ! input satellite coordinate (lat,lon) !--------------------------------------------------------------------------- use shr_const_mod, only: SHR_CONST_REARTH @@ -1415,7 +1415,7 @@ end subroutine dyn_grid_find_gcols ! !================================================================================================= ! - subroutine dyn_grid_get_colndx( igcol, nclosest, owners, col, lbk ) + subroutine dyn_grid_get_colndx( igcol, nclosest, owners, col, lbk ) !------------------------------Arguments------------------------------------ integer, intent(in) :: nclosest integer, intent(in) :: igcol(nclosest) @@ -1437,7 +1437,7 @@ subroutine dyn_grid_get_colndx( igcol, nclosest, owners, col, lbk ) call get_gcol_block_d( igcol(i), 1, blockid, bcid, lclblockid ) owners(i) = get_block_owner_d(blockid(1)) - + if (owners(i)==iam) then lbk(i) = lclblockid(1) ii = igcol(i)-elem(lbk(i))%idxp%UniquePtoffset+1 @@ -1448,7 +1448,7 @@ subroutine dyn_grid_get_colndx( igcol, nclosest, owners, col, lbk ) lbk(i) = -1 col(i) = -1 endif - + end do end subroutine dyn_grid_get_colndx From f0fa68c522af80e8390c69189fa5afa733179432 Mon Sep 17 00:00:00 2001 From: noel Date: Wed, 4 Sep 2024 10:30:29 -0700 Subject: [PATCH 384/451] create and use a module scope pointer to hold area for SCM that will survive until writing to netcdf file --- components/eam/src/dynamics/se/dyn_grid.F90 | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/components/eam/src/dynamics/se/dyn_grid.F90 b/components/eam/src/dynamics/se/dyn_grid.F90 index 6294fafe20f1..0faed9ea1d32 100644 --- a/components/eam/src/dynamics/se/dyn_grid.F90 +++ b/components/eam/src/dynamics/se/dyn_grid.F90 @@ -101,6 +101,7 @@ module dyn_grid real(r8), allocatable :: pelon_deg(:) ! pe-local longitudes (degrees) real(r8), pointer :: pearea(:) => null() ! pe-local areas integer(iMap), pointer :: pemap(:) => null() ! pe-local map for PIO decomp + real(r8), pointer :: pearea_scm(:) => null() ! special case: area for SCM (only 1 value) !=================================================================================================== contains @@ -618,7 +619,7 @@ subroutine define_cam_grids() integer(iMap), pointer :: grid_map_d(:,:) integer(iMap), pointer :: grid_map_p(:,:) integer :: ie, i, j, k, mapind ! Loop variables - real(r8) :: area_scm(1), lat, lon + real(r8) :: lat, lon integer :: ncols_p_lcl ! local column count integer :: ncols_p_gbl ! global column count integer(iMap), pointer :: physgrid_map(:) @@ -670,12 +671,13 @@ subroutine define_cam_grids() call cam_grid_attribute_register(trim(gridname), trim(areaname), & 'gll grid areas', trim(ncolname), pearea, pemap) else - ! if single column model, then this attribute has to be handled - ! by assigning just the SCM point. Else, the model will bomb out - ! when writing the header information to history output - area_scm(1) = 1.0_r8 / elem(1)%rspheremp(1,1) - call cam_grid_attribute_register(trim(gridname), trim(areaname), & - 'gll grid areas', trim(ncolname), area_scm) + ! If single column model, set pearea_scm(1) to be the area. + ! Then register attribute in same way as non-SCM to simplify. + allocate(pearea_scm(1)) + pearea_scm(1) = 1.0_r8 / elem(1)%rspheremp(1,1) + call cam_grid_attribute_register(trim(gridname), trim(areaname), & + 'gll grid areas', trim(ncolname), pearea_scm, pemap) + nullify(pearea_scm) end if ! .not. single_column call cam_grid_attribute_register(trim(gridname), 'np', '', np) From 04933000cb9e2390e5e2231ccba64fd49795e3f4 Mon Sep 17 00:00:00 2001 From: Robert Jacob Date: Wed, 4 Sep 2024 14:52:58 -0500 Subject: [PATCH 385/451] Add single forcing table Add table explaining what is fixed and what is varying in the single forcing compsets. --- docs/user-guide/index.md | 23 +++++++++++++++++++++-- 1 file changed, 21 insertions(+), 2 deletions(-) diff --git a/docs/user-guide/index.md b/docs/user-guide/index.md index 8674926526e9..25d2d1c74c07 100644 --- a/docs/user-guide/index.md +++ b/docs/user-guide/index.md @@ -24,7 +24,7 @@ is available. A *fully coupled* compset is one which has active components for at least the atmosphere, ocean, land surface, ocean and sea-ice all interacting. Each compset is associated with a specific forcing condition. -Coupled compsets in E3SM are developed for three science-driven simulation campaigns: `water cycle change and impacts`, `human-earth system feedbacks`, and `polar processes, sea-level rise and coastal impacts`. The standard coupled configurations -- which consist of prognostic atmosphere, land, river, ocean and sea-ice components -- form the base physical coupled system and are mainly designed for `water cycle change and impacts` simulation campaign. +Coupled compsets in E3SM are developed for three science-driven simulation campaigns: **water cycle change and impacts**, **human-earth system feedbacks**, and **polar processes, sea-level rise and coastal impacts**. The standard coupled configurations -- which consist of prognostic atmosphere, land, river, ocean and sea-ice components -- form the base physical coupled system and are mainly designed for `water cycle change and impacts` simulation campaign. Below list the standard configuration compsets supported in the current version of E3SM: |Compset alias | Description | @@ -37,7 +37,7 @@ Below list the standard configuration compsets supported in the current version |`WCYCLSSP245` | Standard configuration with prescribed SSP-245 forcings | |`WCYCLSSP370` | Standard configuration with prescribed SSP-370 forcings | |`WCYCLSSP585` | Standard configuration with prescribed SSP-585 forcings | -| | #### Compsets for single-forcings simulations of the historical period (1850-2014) | +| | **Compsets for single-forcings simulations of the historical period (1850-2014)** | |`WCYCL20TR-GHG` | Greenhouse gases only configuration (`GHGs`)| |`WCYCL20TR-aer` | Anthropogenic aerosols and precursors only configuration (`aer`)| |`WCYCL20TR-xGHG-xaer` | All forcings except GHGs and aer (`solar irradiance, stratospheric ozone and volcanic emissions, land use land cover`) | @@ -47,6 +47,25 @@ Below list the standard configuration compsets supported in the current version |`WCYCL20TR-lulc` | Land use land cover only configuration | |`WCYCL20TR-volc` | Stratospheric volcanic emissions only configuration | +The table below specifies which forcing category is fixed at 1850 conditions and which are allowed to vary over the historical period +for each of the historical ("20TR") compsets including the single-forcing compsets. + +|Compset alias | GHGs | Aerosol & precursors | Oxidants | Ozone (CI & Linoz) | Volcano | Solar | Land Use & ndep/popdensa | +|:------------ |:-----: | :---: | :---: | :---: | :---: | :---: | :---: | +|`WCYCL20TR` | varying | varying | varying | varying | varying | varying | varying | +|`WCYCL20TR-GHG`| varying | 1850 | 1850 | 1850 | 1850 | 1850 | 1850 | +|`WCYCL20TR-aer`| 1850 | varying | varying | 1850 | 1850 | 1850 | 1850 | +|`WCYCL20TR-xGHG-xaer`| 1850 | 1850 | 1850 | varying | varying | varying | varying | +|`WCYCL20TR-xaer`| varying | 1850 | 1850 | varying | varying | varying | varying | +|`WCYCL20TR-nat`| 1850 | 1850 | 1850 | 1850 | varying | varying | 1850 | +|`WCYCL20TR-ozone`| 1850 | 1850 | 1850 | varying | 1850 | 1850 | 1850 | +|`WCYCL20TR-lulc`| 1850 | 1850 | 1850 | 1850 | 1850 | 1850 | varying | +|`WCYCL20TR-volc`| 1850 | 1850 | 1850 | 1850 | varying | 1850 | 1850 | + + +- *Volcano* refers to stratospheric volcanic SO2 emissions; *1850* for *Volcano refers to background (average) stratospheric volcanic emissions used in pre-industrial control experiments +- *Oxidants* always follow *Aerosol & precursors* for fixed or varying. + The compsets for the other two science simulation campaigns are being finalized, with additional components and/or features. The compset naming follows the same convention, e.g., `CRYO1850` and `CRYO1850-4xCO2` are with prognostic ice-shelf melt fluxes for the `polar processes` simulation campaign. From 344bacac97aa21aa158bce89d1680241be3079df Mon Sep 17 00:00:00 2001 From: Robert Jacob Date: Wed, 4 Sep 2024 15:16:50 -0500 Subject: [PATCH 386/451] Fix linting of markdown Fix linting of markdown --- docs/user-guide/index.md | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/docs/user-guide/index.md b/docs/user-guide/index.md index 25d2d1c74c07..53fa28d64e25 100644 --- a/docs/user-guide/index.md +++ b/docs/user-guide/index.md @@ -62,8 +62,9 @@ for each of the historical ("20TR") compsets including the single-forcing compse |`WCYCL20TR-lulc`| 1850 | 1850 | 1850 | 1850 | 1850 | 1850 | varying | |`WCYCL20TR-volc`| 1850 | 1850 | 1850 | 1850 | varying | 1850 | 1850 | - -- *Volcano* refers to stratospheric volcanic SO2 emissions; *1850* for *Volcano refers to background (average) stratospheric volcanic emissions used in pre-industrial control experiments + +- *Volcano* refers to stratospheric volcanic SO2 emissions; *1850* for *Volcano* refers to background (average) stratospheric volcanic emissions used in pre-industrial control experiments + - *Oxidants* always follow *Aerosol & precursors* for fixed or varying. The compsets for the other two science simulation campaigns are being finalized, with additional components and/or features. From c23345d82da5667a9ebaacf05a7f1d87a7789fbb Mon Sep 17 00:00:00 2001 From: noel Date: Wed, 4 Sep 2024 13:20:22 -0700 Subject: [PATCH 387/451] use different routine signature -- tested correct what looks like an incorrect if conditional for scm and convert it to positive. only nullify is scm --- components/eam/src/dynamics/se/dyn_grid.F90 | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) diff --git a/components/eam/src/dynamics/se/dyn_grid.F90 b/components/eam/src/dynamics/se/dyn_grid.F90 index 0faed9ea1d32..125cfbca7a60 100644 --- a/components/eam/src/dynamics/se/dyn_grid.F90 +++ b/components/eam/src/dynamics/se/dyn_grid.F90 @@ -667,17 +667,16 @@ subroutine define_cam_grids() ! The native HOMME GLL grid call cam_grid_register(trim(gridname), dyn_decomp, lat_coord, lon_coord, & grid_map_d,block_indexed=.false., unstruct=.true.) - if (.not.single_column .or. scm_multcols) then - call cam_grid_attribute_register(trim(gridname), trim(areaname), & - 'gll grid areas', trim(ncolname), pearea, pemap) - else - ! If single column model, set pearea_scm(1) to be the area. - ! Then register attribute in same way as non-SCM to simplify. + if (single_column .or. scm_multcols) then + ! If single column model, set pearea_scm(1) to be the area as 1 value to simplify allocate(pearea_scm(1)) pearea_scm(1) = 1.0_r8 / elem(1)%rspheremp(1,1) call cam_grid_attribute_register(trim(gridname), trim(areaname), & - 'gll grid areas', trim(ncolname), pearea_scm, pemap) - nullify(pearea_scm) + 'gll grid areas', trim(ncolname), pearea_scm) + else + call cam_grid_attribute_register(trim(gridname), trim(areaname), & + 'gll grid areas', trim(ncolname), pearea, pemap) + end if ! .not. single_column call cam_grid_attribute_register(trim(gridname), 'np', '', np) @@ -692,6 +691,9 @@ subroutine define_cam_grids() nullify(grid_map_d) nullify(pearea) nullify(pemap) + if (single_column .or. scm_multcols) then + nullify(pearea_scm) + endif !--------------------------------------------------------------------------- ! Create grid object for physics grid on the dynamics decomposition From 25fe7324339bc2aef8a4b9f37b84d72ca5a21350 Mon Sep 17 00:00:00 2001 From: Youngsung Kim Date: Wed, 7 Aug 2024 13:30:47 -0400 Subject: [PATCH 388/451] Update Frontier machine/compilers following system update - Retain current software modules instead of updating to the latest versions. - Add linker options to use GCC 12.2, addressing linker errors. - Utilize Fortran linker to resolve additional linker errors. - Replace hipcc with mpicxx for MPICXX macro in the GPU compiler definitions. - Adjust compiler priority to prioritize reliability over performance. - Temporarily comment out ADIOS2 configurations --- .../cmake_macros/amdclang_frontier.cmake | 5 ++++- .../cmake_macros/amdclanggpu_frontier.cmake | 13 ++++++------- .../cmake_macros/crayclang_frontier.cmake | 2 ++ .../cmake_macros/crayclanggpu_frontier.cmake | 11 +++++++---- .../machines/cmake_macros/gnu_frontier.cmake | 5 +++++ .../machines/cmake_macros/gnugpu_frontier.cmake | 16 +++++++++++----- cime_config/machines/config_machines.xml | 14 ++++++++------ 7 files changed, 43 insertions(+), 23 deletions(-) diff --git a/cime_config/machines/cmake_macros/amdclang_frontier.cmake b/cime_config/machines/cmake_macros/amdclang_frontier.cmake index 2df5074d11f3..3727164933dc 100644 --- a/cime_config/machines/cmake_macros/amdclang_frontier.cmake +++ b/cime_config/machines/cmake_macros/amdclang_frontier.cmake @@ -9,4 +9,7 @@ string(APPEND CPPDEFS " -DLINUX") if (COMP_NAME STREQUAL gptl) string(APPEND CPPDEFS " -DHAVE_NANOTIME -DBIT64 -DHAVE_SLASHPROC -DHAVE_COMM_F2C -DHAVE_TIMES -DHAVE_GETTIMEOFDAY") endif() -string(APPEND CMAKE_EXE_LINKER_FLAGS " -L$ENV{CRAY_LIBSCI_PREFIX_DIR}/lib -lsci_amd") +string(APPEND CMAKE_EXE_LINKER_FLAGS " -L/opt/cray/pe/gcc/12.2.0/snos/lib64 -lgfortran -lstdc++") + +# to support Fortran specific compiler intrinsic functions +set(E3SM_LINK_WITH_FORTRAN "TRUE") diff --git a/cime_config/machines/cmake_macros/amdclanggpu_frontier.cmake b/cime_config/machines/cmake_macros/amdclanggpu_frontier.cmake index 6f3c0074798e..4412ea0de7b3 100644 --- a/cime_config/machines/cmake_macros/amdclanggpu_frontier.cmake +++ b/cime_config/machines/cmake_macros/amdclanggpu_frontier.cmake @@ -1,8 +1,8 @@ set(MPICC "cc") -set(MPICXX "CC") +set(MPICXX "mpicxx") set(MPIFC "ftn") set(SCC "cc") -set(SCXX "CC") +set(SCXX "hipcc") set(SFC "ftn") string(APPEND CPPDEFS " -DLINUX") @@ -14,13 +14,12 @@ string(APPEND CMAKE_CXX_FLAGS_RELEASE " -O2") string(APPEND CMAKE_Fortran_FLAGS_RELEASE " -O2") string(APPEND SPIO_CMAKE_OPTS " -DPIO_ENABLE_TOOLS:BOOL=OFF") -string(APPEND CMAKE_EXE_LINKER_FLAGS " -L$ENV{CRAY_LIBSCI_PREFIX_DIR}/lib -lsci_amd") -set(MPICXX "hipcc") -set(SCXX "hipcc") -string(APPEND CMAKE_CXX_FLAGS " -I$ENV{MPICH_DIR}/include --offload-arch=gfx90a") -string(APPEND CMAKE_EXE_LINKER_FLAGS " -L$ENV{MPICH_DIR}/lib -lmpi -L$ENV{CRAY_MPICH_ROOTDIR}/gtl/lib -lmpi_gtl_hsa") +string(APPEND CMAKE_CXX_FLAGS " --offload-arch=gfx90a") +string(APPEND CMAKE_EXE_LINKER_FLAGS " -L$ENV{CRAY_MPICH_ROOTDIR}/gtl/lib -lmpi_gtl_hsa") +string(APPEND CMAKE_EXE_LINKER_FLAGS " -L/opt/cray/pe/gcc/12.2.0/snos/lib64 -lgfortran -lstdc++") string(APPEND KOKKOS_OPTIONS " -DKokkos_ENABLE_HIP=On -DKokkos_ARCH_ZEN3=On -DKokkos_ARCH_VEGA90A=On") set(USE_HIP "TRUE") string(APPEND CMAKE_HIP_FLAGS "${CXXFLAGS} -munsafe-fp-atomics -x hip") +set(E3SM_LINK_WITH_FORTRAN "TRUE") diff --git a/cime_config/machines/cmake_macros/crayclang_frontier.cmake b/cime_config/machines/cmake_macros/crayclang_frontier.cmake index 6c8d4164cb28..76ec41bdbe72 100644 --- a/cime_config/machines/cmake_macros/crayclang_frontier.cmake +++ b/cime_config/machines/cmake_macros/crayclang_frontier.cmake @@ -16,5 +16,7 @@ string(APPEND CMAKE_Fortran_FLAGS " -hipa0 -hzero") # Scorpio installs string(APPEND CMAKE_Fortran_FLAGS " -em -ef") +string(APPEND CMAKE_EXE_LINKER_FLAGS " -L/opt/cray/pe/gcc/12.2.0/snos/lib64 -lgfortran -lstdc++") + # to support Fortran specific compiler intrinsic functions set(E3SM_LINK_WITH_FORTRAN "TRUE") diff --git a/cime_config/machines/cmake_macros/crayclanggpu_frontier.cmake b/cime_config/machines/cmake_macros/crayclanggpu_frontier.cmake index 32f125947b5c..a37ccde439e5 100644 --- a/cime_config/machines/cmake_macros/crayclanggpu_frontier.cmake +++ b/cime_config/machines/cmake_macros/crayclanggpu_frontier.cmake @@ -1,5 +1,6 @@ set(MPICC "cc") -set(MPICXX "hipcc") +set(MPICXX "mpicxx") +#set(MPICXX "CC") set(MPIFC "ftn") set(SCC "cc") set(SCXX "hipcc") @@ -33,7 +34,7 @@ set(HAS_F2008_CONTIGUOUS "TRUE") # -Wl,--allow-shlib-undefined was added to address rocm 5.4.3 Fortran linker issue: # /opt/rocm-5.4.3/lib/libhsa-runtime64.so.1: undefined reference to `std::condition_variable::wait(std::unique_lock&)@GLIBCXX_3.4.30' # AMD started building with GCC 12.2.0, which brings in a GLIBCXX symbol that isn't in CCE's default GCC toolchain. -string(APPEND CMAKE_EXE_LINKER_FLAGS " -Wl,--allow-multiple-definition -Wl,--allow-shlib-undefined") +#string(APPEND CMAKE_EXE_LINKER_FLAGS " -Wl,--allow-multiple-definition -Wl,--allow-shlib-undefined") # Switching to O3 for performance benchmarking # Will revisit any failing tests @@ -53,11 +54,13 @@ string(APPEND CMAKE_Fortran_FLAGS " -hipa0 -hzero -em -ef -hnoacc") string(APPEND SPIO_CMAKE_OPTS " -DPIO_ENABLE_TOOLS:BOOL=OFF") -string(APPEND CMAKE_CXX_FLAGS " -I$ENV{MPICH_DIR}/include --offload-arch=gfx90a") -string(APPEND CMAKE_EXE_LINKER_FLAGS " -L$ENV{MPICH_DIR}/lib -lmpi -L$ENV{CRAY_MPICH_ROOTDIR}/gtl/lib -lmpi_gtl_hsa") +string(APPEND CMAKE_CXX_FLAGS " --offload-arch=gfx90a") +string(APPEND CMAKE_EXE_LINKER_FLAGS " -L$ENV{CRAY_MPICH_ROOTDIR}/gtl/lib -lmpi_gtl_hsa") string(APPEND CMAKE_EXE_LINKER_FLAGS " -L$ENV{ROCM_PATH}/lib -lamdhip64") +string(APPEND CMAKE_EXE_LINKER_FLAGS " -L/opt/cray/pe/gcc/12.2.0/snos/lib64 -lgfortran -lstdc++") string(APPEND KOKKOS_OPTIONS " -DKokkos_ENABLE_HIP=On -DKokkos_ARCH_ZEN3=On -DKokkos_ARCH_VEGA90A=On") set(USE_HIP "TRUE") string(APPEND CMAKE_HIP_FLAGS "${CXXFLAGS} -munsafe-fp-atomics -x hip") +set(E3SM_LINK_WITH_FORTRAN "TRUE") diff --git a/cime_config/machines/cmake_macros/gnu_frontier.cmake b/cime_config/machines/cmake_macros/gnu_frontier.cmake index 9b242243989b..ee44a2ca08f5 100644 --- a/cime_config/machines/cmake_macros/gnu_frontier.cmake +++ b/cime_config/machines/cmake_macros/gnu_frontier.cmake @@ -13,3 +13,8 @@ string(APPEND CMAKE_Fortran_FLAGS " -Wno-implicit-interface") string(APPEND CMAKE_Fortran_FLAGS_RELEASE " -O2") string(APPEND CMAKE_C_FLAGS_RELEASE " -O2") + +string(APPEND CMAKE_EXE_LINKER_FLAGS " -L/opt/cray/pe/gcc/12.2.0/snos/lib64 -lgfortran -lstdc++") + +# to support Fortran specific compiler intrinsic functions +set(E3SM_LINK_WITH_FORTRAN "TRUE") diff --git a/cime_config/machines/cmake_macros/gnugpu_frontier.cmake b/cime_config/machines/cmake_macros/gnugpu_frontier.cmake index 174f8207d0d0..6ca4b83d9c2f 100644 --- a/cime_config/machines/cmake_macros/gnugpu_frontier.cmake +++ b/cime_config/machines/cmake_macros/gnugpu_frontier.cmake @@ -1,6 +1,6 @@ set(MPICC "cc") -set(MPICXX "hipcc") # Needs MPICH_CXX to use hipcc -set(MPIFC "ftn") # Linker needs to be the Cray wrapper ftn, not mpif90 +set(MPICXX "mpicxx") +set(MPIFC "ftn") set(SCC "cc") set(SCXX "hipcc") set(SFC "ftn") @@ -16,11 +16,17 @@ string(APPEND CMAKE_CXX_FLAGS_RELEASE " -O2") string(APPEND CMAKE_Fortran_FLAGS_RELEASE " -O2") string(APPEND SPIO_CMAKE_OPTS " -DPIO_ENABLE_TOOLS:BOOL=OFF") -set(E3SM_LINK_WITH_FORTRAN "TRUE") -string(APPEND CMAKE_CXX_FLAGS " -I$ENV{MPICH_DIR}/include --offload-arch=gfx90a") -string(APPEND CMAKE_EXE_LINKER_FLAGS " -L/opt/cray/pe/gcc/11.2.0/snos/lib64/ -lgfortran -L/opt/rocm-5.4.0/lib -lhsa-runtime64 -L$ENV{MPICH_DIR}/lib -lmpi -L$ENV{CRAY_MPICH_ROOTDIR}/gtl/lib -lmpi_gtl_hsa ") +string(APPEND CMAKE_CXX_FLAGS " --offload-arch=gfx90a") +string(APPEND CMAKE_EXE_LINKER_FLAGS " -L$ENV{CRAY_MPICH_ROOTDIR}/gtl/lib -lmpi_gtl_hsa") +string(APPEND CMAKE_EXE_LINKER_FLAGS " -L$ENV{ROCM_PATH}/lib -lamdhip64") +string(APPEND CMAKE_EXE_LINKER_FLAGS " -L/opt/cray/pe/gcc/12.2.0/snos/lib64 -lgfortran -lstdc++") +# +#string(APPEND CMAKE_EXE_LINKER_FLAGS " -L/opt/rocm-5.4.0/lib -lhsa-runtime64 -L$ENV{CRAY_MPICH_ROOTDIR}/gtl/lib -lmpi_gtl_hsa ") string(APPEND KOKKOS_OPTIONS " -DKokkos_ENABLE_HIP=On -DKokkos_ARCH_ZEN3=On -DKokkos_ARCH_VEGA90A=On -DKokkos_ENABLE_OPENMP=Off") set(USE_HIP "TRUE") string(APPEND CMAKE_HIP_FLAGS "${CXXFLAGS} -munsafe-fp-atomics -x hip") + + +set(E3SM_LINK_WITH_FORTRAN "TRUE") diff --git a/cime_config/machines/config_machines.xml b/cime_config/machines/config_machines.xml index 6cd9d585a25b..2841df7200c7 100644 --- a/cime_config/machines/config_machines.xml +++ b/cime_config/machines/config_machines.xml @@ -980,7 +980,7 @@ Frontier exascale supercomputer at ORNL. 9408 nodes, Node: 4 AMD MI250X GPUs (2 GCDs) ~ 8 GPUs, 512 GB HDB2E, AMD EPYC 64 cores, 512GB DDR4 .*frontier.* Linux - crayclang,gnu,amdclang,gnugpu,crayclanggpu,amdclanggpu + gnu,amdclang,crayclang,gnugpu,amdclanggpu,crayclanggpu mpich cli115 /lustre/orion/cli115/world-shared/frontier @@ -1042,8 +1042,7 @@ PrgEnv-cray PrgEnv-gnu/8.3.3 - - gcc gcc/11.2.0 + gcc gcc/12.2.0 craype-accel-amd-gfx90a @@ -1051,6 +1050,7 @@ cray-python/3.9.13.1 + cray-libsci subversion/1.14.1 git/2.36.1 cmake/3.21.3 @@ -1066,14 +1066,12 @@ 0.25 0 + $ENV{CRAY_LIBSCI_PREFIX_DIR}/lib/pkgconfig:$ENV{PKG_CONFIG_PATH} $ENV{NETCDF_DIR} $ENV{PNETCDF_DIR} - - $ENV{CRAY_LIBSCI_DIR}/amd/4.0/x86_64/lib:$ENV{LD_LIBRARY_PATH} - --ntasks-per-gpu=$SHELL{echo "`./xmlquery --value MAX_MPITASKS_PER_NODE`/8"|bc} --gpu-bind=closest @@ -1090,6 +1088,9 @@ spread threads + From 8e6f5ecd8c5870d271790ddaedaa849b60fe7d89 Mon Sep 17 00:00:00 2001 From: Walter Hannah Date: Thu, 5 Sep 2024 13:23:32 -0500 Subject: [PATCH 389/451] remove CMIP6 from MMF compsets --- cime_config/allactive/config_compsets.xml | 6 +++--- components/eam/cime_config/config_compsets.xml | 4 ++-- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/cime_config/allactive/config_compsets.xml b/cime_config/allactive/config_compsets.xml index ace33ae09172..e66f1e473d85 100755 --- a/cime_config/allactive/config_compsets.xml +++ b/cime_config/allactive/config_compsets.xml @@ -133,18 +133,18 @@ WCYCL1950-MMF1 - 1950SOI_EAM%CMIP6-MMF1_ELM%SPBC_MPASSI_MPASO_MOSART_SGLC_SWAV + 1950SOI_EAM%MMF1_ELM%SPBC_MPASSI_MPASO_MOSART_SGLC_SWAV WCYCL20TR-MMF1 - 20TRSOI_EAM%CMIP6-MMF1_ELM%SP_MPASSI_MPASO_MOSART_SGLC_SWAV + 20TRSOI_EAM%MMF1_ELM%SP_MPASSI_MPASO_MOSART_SGLC_SWAV WCYCL20TRNS-MMF1 - 20TR_EAM%CMIP6-MMF1_ELM%SP_MPASSI_MPASO_MOSART_SGLC_SWAV + 20TR_EAM%MMF1_ELM%SP_MPASSI_MPASO_MOSART_SGLC_SWAV diff --git a/components/eam/cime_config/config_compsets.xml b/components/eam/cime_config/config_compsets.xml index 39971fbb0945..7050bd0c8f90 100644 --- a/components/eam/cime_config/config_compsets.xml +++ b/components/eam/cime_config/config_compsets.xml @@ -272,12 +272,12 @@ F20TR-MMF1 - 20TR_EAM%CMIP6-MMF1_ELM%SP_MPASSI%PRES_DOCN%DOM_MOSART_SGLC_SWAV + 20TR_EAM%MMF1_ELM%SP_MPASSI%PRES_DOCN%DOM_MOSART_SGLC_SWAV F20TR-MMF1 - 20TR_EAM%CMIP6-MMF2_ELM%SP_MPASSI%PRES_DOCN%DOM_MOSART_SGLC_SWAV + 20TR_EAM%MMF2_ELM%SP_MPASSI%PRES_DOCN%DOM_MOSART_SGLC_SWAV From e950299cd9e91622308d3a3318b33ee01025b700 Mon Sep 17 00:00:00 2001 From: Carolyn Begeman Date: Thu, 5 Sep 2024 17:00:26 -0500 Subject: [PATCH 390/451] Add eddy product AM to RRSwISC6to18 --- .../mpas-ocean/bld/namelist_files/namelist_defaults_mpaso.xml | 1 + 1 file changed, 1 insertion(+) diff --git a/components/mpas-ocean/bld/namelist_files/namelist_defaults_mpaso.xml b/components/mpas-ocean/bld/namelist_files/namelist_defaults_mpaso.xml index c7441c6b2214..64211f42c39f 100644 --- a/components/mpas-ocean/bld/namelist_files/namelist_defaults_mpaso.xml +++ b/components/mpas-ocean/bld/namelist_files/namelist_defaults_mpaso.xml @@ -1111,6 +1111,7 @@ .false. +.true. '0000-00-00_01:00:00' 'eddyProductVariablesOutput' .true. From f88f96472d48567aafab8a125048bc1e2d14996b Mon Sep 17 00:00:00 2001 From: Naser Mahfouz Date: Thu, 5 Sep 2024 13:35:14 -0400 Subject: [PATCH 391/451] update all actions to use major pins and minor other fixes --- .github/workflows/e3sm-gh-pages.yml | 6 +++--- .github/workflows/e3sm-gh-tools-mkatmsrffile-test.yml | 2 +- .github/workflows/eamxx-gh-pages.yml | 2 +- .github/workflows/eamxx_default_files.yml | 4 +++- 4 files changed, 8 insertions(+), 6 deletions(-) diff --git a/.github/workflows/e3sm-gh-pages.yml b/.github/workflows/e3sm-gh-pages.yml index 709fecc623ac..ebd2ac9c1e97 100644 --- a/.github/workflows/e3sm-gh-pages.yml +++ b/.github/workflows/e3sm-gh-pages.yml @@ -30,10 +30,10 @@ jobs: submodules: true - name: Show action trigger run: echo "= The job was automatically triggered by a ${{github.event_name}} event on repo ${{github.event.repository.name}}." - - name: Set up Python 3.10 - uses: actions/setup-python@v5.2.0 + - name: Set up Python 3.11 + uses: actions/setup-python@v5 with: - python-version: "3.10" + python-version: "3.11" - name: Install python deps run: python3 -m pip install mkdocs-material pymdown-extensions mkdocs-monorepo-plugin mdutils mkdocs-bibtex # build every time (PR or push to master) diff --git a/.github/workflows/e3sm-gh-tools-mkatmsrffile-test.yml b/.github/workflows/e3sm-gh-tools-mkatmsrffile-test.yml index 13b73e4df3f4..8fe212886d9f 100644 --- a/.github/workflows/e3sm-gh-tools-mkatmsrffile-test.yml +++ b/.github/workflows/e3sm-gh-tools-mkatmsrffile-test.yml @@ -79,7 +79,7 @@ jobs: GH_REPO: ${{ github.repository }} TITLE: mkatmsrffile test failure ASSIGNEES: whannah1 - LABELS: bug + LABELS: bug,notify-mkatmsrffile-gh-action BODY: | Workflow failed! There's likely an issue in the mkatmsrffile tool! For more information, please see: - Workflow URL: https://github.com/${{ github.repository }}/actions/runs/${{ github.run_id }} (number ${{ github.run_number }}, attempt ${{ github.run_attempt }}) diff --git a/.github/workflows/eamxx-gh-pages.yml b/.github/workflows/eamxx-gh-pages.yml index 7c9da3264d68..2ce70d97843c 100644 --- a/.github/workflows/eamxx-gh-pages.yml +++ b/.github/workflows/eamxx-gh-pages.yml @@ -54,7 +54,7 @@ jobs: echo "= The job was automatically triggered by a ${{github.event_name}} event." - name: Set up Python 3.11 - uses: actions/setup-python@v5.2.0 + uses: actions/setup-python@v5 with: python-version: "3.11" diff --git a/.github/workflows/eamxx_default_files.yml b/.github/workflows/eamxx_default_files.yml index fa84f9f96f01..950f335700ee 100644 --- a/.github/workflows/eamxx_default_files.yml +++ b/.github/workflows/eamxx_default_files.yml @@ -5,6 +5,8 @@ on: branches: [ master ] pull_request: branches: [ master ] + paths: + - 'components/eamxx/cime_config/namelist_defaults_scream.xml' schedule: - cron: '00 00 * * *' workflow_dispatch: @@ -21,7 +23,7 @@ jobs: show-progress: false submodules: false - name: Set up Python 3.11 - uses: actions/setup-python@v5.2.0 + uses: actions/setup-python@v5 with: python-version: "3.11" - name: Run unit tests From 835ca84d8a97613f9553b2203957b052caea7057 Mon Sep 17 00:00:00 2001 From: Walter Hannah Date: Fri, 6 Sep 2024 09:39:52 -0500 Subject: [PATCH 392/451] simplify CMIP6 physics default config for EAM --- components/eam/cime_config/config_component.xml | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/components/eam/cime_config/config_component.xml b/components/eam/cime_config/config_component.xml index 655d7be5503c..d20a8c400cc1 100755 --- a/components/eam/cime_config/config_component.xml +++ b/components/eam/cime_config/config_component.xml @@ -51,10 +51,7 @@ -mach $MACH -phys default - &eamv3_phys_defaults; &eamv3_chem_defaults; - &eamv3_phys_defaults; &eamv3_chem_defaults; - &eamv3_phys_defaults; &eamv3_chem_defaults; - &eamv3_phys_defaults; &eamv3_chem_defaults; + &eamv3_phys_defaults; &eamv3_chem_defaults; -bc_dep_to_snow_updates -co2_cycle From 8208d4bd376f0cb8b51658f077b3941121ec1d8d Mon Sep 17 00:00:00 2001 From: Walter Hannah Date: Fri, 6 Sep 2024 09:40:29 -0500 Subject: [PATCH 393/451] specify ELM use case for MMF transient compset --- components/elm/cime_config/config_component.xml | 1 + 1 file changed, 1 insertion(+) diff --git a/components/elm/cime_config/config_component.xml b/components/elm/cime_config/config_component.xml index 00518b5dc780..4e637ef55802 100755 --- a/components/elm/cime_config/config_component.xml +++ b/components/elm/cime_config/config_component.xml @@ -81,6 +81,7 @@ 20thC_CMIP6_transient 20thC_CMIP6_transient 20thC_CMIP6_transient + 20thC_CMIP6_transient 20thC_CMIP6bgc_transient 20thC_CMIP6bgc_transient 20thC_bgc_transient From c99179079aee1d1b793ecf07530252046e2e40d6 Mon Sep 17 00:00:00 2001 From: Oksana Guba Date: Thu, 5 Sep 2024 16:19:19 -0600 Subject: [PATCH 394/451] HOMME: add aurora, polaris, spot machine files --- .../homme/cmake/machineFiles/aurora-aot.cmake | 64 ++++++++++++++++ .../homme/cmake/machineFiles/aurora-jit.cmake | 58 +++++++++++++++ .../cmake/machineFiles/chrysalis-bfb.cmake | 2 + .../homme/cmake/machineFiles/chrysalis.cmake | 2 + .../homme/cmake/machineFiles/polaris-a100.sh | 74 +++++++++++++++++++ .../cmake/machineFiles/spot-aot-AB2.cmake | 63 ++++++++++++++++ 6 files changed, 263 insertions(+) create mode 100644 components/homme/cmake/machineFiles/aurora-aot.cmake create mode 100644 components/homme/cmake/machineFiles/aurora-jit.cmake create mode 100644 components/homme/cmake/machineFiles/polaris-a100.sh create mode 100644 components/homme/cmake/machineFiles/spot-aot-AB2.cmake diff --git a/components/homme/cmake/machineFiles/aurora-aot.cmake b/components/homme/cmake/machineFiles/aurora-aot.cmake new file mode 100644 index 000000000000..b6fe34a78d72 --- /dev/null +++ b/components/homme/cmake/machineFiles/aurora-aot.cmake @@ -0,0 +1,64 @@ +#module restore +#module load oneapi/eng-compiler/2022.12.30.005 +#module load intel_compute_runtime/release/agama-devel-627 +#module load spack cmake +#module list + + +SET (SUNSPOT_MACHINE TRUE CACHE BOOL "") + +SET(BUILD_HOMME_WITHOUT_PIOLIBRARY TRUE CACHE BOOL "") +SET(HOMMEXX_MPI_ON_DEVICE FALSE CACHE BOOL "") + +SET(HOMME_FIND_BLASLAPACK TRUE CACHE BOOL "") + +SET(WITH_PNETCDF FALSE CACHE FILEPATH "") + +SET(USE_QUEUING FALSE CACHE BOOL "") + +#temp hack +SET(HOMME_USE_KOKKOS TRUE CACHE BOOL "") + +SET(BUILD_HOMME_PREQX_KOKKOS TRUE CACHE BOOL "") +SET(BUILD_HOMME_THETA_KOKKOS TRUE CACHE BOOL "") + +#set(KOKKOS_HOME "/home/onguba/kokkos-build/mar05-aot/install" CACHE STRING "") +#set(E3SM_KOKKOS_PATH ${KOKKOS_HOME} CACHE STRING "") + +SET(USE_TRILINOS OFF CACHE BOOL "") + +SET(SYCL_BUILD TRUE CACHE BOOL "") +SET(HOMME_ENABLE_COMPOSE FALSE CACHE BOOL "") + +SET(CMAKE_CXX_STANDARD 17) + +SET(CMAKE_C_COMPILER "mpicc" CACHE STRING "") +SET(CMAKE_Fortran_COMPILER "mpifort" CACHE STRING "") +SET(CMAKE_CXX_COMPILER "mpicxx" CACHE STRING "") + +# -fsycl-link-huge-device-code for theta to get build +#JIT flags +#SET(SYCL_COMPILE_FLAGS "-std=c++17 -fsycl -fsycl-device-code-split=per_kernel -fno-sycl-id-queries-fit-in-int -fsycl-unnamed-lambda") +#SET(SYCL_LINK_FLAGS "-fsycl -fsycl-link-huge-device-code -fsycl-device-code-split=per_kernel -fsycl-targets=spir64") + +#AOT flags +SET(SYCL_COMPILE_FLAGS "-std=c++17 -fsycl -fsycl-device-code-split=per_kernel -fno-sycl-id-queries-fit-in-int -fsycl-unnamed-lambda") +SET(SYCL_LINK_FLAGS "-fsycl -fsycl-device-code-split=per_kernel -fsycl-link-huge-device-code -fsycl-targets=spir64_gen -Xsycl-target-backend \"-device 12.60.7\"") + +SET(ADD_Fortran_FLAGS "-fc=ifx -O3 -DNDEBUG -DCPRINTEL -g" CACHE STRING "") +SET(ADD_C_FLAGS "-O3 -DNDEBUG " CACHE STRING "") + +SET(ADD_CXX_FLAGS "-std=c++17 -O3 -DNDEBUG ${SYCL_COMPILE_FLAGS}" CACHE STRING "") +SET(ADD_LINKER_FLAGS "-O3 -DNDEBUG ${SYCL_LINK_FLAGS} -fortlib" CACHE STRING "") + +set (ENABLE_OPENMP OFF CACHE BOOL "") +set (ENABLE_COLUMN_OPENMP OFF CACHE BOOL "") +set (ENABLE_HORIZ_OPENMP OFF CACHE BOOL "") + +set (HOMME_TESTING_PROFILE "dev" CACHE STRING "") + +set (USE_NUM_PROCS 4 CACHE STRING "") + +SET (USE_MPI_OPTIONS "--bind-to core" CACHE FILEPATH "") + + diff --git a/components/homme/cmake/machineFiles/aurora-jit.cmake b/components/homme/cmake/machineFiles/aurora-jit.cmake new file mode 100644 index 000000000000..1941fa9eb3f3 --- /dev/null +++ b/components/homme/cmake/machineFiles/aurora-jit.cmake @@ -0,0 +1,58 @@ +#module restore +#module load oneapi/eng-compiler/2022.12.30.005 +#module load intel_compute_runtime/release/agama-devel-627 +#module load spack cmake +#module list + + + +SET(BUILD_HOMME_WITHOUT_PIOLIBRARY TRUE CACHE BOOL "") +SET(HOMMEXX_MPI_ON_DEVICE FALSE CACHE BOOL "") + +SET(HOMME_FIND_BLASLAPACK TRUE CACHE BOOL "") + +SET(WITH_PNETCDF FALSE CACHE FILEPATH "") + +SET(USE_QUEUING FALSE CACHE BOOL "") + +#temp hack +SET(HOMME_USE_KOKKOS TRUE CACHE BOOL "") + +SET(BUILD_HOMME_PREQX_KOKKOS TRUE CACHE BOOL "") +SET(BUILD_HOMME_THETA_KOKKOS TRUE CACHE BOOL "") + +#set(KOKKOS_HOME "/home/onguba/kokkos-build/jan03-2024/install" CACHE STRING "") +#set(E3SM_KOKKOS_PATH ${KOKKOS_HOME} CACHE STRING "") + +SET(USE_TRILINOS OFF CACHE BOOL "") + +SET(SYCL_BUILD TRUE CACHE BOOL "") +SET(HOMME_ENABLE_COMPOSE FALSE CACHE BOOL "") + +SET(CMAKE_CXX_STANDARD 17) + +SET(CMAKE_C_COMPILER "mpicc" CACHE STRING "") +SET(CMAKE_Fortran_COMPILER "mpifort" CACHE STRING "") +SET(CMAKE_CXX_COMPILER "mpicxx" CACHE STRING "") + +# -fsycl-link-huge-device-code for theta to get build +SET(SYCL_COMPILE_FLAGS "-std=c++17 -fsycl -fsycl-device-code-split=per_kernel -fno-sycl-id-queries-fit-in-int -fsycl-unnamed-lambda") +SET(SYCL_LINK_FLAGS "-fsycl -fsycl-link-huge-device-code -fsycl-device-code-split=per_kernel -fsycl-targets=spir64") + +SET(ADD_Fortran_FLAGS "-fc=ifx -O3 -DNDEBUG -DCPRINTEL -g" CACHE STRING "") +SET(ADD_C_FLAGS "-O3 -DNDEBUG " CACHE STRING "") + +SET(ADD_CXX_FLAGS "-std=c++17 -O3 -DNDEBUG ${SYCL_COMPILE_FLAGS}" CACHE STRING "") +SET(ADD_LINKER_FLAGS "-O3 -DNDEBUG ${SYCL_LINK_FLAGS} -fortlib" CACHE STRING "") + +set (ENABLE_OPENMP OFF CACHE BOOL "") +set (ENABLE_COLUMN_OPENMP OFF CACHE BOOL "") +set (ENABLE_HORIZ_OPENMP OFF CACHE BOOL "") + +set (HOMME_TESTING_PROFILE "dev" CACHE STRING "") + +set (USE_NUM_PROCS 4 CACHE STRING "") + +SET (USE_MPI_OPTIONS "--bind-to core" CACHE FILEPATH "") + + diff --git a/components/homme/cmake/machineFiles/chrysalis-bfb.cmake b/components/homme/cmake/machineFiles/chrysalis-bfb.cmake index b9f0d41a0606..fa1f1ac545c5 100644 --- a/components/homme/cmake/machineFiles/chrysalis-bfb.cmake +++ b/components/homme/cmake/machineFiles/chrysalis-bfb.cmake @@ -17,6 +17,8 @@ ENDIF() SET (USE_MPIEXEC "srun" CACHE STRING "") SET (USE_MPI_OPTIONS "-K --cpu_bind=cores" CACHE STRING "") +SET (CHRYSALIS_MACHINE TRUE CACHE BOOL "") + # Set kokkos arch, to get correct avx flags SET (Kokkos_ARCH_ZEN2 ON CACHE BOOL "") diff --git a/components/homme/cmake/machineFiles/chrysalis.cmake b/components/homme/cmake/machineFiles/chrysalis.cmake index 68ff76ec8082..97bc682c9546 100644 --- a/components/homme/cmake/machineFiles/chrysalis.cmake +++ b/components/homme/cmake/machineFiles/chrysalis.cmake @@ -17,6 +17,8 @@ ENDIF() SET (USE_MPIEXEC "srun" CACHE STRING "") SET (USE_MPI_OPTIONS "-K --cpu_bind=cores" CACHE STRING "") +SET (CHRYSALIS_MACHINE TRUE CACHE BOOL "") + # Set kokkos arch, to get correct avx flags SET (Kokkos_ARCH_ZEN2 ON CACHE BOOL "") diff --git a/components/homme/cmake/machineFiles/polaris-a100.sh b/components/homme/cmake/machineFiles/polaris-a100.sh new file mode 100644 index 000000000000..2b63c61a55e7 --- /dev/null +++ b/components/homme/cmake/machineFiles/polaris-a100.sh @@ -0,0 +1,74 @@ +#Currently Loaded Modules: +# 1) craype-x86-rome 6) craype/2.7.15 11) cray-libpals/1.1.7 16) nvhpc-mixed/21.9 +# 2) libfabric/1.11.0.4.125 7) cray-dsmml/0.2.2 12) PrgEnv-gnu/8.3.3 17) cudatoolkit-standalone/11.6.2 +# 3) craype-network-ofi 8) cray-pmi/6.1.2 13) gnu-parallel/2021-09-22 18) cmake/3.23.2 +# 4) perftools-base/22.05.0 9) cray-pmi-lib/6.0.17 14) gcc/11.2.0 +# 5) craype-accel-nvidia80 10) cray-pals/1.1.7 15) cray-mpich/8.1.16 + + + +#SET(HOMMEXX_EXEC_SPACE CUDA CACHE STRING "") +#SET(HOMMEXX_MPI_ON_DEVICE FALSE CACHE BOOL "") +#SET(HOMMEXX_CUDA_MAX_WARP_PER_TEAM "16" CACHE STRING "") + +# cray-hdf5-parallel/1.12.0.6 cray-netcdf-hdf5parallel/4.7.4.6 cray-parallel-netcdf/1.12.1.6 +#SET(NETCDF_DIR $ENV{CRAY_NETCDF_HDF5PARALLEL_PREFIX} CACHE FILEPATH "") +#SET(PNETCDF_DIR $ENV{CRAY_PARALLEL_NETCDF_DIR} CACHE FILEPATH "") +#SET(HDF5_DIR $ENV{CRAY_HDF5_PARALLEL_PREFIX} CACHE FILEPATH "") + +#for scorpio +#SET (NetCDF_C_PATH $ENV{CRAY_NETCDF_HDF5PARALLEL_PREFIX} CACHE FILEPATH "") +#SET (NetCDF_Fortran_PATH $ENV{CRAY_NETCDF_HDF5PARALLEL_PREFIX} CACHE FILEPATH "") + +SET(BUILD_HOMME_WITHOUT_PIOLIBRARY TRUE CACHE BOOL "") + +SET(HOMME_FIND_BLASLAPACK FALSE CACHE BOOL "") + +SET(WITH_PNETCDF FALSE CACHE FILEPATH "") + +SET(USE_QUEUING FALSE CACHE BOOL "") + +SET(BUILD_HOMME_THETA_KOKKOS TRUE CACHE BOOL "") + +SET(CUDA_BUILD TRUE CACHE BOOL "") + +#SET(HOMMEXX_BFB_TESTING TRUE CACHE BOOL "") + +SET(USE_TRILINOS OFF CACHE BOOL "") + +SET(Kokkos_ENABLE_OPENMP OFF CACHE BOOL "") +SET(Kokkos_ENABLE_CUDA ON CACHE BOOL "") +SET(Kokkos_ENABLE_CUDA_LAMBDA ON CACHE BOOL "") +SET(Kokkos_ARCH_AMPERE80 ON CACHE BOOL "") +#SET(Kokkos_ARCH_ZEN2 ON CACHE BOOL "") # works, and perf same if both AMPERE80 and ZEN2 are on +#SET(Kokkos_ENABLE_CUDA_UVM ON CACHE BOOL "") +SET(Kokkos_ENABLE_EXPLICIT_INSTANTIATION OFF CACHE BOOL "") +#SET(Kokkos_ENABLE_CUDA_ARCH_LINKING OFF CACHE BOOL "") + +#SET(CMAKE_C_COMPILER "mpicc" CACHE STRING "") +#SET(CMAKE_Fortran_COMPILER "mpifort" CACHE STRING "") +#SET(CMAKE_CXX_COMPILER "mpicxx" CACHE STRING "") +SET(CMAKE_C_COMPILER "cc" CACHE STRING "") +SET(CMAKE_Fortran_COMPILER "ftn" CACHE STRING "") +SET(CMAKE_CXX_COMPILER "CC" CACHE STRING "") + +#SET(CMAKE_C_COMPILER "mpicc" CACHE STRING "") +#SET(CMAKE_Fortran_COMPILER "mpifort" CACHE STRING "") +#SET(CMAKE_CXX_COMPILER "${CMAKE_CURRENT_SOURCE_DIR}/../../externals/kokkos/bin/nvcc_wrapper" CACHE STRING "") + +# Note: need to set MPICH_CXX env variable and perhaps NVCC_WRAPPER_DEFAULT_COMPILER + +SET(CXXLIB_SUPPORTED_CACHE FALSE CACHE BOOL "") + +SET(ENABLE_OPENMP OFF CACHE BOOL "") +SET(ENABLE_COLUMN_OPENMP OFF CACHE BOOL "") +SET(ENABLE_HORIZ_OPENMP OFF CACHE BOOL "") + +SET(CMAKE_VERBOSE_MAKEFILE ON CACHE BOOL "") + +#SET(HOMME_TESTING_PROFILE "dev" CACHE STRING "") + +SET(USE_NUM_PROCS 4 CACHE STRING "") + +SET(USE_MPIEXEC "srun" CACHE STRING "") +#SET(CPRNC_DIR /global/cfs/cdirs/e3sm/tools/cprnc CACHE FILEPATH "") diff --git a/components/homme/cmake/machineFiles/spot-aot-AB2.cmake b/components/homme/cmake/machineFiles/spot-aot-AB2.cmake new file mode 100644 index 000000000000..23fad2361ccf --- /dev/null +++ b/components/homme/cmake/machineFiles/spot-aot-AB2.cmake @@ -0,0 +1,63 @@ +#module restore +#module load oneapi/eng-compiler/2022.12.30.005 +#module load intel_compute_runtime/release/agama-devel-627 +#module load spack cmake +#module list + +SET (SUNSPOT_MACHINE TRUE CACHE BOOL "") + +SET (HOMMEXX_MPI_ON_DEVICE TRUE CACHE BOOL "") + +#SET(BUILD_HOMME_WITHOUT_PIOLIBRARY TRUE CACHE BOOL "") + +SET(HOMME_FIND_BLASLAPACK TRUE CACHE BOOL "") + +SET(WITH_PNETCDF FALSE CACHE FILEPATH "") + +SET(USE_QUEUING FALSE CACHE BOOL "") + +#temp hack +SET(HOMME_USE_KOKKOS TRUE CACHE BOOL "") + +SET(BUILD_HOMME_PREQX_KOKKOS TRUE CACHE BOOL "") +SET(BUILD_HOMME_THETA_KOKKOS TRUE CACHE BOOL "") + +#set(KOKKOS_HOME "/home/onguba/kokkos-build/june22-2024-aot/install" CACHE STRING "") +#set(E3SM_KOKKOS_PATH ${KOKKOS_HOME} CACHE STRING "") + +SET (NetCDF_Fortran_PATH "/lus/gila/projects/CSC249ADSE15_CNDA/software/oneAPI.2022.12.30.003/netcdf" CACHE STRING "") +SET (NetCDF_C_PATH "/lus/gila/projects/CSC249ADSE15_CNDA/software/oneAPI.2022.12.30.003/netcdf" CACHE STRING "") + +SET(USE_TRILINOS OFF CACHE BOOL "") + +SET(SYCL_BUILD TRUE CACHE BOOL "") +SET(HOMME_ENABLE_COMPOSE FALSE CACHE BOOL "") + +#SET(CMAKE_CXX_STANDARD 17) +SET(CMAKE_CXX_STANDARD 17 CACHE STRING "CXX Standard") + +SET(CMAKE_C_COMPILER "mpicc" CACHE STRING "") +SET(CMAKE_Fortran_COMPILER "mpifort" CACHE STRING "") +SET(CMAKE_CXX_COMPILER "mpicxx" CACHE STRING "") + +SET(SYCL_COMPILE_FLAGS "-std=c++17 -fsycl -fsycl-device-code-split=per_kernel -fno-sycl-id-queries-fit-in-int -fsycl-unnamed-lambda") +SET(SYCL_LINK_FLAGS "-fsycl-max-parallel-link-jobs=32 -fsycl-link-huge-device-code -fsycl -fsycl-device-code-split=per_kernel -fsycl-targets=spir64_gen -Xsycl-target-backend \"-device 12.60.7\"") + +#-fpscomp does not actually solve the issue with bools in here,another suggestion was -fp-model=precise, not working either +SET(ADD_Fortran_FLAGS " -fc=ifx -fpscomp logicals -O3 -DNDEBUG -DCPRINTEL -g" CACHE STRING "") +SET(ADD_C_FLAGS "-O3 -DNDEBUG " CACHE STRING "") + +SET(ADD_CXX_FLAGS " -std=c++17 -O3 -DNDEBUG ${SYCL_COMPILE_FLAGS}" CACHE STRING "") +SET(ADD_LINKER_FLAGS "-O3 -DNDEBUG ${SYCL_LINK_FLAGS} -fortlib" CACHE STRING "") + +set (ENABLE_OPENMP OFF CACHE BOOL "") +set (ENABLE_COLUMN_OPENMP OFF CACHE BOOL "") +set (ENABLE_HORIZ_OPENMP OFF CACHE BOOL "") + +set (HOMME_TESTING_PROFILE "dev" CACHE STRING "") + +set (USE_NUM_PROCS 4 CACHE STRING "") + +SET (USE_MPI_OPTIONS "--bind-to core" CACHE FILEPATH "") + + From 1379db52a29ff31764b6268eae1f88fbedbae252 Mon Sep 17 00:00:00 2001 From: Oksana Guba Date: Thu, 5 Sep 2024 16:29:27 -0600 Subject: [PATCH 395/451] HOMME: CMake and CPP mods to support SYCL backend --- components/homme/CMakeLists.txt | 8 +++++--- components/homme/cmake/HommeMacros.cmake | 8 +++++++- components/homme/src/share/cxx/Config.hpp | 2 +- components/homme/src/share/cxx/ExecSpaceDefs.hpp | 4 ++++ .../homme/test_execs/share_kokkos_ut/CMakeLists.txt | 4 ++-- .../homme/test_execs/thetal_kokkos_ut/CMakeLists.txt | 3 +++ 6 files changed, 22 insertions(+), 7 deletions(-) diff --git a/components/homme/CMakeLists.txt b/components/homme/CMakeLists.txt index 80a89a296910..6fe81180ab54 100644 --- a/components/homme/CMakeLists.txt +++ b/components/homme/CMakeLists.txt @@ -206,7 +206,9 @@ IF (HOMME_USE_KOKKOS) STRING (TOUPPER ${HOMMEXX_EXEC_SPACE} HOMMEXX_EXEC_SPACE_UPPER) - IF (HOMMEXX_EXEC_SPACE_UPPER STREQUAL "HIP") + IF (${HOMMEXX_EXEC_SPACE_UPPER} STREQUAL "SYCL") + SET (HOMMEXX_SYCL_SPACE ON) + ELSEIF (${HOMMEXX_EXEC_SPACE_UPPER} STREQUAL "HIP") SET (HOMMEXX_HIP_SPACE ON) ELSEIF (HOMMEXX_EXEC_SPACE_UPPER STREQUAL "CUDA") SET (HOMMEXX_CUDA_SPACE ON) @@ -303,7 +305,7 @@ SET (HOMMEXX_ENABLE_GPU_F90 FALSE) IF (HOMME_USE_KOKKOS) - IF (CUDA_BUILD OR HIP_BUILD) + IF (CUDA_BUILD OR HIP_BUILD OR SYCL_BUILD) SET (DEFAULT_VECTOR_SIZE 1) SET (HOMMEXX_ENABLE_GPU TRUE) SET (HOMMEXX_ENABLE_GPU_F90 TRUE) @@ -312,7 +314,7 @@ IF (HOMME_USE_KOKKOS) ENDIF() SET (HOMMEXX_VECTOR_SIZE ${DEFAULT_VECTOR_SIZE} CACHE STRING - "If AVX or Cuda or HIP don't take priority, use this software vector size.") + "If AVX or Cuda or HIP or SYCL don't take priority, use this software vector size.") IF (CMAKE_BUILD_TYPE_UPPER MATCHES "DEBUG" OR CMAKE_BUILD_TYPE_UPPER MATCHES "RELWITHDEBINFO") SET (HOMMEXX_DEBUG ON) diff --git a/components/homme/cmake/HommeMacros.cmake b/components/homme/cmake/HommeMacros.cmake index 6d073dbbe83b..5610947cb299 100644 --- a/components/homme/cmake/HommeMacros.cmake +++ b/components/homme/cmake/HommeMacros.cmake @@ -112,7 +112,13 @@ macro(createTestExec execName execType macroNP macroNC ADD_DEFINITIONS(-DHAVE_CONFIG_H) ADD_EXECUTABLE(${execName} ${EXEC_SOURCES}) - SET_TARGET_PROPERTIES(${execName} PROPERTIES LINKER_LANGUAGE Fortran) + + if(SUNSPOT_MACHINE) + SET_TARGET_PROPERTIES(${execName} PROPERTIES LINKER_LANGUAGE CXX) + else() + SET_TARGET_PROPERTIES(${execName} PROPERTIES LINKER_LANGUAGE Fortran) + endif() + IF(BUILD_HOMME_WITHOUT_PIOLIBRARY) TARGET_COMPILE_DEFINITIONS(${execName} PUBLIC HOMME_WITHOUT_PIOLIBRARY) ENDIF() diff --git a/components/homme/src/share/cxx/Config.hpp b/components/homme/src/share/cxx/Config.hpp index 684f9143beaf..b204b1dbd047 100644 --- a/components/homme/src/share/cxx/Config.hpp +++ b/components/homme/src/share/cxx/Config.hpp @@ -21,7 +21,7 @@ # endif #endif -#if ! defined HOMMEXX_CUDA_SPACE && ! defined HOMMEXX_OPENMP_SPACE && ! defined HOMMEXX_THREADS_SPACE && ! defined HOMMEXX_SERIAL_SPACE && ! defined HOMMEXX_HIP_SPACE +#if ! defined HOMMEXX_CUDA_SPACE && ! defined HOMMEXX_OPENMP_SPACE && ! defined HOMMEXX_THREADS_SPACE && ! defined HOMMEXX_SERIAL_SPACE && ! defined HOMMEXX_HIP_SPACE && ! defined HOMMEXX_SYCL_SPACE # define HOMMEXX_DEFAULT_SPACE #endif diff --git a/components/homme/src/share/cxx/ExecSpaceDefs.hpp b/components/homme/src/share/cxx/ExecSpaceDefs.hpp index cd6649c7ab2d..82f5e803801c 100644 --- a/components/homme/src/share/cxx/ExecSpaceDefs.hpp +++ b/components/homme/src/share/cxx/ExecSpaceDefs.hpp @@ -34,6 +34,10 @@ using HommexxGPU = Kokkos::Cuda; using HommexxGPU = Kokkos::Experimental::HIP; #endif +#ifdef KOKKOS_ENABLE_SYCL +using HommexxGPU = Kokkos::Experimental::SYCL; +#endif + #else using HommexxGPU = void; #endif diff --git a/components/homme/test_execs/share_kokkos_ut/CMakeLists.txt b/components/homme/test_execs/share_kokkos_ut/CMakeLists.txt index 3fbeff9f6f2c..bc788462ce6e 100644 --- a/components/homme/test_execs/share_kokkos_ut/CMakeLists.txt +++ b/components/homme/test_execs/share_kokkos_ut/CMakeLists.txt @@ -10,7 +10,7 @@ SET(UTILS_TIMING_DIRS ${UTILS_TIMING_SRC_DIR} ${UTILS_TIMING_BIN_DIR}) # Note: need CUDA_BUILD and HOMMEXX_BFB_TESTING here, since the share # unit tests do not include a config.h file SET (COMMON_DEFINITIONS NP=4 NC=4) -IF (CUDA_BUILD OR HIP_BUILD) +IF (CUDA_BUILD OR HIP_BUILD OR SYCL_BUILD) SET(COMMON_DEFINITIONS ${COMMON_DEFINITIONS} HOMMEXX_ENABLE_GPU_F90) ENDIF() IF (HOMMEXX_BFB_TESTING) @@ -158,7 +158,7 @@ ELSE() SET (NUM_CPUS 1) ENDIF() cxx_unit_test (sphere_op_ut "${SPHERE_OP_UT_F90_SRCS}" "${SPHERE_OP_UT_CXX_SRCS}" "${SPHERE_OP_UT_INCLUDE_DIRS}" "${CONFIG_DEFINES}" ${NUM_CPUS}) -endif () +endif () #BFB ### Limiters unit test ### diff --git a/components/homme/test_execs/thetal_kokkos_ut/CMakeLists.txt b/components/homme/test_execs/thetal_kokkos_ut/CMakeLists.txt index 205635e918cc..e8bf5e20bd03 100644 --- a/components/homme/test_execs/thetal_kokkos_ut/CMakeLists.txt +++ b/components/homme/test_execs/thetal_kokkos_ut/CMakeLists.txt @@ -11,6 +11,8 @@ SET(UTILS_TIMING_BIN_DIR ${HOMME_BINARY_DIR}/utils/cime/CIME/non_py/src/timing) THETAL_KOKKOS_SETUP() # This is needed to compile the lib and test executables with the correct options +#these vars shared between all targets, so changing one var +#for one test only won't work, config is built once and for the last test SET(THIS_CONFIG_IN ${HOMME_SOURCE_DIR}/src/theta-l_kokkos/config.h.cmake.in) SET(THIS_CONFIG_HC ${CMAKE_CURRENT_BINARY_DIR}/config.h.c) SET(THIS_CONFIG_H ${CMAKE_CURRENT_BINARY_DIR}/config.h) @@ -18,6 +20,7 @@ SET (NUM_POINTS 4) SET (NUM_PLEV 12) SET (QSIZE_D 4) SET (PIO_INTERP TRUE) + HommeConfigFile (${THIS_CONFIG_IN} ${THIS_CONFIG_HC} ${THIS_CONFIG_H} ) ADD_LIBRARY(thetal_kokkos_ut_lib From c7320a6c5e31c161cf8c48ecb72d0ad792506ddf Mon Sep 17 00:00:00 2001 From: Oksana Guba Date: Thu, 5 Sep 2024 16:30:22 -0600 Subject: [PATCH 396/451] HOMME: replace some printf with Kokkos::printf --- components/homme/src/share/cxx/utilities/BfbUtils.hpp | 2 +- .../homme/src/theta-l_kokkos/cxx/DirkFunctorImpl.hpp | 4 ++-- .../homme/src/theta-l_kokkos/cxx/LimiterFunctor.hpp | 8 ++++---- 3 files changed, 7 insertions(+), 7 deletions(-) diff --git a/components/homme/src/share/cxx/utilities/BfbUtils.hpp b/components/homme/src/share/cxx/utilities/BfbUtils.hpp index e3570874e266..7fb4d042f7f2 100644 --- a/components/homme/src/share/cxx/utilities/BfbUtils.hpp +++ b/components/homme/src/share/cxx/utilities/BfbUtils.hpp @@ -64,7 +64,7 @@ KOKKOS_INLINE_FUNCTION ScalarType int_pow (ScalarType val, int k) { constexpr int max_shift = 30; if (k<0) { - printf ("k = %d\n",k); + Kokkos::printf ("k = %d\n",k); Kokkos::abort("int_pow implemented only for k>=0.\n"); } diff --git a/components/homme/src/theta-l_kokkos/cxx/DirkFunctorImpl.hpp b/components/homme/src/theta-l_kokkos/cxx/DirkFunctorImpl.hpp index ace1ba920141..d16769079729 100644 --- a/components/homme/src/theta-l_kokkos/cxx/DirkFunctorImpl.hpp +++ b/components/homme/src/theta-l_kokkos/cxx/DirkFunctorImpl.hpp @@ -382,8 +382,8 @@ struct DirkFunctorImpl { kv.team_barrier(); if (it >= maxiter) { - printf("[DIRK] WARNING! Newton reached max iteration count," - " with deltaerr = %3.17f\n", deltaerr); + Kokkos::printf("[DIRK] WARNING! Newton reached max iteration count," + " with deltaerr = %3.17f\n", deltaerr); nerr = 1; } diff --git a/components/homme/src/theta-l_kokkos/cxx/LimiterFunctor.hpp b/components/homme/src/theta-l_kokkos/cxx/LimiterFunctor.hpp index cd3bf7c32526..7914c0a60e3a 100644 --- a/components/homme/src/theta-l_kokkos/cxx/LimiterFunctor.hpp +++ b/components/homme/src/theta-l_kokkos/cxx/LimiterFunctor.hpp @@ -141,8 +141,8 @@ struct LimiterFunctor { [&](const int k,Real& result) { #ifndef HOMMEXX_BFB_TESTING if(diff_as_real(k) < 0){ - printf("WARNING:CAAR: dp3d too small. k=%d, dp3d(k)=%f, dp0=%f \n", - k+1,dp_as_real(k),dp0_as_real(k)); + Kokkos::printf("WARNING:CAAR: dp3d too small. k=%d, dp3d(k)=%f, dp0=%f \n", + k+1,dp_as_real(k),dp0_as_real(k)); } #endif result = result<=diff_as_real(k) ? result : diff_as_real(k); @@ -202,8 +202,8 @@ struct LimiterFunctor { for (int ivec=0; ivec Date: Thu, 5 Sep 2024 16:33:09 -0600 Subject: [PATCH 397/451] HOMME: prefer to use int to bool in a few places --- components/homme/src/share/control_mod.F90 | 1 + components/homme/src/share/cxx/GllFvRemap.cpp | 4 +- components/homme/src/share/cxx/GllFvRemap.hpp | 4 +- .../homme/src/share/cxx/GllFvRemapImpl.cpp | 8 ++-- .../homme/src/share/cxx/GllFvRemapImpl.hpp | 5 ++- .../homme/src/share/cxx/SimulationParams.hpp | 4 +- components/homme/src/share/gllfvremap_mod.F90 | 14 +++---- components/homme/src/share/namelist_mod.F90 | 6 +++ .../src/theta-l_kokkos/cxx/CamForcing.cpp | 2 +- .../theta-l_kokkos/cxx/EquationOfState.hpp | 4 +- .../src/theta-l_kokkos/cxx/ForcingFunctor.hpp | 4 +- .../cxx/HyperviscosityFunctorImpl.cpp | 8 +++- .../cxx/HyperviscosityFunctorImpl.hpp | 2 +- .../cxx/cxx_f90_interface_theta.cpp | 19 +++++----- .../src/theta-l_kokkos/prim_driver_mod.F90 | 38 ++++++++++++------- .../src/theta-l_kokkos/theta_f2c_mod.F90 | 12 +++--- 16 files changed, 79 insertions(+), 56 deletions(-) diff --git a/components/homme/src/share/control_mod.F90 b/components/homme/src/share/control_mod.F90 index 0e9494f5a6cd..9c3c599b2324 100644 --- a/components/homme/src/share/control_mod.F90 +++ b/components/homme/src/share/control_mod.F90 @@ -43,6 +43,7 @@ module control_mod ! flag used by preqx, theta-l and theta-c models ! should be renamed to "hydrostatic_mode" logical, public :: theta_hydrostatic_mode + integer, public :: theta_hydrostatic_mode_integer integer, public :: tstep_type= 5 ! preqx timestepping options diff --git a/components/homme/src/share/cxx/GllFvRemap.cpp b/components/homme/src/share/cxx/GllFvRemap.cpp index e36dbc14d74f..a8f564958d46 100644 --- a/components/homme/src/share/cxx/GllFvRemap.cpp +++ b/components/homme/src/share/cxx/GllFvRemap.cpp @@ -16,7 +16,7 @@ namespace Homme { void init_gllfvremap_c (int nelemd, int np, int nf, int nf_max, - bool theta_hydrostatic_mode, + int theta_hydrostatic_mode, CF90Ptr fv_metdet, CF90Ptr g2f_remapd, CF90Ptr f2g_remapd, CF90Ptr D_f, CF90Ptr Dinv_f) { auto& c = Context::singleton(); @@ -52,7 +52,7 @@ void GllFvRemap::init_boundary_exchanges () { } void GllFvRemap -::init_data (const int nf, const int nf_max, bool theta_hydrostatic_mode, +::init_data (const int nf, const int nf_max, const int theta_hydrostatic_mode, const Real* fv_metdet, const Real* g2f_remapd, const Real* f2g_remapd, const Real* D_f, const Real* Dinv_f) { m_impl->init_data(nf, nf_max, theta_hydrostatic_mode, fv_metdet, diff --git a/components/homme/src/share/cxx/GllFvRemap.hpp b/components/homme/src/share/cxx/GllFvRemap.hpp index 07e4bf58a903..2adff0aeaa96 100644 --- a/components/homme/src/share/cxx/GllFvRemap.hpp +++ b/components/homme/src/share/cxx/GllFvRemap.hpp @@ -40,7 +40,7 @@ class GllFvRemap { typedef Phys2T::const_type CPhys2T; typedef Phys3T::const_type CPhys3T; - void init_data(const int nf, const int nf_max, bool theta_hydrostatic_mode, + void init_data(const int nf, const int nf_max, const int theta_hydrostatic_mode, const Real* fv_metdet, const Real* g2f_remapd, const Real* f2g_remapd, const Real* D_f, const Real* Dinv_f); @@ -81,7 +81,7 @@ class GllFvRemap { extern "C" void init_gllfvremap_c(int nelemd, int np, int nf, int nf_max, - const bool theta_hydrostatic_mode, + const int theta_hydrostatic_mode, CF90Ptr fv_metdet, CF90Ptr g2f_remapd, CF90Ptr f2g_remapd, CF90Ptr D_f, CF90Ptr Dinv_f); diff --git a/components/homme/src/share/cxx/GllFvRemapImpl.cpp b/components/homme/src/share/cxx/GllFvRemapImpl.cpp index 6148f69cfa9c..d4ab5c89f510 100644 --- a/components/homme/src/share/cxx/GllFvRemapImpl.cpp +++ b/components/homme/src/share/cxx/GllFvRemapImpl.cpp @@ -131,7 +131,7 @@ void GllFvRemapImpl::init_boundary_exchanges () { template using FV = Kokkos::View; void GllFvRemapImpl -::init_data (const int nf, const int nf_max, const bool theta_hydrostatic_mode, +::init_data (const int nf, const int nf_max, const int theta_hydrostatic_mode, const Real* fv_metdet_r, const Real* g2f_remapd_r, const Real* f2g_remapd_r, const Real* D_f_r, const Real* Dinv_f_r) { using Kokkos::create_mirror_view; @@ -142,7 +142,7 @@ ::init_data (const int nf, const int nf_max, const bool theta_hydrostatic_mode, " nf must be > 1.", Errors::err_not_implemented); auto& sp = Context::singleton().get(); - m_data.use_moisture = sp.moisture == MoistDry::MOIST; + m_data.use_moisture = sp.use_moisture; // Only in the unit test gllfvremap_ut does theta_hydrostatic_mode not already // == sp.theta_hydrostatic_mode. m_data.theta_hydrostatic_mode = sp.theta_hydrostatic_mode = theta_hydrostatic_mode; @@ -395,7 +395,7 @@ ::run_dyn_to_fv_phys (const int timeidx, const Phys1T& ps, const Phys1T& phis, c const auto hvcoord = m_hvcoord; const bool use_moisture = m_data.use_moisture; - const bool theta_hydrostatic_mode = m_data.theta_hydrostatic_mode; + const int theta_hydrostatic_mode = m_data.theta_hydrostatic_mode; const bool want_dp_fv_out = dp_fv_out_ptr != nullptr; VPhys2T dp_fv_out; @@ -605,7 +605,7 @@ run_fv_phys_to_dyn (const int timeidx, const CPhys2T& Ts, const CPhys3T& uvs, const auto fT = m_forcing.m_ft; const auto hvcoord = m_hvcoord; const auto dp3d = m_state.m_dp3d; - const bool theta_hydrostatic_mode = m_data.theta_hydrostatic_mode; + const int theta_hydrostatic_mode = m_data.theta_hydrostatic_mode; EquationOfState eos; eos.init(theta_hydrostatic_mode, hvcoord); ElementOps ops; ops.init(hvcoord); const auto tu_ne = m_tu_ne; diff --git a/components/homme/src/share/cxx/GllFvRemapImpl.hpp b/components/homme/src/share/cxx/GllFvRemapImpl.hpp index 11738b2bf455..7388fddb1231 100644 --- a/components/homme/src/share/cxx/GllFvRemapImpl.hpp +++ b/components/homme/src/share/cxx/GllFvRemapImpl.hpp @@ -60,7 +60,8 @@ struct GllFvRemapImpl { struct Data { int nelemd, qsize, nf2, n_dss_fld; - bool use_moisture, theta_hydrostatic_mode; + bool use_moisture; + int theta_hydrostatic_mode; static constexpr int nbuf1 = 2, nbuf2 = 1; Buf1 buf1[nbuf1]; @@ -107,7 +108,7 @@ struct GllFvRemapImpl { void init_buffers(const FunctorsBuffersManager& fbm); void init_boundary_exchanges(); - void init_data(const int nf, const int nf_max, const bool theta_hydrostatic_mode, + void init_data(const int nf, const int nf_max, const int theta_hydrostatic_mode, const Real* fv_metdet_r, const Real* g2f_remapd_r, const Real* f2g_remapd_r, const Real* D_f_r, const Real* Dinv_f_r); diff --git a/components/homme/src/share/cxx/SimulationParams.hpp b/components/homme/src/share/cxx/SimulationParams.hpp index b435911da2e6..4f36962b16c3 100644 --- a/components/homme/src/share/cxx/SimulationParams.hpp +++ b/components/homme/src/share/cxx/SimulationParams.hpp @@ -23,7 +23,7 @@ struct SimulationParams void print(std::ostream& out = std::cout); TimeStepType time_step_type; - MoistDry moisture; + bool use_moisture; RemapAlg remap_alg; TestCase test_case; ForcingAlg ftype = ForcingAlg::FORCING_OFF; @@ -77,7 +77,7 @@ inline void SimulationParams::print (std::ostream& out) { out << "\n************** CXX SimulationParams **********************\n\n"; out << " time_step_type: " << etoi(time_step_type) << "\n"; - out << " moisture: " << (moisture==MoistDry::DRY ? "dry" : "moist") << "\n"; + out << " use_moisture: " << (use_moisture ? "moist" : "dry") << "\n"; out << " remap_alg: " << etoi(remap_alg) << "\n"; out << " test case: " << etoi(test_case) << "\n"; out << " ftype: " << etoi(ftype) << "\n"; diff --git a/components/homme/src/share/gllfvremap_mod.F90 b/components/homme/src/share/gllfvremap_mod.F90 index e0e0fa6c4daa..e927f04aba06 100644 --- a/components/homme/src/share/gllfvremap_mod.F90 +++ b/components/homme/src/share/gllfvremap_mod.F90 @@ -265,22 +265,22 @@ end subroutine gfr_init subroutine gfr_init_hxx() bind(c) #if KOKKOS_TARGET - use control_mod, only: theta_hydrostatic_mode - use iso_c_binding, only: c_bool + use control_mod, only: theta_hydrostatic_mode_integer + use iso_c_binding, only: c_int interface - subroutine init_gllfvremap_c(nelemd, np, nf, nf_max, theta_hydrostatic_mode, & + subroutine init_gllfvremap_c(nelemd, np, nf, nf_max, theta_hydrostatic_mode_integer, & fv_metdet, g2f_remapd, f2g_remapd, D_f, Dinv_f) bind(c) - use iso_c_binding, only: c_bool, c_int, c_double + use iso_c_binding, only: c_int, c_double integer (c_int), value, intent(in) :: nelemd, np, nf, nf_max - logical (c_bool), value, intent(in) :: theta_hydrostatic_mode + integer (c_int), value, intent(in) :: theta_hydrostatic_mode_integer real (c_double), dimension(nf*nf,nelemd), intent(in) :: fv_metdet real (c_double), dimension(np,np,nf_max*nf_max), intent(in) :: g2f_remapd real (c_double), dimension(nf_max*nf_max,np,np), intent(in) :: f2g_remapd real (c_double), dimension(nf*nf,2,2,nelemd), intent(in) :: D_f, Dinv_f end subroutine init_gllfvremap_c end interface - logical (c_bool) :: thm - thm = theta_hydrostatic_mode + integer (c_int) :: thm + thm = theta_hydrostatic_mode_integer call init_gllfvremap_c(nelemd, np, gfr%nphys, nphys_max, thm, & gfr%fv_metdet, gfr%g2f_remapd, gfr%f2g_remapd, gfr%D_f, gfr%Dinv_f) #endif diff --git a/components/homme/src/share/namelist_mod.F90 b/components/homme/src/share/namelist_mod.F90 index 1d47090182ba..a3edaa07e235 100644 --- a/components/homme/src/share/namelist_mod.F90 +++ b/components/homme/src/share/namelist_mod.F90 @@ -41,6 +41,7 @@ module namelist_mod runtype, & integration, & ! integration method theta_hydrostatic_mode, & + theta_hydrostatic_mode_integer, & transport_alg , & ! SE Eulerian, classical SL, cell-integrated SL semi_lagrange_cdr_alg, & ! see control_mod for semi_lagrange_* descriptions semi_lagrange_cdr_check, & @@ -452,8 +453,10 @@ subroutine readnl(par) planar_slice = .false. theta_hydrostatic_mode = .true. ! for preqx, this must be .true. + theta_hydrostatic_mode_integer = 1 ! for preqx, this must be .true. #if ( defined MODEL_THETA_C || defined MODEL_THETA_L ) theta_hydrostatic_mode = .false. ! default NH + theta_hydrostatic_mode_integer = 0 ! default NH #endif @@ -850,7 +853,10 @@ subroutine readnl(par) call MPI_bcast(case_planar_bubble,1,MPIlogical_t,par%root,par%comm,ierr) #endif +if(theta_hydrostatic_mode) theta_hydrostatic_mode_integer = 1 +if(.not. theta_hydrostatic_mode) theta_hydrostatic_mode_integer = 0 call MPI_bcast(theta_hydrostatic_mode ,1,MPIlogical_t,par%root,par%comm,ierr) + call MPI_bcast(theta_hydrostatic_mode_integer ,1,MPIinteger_t,par%root,par%comm,ierr) call MPI_bcast(transport_alg ,1,MPIinteger_t,par%root,par%comm,ierr) call MPI_bcast(semi_lagrange_cdr_alg ,1,MPIinteger_t,par%root,par%comm,ierr) call MPI_bcast(semi_lagrange_cdr_check ,1,MPIlogical_t,par%root,par%comm,ierr) diff --git a/components/homme/src/theta-l_kokkos/cxx/CamForcing.cpp b/components/homme/src/theta-l_kokkos/cxx/CamForcing.cpp index 02b999db16e9..bd7cee3e7c0a 100644 --- a/components/homme/src/theta-l_kokkos/cxx/CamForcing.cpp +++ b/components/homme/src/theta-l_kokkos/cxx/CamForcing.cpp @@ -33,7 +33,7 @@ static void apply_cam_forcing_tracers(const Real dt, ForcingFunctor& ff, if ( p.ftype == ForcingAlg::FORCING_2) adjustment = true; #endif - ff.tracers_forcing(dt, tl.n0, tl.n0_qdp, adjustment, p.moisture); + ff.tracers_forcing(dt, tl.n0, tl.n0_qdp, adjustment, p.use_moisture); GPTLstop("ApplyCAMForcing_tracers"); } diff --git a/components/homme/src/theta-l_kokkos/cxx/EquationOfState.hpp b/components/homme/src/theta-l_kokkos/cxx/EquationOfState.hpp index dd97720f1be2..a50a28d58f55 100644 --- a/components/homme/src/theta-l_kokkos/cxx/EquationOfState.hpp +++ b/components/homme/src/theta-l_kokkos/cxx/EquationOfState.hpp @@ -23,7 +23,7 @@ class EquationOfState { EquationOfState () = default; - void init (const bool theta_hydrostatic_mode, + void init (const int theta_hydrostatic_mode, const HybridVCoord& hvcoord) { m_theta_hydrostatic_mode = theta_hydrostatic_mode; m_hvcoord = hvcoord; @@ -250,7 +250,7 @@ class EquationOfState { public: - bool m_theta_hydrostatic_mode; + int m_theta_hydrostatic_mode; HybridVCoord m_hvcoord; }; diff --git a/components/homme/src/theta-l_kokkos/cxx/ForcingFunctor.hpp b/components/homme/src/theta-l_kokkos/cxx/ForcingFunctor.hpp index 28a702c1d273..00fa1deef667 100644 --- a/components/homme/src/theta-l_kokkos/cxx/ForcingFunctor.hpp +++ b/components/homme/src/theta-l_kokkos/cxx/ForcingFunctor.hpp @@ -236,7 +236,7 @@ class ForcingFunctor }); } - void tracers_forcing (const Real dt, const int np1, const int np1_qdp, const bool adjustment, const MoistDry moisture) { + void tracers_forcing (const Real dt, const int np1, const int np1_qdp, const bool adjustment, const bool use_moisture) { // The Functor needs to be fully setup to use this function assert (is_setup); @@ -245,7 +245,7 @@ class ForcingFunctor m_np1_qdp = np1_qdp; m_adjustment = adjustment; - m_moist = (moisture==MoistDry::MOIST); + m_moist = use_moisture; Kokkos::parallel_for("temperature, NH perturb press, FQps",m_policy_tracers_pre,*this); Kokkos::fence(); diff --git a/components/homme/src/theta-l_kokkos/cxx/HyperviscosityFunctorImpl.cpp b/components/homme/src/theta-l_kokkos/cxx/HyperviscosityFunctorImpl.cpp index 046e6f9956d4..55792051d33b 100644 --- a/components/homme/src/theta-l_kokkos/cxx/HyperviscosityFunctorImpl.cpp +++ b/components/homme/src/theta-l_kokkos/cxx/HyperviscosityFunctorImpl.cpp @@ -118,9 +118,13 @@ void HyperviscosityFunctorImpl::init_params(const SimulationParams& params) m_eos.init(params.theta_hydrostatic_mode,m_hvcoord); #ifdef HOMMEXX_BFB_TESTING - m_process_nh_vars = true; + m_process_nh_vars = 1; #else - m_process_nh_vars = !params.theta_hydrostatic_mode; + if (params.theta_hydrostatic_mode){ + m_process_nh_vars = 0; + }else{ + m_process_nh_vars = 1; + } #endif } diff --git a/components/homme/src/theta-l_kokkos/cxx/HyperviscosityFunctorImpl.hpp b/components/homme/src/theta-l_kokkos/cxx/HyperviscosityFunctorImpl.hpp index a55ecbb365f9..993d525422f5 100644 --- a/components/homme/src/theta-l_kokkos/cxx/HyperviscosityFunctorImpl.hpp +++ b/components/homme/src/theta-l_kokkos/cxx/HyperviscosityFunctorImpl.hpp @@ -397,7 +397,7 @@ class HyperviscosityFunctorImpl Buffers m_buffers; HybridVCoord m_hvcoord; - bool m_process_nh_vars; + int m_process_nh_vars; // Policies Kokkos::TeamPolicy m_policy_update_states; diff --git a/components/homme/src/theta-l_kokkos/cxx/cxx_f90_interface_theta.cpp b/components/homme/src/theta-l_kokkos/cxx/cxx_f90_interface_theta.cpp index ec4e2cbe6328..40c4ae64dc98 100644 --- a/components/homme/src/theta-l_kokkos/cxx/cxx_f90_interface_theta.cpp +++ b/components/homme/src/theta-l_kokkos/cxx/cxx_f90_interface_theta.cpp @@ -43,12 +43,13 @@ void init_simulation_params_c (const int& remap_alg, const int& limiter_option, const Real& nu, const Real& nu_p, const Real& nu_q, const Real& nu_s, const Real& nu_div, const Real& nu_top, const int& hypervis_order, const int& hypervis_subcycle, const int& hypervis_subcycle_tom, const double& hypervis_scaling, const double& dcmip16_mu, - const int& ftype, const int& theta_adv_form, const bool& prescribed_wind, const bool& moisture, const bool& disable_diagnostics, - const bool& use_cpstar, const int& transport_alg, const bool& theta_hydrostatic_mode, const char** test_case, + const int& ftype, const int& theta_adv_form, const int& prescribed_wind, const int& use_moisture, const int& disable_diagnostics, + const int& use_cpstar, const int& transport_alg, const int& theta_hydrostatic_mode, const char** test_case, const int& dt_remap_factor, const int& dt_tracer_factor, - const double& scale_factor, const double& laplacian_rigid_factor, const int& nsplit, const bool& pgrad_correction, + const double& scale_factor, const double& laplacian_rigid_factor, const int& nsplit, const int& pgrad_correction, const double& dp3d_thresh, const double& vtheta_thresh, const int& internal_diagnostics_level) { + // Check that the simulation options are supported. This helps us in the future, since we // are currently 'assuming' some option have/not have certain values. As we support for more // options in the C++ build, we will remove some checks @@ -111,16 +112,16 @@ void init_simulation_params_c (const int& remap_alg, const int& limiter_option, params.hypervis_subcycle = hypervis_subcycle; params.hypervis_subcycle_tom = hypervis_subcycle_tom; params.hypervis_scaling = hypervis_scaling; - params.disable_diagnostics = disable_diagnostics; - params.moisture = (moisture ? MoistDry::MOIST : MoistDry::DRY); - params.use_cpstar = use_cpstar; + params.disable_diagnostics = (bool)disable_diagnostics; + params.use_moisture = (bool)use_moisture; + params.use_cpstar = (bool)use_cpstar; params.transport_alg = transport_alg; - params.theta_hydrostatic_mode = theta_hydrostatic_mode; + params.theta_hydrostatic_mode = (bool)theta_hydrostatic_mode; params.dcmip16_mu = dcmip16_mu; params.nsplit = nsplit; params.scale_factor = scale_factor; params.laplacian_rigid_factor = laplacian_rigid_factor; - params.pgrad_correction = pgrad_correction; + params.pgrad_correction = (bool)pgrad_correction; params.dp3d_thresh = dp3d_thresh; params.vtheta_thresh = vtheta_thresh; params.internal_diagnostics_level = internal_diagnostics_level; @@ -304,7 +305,7 @@ void init_elements_c (const int& num_elems) c.create_ref(e.m_forcing); } -void init_functors_c (const bool& allocate_buffer) +void init_functors_c (const int& allocate_buffer) { auto& c = Context::singleton(); diff --git a/components/homme/src/theta-l_kokkos/prim_driver_mod.F90 b/components/homme/src/theta-l_kokkos/prim_driver_mod.F90 index 96b42314453f..262ba19f4b7a 100644 --- a/components/homme/src/theta-l_kokkos/prim_driver_mod.F90 +++ b/components/homme/src/theta-l_kokkos/prim_driver_mod.F90 @@ -64,7 +64,7 @@ subroutine prim_init2(elem, hybrid, nets, nete, tl, hvcoord) end subroutine prim_init2 subroutine prim_create_c_data_structures (tl, hvcoord, mp) - use iso_c_binding, only : c_loc, c_ptr, c_bool, C_NULL_CHAR + use iso_c_binding, only : c_loc, c_ptr, C_NULL_CHAR use theta_f2c_mod, only : init_reference_element_c, init_simulation_params_c, & init_time_level_c, init_hvcoord_c, init_elements_c use time_mod, only : TimeLevel_t, nsplit @@ -73,7 +73,7 @@ subroutine prim_create_c_data_structures (tl, hvcoord, mp) nu, nu_p, nu_q, nu_s, nu_div, nu_top, vert_remap_q_alg, & hypervis_order, hypervis_subcycle, hypervis_subcycle_tom,& hypervis_scaling, & - ftype, prescribed_wind, moisture, disable_diagnostics, & + ftype, prescribed_wind, use_moisture, disable_diagnostics, & use_cpstar, transport_alg, theta_hydrostatic_mode, & dcmip16_mu, theta_advect_form, test_case, & MAX_STRING_LEN, dt_remap_factor, dt_tracer_factor, & @@ -93,6 +93,8 @@ subroutine prim_create_c_data_structures (tl, hvcoord, mp) type (c_ptr) :: hybrid_am_ptr, hybrid_ai_ptr, hybrid_bm_ptr, hybrid_bi_ptr character(len=MAX_STRING_LEN), target :: test_name + integer :: disable_diagnostics_int, theta_hydrostatic_mode_int, use_moisture_int + ! Initialize the C++ reference element structure (i.e., pseudo-spectral deriv matrix and ref element mass matrix) dvv = deriv1%dvv elem_mp = mp @@ -100,22 +102,30 @@ subroutine prim_create_c_data_structures (tl, hvcoord, mp) ! Fill the simulation params structures in C++ test_name = TRIM(test_case) // C_NULL_CHAR + + if (disable_diagnostics) disable_diagnostics_int=1 + if (.not.disable_diagnostics) disable_diagnostics_int=0 + if (use_moisture) use_moisture_int=1 + if (.not.use_moisture) use_moisture_int=0 + if(theta_hydrostatic_mode) theta_hydrostatic_mode_int=1 + if(.not.theta_hydrostatic_mode) theta_hydrostatic_mode_int=0 + call init_simulation_params_c (vert_remap_q_alg, limiter_option, rsplit, qsplit, tstep_type, & qsize, statefreq, nu, nu_p, nu_q, nu_s, nu_div, nu_top, & hypervis_order, hypervis_subcycle, hypervis_subcycle_tom, & hypervis_scaling, & dcmip16_mu, ftype, theta_advect_form, & - LOGICAL(prescribed_wind==1,c_bool), & - LOGICAL(moisture/="dry",c_bool), & - LOGICAL(disable_diagnostics,c_bool), & - LOGICAL(use_cpstar==1,c_bool), & + prescribed_wind, & + use_moisture_int, & + disable_diagnostics_int, & + use_cpstar, & transport_alg, & - LOGICAL(theta_hydrostatic_mode,c_bool), & + theta_hydrostatic_mode_int, & c_loc(test_name), & dt_remap_factor, dt_tracer_factor, & scale_factor, laplacian_rigid_factor, & nsplit, & - LOGICAL(pgrad_correction==1,c_bool), & + pgrad_correction, & dp3d_thresh, vtheta_thresh, internal_diagnostics_level) ! Initialize time level structure in C++ @@ -343,21 +353,21 @@ subroutine prim_init_elements_views (elem) end subroutine prim_init_elements_views subroutine prim_init_kokkos_functors (allocate_buffer) - use iso_c_binding, only : c_bool + use iso_c_binding, only : c_int use theta_f2c_mod, only : init_functors_c, init_boundary_exchanges_c - ! ! Optional Input ! - logical(kind=c_bool), optional :: allocate_buffer ! Whether functor memory buffer should be allocated internally - + integer, intent(in), optional :: allocate_buffer ! Whether functor memory buffer should be allocated internally + integer(kind=c_int) :: dummy ! Initialize the C++ functors in the C++ context ! If no argument allocate_buffer is present, ! let Homme internally allocate buffers if (present(allocate_buffer)) then - call init_functors_c (logical(allocate_buffer,c_bool)) + call init_functors_c (allocate_buffer) else - call init_functors_c (logical(.true.,c_bool)) + dummy=1; + call init_functors_c (dummy) endif ! Initialize boundary exchange structure in C++ diff --git a/components/homme/src/theta-l_kokkos/theta_f2c_mod.F90 b/components/homme/src/theta-l_kokkos/theta_f2c_mod.F90 index 7a4c0424807b..ba39bb03c22b 100644 --- a/components/homme/src/theta-l_kokkos/theta_f2c_mod.F90 +++ b/components/homme/src/theta-l_kokkos/theta_f2c_mod.F90 @@ -11,14 +11,14 @@ subroutine init_simulation_params_c (remap_alg, limiter_option, rsplit, qsplit, qsize, state_frequency, nu, nu_p, nu_q, nu_s, nu_div, nu_top, & hypervis_order, hypervis_subcycle, hypervis_subcycle_tom, & hypervis_scaling, & - dcmip16_mu, ftype, theta_adv_form, prescribed_wind, moisture, & + dcmip16_mu, ftype, theta_adv_form, prescribed_wind, use_moisture, & disable_diagnostics, use_cpstar, transport_alg, & theta_hydrostatic_mode, test_case_name, dt_remap_factor, & dt_tracer_factor, scale_factor, laplacian_rigid_factor, & nsplit, pgrad_correction, dp3d_thresh, vtheta_thresh, & internal_diagnostics_level) bind(c) - use iso_c_binding, only: c_int, c_bool, c_double, c_ptr + use iso_c_binding, only: c_int, c_double, c_ptr ! ! Inputs ! @@ -29,8 +29,8 @@ subroutine init_simulation_params_c (remap_alg, limiter_option, rsplit, qsplit, scale_factor, laplacian_rigid_factor, dp3d_thresh, vtheta_thresh integer(kind=c_int), intent(in) :: hypervis_order, hypervis_subcycle, hypervis_subcycle_tom integer(kind=c_int), intent(in) :: ftype, theta_adv_form - logical(kind=c_bool), intent(in) :: prescribed_wind, moisture, disable_diagnostics, use_cpstar - logical(kind=c_bool), intent(in) :: theta_hydrostatic_mode, pgrad_correction + integer(kind=c_int), intent(in) :: prescribed_wind, use_moisture, disable_diagnostics, use_cpstar + integer(kind=c_int), intent(in) :: theta_hydrostatic_mode, pgrad_correction type(c_ptr), intent(in) :: test_case_name end subroutine init_simulation_params_c @@ -138,11 +138,11 @@ end subroutine init_reference_element_c ! Create C++ functors subroutine init_functors_c (allocate_buffer) bind(c) - use iso_c_binding, only: c_bool + use iso_c_binding, only: c_int ! ! Inputs ! - logical(kind=c_bool), intent(in) :: allocate_buffer + integer(kind=c_int), intent(in) :: allocate_buffer end subroutine init_functors_c ! Initialize C++ boundary exchange structures From 0200065081910233ce6c861471b062d3e0608a2a Mon Sep 17 00:00:00 2001 From: Oksana Guba Date: Thu, 5 Sep 2024 16:33:51 -0600 Subject: [PATCH 398/451] HOMME: some SYCL related mods in kokkos initialization and team policy defaults --- .../homme/src/share/cxx/ExecSpaceDefs.cpp | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/components/homme/src/share/cxx/ExecSpaceDefs.cpp b/components/homme/src/share/cxx/ExecSpaceDefs.cpp index 8d496bff5d16..c9ca8a0ecd93 100644 --- a/components/homme/src/share/cxx/ExecSpaceDefs.cpp +++ b/components/homme/src/share/cxx/ExecSpaceDefs.cpp @@ -21,6 +21,10 @@ #include #endif +#ifdef KOKKOS_ENABLE_SYCL +#include +#endif + namespace Homme { // Since we're initializing from inside a Fortran code and don't have access to @@ -52,7 +56,16 @@ void initialize_kokkos () { // It isn't a big deal if we can't get the device count. nd = 1; } +#elif defined(KOKKOS_ENABLE_SYCL) + +//https://developer.codeplay.com/products/computecpp/ce/2.11.0/guides/sycl-for-cuda-developers/migrating-from-cuda-to-sycl + +//to make it build + int nd = 1; + #endif + + #ifdef HOMMEXX_ENABLE_GPU std::stringstream ss; ss << "--kokkos-num-devices=" << nd; @@ -117,6 +130,7 @@ team_num_threads_vectors_for_gpu ( assert(num_warps_total >= max_num_warps); assert(tp.max_threads_usable >= 1 && tp.max_vectors_usable >= 1); +#ifndef KOKKOS_ENABLE_SYCL int num_warps; if (tp.prefer_larger_team) { const int num_warps_usable = @@ -161,6 +175,9 @@ team_num_threads_vectors_for_gpu ( return std::make_pair( num_device_threads / num_vectors, num_vectors ); } +#else + return std::make_pair(4,16); +#endif } } // namespace Parallel From 5a43946dcf66085a54e64af76c8c5fade9a0e575 Mon Sep 17 00:00:00 2001 From: Oksana Guba Date: Thu, 5 Sep 2024 16:34:39 -0600 Subject: [PATCH 399/451] HOMME: do not add dependency on cprnc if building without PIO --- components/homme/test_execs/CMakeLists.txt | 3 +++ 1 file changed, 3 insertions(+) diff --git a/components/homme/test_execs/CMakeLists.txt b/components/homme/test_execs/CMakeLists.txt index a3113921b029..a007a5532b61 100644 --- a/components/homme/test_execs/CMakeLists.txt +++ b/components/homme/test_execs/CMakeLists.txt @@ -142,8 +142,11 @@ ADD_CUSTOM_TARGET(test-execs) ADD_CUSTOM_TARGET(check COMMAND ${CMAKE_CTEST_COMMAND} "--output-on-failure") +if(NOT BUILD_HOMME_WITHOUT_PIOLIBRARY) # Force cprnc to be built when make check is run ADD_DEPENDENCIES(check cprnc) +endif() + # Create a target for making the reference data ADD_CUSTOM_TARGET(baseline From 132b3a506b8a90274bcb9cc5f7c67cf2eafdfb20 Mon Sep 17 00:00:00 2001 From: Oksana Guba Date: Thu, 5 Sep 2024 16:30:50 -0600 Subject: [PATCH 400/451] HOMME: minor GPTL timing related mods * Disable timing in prim_main for the first two teps * Add some timers in EulerStepFunctor --- components/homme/src/prim_main.F90 | 7 ++++++- components/homme/src/share/cxx/EulerStepFunctorImpl.hpp | 5 +++++ 2 files changed, 11 insertions(+), 1 deletion(-) diff --git a/components/homme/src/prim_main.F90 b/components/homme/src/prim_main.F90 index bfbe57e8b317..d6901151d365 100644 --- a/components/homme/src/prim_main.F90 +++ b/components/homme/src/prim_main.F90 @@ -20,7 +20,7 @@ program prim_main use element_mod, only: element_t use common_io_mod, only: output_dir, infilenames use common_movie_mod, only: nextoutputstep - use perf_mod, only: t_initf, t_prf, t_finalizef, t_startf, t_stopf ! _EXTERNAL + use perf_mod, only: t_initf, t_prf, t_finalizef, t_startf, t_stopf, t_disablef, t_enablef ! _EXTERNAL use restart_io_mod , only: restartheader_t, writerestart use hybrid_mod, only: hybrid_create #if (defined MODEL_THETA_L && defined ARKODE) @@ -240,6 +240,11 @@ end subroutine finalize_kokkos_f90 nstep = nextoutputstep(tl) do while(tl%nstep= 2) call t_enablef() call t_startf('prim_run') call prim_run_subcycle(elem, hybrid,nets,nete, tstep, .false., tl, hvcoord,1) call t_stopf('prim_run') diff --git a/components/homme/src/share/cxx/EulerStepFunctorImpl.hpp b/components/homme/src/share/cxx/EulerStepFunctorImpl.hpp index f3029764dac3..f87bb108bebf 100644 --- a/components/homme/src/share/cxx/EulerStepFunctorImpl.hpp +++ b/components/homme/src/share/cxx/EulerStepFunctorImpl.hpp @@ -652,7 +652,10 @@ class EulerStepFunctorImpl { minmax_and_biharmonic(); } } + + GPTLstart("tl-at adv-n-limit"); advect_and_limit(); + GPTLstop("tl-at adv-n-limit"); exchange_qdp_dss_var(); } @@ -667,6 +670,7 @@ class EulerStepFunctorImpl { void run_tracer_phase (const KernelVariables& kv) const { compute_qtens(kv); kv.team_barrier(); + if (m_data.limiter_option == 8) { limiter_optim_iter_full(kv); kv.team_barrier(); @@ -674,6 +678,7 @@ class EulerStepFunctorImpl { limiter_clip_and_sum(kv); kv.team_barrier(); } + apply_spheremp(kv); } From 8f670095dcbf1d7fe22470031fdbdf8f2e0a8eff Mon Sep 17 00:00:00 2001 From: noel Date: Sat, 7 Sep 2024 11:36:45 -0700 Subject: [PATCH 401/451] correct my logic mistake in previous commit --- components/eam/src/dynamics/se/dyn_grid.F90 | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/components/eam/src/dynamics/se/dyn_grid.F90 b/components/eam/src/dynamics/se/dyn_grid.F90 index 125cfbca7a60..a4a8424f887b 100644 --- a/components/eam/src/dynamics/se/dyn_grid.F90 +++ b/components/eam/src/dynamics/se/dyn_grid.F90 @@ -667,16 +667,15 @@ subroutine define_cam_grids() ! The native HOMME GLL grid call cam_grid_register(trim(gridname), dyn_decomp, lat_coord, lon_coord, & grid_map_d,block_indexed=.false., unstruct=.true.) - if (single_column .or. scm_multcols) then + if (.not.single_column .or. scm_multcols) then + call cam_grid_attribute_register(trim(gridname), trim(areaname), & + 'gll grid areas', trim(ncolname), pearea, pemap) + else ! If single column model, set pearea_scm(1) to be the area as 1 value to simplify allocate(pearea_scm(1)) pearea_scm(1) = 1.0_r8 / elem(1)%rspheremp(1,1) call cam_grid_attribute_register(trim(gridname), trim(areaname), & 'gll grid areas', trim(ncolname), pearea_scm) - else - call cam_grid_attribute_register(trim(gridname), trim(areaname), & - 'gll grid areas', trim(ncolname), pearea, pemap) - end if ! .not. single_column call cam_grid_attribute_register(trim(gridname), 'np', '', np) @@ -691,7 +690,8 @@ subroutine define_cam_grids() nullify(grid_map_d) nullify(pearea) nullify(pemap) - if (single_column .or. scm_multcols) then + if (.not.single_column .or. scm_multcols) then + else nullify(pearea_scm) endif From 2e56ac054e317d047ccee5e37c40dbff2e9c7cdc Mon Sep 17 00:00:00 2001 From: noel Date: Sat, 7 Sep 2024 11:45:46 -0700 Subject: [PATCH 402/451] upgrade to intel/2023.2.0 on pm-cpu --- cime_config/machines/config_machines.xml | 18 +++++++++++++++--- 1 file changed, 15 insertions(+), 3 deletions(-) diff --git a/cime_config/machines/config_machines.xml b/cime_config/machines/config_machines.xml index 6cd9d585a25b..5b693e455268 100644 --- a/cime_config/machines/config_machines.xml +++ b/cime_config/machines/config_machines.xml @@ -223,8 +223,8 @@ - PrgEnv-intel/8.3.3 - intel/2023.1.0 + PrgEnv-intel/8.5.0 + intel/2023.2.0 @@ -239,13 +239,25 @@ cray-libsci/23.02.1.1 - + + craype-accel-host + craype/2.7.30 + cray-mpich/8.1.28 + cray-hdf5-parallel/1.12.2.9 + cray-netcdf-hdf5parallel/4.9.0.9 + cray-parallel-netcdf/1.12.3.9 + + + craype-accel-host craype/2.7.20 cray-mpich/8.1.25 cray-hdf5-parallel/1.12.2.3 cray-netcdf-hdf5parallel/4.9.0.3 cray-parallel-netcdf/1.12.3.3 + + + cmake/3.24.3 evp-patch From 1ead26f943a8d38c510eebb27872f7ebb238f092 Mon Sep 17 00:00:00 2001 From: Wuyin Lin Date: Sun, 8 Sep 2024 15:05:47 -0500 Subject: [PATCH 403/451] Update ndep and popdens files for all configs including default --- components/elm/bld/namelist_files/namelist_defaults.xml | 6 +++--- .../namelist_files/use_cases/2015-2100_SSP245_transient.xml | 6 ++++-- .../namelist_files/use_cases/2015-2100_SSP370_transient.xml | 6 ++++-- .../namelist_files/use_cases/2015-2100_SSP585_transient.xml | 6 ++++-- .../bld/namelist_files/use_cases/20thC_CMIP6_transient.xml | 6 +++--- 5 files changed, 18 insertions(+), 12 deletions(-) diff --git a/components/elm/bld/namelist_files/namelist_defaults.xml b/components/elm/bld/namelist_files/namelist_defaults.xml index e76a5647b4e7..e66ebfa637ba 100644 --- a/components/elm/bld/namelist_files/namelist_defaults.xml +++ b/components/elm/bld/namelist_files/namelist_defaults.xml @@ -666,7 +666,7 @@ this mask will have smb calculated over the entire global land surface 2000 2100 -lnd/clm2/ndepdata/fndep_elm_cbgc_exp_simyr1849-2101_1.9x2.5_c190103.nc +lnd/clm2/ndepdata/fndep_elm_cbgc_exp_simyr1849-2101_1.9x2.5_ssp245_c240903.nc lnd/clm2/ndepdata/fndep_clm_rcp8.5_simyr1849-2106_1.9x2.5_c100428.nc lnd/clm2/ndepdata/fndep_clm_rcp6.0_simyr1849-2106_1.9x2.5_c100810.nc lnd/clm2/ndepdata/fndep_clm_rcp4.5_simyr1849-2106_1.9x2.5_c100428.nc @@ -899,8 +899,8 @@ this mask will have smb calculated over the entire global land surface 1850 2010 -lnd/clm2/firedata/elmforc.ssp5_hdm_0.5x0.5_simyr1850-2100_c190109.nc -lnd/clm2/firedata/elmforc.ssp5_hdm_0.5x0.5_simyr1850-2100_c190109.nc +lnd/clm2/firedata/elmforc.Li_20181205_mod_hist_SSP2_CMIP6_hdm_0.5x0.5_AVHRR_simyr1850-2100_c240906.nc +lnd/clm2/firedata/elmforc.Li_20181205_mod_hist_SSP2_CMIP6_hdm_0.5x0.5_AVHRR_simyr1850-2100_c240906.nc bilinear diff --git a/components/elm/bld/namelist_files/use_cases/2015-2100_SSP245_transient.xml b/components/elm/bld/namelist_files/use_cases/2015-2100_SSP245_transient.xml index e313dab6b16a..6e664162609f 100755 --- a/components/elm/bld/namelist_files/use_cases/2015-2100_SSP245_transient.xml +++ b/components/elm/bld/namelist_files/use_cases/2015-2100_SSP245_transient.xml @@ -17,8 +17,10 @@ + + 1850 -2005 +2101 1850 2000 @@ -26,7 +28,7 @@ 2000 1850 -2010 +2100 1850 diff --git a/components/elm/bld/namelist_files/use_cases/2015-2100_SSP370_transient.xml b/components/elm/bld/namelist_files/use_cases/2015-2100_SSP370_transient.xml index 0e8415d3c1ab..0c54a8ce6039 100755 --- a/components/elm/bld/namelist_files/use_cases/2015-2100_SSP370_transient.xml +++ b/components/elm/bld/namelist_files/use_cases/2015-2100_SSP370_transient.xml @@ -18,16 +18,18 @@ 1850 -2005 +2101 1850 +lnd/clm2/ndepdata/fndep_elm_cbgc_exp_simyr1849-2101_1.9x2.5_ssp370_c220614.nc 2000 2000 2000 1850 -2010 +2100 1850 +lnd/clm2/firedata/elmforc.Li_20181205_mod_hist_SSP3_CMIP6_hdm_0.5x0.5_AVHRR_simyr1850-2100_c240906.nc diff --git a/components/elm/bld/namelist_files/use_cases/2015-2100_SSP585_transient.xml b/components/elm/bld/namelist_files/use_cases/2015-2100_SSP585_transient.xml index 2db3549ce5f0..c297dffe1138 100644 --- a/components/elm/bld/namelist_files/use_cases/2015-2100_SSP585_transient.xml +++ b/components/elm/bld/namelist_files/use_cases/2015-2100_SSP585_transient.xml @@ -18,16 +18,18 @@ 1850 -2005 +2101 1850 +lnd/clm2/ndepdata/fndep_elm_cbgc_exp_simyr1849-2101_1.9x2.5_ssp585_c190103.nc 2000 2000 2000 1850 -2010 +2100 1850 +lnd/clm2/firedata/elmforc.Li_20181205_mod_hist_SSP5_CMIP6_hdm_0.5x0.5_AVHRR_simyr1850-2100_c240906.nc diff --git a/components/elm/bld/namelist_files/use_cases/20thC_CMIP6_transient.xml b/components/elm/bld/namelist_files/use_cases/20thC_CMIP6_transient.xml index 92f186f1a38d..a919a4847910 100644 --- a/components/elm/bld/namelist_files/use_cases/20thC_CMIP6_transient.xml +++ b/components/elm/bld/namelist_files/use_cases/20thC_CMIP6_transient.xml @@ -9,7 +9,7 @@ 1850 -1850-2000 +1850-2015 arb_ic @@ -18,7 +18,7 @@ 1850 -2005 +2101 1850 @@ -27,7 +27,7 @@ 2000 1850 -2010 +2100 1850 From 84de5e161bc93c8980d20eafaa5ae9deea2edda5 Mon Sep 17 00:00:00 2001 From: Wuyin Lin Date: Sun, 8 Sep 2024 15:06:31 -0500 Subject: [PATCH 404/451] Reset default/placeholder co2vmr value for ssp245 --- driver-mct/cime_config/config_component_e3sm.xml | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/driver-mct/cime_config/config_component_e3sm.xml b/driver-mct/cime_config/config_component_e3sm.xml index 08758f935313..8647bdda189f 100755 --- a/driver-mct/cime_config/config_component_e3sm.xml +++ b/driver-mct/cime_config/config_component_e3sm.xml @@ -753,8 +753,7 @@ 312.821 388.717 388.717 - 0.000001 - 0.000001 + 0.000001 284.317 284.317 284.317 From a0e3ffd9bab97e983078c5ee321370ac3356c451 Mon Sep 17 00:00:00 2001 From: Wuyin Lin Date: Sun, 8 Sep 2024 21:30:03 -0700 Subject: [PATCH 405/451] Explicitly set dust_emis_scheme=2 for MMF --- driver-mct/cime_config/config_component_e3sm.xml | 1 + 1 file changed, 1 insertion(+) diff --git a/driver-mct/cime_config/config_component_e3sm.xml b/driver-mct/cime_config/config_component_e3sm.xml index acdca60ae2a6..feaa8f270a1b 100755 --- a/driver-mct/cime_config/config_component_e3sm.xml +++ b/driver-mct/cime_config/config_component_e3sm.xml @@ -863,6 +863,7 @@ 1 2 + 2 shr_dust_nl env_run.xml From e7eb37a35330c10a76d5b0a0ef808b6f6ef2de82 Mon Sep 17 00:00:00 2001 From: Jinyun Tang Date: Mon, 9 Sep 2024 11:40:32 -0500 Subject: [PATCH 406/451] bug fix for N balance error due to spval value for land use simulation When the land use data is on, at the begining of every year, the model may crash with N balance error due to including spval value in N leaching flux update. This update fixes this error by keeping those spval values away. The fix should be BFB for simulations do not involve land use data. --- .../elm/src/data_types/ColumnDataType.F90 | 32 +++++++++++-------- 1 file changed, 18 insertions(+), 14 deletions(-) diff --git a/components/elm/src/data_types/ColumnDataType.F90 b/components/elm/src/data_types/ColumnDataType.F90 index 724cefb5cfdf..d0a4a10cd3d6 100644 --- a/components/elm/src/data_types/ColumnDataType.F90 +++ b/components/elm/src/data_types/ColumnDataType.F90 @@ -7538,14 +7538,16 @@ subroutine col_cf_summary(this, bounds, num_soilc, filter_soilc, isotope) c = filter_soilc(fc) this%decomp_cpools_leached(c,l) = 0._r8 end do - do j = 1, nlev - do fc = 1,num_soilc + if(l /= i_cwd)then + do j = 1, nlev + do fc = 1,num_soilc c = filter_soilc(fc) this%decomp_cpools_leached(c,l) = & this%decomp_cpools_leached(c,l) + & this%decomp_cpools_transport_tendency(c,j,l) * dzsoi_decomp(j) - end do - end do + end do + end do + endif do fc = 1,num_soilc c = filter_soilc(fc) this%som_c_leached(c) = & @@ -9784,8 +9786,9 @@ subroutine col_nf_summary(this, bounds, num_soilc, filter_soilc) c = filter_soilc(fc) this%decomp_npools_leached(c,l) = 0._r8 end do - do j = 1, nlev - do fc = 1,num_soilc + if(l /= i_cwd)then + do j = 1, nlev + do fc = 1,num_soilc c = filter_soilc(fc) this%decomp_npools_leached(c,l) = & this%decomp_npools_leached(c,l) + & @@ -9793,8 +9796,9 @@ subroutine col_nf_summary(this, bounds, num_soilc, filter_soilc) this%bgc_npool_inputs(c,l) = this%bgc_npool_inputs(c,l) + & (this%bgc_npool_ext_inputs_vr(c,j,l)-this%bgc_npool_ext_loss_vr(c,j,l))*dzsoi_decomp(j) - end do - end do + end do + end do + endif do fc = 1,num_soilc c = filter_soilc(fc) this%som_n_leached(c) = & @@ -11314,16 +11318,16 @@ subroutine col_pf_summary(this, bounds, num_soilc, filter_soilc) c = filter_soilc(fc) this%decomp_ppools_leached(c,l) = 0._r8 end do - - do j = 1, nlevdecomp - do fc = 1,num_soilc + if(l /= i_cwd)then + do j = 1, nlevdecomp + do fc = 1,num_soilc c = filter_soilc(fc) this%decomp_ppools_leached(c,l) = & this%decomp_ppools_leached(c,l) + & this%decomp_ppools_transport_tendency(c,j,l) * dzsoi_decomp(j) - end do - end do - + end do + end do + endif do fc = 1,num_soilc c = filter_soilc(fc) this%som_p_leached(c) = & From 67cda37cb5c617f760793d04b2ee4a8e7731de14 Mon Sep 17 00:00:00 2001 From: James Foucar Date: Mon, 9 Sep 2024 13:19:32 -0600 Subject: [PATCH 407/451] Update CIME submodule with a new fix commit That fixes BFAILs not being considered DIFFs [BFB] --- cime | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cime b/cime index 2a3142fc14b1..0cdd4b1c5c5e 160000 --- a/cime +++ b/cime @@ -1 +1 @@ -Subproject commit 2a3142fc14b18fd58379f98d7d2a9a8b4b0d43a8 +Subproject commit 0cdd4b1c5c5eb2e29c6ec64667724af434847bcf From 30b9f60a441723c13a6e111767b234f8eb482f73 Mon Sep 17 00:00:00 2001 From: "Andrew M. Bradley" Date: Mon, 9 Sep 2024 14:14:42 -0500 Subject: [PATCH 408/451] Hommexx: Isolate int-bool workaround to just the C++-F90 interface code. Also fix preqx's use of use_moisture. Remove MOIST-DRY enum to avoid confusion, since it's no longer used. --- .../homme/src/preqx_kokkos/cxx/CamForcing.cpp | 6 ++--- .../cxx/cxx_f90_interface_preqx.cpp | 4 +-- .../src/preqx_kokkos/cxx/prim_advance_exp.cpp | 2 +- components/homme/src/share/control_mod.F90 | 1 - components/homme/src/share/cxx/GllFvRemap.cpp | 6 ++--- components/homme/src/share/cxx/GllFvRemap.hpp | 2 +- .../homme/src/share/cxx/GllFvRemapImpl.cpp | 6 ++--- .../homme/src/share/cxx/GllFvRemapImpl.hpp | 5 ++-- .../homme/src/share/cxx/HommexxEnums.hpp | 5 ---- components/homme/src/share/gllfvremap_mod.F90 | 9 ++++--- components/homme/src/share/namelist_mod.F90 | 6 ----- .../theta-l_kokkos/cxx/EquationOfState.hpp | 4 +-- .../cxx/HyperviscosityFunctorImpl.cpp | 6 +---- .../cxx/HyperviscosityFunctorImpl.hpp | 2 +- .../src/theta-l_kokkos/prim_driver_mod.F90 | 25 +++++++++---------- .../thetal_kokkos_ut/forcing_ut.cpp | 8 +++--- .../thetal_kokkos_ut/gllfvremap_ut.cpp | 4 +-- 17 files changed, 42 insertions(+), 59 deletions(-) diff --git a/components/homme/src/preqx_kokkos/cxx/CamForcing.cpp b/components/homme/src/preqx_kokkos/cxx/CamForcing.cpp index 2b1e6514389e..36ca5f4a95f4 100644 --- a/components/homme/src/preqx_kokkos/cxx/CamForcing.cpp +++ b/components/homme/src/preqx_kokkos/cxx/CamForcing.cpp @@ -51,7 +51,7 @@ void state_forcing( void tracer_forcing( const ExecViewUnmanaged &f_q, const HybridVCoord &hvcoord, const TimeLevel &tl, const int &num_q, - const MoistDry &moisture, const double &dt, + const bool &use_moisture, const double &dt, const ExecViewManaged &ps_v, const ExecViewManaged< Scalar * [Q_NUM_TIME_LEVELS][QSIZE_D][NP][NP][NUM_LEV]> &qdp, @@ -61,7 +61,7 @@ void tracer_forcing( const int np1 = tl.n0; const int np1_qdp = tl.n0_qdp; - if (moisture == MoistDry::MOIST) { + if (use_moisture) { // Remove the m_fq_ps_v buffer since it's not actually needed. // Instead apply the forcing to m_ps_v directly // Bonus - one less parallel reduce in dry cases! @@ -161,7 +161,7 @@ void apply_cam_forcing(const Real &dt) { tracers.fq = decltype(tracers.fq)("fq", elems.num_elems(),tracers.num_tracers()); } tracer_forcing(tracers.fq, hvcoord, tl, tracers.num_tracers(), - sim_params.moisture, dt, elems.m_state.m_ps_v, tracers.qdp, tracers.Q); + sim_params.use_moisture, dt, elems.m_state.m_ps_v, tracers.qdp, tracers.Q); GPTLstop("ApplyCAMForcing"); } diff --git a/components/homme/src/preqx_kokkos/cxx/cxx_f90_interface_preqx.cpp b/components/homme/src/preqx_kokkos/cxx/cxx_f90_interface_preqx.cpp index c75143a9836a..b433a48c2abc 100644 --- a/components/homme/src/preqx_kokkos/cxx/cxx_f90_interface_preqx.cpp +++ b/components/homme/src/preqx_kokkos/cxx/cxx_f90_interface_preqx.cpp @@ -37,7 +37,7 @@ void init_simulation_params_c (const int& remap_alg, const int& limiter_option, const int& time_step_type, const int& qsize, const int& state_frequency, const Real& nu, const Real& nu_p, const Real& nu_q, const Real& nu_s, const Real& nu_div, const Real& nu_top, const int& hypervis_order, const int& hypervis_subcycle, const double& hypervis_scaling, - const int& ftype, const bool& prescribed_wind, const bool& moisture, const bool& disable_diagnostics, + const int& ftype, const bool& prescribed_wind, const bool& use_moisture, const bool& disable_diagnostics, const bool& use_cpstar, const int& transport_alg, const int& dt_remap_factor, const int& dt_tracer_factor, const double& scale_factor, const double& laplacian_rigid_factor) @@ -90,7 +90,7 @@ void init_simulation_params_c (const int& remap_alg, const int& limiter_option, params.hypervis_subcycle = hypervis_subcycle; params.hypervis_scaling = hypervis_scaling; params.disable_diagnostics = disable_diagnostics; - params.moisture = (moisture ? MoistDry::MOIST : MoistDry::DRY); + params.use_moisture = use_moisture; params.use_cpstar = use_cpstar; params.transport_alg = transport_alg; // SphereOperators parameters; preqx supports only the sphere. diff --git a/components/homme/src/preqx_kokkos/cxx/prim_advance_exp.cpp b/components/homme/src/preqx_kokkos/cxx/prim_advance_exp.cpp index f7c7600aab8d..58e58f0160bf 100644 --- a/components/homme/src/preqx_kokkos/cxx/prim_advance_exp.cpp +++ b/components/homme/src/preqx_kokkos/cxx/prim_advance_exp.cpp @@ -34,7 +34,7 @@ void prim_advance_exp (TimeLevel& tl, const Real dt, const bool compute_diagnost // Determine the tracers time level tl.n0_qdp= -1; - if (params.moisture == MoistDry::MOIST) { + if (params.use_moisture) { tl.update_tracers_levels(params.qsplit); } diff --git a/components/homme/src/share/control_mod.F90 b/components/homme/src/share/control_mod.F90 index 9c3c599b2324..0e9494f5a6cd 100644 --- a/components/homme/src/share/control_mod.F90 +++ b/components/homme/src/share/control_mod.F90 @@ -43,7 +43,6 @@ module control_mod ! flag used by preqx, theta-l and theta-c models ! should be renamed to "hydrostatic_mode" logical, public :: theta_hydrostatic_mode - integer, public :: theta_hydrostatic_mode_integer integer, public :: tstep_type= 5 ! preqx timestepping options diff --git a/components/homme/src/share/cxx/GllFvRemap.cpp b/components/homme/src/share/cxx/GllFvRemap.cpp index a8f564958d46..7b0400427f38 100644 --- a/components/homme/src/share/cxx/GllFvRemap.cpp +++ b/components/homme/src/share/cxx/GllFvRemap.cpp @@ -21,8 +21,8 @@ void init_gllfvremap_c (int nelemd, int np, int nf, int nf_max, CF90Ptr f2g_remapd, CF90Ptr D_f, CF90Ptr Dinv_f) { auto& c = Context::singleton(); auto& g = c.get(); - g.init_data(nf, nf_max, theta_hydrostatic_mode, fv_metdet, g2f_remapd, - f2g_remapd, D_f, Dinv_f); + const bool thm = static_cast(theta_hydrostatic_mode); + g.init_data(nf, nf_max, thm, fv_metdet, g2f_remapd, f2g_remapd, D_f, Dinv_f); } GllFvRemap::GllFvRemap () { @@ -52,7 +52,7 @@ void GllFvRemap::init_boundary_exchanges () { } void GllFvRemap -::init_data (const int nf, const int nf_max, const int theta_hydrostatic_mode, +::init_data (const int nf, const int nf_max, const bool theta_hydrostatic_mode, const Real* fv_metdet, const Real* g2f_remapd, const Real* f2g_remapd, const Real* D_f, const Real* Dinv_f) { m_impl->init_data(nf, nf_max, theta_hydrostatic_mode, fv_metdet, diff --git a/components/homme/src/share/cxx/GllFvRemap.hpp b/components/homme/src/share/cxx/GllFvRemap.hpp index 2adff0aeaa96..7ebf5a82b71a 100644 --- a/components/homme/src/share/cxx/GllFvRemap.hpp +++ b/components/homme/src/share/cxx/GllFvRemap.hpp @@ -40,7 +40,7 @@ class GllFvRemap { typedef Phys2T::const_type CPhys2T; typedef Phys3T::const_type CPhys3T; - void init_data(const int nf, const int nf_max, const int theta_hydrostatic_mode, + void init_data(const int nf, const int nf_max, const bool theta_hydrostatic_mode, const Real* fv_metdet, const Real* g2f_remapd, const Real* f2g_remapd, const Real* D_f, const Real* Dinv_f); diff --git a/components/homme/src/share/cxx/GllFvRemapImpl.cpp b/components/homme/src/share/cxx/GllFvRemapImpl.cpp index d4ab5c89f510..ea1a52f5efdf 100644 --- a/components/homme/src/share/cxx/GllFvRemapImpl.cpp +++ b/components/homme/src/share/cxx/GllFvRemapImpl.cpp @@ -131,7 +131,7 @@ void GllFvRemapImpl::init_boundary_exchanges () { template using FV = Kokkos::View; void GllFvRemapImpl -::init_data (const int nf, const int nf_max, const int theta_hydrostatic_mode, +::init_data (const int nf, const int nf_max, const bool theta_hydrostatic_mode, const Real* fv_metdet_r, const Real* g2f_remapd_r, const Real* f2g_remapd_r, const Real* D_f_r, const Real* Dinv_f_r) { using Kokkos::create_mirror_view; @@ -395,7 +395,7 @@ ::run_dyn_to_fv_phys (const int timeidx, const Phys1T& ps, const Phys1T& phis, c const auto hvcoord = m_hvcoord; const bool use_moisture = m_data.use_moisture; - const int theta_hydrostatic_mode = m_data.theta_hydrostatic_mode; + const bool theta_hydrostatic_mode = m_data.theta_hydrostatic_mode; const bool want_dp_fv_out = dp_fv_out_ptr != nullptr; VPhys2T dp_fv_out; @@ -605,7 +605,7 @@ run_fv_phys_to_dyn (const int timeidx, const CPhys2T& Ts, const CPhys3T& uvs, const auto fT = m_forcing.m_ft; const auto hvcoord = m_hvcoord; const auto dp3d = m_state.m_dp3d; - const int theta_hydrostatic_mode = m_data.theta_hydrostatic_mode; + const bool theta_hydrostatic_mode = m_data.theta_hydrostatic_mode; EquationOfState eos; eos.init(theta_hydrostatic_mode, hvcoord); ElementOps ops; ops.init(hvcoord); const auto tu_ne = m_tu_ne; diff --git a/components/homme/src/share/cxx/GllFvRemapImpl.hpp b/components/homme/src/share/cxx/GllFvRemapImpl.hpp index 7388fddb1231..11738b2bf455 100644 --- a/components/homme/src/share/cxx/GllFvRemapImpl.hpp +++ b/components/homme/src/share/cxx/GllFvRemapImpl.hpp @@ -60,8 +60,7 @@ struct GllFvRemapImpl { struct Data { int nelemd, qsize, nf2, n_dss_fld; - bool use_moisture; - int theta_hydrostatic_mode; + bool use_moisture, theta_hydrostatic_mode; static constexpr int nbuf1 = 2, nbuf2 = 1; Buf1 buf1[nbuf1]; @@ -108,7 +107,7 @@ struct GllFvRemapImpl { void init_buffers(const FunctorsBuffersManager& fbm); void init_boundary_exchanges(); - void init_data(const int nf, const int nf_max, const int theta_hydrostatic_mode, + void init_data(const int nf, const int nf_max, const bool theta_hydrostatic_mode, const Real* fv_metdet_r, const Real* g2f_remapd_r, const Real* f2g_remapd_r, const Real* D_f_r, const Real* Dinv_f_r); diff --git a/components/homme/src/share/cxx/HommexxEnums.hpp b/components/homme/src/share/cxx/HommexxEnums.hpp index 59c8f3c9652c..06abbf35adbc 100644 --- a/components/homme/src/share/cxx/HommexxEnums.hpp +++ b/components/homme/src/share/cxx/HommexxEnums.hpp @@ -47,11 +47,6 @@ enum class ForcingAlg : int { FORCING_2 = 2, // TODO: Rename FORCING_1 and FORCING_2 to something more descriptive }; -enum class MoistDry { - MOIST, - DRY -}; - enum class AdvectionForm { Conservative, NonConservative diff --git a/components/homme/src/share/gllfvremap_mod.F90 b/components/homme/src/share/gllfvremap_mod.F90 index e927f04aba06..a5f9b3033c96 100644 --- a/components/homme/src/share/gllfvremap_mod.F90 +++ b/components/homme/src/share/gllfvremap_mod.F90 @@ -265,14 +265,14 @@ end subroutine gfr_init subroutine gfr_init_hxx() bind(c) #if KOKKOS_TARGET - use control_mod, only: theta_hydrostatic_mode_integer + use control_mod, only: theta_hydrostatic_mode use iso_c_binding, only: c_int interface - subroutine init_gllfvremap_c(nelemd, np, nf, nf_max, theta_hydrostatic_mode_integer, & + subroutine init_gllfvremap_c(nelemd, np, nf, nf_max, theta_hydrostatic_mode, & fv_metdet, g2f_remapd, f2g_remapd, D_f, Dinv_f) bind(c) use iso_c_binding, only: c_int, c_double integer (c_int), value, intent(in) :: nelemd, np, nf, nf_max - integer (c_int), value, intent(in) :: theta_hydrostatic_mode_integer + integer (c_int), value, intent(in) :: theta_hydrostatic_mode real (c_double), dimension(nf*nf,nelemd), intent(in) :: fv_metdet real (c_double), dimension(np,np,nf_max*nf_max), intent(in) :: g2f_remapd real (c_double), dimension(nf_max*nf_max,np,np), intent(in) :: f2g_remapd @@ -280,7 +280,8 @@ subroutine init_gllfvremap_c(nelemd, np, nf, nf_max, theta_hydrostatic_mode_inte end subroutine init_gllfvremap_c end interface integer (c_int) :: thm - thm = theta_hydrostatic_mode_integer + thm = 0 + if (theta_hydrostatic_mode) thm = 1 call init_gllfvremap_c(nelemd, np, gfr%nphys, nphys_max, thm, & gfr%fv_metdet, gfr%g2f_remapd, gfr%f2g_remapd, gfr%D_f, gfr%Dinv_f) #endif diff --git a/components/homme/src/share/namelist_mod.F90 b/components/homme/src/share/namelist_mod.F90 index a3edaa07e235..1d47090182ba 100644 --- a/components/homme/src/share/namelist_mod.F90 +++ b/components/homme/src/share/namelist_mod.F90 @@ -41,7 +41,6 @@ module namelist_mod runtype, & integration, & ! integration method theta_hydrostatic_mode, & - theta_hydrostatic_mode_integer, & transport_alg , & ! SE Eulerian, classical SL, cell-integrated SL semi_lagrange_cdr_alg, & ! see control_mod for semi_lagrange_* descriptions semi_lagrange_cdr_check, & @@ -453,10 +452,8 @@ subroutine readnl(par) planar_slice = .false. theta_hydrostatic_mode = .true. ! for preqx, this must be .true. - theta_hydrostatic_mode_integer = 1 ! for preqx, this must be .true. #if ( defined MODEL_THETA_C || defined MODEL_THETA_L ) theta_hydrostatic_mode = .false. ! default NH - theta_hydrostatic_mode_integer = 0 ! default NH #endif @@ -853,10 +850,7 @@ subroutine readnl(par) call MPI_bcast(case_planar_bubble,1,MPIlogical_t,par%root,par%comm,ierr) #endif -if(theta_hydrostatic_mode) theta_hydrostatic_mode_integer = 1 -if(.not. theta_hydrostatic_mode) theta_hydrostatic_mode_integer = 0 call MPI_bcast(theta_hydrostatic_mode ,1,MPIlogical_t,par%root,par%comm,ierr) - call MPI_bcast(theta_hydrostatic_mode_integer ,1,MPIinteger_t,par%root,par%comm,ierr) call MPI_bcast(transport_alg ,1,MPIinteger_t,par%root,par%comm,ierr) call MPI_bcast(semi_lagrange_cdr_alg ,1,MPIinteger_t,par%root,par%comm,ierr) call MPI_bcast(semi_lagrange_cdr_check ,1,MPIlogical_t,par%root,par%comm,ierr) diff --git a/components/homme/src/theta-l_kokkos/cxx/EquationOfState.hpp b/components/homme/src/theta-l_kokkos/cxx/EquationOfState.hpp index a50a28d58f55..dd97720f1be2 100644 --- a/components/homme/src/theta-l_kokkos/cxx/EquationOfState.hpp +++ b/components/homme/src/theta-l_kokkos/cxx/EquationOfState.hpp @@ -23,7 +23,7 @@ class EquationOfState { EquationOfState () = default; - void init (const int theta_hydrostatic_mode, + void init (const bool theta_hydrostatic_mode, const HybridVCoord& hvcoord) { m_theta_hydrostatic_mode = theta_hydrostatic_mode; m_hvcoord = hvcoord; @@ -250,7 +250,7 @@ class EquationOfState { public: - int m_theta_hydrostatic_mode; + bool m_theta_hydrostatic_mode; HybridVCoord m_hvcoord; }; diff --git a/components/homme/src/theta-l_kokkos/cxx/HyperviscosityFunctorImpl.cpp b/components/homme/src/theta-l_kokkos/cxx/HyperviscosityFunctorImpl.cpp index 55792051d33b..d160e114475b 100644 --- a/components/homme/src/theta-l_kokkos/cxx/HyperviscosityFunctorImpl.cpp +++ b/components/homme/src/theta-l_kokkos/cxx/HyperviscosityFunctorImpl.cpp @@ -120,11 +120,7 @@ void HyperviscosityFunctorImpl::init_params(const SimulationParams& params) #ifdef HOMMEXX_BFB_TESTING m_process_nh_vars = 1; #else - if (params.theta_hydrostatic_mode){ - m_process_nh_vars = 0; - }else{ - m_process_nh_vars = 1; - } + m_process_nh_vars = not params.theta_hydrostatic_mode; #endif } diff --git a/components/homme/src/theta-l_kokkos/cxx/HyperviscosityFunctorImpl.hpp b/components/homme/src/theta-l_kokkos/cxx/HyperviscosityFunctorImpl.hpp index 993d525422f5..a55ecbb365f9 100644 --- a/components/homme/src/theta-l_kokkos/cxx/HyperviscosityFunctorImpl.hpp +++ b/components/homme/src/theta-l_kokkos/cxx/HyperviscosityFunctorImpl.hpp @@ -397,7 +397,7 @@ class HyperviscosityFunctorImpl Buffers m_buffers; HybridVCoord m_hvcoord; - int m_process_nh_vars; + bool m_process_nh_vars; // Policies Kokkos::TeamPolicy m_policy_update_states; diff --git a/components/homme/src/theta-l_kokkos/prim_driver_mod.F90 b/components/homme/src/theta-l_kokkos/prim_driver_mod.F90 index 262ba19f4b7a..eae8544ca865 100644 --- a/components/homme/src/theta-l_kokkos/prim_driver_mod.F90 +++ b/components/homme/src/theta-l_kokkos/prim_driver_mod.F90 @@ -103,12 +103,12 @@ subroutine prim_create_c_data_structures (tl, hvcoord, mp) ! Fill the simulation params structures in C++ test_name = TRIM(test_case) // C_NULL_CHAR - if (disable_diagnostics) disable_diagnostics_int=1 - if (.not.disable_diagnostics) disable_diagnostics_int=0 - if (use_moisture) use_moisture_int=1 - if (.not.use_moisture) use_moisture_int=0 - if(theta_hydrostatic_mode) theta_hydrostatic_mode_int=1 - if(.not.theta_hydrostatic_mode) theta_hydrostatic_mode_int=0 + disable_diagnostics_int = 0 + if (disable_diagnostics) disable_diagnostics_int = 1 + use_moisture_int = 0 + if (use_moisture) use_moisture_int = 1 + theta_hydrostatic_mode_int = 0 + if (theta_hydrostatic_mode) theta_hydrostatic_mode_int = 1 call init_simulation_params_c (vert_remap_q_alg, limiter_option, rsplit, qsplit, tstep_type, & qsize, statefreq, nu, nu_p, nu_q, nu_s, nu_div, nu_top, & @@ -358,17 +358,16 @@ subroutine prim_init_kokkos_functors (allocate_buffer) ! ! Optional Input ! - integer, intent(in), optional :: allocate_buffer ! Whether functor memory buffer should be allocated internally - integer(kind=c_int) :: dummy + logical, intent(in), optional :: allocate_buffer ! Whether functor memory buffer should be allocated internally + integer(kind=c_int) :: ab ! Initialize the C++ functors in the C++ context ! If no argument allocate_buffer is present, ! let Homme internally allocate buffers + ab = 1 if (present(allocate_buffer)) then - call init_functors_c (allocate_buffer) - else - dummy=1; - call init_functors_c (dummy) - endif + if (.not. allocate_buffer) ab = 0 + end if + call init_functors_c (ab) ! Initialize boundary exchange structure in C++ call init_boundary_exchanges_c () diff --git a/components/homme/test_execs/thetal_kokkos_ut/forcing_ut.cpp b/components/homme/test_execs/thetal_kokkos_ut/forcing_ut.cpp index 5e4c51c7ca11..fb301166f429 100644 --- a/components/homme/test_execs/thetal_kokkos_ut/forcing_ut.cpp +++ b/components/homme/test_execs/thetal_kokkos_ut/forcing_ut.cpp @@ -160,8 +160,8 @@ TEST_CASE("forcing", "forcing") { std::cout << "Testing tracers forcing.\n"; for (const bool hydrostatic : {true,false}) { std::cout << " -> hydrostatic mode: " << (hydrostatic ? "true" : "false") << "\n"; - for (const MoistDry moisture : {MoistDry::DRY,MoistDry::MOIST}) { - std::cout << " -> moisture: " << (moisture==MoistDry::MOIST ? "moist" : "dry") << "\n"; + for (const bool use_moisture: {false,true}) { + std::cout << " -> moisture: " << (use_moisture ? "moist" : "dry") << "\n"; for (const bool adjustment : {true,false}) { std::cout << " -> adjustment: " << (adjustment ? "true" : "false") << "\n"; @@ -200,8 +200,8 @@ TEST_CASE("forcing", "forcing") { ff.init_buffers(fbm); // Run tracers forcing (cxx and f90) - ff.tracers_forcing(dt,np1,np1_qdp,adjustment,moisture); - tracers_forcing_f90(dt,np1+1,np1_qdp+1,hydrostatic,moisture==MoistDry::MOIST,adjustment); + ff.tracers_forcing(dt,np1,np1_qdp,adjustment,use_moisture); + tracers_forcing_f90(dt,np1+1,np1_qdp+1,hydrostatic,use_moisture,adjustment); // Compare answers Kokkos::deep_copy(h_dp,state.m_dp3d); diff --git a/components/homme/test_execs/thetal_kokkos_ut/gllfvremap_ut.cpp b/components/homme/test_execs/thetal_kokkos_ut/gllfvremap_ut.cpp index 0f14b0c3e55a..cf9db941ea1c 100644 --- a/components/homme/test_execs/thetal_kokkos_ut/gllfvremap_ut.cpp +++ b/components/homme/test_execs/thetal_kokkos_ut/gllfvremap_ut.cpp @@ -183,7 +183,7 @@ struct Session { p.qsize = qsize; p.hypervis_scaling = 0; p.transport_alg = 0; - p.moisture = MoistDry::MOIST; + p.use_moisture = true; p.theta_hydrostatic_mode = false; p.scale_factor = is_sphere ? PhysicalConstants::rearth0 : 1; p.laplacian_rigid_factor = is_sphere ? 1/p.scale_factor : 0; @@ -725,7 +725,7 @@ static void test_get_temperature (Session& s) { const auto& sp = c.get(); EquationOfState eos; eos.init(theta_hydrostatic_mode, s.h); ElementOps ops; ops.init(s.h); - const bool use_moisture = sp.moisture == MoistDry::MOIST; + const bool use_moisture = sp.use_moisture; const auto state = c.get(); const auto tracers = c.get(); const auto dp3d = state.m_dp3d; From 026ff137c209f2e811c9a31026f23e765026b718 Mon Sep 17 00:00:00 2001 From: Robert Jacob Date: Tue, 10 Sep 2024 13:09:36 -0500 Subject: [PATCH 409/451] Reduce test lengths Reduce the simulation time for tests from defaults following what is used in e3sm_integration for similar cases. --- .github/workflows/e3sm-gh-ci-cime-tests.yml | 8 ++++---- .github/workflows/e3sm-gh-ci-w-cime-tests.yml | 4 ++-- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/.github/workflows/e3sm-gh-ci-cime-tests.yml b/.github/workflows/e3sm-gh-ci-cime-tests.yml index f5c3ffcebf94..b113710f46f3 100644 --- a/.github/workflows/e3sm-gh-ci-cime-tests.yml +++ b/.github/workflows/e3sm-gh-ci-cime-tests.yml @@ -31,10 +31,10 @@ jobs: fail-fast: false matrix: test: - - SMS_D_P4.ne4pg2_oQU480.F2010.ghci-oci_gnu - - ERS_P4.ne4pg2_oQU480.F2010.ghci-oci_gnu.eam-wcprod_F2010 - - SMS_D_P4.ne4pg2_oQU480.F2010-SCREAMv1-MPASSI.ghci-oci_gnu - - ERS_P4.ne4pg2_oQU480.F2010-SCREAMv1-MPASSI.ghci-oci_gnu.eamxx-prod + - SMS_D_Ln5_P4.ne4pg2_oQU480.F2010.ghci-oci_gnu + - ERS_Ld5_P4.ne4pg2_oQU480.F2010.ghci-oci_gnu.eam-wcprod_F2010 + - SMS_D_Ln5_P4.ne4pg2_oQU480.F2010-SCREAMv1-MPASSI.ghci-oci_gnu + - ERS_Ld5_P4.ne4pg2_oQU480.F2010-SCREAMv1-MPASSI.ghci-oci_gnu.eamxx-prod container: image: ghcr.io/mahf708/e3sm-imgs:v0.0.9 diff --git a/.github/workflows/e3sm-gh-ci-w-cime-tests.yml b/.github/workflows/e3sm-gh-ci-w-cime-tests.yml index 178b9a6a4429..ca21646382b8 100644 --- a/.github/workflows/e3sm-gh-ci-w-cime-tests.yml +++ b/.github/workflows/e3sm-gh-ci-w-cime-tests.yml @@ -20,8 +20,8 @@ jobs: fail-fast: false matrix: test: - - SMS_D_P8.ne4pg2_oQU480.WCYCL2010NS.ghci-oci_gnu - - ERS_P8.ne4pg2_oQU480.WCYCL2010NS.ghci-oci_gnu.allactive-wcprod_1850 + - SMS_D_Ld1_P8.ne4pg2_oQU480.WCYCL2010NS.ghci-oci_gnu + - ERS_Ld3_P8.ne4pg2_oQU480.WCYCL2010NS.ghci-oci_gnu.allactive-wcprod_1850 container: image: ghcr.io/mahf708/e3sm-imgs:v0.0.9 From f38fe0e46ab0a225a126f793e5fbcee910dd7a78 Mon Sep 17 00:00:00 2001 From: Iulian Grindeanu Date: Tue, 10 Sep 2024 15:56:02 -0500 Subject: [PATCH 410/451] big flow error compute rof lnd interaction only if rof_c2_lnd is true we were computing an unnecessary map always even if rof_c2_lnd is false (for most coupled cases it is true) --- driver-moab/main/prep_lnd_mod.F90 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/driver-moab/main/prep_lnd_mod.F90 b/driver-moab/main/prep_lnd_mod.F90 index 44ae5490e2c6..0272e835ea03 100644 --- a/driver-moab/main/prep_lnd_mod.F90 +++ b/driver-moab/main/prep_lnd_mod.F90 @@ -222,7 +222,6 @@ subroutine prep_lnd_init(infodata, atm_c2_lnd, rof_c2_lnd, glc_c2_lnd, iac_c2_ln call seq_map_init_rcfile(mapper_Fr2l, rof(1), lnd(1), & 'seq_maps.rc','rof2lnd_fmapname:','rof2lnd_fmaptype:',samegrid_lr, & string='mapper_Fr2l initialization',esmf_map=esmf_map_flag) - end if ! symmetric of l2r, from prep_rof #ifdef HAVE_MOAB ! Call moab intx only if land and river are init in moab @@ -381,6 +380,7 @@ subroutine prep_lnd_init(infodata, atm_c2_lnd, rof_c2_lnd, glc_c2_lnd, iac_c2_ln end if ! if ((mbrxid .ge. 0) .and. (mblxid .ge. 0)) ! endif HAVE_MOAB #endif + end if call shr_sys_flush(logunit) if (atm_c2_lnd) then From 8bd4d09450caf2f6f35892c4076f9e7db270774f Mon Sep 17 00:00:00 2001 From: Azamat Mametjanov Date: Tue, 10 Sep 2024 15:58:30 -0500 Subject: [PATCH 411/451] Adjust PEs for MPAS dev-tests on Anvil --- .../testmods_dirs/config_pes_tests.xml | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/cime_config/testmods_dirs/config_pes_tests.xml b/cime_config/testmods_dirs/config_pes_tests.xml index 080e496d205b..1ac88ac5fe6f 100644 --- a/cime_config/testmods_dirs/config_pes_tests.xml +++ b/cime_config/testmods_dirs/config_pes_tests.xml @@ -37,6 +37,8 @@ -4 -4 -4 + -4 + -4 -4 @@ -203,6 +205,23 @@ + + + + tests+anvil: --compset GMPAS-JRA1p5-DIB-PISMF, 8 nodes + + -8 + -8 + -8 + -8 + -8 + -8 + -8 + -8 + + + + From 1892887ede89b000b3165ea5f76a05c5e1a3dbe2 Mon Sep 17 00:00:00 2001 From: Iulian Grindeanu Date: Tue, 10 Sep 2024 16:15:26 -0500 Subject: [PATCH 412/451] MPI group needs to be retrieved before use in case rof c2 lnd, we were not retrieving the the MPI group needed for comm graph computation, for same grid path we were retrieving it for intx only how come we never had samegrid land rof before ? --- driver-moab/main/prep_rof_mod.F90 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/driver-moab/main/prep_rof_mod.F90 b/driver-moab/main/prep_rof_mod.F90 index 59cc61c58890..a6a9184aefb5 100644 --- a/driver-moab/main/prep_rof_mod.F90 +++ b/driver-moab/main/prep_rof_mod.F90 @@ -327,6 +327,7 @@ subroutine prep_rof_init(infodata, lnd_c2_rof, atm_c2_rof, ocn_c2_rof) write(logunit,*) subname,' error in defining tags for seq_flds_a2x_fields on rof cpl' call shr_sys_abort(subname//' ERROR in defining tags for seq_flds_a2x_fields on rof cpl') endif + call seq_comm_getData(CPLID ,mpigrp=mpigrp_CPLID) if (samegrid_lr) then ! the same mesh , lnd and rof use the same dofs, but restricted ! we do not compute intersection, so we will have to just send data from lnd to rof and viceversa, by GLOBAL_ID matching @@ -363,7 +364,6 @@ subroutine prep_rof_init(infodata, lnd_c2_rof, atm_c2_rof, ocn_c2_rof) ! we also need to compute the comm graph for the second hop, from the lnd on coupler to the ! lnd for the intx lnd-rof context (coverage) ! - call seq_comm_getData(CPLID ,mpigrp=mpigrp_CPLID) type1 = 3 ! land is FV now on coupler side type2 = 3; From e4b86b6e707aa57589e4361001f1540ca4b8542b Mon Sep 17 00:00:00 2001 From: Iulian Grindeanu Date: Tue, 10 Sep 2024 18:35:51 -0500 Subject: [PATCH 413/451] reviews from Vijay --- .../data_comps/dlnd/src/dlnd_comp_mod.F90 | 4 +- driver-moab/main/prep_lnd_mod.F90 | 8 +-- driver-moab/main/prep_ocn_mod.F90 | 66 +++++++++---------- driver-moab/main/prep_rof_mod.F90 | 32 ++++----- 4 files changed, 55 insertions(+), 55 deletions(-) diff --git a/components/data_comps/dlnd/src/dlnd_comp_mod.F90 b/components/data_comps/dlnd/src/dlnd_comp_mod.F90 index 7768b2dfe815..4d76c0fe1a1f 100644 --- a/components/data_comps/dlnd/src/dlnd_comp_mod.F90 +++ b/components/data_comps/dlnd/src/dlnd_comp_mod.F90 @@ -148,10 +148,10 @@ subroutine dlnd_comp_init(Eclock, x2l, l2x, & #ifdef HAVE_MOAB character*400 tagname real(R8) latv, lonv - integer iv, tagindex, ilat, ilon !, arrsize, nfields ! ierr is already defined as integer above + integer iv, tagindex, ilat, ilon real(R8), allocatable, target :: data(:) integer(IN), pointer :: idata(:) ! temporary - real(r8), dimension(:), allocatable :: moab_vert_coords ! temporary + real(R8), dimension(:), allocatable :: moab_vert_coords ! temporary #ifdef MOABDEBUG character*100 outfile, wopts #endif diff --git a/driver-moab/main/prep_lnd_mod.F90 b/driver-moab/main/prep_lnd_mod.F90 index 0272e835ea03..7bdb12376a3d 100644 --- a/driver-moab/main/prep_lnd_mod.F90 +++ b/driver-moab/main/prep_lnd_mod.F90 @@ -1,6 +1,6 @@ module prep_lnd_mod - use shr_kind_mod , only: r8 => SHR_KIND_R8 + use shr_kind_mod , only: R8 => SHR_KIND_R8 use shr_kind_mod , only: cs => SHR_KIND_CS use shr_kind_mod , only: cl => SHR_KIND_CL use shr_kind_mod , only: cxx => SHR_KIND_CXX @@ -162,7 +162,7 @@ subroutine prep_lnd_init(infodata, atm_c2_lnd, rof_c2_lnd, glc_c2_lnd, iac_c2_ln integer nrflds ! number of rof fields projected on land integer arrsize ! for setting the r2x fields on land to 0 integer ent_type ! for setting tags - real (kind=r8) , allocatable :: tmparray (:) ! used to set the r2x fields to 0 + real (kind=R8) , allocatable :: tmparray (:) ! used to set the r2x fields to 0 #endif character(*), parameter :: subname = '(prep_lnd_init)' @@ -369,7 +369,7 @@ subroutine prep_lnd_init(infodata, atm_c2_lnd, rof_c2_lnd, glc_c2_lnd, iac_c2_ln arrsize = nrflds*mlsize allocate (tmparray(arrsize)) ! mlsize is the size of local land ! do we need to zero out others or just river ? - tmparray = 0._r8 + tmparray = 0._R8 ierr = iMOAB_SetDoubleTagStorage(mblxid, tagname, arrsize , ent_type, tmparray) if (ierr .ne. 0) then write(logunit,*) subname,' cant zero out r2x tags on land' @@ -693,7 +693,7 @@ subroutine prep_lnd_mrg_moab (infodata) #endif #ifdef MOABCOMP character(CXX) :: tagname, mct_field - real(r8) :: difference + real(R8) :: difference type(mct_list) :: temp_list integer :: size_list, index_list, ent_type type(mct_string) :: mctOStr ! diff --git a/driver-moab/main/prep_ocn_mod.F90 b/driver-moab/main/prep_ocn_mod.F90 index 44ec0c6a3c7a..b13cce62f95d 100644 --- a/driver-moab/main/prep_ocn_mod.F90 +++ b/driver-moab/main/prep_ocn_mod.F90 @@ -1,6 +1,6 @@ module prep_ocn_mod - use shr_kind_mod, only: r8 => SHR_KIND_R8 + use shr_kind_mod, only: R8 => SHR_KIND_R8 use shr_kind_mod, only: cs => SHR_KIND_CS use shr_kind_mod, only: cl => SHR_KIND_CL use shr_kind_mod, only: CX => shr_kind_CX, CXX => shr_kind_CXX @@ -137,7 +137,7 @@ module prep_ocn_mod integer , target :: x2oacc_ox_cnt ! x2oacc_ox: number of time samples accumulated ! accumulation variables for moab data - real (kind=r8) , allocatable, private, target :: x2oacc_om (:,:) ! Ocn import, ocn grid, cpl pes, moab array + real (kind=R8) , allocatable, private, target :: x2oacc_om (:,:) ! Ocn import, ocn grid, cpl pes, moab array integer , target :: x2oacc_om_cnt ! x2oacc_ox: number of time samples accumulated, in moab array integer :: arrSize_x2o_om ! this will be a module variable, size moabLocal_size * nof @@ -154,20 +154,20 @@ module prep_ocn_mod !================================================================================================ - real (kind=r8) , allocatable, private :: fractions_om (:,:) ! will retrieve the fractions from ocean, and use them + real (kind=R8) , allocatable, private :: fractions_om (:,:) ! will retrieve the fractions from ocean, and use them ! they were init with ! character(*),parameter :: fraclist_o = 'afrac:ifrac:ofrac:ifrad:ofrad' in moab, on the fractions - real (kind=r8) , allocatable, private :: x2o_om (:,:) - real (kind=r8) , allocatable, private :: a2x_om (:,:) - real (kind=r8) , allocatable, private :: i2x_om (:,:) - real (kind=r8) , allocatable, private :: r2x_om (:,:) - real (kind=r8) , allocatable, private :: xao_om (:,:) + real (kind=R8) , allocatable, private :: x2o_om (:,:) + real (kind=R8) , allocatable, private :: a2x_om (:,:) + real (kind=R8) , allocatable, private :: i2x_om (:,:) + real (kind=R8) , allocatable, private :: r2x_om (:,:) + real (kind=R8) , allocatable, private :: xao_om (:,:) ! this will be constructed first time, and be used to copy fields for shared indices ! between xao and x2o character(CXX) :: shared_fields_xao_x2o ! will need some array to hold the data for copying - real(r8) , allocatable, save :: shared_values(:) ! will be the size of shared indices * lsize + real(R8) , allocatable, save :: shared_values(:) ! will be the size of shared indices * lsize integer :: size_of_shared_values logical :: iamin_CPLALLICEID ! pe associated with CPLALLICEID @@ -268,7 +268,7 @@ subroutine prep_ocn_init(infodata, atm_c2_ocn, atm_c2_ice, ice_c2_ocn, rof_c2_oc integer arrsize ! for setting the r2x fields on land to 0 integer ent_type ! for setting tags integer noflds ! used for number of fields in allocating moab accumulated array x2oacc_om - real (kind=r8) , allocatable :: tmparray (:) ! used to set the r2x fields to 0 + real (kind=R8) , allocatable :: tmparray (:) ! used to set the r2x fields to 0 !--------------------------------------------------------------- @@ -786,7 +786,7 @@ subroutine prep_ocn_init(infodata, atm_c2_ocn, atm_c2_ice, ice_c2_ocn, rof_c2_oc arrsize = nrflds*mlsize allocate (tmparray(arrsize)) ! mlsize is the size of local land ! do we need to zero out others or just river ? - tmparray = 0._r8 + tmparray = 0._R8 ierr = iMOAB_SetDoubleTagStorage(mboxid, tagname, arrsize , ent_type, tmparray) if (ierr .ne. 0) then write(logunit,*) subname,' cant zero out r2x tags on ocn' @@ -1095,7 +1095,7 @@ subroutine prep_ocn_mrg(infodata, fractions_ox, xao_ox, timer_mrg) ! ! Local Variables integer :: eii, ewi, egi, eoi, eai, eri, exi, efi, emi - real(r8) :: flux_epbalfact ! adjusted precip factor + real(R8) :: flux_epbalfact ! adjusted precip factor type(mct_avect), pointer :: x2o_ox integer :: cnt character(*), parameter :: subname = '(prep_ocn_mrg)' @@ -1177,7 +1177,7 @@ subroutine prep_ocn_mrg_moab(infodata, xao_ox) !--------------------------------------------------------------- - real(r8) :: flux_epbalfact ! adjusted precip factor + real(R8) :: flux_epbalfact ! adjusted precip factor ! will build x2o_om , similar to x2o_ox ! no averages, just one ocn instance @@ -1187,11 +1187,11 @@ subroutine prep_ocn_mrg_moab(infodata, xao_ox) integer :: kof,kif integer :: lsize, arrsize ! for double arrays integer , save :: noflds,naflds,niflds,nrflds,nxflds! ,ngflds,nwflds, no glacier or wave model - real(r8) :: ifrac,ifracr - real(r8) :: afrac,afracr - real(r8) :: frac_sum - real(r8) :: avsdr, anidr, avsdf, anidf ! albedos - real(r8) :: fswabsv, fswabsi ! sw + real(R8) :: ifrac,ifracr + real(R8) :: afrac,afracr + real(R8) :: frac_sum + real(R8) :: avsdr, anidr, avsdf, anidf ! albedos + real(R8) :: fswabsv, fswabsi ! sw character(CL),allocatable :: field_ocn(:) ! string converted to char character(CL),allocatable :: field_atm(:) ! string converted to char character(CL),allocatable :: field_ice(:) ! string converted to char @@ -1289,7 +1289,7 @@ subroutine prep_ocn_mrg_moab(infodata, xao_ox) #endif #ifdef MOABCOMP character(CXX) :: mct_field - real(r8) :: difference + real(R8) :: difference type(mct_list) :: temp_list integer :: size_list, index_list type(mct_string) :: mctOStr ! @@ -1345,7 +1345,7 @@ subroutine prep_ocn_mrg_moab(infodata, xao_ox) allocate(a2x_om (lsize, naflds)) allocate(i2x_om (lsize, niflds)) allocate(r2x_om (lsize, nrflds)) - r2x_om = 0._r8 ! should we zero out all of them ? + r2x_om = 0._R8 ! should we zero out all of them ? allocate(xao_om (lsize, nxflds)) ! allocate fractions too ! use the fraclist fraclist_o = 'afrac:ifrac:ofrac:ifrad:ofrad' @@ -1769,7 +1769,7 @@ subroutine prep_ocn_mrg_moab(infodata, xao_ox) ifrac = fractions_om(n,kif) ! fo_kif_ifrac(n) ! fractions_o%rAttr(kif,n) afrac = fractions_om(n,kof) ! fo_kof_ofrac(n) ! fractions_o%rAttr(kof,n) frac_sum = ifrac + afrac - if ((frac_sum) /= 0._r8) then + if ((frac_sum) /= 0._R8) then ifrac = ifrac / (frac_sum) afrac = afrac / (frac_sum) endif @@ -1777,7 +1777,7 @@ subroutine prep_ocn_mrg_moab(infodata, xao_ox) ifracr = fractions_om(n,kir) ! fo_kir_ifrad(n) ! fractions_o%rAttr(kir,n) afracr = fractions_om(n,kor) ! fo_kor_ofrad(n) ! fractions_o%rAttr(kor,n) frac_sum = ifracr + afracr - if ((frac_sum) /= 0._r8) then + if ((frac_sum) /= 0._R8) then ifracr = ifracr / (frac_sum) afracr = afracr / (frac_sum) endif @@ -1913,7 +1913,7 @@ subroutine prep_ocn_mrg_moab(infodata, xao_ox) ifrac = fractions_om(n,kif) !fo_kif_ifrac(n) ! fractions_o%rAttr(kif) afrac = fractions_om(n,kof) ! fo_kof_ofrac(n) ! fractions_o%rAttr(kof,n) frac_sum = ifrac + afrac - if ((frac_sum) /= 0._r8) then + if ((frac_sum) /= 0._R8) then ifrac = ifrac / (frac_sum) afrac = afrac / (frac_sum) endif @@ -2046,7 +2046,7 @@ subroutine prep_ocn_merge( flux_epbalfact, a2x_o, i2x_o, r2x_o, w2x_o, g2x_o, xa !----------------------------------------------------------------------- ! ! Arguments - real(r8) , intent(in) :: flux_epbalfact + real(R8) , intent(in) :: flux_epbalfact type(mct_aVect), intent(in) :: a2x_o type(mct_aVect), intent(in) :: i2x_o type(mct_aVect), intent(in) :: r2x_o @@ -2061,11 +2061,11 @@ subroutine prep_ocn_merge( flux_epbalfact, a2x_o, i2x_o, r2x_o, w2x_o, g2x_o, xa integer :: kof,kif integer :: lsize integer :: noflds,naflds,niflds,nrflds,nwflds,nxflds,ngflds - real(r8) :: ifrac,ifracr - real(r8) :: afrac,afracr - real(r8) :: frac_sum - real(r8) :: avsdr, anidr, avsdf, anidf ! albedos - real(r8) :: fswabsv, fswabsi ! sw + real(R8) :: ifrac,ifracr + real(R8) :: afrac,afracr + real(R8) :: frac_sum + real(R8) :: avsdr, anidr, avsdf, anidf ! albedos + real(R8) :: fswabsv, fswabsi ! sw character(CL),allocatable :: field_ocn(:) ! string converted to char character(CL),allocatable :: field_atm(:) ! string converted to char character(CL),allocatable :: field_ice(:) ! string converted to char @@ -2584,7 +2584,7 @@ subroutine prep_ocn_merge( flux_epbalfact, a2x_o, i2x_o, r2x_o, w2x_o, g2x_o, xa ifrac = fractions_o%rAttr(kif,n) afrac = fractions_o%rAttr(kof,n) frac_sum = ifrac + afrac - if ((frac_sum) /= 0._r8) then + if ((frac_sum) /= 0._R8) then ifrac = ifrac / (frac_sum) afrac = afrac / (frac_sum) endif @@ -2592,7 +2592,7 @@ subroutine prep_ocn_merge( flux_epbalfact, a2x_o, i2x_o, r2x_o, w2x_o, g2x_o, xa ifracr = fractions_o%rAttr(kir,n) afracr = fractions_o%rAttr(kor,n) frac_sum = ifracr + afracr - if ((frac_sum) /= 0._r8) then + if ((frac_sum) /= 0._R8) then ifracr = ifracr / (frac_sum) afracr = afracr / (frac_sum) endif @@ -2738,7 +2738,7 @@ subroutine prep_ocn_merge( flux_epbalfact, a2x_o, i2x_o, r2x_o, w2x_o, g2x_o, xa ifrac = fractions_o%rAttr(kif,n) afrac = fractions_o%rAttr(kof,n) frac_sum = ifrac + afrac - if ((frac_sum) /= 0._r8) then + if ((frac_sum) /= 0._R8) then ifrac = ifrac / (frac_sum) afrac = afrac / (frac_sum) endif @@ -3068,7 +3068,7 @@ function prep_ocn_get_mapper_Sw2o() prep_ocn_get_mapper_Sw2o => mapper_Sw2o end function prep_ocn_get_mapper_Sw2o function prep_ocn_get_x2oacc_om() - real(r8), DIMENSION(:, :), pointer :: prep_ocn_get_x2oacc_om + real(R8), DIMENSION(:, :), pointer :: prep_ocn_get_x2oacc_om prep_ocn_get_x2oacc_om => x2oacc_om end function prep_ocn_get_x2oacc_om function prep_ocn_get_x2oacc_om_cnt() diff --git a/driver-moab/main/prep_rof_mod.F90 b/driver-moab/main/prep_rof_mod.F90 index a6a9184aefb5..83a8e331e916 100644 --- a/driver-moab/main/prep_rof_mod.F90 +++ b/driver-moab/main/prep_rof_mod.F90 @@ -1,7 +1,7 @@ module prep_rof_mod #include "shr_assert.h" - use shr_kind_mod, only: r8 => SHR_KIND_R8 + use shr_kind_mod, only: R8 => SHR_KIND_R8 use shr_kind_mod, only: cs => SHR_KIND_CS use shr_kind_mod, only: cl => SHR_KIND_CL use shr_kind_mod, only: cxx => SHR_KIND_CXX @@ -112,22 +112,22 @@ module prep_rof_mod ! accumulation variables over moab fields character(CXX) :: sharedFieldsLndRof ! used in moab to define l2racc_lm - real (kind=r8) , allocatable, private, target :: l2racc_lm(:,:) ! lnd export, lnd grid, cpl pes - real (kind=r8) , allocatable, private :: l2x_lm2(:,:) ! basically l2x_lm, but in another copy, on rof module + real (kind=R8) , allocatable, private, target :: l2racc_lm(:,:) ! lnd export, lnd grid, cpl pes + real (kind=R8) , allocatable, private :: l2x_lm2(:,:) ! basically l2x_lm, but in another copy, on rof module integer , target :: l2racc_lm_cnt ! l2racc_lm: number of time samples accumulated integer :: nfields_sh_lr ! number of fields in sharedFieldsLndRof integer :: lsize_lm ! size of land in moab, local character(CXX) :: sharedFieldsAtmRof ! used in moab to define a2racc_am - real (kind=r8) , allocatable, private :: a2racc_am(:,:) ! atm export, atm grid, cpl pes - real (kind=r8) , allocatable, private :: a2x_am2(:,:) ! basically a2x_am, but in another copy, on rof module + real (kind=R8) , allocatable, private :: a2racc_am(:,:) ! atm export, atm grid, cpl pes + real (kind=R8) , allocatable, private :: a2x_am2(:,:) ! basically a2x_am, but in another copy, on rof module integer , target :: a2racc_am_cnt ! a2racc_am: number of time samples accumulated integer :: nfields_sh_ar ! number of fields in sharedFieldsAtmRof integer :: lsize_am ! size of atm in moab, local character(CXX) :: sharedFieldsOcnRof ! used in moab to define o2racc_om - real (kind=r8) , allocatable, private, target :: o2racc_om(:,:) ! ocn export, ocn grid, cpl pes - real (kind=r8) , allocatable, private :: o2r_om2(:,:) ! basically o2x_om, but in another copy, on rof module, only shared with rof + real (kind=R8) , allocatable, private, target :: o2racc_om(:,:) ! ocn export, ocn grid, cpl pes + real (kind=R8) , allocatable, private :: o2r_om2(:,:) ! basically o2x_om, but in another copy, on rof module, only shared with rof integer , target :: o2racc_om_cnt ! o2racc_om: number of time samples accumulated integer :: nfields_sh_or ! number of fields in sharedFieldsOcnRof integer :: lsize_om ! size of ocn in moab, local @@ -145,12 +145,12 @@ module prep_rof_mod logical :: samegrid_al ! samegrid atm and lnd ! moab stuff - real (kind=r8) , allocatable, private :: fractions_rm (:,:) ! will retrieve the fractions from rof, and use them + real (kind=R8) , allocatable, private :: fractions_rm (:,:) ! will retrieve the fractions from rof, and use them ! they were init with ! character(*),parameter :: fraclist_r = 'lfrac:lfrin:rfrac' in moab, on the fractions - real (kind=r8) , allocatable, private :: x2r_rm (:,:) ! result of merge - real (kind=r8) , allocatable, private :: a2x_rm (:,:) - real (kind=r8) , allocatable, private :: l2x_rm (:,:) + real (kind=R8) , allocatable, private :: x2r_rm (:,:) ! result of merge + real (kind=R8) , allocatable, private :: a2x_rm (:,:) + real (kind=R8) , allocatable, private :: l2x_rm (:,:) !================================================================================================ @@ -1223,7 +1223,7 @@ subroutine prep_rof_merge(l2x_r, a2x_r, fractions_r, x2r_r, cime_model,o2x_r) integer, save :: index_x2r_coszen_str integer, save :: index_frac - real(r8) :: frac + real(R8) :: frac character(CL) :: fracstr logical, save :: first_time = .true. logical, save :: flds_wiso_rof = .false. @@ -1529,7 +1529,7 @@ subroutine prep_rof_mrg_moab (infodata, cime_model) integer, save :: index_x2r_coszen_str integer, save :: index_frac - real(r8) :: frac + real(R8) :: frac character(CL) :: fracstr logical, save :: first_time = .true. logical, save :: flds_wiso_rof = .false. @@ -1548,7 +1548,7 @@ subroutine prep_rof_mrg_moab (infodata, cime_model) character*32 :: outfile, wopts, lnum #endif #ifdef MOABCOMP - real(r8) :: difference + real(R8) :: difference type(mct_list) :: temp_list integer :: size_list, index_list type(mct_string) :: mctOStr ! @@ -1995,7 +1995,7 @@ function prep_rof_get_o2racc_om_cnt() end function prep_rof_get_o2racc_om_cnt function prep_rof_get_o2racc_om() - real(r8), DIMENSION(:, :), pointer :: prep_rof_get_o2racc_om + real(R8), DIMENSION(:, :), pointer :: prep_rof_get_o2racc_om prep_rof_get_o2racc_om => o2racc_om end function prep_rof_get_o2racc_om @@ -2011,7 +2011,7 @@ function prep_rof_get_l2racc_lm_cnt() end function prep_rof_get_l2racc_lm_cnt function prep_rof_get_l2racc_lm() - real(r8), DIMENSION(:, :), pointer :: prep_rof_get_l2racc_lm + real(R8), DIMENSION(:, :), pointer :: prep_rof_get_l2racc_lm prep_rof_get_l2racc_lm => l2racc_lm end function prep_rof_get_l2racc_lm From 73e37fab4cbf63d4ef16759bb02328f9b090798a Mon Sep 17 00:00:00 2001 From: mahf708 Date: Wed, 11 Sep 2024 08:28:27 -0700 Subject: [PATCH 414/451] update compy intel compiler --- cime_config/machines/config_machines.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/cime_config/machines/config_machines.xml b/cime_config/machines/config_machines.xml index 5eaae75f2043..ff6f9ac37597 100644 --- a/cime_config/machines/config_machines.xml +++ b/cime_config/machines/config_machines.xml @@ -3912,7 +3912,7 @@ commented out until "*** No rule to make target '.../libadios2pio-nm-lib.a'" iss gcc/8.1.0 - intel/19.0.5 + intel/20.0.0 pgi/19.10 @@ -3921,7 +3921,7 @@ commented out until "*** No rule to make target '.../libadios2pio-nm-lib.a'" iss mvapich2/2.3.1 - intelmpi/2019u4 + intelmpi/2020 intelmpi/2019u3 From 57f549be17e95ef5b1ab5e1218fcd11547608044 Mon Sep 17 00:00:00 2001 From: Gautam Bisht Date: Wed, 11 Sep 2024 12:08:35 -0700 Subject: [PATCH 415/451] Enables output of land fraction used in dust mobilization Adds a new member variable (`lnd_frc_mbl_patch`) to `dust_type` to allow output of land fraction sued in dust mobilization. This new variable is added to ELM history file and is inactive by default. [BFB] --- components/elm/src/biogeochem/DUSTMod.F90 | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/components/elm/src/biogeochem/DUSTMod.F90 b/components/elm/src/biogeochem/DUSTMod.F90 index ba24f2596697..a6ee6c6c11f8 100644 --- a/components/elm/src/biogeochem/DUSTMod.F90 +++ b/components/elm/src/biogeochem/DUSTMod.F90 @@ -69,6 +69,7 @@ module DUSTMod real(r8), pointer, private :: vlc_trb_2_patch (:) ! turbulent deposition velocity 2(m/s) real(r8), pointer, private :: vlc_trb_3_patch (:) ! turbulent deposition velocity 3(m/s) real(r8), pointer, private :: vlc_trb_4_patch (:) ! turbulent deposition velocity 4(m/s) + real(r8), pointer, private :: lnd_frc_mbl_patch (:) ! land fraction for dust mobilization (-) real(r8), pointer, private :: mbl_bsn_fct_col (:) ! basin factor contains @@ -121,7 +122,8 @@ subroutine InitAllocate(this, bounds) allocate(this%vlc_trb_2_patch (begp:endp)) ; this%vlc_trb_2_patch (:) = nan allocate(this%vlc_trb_3_patch (begp:endp)) ; this%vlc_trb_3_patch (:) = nan allocate(this%vlc_trb_4_patch (begp:endp)) ; this%vlc_trb_4_patch (:) = nan - allocate(this%mbl_bsn_fct_col (begc:endc)) ; this%mbl_bsn_fct_col (:) = nan + allocate(this%lnd_frc_mbl_patch (begp:endp)) ; this%lnd_frc_mbl_patch (:) = spval + allocate(this%mbl_bsn_fct_col (begc:endc)) ; this%mbl_bsn_fct_col (:) = nan end subroutine InitAllocate @@ -167,6 +169,11 @@ subroutine InitHistory(this, bounds) avgflag='A', long_name='turbulent deposition velocity 4', & ptr_patch=this%vlc_trb_4_patch, default='inactive') + this%lnd_frc_mbl_patch(begp:endp) = spval + call hist_addfld1d (fname='LND_FRC_DUST_MBL', units='-', & + avgflag='A', long_name='land fraction for dust mobilization', & + ptr_patch=this%lnd_frc_mbl_patch, default='inactive') + end subroutine InitHistory !----------------------------------------------------------------------- @@ -239,7 +246,6 @@ subroutine DustEmission (bounds, & real(r8) :: Cd ! [dimless] The dust emission coefficient, which depends on ! the soil's standardized threshold friction speed -YF real(r8) :: wnd_frc_slt - real(r8) :: lnd_frc_mbl(bounds%begp:bounds%endp) real(r8) :: bd real(r8) :: gwc_sfc real(r8) :: ttlai(bounds%begp:bounds%endp) @@ -287,6 +293,7 @@ subroutine DustEmission (bounds, & u10 => frictionvel_vars%u10_patch , & ! Input: [real(r8) (:) ] 10-m wind (m/s) (created for dust model) mbl_bsn_fct => dust_vars%mbl_bsn_fct_col , & ! Input: [real(r8) (:) ] basin factor + lnd_frc_mbl => dust_vars%lnd_frc_mbl_patch , & ! Output: [real(r8) (:) ] land fraction for dust mobilization flx_mss_vrt_dst => dust_vars%flx_mss_vrt_dst_patch , & ! Output: [real(r8) (:,:) ] surface dust emission (kg/m**2/s) flx_mss_vrt_dst_tot => dust_vars%flx_mss_vrt_dst_tot_patch & ! Output: [real(r8) (:) ] total dust flux back to atmosphere (pft) ) From f094149ea4e74cda23d72fddfea782abf0977e5d Mon Sep 17 00:00:00 2001 From: Naser Mahfouz Date: Wed, 11 Sep 2024 17:16:28 -0400 Subject: [PATCH 416/451] update ghci container to restore gh/ci --- .github/workflows/e3sm-gh-ci-cime-tests.yml | 6 +----- .github/workflows/e3sm-gh-ci-w-cime-tests.yml | 6 +----- cime_config/machines/config_machines.xml | 16 ++++++++-------- 3 files changed, 10 insertions(+), 18 deletions(-) diff --git a/.github/workflows/e3sm-gh-ci-cime-tests.yml b/.github/workflows/e3sm-gh-ci-cime-tests.yml index b113710f46f3..1f3f63d4f09f 100644 --- a/.github/workflows/e3sm-gh-ci-cime-tests.yml +++ b/.github/workflows/e3sm-gh-ci-cime-tests.yml @@ -36,7 +36,7 @@ jobs: - SMS_D_Ln5_P4.ne4pg2_oQU480.F2010-SCREAMv1-MPASSI.ghci-oci_gnu - ERS_Ld5_P4.ne4pg2_oQU480.F2010-SCREAMv1-MPASSI.ghci-oci_gnu.eamxx-prod container: - image: ghcr.io/mahf708/e3sm-imgs:v0.0.9 + image: ghcr.io/e3sm-project/containers-ghci:ghci-0.1.0 steps: - @@ -49,10 +49,6 @@ jobs: name: CIME working-directory: cime/scripts run: | - mkdir -p $HOME/projects/e3sm/cesm-inputdata/atm/cam/physprops/ - wget https://web.lcrc.anl.gov/public/e3sm/inputdata/atm/cam/physprops/p3_lookup_table_1.dat-v4.1.2 - mv p3_lookup_table_1.dat-v4.1.2 $HOME/projects/e3sm/cesm-inputdata/atm/cam/physprops/ - export USER=test ./create_test ${{ matrix.test }} --wait --debug - name: Artifacts diff --git a/.github/workflows/e3sm-gh-ci-w-cime-tests.yml b/.github/workflows/e3sm-gh-ci-w-cime-tests.yml index ca21646382b8..5f064bcad7f7 100644 --- a/.github/workflows/e3sm-gh-ci-w-cime-tests.yml +++ b/.github/workflows/e3sm-gh-ci-w-cime-tests.yml @@ -23,7 +23,7 @@ jobs: - SMS_D_Ld1_P8.ne4pg2_oQU480.WCYCL2010NS.ghci-oci_gnu - ERS_Ld3_P8.ne4pg2_oQU480.WCYCL2010NS.ghci-oci_gnu.allactive-wcprod_1850 container: - image: ghcr.io/mahf708/e3sm-imgs:v0.0.9 + image: ghcr.io/e3sm-project/containers-ghci:ghci-0.1.0 steps: - @@ -36,10 +36,6 @@ jobs: name: CIME working-directory: cime/scripts run: | - mkdir -p $HOME/projects/e3sm/cesm-inputdata/atm/cam/physprops/ - wget https://web.lcrc.anl.gov/public/e3sm/inputdata/atm/cam/physprops/p3_lookup_table_1.dat-v4.1.2 - mv p3_lookup_table_1.dat-v4.1.2 $HOME/projects/e3sm/cesm-inputdata/atm/cam/physprops/ - export USER=test ./create_test ${{ matrix.test }} --wait --debug - name: Artifacts diff --git a/cime_config/machines/config_machines.xml b/cime_config/machines/config_machines.xml index 30508f8a6307..daff3ed90386 100644 --- a/cime_config/machines/config_machines.xml +++ b/cime_config/machines/config_machines.xml @@ -1715,16 +1715,16 @@ commented out until "*** No rule to make target '.../libadios2pio-nm-lib.a'" iss - OCI-based container 2.0 + OCI-based container ghci-oci LINUX gnu mpich - $ENV{HOME}/projects/e3sm/scratch - $ENV{HOME}/projects/e3sm/cesm-inputdata - $ENV{HOME}/projects/e3sm/ptclm-data - $ENV{HOME}/projects/e3sm/scratch/archive/$CASE - $ENV{HOME}/projects/e3sm/baselines/$COMPILER + /projects/e3sm/scratch + /projects/e3sm/inputdata + /projects/e3sm/ptclm-data + /projects/e3sm/scratch/archive/$CASE + /projects/e3sm/baselines/$COMPILER /usr/local/packages/bin/cprnc make 4 @@ -1740,8 +1740,8 @@ commented out until "*** No rule to make target '.../libadios2pio-nm-lib.a'" iss - $ENV{HOME}/projects/e3sm/scratch/$CASE/run - $ENV{HOME}/projects/e3sm/scratch/$CASE/bld + /projects/e3sm/scratch/$CASE/run + /projects/e3sm/scratch/$CASE/bld $SRCROOT From 20d044b8e29939163657b1eb039c3b36643baee7 Mon Sep 17 00:00:00 2001 From: Naser Mahfouz Date: Wed, 11 Sep 2024 17:51:33 -0400 Subject: [PATCH 417/451] adjust artifacts to reflect recent edits --- .github/workflows/e3sm-gh-ci-cime-tests.yml | 8 ++++---- .github/workflows/e3sm-gh-ci-w-cime-tests.yml | 8 ++++---- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/.github/workflows/e3sm-gh-ci-cime-tests.yml b/.github/workflows/e3sm-gh-ci-cime-tests.yml index 1f3f63d4f09f..6c9ee1ab114c 100644 --- a/.github/workflows/e3sm-gh-ci-cime-tests.yml +++ b/.github/workflows/e3sm-gh-ci-cime-tests.yml @@ -57,7 +57,7 @@ jobs: with: name: ${{ matrix.test }} path: | - ~/projects/e3sm/scratch/${{ matrix.test }}*/TestStatus.log - ~/projects/e3sm/scratch/${{ matrix.test }}*/bld/*.bldlog.* - ~/projects/e3sm/scratch/${{ matrix.test }}*/run/*.log.* - ~/projects/e3sm/scratch/${{ matrix.test }}*/run/*.cprnc.out + /projects/e3sm/scratch/${{ matrix.test }}*/TestStatus.log + /projects/e3sm/scratch/${{ matrix.test }}*/bld/*.bldlog.* + /projects/e3sm/scratch/${{ matrix.test }}*/run/*.log.* + /projects/e3sm/scratch/${{ matrix.test }}*/run/*.cprnc.out diff --git a/.github/workflows/e3sm-gh-ci-w-cime-tests.yml b/.github/workflows/e3sm-gh-ci-w-cime-tests.yml index 5f064bcad7f7..48c367c8f625 100644 --- a/.github/workflows/e3sm-gh-ci-w-cime-tests.yml +++ b/.github/workflows/e3sm-gh-ci-w-cime-tests.yml @@ -44,7 +44,7 @@ jobs: with: name: ${{ matrix.test }} path: | - ~/projects/e3sm/scratch/${{ matrix.test }}*/TestStatus.log - ~/projects/e3sm/scratch/${{ matrix.test }}*/bld/*.bldlog.* - ~/projects/e3sm/scratch/${{ matrix.test }}*/run/*.log.* - ~/projects/e3sm/scratch/${{ matrix.test }}*/run/*.cprnc.out + /projects/e3sm/scratch/${{ matrix.test }}*/TestStatus.log + /projects/e3sm/scratch/${{ matrix.test }}*/bld/*.bldlog.* + /projects/e3sm/scratch/${{ matrix.test }}*/run/*.log.* + /projects/e3sm/scratch/${{ matrix.test }}*/run/*.cprnc.out From f21d4617fae7727c2ddfd691a598305b22a2ff54 Mon Sep 17 00:00:00 2001 From: Gautam Bisht Date: Wed, 11 Sep 2024 17:15:23 -0500 Subject: [PATCH 418/451] Updates the long_name --- components/elm/src/biogeochem/DUSTMod.F90 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/components/elm/src/biogeochem/DUSTMod.F90 b/components/elm/src/biogeochem/DUSTMod.F90 index a6ee6c6c11f8..f53e970423be 100644 --- a/components/elm/src/biogeochem/DUSTMod.F90 +++ b/components/elm/src/biogeochem/DUSTMod.F90 @@ -171,7 +171,7 @@ subroutine InitHistory(this, bounds) this%lnd_frc_mbl_patch(begp:endp) = spval call hist_addfld1d (fname='LND_FRC_DUST_MBL', units='-', & - avgflag='A', long_name='land fraction for dust mobilization', & + avgflag='A', long_name='bare soil fraction for land fraction for dust mobilization', & ptr_patch=this%lnd_frc_mbl_patch, default='inactive') end subroutine InitHistory From 059f6e3def8692f81daeb05ebdf9b87054d90b1a Mon Sep 17 00:00:00 2001 From: Wuyin Lin Date: Thu, 12 Sep 2024 12:50:30 -0500 Subject: [PATCH 419/451] Reset sim_year_range to 1850-2015 in namelist_defaults for flanduse_timeseries --- .../bld/namelist_files/namelist_defaults.xml | 32 +++++++++---------- 1 file changed, 16 insertions(+), 16 deletions(-) diff --git a/components/elm/bld/namelist_files/namelist_defaults.xml b/components/elm/bld/namelist_files/namelist_defaults.xml index e66ebfa637ba..beeae7858595 100644 --- a/components/elm/bld/namelist_files/namelist_defaults.xml +++ b/components/elm/bld/namelist_files/namelist_defaults.xml @@ -485,48 +485,48 @@ lnd/clm2/surfdata_map/surfdata_conusx4v1_simyr2000_c160503.nc dataset (arbitrarily, RCP8.5) for the historical period, because all of the RCP datasets contain the 1850-2000 period as well as the future period. --> -lnd/clm2/surfdata_map/landuse.timeseries_360x720cru_hist_simyr1850-2015_c180220.nc -lnd/clm2/surfdata_map/landuse.timeseries_0.9x1.25_hist_simyr1850-2015_c180306.nc -lnd/clm2/surfdata_map/landuse.timeseries_1.9x2.5_hist_simyr1850-2015_c180306.nc -lnd/clm2/surfdata_map/surfdata.pftdyn_10x15_rcp8.5_simyr1850-2100_c130524.nc -lnd/clm2/surfdata_map/surfdata.pftdyn_48x96_rcp8.5_simyr1850-2100_c130524.nc lnd/clm2/surfdata_map/landuse.timeseries_antarcticax4v1pg2_hist_simyr1850-2015_c210131.nc -lnd/clm2/surfdata_map/surfdata.pftdyn_1x1_tropicAtl_hist_simyr1850-2005_c130627.nc -lnd/clm2/surfdata_map/landuse.timeseries_1x1_brazil_rcp8.5_simyr1850-2100_c140610.nc -lnd/clm2/surfdata_map/landuse.timeseries_ne30np4_hist_simyr1850-2015_c180306.nc - lnd/clm2/surfdata_map/landuse.timeseries_ne30np4.pg2_hist_simyr1850-2015_c210113.nc - lnd/clm2/surfdata_map/landuse.timeseries_ne4pg2_hist_simyr1850-2015_c210722.nc - lnd/clm2/surfdata_map/landuse.timeseries_ne0np4_northamericax4v1.pg2_hist_simyr1850-2015_c211015.nc -lnd/clm2/surfdata_map/surfdata.pftdyn_ne16np4_hist_simyr1850-2005_c160803.nc -lnd/clm2/surfdata_map/surfdata.pftdyn_ne11np4_hist_simyr1850-2005_c160803.nc lnd/clm2/surfdata_map/landuse.timeseries_ne1024pg2_historical_simyr1990-2014_c240109.nc lnd/clm2/surfdata_map/landuse.timeseries_ne256pg2_hist_simyr1850-2015_c240131.nc -lnd/clm2/surfdata_map/landuse.timeseries_0.125x0.125_hist_simyr1850-2015_c191004.nc -lnd/clm2/surfdata_map/landuse.timeseries_0.5x0.5_HIST_simyr1850-2015_c211019.nc -lnd/clm2/surfdata_map/landuse.timeseries_0.5x0.5_hist_simyr1850-2015_c191004.nc From 66ce874b14ed691d12d61933cd2689f3c89f7c45 Mon Sep 17 00:00:00 2001 From: Wuyin Lin Date: Thu, 12 Sep 2024 14:49:24 -0500 Subject: [PATCH 420/451] Add LND_FRC_DUST_MBL to elm.h0 for wcprod mods --- cime_config/testmods_dirs/allactive/wcprod/user_nl_elm | 2 +- cime_config/testmods_dirs/allactive/wcprod_1850/user_nl_elm | 2 +- .../testmods_dirs/allactive/wcprod_1850_1pctCO2/user_nl_elm | 2 +- .../testmods_dirs/allactive/wcprod_1850_4xCO2/user_nl_elm | 2 +- cime_config/testmods_dirs/allactive/wcprodrrm/user_nl_elm | 2 +- cime_config/testmods_dirs/allactive/wcprodrrm_1850/user_nl_elm | 2 +- cime_config/testmods_dirs/allactive/wcprodssp/user_nl_elm | 2 +- .../cime_config/testdefs/testmods_dirs/eam/wcprod/user_nl_elm | 2 +- .../testdefs/testmods_dirs/eam/wcprod_F2010/user_nl_elm | 2 +- .../testdefs/testmods_dirs/eam/wcprod_F20TR/user_nl_elm | 2 +- 10 files changed, 10 insertions(+), 10 deletions(-) diff --git a/cime_config/testmods_dirs/allactive/wcprod/user_nl_elm b/cime_config/testmods_dirs/allactive/wcprod/user_nl_elm index cd1adab77404..9224c77e0f0a 100644 --- a/cime_config/testmods_dirs/allactive/wcprod/user_nl_elm +++ b/cime_config/testmods_dirs/allactive/wcprod/user_nl_elm @@ -33,7 +33,7 @@ hist_fexcl1 = 'AGWDNPP','ALTMAX_LASTYEAR','AVAIL_RETRANSP','AVAILC','BAF_CROP', 'SOIL4N_vr','SOIL4P_TNDNCY_VERT_TRANS','SOIL4P_TO_SMINP','SOIL4P_vr','SOLUTIONP_vr', 'TCS_MONTH_BEGIN','TCS_MONTH_END','TOTCOLCH4','water_scalar','WF', 'wlim_m','WOODC_LOSS','WTGQ' -hist_fincl1 = 'SNOWDP','COL_FIRE_CLOSS','NPOOL','PPOOL','TOTPRODC' +hist_fincl1 = 'SNOWDP','COL_FIRE_CLOSS','NPOOL','PPOOL','TOTPRODC','LND_FRC_DUST_MBL' hist_fincl2 = 'H2OSNO', 'FSNO', 'QRUNOFF', 'QSNOMELT', 'FSNO_EFF', 'SNORDSL', 'SNOW', 'FSDS', 'FSR', 'FLDS', 'FIRE', 'FIRA' hist_mfilt = 1,365 hist_nhtfrq = -24,-24 diff --git a/cime_config/testmods_dirs/allactive/wcprod_1850/user_nl_elm b/cime_config/testmods_dirs/allactive/wcprod_1850/user_nl_elm index cd1adab77404..9224c77e0f0a 100644 --- a/cime_config/testmods_dirs/allactive/wcprod_1850/user_nl_elm +++ b/cime_config/testmods_dirs/allactive/wcprod_1850/user_nl_elm @@ -33,7 +33,7 @@ hist_fexcl1 = 'AGWDNPP','ALTMAX_LASTYEAR','AVAIL_RETRANSP','AVAILC','BAF_CROP', 'SOIL4N_vr','SOIL4P_TNDNCY_VERT_TRANS','SOIL4P_TO_SMINP','SOIL4P_vr','SOLUTIONP_vr', 'TCS_MONTH_BEGIN','TCS_MONTH_END','TOTCOLCH4','water_scalar','WF', 'wlim_m','WOODC_LOSS','WTGQ' -hist_fincl1 = 'SNOWDP','COL_FIRE_CLOSS','NPOOL','PPOOL','TOTPRODC' +hist_fincl1 = 'SNOWDP','COL_FIRE_CLOSS','NPOOL','PPOOL','TOTPRODC','LND_FRC_DUST_MBL' hist_fincl2 = 'H2OSNO', 'FSNO', 'QRUNOFF', 'QSNOMELT', 'FSNO_EFF', 'SNORDSL', 'SNOW', 'FSDS', 'FSR', 'FLDS', 'FIRE', 'FIRA' hist_mfilt = 1,365 hist_nhtfrq = -24,-24 diff --git a/cime_config/testmods_dirs/allactive/wcprod_1850_1pctCO2/user_nl_elm b/cime_config/testmods_dirs/allactive/wcprod_1850_1pctCO2/user_nl_elm index cd1adab77404..9224c77e0f0a 100644 --- a/cime_config/testmods_dirs/allactive/wcprod_1850_1pctCO2/user_nl_elm +++ b/cime_config/testmods_dirs/allactive/wcprod_1850_1pctCO2/user_nl_elm @@ -33,7 +33,7 @@ hist_fexcl1 = 'AGWDNPP','ALTMAX_LASTYEAR','AVAIL_RETRANSP','AVAILC','BAF_CROP', 'SOIL4N_vr','SOIL4P_TNDNCY_VERT_TRANS','SOIL4P_TO_SMINP','SOIL4P_vr','SOLUTIONP_vr', 'TCS_MONTH_BEGIN','TCS_MONTH_END','TOTCOLCH4','water_scalar','WF', 'wlim_m','WOODC_LOSS','WTGQ' -hist_fincl1 = 'SNOWDP','COL_FIRE_CLOSS','NPOOL','PPOOL','TOTPRODC' +hist_fincl1 = 'SNOWDP','COL_FIRE_CLOSS','NPOOL','PPOOL','TOTPRODC','LND_FRC_DUST_MBL' hist_fincl2 = 'H2OSNO', 'FSNO', 'QRUNOFF', 'QSNOMELT', 'FSNO_EFF', 'SNORDSL', 'SNOW', 'FSDS', 'FSR', 'FLDS', 'FIRE', 'FIRA' hist_mfilt = 1,365 hist_nhtfrq = -24,-24 diff --git a/cime_config/testmods_dirs/allactive/wcprod_1850_4xCO2/user_nl_elm b/cime_config/testmods_dirs/allactive/wcprod_1850_4xCO2/user_nl_elm index cd1adab77404..9224c77e0f0a 100644 --- a/cime_config/testmods_dirs/allactive/wcprod_1850_4xCO2/user_nl_elm +++ b/cime_config/testmods_dirs/allactive/wcprod_1850_4xCO2/user_nl_elm @@ -33,7 +33,7 @@ hist_fexcl1 = 'AGWDNPP','ALTMAX_LASTYEAR','AVAIL_RETRANSP','AVAILC','BAF_CROP', 'SOIL4N_vr','SOIL4P_TNDNCY_VERT_TRANS','SOIL4P_TO_SMINP','SOIL4P_vr','SOLUTIONP_vr', 'TCS_MONTH_BEGIN','TCS_MONTH_END','TOTCOLCH4','water_scalar','WF', 'wlim_m','WOODC_LOSS','WTGQ' -hist_fincl1 = 'SNOWDP','COL_FIRE_CLOSS','NPOOL','PPOOL','TOTPRODC' +hist_fincl1 = 'SNOWDP','COL_FIRE_CLOSS','NPOOL','PPOOL','TOTPRODC','LND_FRC_DUST_MBL' hist_fincl2 = 'H2OSNO', 'FSNO', 'QRUNOFF', 'QSNOMELT', 'FSNO_EFF', 'SNORDSL', 'SNOW', 'FSDS', 'FSR', 'FLDS', 'FIRE', 'FIRA' hist_mfilt = 1,365 hist_nhtfrq = -24,-24 diff --git a/cime_config/testmods_dirs/allactive/wcprodrrm/user_nl_elm b/cime_config/testmods_dirs/allactive/wcprodrrm/user_nl_elm index cd1adab77404..9224c77e0f0a 100644 --- a/cime_config/testmods_dirs/allactive/wcprodrrm/user_nl_elm +++ b/cime_config/testmods_dirs/allactive/wcprodrrm/user_nl_elm @@ -33,7 +33,7 @@ hist_fexcl1 = 'AGWDNPP','ALTMAX_LASTYEAR','AVAIL_RETRANSP','AVAILC','BAF_CROP', 'SOIL4N_vr','SOIL4P_TNDNCY_VERT_TRANS','SOIL4P_TO_SMINP','SOIL4P_vr','SOLUTIONP_vr', 'TCS_MONTH_BEGIN','TCS_MONTH_END','TOTCOLCH4','water_scalar','WF', 'wlim_m','WOODC_LOSS','WTGQ' -hist_fincl1 = 'SNOWDP','COL_FIRE_CLOSS','NPOOL','PPOOL','TOTPRODC' +hist_fincl1 = 'SNOWDP','COL_FIRE_CLOSS','NPOOL','PPOOL','TOTPRODC','LND_FRC_DUST_MBL' hist_fincl2 = 'H2OSNO', 'FSNO', 'QRUNOFF', 'QSNOMELT', 'FSNO_EFF', 'SNORDSL', 'SNOW', 'FSDS', 'FSR', 'FLDS', 'FIRE', 'FIRA' hist_mfilt = 1,365 hist_nhtfrq = -24,-24 diff --git a/cime_config/testmods_dirs/allactive/wcprodrrm_1850/user_nl_elm b/cime_config/testmods_dirs/allactive/wcprodrrm_1850/user_nl_elm index cd1adab77404..9224c77e0f0a 100644 --- a/cime_config/testmods_dirs/allactive/wcprodrrm_1850/user_nl_elm +++ b/cime_config/testmods_dirs/allactive/wcprodrrm_1850/user_nl_elm @@ -33,7 +33,7 @@ hist_fexcl1 = 'AGWDNPP','ALTMAX_LASTYEAR','AVAIL_RETRANSP','AVAILC','BAF_CROP', 'SOIL4N_vr','SOIL4P_TNDNCY_VERT_TRANS','SOIL4P_TO_SMINP','SOIL4P_vr','SOLUTIONP_vr', 'TCS_MONTH_BEGIN','TCS_MONTH_END','TOTCOLCH4','water_scalar','WF', 'wlim_m','WOODC_LOSS','WTGQ' -hist_fincl1 = 'SNOWDP','COL_FIRE_CLOSS','NPOOL','PPOOL','TOTPRODC' +hist_fincl1 = 'SNOWDP','COL_FIRE_CLOSS','NPOOL','PPOOL','TOTPRODC','LND_FRC_DUST_MBL' hist_fincl2 = 'H2OSNO', 'FSNO', 'QRUNOFF', 'QSNOMELT', 'FSNO_EFF', 'SNORDSL', 'SNOW', 'FSDS', 'FSR', 'FLDS', 'FIRE', 'FIRA' hist_mfilt = 1,365 hist_nhtfrq = -24,-24 diff --git a/cime_config/testmods_dirs/allactive/wcprodssp/user_nl_elm b/cime_config/testmods_dirs/allactive/wcprodssp/user_nl_elm index 7bfdbac5c84b..e2ac4d5d1ab7 100644 --- a/cime_config/testmods_dirs/allactive/wcprodssp/user_nl_elm +++ b/cime_config/testmods_dirs/allactive/wcprodssp/user_nl_elm @@ -38,7 +38,7 @@ 'SOIL4N_vr','SOIL4P_TNDNCY_VERT_TRANS','SOIL4P_TO_SMINP','SOIL4P_vr','SOLUTIONP_vr', 'TCS_MONTH_BEGIN','TCS_MONTH_END','TOTCOLCH4','water_scalar','WF', 'wlim_m','WOODC_LOSS','WTGQ' - hist_fincl1 = 'SNOWDP','COL_FIRE_CLOSS','NPOOL','PPOOL','TOTPRODC' + hist_fincl1 = 'SNOWDP','COL_FIRE_CLOSS','NPOOL','PPOOL','TOTPRODC','LND_FRC_DUST_MBL' hist_fincl2 = 'H2OSNO', 'FSNO', 'QRUNOFF', 'QSNOMELT', 'FSNO_EFF', 'SNORDSL', 'SNOW', 'FSDS', 'FSR', 'FLDS', 'FIRE', 'FIRA' hist_mfilt = 1,365 hist_nhtfrq = -24,-24 diff --git a/components/eam/cime_config/testdefs/testmods_dirs/eam/wcprod/user_nl_elm b/components/eam/cime_config/testdefs/testmods_dirs/eam/wcprod/user_nl_elm index cd1adab77404..9224c77e0f0a 100644 --- a/components/eam/cime_config/testdefs/testmods_dirs/eam/wcprod/user_nl_elm +++ b/components/eam/cime_config/testdefs/testmods_dirs/eam/wcprod/user_nl_elm @@ -33,7 +33,7 @@ hist_fexcl1 = 'AGWDNPP','ALTMAX_LASTYEAR','AVAIL_RETRANSP','AVAILC','BAF_CROP', 'SOIL4N_vr','SOIL4P_TNDNCY_VERT_TRANS','SOIL4P_TO_SMINP','SOIL4P_vr','SOLUTIONP_vr', 'TCS_MONTH_BEGIN','TCS_MONTH_END','TOTCOLCH4','water_scalar','WF', 'wlim_m','WOODC_LOSS','WTGQ' -hist_fincl1 = 'SNOWDP','COL_FIRE_CLOSS','NPOOL','PPOOL','TOTPRODC' +hist_fincl1 = 'SNOWDP','COL_FIRE_CLOSS','NPOOL','PPOOL','TOTPRODC','LND_FRC_DUST_MBL' hist_fincl2 = 'H2OSNO', 'FSNO', 'QRUNOFF', 'QSNOMELT', 'FSNO_EFF', 'SNORDSL', 'SNOW', 'FSDS', 'FSR', 'FLDS', 'FIRE', 'FIRA' hist_mfilt = 1,365 hist_nhtfrq = -24,-24 diff --git a/components/eam/cime_config/testdefs/testmods_dirs/eam/wcprod_F2010/user_nl_elm b/components/eam/cime_config/testdefs/testmods_dirs/eam/wcprod_F2010/user_nl_elm index cd1adab77404..9224c77e0f0a 100644 --- a/components/eam/cime_config/testdefs/testmods_dirs/eam/wcprod_F2010/user_nl_elm +++ b/components/eam/cime_config/testdefs/testmods_dirs/eam/wcprod_F2010/user_nl_elm @@ -33,7 +33,7 @@ hist_fexcl1 = 'AGWDNPP','ALTMAX_LASTYEAR','AVAIL_RETRANSP','AVAILC','BAF_CROP', 'SOIL4N_vr','SOIL4P_TNDNCY_VERT_TRANS','SOIL4P_TO_SMINP','SOIL4P_vr','SOLUTIONP_vr', 'TCS_MONTH_BEGIN','TCS_MONTH_END','TOTCOLCH4','water_scalar','WF', 'wlim_m','WOODC_LOSS','WTGQ' -hist_fincl1 = 'SNOWDP','COL_FIRE_CLOSS','NPOOL','PPOOL','TOTPRODC' +hist_fincl1 = 'SNOWDP','COL_FIRE_CLOSS','NPOOL','PPOOL','TOTPRODC','LND_FRC_DUST_MBL' hist_fincl2 = 'H2OSNO', 'FSNO', 'QRUNOFF', 'QSNOMELT', 'FSNO_EFF', 'SNORDSL', 'SNOW', 'FSDS', 'FSR', 'FLDS', 'FIRE', 'FIRA' hist_mfilt = 1,365 hist_nhtfrq = -24,-24 diff --git a/components/eam/cime_config/testdefs/testmods_dirs/eam/wcprod_F20TR/user_nl_elm b/components/eam/cime_config/testdefs/testmods_dirs/eam/wcprod_F20TR/user_nl_elm index cd1adab77404..9224c77e0f0a 100644 --- a/components/eam/cime_config/testdefs/testmods_dirs/eam/wcprod_F20TR/user_nl_elm +++ b/components/eam/cime_config/testdefs/testmods_dirs/eam/wcprod_F20TR/user_nl_elm @@ -33,7 +33,7 @@ hist_fexcl1 = 'AGWDNPP','ALTMAX_LASTYEAR','AVAIL_RETRANSP','AVAILC','BAF_CROP', 'SOIL4N_vr','SOIL4P_TNDNCY_VERT_TRANS','SOIL4P_TO_SMINP','SOIL4P_vr','SOLUTIONP_vr', 'TCS_MONTH_BEGIN','TCS_MONTH_END','TOTCOLCH4','water_scalar','WF', 'wlim_m','WOODC_LOSS','WTGQ' -hist_fincl1 = 'SNOWDP','COL_FIRE_CLOSS','NPOOL','PPOOL','TOTPRODC' +hist_fincl1 = 'SNOWDP','COL_FIRE_CLOSS','NPOOL','PPOOL','TOTPRODC','LND_FRC_DUST_MBL' hist_fincl2 = 'H2OSNO', 'FSNO', 'QRUNOFF', 'QSNOMELT', 'FSNO_EFF', 'SNORDSL', 'SNOW', 'FSDS', 'FSR', 'FLDS', 'FIRE', 'FIRA' hist_mfilt = 1,365 hist_nhtfrq = -24,-24 From f30afb2f1db294c3ddda8e9dcb7bd9ffdba1a3fb Mon Sep 17 00:00:00 2001 From: Oksana Guba Date: Tue, 10 Sep 2024 19:04:55 +0000 Subject: [PATCH 421/451] switch linker back to F --- components/homme/cmake/HommeMacros.cmake | 8 +------- components/homme/cmake/machineFiles/chrysalis-bfb.cmake | 2 -- components/homme/cmake/machineFiles/chrysalis.cmake | 2 -- 3 files changed, 1 insertion(+), 11 deletions(-) diff --git a/components/homme/cmake/HommeMacros.cmake b/components/homme/cmake/HommeMacros.cmake index 5610947cb299..6d073dbbe83b 100644 --- a/components/homme/cmake/HommeMacros.cmake +++ b/components/homme/cmake/HommeMacros.cmake @@ -112,13 +112,7 @@ macro(createTestExec execName execType macroNP macroNC ADD_DEFINITIONS(-DHAVE_CONFIG_H) ADD_EXECUTABLE(${execName} ${EXEC_SOURCES}) - - if(SUNSPOT_MACHINE) - SET_TARGET_PROPERTIES(${execName} PROPERTIES LINKER_LANGUAGE CXX) - else() - SET_TARGET_PROPERTIES(${execName} PROPERTIES LINKER_LANGUAGE Fortran) - endif() - + SET_TARGET_PROPERTIES(${execName} PROPERTIES LINKER_LANGUAGE Fortran) IF(BUILD_HOMME_WITHOUT_PIOLIBRARY) TARGET_COMPILE_DEFINITIONS(${execName} PUBLIC HOMME_WITHOUT_PIOLIBRARY) ENDIF() diff --git a/components/homme/cmake/machineFiles/chrysalis-bfb.cmake b/components/homme/cmake/machineFiles/chrysalis-bfb.cmake index fa1f1ac545c5..b9f0d41a0606 100644 --- a/components/homme/cmake/machineFiles/chrysalis-bfb.cmake +++ b/components/homme/cmake/machineFiles/chrysalis-bfb.cmake @@ -17,8 +17,6 @@ ENDIF() SET (USE_MPIEXEC "srun" CACHE STRING "") SET (USE_MPI_OPTIONS "-K --cpu_bind=cores" CACHE STRING "") -SET (CHRYSALIS_MACHINE TRUE CACHE BOOL "") - # Set kokkos arch, to get correct avx flags SET (Kokkos_ARCH_ZEN2 ON CACHE BOOL "") diff --git a/components/homme/cmake/machineFiles/chrysalis.cmake b/components/homme/cmake/machineFiles/chrysalis.cmake index 97bc682c9546..68ff76ec8082 100644 --- a/components/homme/cmake/machineFiles/chrysalis.cmake +++ b/components/homme/cmake/machineFiles/chrysalis.cmake @@ -17,8 +17,6 @@ ENDIF() SET (USE_MPIEXEC "srun" CACHE STRING "") SET (USE_MPI_OPTIONS "-K --cpu_bind=cores" CACHE STRING "") -SET (CHRYSALIS_MACHINE TRUE CACHE BOOL "") - # Set kokkos arch, to get correct avx flags SET (Kokkos_ARCH_ZEN2 ON CACHE BOOL "") From a4c907fea9039e608d04799ce725de2a8f10eb1a Mon Sep 17 00:00:00 2001 From: Iulian Grindeanu Date: Thu, 12 Sep 2024 18:21:11 -0500 Subject: [PATCH 422/451] more reviews --- components/data_comps/dlnd/src/dlnd_comp_mod.F90 | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/components/data_comps/dlnd/src/dlnd_comp_mod.F90 b/components/data_comps/dlnd/src/dlnd_comp_mod.F90 index 4d76c0fe1a1f..fbd6e35cf87d 100644 --- a/components/data_comps/dlnd/src/dlnd_comp_mod.F90 +++ b/components/data_comps/dlnd/src/dlnd_comp_mod.F90 @@ -105,10 +105,13 @@ subroutine dlnd_comp_init(Eclock, x2l, l2x, & ! !DESCRIPTION: initialize dlnd model #ifdef HAVE_MOAB - use iMOAB, only: iMOAB_DefineTagStorage, iMOAB_GetDoubleTagStorage, & + use iMOAB, only: iMOAB_DefineTagStorage, & iMOAB_SetIntTagStorage, iMOAB_SetDoubleTagStorage, & iMOAB_ResolveSharedEntities, iMOAB_CreateVertices, & - iMOAB_GetMeshInfo, iMOAB_UpdateMeshInfo, iMOAB_WriteMesh + iMOAB_UpdateMeshInfo +#ifdef MOABDEBUG + use iMOAB, only: iMOAB_WriteMesh +#endif #endif implicit none From b69636d543a21c7384e239178fcfc003e8d8c705 Mon Sep 17 00:00:00 2001 From: Balwinder Singh Date: Thu, 12 Sep 2024 17:45:36 -0700 Subject: [PATCH 423/451] Updates cprnc version to match the new compiler version --- cime_config/machines/config_machines.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cime_config/machines/config_machines.xml b/cime_config/machines/config_machines.xml index ff6f9ac37597..6f0a952ac6ca 100644 --- a/cime_config/machines/config_machines.xml +++ b/cime_config/machines/config_machines.xml @@ -3865,7 +3865,7 @@ commented out until "*** No rule to make target '.../libadios2pio-nm-lib.a'" iss /compyfs/inputdata/atm/datm7 /compyfs/$USER/e3sm_scratch/archive/$CASE /compyfs/e3sm_baselines/$COMPILER - /compyfs/e3sm_baselines/cprnc/cprnc + /compyfs/e3sm_baselines/cprnc/cprnc.intel.v20.0.04/cprnc 8 e3sm_integration 4 From d5dd94cb4fe8cd53fafb3b11b46f79d07e23ecf7 Mon Sep 17 00:00:00 2001 From: Wuyin Lin Date: Fri, 13 Sep 2024 09:02:25 -0500 Subject: [PATCH 424/451] Update sim_year_range in 20thC_transient.xml --- components/elm/bld/namelist_files/use_cases/20thC_transient.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/components/elm/bld/namelist_files/use_cases/20thC_transient.xml b/components/elm/bld/namelist_files/use_cases/20thC_transient.xml index 86035ec6e081..1fe1f2860496 100644 --- a/components/elm/bld/namelist_files/use_cases/20thC_transient.xml +++ b/components/elm/bld/namelist_files/use_cases/20thC_transient.xml @@ -9,7 +9,7 @@ 1850 -1850-2000 +1850-2015 arb_ic From 2c103c0e757ab099d82746e734dead767aa6742e Mon Sep 17 00:00:00 2001 From: Charlie Zender Date: Fri, 13 Sep 2024 09:26:28 -0700 Subject: [PATCH 425/451] Allow interpinic to accept any netCDF filetype for output. Print warning and continue (instead of failing) when input has month dimension and output does not. --- .../elm/tools/interpinic/src/interpinic.F90 | 54 ++++++++++++++----- 1 file changed, 42 insertions(+), 12 deletions(-) diff --git a/components/elm/tools/interpinic/src/interpinic.F90 b/components/elm/tools/interpinic/src/interpinic.F90 index b75afd3a411d..0b8af6155775 100644 --- a/components/elm/tools/interpinic/src/interpinic.F90 +++ b/components/elm/tools/interpinic/src/interpinic.F90 @@ -146,9 +146,22 @@ subroutine interp_filei (fin, fout, cmdline) call check_ret (nf90_open(fin, NF90_NOWRITE, ncidi )) call check_ret (nf90_open(fout, NF90_NOWRITE, ncido )) call check_ret (nf_inq_format( ncido, ncformat )) - if ( ncformat /= NF_FORMAT_64BIT )then - write (6,*) 'error: output file is NOT in NetCDF large-file format!' - stop + ! 20240822 csz++ + ! Allow any format for output dataset + ! if ( ncformat /= NF_FORMAT_64BIT )then + ! write (6,*) 'error: output file is NOT in NetCDF large-file format!' + ! stop + ! 20240822 csz-- + if ( ncformat == NF_FORMAT_CLASSIC )then + write (6,*) 'info: output file is NF_FORMAT_CLASSIC' + else if ( ncformat == NF_FORMAT_64BIT_OFFSET )then + write (6,*) 'info: output file is NF_FORMAT_64BIT_OFFSET' + else if ( ncformat == NF_FORMAT_64BIT_DATA )then + write (6,*) 'info: output file is NF_FORMAT_64BIT_DATA' + else if ( ncformat == NF_FORMAT_NETCDF4 )then + write (6,*) 'info: output file is NF_FORMAT_NETCDF4' + else if ( ncformat == NF_FORMAT_NETCDF4_CLASSIC )then + write (6,*) 'info: output file is NF_FORMAT_NETCDF4_CLASSIC' end if call check_ret (nf90_inq_dimid(ncidi, "column", dimidcols )) @@ -214,13 +227,27 @@ subroutine interp_filei (fin, fout, cmdline) ret = nf90_inq_dimid(ncidi, "month", dimidmon) if (ret == NF90_NOERR) then call check_ret (nf90_inquire_dimension(ncidi, dimidmon, len=nlevmon)) - call check_ret (nf90_inq_dimid(ncido, "month", dimid )) - call check_ret (nf90_inquire_dimension(ncido, dimid, len=dimlen)) - if (dimlen/=nlevmon) then - write (6,*) 'error: input and output nlevmon values disagree' - write (6,*) 'input nlevmon = ',nlevmon,' output nlevmon = ',dimlen - stop + ! 20240912 csz++ + ! Many restart files have "month" dimension in input dataset + ! It is only necessary that the output dataset contains "month" dimension + ! when a variable in the input dataset contains the "month" dimension + ! Otherwise, the "month" dimension will never be used + ! Warn rather than die when input has "month" and output does not + !call check_ret (nf90_inq_dimid(ncido, "month", dimid )) + ret = nf90_inq_dimid(ncido, "month", dimid ) + if ( ret == nf_ebaddim ) then + write (6,*) 'warning: input has "month" dimension and output does not' + write (6,*) 'warning: interpolation will fail if any input variable uses "month" dimension' + write (6,*) 'chill: many times the "month" dimension is superfluous so this might work...' + else + call check_ret (nf90_inquire_dimension(ncido, dimid, len=dimlen)) + if (dimlen/=nlevmon) then + write (6,*) 'error: input and output nlevmon values disagree' + write (6,*) 'input nlevmon = ',nlevmon,' output nlevmon = ',dimlen + stop + end if end if + ! 20240912 csz-- else write (6,*) 'month dimension does NOT exist on the input dataset' dimidmon = -9999 @@ -321,7 +348,11 @@ subroutine interp_filei (fin, fout, cmdline) ! OK now, open the output file for writing ! call check_ret(nf90_close( ncido)) - call check_ret (nf90_open(fout, ior(NF90_WRITE, NF_64BIT_OFFSET), ncido )) + ! 20240822 csz++ + ! Allow any format for output dataset + ! call check_ret (nf90_open(fout, ior(NF90_WRITE, NF_64BIT_OFFSET), ncido )) + call check_ret (nf90_open(fout, NF90_WRITE, ncido )) + ! csz-- call addglobal (ncido, cmdline) @@ -1503,8 +1534,7 @@ subroutine addglobal (ncid, cmdline) character(len=10) :: time character(len= 5) :: zone character(len=18) :: datetime - character(len=256):: version = & - "$HeadURL: https://svn-ccsm-models.cgd.ucar.edu/clm2/trunk_tags/clm4_5_1_r085/models/lnd/clm/tools/clm4_5/interpinic/src/interpinic.F90 $" + character(len=256):: version = "" character(len=256) :: revision_id = "$Id: interpinic.F90 54953 2013-11-06 16:29:45Z sacks $" character(len=16) :: logname character(len=16) :: hostname From 4d1c5ea1a6af9249eb616ba408f6c4a0e36e293c Mon Sep 17 00:00:00 2001 From: Charlie Zender Date: Fri, 13 Sep 2024 09:42:06 -0700 Subject: [PATCH 426/451] Place hexadecimal parameters within int() intrinsic in NaN module for modern compilers (per Xylar) --- .../tools/interpinic/src/shr_infnan_mod.F90 | 88 +++++++++---------- 1 file changed, 44 insertions(+), 44 deletions(-) diff --git a/components/elm/tools/interpinic/src/shr_infnan_mod.F90 b/components/elm/tools/interpinic/src/shr_infnan_mod.F90 index 638cad84d20e..31ffb1dff329 100644 --- a/components/elm/tools/interpinic/src/shr_infnan_mod.F90 +++ b/components/elm/tools/interpinic/src/shr_infnan_mod.F90 @@ -2,11 +2,11 @@ module shr_infnan_mod -!! Inf_NaN_Detection module +!! Inf_NaN_Detection module !! Copyright(c) 2003, Lahey Computer Systems, Inc. -!! Copies of this source code, or standalone compiled files +!! Copies of this source code, or standalone compiled files !! derived from this source may not be sold without permission -!! from Lahey Computers Systems. All or part of this module may be +!! from Lahey Computers Systems. All or part of this module may be !! freely incorporated into executable programs which are offered !! for sale. Otherwise, distribution of all or part of this file is !! permitted, provided this copyright notice and header are included. @@ -22,12 +22,12 @@ module shr_infnan_mod !! isneginf(x) - test for a negative "infinite" value !! !! Each function accepts a single or double precision real argument, and -!! returns a true or false value to indicate the presence of the value +!! returns a true or false value to indicate the presence of the value !! being tested for. If the argument is array valued, the function returns !! a conformable logical array, suitable for use with the ANY function, or !! as a logical mask. !! -!! Each function operates by transferring the bit pattern from a real +!! Each function operates by transferring the bit pattern from a real !! variable to an integer container. Unless testing for + or - infinity, !! the sign bit is cleared to zero. The value is exclusive ORed with !! the value being tested for. The integer result of the IEOR function is @@ -48,14 +48,14 @@ module shr_infnan_mod integer, parameter :: Double = selected_int_kind(precision(1.0_r8)) ! Single precision IEEE values - integer(Single), parameter :: sNaN = Z"7FC00000" - integer(Single), parameter :: sPosInf = Z"7F800000" - integer(Single), parameter :: sNegInf = Z"FF800000" + integer(Single), parameter :: sNaN = int(Z"7FC00000") + integer(Single), parameter :: sPosInf = int(Z"7F800000") + integer(Single), parameter :: sNegInf = int(Z"FF800000") ! Double precision IEEE values - integer(Double), parameter :: dNaN = Z"7FF8000000000000" - integer(Double), parameter :: dPosInf = Z"7FF0000000000000" - integer(Double), parameter :: dNegInf = Z"FFF0000000000000" + integer(Double), parameter :: dNaN = int(Z"7FF8000000000000") + integer(Double), parameter :: dPosInf = int(Z"7FF0000000000000") + integer(Double), parameter :: dNegInf = int(Z"FFF0000000000000") ! Locatation of single and double precision sign bit (Intel) ! Subtract one because bit numbering starts at zero @@ -84,22 +84,22 @@ module shr_infnan_mod module procedure sisnan module procedure disnan #endif - end interface + end interface interface shr_infnan_isinf module procedure sisinf module procedure disinf - end interface - + end interface + interface shr_infnan_isposinf module procedure sisposinf module procedure disposinf - end interface - + end interface + interface shr_infnan_isneginf module procedure sisneginf module procedure disneginf - end interface + end interface integer :: shr_sisnan @@ -107,7 +107,7 @@ module shr_infnan_mod integer :: shr_disnan external :: shr_disnan -contains +contains ! ! If FORTRAN intrinsic's exist use them @@ -134,7 +134,7 @@ elemental function sisnan(x) result(res) res = isnan(x) #endif - end function + end function ! Double precision test for NaN elemental function disnan(d) result(res) @@ -156,7 +156,7 @@ elemental function disnan(d) result(res) res = isnan(d) #endif - end function + end function ! ! Otherwise link to a C function call that either uses the C90 isnan function or a x != x check @@ -176,13 +176,13 @@ function c_sisnan_1D(x) result(res) real(r4), intent(in) :: x(:) logical :: res(size(x)) - integer :: i + integer :: i do i = 1, size(x) res(i) = (shr_sisnan(x(i)) /= 0) end do end function c_sisnan_1D - + function c_sisnan_2D(x) result(res) real(r4), intent(in) :: x(:,:) logical :: res(size(x,1),size(x,2)) @@ -195,7 +195,7 @@ function c_sisnan_2D(x) result(res) end do end do end function c_sisnan_2D - + function c_sisnan_3D(x) result(res) real(r4), intent(in) :: x(:,:,:) logical :: res(size(x,1),size(x,2),size(x,3)) @@ -210,7 +210,7 @@ function c_sisnan_3D(x) result(res) end do end do end function c_sisnan_3D - + function c_sisnan_4D(x) result(res) real(r4), intent(in) :: x(:,:,:,:) logical :: res(size(x,1),size(x,2),size(x,3),size(x,4)) @@ -227,7 +227,7 @@ function c_sisnan_4D(x) result(res) end do end do end function c_sisnan_4D - + function c_sisnan_5D(x) result(res) real(r4), intent(in) :: x(:,:,:,:,:) logical :: res(size(x,1),size(x,2),size(x,3),size(x,4),size(x,5)) @@ -246,7 +246,7 @@ function c_sisnan_5D(x) result(res) end do end do end function c_sisnan_5D - + function c_sisnan_6D(x) result(res) real(r4), intent(in) :: x(:,:,:,:,:,:) logical :: res(size(x,1),size(x,2),size(x,3),size(x,4),size(x,5),size(x,6)) @@ -267,7 +267,7 @@ function c_sisnan_6D(x) result(res) end do end do end function c_sisnan_6D - + function c_sisnan_7D(x) result(res) real(r4), intent(in) :: x(:,:,:,:,:,:,:) logical :: res(size(x,1),size(x,2),size(x,3),size(x,4),size(x,5),size(x,6),size(x,7)) @@ -290,7 +290,7 @@ function c_sisnan_7D(x) result(res) end do end do end function c_sisnan_7D - + function c_disnan_scalar(x) result(res) real(r8), intent(in) :: x logical :: res @@ -302,13 +302,13 @@ function c_disnan_1D(x) result(res) real(r8), intent(in) :: x(:) logical :: res(size(x)) - integer :: i + integer :: i do i = 1, size(x) res(i) = (shr_disnan(x(i)) /= 0) end do end function c_disnan_1D - + function c_disnan_2D(x) result(res) real(r8), intent(in) :: x(:,:) logical :: res(size(x,1),size(x,2)) @@ -321,7 +321,7 @@ function c_disnan_2D(x) result(res) end do end do end function c_disnan_2D - + function c_disnan_3D(x) result(res) real(r8), intent(in) :: x(:,:,:) logical :: res(size(x,1),size(x,2),size(x,3)) @@ -336,7 +336,7 @@ function c_disnan_3D(x) result(res) end do end do end function c_disnan_3D - + function c_disnan_4D(x) result(res) real(r8), intent(in) :: x(:,:,:,:) logical :: res(size(x,1),size(x,2),size(x,3),size(x,4)) @@ -353,7 +353,7 @@ function c_disnan_4D(x) result(res) end do end do end function c_disnan_4D - + function c_disnan_5D(x) result(res) real(r8), intent(in) :: x(:,:,:,:,:) logical :: res(size(x,1),size(x,2),size(x,3),size(x,4),size(x,5)) @@ -372,7 +372,7 @@ function c_disnan_5D(x) result(res) end do end do end function c_disnan_5D - + function c_disnan_6D(x) result(res) real(r8), intent(in) :: x(:,:,:,:,:,:) logical :: res(size(x,1),size(x,2),size(x,3),size(x,4),size(x,5),size(x,6)) @@ -393,7 +393,7 @@ function c_disnan_6D(x) result(res) end do end do end function c_disnan_6D - + function c_disnan_7D(x) result(res) real(r8), intent(in) :: x(:,:,:,:,:,:,:) logical :: res(size(x,1),size(x,2),size(x,3),size(x,4),size(x,5),size(x,6),size(x,7)) @@ -418,48 +418,48 @@ function c_disnan_7D(x) result(res) end function c_disnan_7D #endif - + ! Single precision test for Inf elemental function sisinf(x) result(res) real(r4), intent(in) :: x logical :: res res = ieor(ibclr(transfer(x,sPosInf),SPSB), sPosInf) == 0 - end function + end function ! Double precision test for Inf elemental function disinf(d) result(res) real(r8), intent(in) :: d logical :: res res = ieor(ibclr(transfer(d,dPosInf),DPSB), dPosInf) == 0 - end function - + end function + ! Single precision test for +Inf elemental function sisposinf(x) result(res) real(r4), intent(in) :: x logical :: res res = ieor(transfer(x,sPosInf), sPosInf) == 0 - end function + end function ! Double precision test for +Inf elemental function disposinf(d) result(res) real(r8), intent(in) :: d logical :: res res = ieor(transfer(d,dPosInf), dPosInf) == 0 - end function - + end function + ! Single precision test for -Inf elemental function sisneginf(x) result(res) real(r4), intent(in) :: x logical :: res res = ieor(transfer(x,sNegInf), sNegInf) == 0 - end function + end function ! Double precision test for -Inf elemental function disneginf(d) result(res) real(r8), intent(in) :: d logical :: res res = ieor(transfer(d,dNegInf), dNegInf) == 0 - end function + end function end module shr_infnan_mod From c11886bcd6e3056be6dd28ca577ea6f97bd807ec Mon Sep 17 00:00:00 2001 From: jayeshkrishna Date: Wed, 11 Sep 2024 23:06:33 -0500 Subject: [PATCH 427/451] Log PIO buffer size limit for default case Logging the SCORPIO internal buffer cache size when the user lets the library choose the buffer size (the default case) --- share/util/shr_pio_mod.F90 | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/share/util/shr_pio_mod.F90 b/share/util/shr_pio_mod.F90 index 0935bce351a5..d500cbc680a2 100644 --- a/share/util/shr_pio_mod.F90 +++ b/share/util/shr_pio_mod.F90 @@ -173,17 +173,24 @@ subroutine shr_pio_init2(comp_id, comp_name, comp_iamin, comp_comm, comp_comm_ia logical, intent(in) :: comp_iamin(:) character(len=*), intent(in) :: comp_name(:) integer, intent(in) :: comp_comm(:), comp_comm_iam(:) + integer(kind=pio_offset_kind) :: cur_buffer_size_limit=-1 integer :: i character(len=shr_kind_cl) :: nlfilename, cname integer :: ret character(*), parameter :: subName = '(shr_pio_init2) ' ! 0 is a valid value of pio_buffer_size_limit - if(pio_buffer_size_limit>=0) then + ! -1 is the value used by CIME to let the library choose the buffer limit + if(pio_buffer_size_limit>=-1) then + call pio_set_buffer_size_limit(pio_buffer_size_limit, prev_limit=cur_buffer_size_limit) if(comp_comm_iam(1)==0) then - write(shr_log_unit,*) 'Setting pio_buffer_size_limit : ',pio_buffer_size_limit + if(pio_buffer_size_limit >= 0) then + write(shr_log_unit,*) 'Set pio_buffer_size_limit to : ', pio_buffer_size_limit, ' (bytes)' + else + ! Default pio_buffer_size_limit + write(shr_log_unit,*) 'Using pio_buffer_size_limit (default): ', cur_buffer_size_limit, ' (bytes)' + end if end if - call pio_set_buffer_size_limit(pio_buffer_size_limit) endif if(pio_blocksize>0) then if(comp_comm_iam(1)==0) then From 25fcf92996d401b7c674c8a7f18abad1c798583e Mon Sep 17 00:00:00 2001 From: Walter Hannah Date: Fri, 13 Sep 2024 14:21:12 -0700 Subject: [PATCH 428/451] add newline at end of file --- components/eam/cime_config/usermods_dirs/rcemip/user_nl_cpl | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/components/eam/cime_config/usermods_dirs/rcemip/user_nl_cpl b/components/eam/cime_config/usermods_dirs/rcemip/user_nl_cpl index e3d4433d4a8d..3a47a8bb2ff9 100644 --- a/components/eam/cime_config/usermods_dirs/rcemip/user_nl_cpl +++ b/components/eam/cime_config/usermods_dirs/rcemip/user_nl_cpl @@ -31,4 +31,5 @@ seq_flux_mct_albdif = 0.07 seq_flux_mct_albdir = 0.07 seq_flux_atmocn_minwind = 1 -constant_zenith_deg = 42.04 \ No newline at end of file +constant_zenith_deg = 42.04 + From ef7aeca234bdd44b9bce518671e69489e13df6b6 Mon Sep 17 00:00:00 2001 From: Charlie Zender Date: Fri, 13 Sep 2024 16:38:59 -0700 Subject: [PATCH 429/451] remove external qualifier from iargc definition --- components/elm/tools/interpinic/src/fmain.F90 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/components/elm/tools/interpinic/src/fmain.F90 b/components/elm/tools/interpinic/src/fmain.F90 index 0f55c12c67c9..a67e6e2627fb 100644 --- a/components/elm/tools/interpinic/src/fmain.F90 +++ b/components/elm/tools/interpinic/src/fmain.F90 @@ -14,7 +14,7 @@ program fmain character(len= 256) :: arg integer :: n !index integer :: nargs !number of arguments - integer, external :: iargc !number of arguments function + integer :: iargc !number of arguments function character(len=256) :: finidati !input initial dataset to read character(len=256) :: finidato !output initial dataset to create character(len=256) :: cmdline !input command line From ece56d136c5861288291243cae2f49e73414c250 Mon Sep 17 00:00:00 2001 From: Charlie Zender Date: Fri, 13 Sep 2024 16:59:21 -0700 Subject: [PATCH 430/451] Remove commented-out code, CSZ markers, and dates last changed --- .../elm/tools/interpinic/src/interpinic.F90 | 16 +++++----------- 1 file changed, 5 insertions(+), 11 deletions(-) diff --git a/components/elm/tools/interpinic/src/interpinic.F90 b/components/elm/tools/interpinic/src/interpinic.F90 index 0b8af6155775..3d890a14b895 100644 --- a/components/elm/tools/interpinic/src/interpinic.F90 +++ b/components/elm/tools/interpinic/src/interpinic.F90 @@ -146,12 +146,9 @@ subroutine interp_filei (fin, fout, cmdline) call check_ret (nf90_open(fin, NF90_NOWRITE, ncidi )) call check_ret (nf90_open(fout, NF90_NOWRITE, ncido )) call check_ret (nf_inq_format( ncido, ncformat )) - ! 20240822 csz++ + ! Allow any format for output dataset - ! if ( ncformat /= NF_FORMAT_64BIT )then - ! write (6,*) 'error: output file is NOT in NetCDF large-file format!' - ! stop - ! 20240822 csz-- + if ( ncformat == NF_FORMAT_CLASSIC )then write (6,*) 'info: output file is NF_FORMAT_CLASSIC' else if ( ncformat == NF_FORMAT_64BIT_OFFSET )then @@ -227,13 +224,13 @@ subroutine interp_filei (fin, fout, cmdline) ret = nf90_inq_dimid(ncidi, "month", dimidmon) if (ret == NF90_NOERR) then call check_ret (nf90_inquire_dimension(ncidi, dimidmon, len=nlevmon)) - ! 20240912 csz++ + ! Many restart files have "month" dimension in input dataset ! It is only necessary that the output dataset contains "month" dimension ! when a variable in the input dataset contains the "month" dimension ! Otherwise, the "month" dimension will never be used ! Warn rather than die when input has "month" and output does not - !call check_ret (nf90_inq_dimid(ncido, "month", dimid )) + ret = nf90_inq_dimid(ncido, "month", dimid ) if ( ret == nf_ebaddim ) then write (6,*) 'warning: input has "month" dimension and output does not' @@ -247,7 +244,6 @@ subroutine interp_filei (fin, fout, cmdline) stop end if end if - ! 20240912 csz-- else write (6,*) 'month dimension does NOT exist on the input dataset' dimidmon = -9999 @@ -348,11 +344,9 @@ subroutine interp_filei (fin, fout, cmdline) ! OK now, open the output file for writing ! call check_ret(nf90_close( ncido)) - ! 20240822 csz++ + ! Allow any format for output dataset - ! call check_ret (nf90_open(fout, ior(NF90_WRITE, NF_64BIT_OFFSET), ncido )) call check_ret (nf90_open(fout, NF90_WRITE, ncido )) - ! csz-- call addglobal (ncido, cmdline) From 2aadb974efacf339f7e76e6ce98f250da573aefc Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 16 Sep 2024 11:02:49 +0000 Subject: [PATCH 431/451] Bump DavidAnson/markdownlint-cli2-action from 16 to 17 Bumps [DavidAnson/markdownlint-cli2-action](https://github.com/davidanson/markdownlint-cli2-action) from 16 to 17. - [Release notes](https://github.com/davidanson/markdownlint-cli2-action/releases) - [Commits](https://github.com/davidanson/markdownlint-cli2-action/compare/v16...v17) --- updated-dependencies: - dependency-name: DavidAnson/markdownlint-cli2-action dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] --- .github/workflows/e3sm-gh-md-linter.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/e3sm-gh-md-linter.yml b/.github/workflows/e3sm-gh-md-linter.yml index 507c2c3745ea..424a871637b6 100644 --- a/.github/workflows/e3sm-gh-md-linter.yml +++ b/.github/workflows/e3sm-gh-md-linter.yml @@ -22,7 +22,7 @@ jobs: with: files: '**/*.md' separator: "," - - uses: DavidAnson/markdownlint-cli2-action@v16 + - uses: DavidAnson/markdownlint-cli2-action@v17 if: steps.changed-files.outputs.any_changed == 'true' with: config: 'docs/.markdownlint.json' From dfeefffa109c1136068eefce1881121f67951a4f Mon Sep 17 00:00:00 2001 From: Walter Hannah Date: Mon, 16 Sep 2024 08:31:31 -0700 Subject: [PATCH 432/451] clean up new mock-walker SST section to make it more compact and less redundant --- .../data_comps/docn/src/docn_comp_mod.F90 | 49 +++---------------- 1 file changed, 7 insertions(+), 42 deletions(-) diff --git a/components/data_comps/docn/src/docn_comp_mod.F90 b/components/data_comps/docn/src/docn_comp_mod.F90 index ac1278673656..43bac32bff73 100644 --- a/components/data_comps/docn/src/docn_comp_mod.F90 +++ b/components/data_comps/docn/src/docn_comp_mod.F90 @@ -1177,52 +1177,17 @@ subroutine prescribed_sst(xc, yc, lsize, sst_option, sst) !------------------------------------------------------------------------------- ! RCEMIP phase 2 - Mock-Walker - - ! MW_295dT1p25 - mean SST = 295 K / dSST = 1.25 K - - if (sst_option == 11) then - mean_SST = 295 - TkFrz - delta_SST = 1.25 - do i = 1, lsize - sst(i) = mean_SST + (delta_SST/2) * cos( rlat(i) * 360/54 ) - end do - end if - - ! MW_300dT0p625 - mean SST = 300 K / dSST = 0.625 K - if (sst_option == 12) then - mean_SST = 300 - TkFrz - delta_SST = 0.625 - do i = 1, lsize - sst(i) = mean_SST + (delta_SST/2) * cos( rlat(i) * 360/54 ) - end do - end if - - ! MW_300dT1p25 - mean SST = 300 K / dSST = 1.25 K - if (sst_option == 13) then - mean_SST = 300 - TkFrz - delta_SST = 1.25 - do i = 1, lsize - sst(i) = mean_SST + (delta_SST/2) * cos( rlat(i) * 360/54 ) - end do - end if - - ! MW_300dT2p5 - mean SST = 300 K / dSST = 2.5 K - if (sst_option == 14) then - mean_SST = 300 - TkFrz - delta_SST = 2.5 - do i = 1, lsize - sst(i) = mean_SST + (delta_SST/2) * cos( rlat(i) * 360/54 ) - end do - end if - - ! MW_305dT1p25 - mean SST = 305 K / dSST = 1.25 K - if (sst_option == 15) then - mean_SST = 305 - TkFrz - delta_SST = 1.25 + if (sst_option>=11 .and. sst_option<=15) then + if (sst_option==11) then; mean_SST = 295 - TkFrz; delta_SST = 1.250; end if ! MW_295dT1p25 + if (sst_option==12) then; mean_SST = 300 - TkFrz; delta_SST = 0.625; end if ! MW_300dT0p625 + if (sst_option==13) then; mean_SST = 300 - TkFrz; delta_SST = 1.250; end if ! MW_300dT1p25 + if (sst_option==14) then; mean_SST = 300 - TkFrz; delta_SST = 2.500; end if ! MW_300dT2p5 + if (sst_option==15) then; mean_SST = 305 - TkFrz; delta_SST = 1.250; end if ! MW_305dT1p25 do i = 1, lsize sst(i) = mean_SST + (delta_SST/2) * cos( rlat(i) * 360/54 ) end do end if + !------------------------------------------------------------------------------- end subroutine prescribed_sst From a2e91dc0e9b476e9f6a845fd3c1b9f7e3e2746d8 Mon Sep 17 00:00:00 2001 From: James Foucar Date: Mon, 16 Sep 2024 15:14:56 -0600 Subject: [PATCH 433/451] Get mappy working again with RHEL9 --- cime_config/machines/config_machines.xml | 38 +++++++++++++----------- 1 file changed, 21 insertions(+), 17 deletions(-) diff --git a/cime_config/machines/config_machines.xml b/cime_config/machines/config_machines.xml index fe1febd6ddcb..dcbd43ad6f08 100644 --- a/cime_config/machines/config_machines.xml +++ b/cime_config/machines/config_machines.xml @@ -1861,31 +1861,32 @@ commented out until "*** No rule to make target '.../libadios2pio-nm-lib.a'" iss - /projects/sems/install/rhel7-x86_64/sems/v2/lmod/lmod/8.3/gcc/10.1.0/zbzzu7k/lmod/lmod/init/env_modules_python.py - /projects/sems/install/rhel7-x86_64/sems/v2/lmod/lmod/8.3/gcc/10.1.0/zbzzu7k/lmod/lmod/init/perl - /projects/sems/install/rhel7-x86_64/sems/v2/lmod/lmod/8.3/gcc/10.1.0/zbzzu7k/lmod/lmod/init/sh - /projects/sems/install/rhel7-x86_64/sems/v2/lmod/lmod/8.3/gcc/10.1.0/zbzzu7k/lmod/lmod/init/csh - /projects/sems/install/rhel7-x86_64/sems/v2/lmod/lmod/8.3/gcc/10.1.0/zbzzu7k/lmod/lmod/libexec/lmod python - /projects/sems/install/rhel7-x86_64/sems/v2/lmod/lmod/8.3/gcc/10.1.0/zbzzu7k/lmod/lmod/libexec/lmod perl + /projects/sems/install/rhel9-x86_64/sems/lmod/lmod/8.7.24/gcc/11.4.1/base/lnirq74/lmod/lmod/init/env_modules_python.py + /projects/sems/install/rhel9-x86_64/sems/lmod/lmod/8.7.24/gcc/11.4.1/base/lnirq74/lmod/lmod/init/perl + /projects/sems/install/rhel9-x86_64/sems/lmod/lmod/8.7.24/gcc/11.4.1/base/lnirq74/lmod/lmod/init/sh + /projects/sems/install/rhel9-x86_64/sems/lmod/lmod/8.7.24/gcc/11.4.1/base/lnirq74/lmod/lmod/init/csh + /projects/sems/install/rhel9-x86_64/sems/lmod/lmod/8.7.24/gcc/11.4.1/base/lnirq74/lmod/lmod/libexec/lmod python + /projects/sems/install/rhel9-x86_64/sems/lmod/lmod/8.7.24/gcc/11.4.1/base/lnirq74/lmod/lmod/libexec/lmod perl module module - sems-archive-env - acme-env - sems-archive-git - acme-cmake/3.26.3 + sems-git/2.42.0 + sems-cmake/3.27.9 - acme-gcc/11.2.0 + sems-gcc/11.4.0 + sems-openblas - acme-netcdf/4.4.1/exo_acme - acme-pfunit/3.2.8/base + sems-netcdf-c-serial/4.9.2 - acme-openmpi/4.1.4 - acme-netcdf/4.7.4/acme + sems-openmpi/4.1.6 + sems-netcdf-c/4.9.2 + sems-netcdf-cxx/4.2 + sems-netcdf-fortran/4.6.1 + sems-parallel-netcdf/1.12.3 $CIME_OUTPUT_ROOT/$CASE/run @@ -1894,11 +1895,14 @@ commented out until "*** No rule to make target '.../libadios2pio-nm-lib.a'" iss 0 - $ENV{SEMS_NETCDF_ROOT} + $ENV{NETCDF_C_ROOT} + $ENV{NETCDF_FORTRAN_ROOT} + $ENV{PARALLEL_NETCDF_ROOT} + $ENV{OPENBLAS_ROOT} 64M spread threads - Generic + OpenBLAS 4000MB From a56bd4e2efdc2e14b975d2efe8272484be8f2a9e Mon Sep 17 00:00:00 2001 From: Naser Mahfouz Date: Mon, 16 Sep 2024 17:47:30 -0400 Subject: [PATCH 434/451] fix outdated path of output yaml files --- .../testdefs/testmods_dirs/eamxx/prod/shell_commands | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/components/eamxx/cime_config/testdefs/testmods_dirs/eamxx/prod/shell_commands b/components/eamxx/cime_config/testdefs/testmods_dirs/eamxx/prod/shell_commands index 435556401a2b..a5ad8d6c668e 100644 --- a/components/eamxx/cime_config/testdefs/testmods_dirs/eamxx/prod/shell_commands +++ b/components/eamxx/cime_config/testdefs/testmods_dirs/eamxx/prod/shell_commands @@ -61,7 +61,7 @@ else fi # set the output yaml files -output_yaml_files=$(find ${cime_root}/../components/eamxx/cime_config/testdefs/testmods_dirs/scream/v1prod/yaml_outs/ -maxdepth 1 -type f) +output_yaml_files=$(find ${cime_root}/../components/eamxx/cime_config/testdefs/testmods_dirs/eamxx/prod/yaml_outs/ -maxdepth 1 -type f) for file in ${output_yaml_files[@]}; do # if the word "coarse" is in the file name, do nothing if [[ "${file}" == *"_coarse.yaml" && "${hmapfile}" == "not-supported-yet" ]]; then From 6a6415a80c6bf1342c19abe789bfcac4dbf50d50 Mon Sep 17 00:00:00 2001 From: Naser Mahfouz Date: Mon, 16 Sep 2024 19:45:04 -0400 Subject: [PATCH 435/451] edit logic to accomodate eamxx specs --- cime_config/config_archive.xml | 2 +- .../testdefs/testmods_dirs/eamxx/prod/shell_commands | 3 +++ ..._native.yaml => eamxx_output.decadal.1dailyAVG_native.yaml} | 2 +- ..._native.yaml => eamxx_output.decadal.1dailyMAX_native.yaml} | 2 +- ..._native.yaml => eamxx_output.decadal.1dailyMIN_native.yaml} | 2 +- ...INST_arm.yaml => eamxx_output.decadal.1hourlyINST_arm.yaml} | 2 +- ...ative.yaml => eamxx_output.decadal.1hourlyINST_native.yaml} | 2 +- ...coarse.yaml => eamxx_output.decadal.3hourlyAVG_coarse.yaml} | 2 +- ...oarse.yaml => eamxx_output.decadal.3hourlyINST_coarse.yaml} | 2 +- ...coarse.yaml => eamxx_output.decadal.6hourlyAVG_coarse.yaml} | 2 +- ...oarse.yaml => eamxx_output.decadal.6hourlyINST_coarse.yaml} | 2 +- ...ative.yaml => eamxx_output.decadal.6hourlyINST_native.yaml} | 2 +- ...G_coarse.yaml => eamxx_output.decadal.dailyAVG_coarse.yaml} | 2 +- 13 files changed, 15 insertions(+), 12 deletions(-) rename components/eamxx/cime_config/testdefs/testmods_dirs/eamxx/prod/yaml_outs/{scream_output.decadal.1dailyAVG_native.yaml => eamxx_output.decadal.1dailyAVG_native.yaml} (81%) rename components/eamxx/cime_config/testdefs/testmods_dirs/eamxx/prod/yaml_outs/{scream_output.decadal.1dailyMAX_native.yaml => eamxx_output.decadal.1dailyMAX_native.yaml} (82%) rename components/eamxx/cime_config/testdefs/testmods_dirs/eamxx/prod/yaml_outs/{scream_output.decadal.1dailyMIN_native.yaml => eamxx_output.decadal.1dailyMIN_native.yaml} (80%) rename components/eamxx/cime_config/testdefs/testmods_dirs/eamxx/prod/yaml_outs/{scream_output.decadal.1hourlyINST_arm.yaml => eamxx_output.decadal.1hourlyINST_arm.yaml} (92%) rename components/eamxx/cime_config/testdefs/testmods_dirs/eamxx/prod/yaml_outs/{scream_output.decadal.1hourlyINST_native.yaml => eamxx_output.decadal.1hourlyINST_native.yaml} (85%) rename components/eamxx/cime_config/testdefs/testmods_dirs/eamxx/prod/yaml_outs/{scream_output.decadal.3hourlyAVG_coarse.yaml => eamxx_output.decadal.3hourlyAVG_coarse.yaml} (96%) rename components/eamxx/cime_config/testdefs/testmods_dirs/eamxx/prod/yaml_outs/{scream_output.decadal.3hourlyINST_coarse.yaml => eamxx_output.decadal.3hourlyINST_coarse.yaml} (96%) rename components/eamxx/cime_config/testdefs/testmods_dirs/eamxx/prod/yaml_outs/{scream_output.decadal.6hourlyAVG_coarse.yaml => eamxx_output.decadal.6hourlyAVG_coarse.yaml} (94%) rename components/eamxx/cime_config/testdefs/testmods_dirs/eamxx/prod/yaml_outs/{scream_output.decadal.6hourlyINST_coarse.yaml => eamxx_output.decadal.6hourlyINST_coarse.yaml} (91%) rename components/eamxx/cime_config/testdefs/testmods_dirs/eamxx/prod/yaml_outs/{scream_output.decadal.6hourlyINST_native.yaml => eamxx_output.decadal.6hourlyINST_native.yaml} (90%) rename components/eamxx/cime_config/testdefs/testmods_dirs/eamxx/prod/yaml_outs/{scream_output.decadal.dailyAVG_coarse.yaml => eamxx_output.decadal.dailyAVG_coarse.yaml} (97%) diff --git a/cime_config/config_archive.xml b/cime_config/config_archive.xml index f343fce81ba0..8cb7a5305386 100644 --- a/cime_config/config_archive.xml +++ b/cime_config/config_archive.xml @@ -29,7 +29,7 @@ r\.(INSTANT|AVERAGE|MAX|MIN)\.n(step|sec|min|hour|day|month|year)s_x\d* rhist\.(INSTANT|AVERAGE|MAX|MIN)\.n(step|sec|min|hour|day|month|year)s_x\d* - hi\.(INSTANT|AVERAGE|MAX|MIN)\.n(step|sec|min|hour|day|month|year)s_x\d*\.\d{4}-\d{2}-\d{2}-\d{5}\.nc$ + .*\.h\.(?!rhist\.).*\.nc$ diff --git a/components/eamxx/cime_config/testdefs/testmods_dirs/eamxx/prod/shell_commands b/components/eamxx/cime_config/testdefs/testmods_dirs/eamxx/prod/shell_commands index a5ad8d6c668e..2520f7b6b12b 100644 --- a/components/eamxx/cime_config/testdefs/testmods_dirs/eamxx/prod/shell_commands +++ b/components/eamxx/cime_config/testdefs/testmods_dirs/eamxx/prod/shell_commands @@ -3,6 +3,7 @@ cime_root=$(./xmlquery --value CIMEROOT) input_data_dir=$(./xmlquery --value DIN_LOC_ROOT) atmchange=$cime_root/../components/eamxx/scripts/atmchange +case_name=$(./xmlquery --value CASE) # Change run length ./xmlchange RUN_STARTDATE="1994-10-01" @@ -82,6 +83,8 @@ for file in ${output_yaml_files[@]}; do sed -i "s|horiz_remap_file:.*_to_ne30.*|horiz_remap_file: ${hmapfile}|" ./$(basename ${file}) sed -i "s|horiz_remap_file:.*_to_DecadalSites.*|horiz_remap_file: ${armmapfile}|" ./$(basename ${file}) fi + # replace all filename prefixes so that st_archive works... + sed -i "s|eamxx_output.decadal|${case_name}.scream|" ./$(basename ${file}) done # TODO: diff --git a/components/eamxx/cime_config/testdefs/testmods_dirs/eamxx/prod/yaml_outs/scream_output.decadal.1dailyAVG_native.yaml b/components/eamxx/cime_config/testdefs/testmods_dirs/eamxx/prod/yaml_outs/eamxx_output.decadal.1dailyAVG_native.yaml similarity index 81% rename from components/eamxx/cime_config/testdefs/testmods_dirs/eamxx/prod/yaml_outs/scream_output.decadal.1dailyAVG_native.yaml rename to components/eamxx/cime_config/testdefs/testmods_dirs/eamxx/prod/yaml_outs/eamxx_output.decadal.1dailyAVG_native.yaml index 4e1239b5c33c..181f841eeb81 100644 --- a/components/eamxx/cime_config/testdefs/testmods_dirs/eamxx/prod/yaml_outs/scream_output.decadal.1dailyAVG_native.yaml +++ b/components/eamxx/cime_config/testdefs/testmods_dirs/eamxx/prod/yaml_outs/eamxx_output.decadal.1dailyAVG_native.yaml @@ -1,6 +1,6 @@ %YAML 1.1 --- -filename_prefix: scream_output.decadal.1dailyAVG_native.h +filename_prefix: eamxx_output.decadal.1dailyAVG_native.h iotype: pnetcdf Averaging Type: Average Max Snapshots Per File: 1 diff --git a/components/eamxx/cime_config/testdefs/testmods_dirs/eamxx/prod/yaml_outs/scream_output.decadal.1dailyMAX_native.yaml b/components/eamxx/cime_config/testdefs/testmods_dirs/eamxx/prod/yaml_outs/eamxx_output.decadal.1dailyMAX_native.yaml similarity index 82% rename from components/eamxx/cime_config/testdefs/testmods_dirs/eamxx/prod/yaml_outs/scream_output.decadal.1dailyMAX_native.yaml rename to components/eamxx/cime_config/testdefs/testmods_dirs/eamxx/prod/yaml_outs/eamxx_output.decadal.1dailyMAX_native.yaml index a7d10efe0707..a8974c75b35e 100644 --- a/components/eamxx/cime_config/testdefs/testmods_dirs/eamxx/prod/yaml_outs/scream_output.decadal.1dailyMAX_native.yaml +++ b/components/eamxx/cime_config/testdefs/testmods_dirs/eamxx/prod/yaml_outs/eamxx_output.decadal.1dailyMAX_native.yaml @@ -1,6 +1,6 @@ %YAML 1.1 --- -filename_prefix: scream_output.decadal.1dailyMAX_native.h +filename_prefix: eamxx_output.decadal.1dailyMAX_native.h iotype: pnetcdf Averaging Type: Max Max Snapshots Per File: 1 diff --git a/components/eamxx/cime_config/testdefs/testmods_dirs/eamxx/prod/yaml_outs/scream_output.decadal.1dailyMIN_native.yaml b/components/eamxx/cime_config/testdefs/testmods_dirs/eamxx/prod/yaml_outs/eamxx_output.decadal.1dailyMIN_native.yaml similarity index 80% rename from components/eamxx/cime_config/testdefs/testmods_dirs/eamxx/prod/yaml_outs/scream_output.decadal.1dailyMIN_native.yaml rename to components/eamxx/cime_config/testdefs/testmods_dirs/eamxx/prod/yaml_outs/eamxx_output.decadal.1dailyMIN_native.yaml index 653e194d278b..8d48a1bedf63 100644 --- a/components/eamxx/cime_config/testdefs/testmods_dirs/eamxx/prod/yaml_outs/scream_output.decadal.1dailyMIN_native.yaml +++ b/components/eamxx/cime_config/testdefs/testmods_dirs/eamxx/prod/yaml_outs/eamxx_output.decadal.1dailyMIN_native.yaml @@ -1,6 +1,6 @@ %YAML 1.1 --- -filename_prefix: scream_output.decadal.1dailyMIN_native.h +filename_prefix: eamxx_output.decadal.1dailyMIN_native.h iotype: pnetcdf Averaging Type: Min Max Snapshots Per File: 1 diff --git a/components/eamxx/cime_config/testdefs/testmods_dirs/eamxx/prod/yaml_outs/scream_output.decadal.1hourlyINST_arm.yaml b/components/eamxx/cime_config/testdefs/testmods_dirs/eamxx/prod/yaml_outs/eamxx_output.decadal.1hourlyINST_arm.yaml similarity index 92% rename from components/eamxx/cime_config/testdefs/testmods_dirs/eamxx/prod/yaml_outs/scream_output.decadal.1hourlyINST_arm.yaml rename to components/eamxx/cime_config/testdefs/testmods_dirs/eamxx/prod/yaml_outs/eamxx_output.decadal.1hourlyINST_arm.yaml index 5bb07048aed6..52fc391ca4d9 100644 --- a/components/eamxx/cime_config/testdefs/testmods_dirs/eamxx/prod/yaml_outs/scream_output.decadal.1hourlyINST_arm.yaml +++ b/components/eamxx/cime_config/testdefs/testmods_dirs/eamxx/prod/yaml_outs/eamxx_output.decadal.1hourlyINST_arm.yaml @@ -1,6 +1,6 @@ %YAML 1.1 --- -filename_prefix: scream_output.decadal.1hourlyINST_arm.h +filename_prefix: eamxx_output.decadal.1hourlyINST_arm.h iotype: pnetcdf Averaging Type: Instant Max Snapshots Per File: 24 # one file per day diff --git a/components/eamxx/cime_config/testdefs/testmods_dirs/eamxx/prod/yaml_outs/scream_output.decadal.1hourlyINST_native.yaml b/components/eamxx/cime_config/testdefs/testmods_dirs/eamxx/prod/yaml_outs/eamxx_output.decadal.1hourlyINST_native.yaml similarity index 85% rename from components/eamxx/cime_config/testdefs/testmods_dirs/eamxx/prod/yaml_outs/scream_output.decadal.1hourlyINST_native.yaml rename to components/eamxx/cime_config/testdefs/testmods_dirs/eamxx/prod/yaml_outs/eamxx_output.decadal.1hourlyINST_native.yaml index 7a221e89f1c3..0aba4827ead7 100644 --- a/components/eamxx/cime_config/testdefs/testmods_dirs/eamxx/prod/yaml_outs/scream_output.decadal.1hourlyINST_native.yaml +++ b/components/eamxx/cime_config/testdefs/testmods_dirs/eamxx/prod/yaml_outs/eamxx_output.decadal.1hourlyINST_native.yaml @@ -1,6 +1,6 @@ %YAML 1.1 --- -filename_prefix: scream_output.decadal.1hourlyINST_native.h +filename_prefix: eamxx_output.decadal.1hourlyINST_native.h iotype: pnetcdf Averaging Type: Instant Max Snapshots Per File: 24 diff --git a/components/eamxx/cime_config/testdefs/testmods_dirs/eamxx/prod/yaml_outs/scream_output.decadal.3hourlyAVG_coarse.yaml b/components/eamxx/cime_config/testdefs/testmods_dirs/eamxx/prod/yaml_outs/eamxx_output.decadal.3hourlyAVG_coarse.yaml similarity index 96% rename from components/eamxx/cime_config/testdefs/testmods_dirs/eamxx/prod/yaml_outs/scream_output.decadal.3hourlyAVG_coarse.yaml rename to components/eamxx/cime_config/testdefs/testmods_dirs/eamxx/prod/yaml_outs/eamxx_output.decadal.3hourlyAVG_coarse.yaml index 665294c62273..d429b11ebd1f 100644 --- a/components/eamxx/cime_config/testdefs/testmods_dirs/eamxx/prod/yaml_outs/scream_output.decadal.3hourlyAVG_coarse.yaml +++ b/components/eamxx/cime_config/testdefs/testmods_dirs/eamxx/prod/yaml_outs/eamxx_output.decadal.3hourlyAVG_coarse.yaml @@ -1,6 +1,6 @@ %YAML 1.1 --- -filename_prefix: scream_output.decadal.3hourlyAVG_coarse.h +filename_prefix: eamxx_output.decadal.3hourlyAVG_coarse.h iotype: pnetcdf Averaging Type: Average Max Snapshots Per File: 8 # one file per day diff --git a/components/eamxx/cime_config/testdefs/testmods_dirs/eamxx/prod/yaml_outs/scream_output.decadal.3hourlyINST_coarse.yaml b/components/eamxx/cime_config/testdefs/testmods_dirs/eamxx/prod/yaml_outs/eamxx_output.decadal.3hourlyINST_coarse.yaml similarity index 96% rename from components/eamxx/cime_config/testdefs/testmods_dirs/eamxx/prod/yaml_outs/scream_output.decadal.3hourlyINST_coarse.yaml rename to components/eamxx/cime_config/testdefs/testmods_dirs/eamxx/prod/yaml_outs/eamxx_output.decadal.3hourlyINST_coarse.yaml index 42c649545088..a2faa1b971c1 100644 --- a/components/eamxx/cime_config/testdefs/testmods_dirs/eamxx/prod/yaml_outs/scream_output.decadal.3hourlyINST_coarse.yaml +++ b/components/eamxx/cime_config/testdefs/testmods_dirs/eamxx/prod/yaml_outs/eamxx_output.decadal.3hourlyINST_coarse.yaml @@ -1,6 +1,6 @@ %YAML 1.1 --- -filename_prefix: scream_output.decadal.3hourlyINST_coarse.h +filename_prefix: eamxx_output.decadal.3hourlyINST_coarse.h iotype: pnetcdf Averaging Type: Instant Max Snapshots Per File: 8 # one file per day diff --git a/components/eamxx/cime_config/testdefs/testmods_dirs/eamxx/prod/yaml_outs/scream_output.decadal.6hourlyAVG_coarse.yaml b/components/eamxx/cime_config/testdefs/testmods_dirs/eamxx/prod/yaml_outs/eamxx_output.decadal.6hourlyAVG_coarse.yaml similarity index 94% rename from components/eamxx/cime_config/testdefs/testmods_dirs/eamxx/prod/yaml_outs/scream_output.decadal.6hourlyAVG_coarse.yaml rename to components/eamxx/cime_config/testdefs/testmods_dirs/eamxx/prod/yaml_outs/eamxx_output.decadal.6hourlyAVG_coarse.yaml index 5e4aaed07384..437142ba5599 100644 --- a/components/eamxx/cime_config/testdefs/testmods_dirs/eamxx/prod/yaml_outs/scream_output.decadal.6hourlyAVG_coarse.yaml +++ b/components/eamxx/cime_config/testdefs/testmods_dirs/eamxx/prod/yaml_outs/eamxx_output.decadal.6hourlyAVG_coarse.yaml @@ -1,6 +1,6 @@ %YAML 1.1 --- -filename_prefix: scream_output.decadal.6hourlyAVG_coarse.h +filename_prefix: eamxx_output.decadal.6hourlyAVG_coarse.h iotype: pnetcdf Averaging Type: Average Max Snapshots Per File: 4 # one file per day diff --git a/components/eamxx/cime_config/testdefs/testmods_dirs/eamxx/prod/yaml_outs/scream_output.decadal.6hourlyINST_coarse.yaml b/components/eamxx/cime_config/testdefs/testmods_dirs/eamxx/prod/yaml_outs/eamxx_output.decadal.6hourlyINST_coarse.yaml similarity index 91% rename from components/eamxx/cime_config/testdefs/testmods_dirs/eamxx/prod/yaml_outs/scream_output.decadal.6hourlyINST_coarse.yaml rename to components/eamxx/cime_config/testdefs/testmods_dirs/eamxx/prod/yaml_outs/eamxx_output.decadal.6hourlyINST_coarse.yaml index e9e0f34d5e0f..bb83718a8eb0 100644 --- a/components/eamxx/cime_config/testdefs/testmods_dirs/eamxx/prod/yaml_outs/scream_output.decadal.6hourlyINST_coarse.yaml +++ b/components/eamxx/cime_config/testdefs/testmods_dirs/eamxx/prod/yaml_outs/eamxx_output.decadal.6hourlyINST_coarse.yaml @@ -1,6 +1,6 @@ %YAML 1.1 --- -filename_prefix: scream_output.decadal.6hourlyINST_coarse.h +filename_prefix: eamxx_output.decadal.6hourlyINST_coarse.h iotype: pnetcdf Averaging Type: Instant Max Snapshots Per File: 4 # one file per day diff --git a/components/eamxx/cime_config/testdefs/testmods_dirs/eamxx/prod/yaml_outs/scream_output.decadal.6hourlyINST_native.yaml b/components/eamxx/cime_config/testdefs/testmods_dirs/eamxx/prod/yaml_outs/eamxx_output.decadal.6hourlyINST_native.yaml similarity index 90% rename from components/eamxx/cime_config/testdefs/testmods_dirs/eamxx/prod/yaml_outs/scream_output.decadal.6hourlyINST_native.yaml rename to components/eamxx/cime_config/testdefs/testmods_dirs/eamxx/prod/yaml_outs/eamxx_output.decadal.6hourlyINST_native.yaml index bb7fd275abf4..c69dc4b2212b 100644 --- a/components/eamxx/cime_config/testdefs/testmods_dirs/eamxx/prod/yaml_outs/scream_output.decadal.6hourlyINST_native.yaml +++ b/components/eamxx/cime_config/testdefs/testmods_dirs/eamxx/prod/yaml_outs/eamxx_output.decadal.6hourlyINST_native.yaml @@ -1,6 +1,6 @@ %YAML 1.1 --- -filename_prefix: scream_output.decadal.6hourlyINST_native.h +filename_prefix: eamxx_output.decadal.6hourlyINST_native.h iotype: pnetcdf Averaging Type: Instant Max Snapshots Per File: 4 # one file per day diff --git a/components/eamxx/cime_config/testdefs/testmods_dirs/eamxx/prod/yaml_outs/scream_output.decadal.dailyAVG_coarse.yaml b/components/eamxx/cime_config/testdefs/testmods_dirs/eamxx/prod/yaml_outs/eamxx_output.decadal.dailyAVG_coarse.yaml similarity index 97% rename from components/eamxx/cime_config/testdefs/testmods_dirs/eamxx/prod/yaml_outs/scream_output.decadal.dailyAVG_coarse.yaml rename to components/eamxx/cime_config/testdefs/testmods_dirs/eamxx/prod/yaml_outs/eamxx_output.decadal.dailyAVG_coarse.yaml index 7c1990a7b56e..2d1e6e7221ef 100644 --- a/components/eamxx/cime_config/testdefs/testmods_dirs/eamxx/prod/yaml_outs/scream_output.decadal.dailyAVG_coarse.yaml +++ b/components/eamxx/cime_config/testdefs/testmods_dirs/eamxx/prod/yaml_outs/eamxx_output.decadal.dailyAVG_coarse.yaml @@ -1,6 +1,6 @@ %YAML 1.1 --- -filename_prefix: scream_output.decadal.dailyAVG_coarse.h +filename_prefix: eamxx_output.decadal.dailyAVG_coarse.h iotype: pnetcdf Averaging Type: Average Max Snapshots Per File: 1 From 30ffb16650cfeeb54098495f630fd9698586d16c Mon Sep 17 00:00:00 2001 From: Oksana Guba Date: Tue, 17 Sep 2024 01:02:49 +0000 Subject: [PATCH 436/451] switch to 16,8 pair --- components/homme/src/share/cxx/ExecSpaceDefs.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/components/homme/src/share/cxx/ExecSpaceDefs.cpp b/components/homme/src/share/cxx/ExecSpaceDefs.cpp index c9ca8a0ecd93..4f3d97135fea 100644 --- a/components/homme/src/share/cxx/ExecSpaceDefs.cpp +++ b/components/homme/src/share/cxx/ExecSpaceDefs.cpp @@ -176,7 +176,7 @@ team_num_threads_vectors_for_gpu ( num_vectors ); } #else - return std::make_pair(4,16); + return std::make_pair(16,8); #endif } From 112fe79e60eeaa4d7ca0d85a54f24640b6a974f6 Mon Sep 17 00:00:00 2001 From: Oksana Guba Date: Tue, 17 Sep 2024 01:03:44 +0000 Subject: [PATCH 437/451] adjust aurora flags --- components/homme/cmake/machineFiles/aurora-aot.cmake | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/components/homme/cmake/machineFiles/aurora-aot.cmake b/components/homme/cmake/machineFiles/aurora-aot.cmake index b6fe34a78d72..094ec8882784 100644 --- a/components/homme/cmake/machineFiles/aurora-aot.cmake +++ b/components/homme/cmake/machineFiles/aurora-aot.cmake @@ -43,9 +43,9 @@ SET(CMAKE_CXX_COMPILER "mpicxx" CACHE STRING "") #AOT flags SET(SYCL_COMPILE_FLAGS "-std=c++17 -fsycl -fsycl-device-code-split=per_kernel -fno-sycl-id-queries-fit-in-int -fsycl-unnamed-lambda") -SET(SYCL_LINK_FLAGS "-fsycl -fsycl-device-code-split=per_kernel -fsycl-link-huge-device-code -fsycl-targets=spir64_gen -Xsycl-target-backend \"-device 12.60.7\"") +SET(SYCL_LINK_FLAGS "-fsycl-max-parallel-link-jobs=32 -fsycl-link-huge-device-code -fsycl -fsycl-device-code-split=per_kernel -fsycl-targets=spir64_gen -Xsycl-target-backend \"-device 12.60.7\"") -SET(ADD_Fortran_FLAGS "-fc=ifx -O3 -DNDEBUG -DCPRINTEL -g" CACHE STRING "") +SET(ADD_Fortran_FLAGS "-fc=ifx -fpscomp logicals -O3 -DNDEBUG -DCPRINTEL -g" CACHE STRING "") SET(ADD_C_FLAGS "-O3 -DNDEBUG " CACHE STRING "") SET(ADD_CXX_FLAGS "-std=c++17 -O3 -DNDEBUG ${SYCL_COMPILE_FLAGS}" CACHE STRING "") From 0fcac3cc2906dee8a391f2d446bcf5286db38919 Mon Sep 17 00:00:00 2001 From: Oksana Guba Date: Tue, 17 Sep 2024 01:04:25 +0000 Subject: [PATCH 438/451] adopt ekat sycl changes, TeamVectorRange --- .../share/cxx/utilities/scream_tridiag.hpp | 21 +++++++++++++++++-- 1 file changed, 19 insertions(+), 2 deletions(-) diff --git a/components/homme/src/share/cxx/utilities/scream_tridiag.hpp b/components/homme/src/share/cxx/utilities/scream_tridiag.hpp index e18bbc4e7e27..26221db39552 100644 --- a/components/homme/src/share/cxx/utilities/scream_tridiag.hpp +++ b/components/homme/src/share/cxx/utilities/scream_tridiag.hpp @@ -128,6 +128,10 @@ int get_thread_id_within_team_gpu (const TeamMember& team) { // Can't use team.team_rank() here because vector direction also uses physical // threads but TeamMember types don't expose that information. return blockDim.x * threadIdx.y + threadIdx.x; +#elif defined(__SYCL_DEVICE_ONLY__) + auto item = team.item(); + return static_cast(item.get_local_range(1) * item.get_local_id(0) + + item.get_local_id(1)); #else assert(0); return -1; @@ -138,6 +142,9 @@ template KOKKOS_FORCEINLINE_FUNCTION int get_team_nthr_gpu (const TeamMember& team) { #if defined __CUDA_ARCH__ || defined __HIP_DEVICE_COMPILE__ return blockDim.x * blockDim.y; +#elif defined __SYCL_DEVICE_ONLY__ + auto item = team.item(); + return static_cast(item.get_local_range(0) * item.get_local_range(1)); #else assert(0); return -1; @@ -161,6 +168,16 @@ KOKKOS_FORCEINLINE_FUNCTION int get_team_nthr (const Kokkos::Impl::HIPTeamMember& team) { return get_team_nthr_gpu(team); } #endif // KOKKOS_ENABLE_HIP + +#ifdef KOKKOS_ENABLE_SYCL +KOKKOS_FORCEINLINE_FUNCTION +int get_thread_id_within_team (const Kokkos::Impl::SYCLTeamMember& team) +{ return get_thread_id_within_team_gpu(team); } +KOKKOS_FORCEINLINE_FUNCTION +int get_team_nthr (const Kokkos::Impl::SYCLTeamMember& team) +{ return get_team_nthr_gpu(team); } +#endif // KOKKOS_ENABLE_SYCL + template KOKKOS_INLINE_FUNCTION const T& min (const T& a, const T& b) { return a < b ? a : b; } @@ -634,7 +651,7 @@ void bfb (const TeamMember& team, const auto f = [&] (const int& j) { impl::bfb_thomas_solve(dl, d, du, Kokkos::subview(X , Kokkos::ALL(), j)); }; - Kokkos::parallel_for(Kokkos::TeamThreadRange(team, nrhs), f); + Kokkos::parallel_for(Kokkos::TeamVectorRange(team, nrhs), f); } template @@ -664,7 +681,7 @@ void bfb (const TeamMember& team, subview(du, ALL(), j), subview(X , ALL(), j)); }; - Kokkos::parallel_for(Kokkos::TeamThreadRange(team, nrhs), f); + Kokkos::parallel_for(Kokkos::TeamVectorRange(team, nrhs), f); } } // namespace tridiag From 312c442ac6018cecde4b9024f4b0ea6090d57017 Mon Sep 17 00:00:00 2001 From: Wuyin Lin Date: Mon, 16 Sep 2024 21:27:35 -0500 Subject: [PATCH 439/451] Revert "Merge remote-tracking branch 'liho/liho745/river/bug-fix-7792c63' (PR #6313)" This reverts commit 427b86040f21ce3e41cc99f7cc2aeff02267f17f, reversing changes made to cf32a25b559c71ba63208fc09adaae5daebe6412. --- components/mosart/src/riverroute/MOSART_physics_mod.F90 | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/components/mosart/src/riverroute/MOSART_physics_mod.F90 b/components/mosart/src/riverroute/MOSART_physics_mod.F90 index cad978577cda..912014904e93 100644 --- a/components/mosart/src/riverroute/MOSART_physics_mod.F90 +++ b/components/mosart/src/riverroute/MOSART_physics_mod.F90 @@ -682,8 +682,8 @@ subroutine Euler ! check for negative channel storage if (negchan < -1.e-10) then - write(iulog,*) 'Error: Negative channel storage found! ',negchan - call shr_sys_abort('mosart: negative channel storage') + write(iulog,*) 'Warning: Negative channel storage found! ',negchan +! call shr_sys_abort('mosart: negative channel storage') endif TRunoff%flow = TRunoff%flow / Tctl%DLevelH2R TRunoff%erowm_regi(:,nt_nmud:nt_nsan) = TRunoff%erowm_regi(:,nt_nmud:nt_nsan) / Tctl%DLevelH2R From 43239f35bcf42b4c33ef713c1ee2fdc3a8699238 Mon Sep 17 00:00:00 2001 From: James Foucar Date: Tue, 17 Sep 2024 11:31:00 -0600 Subject: [PATCH 440/451] Fixes for mpi-serial on mappy --- cime_config/machines/config_machines.xml | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/cime_config/machines/config_machines.xml b/cime_config/machines/config_machines.xml index dcbd43ad6f08..fedb4318b3eb 100644 --- a/cime_config/machines/config_machines.xml +++ b/cime_config/machines/config_machines.xml @@ -1896,8 +1896,6 @@ commented out until "*** No rule to make target '.../libadios2pio-nm-lib.a'" iss $ENV{NETCDF_C_ROOT} - $ENV{NETCDF_FORTRAN_ROOT} - $ENV{PARALLEL_NETCDF_ROOT} $ENV{OPENBLAS_ROOT} 64M spread @@ -1905,6 +1903,14 @@ commented out until "*** No rule to make target '.../libadios2pio-nm-lib.a'" iss OpenBLAS 4000MB + + /home/jgfouca/packages/netcdf-fortran-4.6.1-bin + /home/jgfouca/packages/netcdf-fortran-4.6.1-bin:$ENV{LD_LIBRARY_PATH} + + + $ENV{NETCDF_FORTRAN_ROOT} + $ENV{PARALLEL_NETCDF_ROOT} + @@ -3497,7 +3503,7 @@ commented out until "*** No rule to make target '.../libadios2pio-nm-lib.a'" iss 104 104 48 - FALSE + FALSE mpiexec @@ -4290,7 +4296,7 @@ commented out until "*** No rule to make target '.../libadios2pio-nm-lib.a'" iss - Chicoma GPU nodes at LANL IC. Each GPU node has single + Chicoma GPU nodes at LANL IC. Each GPU node has single AMD EPYC 7713 64-Core (Milan) (256GB) and 4 nvidia A100' ch-fe* Linux From 03158e3e8fddfb860ea1818acea9986c81746f7a Mon Sep 17 00:00:00 2001 From: Darin Comeau Date: Wed, 18 Sep 2024 16:16:13 -0500 Subject: [PATCH 441/451] Updating CRYO1850* compsets to v3 ELM settings --- cime_config/allactive/config_compsets.xml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/cime_config/allactive/config_compsets.xml b/cime_config/allactive/config_compsets.xml index e66f1e473d85..b17bfd7c7ca9 100755 --- a/cime_config/allactive/config_compsets.xml +++ b/cime_config/allactive/config_compsets.xml @@ -383,12 +383,12 @@ CRYO1850 - 1850SOI_EAM%CMIP6_ELM%SPBC_MPASSI%DIB_MPASO%IBPISMF_MOSART_SGLC_SWAV + 1850SOI_EAM%CMIP6_ELM%CNPRDCTCBCTOP_MPASSI%DIB_MPASO%IBPISMF_MOSART_SGLC_SWAV CRYO1850-4xCO2 - 1850SOI_EAM%CMIP6-4xCO2_ELM%SPBC_MPASSI%DIB_MPASO%IBPISMF_MOSART_SGLC_SWAV + 1850SOI_EAM%CMIP6-4xCO2_ELM%CNPRDCTCBCTOP_MPASSI%DIB_MPASO%IBPISMF_MOSART_SGLC_SWAV @@ -398,7 +398,7 @@ CRYO1850-DISMF - 1850SOI_EAM%CMIP6_ELM%SPBC_MPASSI%DIB_MPASO%IBDISMF_MOSART_SGLC_SWAV + 1850SOI_EAM%CMIP6_ELM%CNPRDCTCBCTOP_MPASSI%DIB_MPASO%IBDISMF_MOSART_SGLC_SWAV From 67a5f9aca7e8e532894af791612d92689a0fd5a4 Mon Sep 17 00:00:00 2001 From: James Foucar Date: Thu, 19 Sep 2024 09:56:10 -0600 Subject: [PATCH 442/451] Everything working now --- cime_config/machines/config_machines.xml | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/cime_config/machines/config_machines.xml b/cime_config/machines/config_machines.xml index fedb4318b3eb..5d997dcb5d65 100644 --- a/cime_config/machines/config_machines.xml +++ b/cime_config/machines/config_machines.xml @@ -1880,9 +1880,10 @@ commented out until "*** No rule to make target '.../libadios2pio-nm-lib.a'" iss sems-netcdf-c-serial/4.9.2 + sems-netcdf-fortran-serial/4.6.1 - sems-openmpi/4.1.6 + sems-openmpi-no-cuda/4.1.6 sems-netcdf-c/4.9.2 sems-netcdf-cxx/4.2 sems-netcdf-fortran/4.6.1 @@ -1896,6 +1897,7 @@ commented out until "*** No rule to make target '.../libadios2pio-nm-lib.a'" iss $ENV{NETCDF_C_ROOT} + $ENV{NETCDF_FORTRAN_ROOT} $ENV{OPENBLAS_ROOT} 64M spread @@ -1903,12 +1905,7 @@ commented out until "*** No rule to make target '.../libadios2pio-nm-lib.a'" iss OpenBLAS 4000MB - - /home/jgfouca/packages/netcdf-fortran-4.6.1-bin - /home/jgfouca/packages/netcdf-fortran-4.6.1-bin:$ENV{LD_LIBRARY_PATH} - - $ENV{NETCDF_FORTRAN_ROOT} $ENV{PARALLEL_NETCDF_ROOT} From a8763c20197cee06943a527eba000a6e0b93fb34 Mon Sep 17 00:00:00 2001 From: Jon Wolfe Date: Thu, 19 Sep 2024 08:58:52 -0700 Subject: [PATCH 443/451] Cleanup to fix issues from earlier PR causing sporadic test failures --- .../bld/namelist_files/namelist_defaults_mali.xml | 2 +- components/mpas-albany-landice/cime_config/buildnml | 4 +++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/components/mpas-albany-landice/bld/namelist_files/namelist_defaults_mali.xml b/components/mpas-albany-landice/bld/namelist_files/namelist_defaults_mali.xml index 0450eb44f116..8dc305533ca3 100644 --- a/components/mpas-albany-landice/bld/namelist_files/namelist_defaults_mali.xml +++ b/components/mpas-albany-landice/bld/namelist_files/namelist_defaults_mali.xml @@ -18,7 +18,7 @@ 'fo' -'none' +'fo' 3 0.25 .false. diff --git a/components/mpas-albany-landice/cime_config/buildnml b/components/mpas-albany-landice/cime_config/buildnml index 9489b6dfa8fd..3b38ed39c438 100755 --- a/components/mpas-albany-landice/cime_config/buildnml +++ b/components/mpas-albany-landice/cime_config/buildnml @@ -280,7 +280,9 @@ def buildnml(case, caseroot, compname): lines.append(' ') lines.append(' ') lines.append(' ') - lines.append(' ') + if mali_use_albany: + lines.append(' ') + lines.append('') lines.append('') lines.append(' - - squeue - sbatch - scancel - #SBATCH - (\d+)$ - --dependency=afterok:jobid - --dependency=afterany:jobid - : - %H:%M:%S - --mail-user - --mail-type - none, all, begin, end, fail - - --export=ALL - -p {{ job_queue }} - -J {{ job_id }} - -N {{ num_nodes }} - -n {{ total_tasks }} - -t {{ job_wallclock_time }} - -o {{ job_id }}.out - -e {{ job_id }}.err - -A {{ project }} - + + + pbatch + pdebug + + + + - pbatch - pdebug + pbatch + pdebug diff --git a/cime_config/machines/config_machines.xml b/cime_config/machines/config_machines.xml index ff0c583fc93a..249cfdfc5a88 100644 --- a/cime_config/machines/config_machines.xml +++ b/cime_config/machines/config_machines.xml @@ -3065,9 +3065,9 @@ commented out until "*** No rule to make target '.../libadios2pio-nm-lib.a'" iss /usr/workspace/e3sm/ccsm3data/inputdata/atm/datm7 /p/lustre2/$USER/archive/$CASE /p/lustre2/$USER/ccsm_baselines/$COMPILER - /usr/workspace/e3sm/tools/cprnc + /usr/workspace/e3sm/apps/cprnc 8 - lc_slurm + slurm boutte3 -at- llnl.gov 56 56 @@ -3076,8 +3076,16 @@ commented out until "*** No rule to make target '.../libadios2pio-nm-lib.a'" iss srun + + --mpi=pmi2 + --export=ALL + -n {{ total_tasks }} -N {{ num_nodes }} + -c 1 + --cpu_bind=cores + -m plane={{ tasks_per_node }} + - + /usr/share/lmod/lmod/init/env_modules_python.py /usr/share/lmod/lmod/init/perl /usr/share/lmod/lmod/init/sh @@ -3089,24 +3097,27 @@ commented out until "*** No rule to make target '.../libadios2pio-nm-lib.a'" iss python/3.9.12 git + subversion + cmake/3.19.2 mkl/2022.1.0 intel-classic/2021.6.0-magic - mvapich2/2.3.7 - cmake/3.19.2 - /usr/workspace/e3sm/install/quartz/modulefiles - hdf5/1.12.2 - netcdf-c/4.9.0 - netcdf-fortran/4.6.0 - parallel-netcdf/1.12.3 - screamML-venv/0.0.1 - subversion + /usr/workspace/e3sm/spack/modules/ruby/linux-rhel8-x86_64/Core + mvapich2/2.3.7-ll7cmqm + hdf5/1.10.7-ewjpbjd + netcdf-c/4.4.1.1-vaxofek + netcdf-fortran/4.4.4-3pzbx2u + parallel-netcdf/1.11.0-tzgdala $CIME_OUTPUT_ROOT/$CASE/run $CIME_OUTPUT_ROOT/$CASE/bld - /usr/workspace/e3sm/install/quartz/netcdf-fortran/ - /usr/tce/packages/parallel-netcdf/parallel-netcdf-1.12.3-mvapich2-2.3.7-intel-classic-2021.6.0 + 128M + FALSE + /usr/workspace/e3sm/spack/libs/linux-rhel8-cascadelake/intel-2021.6.0/hdf5-1.10.7-ewjpbjdhjgjzrzjcvwyjyuulaesbsjhg + /usr/workspace/e3sm/spack/libs/linux-rhel8-cascadelake/intel-2021.6.0/netcdf-c-4.4.1.1-vaxofekwvnvngh7wptmzkwdb7tkzvesn + /usr/workspace/e3sm/spack/libs/linux-rhel8-cascadelake/intel-2021.6.0/netcdf-fortran-4.4.4-3pzbx2unddhladhubaahhhysjmprzqi2 + /usr/workspace/e3sm/spack/libs/linux-rhel8-cascadelake/intel-2021.6.0/parallel-netcdf-1.11.0-tzgdalakmem7tod6cruhqyeackeix5q5 @@ -3121,9 +3132,9 @@ commented out until "*** No rule to make target '.../libadios2pio-nm-lib.a'" iss /usr/workspace/e3sm/ccsm3data/inputdata/atm/datm7 /p/lustre2/$USER/archive/$CASE /p/lustre2/$USER/ccsm_baselines/$COMPILER - /usr/workspace/e3sm/tools/cprnc + /usr/workspace/e3sm/apps/cprnc 8 - lc_slurm + slurm boutte3 -at- llnl.gov 224 112 @@ -3132,8 +3143,16 @@ commented out until "*** No rule to make target '.../libadios2pio-nm-lib.a'" iss srun + + --mpi=pmi2 + --export=ALL + -n {{ total_tasks }} -N {{ num_nodes }} + -c 1 + --cpu_bind=cores + -m plane={{ tasks_per_node }} + - + /usr/share/lmod/lmod/init/env_modules_python.py /usr/share/lmod/lmod/init/perl /usr/share/lmod/lmod/init/sh @@ -3145,24 +3164,27 @@ commented out until "*** No rule to make target '.../libadios2pio-nm-lib.a'" iss python/3.9.12 git + subversion mkl/2022.1.0 intel-classic/2021.6.0-magic - mvapich2/2.3.7 cmake/3.19.2 - /usr/workspace/e3sm/install/quartz/modulefiles - hdf5/1.12.2 - netcdf-c/4.9.0 - netcdf-fortran/4.6.0 - parallel-netcdf/1.12.3 - screamML-venv/0.0.1 - subversion + /usr/workspace/e3sm/spack/modules/dane/linux-rhel8-x86_64/Core + mvapich2/2.3.7-27jao34 + hdf5/1.10.7-766kapa + netcdf-c/4.4.1.1-2uznnlw + netcdf-fortran/4.4.4-itpstyo + parallel-netcdf/1.11.0-26sxm4m $CIME_OUTPUT_ROOT/$CASE/run $CIME_OUTPUT_ROOT/$CASE/bld - /usr/workspace/e3sm/install/quartz/netcdf-fortran/ - /usr/tce/packages/parallel-netcdf/parallel-netcdf-1.12.3-mvapich2-2.3.7-intel-classic-2021.6.0 + 128M + FALSE + /usr/workspace/e3sm/spack/libs/linux-rhel8-sapphirerapids/intel-2021.6.0/hdf5-1.10.7-766kapalbrdntu2pcgdgbhg2ch26gsuv + /usr/workspace/e3sm/spack/libs/linux-rhel8-sapphirerapids/intel-2021.6.0/netcdf-c-4.4.1.1-2uznnlwgiezxute6iyqzqjrpolokeaib + /usr/workspace/e3sm/spack/libs/linux-rhel8-sapphirerapids/intel-2021.6.0/netcdf-fortran-4.4.4-itpstyordbern7vlulmlnt47eeeokzfp + /usr/workspace/e3sm/spack/libs/linux-rhel8-sapphirerapids/intel-2021.6.0/parallel-netcdf-1.11.0-26sxm4mormsglmhi24poix7sugbigkck From 2413f42432a1e635117335c31d3bc7feef4f285d Mon Sep 17 00:00:00 2001 From: "Andrew M. Bradley" Date: Tue, 24 Sep 2024 14:10:12 -0500 Subject: [PATCH 451/451] Hommexx: Temporarily work around some EAMxx-Hommexx incompatibilities. These are due to PR #6594 and break the E3SM-repo EAMxx build. Once the SCREAM and E3SM repos are unified, we can back out these workarounds. The workarounds are isolated to components/homme, keeping the commit separation of components/eamxx (SCREAM repo) and components/homme (E3SM repo) clean. --- .../homme/src/preqx_kokkos/cxx/cxx_f90_interface_preqx.cpp | 1 + components/homme/src/share/cxx/HommexxEnums.hpp | 6 ++++++ components/homme/src/share/cxx/SimulationParams.hpp | 1 + .../src/theta-l_kokkos/cxx/cxx_f90_interface_theta.cpp | 1 + components/homme/src/theta-l_kokkos/prim_driver_mod.F90 | 6 ++++-- 5 files changed, 13 insertions(+), 2 deletions(-) diff --git a/components/homme/src/preqx_kokkos/cxx/cxx_f90_interface_preqx.cpp b/components/homme/src/preqx_kokkos/cxx/cxx_f90_interface_preqx.cpp index b433a48c2abc..aa21f5c16f29 100644 --- a/components/homme/src/preqx_kokkos/cxx/cxx_f90_interface_preqx.cpp +++ b/components/homme/src/preqx_kokkos/cxx/cxx_f90_interface_preqx.cpp @@ -91,6 +91,7 @@ void init_simulation_params_c (const int& remap_alg, const int& limiter_option, params.hypervis_scaling = hypervis_scaling; params.disable_diagnostics = disable_diagnostics; params.use_moisture = use_moisture; + params.moisture = params.use_moisture ? MoistDry::MOIST : MoistDry::DRY; //todo-repo-unification params.use_cpstar = use_cpstar; params.transport_alg = transport_alg; // SphereOperators parameters; preqx supports only the sphere. diff --git a/components/homme/src/share/cxx/HommexxEnums.hpp b/components/homme/src/share/cxx/HommexxEnums.hpp index 06abbf35adbc..f41ed9d3651e 100644 --- a/components/homme/src/share/cxx/HommexxEnums.hpp +++ b/components/homme/src/share/cxx/HommexxEnums.hpp @@ -40,6 +40,12 @@ enum class ComparisonOp { // =================== Run parameters enums ====================== // +//todo-repo-unification Remove this enum in favor of bool +// SimulationParams::use_moisture once we change EAMxx to use +// use_moisture. Search "todo-repo-unification" for other bits of code to +// remove. +enum class MoistDry { MOIST, DRY }; + enum class ForcingAlg : int { FORCING_OFF =-1, FORCING_0 = 0, diff --git a/components/homme/src/share/cxx/SimulationParams.hpp b/components/homme/src/share/cxx/SimulationParams.hpp index 4f36962b16c3..9247f54a352c 100644 --- a/components/homme/src/share/cxx/SimulationParams.hpp +++ b/components/homme/src/share/cxx/SimulationParams.hpp @@ -24,6 +24,7 @@ struct SimulationParams TimeStepType time_step_type; bool use_moisture; + MoistDry moisture; //todo-repo-unification RemapAlg remap_alg; TestCase test_case; ForcingAlg ftype = ForcingAlg::FORCING_OFF; diff --git a/components/homme/src/theta-l_kokkos/cxx/cxx_f90_interface_theta.cpp b/components/homme/src/theta-l_kokkos/cxx/cxx_f90_interface_theta.cpp index 40c4ae64dc98..e96b838f0961 100644 --- a/components/homme/src/theta-l_kokkos/cxx/cxx_f90_interface_theta.cpp +++ b/components/homme/src/theta-l_kokkos/cxx/cxx_f90_interface_theta.cpp @@ -114,6 +114,7 @@ void init_simulation_params_c (const int& remap_alg, const int& limiter_option, params.hypervis_scaling = hypervis_scaling; params.disable_diagnostics = (bool)disable_diagnostics; params.use_moisture = (bool)use_moisture; + params.moisture = params.use_moisture ? MoistDry::MOIST : MoistDry::DRY; //todo-repo-unification params.use_cpstar = (bool)use_cpstar; params.transport_alg = transport_alg; params.theta_hydrostatic_mode = (bool)theta_hydrostatic_mode; diff --git a/components/homme/src/theta-l_kokkos/prim_driver_mod.F90 b/components/homme/src/theta-l_kokkos/prim_driver_mod.F90 index eae8544ca865..e7cc245a2bd7 100644 --- a/components/homme/src/theta-l_kokkos/prim_driver_mod.F90 +++ b/components/homme/src/theta-l_kokkos/prim_driver_mod.F90 @@ -353,12 +353,14 @@ subroutine prim_init_elements_views (elem) end subroutine prim_init_elements_views subroutine prim_init_kokkos_functors (allocate_buffer) - use iso_c_binding, only : c_int + !todo-repo-unification Remove the use of c_bool here. It's used in purely + ! F90 code. + use iso_c_binding, only : c_int, c_bool use theta_f2c_mod, only : init_functors_c, init_boundary_exchanges_c ! ! Optional Input ! - logical, intent(in), optional :: allocate_buffer ! Whether functor memory buffer should be allocated internally + logical(kind=c_bool), intent(in), optional :: allocate_buffer ! Whether functor memory buffer should be allocated internally integer(kind=c_int) :: ab ! Initialize the C++ functors in the C++ context ! If no argument allocate_buffer is present,