From cc60fb5b489e864260e8c6bcaa82a2d2c7ca9fc1 Mon Sep 17 00:00:00 2001 From: Haipeng Lin Date: Wed, 10 Sep 2025 20:58:51 -0600 Subject: [PATCH 1/4] Misc fix: 3-D input field read with dycore enabled; cam_in/cam_out from physics data. Add FADIAB test Update comment --- cime_config/testdefs/testlist_cam.xml | 10 +++++++++ src/control/cam_comp.F90 | 18 ++++++++-------- src/cpl/nuopc/atm_comp_nuopc.F90 | 3 +-- src/utils/cam_field_read.F90 | 31 +++++++++++++++++++++------ 4 files changed, 45 insertions(+), 17 deletions(-) diff --git a/cime_config/testdefs/testlist_cam.xml b/cime_config/testdefs/testlist_cam.xml index ccec7022..97573ab1 100644 --- a/cime_config/testdefs/testlist_cam.xml +++ b/cime_config/testdefs/testlist_cam.xml @@ -121,6 +121,16 @@ + + + + + + + + + + diff --git a/src/control/cam_comp.F90 b/src/control/cam_comp.F90 index 3af07091..28b76119 100644 --- a/src/control/cam_comp.F90 +++ b/src/control/cam_comp.F90 @@ -145,8 +145,8 @@ subroutine cam_init(caseid, ctitle, model_doi_url, & integer, intent(in) :: ref_ymd ! Reference date (YYYYMMDD) integer, intent(in) :: ref_tod ! Reference time of day (sec) - type(cam_out_t), pointer :: cam_out ! Output from CAM to surface - type(cam_in_t), pointer :: cam_in ! Merged input state to CAM + type(cam_out_t) :: cam_out ! Output from CAM to surface + type(cam_in_t) :: cam_in ! Merged input state to CAM ! Local variables character(len=cs) :: filein ! Input namelist filename @@ -357,8 +357,8 @@ subroutine cam_run1(cam_in, cam_out) use phys_comp, only: phys_run1 ! use ionosphere_interface, only: ionosphere_run1 - type(cam_in_t), pointer, intent(inout) :: cam_in ! Input from surface to CAM - type(cam_out_t), pointer, intent(inout) :: cam_out ! Output from CAM to surface + type(cam_in_t), intent(inout) :: cam_in ! Input from surface to CAM + type(cam_out_t), intent(inout) :: cam_out ! Output from CAM to surface !---------------------------------------------------------- ! first phase of ionosphere -- write to IC file if needed @@ -396,8 +396,8 @@ subroutine cam_run2(cam_out, cam_in) use stepon, only: stepon_run2 ! use ionosphere_interface, only: ionosphere_run2 - type(cam_out_t), pointer, intent(inout) :: cam_out ! Output from CAM to surface - type(cam_in_t), pointer, intent(inout) :: cam_in ! Input from surface to CAM + type(cam_out_t), intent(inout) :: cam_out ! Output from CAM to surface + type(cam_in_t), intent(inout) :: cam_in ! Input from surface to CAM ! ! Second phase of physics (after surface model update) @@ -439,7 +439,7 @@ subroutine cam_run3(cam_out) !----------------------------------------------------------------------- use stepon, only: stepon_run3 - type(cam_out_t), pointer, intent(inout) :: cam_out ! Output from CAM to surface + type(cam_out_t), intent(inout) :: cam_out ! Output from CAM to surface !----------------------------------------------------------------------- ! @@ -564,8 +564,8 @@ subroutine cam_final(cam_out, cam_in) ! ! Arguments ! - type(cam_out_t), pointer :: cam_out ! Output from CAM to surface - type(cam_in_t), pointer :: cam_in ! Input from merged surface to CAM + type(cam_out_t) :: cam_out ! Output from CAM to surface + type(cam_in_t) :: cam_in ! Input from merged surface to CAM !----------------------------------------------------------------------- diff --git a/src/cpl/nuopc/atm_comp_nuopc.F90 b/src/cpl/nuopc/atm_comp_nuopc.F90 index 4e7498b9..aa420652 100644 --- a/src/cpl/nuopc/atm_comp_nuopc.F90 +++ b/src/cpl/nuopc/atm_comp_nuopc.F90 @@ -44,6 +44,7 @@ module atm_comp_nuopc use cam_comp , only : cam_init, cam_run1, cam_run2, cam_run3, cam_run4, cam_final use cam_comp , only : cam_timestep_init, cam_timestep_final use physics_types , only : cam_out_t, cam_in_t + use physics_types , only : cam_out, cam_in ! use radiation , only : nextsw_cday !uncomment once radiation has been CCPP-ized -JN use cam_logfile , only : cam_set_log_unit, iulog use cam_abortutils , only : check_allocate @@ -108,8 +109,6 @@ module atm_comp_nuopc integer :: nthrds integer :: ierr ! allocate status integer , parameter :: dbug_flag = 0 - type(cam_in_t) , pointer :: cam_in - type(cam_out_t) , pointer :: cam_out integer , pointer :: dof(:) ! global index space decomposition character(len=256) :: rsfilename_spec_cam ! Filename specifier for restart surface file character(*) ,parameter :: modName = "(atm_comp_nuopc)" diff --git a/src/utils/cam_field_read.F90 b/src/utils/cam_field_read.F90 index af3e5080..12df2d54 100644 --- a/src/utils/cam_field_read.F90 +++ b/src/utils/cam_field_read.F90 @@ -788,12 +788,28 @@ subroutine infld_real8_3d(varname, ncid, field, readvar, dim3name, & ! ! Ensure that is configured correctly if (dim_bounds(2,2) < dim_bounds(2,1)) then - if (present(gridname)) then - write(errormsg, *) ': grid, ', trim(gridname), & - ' invalid for3D field' + if(unstruct) then + ! Unstructured grid expects that a second dimension does not + ! exist horizontally. Receive vertical dimension from caller + if (present(dim3_pos)) then + if ((dim3_pos < 1) .or. (dim3_pos > 3)) then + call safe_endrun(subname//': Bad value for dim3_pos') + end if + index = dim3_pos + else + index = 2 + end if + dim_bounds(index,1) = dim3_bnds(1) + dim_bounds(index,2) = dim3_bnds(2) else - write(errormsg, *) ': grid, physgrid, invalid for3D field' - end if + if (present(gridname)) then + write(errormsg, *) ': grid, ', trim(gridname), & + ' invalid for 3D field' + else + write(errormsg, *) ': grid, physgrid, invalid for 3D field' + end if + call safe_endrun(subname//errormsg) + endif else if (present(dim3_pos)) then if ((dim3_pos < 1) .or. (dim3_pos > 3)) then @@ -866,7 +882,10 @@ subroutine infld_real8_3d(varname, ncid, field, readvar, dim3name, & (grid_dimlens(1) * grid_dimlens(2)) call safe_endrun(subname//trim(errormsg)) end if - else + else if (unstruct) then + ! Initialize index offset to remove vertical dimension from dimlens + ! to be checked. + index = 0 do jndex = 1, target_ndims if (trim(file_dnames(jndex)) == trim(dim3name)) then ! The vertical dimension may be in between array dims From db335b5d8d4458000918b7f44f4d36a385a0f702 Mon Sep 17 00:00:00 2001 From: Haipeng Lin Date: Fri, 12 Sep 2025 12:48:37 -0400 Subject: [PATCH 2/4] Update cime_config/testdefs/testlist_cam.xml Co-authored-by: Jesse Nusbaumer --- cime_config/testdefs/testlist_cam.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cime_config/testdefs/testlist_cam.xml b/cime_config/testdefs/testlist_cam.xml index 97573ab1..2bbf396f 100644 --- a/cime_config/testdefs/testlist_cam.xml +++ b/cime_config/testdefs/testlist_cam.xml @@ -128,7 +128,7 @@ - + From 573cf9a57e4b5b2683c5f766c2de5e9e1f45769f Mon Sep 17 00:00:00 2001 From: Haipeng Lin Date: Fri, 12 Sep 2025 10:48:56 -0600 Subject: [PATCH 3/4] Address review comments --- src/control/cam_comp.F90 | 4 ++-- src/cpl/nuopc/atm_comp_nuopc.F90 | 1 - 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/src/control/cam_comp.F90 b/src/control/cam_comp.F90 index 28b76119..5947e932 100644 --- a/src/control/cam_comp.F90 +++ b/src/control/cam_comp.F90 @@ -145,8 +145,8 @@ subroutine cam_init(caseid, ctitle, model_doi_url, & integer, intent(in) :: ref_ymd ! Reference date (YYYYMMDD) integer, intent(in) :: ref_tod ! Reference time of day (sec) - type(cam_out_t) :: cam_out ! Output from CAM to surface - type(cam_in_t) :: cam_in ! Merged input state to CAM + type(cam_out_t), intent(inout) :: cam_out ! Output from CAM to surface + type(cam_in_t) , intent(inout) :: cam_in ! Merged input state to CAM ! Local variables character(len=cs) :: filein ! Input namelist filename diff --git a/src/cpl/nuopc/atm_comp_nuopc.F90 b/src/cpl/nuopc/atm_comp_nuopc.F90 index aa420652..bc202466 100644 --- a/src/cpl/nuopc/atm_comp_nuopc.F90 +++ b/src/cpl/nuopc/atm_comp_nuopc.F90 @@ -43,7 +43,6 @@ module atm_comp_nuopc use cam_instance , only : cam_instance_init, inst_suffix, inst_index use cam_comp , only : cam_init, cam_run1, cam_run2, cam_run3, cam_run4, cam_final use cam_comp , only : cam_timestep_init, cam_timestep_final - use physics_types , only : cam_out_t, cam_in_t use physics_types , only : cam_out, cam_in ! use radiation , only : nextsw_cday !uncomment once radiation has been CCPP-ized -JN use cam_logfile , only : cam_set_log_unit, iulog From d347cf38324022599965f1ff689517c1044b8f94 Mon Sep 17 00:00:00 2001 From: Haipeng Lin Date: Fri, 12 Sep 2025 15:36:29 -0600 Subject: [PATCH 4/4] Updated to remove unused cam_in/cam_outs --- src/control/cam_comp.F90 | 32 +++++++------------------------- src/cpl/nuopc/atm_comp_nuopc.F90 | 20 +++++++++----------- 2 files changed, 16 insertions(+), 36 deletions(-) diff --git a/src/control/cam_comp.F90 b/src/control/cam_comp.F90 index 5947e932..af139aba 100644 --- a/src/control/cam_comp.F90 +++ b/src/control/cam_comp.F90 @@ -75,8 +75,7 @@ subroutine cam_init(caseid, ctitle, model_doi_url, & eccen, obliqr, lambm0, mvelpp, & perpetual_run, perpetual_ymd, & dtime, start_ymd, start_tod, ref_ymd, ref_tod, & - stop_ymd, stop_tod, curr_ymd, curr_tod, & - cam_out, cam_in) + stop_ymd, stop_tod, curr_ymd, curr_tod) !----------------------------------------------------------------------- ! @@ -145,9 +144,6 @@ subroutine cam_init(caseid, ctitle, model_doi_url, & integer, intent(in) :: ref_ymd ! Reference date (YYYYMMDD) integer, intent(in) :: ref_tod ! Reference time of day (sec) - type(cam_out_t), intent(inout) :: cam_out ! Output from CAM to surface - type(cam_in_t) , intent(inout) :: cam_in ! Merged input state to CAM - ! Local variables character(len=cs) :: filein ! Input namelist filename integer :: errflg @@ -345,7 +341,7 @@ end subroutine cam_timestep_init ! !----------------------------------------------------------------------- ! - subroutine cam_run1(cam_in, cam_out) + subroutine cam_run1() !----------------------------------------------------------------------- ! ! Purpose: First phase of atmosphere model run method. @@ -357,9 +353,6 @@ subroutine cam_run1(cam_in, cam_out) use phys_comp, only: phys_run1 ! use ionosphere_interface, only: ionosphere_run1 - type(cam_in_t), intent(inout) :: cam_in ! Input from surface to CAM - type(cam_out_t), intent(inout) :: cam_out ! Output from CAM to surface - !---------------------------------------------------------- ! first phase of ionosphere -- write to IC file if needed !---------------------------------------------------------- @@ -381,7 +374,7 @@ end subroutine cam_run1 !----------------------------------------------------------------------- ! - subroutine cam_run2(cam_out, cam_in) + subroutine cam_run2() !----------------------------------------------------------------------- ! ! Purpose: Second phase of atmosphere model run method. @@ -396,9 +389,6 @@ subroutine cam_run2(cam_out, cam_in) use stepon, only: stepon_run2 ! use ionosphere_interface, only: ionosphere_run2 - type(cam_out_t), intent(inout) :: cam_out ! Output from CAM to surface - type(cam_in_t), intent(inout) :: cam_in ! Input from surface to CAM - ! ! Second phase of physics (after surface model update) ! @@ -428,7 +418,7 @@ end subroutine cam_run2 !----------------------------------------------------------------------- ! - subroutine cam_run3(cam_out) + subroutine cam_run3() !----------------------------------------------------------------------- ! ! Purpose: Third phase of atmosphere model run method. This consists @@ -438,8 +428,8 @@ subroutine cam_run3(cam_out) ! !----------------------------------------------------------------------- use stepon, only: stepon_run3 + use physics_types, only: cam_out ! Output from CAM to surface - type(cam_out_t), intent(inout) :: cam_out ! Output from CAM to surface !----------------------------------------------------------------------- ! @@ -457,7 +447,7 @@ end subroutine cam_run3 !----------------------------------------------------------------------- ! - subroutine cam_run4(cam_out, cam_in, rstwr, nlend, & + subroutine cam_run4(rstwr, nlend, & yr_spec, mon_spec, day_spec, sec_spec) !----------------------------------------------------------------------- @@ -470,8 +460,6 @@ subroutine cam_run4(cam_out, cam_in, rstwr, nlend, & ! use cam_restart, only: cam_write_restart ! use qneg_module, only: qneg_print_summary - type(cam_out_t), intent(inout) :: cam_out ! Output from CAM to surface - type(cam_in_t), intent(inout) :: cam_in ! Input from surface to CAM logical, intent(in) :: rstwr ! write restart file logical, intent(in) :: nlend ! this is final timestep integer, intent(in), optional :: yr_spec ! Simulation year @@ -549,7 +537,7 @@ end subroutine cam_timestep_final !----------------------------------------------------------------------- ! - subroutine cam_final(cam_out, cam_in) + subroutine cam_final() !----------------------------------------------------------------------- ! ! Purpose: CAM finalization. @@ -561,12 +549,6 @@ subroutine cam_final(cam_out, cam_in) ! use ionosphere_interface, only: ionosphere_final use cam_control_mod, only: initial_run - ! - ! Arguments - ! - type(cam_out_t) :: cam_out ! Output from CAM to surface - type(cam_in_t) :: cam_in ! Input from merged surface to CAM - !----------------------------------------------------------------------- call phys_final() diff --git a/src/cpl/nuopc/atm_comp_nuopc.F90 b/src/cpl/nuopc/atm_comp_nuopc.F90 index bc202466..b13cbe94 100644 --- a/src/cpl/nuopc/atm_comp_nuopc.F90 +++ b/src/cpl/nuopc/atm_comp_nuopc.F90 @@ -662,9 +662,7 @@ subroutine InitializeRealize(gcomp, importState, exportState, clock, rc) stop_ymd=stop_ymd, & stop_tod=stop_tod, & curr_ymd=curr_ymd, & - curr_tod=curr_tod, & - cam_out=cam_out, & - cam_in=cam_in) + curr_tod=curr_tod) if (mediator_present) then @@ -916,7 +914,7 @@ subroutine DataInitialize(gcomp, rc) call import_fields( gcomp, cam_in, rc=rc ) if (ChkErr(rc,__LINE__,u_FILE_u)) return call cam_timestep_init() - call cam_run1 ( cam_in, cam_out ) + call cam_run1 () call export_fields( gcomp, model_mesh, model_clock, cam_out, rc=rc ) if (ChkErr(rc,__LINE__,u_FILE_u)) return else @@ -925,7 +923,7 @@ subroutine DataInitialize(gcomp, rc) call import_fields( gcomp, cam_in, restart_init=.true., rc=rc ) if (ChkErr(rc,__LINE__,u_FILE_u)) return call cam_timestep_init() - call cam_run1 ( cam_in, cam_out ) + call cam_run1 () call export_fields( gcomp, model_mesh, model_clock, cam_out, rc=rc ) if (ChkErr(rc,__LINE__,u_FILE_u)) return end if @@ -978,7 +976,7 @@ subroutine DataInitialize(gcomp, rc) !--------------------------------------------------------------- call cam_timestep_init() - call cam_run1 ( cam_in, cam_out ) + call cam_run1 () call NUOPC_CompAttributeSet(gcomp, name="InitializeDataComplete", value="true", rc=rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return @@ -1154,15 +1152,15 @@ subroutine ModelAdvance(gcomp, rc) ! This includes the "physics_after_coupler" CCPP physics group. call t_startf ('CAM_run2') - call cam_run2( cam_out, cam_in ) + call cam_run2() call t_stopf ('CAM_run2') call t_startf ('CAM_run3') - call cam_run3( cam_out ) + call cam_run3() call t_stopf ('CAM_run3') call t_startf ('CAM_run4') - call cam_run4( cam_out, cam_in, rstwr, nlend, & + call cam_run4( rstwr, nlend, & yr_spec=yr_sync, mon_spec=mon_sync, day_spec=day_sync, sec_spec=tod_sync) call t_stopf ('CAM_run4') call cam_timestep_final(rstwr, nlend, do_ncdata_check=do_ncdata_check) @@ -1178,7 +1176,7 @@ subroutine ModelAdvance(gcomp, rc) ! This includes the "physics_before_coupler" CCPP physics group. call t_startf ('CAM_run1') - call cam_run1 ( cam_in, cam_out ) + call cam_run1 () call t_stopf ('CAM_run1') end do @@ -1451,7 +1449,7 @@ subroutine ModelFinalize(gcomp, rc) endif call cam_timestep_final(rstwr, nlend, do_ncdata_check=.false., do_history_write=.false.) - call cam_final(cam_out, cam_in) + call cam_final() if (masterproc) then write(iulog,F91)