diff --git a/.zenodo.json b/.zenodo.json index 6a3217023..f5b00f1f8 100644 --- a/.zenodo.json +++ b/.zenodo.json @@ -1,19 +1,22 @@ { - "license": "other-open", - "description": "No description provided", + "license": "BSD-3-Clause", + "copyright": "Copyright (c) 1998, 2017 Triad National Security, LLC", + "description": "View detailed release notes at https://github.com/CICE-Consortium/CICE/releases", "language": "eng", - "title": "CICE-Consortium/CICE: CICE Version m.n.p", + "title": "CICE-Consortium/CICE: CICE Version 6.6.1", "keywords": [ - "sea ice model, CICE, Icepack" + "sea ice model", + "CICE", + "Icepack" ], - "version": "m.n.p", + "version": "6.6.1", "upload_type": "software", "communities": [ { "identifier": "cice-consortium" } ], - "publication_date": "2019-07-25", + "publication_date": "2025-07-21", "creators": [ { "affiliation": "Los Alamos National Laboratory", @@ -32,7 +35,11 @@ "name": "Philippe Blain" }, { - "affiliation": "National Oceanographic and Atmospheric Administration (CTR)", + "affiliation": "National Center for Atmospheric Research", + "name": "David Clemens-Sewall" + }, + { + "affiliation": "National Oceanic and Atmospheric Administration (CTR)", "name": "Anthony Craig" }, { @@ -44,7 +51,11 @@ "name": "Alice DuVivier" }, { - "affiliation": "National Oceanographic and Atmospheric Administration", + "affiliation": "National Center for Atmospheric Research", + "name": "Jim Edwards" + }, + { + "affiliation": "National Oceanic and Atmospheric Administration", "name": "Robert Grumbine" }, { @@ -67,6 +78,10 @@ "affiliation": "Institute of Oceanology, Polish Academy of Sciences", "name": "Robert Osinski" }, + { + "affiliation": "Intel Corporation", + "name": "Jacob Poulsen" + }, { "affiliation": "Danish Meteorological Institute", "name": "Till Rasmussen" @@ -75,10 +90,18 @@ "affiliation": "Danish Meteorological Institute", "name": "Mads Ribergaard" }, + { + "affiliation": "Alfred-Wegener-Institut Helmholz-Zentrum fur Polar- und Meersforschung", + "name": "Lettie Roach" + }, { "affiliation": "Los Alamos National Laboratory", "name": "Andrew Roberts" }, + { + "affiliation": "Australian Earth-System Simulator", + "name": "Anton Steketee" + }, { "affiliation": "Los Alamos National Laboratory", "name": "Matthew Turner" @@ -86,9 +109,18 @@ { "affiliation": "Geophysical Fluid Dynamics Laboratory", "name": "Michael Winton" + }, + { + "affiliation": "National Oceanic and Atmospheric Administration", + "name": "Denise Worthen" + }, + { + "affiliation": "National Aeronautics and Space Administration", + "name": "Bin Zhao" } ], "access_right": "open", + "repository_url": "https://github.com/CICE-Consortium/CICE", "related_identifiers": [ { "identifier": "https://github.com/CICE-Consortium/CICE/tree/CICE6.0.1", diff --git a/COPYRIGHT.pdf b/COPYRIGHT.pdf new file mode 100644 index 000000000..55132ca5e Binary files /dev/null and b/COPYRIGHT.pdf differ diff --git a/DistributionPolicy.pdf b/DistributionPolicy.pdf index 014c88815..cb8c17ac8 100644 Binary files a/DistributionPolicy.pdf and b/DistributionPolicy.pdf differ diff --git a/LICENSE.pdf b/LICENSE.pdf index 18e26a099..5fea34da5 100644 Binary files a/LICENSE.pdf and b/LICENSE.pdf differ diff --git a/README.md b/README.md index 45e4a6a1a..395cb6999 100644 --- a/README.md +++ b/README.md @@ -6,7 +6,7 @@ ## The CICE Consortium sea-ice model -CICE is a computationally efficient model for simulating the growth, melting, and movement of polar sea ice. Designed as one component of coupled atmosphere-ocean-land-ice global climate models, today’s CICE model is the outcome of more than two decades of community collaboration in building a sea ice model suitable for multiple uses including process studies, operational forecasting, and climate simulation. +CICE is a computationally efficient model for simulating the growth, melting, and movement of polar sea ice. Designed as one component of coupled atmosphere-ocean-land-ice global coupled models, today’s CICE model is the outcome of more than two decades of community collaboration in building a sea ice model suitable for multiple uses including process studies, operational forecasting, and Earth system simulation. This repository contains the files and code needed to run the CICE sea ice numerical model starting with version 6. CICE is maintained by the CICE Consortium. diff --git a/cicecore/cicedyn/analysis/ice_history.F90 b/cicecore/cicedyn/analysis/ice_history.F90 index a0313c56c..a6eabe2db 100644 --- a/cicecore/cicedyn/analysis/ice_history.F90 +++ b/cicecore/cicedyn/analysis/ice_history.F90 @@ -69,7 +69,7 @@ subroutine init_hist (dt) use ice_domain_size, only: max_blocks, max_nstrm, nilyr, nslyr, nblyr, ncat, nfsd use ice_dyn_shared, only: kdyn use ice_flux, only: mlt_onset, frz_onset, albcnt, snwcnt - use ice_grid, only: grid_ice, & + use ice_grid, only: grid_ice, grid_outfile, & grid_atm_thrm, grid_atm_dynu, grid_atm_dynv, & grid_ocn_thrm, grid_ocn_dynu, grid_ocn_dynv use ice_history_shared ! everything @@ -239,15 +239,14 @@ subroutine init_hist (dt) call get_fileunit(nu_nml) open (nu_nml, file=trim(nml_filename), status='old',iostat=nml_error) if (nml_error /= 0) then - call abort_ice(subname//'ERROR: '//trim(nml_name)//' open file '// & - trim(nml_filename), & - file=__FILE__, line=__LINE__) + call abort_ice(subname//' ERROR: '//trim(nml_name)//' open file '// & + trim(nml_filename), file=__FILE__, line=__LINE__) endif ! seek to this namelist call goto_nml(nu_nml,trim(nml_name),nml_error) if (nml_error /= 0) then - call abort_ice(subname//'ERROR: searching for '// trim(nml_name), & + call abort_ice(subname//' ERROR: searching for '// trim(nml_name), & file=__FILE__, line=__LINE__) endif @@ -260,7 +259,7 @@ subroutine init_hist (dt) ! backspace and re-read erroneous line backspace(nu_nml) read(nu_nml,fmt='(A)') tmpstr2 - call abort_ice(subname//'ERROR: ' // trim(nml_name) // ' reading ' // & + call abort_ice(subname//' ERROR: ' // trim(nml_name) // ' reading ' // & trim(tmpstr2), file=__FILE__, line=__LINE__) endif end do @@ -278,23 +277,35 @@ subroutine init_hist (dt) nstreams = nstreams + 1 if (ns >= 2) then if (histfreq(ns-1) == 'x') then - call abort_ice(subname//'ERROR: histfreq all non x must be at start of array') + call abort_ice(subname//' ERROR: histfreq all non x must be at start of array', & + file=__FILE__, line=__LINE__) endif endif else if (histfreq(ns) /= 'x') then - call abort_ice(subname//'ERROR: histfreq contains illegal element') + write(nu_diag, * ) subname,' ns,histfreq = ',ns,histfreq(ns) + call abort_ice(subname//' ERROR: histfreq contains illegal element', & + file=__FILE__, line=__LINE__) endif enddo - if (nstreams == 0) write (nu_diag,*) 'WARNING: No history output' + if (nstreams == 0 .and. my_task == master_task) write (nu_diag,*) subname,' WARNING: No history output' do ns1 = 1, nstreams do ns2 = 1, nstreams if (histfreq(ns1) == histfreq(ns2) .and. ns1/=ns2 & .and. my_task == master_task) then - call abort_ice(subname//'ERROR: histfreq elements must be unique') + call abort_ice(subname//' ERROR: histfreq elements must be unique', & + file=__FILE__, line=__LINE__) endif enddo enddo + ! Turn on one-time grid output file + if (grid_outfile) then + nstreams = nstreams + 1 + histfreq(nstreams) = 'g' + hist_avg(nstreams) = .false. + if (my_task == master_task) write (nu_diag,*) subname,' Writing one-time grid file' + endif + if (.not. tr_iage) then f_iage = 'x' f_dagedtt = 'x' @@ -445,14 +456,6 @@ subroutine init_hist (dt) f_taubyE = f_tauby endif - ! write dimensions for 3D or 4D history variables - ! note: list of variables checked here is incomplete - if (f_aicen(1:1) /= 'x' .or. f_vicen(1:1) /= 'x' .or. & - f_Tinz (1:1) /= 'x' .or. f_Sinz (1:1) /= 'x') f_NCAT = .true. - if (f_Tinz (1:1) /= 'x' .or. f_Sinz (1:1) /= 'x') f_VGRDi = .true. - if (f_Tsnz (1:1) /= 'x') f_VGRDs = .true. - if (tr_fsd) f_NFSD = .true. - call broadcast_scalar (f_tlon, master_task) call broadcast_scalar (f_tlat, master_task) call broadcast_scalar (f_ulon, master_task) @@ -2319,7 +2322,7 @@ subroutine accum_hist (dt) timedbl = (timesecs-dt)/(secday) time_beg(ns) = real(timedbl,kind=real_kind) endif - enddo + enddo ! ns !--------------------------------------------------------------- ! increment field @@ -4195,6 +4198,13 @@ subroutine accum_hist (dt) enddo endif ! write_history or write_ic + + ! Turn off one-time grid output file + if (histfreq(ns) == 'g') then + histfreq(ns) = 'x' + nstreams = nstreams - 1 + endif + enddo ! nstreams !$OMP PARALLEL DO PRIVATE(iblk,i,j,ilo,ihi,jlo,jhi,this_block) diff --git a/cicecore/cicedyn/analysis/ice_history_pond.F90 b/cicecore/cicedyn/analysis/ice_history_pond.F90 index 976a87d40..88b5fa899 100644 --- a/cicecore/cicedyn/analysis/ice_history_pond.F90 +++ b/cicecore/cicedyn/analysis/ice_history_pond.F90 @@ -26,12 +26,19 @@ module ice_history_pond !--------------------------------------------------------------- character (len=max_nstrm), public :: & - f_apondn = 'm', f_apeffn = 'm', & - f_hpondn = 'm', & - f_apond = 'x', f_apond_ai = 'x', & - f_hpond = 'x', f_hpond_ai = 'x', & - f_ipond = 'x', f_ipond_ai = 'x', & - f_apeff = 'x', f_apeff_ai = 'x' + f_apondn = 'm', f_apeffn = 'm', & + f_hpondn = 'm', & + f_apond = 'x', f_apond_ai = 'x', & + f_hpond = 'x', f_hpond_ai = 'x', & + f_ipond = 'x', f_ipond_ai = 'x', & + f_apeff = 'x', f_apeff_ai = 'x', & + f_dpnd_flush = 'x', f_dpnd_expon = 'x', & + f_dpnd_freebd = 'x', f_dpnd_initial = 'x', & + f_dpnd_dlid = 'x', f_dpnd_melt = 'x', & + f_dpnd_ridge = 'x', & + f_dpnd_flushn = 'x', f_dpnd_exponn = 'x', & + f_dpnd_freebdn= 'x', f_dpnd_initialn= 'x', & + f_dpnd_dlidn = 'x' !--------------------------------------------------------------- ! namelist variables @@ -43,7 +50,19 @@ module ice_history_pond f_apond, f_apond_ai , & f_hpond, f_hpond_ai , & f_ipond, f_ipond_ai , & - f_apeff, f_apeff_ai + f_apeff, f_apeff_ai , & + f_dpnd_flush , & + f_dpnd_expon , & + f_dpnd_freebd , & + f_dpnd_initial , & + f_dpnd_dlid , & + f_dpnd_melt , & + f_dpnd_ridge , & + f_dpnd_flushn , & + f_dpnd_exponn , & + f_dpnd_freebdn , & + f_dpnd_initialn , & + f_dpnd_dlidn !--------------------------------------------------------------- ! field indices @@ -55,7 +74,14 @@ module ice_history_pond n_apond , n_apond_ai, & n_hpond , n_hpond_ai, & n_ipond , n_ipond_ai, & - n_apeff , n_apeff_ai + n_apeff , n_apeff_ai, & + n_dpnd_flush , n_dpnd_expon, & + n_dpnd_freebd , n_dpnd_initial, & + n_dpnd_dlid , n_dpnd_melt, & + n_dpnd_ridge , & + n_dpnd_flushn , n_dpnd_exponn, & + n_dpnd_freebdn, n_dpnd_initialn, & + n_dpnd_dlidn !======================================================================= @@ -73,13 +99,14 @@ subroutine init_hist_pond_2D integer (kind=int_kind) :: ns integer (kind=int_kind) :: nml_error ! namelist i/o error flag - logical (kind=log_kind) :: tr_pond + logical (kind=log_kind) :: tr_pond, tr_pond_topo character(len=char_len_long) :: tmpstr2 ! for namelist check character(len=char_len) :: nml_name ! text namelist name character(len=*), parameter :: subname = '(init_hist_pond_2D)' - call icepack_query_tracer_flags(tr_pond_out=tr_pond) + call icepack_query_tracer_flags(tr_pond_out=tr_pond,& + tr_pond_topo_out=tr_pond_topo) call icepack_warnings_flush(nu_diag) if (icepack_warnings_aborted()) call abort_ice(error_message=subname, & file=__FILE__, line=__LINE__) @@ -127,17 +154,46 @@ subroutine init_hist_pond_2D endif if (.not. tr_pond) then - f_apondn = 'x' - f_hpondn = 'x' - f_apeffn = 'x' - f_apond = 'x' - f_hpond = 'x' - f_ipond = 'x' - f_apeff = 'x' - f_apond_ai = 'x' - f_hpond_ai = 'x' - f_ipond_ai = 'x' - f_apeff_ai = 'x' + f_apondn = 'x' + f_hpondn = 'x' + f_apeffn = 'x' + f_apond = 'x' + f_hpond = 'x' + f_ipond = 'x' + f_apeff = 'x' + f_apond_ai = 'x' + f_hpond_ai = 'x' + f_ipond_ai = 'x' + f_apeff_ai = 'x' + f_dpnd_flush = 'x' + f_dpnd_expon = 'x' + f_dpnd_freebd = 'x' + f_dpnd_initial = 'x' + f_dpnd_dlid = 'x' + f_dpnd_melt = 'x' + f_dpnd_ridge = 'x' + f_dpnd_flushn = 'x' + f_dpnd_exponn = 'x' + f_dpnd_freebdn = 'x' + f_dpnd_initialn= 'x' + f_dpnd_dlidn = 'x' + endif + + if (tr_pond_topo) then + ! tcraig, July 2025. Turn off dpnd history fields for topo ponds, + ! they are not yet validated. This is temporary. + f_dpnd_flush = 'x' + f_dpnd_expon = 'x' + f_dpnd_freebd = 'x' + f_dpnd_initial = 'x' + f_dpnd_dlid = 'x' + f_dpnd_melt = 'x' + f_dpnd_ridge = 'x' + f_dpnd_flushn = 'x' + f_dpnd_exponn = 'x' + f_dpnd_freebdn = 'x' + f_dpnd_initialn= 'x' + f_dpnd_dlidn = 'x' endif call broadcast_scalar (f_apondn, master_task) @@ -151,6 +207,18 @@ subroutine init_hist_pond_2D call broadcast_scalar (f_hpond_ai, master_task) call broadcast_scalar (f_ipond_ai, master_task) call broadcast_scalar (f_apeff_ai, master_task) + call broadcast_scalar (f_dpnd_flush , master_task) + call broadcast_scalar (f_dpnd_expon , master_task) + call broadcast_scalar (f_dpnd_freebd , master_task) + call broadcast_scalar (f_dpnd_initial , master_task) + call broadcast_scalar (f_dpnd_dlid , master_task) + call broadcast_scalar (f_dpnd_melt , master_task) + call broadcast_scalar (f_dpnd_ridge , master_task) + call broadcast_scalar (f_dpnd_flushn , master_task) + call broadcast_scalar (f_dpnd_exponn , master_task) + call broadcast_scalar (f_dpnd_freebdn , master_task) + call broadcast_scalar (f_dpnd_initialn, master_task) + call broadcast_scalar (f_dpnd_dlidn , master_task) if (tr_pond) then @@ -206,6 +274,48 @@ subroutine init_hist_pond_2D "weighted by ice area", c1, c0, & ns, f_apeff_ai) + if (f_dpnd_flush(1:1) /= 'x') & + call define_hist_field(n_dpnd_flush,"dpnd_flush","m/s",tstr2D, tcstr, & + "pond flushing rate due to ice permeability", & + "none", c1, c0, & + ns, f_dpnd_flush) + + if (f_dpnd_expon(1:1) /= 'x') & + call define_hist_field(n_dpnd_expon,"dpnd_expon","m/s",tstr2D, tcstr, & + "exponential pond drainage rate", & + "none", c1, c0, & + ns, f_dpnd_expon) + + if (f_dpnd_freebd(1:1) /= 'x') & + call define_hist_field(n_dpnd_freebd,"dpnd_freebd","m/s",tstr2D, tcstr, & + "pond drainage rate due to freeboard constraint", & + "none", c1, c0, & + ns, f_dpnd_freebd) + + if (f_dpnd_initial(1:1) /= 'x') & + call define_hist_field(n_dpnd_initial,"dpnd_initial","m/s",tstr2D, tcstr, & + "runoff rate due to rfrac", & + "none", c1, c0, & + ns, f_dpnd_initial) + + if (f_dpnd_dlid(1:1) /= 'x') & + call define_hist_field(n_dpnd_dlid,"dpnd_dlid","m/s",tstr2D, tcstr, & + "pond loss / gain to ice lid freezing / melting", & + "none", c1, c0, & + ns, f_dpnd_dlid) + + if (f_dpnd_melt(1:1) /= 'x') & + call define_hist_field(n_dpnd_melt,"dpnd_melt","m/s",tstr2D, tcstr, & + "pond drainage due to ice melting", & + "none", c1, c0, & + ns, f_dpnd_melt) + + if (f_dpnd_ridge(1:1) /= 'x') & + call define_hist_field(n_dpnd_ridge,"dpnd_ridge","m",tstr2D, tcstr, & + "pond drainage due to ridging", & + "none", c1, c0, & + ns, f_dpnd_ridge) + endif ! histfreq(ns) /= 'x' enddo ! nstreams @@ -251,6 +361,36 @@ subroutine init_hist_pond_3Dc "none", c1, c0, & ns, f_apeffn) + if (f_dpnd_flushn(1:1) /= 'x') & + call define_hist_field(n_dpnd_flushn,"dpnd_flushn","m/s",tstr3Dc, tcstr, & + "category pond flushing rate due to ice permeability", & + "none", c1, c0, & + ns, f_dpnd_flushn) + + if (f_dpnd_exponn(1:1) /= 'x') & + call define_hist_field(n_dpnd_exponn,"dpnd_exponn","m/s",tstr3Dc, tcstr, & + "category exponential pond drainage rate", & + "none", c1, c0, & + ns, f_dpnd_exponn) + + if (f_dpnd_freebdn(1:1) /= 'x') & + call define_hist_field(n_dpnd_freebdn,"dpnd_freebdn","m/s",tstr3Dc, tcstr, & + "category pond drainage rate due to freeboard constraint", & + "none", c1, c0, & + ns, f_dpnd_freebdn) + + if (f_dpnd_initialn(1:1) /= 'x') & + call define_hist_field(n_dpnd_initialn,"dpnd_initialn","m/s",tstr3Dc, tcstr, & + "category runoff rate due to rfrac", & + "none", c1, c0, & + ns, f_dpnd_initialn) + + if (f_dpnd_dlidn(1:1) /= 'x') & + call define_hist_field(n_dpnd_dlidn,"dpnd_dlidn","m/s",tstr3Dc, tcstr, & + "category pond loss / gain to ice lid freezing / melting", & + "none", c1, c0, & + ns, f_dpnd_dlidn) + endif ! histfreq(ns) /= 'x' enddo ! ns @@ -268,6 +408,9 @@ subroutine accum_hist_pond (iblk) use ice_blocks, only: block, get_block, nx_block, ny_block use ice_domain, only: blocks_ice use ice_flux, only: apeff_ai + use ice_flux, only: dpnd_flush, dpnd_expon, dpnd_freebd, dpnd_initial + use ice_flux, only: dpnd_dlid, dpnd_melt,dpnd_ridge, dpnd_dlidn + use ice_flux, only: dpnd_flushn, dpnd_exponn, dpnd_freebdn, dpnd_initialn use ice_history_shared, only: n2D, a2D, a3Dc, ncat_hist, & accum_hist_field use ice_state, only: aice, trcr, trcrn @@ -287,7 +430,7 @@ subroutine accum_hist_pond (iblk) integer (kind=int_kind) :: & nt_apnd, nt_hpnd, nt_alvl, nt_ipnd logical (kind=log_kind) :: & - tr_pond_lvl, tr_pond_topo + tr_pond_lvl, tr_pond_sealvl, tr_pond_topo real (kind=dbl_kind) :: & puny @@ -303,7 +446,7 @@ subroutine accum_hist_pond (iblk) call icepack_query_parameters(puny_out=puny) call icepack_query_tracer_flags(tr_pond_lvl_out=tr_pond_lvl, & - tr_pond_topo_out=tr_pond_topo) + tr_pond_topo_out=tr_pond_topo, tr_pond_sealvl_out=tr_pond_sealvl) call icepack_query_tracer_indices(nt_apnd_out=nt_apnd, nt_hpnd_out=nt_hpnd, & nt_alvl_out=nt_alvl, nt_ipnd_out=nt_ipnd) call icepack_warnings_flush(nu_diag) @@ -340,7 +483,7 @@ subroutine accum_hist_pond (iblk) * trcr(:,:,nt_alvl,iblk) * trcr(:,:,nt_apnd,iblk) & * trcr(:,:,nt_ipnd,iblk), a2D) - elseif (tr_pond_topo) then + elseif (tr_pond_topo .or. tr_pond_sealvl) then if (f_apond(1:1)/= 'x') & call accum_hist_field(n_apond, iblk, & @@ -385,6 +528,21 @@ subroutine accum_hist_pond (iblk) if (f_apeff_ai(1:1) /= 'x') & call accum_hist_field(n_apeff_ai, iblk, apeff_ai(:,:,iblk), a2D) + if (f_dpnd_flush (1:1) /= 'x') & + call accum_hist_field(n_dpnd_flush , iblk, dpnd_flush (:,:,iblk), a2D) + if (f_dpnd_expon (1:1) /= 'x') & + call accum_hist_field(n_dpnd_expon , iblk, dpnd_expon (:,:,iblk), a2D) + if (f_dpnd_freebd (1:1) /= 'x') & + call accum_hist_field(n_dpnd_freebd , iblk, dpnd_freebd (:,:,iblk), a2D) + if (f_dpnd_initial (1:1) /= 'x') & + call accum_hist_field(n_dpnd_initial, iblk, dpnd_initial(:,:,iblk), a2D) + if (f_dpnd_dlid (1:1) /= 'x') & + call accum_hist_field(n_dpnd_dlid , iblk, dpnd_dlid (:,:,iblk), a2D) + if (f_dpnd_melt (1:1) /= 'x') & + call accum_hist_field(n_dpnd_melt , iblk, dpnd_melt (:,:,iblk), a2D) + if (f_dpnd_ridge (1:1) /= 'x') & + call accum_hist_field(n_dpnd_ridge , iblk, dpnd_ridge (:,:,iblk), a2D) + endif ! allocated(a2D) ! 3D category fields @@ -399,6 +557,18 @@ subroutine accum_hist_pond (iblk) call accum_hist_field(n_hpondn-n2D, iblk, ncat_hist, & trcrn(:,:,nt_apnd,1:ncat_hist,iblk) & * trcrn(:,:,nt_hpnd,1:ncat_hist,iblk), a3Dc) + + if (f_dpnd_flushn (1:1) /= 'x') & + call accum_hist_field(n_dpnd_flushn-n2D , iblk, ncat_hist, dpnd_flushn (:,:,1:ncat_hist,iblk), a3Dc) + if (f_dpnd_exponn (1:1) /= 'x') & + call accum_hist_field(n_dpnd_exponn-n2D , iblk, ncat_hist, dpnd_exponn (:,:,1:ncat_hist,iblk), a3Dc) + if (f_dpnd_freebdn (1:1) /= 'x') & + call accum_hist_field(n_dpnd_freebdn-n2D , iblk, ncat_hist, dpnd_freebdn (:,:,1:ncat_hist,iblk), a3Dc) + if (f_dpnd_initialn (1:1) /= 'x') & + call accum_hist_field(n_dpnd_initialn-n2D, iblk, ncat_hist, dpnd_initialn(:,:,1:ncat_hist,iblk), a3Dc) + if (f_dpnd_dlidn (1:1) /= 'x') & + call accum_hist_field(n_dpnd_dlidn-n2D , iblk, ncat_hist, dpnd_dlidn (:,:,1:ncat_hist,iblk), a3Dc) + endif ! allocated(a3Dc) end subroutine accum_hist_pond diff --git a/cicecore/cicedyn/analysis/ice_history_shared.F90 b/cicecore/cicedyn/analysis/ice_history_shared.F90 index 97e0e563f..83b8d8eca 100644 --- a/cicecore/cicedyn/analysis/ice_history_shared.F90 +++ b/cicecore/cicedyn/analysis/ice_history_shared.F90 @@ -822,12 +822,22 @@ subroutine construct_filename(ncfile,suffix,ns) write(ncfile,'(a,a,i4.4,a,a)') & history_file(1:lenstr(history_file))//trim(cstream),'.', & iyear,'.',trim(suffix) + elseif (histfreq(ns) == 'g') then + write(ncfile,'(a,a,a,a)') & + history_file(1:lenstr(history_file)),'_grid', & + '.',trim(suffix) endif else ! instantaneous - write(ncfile,'(a,a,i4.4,a,i2.2,a,i2.2,a,i5.5,a,a)') & - history_file(1:lenstr(history_file))//trim(cstream),'_inst.', & - iyear,'-',imonth,'-',iday,'-',msec,'.',trim(suffix) + if (histfreq(ns) == 'g') then + write(ncfile,'(a,a,a,a)') & + history_file(1:lenstr(history_file)),'_grid', & + '.',trim(suffix) + else + write(ncfile,'(a,a,i4.4,a,i2.2,a,i2.2,a,i5.5,a,a)') & + history_file(1:lenstr(history_file))//trim(cstream),'_inst.', & + iyear,'-',imonth,'-',iday,'-',msec,'.',trim(suffix) + endif endif endif diff --git a/cicecore/cicedyn/dynamics/ice_dyn_eap.F90 b/cicecore/cicedyn/dynamics/ice_dyn_eap.F90 index 8249e3068..852a897f6 100644 --- a/cicecore/cicedyn/dynamics/ice_dyn_eap.F90 +++ b/cicecore/cicedyn/dynamics/ice_dyn_eap.F90 @@ -2090,8 +2090,7 @@ subroutine read_restart_eap() use ice_boundary, only: ice_HaloUpdate_stress use ice_constants, only: & field_loc_center, field_type_scalar - use ice_domain, only: nblocks, halo_info - use ice_grid, only: grid_type + use ice_domain, only: nblocks, halo_info, ns_boundary_type use ice_restart, only: read_restart_field ! local variables @@ -2131,7 +2130,8 @@ subroutine read_restart_eap() call read_restart_field(nu_restart_eap,0,a12_4,'ruf8', & 'a12_4',1,diag,field_loc_center,field_type_scalar) ! a12_4 - if (trim(grid_type) == 'tripole') then + if (trim(ns_boundary_type) == 'tripole' .or. & + trim(ns_boundary_type) == 'tripoleT') then call ice_HaloUpdate_stress(a11_1, a11_3, halo_info, & field_loc_center, field_type_scalar) diff --git a/cicecore/cicedyn/dynamics/ice_dyn_evp.F90 b/cicecore/cicedyn/dynamics/ice_dyn_evp.F90 index c858de1c8..39d5a8e20 100644 --- a/cicecore/cicedyn/dynamics/ice_dyn_evp.F90 +++ b/cicecore/cicedyn/dynamics/ice_dyn_evp.F90 @@ -259,7 +259,8 @@ subroutine evp (dt) use ice_boundary, only: ice_halo, ice_HaloMask, ice_HaloUpdate, & ice_HaloDestroy, ice_HaloUpdate_stress use ice_blocks, only: block, get_block, nx_block, ny_block, nghost - use ice_domain, only: nblocks, blocks_ice, halo_info, maskhalo_dyn + use ice_domain, only: nblocks, blocks_ice, halo_info, maskhalo_dyn, & + ns_boundary_type use ice_domain_size, only: max_blocks, ncat use ice_flux, only: rdg_conv, rdg_shear, strairxT, strairyT, & strairxU, strairyU, uocn, vocn, ss_tltx, ss_tlty, fmU, & @@ -280,8 +281,7 @@ subroutine evp (dt) use ice_grid, only: tmask, umask, umaskCD, nmask, emask, uvm, epm, npm, & dxE, dxN, dxT, dxU, dyE, dyN, dyT, dyU, & tarear, uarear, earear, narear, grid_average_X2Y, uarea, & - grid_type, grid_ice, & - grid_atm_dynu, grid_atm_dynv, grid_ocn_dynu, grid_ocn_dynv + grid_ice, grid_atm_dynu, grid_atm_dynv, grid_ocn_dynu, grid_ocn_dynv use ice_state, only: aice, aiU, vice, vsno, uvel, vvel, uvelN, vvelN, & uvelE, vvelE, divu, shear, vort, & aice_init, aice0, aicen, vicen, strength @@ -1313,7 +1313,8 @@ subroutine evp (dt) endif ! Force symmetry across the tripole seam - if (trim(grid_type) == 'tripole') then + if (trim(ns_boundary_type) == 'tripole' .or. & + trim(ns_boundary_type) == 'tripoleT') then ! TODO: C/CD-grid if (maskhalo_dyn) then !------------------------------------------------------- diff --git a/cicecore/cicedyn/dynamics/ice_dyn_shared.F90 b/cicecore/cicedyn/dynamics/ice_dyn_shared.F90 index 84edea237..40f49877d 100644 --- a/cicecore/cicedyn/dynamics/ice_dyn_shared.F90 +++ b/cicecore/cicedyn/dynamics/ice_dyn_shared.F90 @@ -51,6 +51,8 @@ module ice_dyn_shared ! shared_mem_1d = 1d without mpi call and refactorization to 1d real (kind=dbl_kind), public :: & + dyn_area_min,& ! minimum ice area concentration to activate dynamics + dyn_mass_min,& ! minimum ice mass to activate dynamics (kg/m^2) elasticDamp ! coefficient for calculating the parameter E, elastic damping parameter ! other EVP parameters @@ -64,9 +66,7 @@ module ice_dyn_shared real (kind=dbl_kind), parameter, public :: & u0 = 5e-5_dbl_kind, & ! residual velocity for seabed stress (m/s) cosw = c1 , & ! cos(ocean turning angle) ! turning angle = 0 - sinw = c0 , & ! sin(ocean turning angle) ! turning angle = 0 - a_min = p001 , & ! minimum ice area - m_min = p01 ! minimum ice mass (kg/m^2) + sinw = c0 ! sin(ocean turning angle) ! turning angle = 0 real (kind=dbl_kind), public :: & revp , & ! 0 for classic EVP, 1 for revised EVP @@ -240,7 +240,8 @@ subroutine init_dyn_shared (dt) use ice_blocks, only: block, get_block use ice_boundary, only: ice_halo, ice_haloUpdate - use ice_domain, only: nblocks, halo_dynbundle, blocks_ice, halo_info + use ice_domain, only: nblocks, halo_dynbundle, blocks_ice, halo_info, & + ns_boundary_type use ice_domain_size, only: max_blocks use ice_flux, only: & stressp_1, stressp_2, stressp_3, stressp_4, & @@ -268,6 +269,13 @@ subroutine init_dyn_shared (dt) character(len=*), parameter :: subname = '(init_dyn_shared)' + ! checks + if (kdyn == 1 .and. evp_algorithm == 'shared_mem_1d' .and. & + (ns_boundary_type == 'tripole' .or. ns_boundary_type == 'tripoleT')) then + call abort_ice(subname//' ERROR: evp_alg shared mem 1d not supported with tripole', & + file=__FILE__, line=__LINE__) + endif + call set_evp_parameters (dt) ! allocate dyn shared (init_uvel,init_vvel) call alloc_dyn_shared @@ -517,8 +525,8 @@ subroutine dyn_prep1 (nx_block, ny_block, & !----------------------------------------------------------------- ! ice extent mask (T-cells) !----------------------------------------------------------------- - tmphm(i,j) = Tmask(i,j) .and. (aice (i,j) > a_min) & - .and. (Tmass(i,j) > m_min) + tmphm(i,j) = Tmask(i,j) .and. (aice (i,j) > dyn_area_min) & + .and. (Tmass(i,j) > dyn_mass_min) !----------------------------------------------------------------- ! augmented mask (land + open ocean) @@ -721,8 +729,8 @@ subroutine dyn_prep2 (nx_block, ny_block, & do i = ilo, ihi iceXmask_old(i,j) = iceXmask(i,j) ! save ! ice extent mask (U-cells) - iceXmask(i,j) = (Xmask(i,j)) .and. (aiX (i,j) > a_min) & - .and. (Xmass(i,j) > m_min) + iceXmask(i,j) = (Xmask(i,j)) .and. (aiX (i,j) > dyn_area_min) & + .and. (Xmass(i,j) > dyn_mass_min) if (iceXmask(i,j)) then icellX = icellX + 1 diff --git a/cicecore/cicedyn/dynamics/ice_dyn_vp.F90 b/cicecore/cicedyn/dynamics/ice_dyn_vp.F90 index 22a53bc59..23f260d65 100644 --- a/cicecore/cicedyn/dynamics/ice_dyn_vp.F90 +++ b/cicecore/cicedyn/dynamics/ice_dyn_vp.F90 @@ -155,7 +155,8 @@ subroutine implicit_solver (dt) use ice_boundary, only: ice_HaloMask, ice_HaloUpdate, & ice_HaloDestroy, ice_HaloUpdate_stress use ice_blocks, only: block, get_block, nx_block, ny_block - use ice_domain, only: blocks_ice, halo_info, maskhalo_dyn + use ice_domain, only: blocks_ice, halo_info, maskhalo_dyn, & + ns_boundary_type use ice_domain_size, only: max_blocks, ncat use ice_dyn_shared, only: deformations, iceTmask, iceUmask, & cxp, cyp, cxm, cym @@ -168,7 +169,7 @@ subroutine implicit_solver (dt) stressm_1, stressm_2, stressm_3, stressm_4, & stress12_1, stress12_2, stress12_3, stress12_4 use ice_grid, only: tmask, umask, dxT, dyT, dxU, dyU, & - tarear, grid_type, grid_average_X2Y, & + tarear, grid_average_X2Y, & grid_atm_dynu, grid_atm_dynv, grid_ocn_dynu, grid_ocn_dynv use ice_state, only: aice, aiU, vice, vsno, uvel, vvel, divu, shear, vort, & aice_init, aice0, aicen, vicen, strength @@ -546,7 +547,8 @@ subroutine implicit_solver (dt) endif ! Force symmetry across the tripole seam - if (trim(grid_type) == 'tripole') then + if (trim(ns_boundary_type) == 'tripole' .or. & + trim(ns_boundary_type) == 'tripoleT') then if (maskhalo_dyn) then !------------------------------------------------------- ! set halomask to zero because ice_HaloMask always keeps diff --git a/cicecore/cicedyn/dynamics/ice_transport_driver.F90 b/cicecore/cicedyn/dynamics/ice_transport_driver.F90 index 7d19a7974..3c3b7e5ef 100644 --- a/cicecore/cicedyn/dynamics/ice_transport_driver.F90 +++ b/cicecore/cicedyn/dynamics/ice_transport_driver.F90 @@ -1528,7 +1528,7 @@ subroutine state_to_work (nx_block, ny_block, & nt_alvl, nt_apnd, nt_fbri logical (kind=log_kind) :: & - tr_pond_lvl, tr_pond_topo + tr_pond_lvl, tr_pond_topo, tr_pond_sealvl integer (kind=int_kind) :: & i, j, n, it, & ! counting indices @@ -1537,7 +1537,7 @@ subroutine state_to_work (nx_block, ny_block, & character(len=*), parameter :: subname = '(state_to_work)' call icepack_query_tracer_flags(tr_pond_lvl_out=tr_pond_lvl, & - tr_pond_topo_out=tr_pond_topo) + tr_pond_topo_out=tr_pond_topo, tr_pond_sealvl_out=tr_pond_sealvl) call icepack_query_tracer_indices(nt_alvl_out=nt_alvl, nt_apnd_out=nt_apnd, & nt_fbri_out=nt_fbri) call icepack_warnings_flush(nu_diag) @@ -1597,7 +1597,7 @@ subroutine state_to_work (nx_block, ny_block, & enddo enddo elseif (trcr_depend(it) == 2+nt_apnd .and. & - tr_pond_topo) then + (tr_pond_topo .or. tr_pond_sealvl)) then do j = 1, ny_block do i = 1, nx_block works(i,j,narrays+it) = aicen(i,j ,n) & diff --git a/cicecore/cicedyn/dynamics/ice_transport_remap.F90 b/cicecore/cicedyn/dynamics/ice_transport_remap.F90 index 8916c359d..56e26bf6b 100644 --- a/cicecore/cicedyn/dynamics/ice_transport_remap.F90 +++ b/cicecore/cicedyn/dynamics/ice_transport_remap.F90 @@ -13,6 +13,12 @@ ! transport using incremental remapping, Mon. Wea. Rev., 132, ! 1341-1354. ! +! Lemieux, J.-F., Lipscomb, W. H., Craig, A., Bailey, D. A., +! Hunke, E. C., Blain, P., Rasmussen, T. A. S., Bentsen, M., +! Dupont, F., Hebert, D., and Allard, R., 2024: CICE on a +! C-grid: new momentum, stress, and transport schemes for CICEv6.5, +! Geosci. Model Dev., 17, 6703-6724. +! ! authors William H. Lipscomb, LANL ! John Baumgardner, LANL ! @@ -26,6 +32,7 @@ ! 2010: ECH removed unnecessary grid arrays and optional arguments from ! horizontal_remap ! 2023: TAR, DMI Remove commented code and unnecessary arrays +! 2024: JFL and WHL improved robustness of Bentsen's approach for area flux. module ice_transport_remap @@ -60,9 +67,9 @@ module ice_transport_remap p52083 = 25._dbl_kind/48._dbl_kind logical :: & - l_fixed_area ! if true, prescribe area flux across each edge - ! if false, area flux is determined internally - ! and is passed out + l_edge_flux_adj ! if true, prescribe area flux across each edge + ! if false, area flux is determined internally + ! and is passed out logical (kind=log_kind), parameter :: bugcheck = .false. @@ -239,12 +246,13 @@ module ice_transport_remap ! field implied by the remapping was, in general, different from the ! value of del*u computed in the dynamics. For energetic consistency ! (in CICE as well as in layered ocean models such as HYPOP), -! these two values should agree. This can be ensured by setting -! l_fixed_area = T and specifying the area transported across each grid -! cell edge in the arrays edgearea_e and edgearea_n. The departure -! regions are then tweaked, following an idea by Mats Bentsen, such -! that they have the desired area. If l_fixed_area = F, these regions -! are not tweaked, and the edgearea arrays are output variables. +! these two values should agree. This can be ensured by using the +! edge flux adjustment (EFA) method by setting l_edge_flux_adj = T. +! The EFA method specifies the area transported across each grid cell +! edge in the arrays edgearea_e and edgearea_n. The departure regions +! are then tweaked, following an idea by Mats Bentsen, such that they +! have the desired area. If l_edge_flux_adj = F, these regions are +! not tweaked, and the edgearea arrays are output variables. ! !======================================================================= @@ -264,26 +272,26 @@ subroutine init_remap character(len=*), parameter :: subname = '(init_remap)' !------------------------------------------------------------------- - ! Set logical l_fixed_area depending of the grid type. + ! Set logical l_edge_flux_adj depending of the grid type. ! - ! If l_fixed_area is true, the area of each departure region is - ! computed in advance (e.g., by taking the divergence of the - ! velocity field and passed to locate_triangles. The departure - ! regions are adjusted to obtain the desired area. + ! If l_edge_flux_adj is true, the area of each departure region is + ! computed in advance (e.g., by taking the divergence of the + ! velocity field and passed to locate_triangles. The departure + ! regions are adjusted to obtain the desired area. ! If false, edgearea is computed in locate_triangles and passed out. ! - ! l_fixed_area = .false. has been the default approach in CICE. It is - ! used like this for the B-grid. However, idealized tests with the - ! C-grid have shown that l_fixed_area = .false. leads to a checkerboard - ! pattern in prognostic fields (e.g. aice). Using l_fixed_area = .true. - ! eliminates the checkerboard pattern in C-grid simulations. - ! + ! l_edge_flux_adj = .false. has been the default approach in CICE. + ! It is used like this for the B-grid. However, idealized tests with + ! the C-grid have shown that l_edge_flux_adj = .false. leads to a + ! checkerboard pattern in prognostic fields such as aice Using + ! l_edge_flux_adj = .true. eliminates the checkerboard pattern in + ! C-grid simulations (Lemieux et al. 2024). !------------------------------------------------------------------- if (grid_ice == 'CD' .or. grid_ice == 'C') then - l_fixed_area = .true. + l_edge_flux_adj = .true. else - l_fixed_area = .false. + l_edge_flux_adj = .false. endif end subroutine init_remap @@ -618,8 +626,8 @@ subroutine horizontal_remap (dt, ntrace, & jhi = this_block%jhi !------------------------------------------------------------------- - ! If l_fixed_area is true, compute edgearea by taking the divergence - ! of the velocity field. Otherwise, initialize edgearea. + ! If l_edge_flux_adj is true, compute edgearea by taking the + ! divergence of the velocity field. Otherwise, initialize edgearea. !------------------------------------------------------------------- do j = 1, ny_block @@ -629,10 +637,10 @@ subroutine horizontal_remap (dt, ntrace, & enddo enddo - if (l_fixed_area) then + if (l_edge_flux_adj) then if (grid_ice == 'CD' .or. grid_ice == 'C') then ! velocities are already on the center if (.not.present(uvelE).or..not.present(vvelN)) then - call abort_ice (subname//'ERROR: uvelE,vvelN required with C|CD and l_fixed_area') + call abort_ice (subname//'ERROR: uvelE,vvelN required with C|CD and l_edge_flux_adj') endif do j = jlo, jhi @@ -1715,7 +1723,7 @@ subroutine locate_triangles (nx_block, ny_block, & xicl, yicl , & ! left-hand x-axis intersection point xicr, yicr , & ! right-hand x-axis intersection point xdm, ydm , & ! midpoint of segment connecting DL and DR; - ! shifted if l_fixed_area = T + ! shifted if l_edge_flux_adj = T md , & ! slope of line connecting DL and DR mdl , & ! slope of line connecting DL and DM mdr , & ! slope of line connecting DR and DM @@ -2040,9 +2048,8 @@ subroutine locate_triangles (nx_block, ny_block, & ! areafact_c or areafac_ce (areafact_c for the other edge) are used ! (with shifted indices) to make sure that a flux area on one edge ! is consistent with the analogous area on the other edge and to - ! ensure that areas add up when using l_fixed_area = T. See PR #849 - ! for details. - ! + ! ensure that areas add up when using l_edge_flux_adj = T. + ! See PR #849 for details. !------------------------------------------------------------------- if (yil > c0 .and. xdl < xcl .and. ydl >= c0) then @@ -2241,11 +2248,11 @@ subroutine locate_triangles (nx_block, ny_block, & endif !------------------------------------------------------------------- - ! For l_fixed_area = T, shift the midpoint so that the departure + ! For l_edge_flux_adj = T, shift the midpoint so that the departure ! region has the prescribed area !------------------------------------------------------------------- - if (l_fixed_area) then + if (l_edge_flux_adj) then ! Sum the areas of the left and right triangles. ! Note that yp(i,j,1,ng) = 0 for all triangles, so we can @@ -2375,7 +2382,7 @@ subroutine locate_triangles (nx_block, ny_block, & endif ! ydl*ydr >= c0 - endif ! l_fixed_area + endif ! l_edge_flux_adj !------------------------------------------------------------------- ! Locate triangles in BC cell (H for both north and east edges) @@ -2907,8 +2914,8 @@ subroutine locate_triangles (nx_block, ny_block, & ! The fluxes work out correctly in the end. ! ! Also compute the cumulative area transported across each edge. - ! If l_fixed_area = T, this area is compared to edgearea as a bug check. - ! If l_fixed_area = F, this area is passed as an output array. + ! If l_edge_flux_adj = T, this area is compared to edgearea as a bug check. + ! If l_edge_flux_adj = F, this area is passed as an output array. !------------------------------------------------------------------- areasum(:,:) = c0 @@ -2940,7 +2947,7 @@ subroutine locate_triangles (nx_block, ny_block, & enddo ! ij enddo ! ng - if (l_fixed_area) then + if (l_edge_flux_adj) then if (bugcheck) then ! set bugcheck = F to speed up code do ij = 1, icellsd i = indxid(ij) @@ -2963,13 +2970,13 @@ subroutine locate_triangles (nx_block, ny_block, & enddo endif ! bugcheck - else ! l_fixed_area = F + else ! l_edge_flux_adj = F do ij = 1, icellsd i = indxid(ij) j = indxjd(ij) edgearea(i,j) = areasum(i,j) enddo - endif ! l_fixed_area + endif ! l_edge_flux_adj !------------------------------------------------------------------- ! Transform triangle vertices to a scaled coordinate system centered diff --git a/cicecore/cicedyn/general/ice_flux.F90 b/cicecore/cicedyn/general/ice_flux.F90 index 6378db6eb..ff71a4a4d 100644 --- a/cicecore/cicedyn/general/ice_flux.F90 +++ b/cicecore/cicedyn/general/ice_flux.F90 @@ -114,8 +114,7 @@ module ice_flux dvirdgdt, & ! rate of ice volume ridged (m/s) opening ! rate of opening due to divergence/shear (1/s) - real (kind=dbl_kind), & - dimension (:,:,:,:), allocatable, public :: & + real (kind=dbl_kind), dimension (:,:,:,:), allocatable, public :: & ! ridging diagnostics in categories dardg1ndt, & ! rate of area loss by ridging ice (1/s) dardg2ndt, & ! rate of area gain by new ridges (1/s) @@ -177,13 +176,26 @@ module ice_flux ! NOTE: when in CICE_IN_NEMO mode, these are gridbox mean fields, ! not per ice area. When in standalone mode, these are per ice area. - real (kind=dbl_kind), & - dimension (:,:,:,:), allocatable, public :: & + real (kind=dbl_kind), dimension (:,:,:,:), allocatable, public :: & fsurfn_f , & ! net flux to top surface, excluding fcondtop fcondtopn_f, & ! downward cond flux at top surface (W m-2) fsensn_f , & ! sensible heat flux (W m-2) flatn_f ! latent heat flux (W m-2) + ! in from atmosphere + ! required for coupling in GEOS + + real (kind=dbl_kind), dimension (:,:,:,:), allocatable, public :: & + evapn_f, & ! evaporation/sublimation (kg m-2 s-1) + dflatndTsfc_f, & ! derivative of latent flux w.r.t. Tsfc + dfsurfndTsfc_f ! derivative of surface flux w.r.t. Tsfc + + real (kind=dbl_kind), dimension (:,:,:), allocatable, public :: & + swuvrdr , & ! vis uvr flux, direct (W m-2) + swuvrdf , & ! vis uvr flux, diffuse (W m-2) + swpardr , & ! vis par flux, direct (W m-2) + swpardf ! vis par flux, diffuse (W m-2) + ! in from atmosphere real (kind=dbl_kind), dimension (:,:,:), allocatable, public :: & @@ -258,7 +270,11 @@ module ice_flux fswthru_vdr , & ! vis dir shortwave penetrating to ocean (W/m^2) fswthru_vdf , & ! vis dif shortwave penetrating to ocean (W/m^2) fswthru_idr , & ! nir dir shortwave penetrating to ocean (W/m^2) - fswthru_idf ! nir dif shortwave penetrating to ocean (W/m^2) + fswthru_idf , & ! nir dif shortwave penetrating to ocean (W/m^2) + fswthru_uvrdr,& ! vis dir uvr SW penetrating to ocean (W/m^2) + fswthru_uvrdf,& ! vis dif uvr SW penetrating to ocean (W/m^2) + fswthru_pardr,& ! nir dir par SW penetrating to ocean (W/m^2) + fswthru_pardf ! nir dif par SW penetrating to ocean (W/m^2) ! internal @@ -326,16 +342,30 @@ module ice_flux frz_onset, &! day of year that freezing begins (congel or frazil) frazil_diag ! frazil ice growth diagnostic (m/step-->cm/day) - real (kind=dbl_kind), & - dimension (:,:,:,:), allocatable, public :: & + real (kind=dbl_kind), dimension (:,:,:), allocatable, public :: & + dpnd_flush, & ! pond flushing rate due to ice permeability (m/step) + dpnd_expon, & ! exponential pond drainage rate (m/step) + dpnd_freebd, & ! pond drainage rate due to freeboard constraint (m/step) + dpnd_initial,& ! runoff rate due to rfrac (m/step) + dpnd_dlid, & ! pond loss/gain (+/-) to ice lid freezing/melting (m/step) + dpnd_melt, & ! pond 'drainage' due to ice melting (m / step) + dpnd_ridge ! pond 'drainage' due to ridging (m) + + real (kind=dbl_kind), dimension (:,:,:,:), allocatable, public :: & + dpnd_flushn, & ! category pond flushing rate due to ice permeability (m/step) + dpnd_exponn, & ! category exponential pond drainage rate (m/step) + dpnd_freebdn,& ! category pond drainage rate due to freeboard constraint (m/step) + dpnd_initialn,&! category runoff rate due to rfrac (m/step) + dpnd_dlidn ! category pond loss/gain (+/-) to ice lid freezing/melting (m/step) + + real (kind=dbl_kind), dimension (:,:,:,:), allocatable, public :: & fsurfn, & ! category fsurf fcondtopn,& ! category fcondtop fcondbotn,& ! category fcondbot fsensn, & ! category sensible heat flux flatn ! category latent heat flux - real (kind=dbl_kind), & - dimension (:,:,:,:), allocatable, public :: & + real (kind=dbl_kind), dimension (:,:,:,:), allocatable, public :: & snwcnt ! counter for presence of snow ! As above but these remain grid box mean values i.e. they are not @@ -453,6 +483,10 @@ subroutine alloc_flux swvdf (nx_block,ny_block,max_blocks), & ! sw down, visible, diffuse (W/m^2) swidr (nx_block,ny_block,max_blocks), & ! sw down, near IR, direct (W/m^2) swidf (nx_block,ny_block,max_blocks), & ! sw down, near IR, diffuse (W/m^2) + swuvrdr (nx_block,ny_block,max_blocks), & ! vis uvr flux, direct (W m-2) + swuvrdf (nx_block,ny_block,max_blocks), & ! vis uvr flux, diffuse (W m-2) + swpardr (nx_block,ny_block,max_blocks), & ! vis par flux, direct (W m-2) + swpardf (nx_block,ny_block,max_blocks), & ! vis par flux, diffuse (W m-2) flw (nx_block,ny_block,max_blocks), & ! incoming longwave radiation (W/m^2) frain (nx_block,ny_block,max_blocks), & ! rainfall rate (kg/m^2 s) fsnow (nx_block,ny_block,max_blocks), & ! snowfall rate (kg/m^2 s) @@ -499,11 +533,15 @@ subroutine alloc_flux fhocn (nx_block,ny_block,max_blocks), & ! net heat flux to ocean (W/m^2) fsloss (nx_block,ny_block,max_blocks), & ! rate of snow loss to leads (kg/m^2/s) fswthru (nx_block,ny_block,max_blocks), & ! shortwave penetrating to ocean (W/m^2) - fswthru_vdr (nx_block,ny_block,max_blocks), & ! vis dir shortwave penetrating to ocean (W/m^2) - fswthru_vdf (nx_block,ny_block,max_blocks), & ! vis dif shortwave penetrating to ocean (W/m^2) - fswthru_idr (nx_block,ny_block,max_blocks), & ! nir dir shortwave penetrating to ocean (W/m^2) - fswthru_idf (nx_block,ny_block,max_blocks), & ! nir dif shortwave penetrating to ocean (W/m^2) - scale_factor (nx_block,ny_block,max_blocks), & ! scaling factor for shortwave components + fswthru_vdr(nx_block,ny_block,max_blocks), & ! vis dir shortwave penetrating to ocean (W/m^2) + fswthru_vdf(nx_block,ny_block,max_blocks), & ! vis dif shortwave penetrating to ocean (W/m^2) + fswthru_idr(nx_block,ny_block,max_blocks), & ! nir dir shortwave penetrating to ocean (W/m^2) + fswthru_idf(nx_block,ny_block,max_blocks), & ! nir dif shortwave penetrating to ocean (W/m^2) + fswthru_uvrdr (nx_block,ny_block,max_blocks), & ! vis dir uvr SW penetrating to ocean (W/m^2) + fswthru_uvrdf (nx_block,ny_block,max_blocks), & ! vis dir uvr SW penetrating to ocean (W/m^2) + fswthru_pardr (nx_block,ny_block,max_blocks), & ! vis dir par SW penetrating to ocean (W/m^2) + fswthru_pardf (nx_block,ny_block,max_blocks), & ! vis dir par SW penetrating to ocean (W/m^2) + scale_factor (nx_block,ny_block,max_blocks), & ! scaling factor for shortwave components strairx_ocn(nx_block,ny_block,max_blocks), & ! stress on ocean by air, x-direction strairy_ocn(nx_block,ny_block,max_blocks), & ! stress on ocean by air, y-direction fsens_ocn (nx_block,ny_block,max_blocks), & ! sensible heat flux (W/m^2) @@ -566,6 +604,9 @@ subroutine alloc_flux fcondtopn_f(nx_block,ny_block,ncat,max_blocks), & ! downward cond flux at top surface (W m-2) fsensn_f (nx_block,ny_block,ncat,max_blocks), & ! sensible heat flux (W m-2) flatn_f (nx_block,ny_block,ncat,max_blocks), & ! latent heat flux (W m-2) + evapn_f (nx_block,ny_block,ncat,max_blocks), & ! evaporative water flux (kg/m^2/s) by atmosphere model + dflatndTsfc_f (nx_block,ny_block,ncat,max_blocks), & ! derivative of flatn with respect to Tsfc + dfsurfndTsfc_f(nx_block,ny_block,ncat,max_blocks), & ! derivative of fsurfn with respect to Tsfc meltsn (nx_block,ny_block,ncat,max_blocks), & ! snow melt in category n (m) melttn (nx_block,ny_block,ncat,max_blocks), & ! top melt in category n (m) meltbn (nx_block,ny_block,ncat,max_blocks), & ! bottom melt in category n (m) @@ -617,7 +658,24 @@ subroutine alloc_flux stressmU (nx_block,ny_block,max_blocks), & ! sigma11-sigma22 stress12U (nx_block,ny_block,max_blocks), & ! sigma12 stat=ierr) - if (ierr/=0) call abort_ice('(alloc_flux): Out of memory') + if (ierr/=0) call abort_ice('(alloc_flux): Out of memory (C or CD grid)') + + ! Pond diagnostics + allocate( & + dpnd_flush (nx_block,ny_block,max_blocks), & ! pond flushing rate due to ice permeability (m/step) + dpnd_expon (nx_block,ny_block,max_blocks), & ! exponential pond drainage rate (m/step) + dpnd_freebd (nx_block,ny_block,max_blocks), & ! pond drainage rate due to freeboard constraint (m/step) + dpnd_initial (nx_block,ny_block,max_blocks), & ! runoff rate due to rfrac (m/step) + dpnd_dlid (nx_block,ny_block,max_blocks), & ! pond loss/gain (+/-) to ice lid freezing/melting (m/step) + dpnd_melt (nx_block,ny_block,max_blocks), & ! pond 'drainage' due to ice melting (m / step) + dpnd_ridge (nx_block,ny_block,max_blocks), & ! pond 'drainage' due to ridging (m) + dpnd_flushn (nx_block,ny_block,ncat,max_blocks), & ! category pond flushing rate due to ice permeability (m/step) + dpnd_exponn (nx_block,ny_block,ncat,max_blocks), & ! category exponential pond drainage rate (m/step) + dpnd_freebdn (nx_block,ny_block,ncat,max_blocks), & ! category pond drainage rate due to freeboard constraint (m/step) + dpnd_initialn(nx_block,ny_block,ncat,max_blocks), & ! category runoff rate due to rfrac (m/step) + dpnd_dlidn (nx_block,ny_block,ncat,max_blocks), & ! category pond loss/gain (+/-) to ice lid freezing/melting (m/step) + stat=ierr) + if (ierr/=0) call abort_ice('(alloc_flux): Out of memory (ponds)') end subroutine alloc_flux @@ -723,6 +781,11 @@ subroutine init_coupler_flux fsensn_f (:,:,:,:) = c0 ! sensible heat flux (W/m^2) endif ! + swuvrdr(:,:,:) = c0 ! visible uvr flux, direct (W/m^2) + swuvrdf(:,:,:) = c0 ! visible uvr flux, diffuse (W/m^2) + swpardr(:,:,:) = c0 ! visible par flux, direct (W/m^2) + swpardf(:,:,:) = c0 ! visible par flux, diffuse (W/m^2) + fiso_atm (:,:,:,:) = c0 ! isotope deposition rate (kg/m2/s) faero_atm (:,:,:,:) = c0 ! aerosol deposition rate (kg/m2/s) flux_bio_atm (:,:,:,:) = c0 ! zaero and bio deposition rate (kg/m2/s) @@ -792,6 +855,10 @@ subroutine init_coupler_flux fswthru_vdf (:,:,:) = c0 fswthru_idr (:,:,:) = c0 fswthru_idf (:,:,:) = c0 + fswthru_uvrdr (:,:,:) = c0 + fswthru_uvrdf (:,:,:) = c0 + fswthru_pardr (:,:,:) = c0 + fswthru_pardf (:,:,:) = c0 fresh_da(:,:,:) = c0 ! data assimilation fsalt_da(:,:,:) = c0 flux_bio (:,:,:,:) = c0 ! bgc @@ -853,6 +920,8 @@ subroutine init_flux_atm ! strairxT(:,:,:) = 0.15_dbl_kind ! strairyT(:,:,:) = 0.15_dbl_kind + fsurf (:,:,:) = c0 + fcondtop(:,:,:) = c0 fsens (:,:,:) = c0 flat (:,:,:) = c0 fswabs (:,:,:) = c0 @@ -898,6 +967,10 @@ subroutine init_flux_ocn fswthru_vdf (:,:,:) = c0 fswthru_idr (:,:,:) = c0 fswthru_idf (:,:,:) = c0 + fswthru_uvrdr(:,:,:) = c0 + fswthru_uvrdf(:,:,:) = c0 + fswthru_pardr(:,:,:) = c0 + fswthru_pardf(:,:,:) = c0 faero_ocn (:,:,:,:) = c0 fiso_ocn (:,:,:,:) = c0 @@ -929,6 +1002,7 @@ subroutine init_history_therm logical (kind=log_kind) :: & formdrag, & + tr_pond, & tr_iage integer (kind=int_kind) :: & @@ -944,6 +1018,7 @@ subroutine init_history_therm call icepack_query_parameters(formdrag_out=formdrag) call icepack_query_tracer_flags(tr_iage_out=tr_iage) + call icepack_query_tracer_flags(tr_pond_out=tr_pond) call icepack_query_tracer_indices(nt_iage_out=nt_iage) call icepack_query_parameters( dragio_out=dragio, & vonkar_out=vonkar, zref_out=zref, iceruf_out=iceruf) @@ -989,6 +1064,20 @@ subroutine init_history_therm snowfrac (:,:,:) = c0 frazil_diag (:,:,:) = c0 + ! Extra pond diagnostics + dpnd_flush(:,:,:) = c0 + dpnd_expon(:,:,:) = c0 + dpnd_freebd(:,:,:) = c0 + dpnd_initial(:,:,:) = c0 + dpnd_dlid(:,:,:) = c0 + dpnd_melt(:,:,:) = c0 + dpnd_ridge(:,:,:) = c0 + dpnd_flushn(:,:,:,:) = c0 + dpnd_exponn(:,:,:,:) = c0 + dpnd_freebdn(:,:,:,:) = c0 + dpnd_initialn(:,:,:,:) = c0 + dpnd_dlidn(:,:,:,:) = c0 + ! drag coefficients are computed prior to the atmo_boundary call, ! during the thermodynamics section Cdn_ocn(:,:,:) = dragio @@ -1232,7 +1321,7 @@ subroutine scale_fluxes (nx_block, ny_block, & flat (i,j) = flat (i,j) * ar fswabs (i,j) = fswabs (i,j) * ar ! Special case where aice_init was zero and aice > 0. - if (flwout(i,j) > -puny) & + if (flwout(i,j) > -puny) & flwout (i,j) = -stefan_boltzmann *(Tf(i,j) + Tffresh)**4 flwout (i,j) = flwout (i,j) * ar evap (i,j) = evap (i,j) * ar diff --git a/cicecore/cicedyn/general/ice_forcing.F90 b/cicecore/cicedyn/general/ice_forcing.F90 index af589c795..e0f1b736a 100755 --- a/cicecore/cicedyn/general/ice_forcing.F90 +++ b/cicecore/cicedyn/general/ice_forcing.F90 @@ -5202,7 +5202,6 @@ subroutine box2001_data_ocn use ice_domain, only: nblocks, blocks_ice use ice_blocks, only: block, get_block, nx_block, ny_block, nghost use ice_flux, only: uocn, vocn - use ice_grid, only: uvm ! local parameters @@ -5235,9 +5234,6 @@ subroutine box2001_data_ocn vocn(i,j,iblk) = -p2*real(iglob(i), kind=dbl_kind) & / real(nx_global,kind=dbl_kind) + p1 - uocn(i,j,iblk) = uocn(i,j,iblk) * uvm(i,j,iblk) - vocn(i,j,iblk) = vocn(i,j,iblk) * uvm(i,j,iblk) - enddo enddo enddo ! nblocks diff --git a/cicecore/cicedyn/general/ice_init.F90 b/cicecore/cicedyn/general/ice_init.F90 index 91293db42..92580a512 100644 --- a/cicecore/cicedyn/general/ice_init.F90 +++ b/cicecore/cicedyn/general/ice_init.F90 @@ -14,8 +14,8 @@ module ice_init use ice_kinds_mod use ice_communicate, only: my_task, master_task, ice_barrier - use ice_constants, only: c0, c1, c2, c3, c5, c12, p01, p2, p3, p5, p75, p166, & - cm_to_m + use ice_constants, only: c0, c1, c2, c3, c5, c10, c12, & + p001, p01, p2, p3, p5, p75, p166, cm_to_m use ice_exit, only: abort_ice use ice_fileunits, only: nu_nml, nu_diag, nml_filename, diag_type, & ice_stdout, get_fileunit, release_fileunit, bfbflag, flush_fileunit, & @@ -26,7 +26,7 @@ module ice_init use icepack_intfc, only: icepack_warnings_flush, icepack_warnings_aborted use icepack_intfc, only: icepack_aggregate use icepack_intfc, only: icepack_init_trcr - use icepack_intfc, only: icepack_init_parameters + use icepack_intfc, only: icepack_init_parameters, icepack_write_parameters use icepack_intfc, only: icepack_init_tracer_flags use icepack_intfc, only: icepack_init_tracer_sizes use icepack_intfc, only: icepack_query_tracer_flags @@ -78,8 +78,8 @@ subroutine input_data use ice_arrays_column, only: oceanmixed_ice use ice_restart_column, only: & restart_age, restart_FY, restart_lvl, & - restart_pond_lvl, restart_pond_topo, restart_aero, & - restart_fsd, restart_iso, restart_snow + restart_pond_lvl, restart_pond_topo, restart_pond_sealvl, & + restart_aero, restart_fsd, restart_iso, restart_snow use ice_restart_shared, only: & restart, restart_ext, restart_coszen, use_restart_time, & runtype, restart_file, restart_dir, runid, pointer_file, & @@ -109,7 +109,7 @@ subroutine input_data grid_file, gridcpl_file, kmt_file, & bathymetry_file, use_bathymetry, & bathymetry_format, kmt_type, & - grid_type, grid_format, & + grid_type, grid_format, grid_outfile, & grid_ice, grid_ice_thrm, grid_ice_dynu, grid_ice_dynv, & grid_ocn, grid_ocn_thrm, grid_ocn_dynu, grid_ocn_dynv, & grid_atm, grid_atm_thrm, grid_atm_dynu, grid_atm_dynv, & @@ -123,7 +123,7 @@ subroutine input_data e_yieldcurve, e_plasticpot, coriolis, & ssh_stress, kridge, brlx, arlx, & deltaminEVP, deltaminVP, capping, & - elasticDamp + elasticDamp, dyn_area_min, dyn_mass_min use ice_dyn_vp, only: & maxits_nonlin, precond, dim_fgmres, dim_pgmres, maxits_fgmres, & maxits_pgmres, monitor_nonlin, monitor_fgmres, & @@ -152,12 +152,12 @@ subroutine input_data real (kind=dbl_kind) :: ustar_min, albicev, albicei, albsnowv, albsnowi, & ahmax, R_ice, R_pnd, R_snw, dT_mlt, rsnw_mlt, emissivity, hi_min, & - mu_rdg, hs0, dpscale, rfracmin, rfracmax, pndaspect, hs1, hp1, & + mu_rdg, hs0, dpscale, rfracmin, rfracmax, pndaspect, apnd_sl, hs1, hp1, & a_rapid_mode, Rac_rapid_mode, aspect_rapid_mode, dSdt_slow_mode, & phi_c_slow_mode, phi_i_mushy, kalg, atmiter_conv, Pstar, Cstar, & sw_frac, sw_dtemp, floediam, hfrazilmin, iceruf, iceruf_ocn, & rsnw_fall, rsnw_tmax, rhosnew, rhosmin, rhosmax, Tliquidus_max, & - windmin, drhosdwind, snwlvlfac + windmin, drhosdwind, snwlvlfac, tscale_pnd_drain integer (kind=int_kind) :: ktherm, kstrength, krdg_partic, krdg_redist, natmiter, & kitd, kcatbound, ktransport @@ -167,16 +167,16 @@ subroutine input_data congel_freeze, capping_method, snw_ssp_table logical (kind=log_kind) :: calc_Tsfc, formdrag, highfreq, calc_strair, wave_spec, & - sw_redist, calc_dragio, use_smliq_pnd, snwgrain + sw_redist, calc_dragio, use_smliq_pnd, snwgrain, semi_implicit_Tsfc, vapor_flux_correction logical (kind=log_kind) :: tr_iage, tr_FY, tr_lvl, tr_pond logical (kind=log_kind) :: tr_iso, tr_aero, tr_fsd, tr_snow - logical (kind=log_kind) :: tr_pond_lvl, tr_pond_topo + logical (kind=log_kind) :: tr_pond_lvl, tr_pond_topo, tr_pond_sealvl integer (kind=int_kind) :: numin, numax ! unit number limits logical (kind=log_kind) :: lcdf64 ! deprecated, backwards compatibility logical (kind=log_kind) :: orca_halogrid !deprecated - integer (kind=int_kind) :: rplvl, rptopo + integer (kind=int_kind) :: rplvl, rptopo, rpsealvl real (kind=dbl_kind) :: Cf, ksno, puny, ice_ref_salinity, Tocnfrz character (len=char_len) :: abort_list @@ -217,7 +217,7 @@ subroutine input_data ncat, nilyr, nslyr, nblyr, & kcatbound, gridcpl_file, dxrect, dyrect, & dxscale, dyscale, lonrefrect, latrefrect, & - scale_dxdy, & + scale_dxdy, grid_outfile, & close_boundaries, orca_halogrid, grid_ice, kmt_type, & grid_atm, grid_ocn @@ -226,6 +226,7 @@ subroutine input_data tr_FY, restart_FY, & tr_lvl, restart_lvl, & tr_pond_lvl, restart_pond_lvl, & + tr_pond_sealvl, restart_pond_sealvl, & tr_pond_topo, restart_pond_topo, & tr_snow, restart_snow, & tr_iso, restart_iso, & @@ -238,7 +239,9 @@ subroutine input_data kitd, ktherm, conduct, ksno, & a_rapid_mode, Rac_rapid_mode, aspect_rapid_mode, & dSdt_slow_mode, phi_c_slow_mode, phi_i_mushy, & - floediam, hfrazilmin, Tliquidus_max, hi_min + floediam, hfrazilmin, Tliquidus_max, hi_min, & + tscale_pnd_drain + namelist /dynamics_nml/ & kdyn, ndte, revised_evp, yield_curve, & @@ -246,7 +249,7 @@ subroutine input_data brlx, arlx, ssh_stress, & advection, coriolis, kridge, ktransport, & kstrength, krdg_partic, krdg_redist, mu_rdg, & - e_yieldcurve, e_plasticpot, visc_method, & + e_yieldcurve, e_plasticpot, visc_method, & maxits_nonlin, precond, dim_fgmres, & dim_pgmres, maxits_fgmres, maxits_pgmres, monitor_nonlin, & monitor_fgmres, monitor_pgmres, reltol_nonlin, reltol_fgmres, & @@ -255,7 +258,8 @@ subroutine input_data ortho_type, seabed_stress, seabed_stress_method, & k1, k2, alphab, threshold_hw, & deltaminEVP, deltaminVP, capping_method, & - Cf, Pstar, Cstar, Ktens + Cf, Pstar, Cstar, Ktens, & + dyn_area_min, dyn_mass_min namelist /shortwave_nml/ & shortwave, albedo_type, snw_ssp_table, & @@ -267,7 +271,7 @@ subroutine input_data namelist /ponds_nml/ & hs0, dpscale, frzpnd, & rfracmin, rfracmax, pndaspect, hs1, & - hp1 + hp1, apnd_sl namelist /snow_nml/ & snwredist, snwgrain, rsnw_fall, rsnw_tmax, & @@ -289,7 +293,8 @@ subroutine input_data fyear_init, ycycle, wave_spec_file,restart_coszen, & atm_data_dir, ocn_data_dir, bgc_data_dir, & atm_data_format, ocn_data_format, rotate_wind, & - oceanmixed_file, atm_data_version + oceanmixed_file, atm_data_version,semi_implicit_Tsfc, & + vapor_flux_correction !----------------------------------------------------------------- ! default values @@ -332,6 +337,7 @@ subroutine input_data bfbflag = 'off' ! off = optimized diag_type = 'stdout' diag_file = 'ice_diag.d' + histfreq(:) = 'x' histfreq(1) = '1' ! output frequency option for different streams histfreq(2) = 'h' ! output frequency option for different streams histfreq(3) = 'd' ! output frequency option for different streams @@ -376,13 +382,15 @@ subroutine input_data restart_chunksize(:) = 0 ! chunksize for netcdf4 lcdf64 = .false. ! 64 bit offset for netCDF ice_ic = 'default' ! latitude and sst-dependent - grid_format = 'bin' ! file format ('bin'=binary or 'nc'=netcdf) + grid_format = 'bin' ! grid format + ! ('bin'=binary or 'pop_nc'=pop netcdf or 'mom_nc'=mom netcdf) grid_type = 'rectangular'! define rectangular grid internally grid_file = 'unknown_grid_file' grid_ice = 'B' ! underlying grid system grid_atm = 'A' ! underlying atm forcing/coupling grid grid_ocn = 'A' ! underlying atm forcing/coupling grid gridcpl_file = 'unknown_gridcpl_file' + grid_outfile = .false. ! write out one-time grid history file orca_halogrid = .false. ! orca haloed grid - deprecated bathymetry_file = 'unknown_bathymetry_file' bathymetry_format = 'default' @@ -411,6 +419,8 @@ subroutine input_data kstrength = 1 ! 1 = Rothrock 75 strength, 0 = Hibler 79 Pstar = 2.75e4_dbl_kind ! constant in Hibler strength formula (kstrength = 0) Cstar = 20._dbl_kind ! constant in Hibler strength formula (kstrength = 0) + dyn_area_min = p001 ! minimum ice area concentration to activate dynamics + dyn_mass_min = p01 ! minimum ice mass to activate dynamics (kg/m^2) krdg_partic = 1 ! 1 = new participation, 0 = Thorndike et al 75 krdg_redist = 1 ! 1 = new redistribution, 0 = Hibler 80 mu_rdg = 3 ! e-folding scale of ridged ice, krdg_partic=1 (m^0.5) @@ -471,6 +481,8 @@ subroutine input_data kridge = 1 ! -1 = off, 1 = on ktransport = 1 ! -1 = off, 1 = on calc_Tsfc = .true. ! calculate surface temperature + semi_implicit_Tsfc = .false. ! surface temperature coupling option based on d(hf)/dTs + vapor_flux_correction = .false. ! mass/enthalpy correction for evaporation/sublimation update_ocn_f = .false. ! include fresh water and salt fluxes for frazil cpl_frazil = 'fresh_ice_correction' ! type of coupling for frazil ice ustar_min = 0.005 ! minimum friction velocity for ocean heat flux (m/s) @@ -490,6 +502,7 @@ subroutine input_data rsnw_mlt = 1500._dbl_kind ! maximum melting snow grain radius kalg = 0.60_dbl_kind ! algae absorption coefficient for 0.5 m thick layer ! 0.5 m path of 75 mg Chl a / m2 + apnd_sl = 0.27_dbl_kind ! equilibrium pond fraction in sealvl ponds hp1 = 0.01_dbl_kind ! critical pond lid thickness for topo ponds hs0 = 0.03_dbl_kind ! snow depth for transition to bare sea ice (m) hs1 = 0.03_dbl_kind ! snow depth for transition to bare pond ice (m) @@ -498,6 +511,7 @@ subroutine input_data rfracmin = 0.15_dbl_kind ! minimum retained fraction of meltwater rfracmax = 0.85_dbl_kind ! maximum retained fraction of meltwater pndaspect = 0.8_dbl_kind ! ratio of pond depth to area fraction + tscale_pnd_drain = c10 ! mushy macroscopic drainage timescale (days) snwredist = 'none' ! type of snow redistribution snw_aging_table = 'test' ! snow aging lookup table snw_filename = 'unknown' ! snowtable filename @@ -582,6 +596,8 @@ subroutine input_data restart_lvl = .false. ! level ice restart tr_pond_lvl = .false. ! level-ice melt ponds restart_pond_lvl = .false. ! melt ponds restart + tr_pond_sealvl = .false. ! Sea level melt ponds + restart_pond_sealvl = .false. ! Sea level melt ponds restart tr_pond_topo = .false. ! explicit melt ponds (topographic) restart_pond_topo = .false. ! melt ponds restart tr_snow = .false. ! advanced snow physics @@ -960,6 +976,7 @@ subroutine input_data call broadcast_scalar(cpl_bgc, master_task) call broadcast_scalar(incond_dir, master_task) call broadcast_scalar(incond_file, master_task) + call broadcast_scalar(version_name, master_task) call broadcast_scalar(dump_last, master_task) call broadcast_scalar(restart_file, master_task) call broadcast_scalar(restart, master_task) @@ -992,6 +1009,7 @@ subroutine input_data call broadcast_scalar(grid_atm, master_task) call broadcast_scalar(grid_file, master_task) call broadcast_scalar(gridcpl_file, master_task) + call broadcast_scalar(grid_outfile, master_task) call broadcast_scalar(orca_halogrid, master_task) call broadcast_scalar(bathymetry_file, master_task) call broadcast_scalar(bathymetry_format, master_task) @@ -1012,6 +1030,8 @@ subroutine input_data call broadcast_scalar(kstrength, master_task) call broadcast_scalar(Pstar, master_task) call broadcast_scalar(Cstar, master_task) + call broadcast_scalar(dyn_area_min, master_task) + call broadcast_scalar(dyn_mass_min, master_task) call broadcast_scalar(krdg_partic, master_task) call broadcast_scalar(krdg_redist, master_task) call broadcast_scalar(mu_rdg, master_task) @@ -1067,6 +1087,7 @@ subroutine input_data call broadcast_scalar(dT_mlt, master_task) call broadcast_scalar(rsnw_mlt, master_task) call broadcast_scalar(kalg, master_task) + call broadcast_scalar(apnd_sl, master_task) call broadcast_scalar(hp1, master_task) call broadcast_scalar(hs0, master_task) call broadcast_scalar(hs1, master_task) @@ -1075,6 +1096,7 @@ subroutine input_data call broadcast_scalar(rfracmin, master_task) call broadcast_scalar(rfracmax, master_task) call broadcast_scalar(pndaspect, master_task) + call broadcast_scalar(tscale_pnd_drain, master_task) call broadcast_scalar(snwredist, master_task) call broadcast_scalar(snw_aging_table, master_task) call broadcast_scalar(snw_filename, master_task) @@ -1110,6 +1132,8 @@ subroutine input_data call broadcast_scalar(rotate_wind, master_task) call broadcast_scalar(calc_strair, master_task) call broadcast_scalar(calc_Tsfc, master_task) + call broadcast_scalar(semi_implicit_Tsfc, master_task) + call broadcast_scalar(vapor_flux_correction,master_task) call broadcast_scalar(formdrag, master_task) call broadcast_scalar(highfreq, master_task) call broadcast_scalar(natmiter, master_task) @@ -1162,6 +1186,8 @@ subroutine input_data call broadcast_scalar(restart_lvl, master_task) call broadcast_scalar(tr_pond_lvl, master_task) call broadcast_scalar(restart_pond_lvl, master_task) + call broadcast_scalar(tr_pond_sealvl, master_task) + call broadcast_scalar(restart_pond_sealvl, master_task) call broadcast_scalar(tr_pond_topo, master_task) call broadcast_scalar(restart_pond_topo, master_task) call broadcast_scalar(tr_snow, master_task) @@ -1208,6 +1234,9 @@ subroutine input_data if (trim(ice_data_dist) == 'default') ice_data_dist = 'uniform' if (trim(ice_data_type) == 'default') ice_data_type = 'latsst' + ! For backward compatibility + if (grid_format == 'nc') grid_format = 'pop_nc' + !----------------------------------------------------------------- ! verify inputs !----------------------------------------------------------------- @@ -1443,15 +1472,6 @@ subroutine input_data endif endif - if (evp_algorithm == 'shared_mem_1d' .and. & - grid_type == 'tripole') then - if (my_task == master_task) then - write(nu_diag,*) subname//' ERROR: evp_algorithm=shared_mem_1d is not tested for gridtype=tripole' - write(nu_diag,*) subname//' ERROR: change evp_algorithm to standard_2d' - endif - abort_list = trim(abort_list)//":49" - endif - capping = -9.99e30 if (kdyn == 1 .or. kdyn == 3) then if (capping_method == 'max') then @@ -1469,13 +1489,15 @@ subroutine input_data rplvl = 0 rptopo = 0 + rpsealvl = 0 if (tr_pond_lvl ) rplvl = 1 + if (tr_pond_sealvl ) rpsealvl = 1 if (tr_pond_topo) rptopo = 1 tr_pond = .false. ! explicit melt ponds - if (rplvl + rptopo > 0) tr_pond = .true. + if (rplvl + rptopo + rpsealvl > 0) tr_pond = .true. - if (rplvl + rptopo > 1) then + if (rplvl + rptopo + rpsealvl > 1) then if (my_task == master_task) then write(nu_diag,*) subname//' ERROR: Must use only one melt pond scheme' endif @@ -1500,6 +1522,13 @@ subroutine input_data abort_list = trim(abort_list)//":7" endif + if (semi_implicit_Tsfc .and. tr_pond_topo) then + if (my_task == master_task) then + write(nu_diag,*)'ERROR: semi_implicit_Tsfc and tr_pond_topo not supported together' + endif + abort_list = trim(abort_list)//":57" + endif + if (shortwave(1:4) /= 'dEdd' .and. tr_pond .and. calc_tsfc) then if (my_task == master_task) then write(nu_diag,*) subname//' ERROR: tr_pond=T, calc_tsfc=T, invalid shortwave' @@ -1948,11 +1977,13 @@ subroutine input_data write(nu_diag,*) ' ' write(nu_diag,*) ' Grid, Discretization' write(nu_diag,*) '--------------------------------' + write(nu_diag,1030) ' grid_format = ',trim(grid_format) tmpstr2 = ' ' if (trim(grid_type) == 'rectangular') tmpstr2 = ' : internally defined, rectangular grid' - if (trim(grid_type) == 'regional') tmpstr2 = ' : user-defined, regional grid' - if (trim(grid_type) == 'displaced_pole') tmpstr2 = ' : user-defined grid with rotated north pole' - if (trim(grid_type) == 'tripole') tmpstr2 = ' : user-defined grid with northern hemisphere zipper' + if (trim(grid_type) == 'regional') tmpstr2 = ' : grid file, regional grid' + if (trim(grid_type) == 'displaced_pole') tmpstr2 = ' : grid file with rotated north pole' + if (trim(grid_type) == 'tripole') tmpstr2 = ' : grid file with northern hemisphere zipper' + if (trim(grid_type) == 'latlon') tmpstr2 = ' : cesm latlon domain file' write(nu_diag,1030) ' grid_type = ',trim(grid_type),trim(tmpstr2) write(nu_diag,1030) ' grid_ice = ',trim(grid_ice) write(nu_diag,1030) ' grid_ice_thrm = ',trim(grid_ice_thrm) @@ -1967,7 +1998,12 @@ subroutine input_data write(nu_diag,1030) ' grid_ocn_dynu = ',trim(grid_ocn_dynu) write(nu_diag,1030) ' grid_ocn_dynv = ',trim(grid_ocn_dynv) write(nu_diag,1030) ' kmt_type = ',trim(kmt_type) - if (trim(grid_type) /= 'rectangular') then + if (trim(grid_type) == 'rectangular') then + write(nu_diag,1004) 'lon/lat refrect = ',lonrefrect,latrefrect + write(nu_diag,1004) 'dx/dy rect (cm) = ',dxrect,dyrect + write(nu_diag,1010) 'scale_dxdy = ',scale_dxdy + write(nu_diag,1004) 'dx/dy scale = ',dxscale,dyscale + else if (use_bathymetry) then tmpstr2 = ' : bathymetric input data is used' else @@ -2024,6 +2060,8 @@ subroutine input_data tmpstr2 = ' : unknown value' endif write(nu_diag,1020) ' kdyn = ', kdyn,trim(tmpstr2) + write(nu_diag,1003) ' dyn_area_min = ', dyn_area_min,' : min ice area concentration to activate dynamics' + write(nu_diag,1003) ' dyn_mass_min = ', dyn_mass_min,' : min ice mass to activate dynamics (kg/m2)' if (kdyn >= 1) then if (kdyn == 1 .or. kdyn == 2) then if (revised_evp) then @@ -2276,6 +2314,8 @@ subroutine input_data write(nu_diag,1010) ' rotate_wind = ', rotate_wind,' : rotate wind/stress to computational grid' write(nu_diag,1010) ' formdrag = ', formdrag,' : use form drag parameterization' write(nu_diag,1000) ' iceruf = ', iceruf, ' : ice surface roughness at atmosphere interface (m)' + write(nu_diag,1010) ' semi_implicit_Tsfc = ', semi_implicit_Tsfc,' : surface temperature coupling option based on d(hf)/dTs' + write(nu_diag,1010) ' vapor_flux_correction = ', vapor_flux_correction,' : mass/enthalpy correction for evaporation/sublimation' if (trim(atmbndy) == 'constant') then tmpstr2 = ' : constant-based boundary layer' elseif (trim(atmbndy) == 'similarity' .or. & @@ -2412,7 +2452,11 @@ subroutine input_data write(nu_diag,1002) ' hs1 = ', hs1,' : snow depth of transition to pond ice' elseif (tr_pond_topo) then write(nu_diag,1010) ' tr_pond_topo = ', tr_pond_topo,' : topo pond formulation' + write(nu_diag,*) ' WARNING: dpnd history fields are turned off for topo ponds' write(nu_diag,1002) ' hp1 = ', hp1,' : critical ice lid thickness for topo ponds' + elseif (tr_pond_sealvl) then + write(nu_diag,1010) ' tr_pond_sealvl = ', tr_pond_sealvl,' : sealvl pond formulation' + write(nu_diag,1002) ' apnd_sl = ', apnd_sl,' : equilibrium pond fraction' elseif (trim(shortwave) == 'ccsm3') then write(nu_diag,*) 'Pond effects on radiation are treated implicitly in the ccsm3 shortwave scheme' else @@ -2509,6 +2553,7 @@ subroutine input_data if (tr_fsd) write(nu_diag,1010) ' tr_fsd = ', tr_fsd,' : floe size distribution' if (tr_lvl) write(nu_diag,1010) ' tr_lvl = ', tr_lvl,' : ridging related tracers' if (tr_pond_lvl) write(nu_diag,1010) ' tr_pond_lvl = ', tr_pond_lvl,' : level-ice pond formulation' + if (tr_pond_sealvl) write(nu_diag,1010) ' tr_pond_sealvl = ', tr_pond_sealvl,' : sea level pond formulation' if (tr_pond_topo) write(nu_diag,1010) ' tr_pond_topo = ', tr_pond_topo,' : topo pond formulation' if (tr_snow) write(nu_diag,1010) ' tr_snow = ', tr_snow,' : advanced snow physics' if (tr_iage) write(nu_diag,1010) ' tr_iage = ', tr_iage,' : chronological ice age' @@ -2524,6 +2569,7 @@ subroutine input_data write(nu_diag,*) '===================================== ' if (trim(runid) /= 'unknown') & write(nu_diag,1031) ' runid = ', trim(runid) + write(nu_diag,1031) ' version_name = ', trim(version_name) write(nu_diag,1031) ' runtype = ', trim(runtype) write(nu_diag,1021) ' year_init = ', year_init write(nu_diag,1021) ' month_init = ', month_init @@ -2546,11 +2592,12 @@ subroutine input_data write(nu_diag,1031) ' bfbflag = ', trim(bfbflag) write(nu_diag,1021) ' numin = ', numin write(nu_diag,1021) ' numax = ', numax - write(nu_diag,1033) ' histfreq = ', histfreq(:) - write(nu_diag,1023) ' histfreq_n = ', histfreq_n(:) - write(nu_diag,1033) ' histfreq_base = ', histfreq_base(:) - write(nu_diag,1013) ' hist_avg = ', hist_avg(:) - write(nu_diag,1033) ' hist_suffix = ', hist_suffix(:) + write(nu_diag,1011) ' grid_outfile = ', grid_outfile + write(nu_diag,1033) ' histfreq = ', histfreq(1:max_nstrm-1) + write(nu_diag,1023) ' histfreq_n = ', histfreq_n(1:max_nstrm-1) + write(nu_diag,1033) ' histfreq_base = ', histfreq_base(1:max_nstrm-1) + write(nu_diag,1013) ' hist_avg = ', hist_avg(1:max_nstrm-1) + write(nu_diag,1033) ' hist_suffix = ', hist_suffix(1:max_nstrm-1) write(nu_diag,1031) ' history_dir = ', trim(history_dir) write(nu_diag,1031) ' history_file = ', trim(history_file) write(nu_diag,1021) ' history_precision= ', history_precision @@ -2566,9 +2613,9 @@ subroutine input_data write(nu_diag,1039) ' Initial condition will be written in ', & trim(incond_dir) endif - write(nu_diag,1033) ' dumpfreq = ', dumpfreq(:) - write(nu_diag,1023) ' dumpfreq_n = ', dumpfreq_n(:) - write(nu_diag,1033) ' dumpfreq_base = ', dumpfreq_base(:) + write(nu_diag,1033) ' dumpfreq = ', dumpfreq(1:max_nstrm-1) + write(nu_diag,1023) ' dumpfreq_n = ', dumpfreq_n(1:max_nstrm-1) + write(nu_diag,1033) ' dumpfreq_base = ', dumpfreq_base(1:max_nstrm-1) write(nu_diag,1011) ' dump_last = ', dump_last write(nu_diag,1011) ' restart = ', restart write(nu_diag,1031) ' restart_dir = ', trim(restart_dir) @@ -2649,6 +2696,7 @@ subroutine input_data write(nu_diag,1011) ' restart_FY = ', restart_FY write(nu_diag,1011) ' restart_lvl = ', restart_lvl write(nu_diag,1011) ' restart_pond_lvl = ', restart_pond_lvl + write(nu_diag,1011) ' restart_pond_sealvl = ', restart_pond_sealvl write(nu_diag,1011) ' restart_pond_topo= ', restart_pond_topo write(nu_diag,1011) ' restart_snow = ', restart_snow write(nu_diag,1011) ' restart_iso = ', restart_iso @@ -2668,11 +2716,19 @@ subroutine input_data endif ! my_task = master_task + if (grid_format /= 'pop_nc' .and. & + grid_format /= 'mom_nc' .and. & + grid_format /= 'geosnc' .and. & + grid_format /= 'meshnc' .and. & + grid_format /= 'bin' ) then + if (my_task == master_task) write(nu_diag,*) subname//' ERROR: unknown grid_format=',trim(grid_type) + abort_list = trim(abort_list)//":67" + endif + if (grid_type /= 'displaced_pole' .and. & grid_type /= 'tripole' .and. & grid_type /= 'column' .and. & grid_type /= 'rectangular' .and. & - grid_type /= 'cpom_grid' .and. & grid_type /= 'regional' .and. & grid_type /= 'latlon') then if (my_task == master_task) write(nu_diag,*) subname//' ERROR: unknown grid_type=',trim(grid_type) @@ -2692,14 +2748,16 @@ subroutine input_data kmt_type /= 'channel_onenorth' .and. & kmt_type /= 'wall' .and. & kmt_type /= 'default' .and. & - kmt_type /= 'boxislands') then + kmt_type /= 'boxislands'.and. & + kmt_type /= 'none' ) then if (my_task == master_task) write(nu_diag,*) subname//' ERROR: unknown kmt_type=',trim(kmt_type) abort_list = trim(abort_list)//":27" endif if (grid_type /= 'column' .and. & grid_type /= 'rectangular' .and. & - kmt_type /= 'file') then + kmt_type /= 'file' .and. & + kmt_type /= 'none') then if (my_task == master_task) write(nu_diag,*) subname//' ERROR: need kmt file, kmt_type=',trim(kmt_type) abort_list = trim(abort_list)//":28" endif @@ -2730,8 +2788,9 @@ subroutine input_data atmbndy_in=atmbndy, calc_strair_in=calc_strair, formdrag_in=formdrag, highfreq_in=highfreq, & kitd_in=kitd, kcatbound_in=kcatbound, hs0_in=hs0, dpscale_in=dpscale, frzpnd_in=frzpnd, & rfracmin_in=rfracmin, rfracmax_in=rfracmax, pndaspect_in=pndaspect, hs1_in=hs1, hp1_in=hp1, & - ktherm_in=ktherm, calc_Tsfc_in=calc_Tsfc, conduct_in=conduct, & - a_rapid_mode_in=a_rapid_mode, Rac_rapid_mode_in=Rac_rapid_mode, & + apnd_sl_in=apnd_sl, & + ktherm_in=ktherm, calc_Tsfc_in=calc_Tsfc, conduct_in=conduct, semi_implicit_Tsfc_in=semi_implicit_Tsfc, & + a_rapid_mode_in=a_rapid_mode, Rac_rapid_mode_in=Rac_rapid_mode, vapor_flux_correction_in=vapor_flux_correction, & floediam_in=floediam, hfrazilmin_in=hfrazilmin, Tliquidus_max_in=Tliquidus_max, & aspect_rapid_mode_in=aspect_rapid_mode, dSdt_slow_mode_in=dSdt_slow_mode, & phi_c_slow_mode_in=phi_c_slow_mode, phi_i_mushy_in=phi_i_mushy, conserv_check_in=conserv_check, & @@ -2744,11 +2803,12 @@ subroutine input_data rsnw_fall_in=rsnw_fall, rsnw_tmax_in=rsnw_tmax, rhosnew_in=rhosnew, & snwlvlfac_in=snwlvlfac, rhosmin_in=rhosmin, rhosmax_in=rhosmax, & snwredist_in=snwredist, snwgrain_in=snwgrain, snw_aging_table_in=trim(snw_aging_table), & - sw_redist_in=sw_redist, sw_frac_in=sw_frac, sw_dtemp_in=sw_dtemp) + sw_redist_in=sw_redist, sw_frac_in=sw_frac, sw_dtemp_in=sw_dtemp, & + tscale_pnd_drain_in=tscale_pnd_drain) call icepack_init_tracer_flags(tr_iage_in=tr_iage, tr_FY_in=tr_FY, & tr_lvl_in=tr_lvl, tr_iso_in=tr_iso, tr_aero_in=tr_aero, & tr_fsd_in=tr_fsd, tr_snow_in=tr_snow, tr_pond_in=tr_pond, & - tr_pond_lvl_in=tr_pond_lvl, tr_pond_topo_in=tr_pond_topo) + tr_pond_lvl_in=tr_pond_lvl, tr_pond_sealvl_in=tr_pond_sealvl, tr_pond_topo_in=tr_pond_topo) call icepack_init_tracer_sizes(ncat_in=ncat, nilyr_in=nilyr, nslyr_in=nslyr, nblyr_in=nblyr, & nfsd_in=nfsd, n_algae_in=n_algae, n_iso_in=n_iso, n_aero_in=n_aero, & n_DOC_in=n_DOC, n_DON_in=n_DON, & @@ -2759,7 +2819,8 @@ subroutine input_data 1000 format (a20,1x,f13.6,1x,a) ! float 1002 format (a20,5x,f9.2,1x,a) - 1003 format (a20,1x,G13.4,1x,a) + 1003 format (a20,1x,g13.4,1x,a) + 1004 format (a20,1x,2g13.4,1x,a) 1009 format (a20,1x,d13.6,1x,a) 1010 format (a20,8x,l6,1x,a) ! logical 1011 format (a20,1x,l6) @@ -2809,7 +2870,7 @@ subroutine init_state integer (kind=int_kind) :: ntrcr logical (kind=log_kind) :: tr_iage, tr_FY, tr_lvl, tr_iso, tr_aero - logical (kind=log_kind) :: tr_pond_lvl, tr_pond_topo + logical (kind=log_kind) :: tr_pond_lvl, tr_pond_topo, tr_pond_sealvl logical (kind=log_kind) :: tr_snow, tr_fsd integer (kind=int_kind) :: nt_Tsfc, nt_sice, nt_qice, nt_qsno, nt_iage, nt_FY integer (kind=int_kind) :: nt_alvl, nt_vlvl, nt_apnd, nt_hpnd, nt_ipnd @@ -2827,6 +2888,7 @@ subroutine init_state call icepack_query_tracer_flags(tr_iage_out=tr_iage, tr_FY_out=tr_FY, & tr_lvl_out=tr_lvl, tr_iso_out=tr_iso, tr_aero_out=tr_aero, & tr_pond_lvl_out=tr_pond_lvl, tr_pond_topo_out=tr_pond_topo, & + tr_pond_sealvl_out=tr_pond_sealvl, & tr_snow_out=tr_snow, tr_fsd_out=tr_fsd) call icepack_query_tracer_indices(nt_Tsfc_out=nt_Tsfc, nt_sice_out=nt_sice, & nt_qice_out=nt_qice, nt_qsno_out=nt_qsno, nt_iage_out=nt_iage, nt_fy_out=nt_fy, & @@ -2883,7 +2945,7 @@ subroutine init_state trcr_depend(nt_hpnd) = 2+nt_apnd ! melt pond depth trcr_depend(nt_ipnd) = 2+nt_apnd ! refrozen pond lid endif - if (tr_pond_topo) then + if (tr_pond_topo .or. tr_pond_sealvl) then trcr_depend(nt_apnd) = 0 ! melt pond area trcr_depend(nt_hpnd) = 2+nt_apnd ! melt pond depth trcr_depend(nt_ipnd) = 2+nt_apnd ! refrozen pond lid @@ -2949,7 +3011,7 @@ subroutine init_state nt_strata (nt_ipnd,2) = nt_apnd ! on melt pond area nt_strata (nt_ipnd,1) = nt_alvl ! on level ice area endif - if (tr_pond_topo) then + if (tr_pond_topo .or. tr_pond_sealvl) then n_trcr_strata(nt_hpnd) = 1 ! melt pond depth nt_strata (nt_hpnd,1) = nt_apnd ! on melt pond area n_trcr_strata(nt_ipnd) = 1 ! refrozen pond lid @@ -3318,23 +3380,9 @@ subroutine set_state_var (nx_block, ny_block, & ! location of ice !--------------------------------------------------------- - if (trim(ice_data_type) == 'box2001') then + icells = 0 - ! place ice on left side of domain - icells = 0 - do j = jlo, jhi - do i = ilo, ihi - if (tmask(i,j)) then - if (ULON(i,j) < -50./rad_to_deg) then - icells = icells + 1 - indxi(icells) = i - indxj(icells) = j - endif ! ULON - endif ! tmask - enddo ! i - enddo ! j - - elseif (trim(ice_data_type) == 'boxslotcyl') then + if (trim(ice_data_type) == 'boxslotcyl') then ! Geometric configuration of the slotted cylinder diam = p3 *dxrect*(nx_global-1) @@ -3366,8 +3414,10 @@ subroutine set_state_var (nx_block, ny_block, & enddo enddo - elseif (trim(ice_data_type) == 'uniform') then + elseif (trim(ice_data_type) == 'uniform' .or. trim(ice_data_type) == 'box2001') then ! all cells not land mask are ice + ! box2001 used to have a check for west of 50W, this was changed, so now box2001 is + ! the same as uniform. keep box2001 option for backwards compatibility. icells = 0 do j = jlo, jhi do i = ilo, ihi diff --git a/cicecore/cicedyn/general/ice_state.F90 b/cicecore/cicedyn/general/ice_state.F90 index 21ddf562c..82b03f2cb 100644 --- a/cicecore/cicedyn/general/ice_state.F90 +++ b/cicecore/cicedyn/general/ice_state.F90 @@ -52,15 +52,13 @@ module ice_state ! state of the ice aggregated over all categories !----------------------------------------------------------------- - real (kind=dbl_kind), dimension(:,:,:), allocatable, & - public :: & + real (kind=dbl_kind), dimension(:,:,:), allocatable, public :: & aice , & ! concentration of ice on T grid aiU , & ! concentration of ice on U grid vice , & ! volume per unit area of ice (m) vsno ! volume per unit area of snow (m) - real (kind=dbl_kind), & - dimension(:,:,:,:), allocatable, public :: & + real (kind=dbl_kind), dimension(:,:,:,:), allocatable, public :: & trcr ! ice tracers ! 1: surface temperature of ice/snow (C) @@ -68,18 +66,15 @@ module ice_state ! state of the ice for each category !----------------------------------------------------------------- - real (kind=dbl_kind), dimension (:,:,:), allocatable, & - public:: & + real (kind=dbl_kind), dimension (:,:,:), allocatable, public:: & aice0 ! concentration of open water - real (kind=dbl_kind), & - dimension (:,:,:,:), allocatable, public :: & + real (kind=dbl_kind), dimension (:,:,:,:), allocatable, public :: & aicen , & ! concentration of ice vicen , & ! volume per unit area of ice (m) vsnon ! volume per unit area of snow (m) - real (kind=dbl_kind), public, & - dimension (:,:,:,:,:), allocatable :: & + real (kind=dbl_kind), dimension (:,:,:,:,:), allocatable, public :: & trcrn ! tracers ! 1: surface temperature of ice/snow (C) @@ -106,8 +101,7 @@ module ice_state ! dynamic variables closely related to the state of the ice !----------------------------------------------------------------- - real (kind=dbl_kind), dimension(:,:,:), allocatable, & - public :: & + real (kind=dbl_kind), dimension(:,:,:), allocatable, public :: & uvel , & ! x-component of velocity on U grid (m/s) vvel , & ! y-component of velocity on U grid (m/s) uvelE , & ! x-component of velocity on E grid (m/s) @@ -123,15 +117,14 @@ module ice_state ! ice state at start of time step, saved for later in the step !----------------------------------------------------------------- - real (kind=dbl_kind), dimension(:,:,:), allocatable, & - public :: & + real (kind=dbl_kind), dimension(:,:,:), allocatable, public :: & aice_init ! initial concentration of ice, for diagnostics - real (kind=dbl_kind), & - dimension(:,:,:,:), allocatable, public :: & + real (kind=dbl_kind), dimension(:,:,:,:), allocatable, public :: & aicen_init , & ! initial ice concentration, for linear ITD vicen_init , & ! initial ice volume (m), for linear ITD - vsnon_init ! initial snow volume (m), for aerosol + vsnon_init , & ! initial snow volume (m), for aerosol + Tsfcn_init ! initial ice surface temperature (degC) !======================================================================= @@ -173,6 +166,7 @@ subroutine alloc_state aicen_init(nx_block,ny_block,ncat,max_blocks) , & ! initial ice concentration, for linear ITD vicen_init(nx_block,ny_block,ncat,max_blocks) , & ! initial ice volume (m), for linear ITD vsnon_init(nx_block,ny_block,ncat,max_blocks) , & ! initial snow volume (m), for aerosol + Tsfcn_init(nx_block,ny_block,ncat,max_blocks) , & ! initial snow/ice surface temperature(degC) trcr (nx_block,ny_block,ntrcr,max_blocks) , & ! ice tracers: 1: surface temperature of ice/snow (C) trcrn (nx_block,ny_block,ntrcr,ncat,max_blocks) , & ! tracers: 1: surface temperature of ice/snow (C) stat=ierr) diff --git a/cicecore/cicedyn/general/ice_step_mod.F90 b/cicecore/cicedyn/general/ice_step_mod.F90 index 6a6810a4f..b7aff0779 100644 --- a/cicecore/cicedyn/general/ice_step_mod.F90 +++ b/cicecore/cicedyn/general/ice_step_mod.F90 @@ -60,7 +60,10 @@ subroutine save_init ! saves initial values for aice, aicen, vicen, vsnon use ice_state, only: aice, aicen, aice_init, aicen_init, & - vicen, vicen_init, vsnon, vsnon_init + vicen, vicen_init, vsnon, vsnon_init, trcrn, Tsfcn_init + + integer (kind=int_kind) :: & + nt_Tsfc ! Tsfc index in trcrn character(len=*), parameter :: subname = '(save_init)' @@ -70,10 +73,13 @@ subroutine save_init ! Save the initial ice area and volume in each category. !----------------------------------------------------------------- + call icepack_query_tracer_indices(nt_Tsfc_out=nt_Tsfc) + aice_init = aice aicen_init = aicen vicen_init = vicen vsnon_init = vsnon + Tsfcn_init = trcrn(:,:,nt_Tsfc,:,:) end subroutine save_init @@ -222,7 +228,8 @@ subroutine step_therm1 (dt, iblk) Cdn_atm, Cdn_atm_skin, Cdn_atm_floe, Cdn_atm_rdg, Cdn_atm_pond, & hfreebd, hdraft, hridge, distrdg, hkeel, dkeel, lfloe, dfloe, & fswsfcn, fswintn, Sswabsn, Iswabsn, meltsliqn, meltsliq, & - fswthrun, fswthrun_vdr, fswthrun_vdf, fswthrun_idr, fswthrun_idf + fswthrun, fswthrun_vdr, fswthrun_vdf, fswthrun_idr, fswthrun_idf, & + fswthrun_uvrdr, fswthrun_uvrdf, fswthrun_pardr, fswthrun_pardf use ice_calendar, only: yday use ice_domain_size, only: ncat, nilyr, nslyr, n_iso, n_aero, nfsd use ice_flux, only: frzmlt, sst, Tf, strocnxT_iavg, strocnyT_iavg, rsiden, fbot, Tbot, Tsnice, & @@ -232,12 +239,16 @@ subroutine step_therm1 (dt, iblk) frain, Tair, strairxT, strairyT, fsurf, fcondtop, fsens, & flat, fswabs, flwout, evap, evaps, evapi, Tref, Qref, Uref, fresh, fsalt, fhocn, & fswthru, fswthru_vdr, fswthru_vdf, fswthru_idr, fswthru_idf, & + fswthru_uvrdr, fswthru_uvrdf, fswthru_pardr, fswthru_pardf, & meltt, melts, meltb, congel, snoice, & flatn_f, fsensn_f, fsurfn_f, fcondtopn_f, & + dfsurfndTsfc_f, dflatndTsfc_f, & send_i2x_per_cat, fswthrun_ai, dsnow + use ice_flux, only: dpnd_flush, dpnd_expon, dpnd_freebd, dpnd_initial, & + dpnd_dlid, dpnd_flushn, dpnd_exponn, dpnd_freebdn, dpnd_initialn, dpnd_dlidn use ice_flux_bgc, only: dsnown, faero_atm, faero_ocn, fiso_atm, fiso_ocn, & Qa_iso, Qref_iso, fiso_evap, HDO_ocn, H2_16O_ocn, H2_18O_ocn - use ice_grid, only: lmask_n, lmask_s, tmask + use ice_grid, only: lmask_n, lmask_s, tmask, opmask use ice_state, only: aice, aicen, aicen_init, vicen_init, & vice, vicen, vsno, vsnon, trcrn, vsnon_init #ifdef CICE_IN_NEMO @@ -273,8 +284,7 @@ subroutine step_therm1 (dt, iblk) nt_isosno, nt_isoice, nt_rsnw, nt_smice, nt_smliq logical (kind=log_kind) :: & - tr_iage, tr_FY, tr_iso, tr_aero, tr_pond, & - tr_pond_lvl, tr_pond_topo, calc_Tsfc, snwgrain + tr_iage, tr_FY, tr_iso, tr_aero, calc_Tsfc, snwgrain real (kind=dbl_kind) :: & puny ! a very small number @@ -299,8 +309,7 @@ subroutine step_therm1 (dt, iblk) call icepack_query_tracer_sizes(ntrcr_out=ntrcr) call icepack_query_tracer_flags( & tr_iage_out=tr_iage, tr_FY_out=tr_FY, tr_iso_out=tr_iso, & - tr_aero_out=tr_aero, tr_pond_out=tr_pond, & - tr_pond_lvl_out=tr_pond_lvl, tr_pond_topo_out=tr_pond_topo) + tr_aero_out=tr_aero ) call icepack_query_tracer_indices( & nt_apnd_out=nt_apnd, nt_hpnd_out=nt_hpnd, nt_ipnd_out=nt_ipnd, & nt_alvl_out=nt_alvl, nt_vlvl_out=nt_vlvl, nt_Tsfc_out=nt_Tsfc, & @@ -387,7 +396,7 @@ subroutine step_therm1 (dt, iblk) enddo endif ! tr_aero - if (tmask(i,j,iblk)) then + if (tmask(i,j,iblk) .or. opmask(i,j,iblk)) then call icepack_step_therm1(dt=dt, & aicen_init = aicen_init (i,j,:,iblk), & @@ -484,6 +493,10 @@ subroutine step_therm1 (dt, iblk) fswthrun_vdf = fswthrun_vdf (i,j,:,iblk),& fswthrun_idr = fswthrun_idr (i,j,:,iblk),& fswthrun_idf = fswthrun_idf (i,j,:,iblk),& + fswthrun_uvrdr = fswthrun_uvrdr (i,j,:,iblk),& + fswthrun_uvrdf = fswthrun_uvrdf (i,j,:,iblk),& + fswthrun_pardr = fswthrun_pardr (i,j,:,iblk),& + fswthrun_pardf = fswthrun_pardf (i,j,:,iblk),& fswabs = fswabs (i,j, iblk), & flwout = flwout (i,j, iblk), & Sswabsn = Sswabsn (i,j,:,:,iblk), & @@ -504,10 +517,16 @@ subroutine step_therm1 (dt, iblk) fswthru_vdf = fswthru_vdf (i,j, iblk), & fswthru_idr = fswthru_idr (i,j, iblk), & fswthru_idf = fswthru_idf (i,j, iblk), & + fswthru_uvrdr = fswthru_uvrdr (i,j, iblk), & + fswthru_uvrdf = fswthru_uvrdf (i,j, iblk), & + fswthru_pardr = fswthru_pardr (i,j, iblk), & + fswthru_pardf = fswthru_pardf (i,j, iblk), & flatn_f = flatn_f (i,j,:,iblk), & fsensn_f = fsensn_f (i,j,:,iblk), & fsurfn_f = fsurfn_f (i,j,:,iblk), & fcondtopn_f = fcondtopn_f (i,j,:,iblk), & + dfsurfdT = dfsurfndTsfc_f(i,j,:,iblk), & + dflatdT = dflatndTsfc_f (i,j,:,iblk), & faero_atm = faero_atm (i,j,1:n_aero,iblk), & faero_ocn = faero_ocn (i,j,1:n_aero,iblk), & fiso_atm = fiso_atm (i,j,:,iblk), & @@ -536,6 +555,16 @@ subroutine step_therm1 (dt, iblk) lmask_s = lmask_s (i,j, iblk), & mlt_onset = mlt_onset (i,j, iblk), & frz_onset = frz_onset (i,j, iblk), & + dpnd_flush = dpnd_flush (i,j, iblk), & + dpnd_expon = dpnd_expon (i,j, iblk), & + dpnd_freebd = dpnd_freebd (i,j, iblk), & + dpnd_initial = dpnd_initial(i,j, iblk), & + dpnd_dlid = dpnd_dlid (i,j, iblk), & + dpnd_flushn = dpnd_flushn (i,j,:,iblk), & + dpnd_exponn = dpnd_exponn (i,j,:,iblk), & + dpnd_freebdn = dpnd_freebdn(i,j,:,iblk), & + dpnd_initialn=dpnd_initialn(i,j,:,iblk), & + dpnd_dlidn = dpnd_dlidn (i,j,:,iblk), & yday=yday, prescribed_ice=prescribed_ice) !----------------------------------------------------------------- @@ -617,10 +646,10 @@ subroutine step_therm2 (dt, iblk) use ice_domain_size, only: ncat, nilyr, nslyr, nblyr, nfsd use ice_flux, only: fresh, frain, fpond, frzmlt, frazil, frz_onset, & fsalt, Tf, sss, salinz, fhocn, rsiden, wlat, & - meltl, frazil_diag + meltl, frazil_diag, dpnd_melt use ice_flux_bgc, only: flux_bio, faero_ocn, & fiso_ocn, HDO_ocn, H2_16O_ocn, H2_18O_ocn - use ice_grid, only: tmask + use ice_grid, only: tmask, opmask use ice_state, only: aice, aicen, aice0, trcr_depend, & aicen_init, vicen_init, trcrn, vicen, vsnon, & trcr_base, n_trcr_strata, nt_strata @@ -672,58 +701,60 @@ subroutine step_therm2 (dt, iblk) do j = jlo, jhi do i = ilo, ihi - if (tmask(i,j,iblk)) then + if (tmask(i,j,iblk) .or. opmask(i,j,iblk)) then ! significant wave height for FSD if (tr_fsd) & wave_sig_ht(i,j,iblk) = c4*SQRT(SUM(wave_spectrum(i,j,:,iblk)*dwavefreq(:))) - call icepack_step_therm2(dt=dt, & - hin_max = hin_max (:), & - aicen = aicen (i,j,:,iblk), & - vicen = vicen (i,j,:,iblk), & - vsnon = vsnon (i,j,:,iblk), & - aicen_init = aicen_init(i,j,:,iblk), & - vicen_init = vicen_init(i,j,:,iblk), & - trcrn = trcrn (i,j,:,:,iblk), & - aice0 = aice0 (i,j, iblk), & - aice = aice (i,j, iblk), & - trcr_depend= trcr_depend(:), & - trcr_base = trcr_base(:,:), & - n_trcr_strata = n_trcr_strata(:), & - nt_strata = nt_strata(:,:), & - Tf = Tf (i,j, iblk), & - sss = sss (i,j, iblk), & - salinz = salinz (i,j,:,iblk), & - rsiden = rsiden (i,j,:,iblk), & - meltl = meltl (i,j, iblk), & - wlat = wlat (i,j, iblk), & - frzmlt = frzmlt (i,j, iblk), & - frazil = frazil (i,j, iblk), & - frain = frain (i,j, iblk), & - fpond = fpond (i,j, iblk), & - fresh = fresh (i,j, iblk), & - fsalt = fsalt (i,j, iblk), & - fhocn = fhocn (i,j, iblk), & - faero_ocn = faero_ocn (i,j,:,iblk), & - first_ice = first_ice (i,j,:,iblk), & - flux_bio = flux_bio (i,j,1:nbtrcr,iblk), & - ocean_bio = ocean_bio (i,j,1:nbtrcr,iblk), & - frazil_diag= frazil_diag(i,j,iblk), & - frz_onset = frz_onset (i,j, iblk), & - yday = yday, & - fiso_ocn = fiso_ocn (i,j,:,iblk), & - HDO_ocn = HDO_ocn (i,j, iblk), & - H2_16O_ocn = H2_16O_ocn(i,j, iblk), & - H2_18O_ocn = H2_18O_ocn(i,j, iblk), & - wave_sig_ht= wave_sig_ht(i,j,iblk), & - wave_spectrum = wave_spectrum(i,j,:,iblk), & - wavefreq = wavefreq(:), & - dwavefreq = dwavefreq(:), & - d_afsd_latg= d_afsd_latg(i,j,:,iblk),& - d_afsd_newi= d_afsd_newi(i,j,:,iblk),& - d_afsd_latm= d_afsd_latm(i,j,:,iblk),& - d_afsd_weld= d_afsd_weld(i,j,:,iblk)) + call icepack_step_therm2(dt=dt, & + hin_max = hin_max (:), & + aicen = aicen (i,j,:,iblk), & + vicen = vicen (i,j,:,iblk), & + vsnon = vsnon (i,j,:,iblk), & + aicen_init = aicen_init (i,j,:,iblk), & + vicen_init = vicen_init (i,j,:,iblk), & + trcrn = trcrn (i,j,:,:,iblk), & + aice0 = aice0 (i,j, iblk), & + aice = aice (i,j, iblk), & + trcr_depend = trcr_depend(:), & + trcr_base = trcr_base (:,:), & + n_trcr_strata = n_trcr_strata(:), & + nt_strata = nt_strata (:,:), & + Tf = Tf (i,j, iblk), & + sss = sss (i,j, iblk), & + salinz = salinz (i,j,:,iblk), & + rsiden = rsiden (i,j,:,iblk), & + meltl = meltl (i,j, iblk), & + wlat = wlat (i,j, iblk), & + frzmlt = frzmlt (i,j, iblk), & + frazil = frazil (i,j, iblk), & + frain = frain (i,j, iblk), & + fpond = fpond (i,j, iblk), & + fresh = fresh (i,j, iblk), & + fsalt = fsalt (i,j, iblk), & + fhocn = fhocn (i,j, iblk), & + faero_ocn = faero_ocn (i,j,:,iblk), & + first_ice = first_ice (i,j,:,iblk), & + flux_bio = flux_bio (i,j,1:nbtrcr,iblk), & + ocean_bio = ocean_bio (i,j,1:nbtrcr,iblk), & + frazil_diag = frazil_diag(i,j, iblk), & + frz_onset = frz_onset (i,j, iblk), & + yday = yday, & + fiso_ocn = fiso_ocn (i,j,:,iblk), & + HDO_ocn = HDO_ocn (i,j, iblk), & + H2_16O_ocn = H2_16O_ocn (i,j, iblk), & + H2_18O_ocn = H2_18O_ocn (i,j, iblk), & + wave_sig_ht = wave_sig_ht(i,j, iblk), & + wave_spectrum = & + wave_spectrum(i,j,:,iblk), & + wavefreq = wavefreq (:), & + dwavefreq = dwavefreq (:), & + d_afsd_latg = d_afsd_latg(i,j,:,iblk), & + d_afsd_newi = d_afsd_newi(i,j,:,iblk), & + d_afsd_latm = d_afsd_latm(i,j,:,iblk), & + d_afsd_weld = d_afsd_weld(i,j,:,iblk), & + dpnd_melt = dpnd_melt (i,j, iblk)) endif ! tmask enddo ! i @@ -1031,7 +1062,7 @@ subroutine step_dyn_ridge (dt, ndtd, iblk) use ice_domain_size, only: ncat, nilyr, nslyr, n_aero, nblyr use ice_flux, only: & rdg_conv, rdg_shear, dardg1dt, dardg2dt, & - dvirdgdt, opening, fpond, fresh, fhocn, & + dvirdgdt, opening, fpond, fresh, fhocn, dpnd_ridge, & aparticn, krdgn, aredistn, vredistn, dardg1ndt, dardg2ndt, & dvirdgndt, araftn, vraftn, fsalt, Tf use ice_flux_bgc, only: flux_bio, faero_ocn, fiso_ocn @@ -1124,8 +1155,8 @@ subroutine step_dyn_ridge (dt, ndtd, iblk) fsalt = fsalt (i,j, iblk), & first_ice = first_ice(i,j,:,iblk), & flux_bio = flux_bio (i,j,1:nbtrcr,iblk), & - Tf = Tf(i,j,iblk)) - + Tf = Tf (i,j, iblk), & + dpnd_ridge=dpnd_ridge(i,j, iblk)) endif ! tmask enddo ! i @@ -1260,13 +1291,15 @@ subroutine step_radiation (dt, iblk) use ice_arrays_column, only: ffracn, dhsn, & fswsfcn, fswintn, fswpenln, Sswabsn, Iswabsn, & fswthrun, fswthrun_vdr, fswthrun_vdf, fswthrun_idr, fswthrun_idf, & + fswthrun_uvrdr, fswthrun_uvrdf, fswthrun_pardr, fswthrun_pardf, & albicen, albsnon, albpndn, & alvdrn, alidrn, alvdfn, alidfn, apeffn, trcrn_sw, snowfracn, & swgrid, igrid use ice_calendar, only: calendar_type, days_per_year, nextsw_cday, yday, msec use ice_domain_size, only: ncat, n_aero, nilyr, nslyr, n_zaero, n_algae, nblyr - use ice_flux, only: swvdr, swvdf, swidr, swidf, coszen, fsnow - use ice_grid, only: TLAT, TLON, tmask + use ice_flux, only: swvdr, swvdf, swidr, swidf, coszen, fsnow, & + swuvrdr, swuvrdf, swpardr, swpardf + use ice_grid, only: TLAT, TLON, tmask, opmask use ice_state, only: aicen, vicen, vsnon, trcrn use ice_timers, only: ice_timer_start, ice_timer_stop, timer_sw use ice_communicate, only: my_task @@ -1367,7 +1400,7 @@ subroutine step_radiation (dt, iblk) endif enddo - if (tmask(i,j,iblk)) then + if (tmask(i,j,iblk) .or. opmask(i,j,iblk)) then call icepack_step_radiation (dt=dt, & fbri=fbri(:), & @@ -1390,6 +1423,8 @@ subroutine step_radiation (dt, iblk) sec=msec, & swvdr =swvdr (i,j ,iblk), swvdf =swvdf (i,j ,iblk), & swidr =swidr (i,j ,iblk), swidf =swidf (i,j ,iblk), & + swuvrdr =swuvrdr (i,j ,iblk), swuvrdf =swuvrdf (i,j ,iblk), & + swpardr =swpardr (i,j ,iblk), swpardf =swpardf (i,j ,iblk), & coszen =coszen (i,j ,iblk), fsnow =fsnow (i,j ,iblk), & alvdrn =alvdrn (i,j,: ,iblk), alvdfn =alvdfn (i,j,: ,iblk), & alidrn =alidrn (i,j,: ,iblk), alidfn =alidfn (i,j,: ,iblk), & @@ -1399,7 +1434,11 @@ subroutine step_radiation (dt, iblk) fswthrun_vdf =fswthrun_vdf (i,j,: ,iblk), & fswthrun_idr =fswthrun_idr (i,j,: ,iblk), & fswthrun_idf =fswthrun_idf (i,j,: ,iblk), & - fswpenln=fswpenln(i,j,:,:,iblk), & + fswthrun_uvrdr =fswthrun_uvrdr (i,j,: ,iblk), & + fswthrun_uvrdf =fswthrun_uvrdf (i,j,: ,iblk), & + fswthrun_pardr =fswthrun_pardr (i,j,: ,iblk), & + fswthrun_pardf =fswthrun_pardf (i,j,: ,iblk), & + fswpenln =fswpenln (i,j,:,:,iblk), & Sswabsn =Sswabsn (i,j,:,:,iblk), Iswabsn =Iswabsn (i,j,:,:,iblk), & albicen =albicen (i,j,: ,iblk), albsnon =albsnon (i,j,: ,iblk), & albpndn =albpndn (i,j,: ,iblk), apeffn =apeffn (i,j,: ,iblk), & diff --git a/cicecore/cicedyn/infrastructure/comm/mpi/ice_boundary.F90 b/cicecore/cicedyn/infrastructure/comm/mpi/ice_boundary.F90 index a33e050b9..11cd0d2e1 100644 --- a/cicecore/cicedyn/infrastructure/comm/mpi/ice_boundary.F90 +++ b/cicecore/cicedyn/infrastructure/comm/mpi/ice_boundary.F90 @@ -1333,7 +1333,7 @@ subroutine ice_HaloUpdate2DR8(array, halo, & do nmsg=1,halo%numMsgRecv len = halo%SizeRecv(nmsg) - call MPI_IRECV(bufRecvR8(1:len,nmsg), len, mpiR8, & + call MPI_IRECV(bufRecvR8(1,nmsg), len, mpiR8, & halo%recvTask(nmsg), & mpitagHalo + halo%recvTask(nmsg), & halo%communicator, rcvRequest(nmsg), ierr) @@ -1359,7 +1359,7 @@ subroutine ice_HaloUpdate2DR8(array, halo, & end do len = halo%SizeSend(nmsg) - call MPI_ISEND(bufSendR8(1:len,nmsg), len, mpiR8, & + call MPI_ISEND(bufSendR8(1,nmsg), len, mpiR8, & halo%sendTask(nmsg), & mpitagHalo + my_task, & halo%communicator, sndRequest(nmsg), ierr) @@ -1768,7 +1768,7 @@ subroutine ice_HaloUpdate2DR4(array, halo, & do nmsg=1,halo%numMsgRecv len = halo%SizeRecv(nmsg) - call MPI_IRECV(bufRecvR4(1:len,nmsg), len, mpiR4, & + call MPI_IRECV(bufRecvR4(1,nmsg), len, mpiR4, & halo%recvTask(nmsg), & mpitagHalo + halo%recvTask(nmsg), & halo%communicator, rcvRequest(nmsg), ierr) @@ -1794,7 +1794,7 @@ subroutine ice_HaloUpdate2DR4(array, halo, & end do len = halo%SizeSend(nmsg) - call MPI_ISEND(bufSendR4(1:len,nmsg), len, mpiR4, & + call MPI_ISEND(bufSendR4(1,nmsg), len, mpiR4, & halo%sendTask(nmsg), & mpitagHalo + my_task, & halo%communicator, sndRequest(nmsg), ierr) @@ -2183,7 +2183,7 @@ subroutine ice_HaloUpdate2DI4(array, halo, & do nmsg=1,halo%numMsgRecv len = halo%SizeRecv(nmsg) - call MPI_IRECV(bufRecvI4(1:len,nmsg), len, MPI_INTEGER, & + call MPI_IRECV(bufRecvI4(1,nmsg), len, MPI_INTEGER, & halo%recvTask(nmsg), & mpitagHalo + halo%recvTask(nmsg), & halo%communicator, rcvRequest(nmsg), ierr) @@ -2209,7 +2209,7 @@ subroutine ice_HaloUpdate2DI4(array, halo, & end do len = halo%SizeSend(nmsg) - call MPI_ISEND(bufSendI4(1:len,nmsg), len, MPI_INTEGER, & + call MPI_ISEND(bufSendI4(1,nmsg), len, MPI_INTEGER, & halo%sendTask(nmsg), & mpitagHalo + my_task, & halo%communicator, sndRequest(nmsg), ierr) @@ -2702,7 +2702,7 @@ subroutine ice_HaloUpdate3DR8(array, halo, & do nmsg=1,halo%numMsgRecv len = halo%SizeRecv(nmsg)*nz - call MPI_IRECV(bufRecv(1:len,nmsg), len, mpiR8, & + call MPI_IRECV(bufRecv(1,nmsg), len, mpiR8, & halo%recvTask(nmsg), & mpitagHalo + halo%recvTask(nmsg), & halo%communicator, rcvRequest(nmsg), ierr) @@ -2732,7 +2732,7 @@ subroutine ice_HaloUpdate3DR8(array, halo, & end do len = halo%SizeSend(nmsg)*nz - call MPI_ISEND(bufSend(1:len,nmsg), len, mpiR8, & + call MPI_ISEND(bufSend(1,nmsg), len, mpiR8, & halo%sendTask(nmsg), & mpitagHalo + my_task, & halo%communicator, sndRequest(nmsg), ierr) @@ -3176,7 +3176,7 @@ subroutine ice_HaloUpdate3DR4(array, halo, & do nmsg=1,halo%numMsgRecv len = halo%SizeRecv(nmsg)*nz - call MPI_IRECV(bufRecv(1:len,nmsg), len, mpiR4, & + call MPI_IRECV(bufRecv(1,nmsg), len, mpiR4, & halo%recvTask(nmsg), & mpitagHalo + halo%recvTask(nmsg), & halo%communicator, rcvRequest(nmsg), ierr) @@ -3206,7 +3206,7 @@ subroutine ice_HaloUpdate3DR4(array, halo, & end do len = halo%SizeSend(nmsg)*nz - call MPI_ISEND(bufSend(1:len,nmsg), len, mpiR4, & + call MPI_ISEND(bufSend(1,nmsg), len, mpiR4, & halo%sendTask(nmsg), & mpitagHalo + my_task, & halo%communicator, sndRequest(nmsg), ierr) @@ -3650,7 +3650,7 @@ subroutine ice_HaloUpdate3DI4(array, halo, & do nmsg=1,halo%numMsgRecv len = halo%SizeRecv(nmsg)*nz - call MPI_IRECV(bufRecv(1:len,nmsg), len, MPI_INTEGER, & + call MPI_IRECV(bufRecv(1,nmsg), len, MPI_INTEGER, & halo%recvTask(nmsg), & mpitagHalo + halo%recvTask(nmsg), & halo%communicator, rcvRequest(nmsg), ierr) @@ -3680,7 +3680,7 @@ subroutine ice_HaloUpdate3DI4(array, halo, & end do len = halo%SizeSend(nmsg)*nz - call MPI_ISEND(bufSend(1:len,nmsg), len, MPI_INTEGER, & + call MPI_ISEND(bufSend(1,nmsg), len, MPI_INTEGER, & halo%sendTask(nmsg), & mpitagHalo + my_task, & halo%communicator, sndRequest(nmsg), ierr) @@ -4125,7 +4125,7 @@ subroutine ice_HaloUpdate4DR8(array, halo, & do nmsg=1,halo%numMsgRecv len = halo%SizeRecv(nmsg)*nz*nt - call MPI_IRECV(bufRecv(1:len,nmsg), len, mpiR8, & + call MPI_IRECV(bufRecv(1,nmsg), len, mpiR8, & halo%recvTask(nmsg), & mpitagHalo + halo%recvTask(nmsg), & halo%communicator, rcvRequest(nmsg), ierr) @@ -4158,7 +4158,7 @@ subroutine ice_HaloUpdate4DR8(array, halo, & end do len = halo%SizeSend(nmsg)*nz*nt - call MPI_ISEND(bufSend(1:len,nmsg), len, mpiR8, & + call MPI_ISEND(bufSend(1,nmsg), len, mpiR8, & halo%sendTask(nmsg), & mpitagHalo + my_task, & halo%communicator, sndRequest(nmsg), ierr) @@ -4623,7 +4623,7 @@ subroutine ice_HaloUpdate4DR4(array, halo, & do nmsg=1,halo%numMsgRecv len = halo%SizeRecv(nmsg)*nz*nt - call MPI_IRECV(bufRecv(1:len,nmsg), len, mpiR4, & + call MPI_IRECV(bufRecv(1,nmsg), len, mpiR4, & halo%recvTask(nmsg), & mpitagHalo + halo%recvTask(nmsg), & halo%communicator, rcvRequest(nmsg), ierr) @@ -4656,7 +4656,7 @@ subroutine ice_HaloUpdate4DR4(array, halo, & end do len = halo%SizeSend(nmsg)*nz*nt - call MPI_ISEND(bufSend(1:len,nmsg), len, mpiR4, & + call MPI_ISEND(bufSend(1,nmsg), len, mpiR4, & halo%sendTask(nmsg), & mpitagHalo + my_task, & halo%communicator, sndRequest(nmsg), ierr) @@ -5121,7 +5121,7 @@ subroutine ice_HaloUpdate4DI4(array, halo, & do nmsg=1,halo%numMsgRecv len = halo%SizeRecv(nmsg)*nz*nt - call MPI_IRECV(bufRecv(1:len,nmsg), len, MPI_INTEGER, & + call MPI_IRECV(bufRecv(1,nmsg), len, MPI_INTEGER, & halo%recvTask(nmsg), & mpitagHalo + halo%recvTask(nmsg), & halo%communicator, rcvRequest(nmsg), ierr) @@ -5154,7 +5154,7 @@ subroutine ice_HaloUpdate4DI4(array, halo, & end do len = halo%SizeSend(nmsg)*nz*nt - call MPI_ISEND(bufSend(1:len,nmsg), len, MPI_INTEGER, & + call MPI_ISEND(bufSend(1,nmsg), len, MPI_INTEGER, & halo%sendTask(nmsg), & mpitagHalo + my_task, & halo%communicator, sndRequest(nmsg), ierr) @@ -5588,7 +5588,7 @@ subroutine ice_HaloUpdate_stress(array1, array2, halo, & do nmsg=1,halo%numMsgRecv len = halo%SizeRecv(nmsg) - call MPI_IRECV(bufRecvR8(1:len,nmsg), len, mpiR8, & + call MPI_IRECV(bufRecvR8(1,nmsg), len, mpiR8, & halo%recvTask(nmsg), & mpitagHalo + halo%recvTask(nmsg), & halo%communicator, rcvRequest(nmsg), ierr) @@ -5614,7 +5614,7 @@ subroutine ice_HaloUpdate_stress(array1, array2, halo, & end do len = halo%SizeSend(nmsg) - call MPI_ISEND(bufSendR8(1:len,nmsg), len, mpiR8, & + call MPI_ISEND(bufSendR8(1,nmsg), len, mpiR8, & halo%sendTask(nmsg), & mpitagHalo + my_task, & halo%communicator, sndRequest(nmsg), ierr) diff --git a/cicecore/cicedyn/infrastructure/ice_domain.F90 b/cicecore/cicedyn/infrastructure/ice_domain.F90 index 301120108..86d6a1939 100644 --- a/cicecore/cicedyn/infrastructure/ice_domain.F90 +++ b/cicecore/cicedyn/infrastructure/ice_domain.F90 @@ -79,8 +79,9 @@ module ice_domain ! 'cartesian', 'roundrobin', 'sectrobin', 'sectcart' ! 'rake', 'spacecurve', etc distribution_wght ! method for weighting work per block - ! 'block' = POP default configuration - ! 'blockall' = no land block elimination + ! 'block' = block weighted method with land block elimination + ! 'blockall' = block method with NO land block elimination and minimum weight given to land blocks + ! 'blockfull'= block method with NO land block elimination and full weight given to land blocks ! 'latitude' = no. ocean points * |lat| ! 'file' = read distribution_wgth_file character (char_len_long) :: & @@ -104,6 +105,7 @@ subroutine init_domain_blocks use ice_domain_size, only: ncat, nilyr, nslyr, max_blocks, & nx_global, ny_global, block_size_x, block_size_y use ice_fileunits, only: goto_nml + !---------------------------------------------------------------------- ! ! local variables @@ -476,7 +478,8 @@ subroutine init_domain_distribution(KMTG,ULATG,grid_ice) flat = 1 endif - if (distribution_wght == 'blockall') landblockelim = .false. + if (distribution_wght == 'blockall' ) landblockelim = .false. + if (distribution_wght == 'blockfull') landblockelim = .false. allocate(nocn(nblocks_tot)) @@ -579,8 +582,10 @@ subroutine init_domain_distribution(KMTG,ULATG,grid_ice) #ifdef CICE_IN_NEMO ! Keep all blocks even the ones only containing land points + ! tcraig, use 'blockfull', get rid of the CPP, keep for backwards compatibility for now if (distribution_wght == 'block') nocn(n) = nx_block*ny_block #else + if (distribution_wght == 'blockfull') nocn(n) = nx_block*ny_block if (distribution_wght == 'block' .and. nocn(n) > 0) nocn(n) = nx_block*ny_block if (.not. landblockelim) nocn(n) = max(nocn(n),1) #endif diff --git a/cicecore/cicedyn/infrastructure/ice_grid.F90 b/cicecore/cicedyn/infrastructure/ice_grid.F90 index a1dee3e33..d6f306c90 100644 --- a/cicecore/cicedyn/infrastructure/ice_grid.F90 +++ b/cicecore/cicedyn/infrastructure/ice_grid.F90 @@ -25,8 +25,8 @@ module ice_grid use ice_kinds_mod use ice_broadcast, only: broadcast_scalar, broadcast_array use ice_boundary, only: ice_HaloUpdate, ice_HaloExtrapolate - use ice_constants, only: c0, c1, c1p5, c2, c4, c20, c360, & - p5, p25, radius, cm_to_m, m_to_cm, & + use ice_constants, only: c0, c1, c1p5, c2, c4, c20, c180, c360, & + p5, p25, radius, cm_to_m, & field_loc_center, field_loc_NEcorner, field_loc_Nface, field_loc_Eface, & field_type_scalar, field_type_vector, field_type_angle use ice_communicate, only: my_task, master_task @@ -53,7 +53,7 @@ module ice_grid grid_neighbor_min, grid_neighbor_max character (len=char_len_long), public :: & - grid_format , & ! file format ('bin'=binary or 'nc'=netcdf) + grid_format , & ! file format ('bin'=binary or 'pop_nc'= pop netcdf or 'mom_nc'=mom (supergrid) netcdf) gridcpl_file , & ! input file for POP coupling grid info grid_file , & ! input file for POP grid info kmt_file , & ! input file for POP grid info @@ -108,7 +108,7 @@ module ice_grid ANGLE , & ! for conversions between POP grid and lat/lon ANGLET , & ! ANGLE converted to T-cells, valid in halo bathymetry , & ! ocean depth, for grounding keels and bergs (m) - ocn_gridcell_frac ! only relevant for lat-lon grids + ocn_gridcell_frac ! ocean gridcell fraction ! gridcell value of [1 - (land fraction)] (T-cell) real (kind=dbl_kind), dimension (:,:), allocatable, public :: & @@ -150,6 +150,7 @@ module ice_grid kmt ! ocean topography mask for bathymetry (T-cell) logical (kind=log_kind), public :: & + grid_outfile, & ! flag to write out one-time grid history file use_bathymetry, & ! flag for reading in bathymetry_file save_ghte_ghtn, & ! flag for saving global hte and htn during initialization scale_dxdy ! flag to apply scale factor to vary dx/dy in rectgrid @@ -160,6 +161,7 @@ module ice_grid umaskCD, & ! land/boundary mask (U-cell) (1 if at least two surrounding T cells are ocean) nmask , & ! land/boundary mask, (N-cell) emask , & ! land/boundary mask, (E-cell) + opmask , & ! land/boundary orphan mask, ocean cells in atmosphere but not ocean/ice lmask_n, & ! northern hemisphere mask lmask_s ! southern hemisphere mask @@ -172,7 +174,6 @@ module ice_grid character (len=char_len), private :: & mask_fieldname !field/var name for the mask variable (in nc files) - interface grid_average_X2Y module procedure grid_average_X2Y_base , & grid_average_X2Y_userwghts, & @@ -237,6 +238,7 @@ subroutine alloc_grid umaskCD (nx_block,ny_block,max_blocks), & ! land/boundary mask, velocity (U-cell) nmask (nx_block,ny_block,max_blocks), & ! land/boundary mask (N-cell) emask (nx_block,ny_block,max_blocks), & ! land/boundary mask (E-cell) + opmask (nx_block,ny_block,max_blocks), & ! land/boundary orphan mask (atm ocean/ice cell) lmask_n (nx_block,ny_block,max_blocks), & ! northern hemisphere mask lmask_s (nx_block,ny_block,max_blocks), & ! southern hemisphere mask rndex_global(nx_block,ny_block,max_blocks), & ! global index for local subdomain (dbl) @@ -251,6 +253,8 @@ subroutine alloc_grid stat=ierr) if (ierr/=0) call abort_ice(subname//' ERROR: Out of memory1', file=__FILE__, line=__LINE__) + ocn_gridcell_frac(:,:,:) = -c1 ! special value to start, will be ignored unless set elsewhere + if (save_ghte_ghtn) then if (my_task == master_task) then allocate( & @@ -269,7 +273,6 @@ subroutine alloc_grid end subroutine alloc_grid !======================================================================= - ! ! DeAllocate space for variables no longer needed after initialization ! @@ -287,7 +290,6 @@ subroutine dealloc_grid end subroutine dealloc_grid !======================================================================= - ! Distribute blocks across processors. The distribution is optimized ! based on latitude and topography, contained in the ULAT and KMT arrays. ! @@ -301,18 +303,19 @@ subroutine init_grid1 #endif integer (kind=int_kind) :: & - fid_grid, & ! file id for netCDF grid file - fid_kmt ! file id for netCDF kmt file + fid_grid, & ! file id for netCDF grid file + fid_kmt ! file id for netCDF kmt file character (char_len) :: & fieldname ! field name in netCDF file real (kind=dbl_kind), dimension(:,:), allocatable :: & - work_g1, work_g2 + work_g1, work_g2, work_mom integer (kind=int_kind) :: & max_blocks_min, & ! min value of max_blocks across procs - max_blocks_max ! max value of max_blocks across procs + max_blocks_max, & ! max value of max_blocks across procs + i, j, im, jm, ierr real (kind=dbl_kind) :: & rad_to_deg @@ -328,8 +331,12 @@ subroutine init_grid1 if (icepack_warnings_aborted()) call abort_ice(error_message=subname, & file=__FILE__, line=__LINE__) - allocate(work_g1(nx_global,ny_global)) - allocate(work_g2(nx_global,ny_global)) + allocate( & + work_g1(nx_global,ny_global), & + work_g2(nx_global,ny_global), & + stat=ierr & + ) + if (ierr/=0) call abort_ice(subname//' ERROR: Out of memory', file=__FILE__, line=__LINE__) ! check tripole flags here ! can't check in init_data because ns_boundary_type is not yet read @@ -346,57 +353,98 @@ subroutine init_grid1 file=__FILE__, line=__LINE__) endif + if (grid_format == 'mom_nc' .and. ns_boundary_type == 'tripoleT') then + call abort_ice(subname//" ERROR: ns_boundary_type='tripoleT' not implemented "// & + "for grid_format='mom_nc'. Use 'tripole' instead.", & + file=__FILE__, line=__LINE__) + endif + if (trim(grid_type) == 'displaced_pole' .or. & trim(grid_type) == 'tripole' .or. & - trim(grid_type) == 'regional' ) then + trim(grid_type) == 'regional') then - if (trim(grid_format) == 'nc') then + ! Fill ULAT + select case(trim(grid_format)) + case ('mom_nc') - fieldname='ulat' - call ice_open_nc(grid_file,fid_grid) - call ice_read_global_nc(fid_grid,1,fieldname,work_g1,.true.) - call ice_close_nc(fid_grid) - - ! mask variable name might be kmt or mask, check both - call ice_open_nc(kmt_file,fid_kmt) -#ifdef USE_NETCDF - if ( my_task==master_task ) then - status = nf90_inq_varid(fid_kmt, 'kmt', varid) - if (status == nf90_noerr) then - mask_fieldname = 'kmt' + if (my_task == master_task) then + allocate(work_mom(nx_global*2+1, ny_global*2+1), stat=ierr) else - status = nf90_inq_varid(fid_kmt, 'mask', varid) - call ice_check_nc(status, subname//' ERROR: does '//trim(kmt_file)//& - ' contain "kmt" or "mask" variable?', file=__FILE__, line=__LINE__) - mask_fieldname = 'mask' + allocate(work_mom(1, 1), stat=ierr) endif - endif -#endif - call broadcast_scalar(mask_fieldname, master_task) + if (ierr/=0) call abort_ice(subname//' ERROR: Out of memory', file=__FILE__, line=__LINE__) + + fieldname='y' ! use mom y field to fill cice ULAT + call ice_open_nc(grid_file,fid_grid) + call ice_read_global_nc(fid_grid,1,fieldname,work_mom,.true.) + call ice_close_nc(fid_grid) + im = 3 + do i = 1, nx_global + jm = 3 + do j = 1, ny_global + work_g1(i,j) = work_mom(im, jm) + jm = jm + 2 + enddo + im = im + 2 + enddo - call ice_read_global_nc(fid_kmt,1,mask_fieldname,work_g2,.true.) - call ice_close_nc(fid_kmt) + deallocate(work_mom, stat=ierr) + if (ierr/=0) call abort_ice(subname//' ERROR: Dealloc error', file=__FILE__, line=__LINE__) - else + case('pop_nc', 'geosnc') - call ice_open(nu_grid,grid_file,64) ! ULAT - call ice_open(nu_kmt, kmt_file, 32) ! KMT + fieldname='ulat' + call ice_open_nc(grid_file,fid_grid) + call ice_read_global_nc(fid_grid,1,fieldname,work_g1,.true.) + call ice_close_nc(fid_grid) - call ice_read_global(nu_grid,1,work_g1,'rda8',.true.) ! ULAT - call ice_read_global(nu_kmt, 1,work_g2,'ida4',.true.) ! KMT + case default - if (my_task == master_task) then - close (nu_grid) - close (nu_kmt) - endif + call ice_open(nu_grid,grid_file,64) + call ice_read_global(nu_grid,1,work_g1,'rda8',.true.) + if (my_task == master_task) close (nu_grid) - endif + end select else ! rectangular grid - work_g1(:,:) = 75._dbl_kind/rad_to_deg ! arbitrary polar latitude - work_g2(:,:) = c1 + endif + + ! Fill kmt + if (trim(kmt_type) =='file') then + select case(trim(grid_format)) + case ('mom_nc', 'pop_nc', 'geosnc') + + ! mask variable name might be kmt or mask, check both + call ice_open_nc(kmt_file,fid_kmt) +#ifdef USE_NETCDF + if ( my_task==master_task ) then + status = nf90_inq_varid(fid_kmt, 'kmt', varid) + if (status == nf90_noerr) then + mask_fieldname = 'kmt' + else + status = nf90_inq_varid(fid_kmt, 'mask', varid) + call ice_check_nc(status, subname//' ERROR: does '//trim(kmt_file)//& + ' contain "kmt" or "mask" variable?', file=__FILE__, line=__LINE__) + mask_fieldname = 'mask' + endif + endif +#endif + call broadcast_scalar(mask_fieldname, master_task) + + call ice_read_global_nc(fid_kmt,1,mask_fieldname,work_g2,.true.) + call ice_close_nc(fid_kmt) + + case default + + call ice_open(nu_kmt, kmt_file, 32) ! KMT + call ice_read_global(nu_kmt, 1,work_g2,'ida4',.true.) ! KMT + if (my_task == master_task) close (nu_kmt) + end select + + else + work_g2(:,:) = c1 endif call broadcast_array(work_g1, master_task) ! ULAT @@ -408,8 +456,8 @@ subroutine init_grid1 call init_domain_distribution(work_g2, work_g1, grid_ice) ! KMT, ULAT - deallocate(work_g1) - deallocate(work_g2) + deallocate(work_g1, work_g2, stat = ierr) + if (ierr/=0) call abort_ice(subname//' ERROR: Dealloc error', file=__FILE__, line=__LINE__) !----------------------------------------------------------------- ! write additional domain information @@ -429,7 +477,6 @@ subroutine init_grid1 end subroutine init_grid1 !======================================================================= - ! Horizontal grid initialization: ! ! U{LAT,LONG} = true {latitude,longitude} of U points @@ -449,12 +496,12 @@ subroutine init_grid2 #endif integer (kind=int_kind) :: & - i, j, iblk, & - ilo,ihi,jlo,jhi ! beginning and end of physical domain + i, j, iblk, & + ilo,ihi,jlo,jhi, & ! beginning and end of physical domain + ierr real (kind=dbl_kind) :: & - angle_0, angle_w, angle_s, angle_sw, & - pi, pi2, puny + angle_0, angle_w, angle_s, angle_sw, pi logical (kind=log_kind), dimension(nx_block,ny_block,max_blocks):: & out_of_range @@ -477,8 +524,8 @@ subroutine init_grid2 !----------------------------------------------------------------- l_readCenter = .false. + call icepack_query_parameters(pi_out=pi) - call icepack_query_parameters(pi_out=pi, pi2_out=pi2, puny_out=puny) call icepack_warnings_flush(nu_diag) if (icepack_warnings_aborted()) call abort_ice(error_message=subname, & file=__FILE__, line=__LINE__) @@ -486,13 +533,16 @@ subroutine init_grid2 if (trim(grid_type) == 'displaced_pole' .or. & trim(grid_type) == 'tripole' .or. & trim(grid_type) == 'regional' ) then - if (trim(grid_format) == 'nc') then - call kmtmask_nc ! read mask from nc file - call popgrid_nc ! read POP grid lengths from nc file - else - call kmtmask ! read kmt directly - call popgrid ! read POP grid lengths directly - endif + select case (trim(grid_format)) + case('mom_nc') + call mom_grid ! derive cice grid from MOM supergrid nc file + case ('pop_nc') + call popgrid_nc ! read POP grid lengths from nc file + case ('geosnc') + call geosgrid_nc ! read GEOS MOM grid used from nc file + case default + call popgrid ! read POP grid lengths directly + end select #ifdef CESMCOUPLED elseif (trim(grid_type) == 'latlon') then call latlongrid ! lat lon grid for sequential CESM (CAM mode) @@ -502,6 +552,18 @@ subroutine init_grid2 call rectgrid ! regular rectangular grid endif + if (trim(kmt_type) =='none') then + kmt(:,:,:) = c1 + hm(:,:,:) = c1 + else if (trim(kmt_type) =='file') then + select case (trim(grid_format)) + case('mom_nc', 'pop_nc' ,'geosnc') + call kmtmask('nc') + case default + call kmtmask('bin') + end select + endif ! the other types are handled by rectgrid + !----------------------------------------------------------------- ! Diagnose OpenMP thread schedule, force order in output !----------------------------------------------------------------- @@ -533,6 +595,27 @@ subroutine init_grid2 ! at halos. !----------------------------------------------------------------- + if (trim(grid_format) /= 'mom_nc') then + !$OMP PARALLEL DO PRIVATE(iblk,i,j,ilo,ihi,jlo,jhi,this_block) + do iblk = 1, nblocks + this_block = get_block(blocks_ice(iblk),iblk) + ilo = this_block%ilo + ihi = this_block%ihi + jlo = this_block%jlo + jhi = this_block%jhi + + do j = 1,ny_block + do i = 1,nx_block + tarea(i,j,iblk) = dxT(i,j,iblk)*dyT(i,j,iblk) + uarea(i,j,iblk) = dxU(i,j,iblk)*dyU(i,j,iblk) + narea(i,j,iblk) = dxN(i,j,iblk)*dyN(i,j,iblk) + earea(i,j,iblk) = dxE(i,j,iblk)*dyE(i,j,iblk) + enddo + enddo + enddo + !$OMP END PARALLEL DO + endif + !$OMP PARALLEL DO PRIVATE(iblk,i,j,ilo,ihi,jlo,jhi,this_block) do iblk = 1, nblocks this_block = get_block(blocks_ice(iblk),iblk) @@ -543,11 +626,6 @@ subroutine init_grid2 do j = 1,ny_block do i = 1,nx_block - tarea(i,j,iblk) = dxT(i,j,iblk)*dyT(i,j,iblk) - uarea(i,j,iblk) = dxU(i,j,iblk)*dyU(i,j,iblk) - narea(i,j,iblk) = dxN(i,j,iblk)*dyN(i,j,iblk) - earea(i,j,iblk) = dxE(i,j,iblk)*dyE(i,j,iblk) - if (tarea(i,j,iblk) > c0) then tarear(i,j,iblk) = c1/tarea(i,j,iblk) else @@ -616,8 +694,7 @@ subroutine init_grid2 call ice_timer_stop(timer_bound) !----------------------------------------------------------------- - ! Calculate ANGLET to be compatible with POP ocean model - ! First, ensure that -pi <= ANGLE <= pi + ! Ensure that -pi <= ANGLE <= pi !----------------------------------------------------------------- out_of_range = .false. @@ -673,7 +750,8 @@ subroutine init_grid2 !$OMP END PARALLEL DO endif - if (trim(grid_type) == 'regional' .and. & + if ((trim(grid_type) == 'regional' .or. & + trim(grid_type) == 'rectangular') .and. & (.not. (l_readCenter))) then ! for W boundary extrapolate from interior !$OMP PARALLEL DO PRIVATE(iblk,i,j,ilo,ihi,jlo,jhi,this_block) @@ -701,10 +779,21 @@ subroutine init_grid2 call ice_timer_stop(timer_bound) call makemask ! velocity mask, hemisphere masks - if (.not. (l_readCenter)) then - call Tlatlon ! get lat, lon on the T grid + + !---------------------------------------------------------------- + ! Coordinates for all T/N/E cells + !---------------------------------------------------------------- + + if (trim(grid_format) /= 'mom_nc') then + if (.not. (l_readCenter)) then + call Tlatlon ! get lat, lon on the T grid + endif + call NElatlon ! get lat, lon on the N, E grid + + ! corners for CF-compliant output + call gridbox_corners + call gridbox_edges endif - call NElatlon ! get lat, lon on the N, E grid !----------------------------------------------------------------- ! bathymetry @@ -719,70 +808,82 @@ subroutine init_grid2 file=__FILE__, line=__LINE__) endif - !---------------------------------------------------------------- - ! Corner coordinates for CF compliant history files - !---------------------------------------------------------------- - - call gridbox_corners - call gridbox_edges - !----------------------------------------------------------------- ! Compute global index (used for unpacking messages from coupler) !----------------------------------------------------------------- if (my_task==master_task) then - allocate(work_g1(nx_global,ny_global)) + allocate(work_g1(nx_global,ny_global), stat=ierr) + if (ierr/=0) call abort_ice(subname//' ERROR: Out of memory', file=__FILE__, line=__LINE__) do j=1,ny_global do i=1,nx_global work_g1(i,j) = real((j-1)*nx_global + i,kind=dbl_kind) enddo enddo else - allocate(work_g1(1,1)) ! to save memory + allocate(work_g1(1,1), stat=ierr) ! to save memory + if (ierr/=0) call abort_ice(subname//' ERROR: Out of memory', file=__FILE__, line=__LINE__) endif call scatter_global(rndex_global, work_g1, & master_task, distrb_info, & field_loc_center, field_type_scalar) - deallocate(work_g1) + deallocate(work_g1, stat=ierr) + if (ierr/=0) call abort_ice(subname//' ERROR: Dealloc error', file=__FILE__, line=__LINE__) end subroutine init_grid2 !======================================================================= - ! POP land mask ! Land mask record number and field is (1) KMT. - subroutine kmtmask + subroutine kmtmask(filetype) + + character(len=*), intent(in) :: & + filetype ! 'nc' or 'bin' integer (kind=int_kind) :: & i, j, iblk, & - ilo,ihi,jlo,jhi ! beginning and end of physical domain + ilo,ihi,jlo,jhi ! beginning and end of physical domain + + integer (kind=int_kind) :: & + fid_kmt ! file id for netCDF kmt file logical (kind=log_kind) :: diag - real (kind=dbl_kind), dimension (nx_block,ny_block,max_blocks) :: & - work1 + real (kind=dbl_kind) :: & + puny type (block) :: & - this_block ! block information for current block + this_block ! block information for current block character(len=*), parameter :: subname = '(kmtmask)' - call ice_open(nu_kmt,kmt_file,32) + call icepack_query_parameters(puny_out=puny) diag = .true. ! write diagnostic info - !----------------------------------------------------------------- - ! topography - !----------------------------------------------------------------- kmt(:,:,:) = c0 hm (:,:,:) = c0 - call ice_read(nu_kmt,1,kmt,'ida4',diag, & - field_loc=field_loc_center, & - field_type=field_type_scalar) + if (filetype == 'bin') then + call ice_open(nu_kmt,kmt_file,32) + call ice_read(nu_kmt,1,kmt,'ida4',diag, & + field_loc=field_loc_center, & + field_type=field_type_scalar) + if (my_task == master_task) then + close (nu_kmt) + endif + elseif (filetype == 'nc') then + call ice_open_nc(kmt_file,fid_kmt) + call ice_read_nc(fid_kmt,1,mask_fieldname,kmt,diag, & + field_loc=field_loc_center, & + field_type=field_type_scalar) + call ice_close_nc(fid_kmt) + else + call abort_ice(subname//' ERROR: invalid filetype='//trim(filetype), file=__FILE__, line=__LINE__) + endif !$OMP PARALLEL DO PRIVATE(iblk,i,j,ilo,ihi,jlo,jhi,this_block) do iblk = 1, nblocks @@ -794,20 +895,20 @@ subroutine kmtmask do j = jlo, jhi do i = ilo, ihi + ! force grid cells to land if ocn_gridcell_frac is defined + if (ocn_gridcell_frac(i,j,iblk) >= c0 .and. & + ocn_gridcell_frac(i,j,iblk) < puny) then + kmt(i,j,iblk) = c0 + endif if (kmt(i,j,iblk) >= p5) hm(i,j,iblk) = c1 enddo enddo enddo !$OMP END PARALLEL DO - if (my_task == master_task) then - close (nu_kmt) - endif - end subroutine kmtmask !======================================================================= - ! POP displaced pole grid (or tripole). ! Grid record number, field and units are: \\ ! (1) ULAT (radians) \\ @@ -827,6 +928,8 @@ subroutine popgrid real (kind=dbl_kind), dimension(:,:), allocatable :: & work_g1 + integer (int_kind) :: ierr + character(len=*), parameter :: subname = '(popgrid)' call ice_open(nu_grid,grid_file,64) @@ -837,7 +940,8 @@ subroutine popgrid ! lat, lon, angle !----------------------------------------------------------------- - allocate(work_g1(nx_global,ny_global)) + allocate(work_g1(nx_global,ny_global), stat=ierr) + if (ierr/=0) call abort_ice(subname//' ERROR: Out of memory', file=__FILE__, line=__LINE__) call ice_read_global(nu_grid,1,work_g1,'rda8',.true.) ! ULAT call gridbox_verts(work_g1,latt_bounds) @@ -869,7 +973,8 @@ subroutine popgrid call ice_read_global(nu_grid,4,work_g1,'rda8',.true.) ! HTE call primary_grid_lengths_HTE(work_g1) ! dyU, dyT, dyN, dyE - deallocate(work_g1) + deallocate(work_g1, stat=ierr) + if (ierr/=0) call abort_ice(subname//' ERROR: Dealloc error', file=__FILE__, line=__LINE__) if (my_task == master_task) then close (nu_grid) @@ -878,60 +983,6 @@ subroutine popgrid end subroutine popgrid !======================================================================= - -! POP/MOM land mask. -! Land mask field is kmt or mask, saved in mask_fieldname. - - subroutine kmtmask_nc - - integer (kind=int_kind) :: & - i, j, iblk, & - ilo,ihi,jlo,jhi, & ! beginning and end of physical domain - fid_kmt ! file id for netCDF kmt file - - logical (kind=log_kind) :: diag - - real (kind=dbl_kind), dimension (nx_block,ny_block,max_blocks) :: & - work1 - - type (block) :: & - this_block ! block information for current block - - character(len=*), parameter :: subname = '(kmtmask_nc)' - - diag = .true. ! write diagnostic info - - hm (:,:,:) = c0 - kmt(:,:,:) = c0 - - call ice_open_nc(kmt_file,fid_kmt) - - call ice_read_nc(fid_kmt,1,mask_fieldname,kmt,diag, & - field_loc=field_loc_center, & - field_type=field_type_scalar) - - call ice_close_nc(fid_kmt) - - !$OMP PARALLEL DO PRIVATE(iblk,i,j,ilo,ihi,jlo,jhi,this_block) - do iblk = 1, nblocks - this_block = get_block(blocks_ice(iblk),iblk) - ilo = this_block%ilo - ihi = this_block%ihi - jlo = this_block%jlo - jhi = this_block%jhi - - do j = jlo, jhi - do i = ilo, ihi - if (kmt(i,j,iblk) >= c1) hm(i,j,iblk) = c1 - enddo - enddo - enddo - !$OMP END PARALLEL DO - - end subroutine kmtmask_nc - -!======================================================================= - ! POP displaced pole grid and land mask. ! Grid record number, field and units are: \\ ! (1) ULAT (radians) \\ @@ -948,13 +999,15 @@ end subroutine kmtmask_nc subroutine popgrid_nc #ifdef USE_NETCDF - use netcdf + use netcdf, only : nf90_inq_varid , nf90_inq_dimid, & + nf90_inquire_dimension, nf90_get_var, nf90_noerr #endif integer (kind=int_kind) :: & i, j, iblk, & ilo,ihi,jlo,jhi, & ! beginning and end of physical domain - fid_grid ! file id for netCDF grid file + fid_grid , & ! file id for netCDF grid file + ierr logical (kind=log_kind) :: diag @@ -986,7 +1039,8 @@ subroutine popgrid_nc ! lat, lon, angle !----------------------------------------------------------------- - allocate(work_g1(nx_global,ny_global)) + allocate(work_g1(nx_global,ny_global), stat=ierr) + if (ierr/=0) call abort_ice(subname//' ERROR: Out of memory', file=__FILE__, line=__LINE__) fieldname='ulat' call ice_read_global_nc(fid_grid,1,fieldname,work_g1,diag) ! ULAT @@ -1015,7 +1069,7 @@ subroutine popgrid_nc ! if grid file includes anglet then read instead fieldname='anglet' if (my_task == master_task) then - status = nf90_inq_varid(fid_grid, trim(fieldname) , varid) + status = nf90_inq_varid(fid_grid, fieldname , varid) if (status /= nf90_noerr) then write(nu_diag,*) subname//' CICE will calculate angleT, TLON and TLAT' else @@ -1052,7 +1106,8 @@ subroutine popgrid_nc call ice_read_global_nc(fid_grid,1,fieldname,work_g1,diag) ! HTE call primary_grid_lengths_HTE(work_g1) ! dyU, dyT, dyN, dyE - deallocate(work_g1) + deallocate(work_g1, stat=ierr) + if (ierr/=0) call abort_ice(subname//' ERROR: Dealloc error', file=__FILE__, line=__LINE__) call ice_close_nc(fid_grid) @@ -1065,7 +1120,6 @@ end subroutine popgrid_nc #ifdef CESMCOUPLED !======================================================================= - ! Read in kmt file that matches CAM lat-lon grid and has single column ! functionality ! author: Mariana Vertenstein @@ -1075,7 +1129,8 @@ subroutine latlongrid use ice_scam, only : scmlat, scmlon, single_column #ifdef USE_NETCDF - use netcdf + use netcdf, only : nf90_inq_varid , nf90_inq_dimid, & + nf90_inquire_dimension, nf90_get_var #endif integer (kind=int_kind) :: & @@ -1113,7 +1168,6 @@ subroutine latlongrid real (kind=dbl_kind) :: & pos_scmlon,& ! temporary pi, & - puny, & scamdata ! temporary character(len=*), parameter :: subname = '(lonlatgrid)' @@ -1126,7 +1180,7 @@ subroutine latlongrid ! - Read in ocean from "kmt" file (1 for ocean, 0 for land) !----------------------------------------------------------------- - call icepack_query_parameters(pi_out=pi, puny_out=puny) + call icepack_query_parameters(pi_out=pi) call icepack_warnings_flush(nu_diag) if (icepack_warnings_aborted()) call abort_ice(error_message=subname, & file=__FILE__, line=__LINE__) @@ -1242,11 +1296,653 @@ subroutine latlongrid call ice_read_nc(ncid, 1, 'frac', ocn_gridcell_frac, diag=.true.) end if - if (my_task == master_task) then - call ice_close_nc(ncid) - end if + if (my_task == master_task) then + call ice_close_nc(ncid) + end if + + !$OMP PARALLEL DO PRIVATE(iblk,this_block,ilo,ihi,jlo,jhi,i,j) + do iblk = 1, nblocks + this_block = get_block(blocks_ice(iblk),iblk) + ilo = this_block%ilo + ihi = this_block%ihi + jlo = this_block%jlo + jhi = this_block%jhi + + do j = jlo, jhi + do i = ilo, ihi + ! Convert from degrees to radians + TLON(i,j,iblk) = pi*TLON(i,j,iblk)/180._dbl_kind + + ! Convert from degrees to radians + TLAT(i,j,iblk) = pi*TLAT(i,j,iblk)/180._dbl_kind + + ! Convert from radians^2 to m^2 + ! (area in domain file is in radians^2 and tarea is in m^2) + tarea(i,j,iblk) = tarea(i,j,iblk) * (radius*radius) + end do + end do + end do + !$OMP END PARALLEL DO + + !----------------------------------------------------------------- + ! Calculate various geometric 2d arrays + ! The U grid (velocity) is not used when run with sequential CAM + ! because we only use thermodynamic sea ice. However, ULAT is used + ! in the default initialization of CICE so we calculate it here as + ! a "dummy" so that CICE will initialize with ice. If a no ice + ! initialization is OK (or desired) this can be commented out and + ! ULAT will remain 0 as specified above. ULAT is located at the + ! NE corner of the grid cell, TLAT at the center, so here ULAT is + ! hacked by adding half the latitudinal spacing (in radians) to + ! TLAT. + !----------------------------------------------------------------- + + !$OMP PARALLEL DO PRIVATE(iblk,this_block,ilo,ihi,jlo,jhi,i,j) + do iblk = 1, nblocks + this_block = get_block(blocks_ice(iblk),iblk) + ilo = this_block%ilo + ihi = this_block%ihi + jlo = this_block%jlo + jhi = this_block%jhi + + do j = jlo, jhi + do i = ilo, ihi + + if (ny_global == 1) then + uarea(i,j,iblk) = tarea(i,j, iblk) + else + uarea(i,j,iblk) = p25* & + (tarea(i,j, iblk) + tarea(i+1,j, iblk) & + + tarea(i,j+1,iblk) + tarea(i+1,j+1,iblk)) + endif + tarear(i,j,iblk) = c1/tarea(i,j,iblk) + uarear(i,j,iblk) = c1/uarea(i,j,iblk) + + if (single_column) then + ULAT (i,j,iblk) = TLAT(i,j,iblk)+(pi/nj) + else + if (ny_global == 1) then + ULAT (i,j,iblk) = TLAT(i,j,iblk) + else + ULAT (i,j,iblk) = TLAT(i,j,iblk)+(pi/ny_global) + endif + endif + ULON (i,j,iblk) = c0 + NLON (i,j,iblk) = c0 + NLAT (i,j,iblk) = c0 + ELON (i,j,iblk) = c0 + ELAT (i,j,iblk) = c0 + ANGLE (i,j,iblk) = c0 + + ANGLET(i,j,iblk) = c0 + HTN (i,j,iblk) = 1.e36_dbl_kind + HTE (i,j,iblk) = 1.e36_dbl_kind + dxT (i,j,iblk) = 1.e36_dbl_kind + dyT (i,j,iblk) = 1.e36_dbl_kind + dxU (i,j,iblk) = 1.e36_dbl_kind + dyU (i,j,iblk) = 1.e36_dbl_kind + dxN (i,j,iblk) = 1.e36_dbl_kind + dyN (i,j,iblk) = 1.e36_dbl_kind + dxE (i,j,iblk) = 1.e36_dbl_kind + dyE (i,j,iblk) = 1.e36_dbl_kind + enddo + enddo + enddo + !$OMP END PARALLEL DO + + call makemask +#else + call abort_ice(subname//' ERROR: USE_NETCDF cpp not defined', & + file=__FILE__, line=__LINE__) +#endif + + end subroutine latlongrid +#endif + +!======================================================================= +! Create the CICE grid from the MOM supergrid netcdf file. +! CICE fields and units are: +! ULAT, ULON, TLAT, TLON, ELAT, ELON, NLAT, NLON (radians) +! HTN, HTE (m) +! dxT, dyT, dxU, dyU, dxN, dyN, dxE, dyE, (m) +! ANGLE, ANGLET (radians) +! tarea, uarea, narea, earea (m^2) +! lont_bounds, latt_bounds, etc (degrees) + + subroutine mom_grid + + integer (kind=int_kind) :: & + fid_grid, & ! file id for netCDF grid file + varid, & ! netcdf varid + ierr + + logical (kind=log_kind) :: diag + + character (char_len) :: & + fieldname ! field name in netCDF file + + real (kind=dbl_kind), dimension(:,:), allocatable :: & + G_TLON, work_gE, G_ULON, work_gN, work_mom, G_ULAT, G_TLAT, work_g1 + + character(len=*), parameter :: subname = '(mom_grid)' + + call ice_open_nc(grid_file,fid_grid) + + !----------------------------------------------------------------- + ! lat, lon, angle + !----------------------------------------------------------------- + + if (my_task == master_task) then + allocate( & + work_mom(nx_global*2+1, ny_global*2+1), & + work_gE(nx_global+1,ny_global+1) , & + work_gN(nx_global+1,ny_global+1) , & + G_ULAT(nx_global+1,ny_global+1) , & !include left and bottom + G_TLAT(nx_global+1,ny_global+1) , & !include top and right + G_TLON(nx_global+1,ny_global+1) , & !include left and bottom + G_ULON(nx_global+1,ny_global+1) , & !include top and right + stat = ierr & + ) + else + allocate(work_mom(1,1), work_gE(1,1), work_gN(1,1), & + G_ULAT(1,1), G_TLAT(1,1), G_TLON(1,1), G_ULON(1,1), & + stat=ierr) + endif + if (ierr/=0) call abort_ice(subname//' ERROR: Out of memory', file=__FILE__, line=__LINE__) + + ! populate all LAT fields + fieldname='y' + call ice_read_global_nc(fid_grid,1,fieldname,work_mom,diag) + call mom_corners_global(work_mom, G_ULAT, G_TLAT, work_gE, work_gN) + ! create bounds fields for cf-compliant output + call mom_bounds(G_ULAT, latt_bounds) ! u points define corners for t-cells + call mom_bounds(G_TLAT, latu_bounds) + call mom_bounds(work_gN, late_bounds) + call mom_bounds(work_gE, latn_bounds) + !distribute global array to local + call mom_corners_scatter(G_ULAT, G_TLAT, work_gE, work_gN, & + ULAT, TLAT, ELAT, NLAT) + + ! populate all LON fields + fieldname='x' + call ice_read_global_nc(fid_grid,1,fieldname,work_mom,diag) + call mom_corners_global(work_mom, G_ULON, G_TLON, work_gE, work_gN) + call mom_bounds(G_ULON, lont_bounds) + call mom_bounds(G_TLON, lonu_bounds) + call mom_bounds(work_gN, lone_bounds) + call mom_bounds(work_gE, lonn_bounds) + call mom_corners_scatter(G_ULON, G_TLON, work_gE, work_gN, & + ULON, TLON, ELON, NLON) + + deallocate(work_gE, work_gN, stat=ierr) + if (ierr/=0) call abort_ice(subname//' ERROR: Dealloc error', file=__FILE__, line=__LINE__) + if (my_task == master_task) then + allocate(work_g1(nx_global, ny_global), stat=ierr) !array for angle field + else + allocate(work_g1(1, 1), stat=ierr) + endif + if (ierr/=0) call abort_ice(subname//' ERROR: Out of memory', file=__FILE__, line=__LINE__) + + ! populate angle fields, angle is u-points, angleT is t-points + ! even though mom supergrid files contain angle_dx, mom6 calculates internally + call mom_grid_rotation_angle(G_ULON, G_ULAT, G_TLON(1:nx_global,1:ny_global), work_g1) ! anglet + call scatter_global(ANGLET, work_g1, master_task, distrb_info, & + field_loc_center, field_type_angle) + call mom_grid_rotation_angle(G_TLON, G_TLAT, G_ULON(2:nx_global+1,2:ny_global+1), work_g1) ! angle + call scatter_global(ANGLE, work_g1, master_task, distrb_info, & + field_loc_NEcorner, field_type_angle) + + deallocate(work_g1, G_ULAT, G_TLAT, G_TLON, G_ULON, stat=ierr) + if (ierr/=0) call abort_ice(subname//' ERROR: Dealloc error', file=__FILE__, line=__LINE__) + + !----------------------------------------------------------------- + ! cell dimensions + !----------------------------------------------------------------- + fieldname='dx' + ! dx uses the cells in x, edges in y, reallocate work_mom to this size + deallocate(work_mom, stat=ierr) + if (ierr/=0) call abort_ice(subname//' ERROR: Dealloc error', file=__FILE__, line=__LINE__) + if (my_task == master_task) then + allocate(work_mom(nx_global*2, ny_global*2+1), stat=ierr) + else + allocate(work_mom(1, 1), stat=ierr) + endif + if (ierr/=0) call abort_ice(subname//' ERROR: Out of memory', file=__FILE__, line=__LINE__) + + call ice_read_global_nc(fid_grid,1,fieldname,work_mom,diag) + call mom_dx(work_mom) + deallocate(work_mom, stat=ierr) + if (ierr/=0) call abort_ice(subname//' ERROR: Dealloc error', file=__FILE__, line=__LINE__) + + fieldname='dy' + ! dy uses the edges in x, cells in y, reallocate work_mom to this size + if (my_task == master_task) then + allocate(work_mom(nx_global*2+1, ny_global*2), stat=ierr) + else + allocate(work_mom(1, 1), stat=ierr) + endif + if (ierr/=0) call abort_ice(subname//' ERROR: Out of memory', file=__FILE__, line=__LINE__) + + call ice_read_global_nc(fid_grid,1,fieldname,work_mom,diag) + call mom_dy(work_mom) + deallocate(work_mom, stat=ierr) + if (ierr/=0) call abort_ice(subname//' ERROR: Dealloc error', file=__FILE__, line=__LINE__) + + + !----------------------------------------------------------------- + ! cell areas + !----------------------------------------------------------------- + fieldname = 'area' + if (my_task == master_task) then + allocate(work_mom(nx_global*2, ny_global*2), stat=ierr) + else + allocate(work_mom(1, 1), stat=ierr) + endif + if (ierr/=0) call abort_ice(subname//' ERROR: Out of memory', file=__FILE__, line=__LINE__) + + call ice_read_global_nc(fid_grid,1,fieldname,work_mom,diag) + call mom_area(work_mom) + deallocate(work_mom, stat=ierr) + if (ierr/=0) call abort_ice(subname//' ERROR: Dealloc', file=__FILE__, line=__LINE__) + + !----------------------------------------------------------------- + ! fin + !----------------------------------------------------------------- + call ice_close_nc(fid_grid) + l_readCenter = .true. ! we have read t quantities + + end subroutine mom_grid + +!======================================================================= + + subroutine mom_corners_global(work_mom, G_U, G_T, G_E, G_N) + + ! mom supergrid has four cells for every model cell + ! we need to select the correct edges to get lat & lon for a model cell + ! we include left/bottom edges for U-points, and top/right edges for T-points + ! and close per ew_boundary_type & ns_boundary_type + + real (kind=dbl_kind), dimension(:,:), intent(in) :: work_mom + ! supergrid array of x or y + + real (kind=dbl_kind), dimension(:,:), intent(out) :: G_U, G_T, G_E, G_N + ! global grids + + integer (kind=int_kind) :: & + i, j, & + im1, im2, jm1, jm2 ! i & j for mom supergrid + + character(len=*), parameter :: subname = '(mom_corners_global)' + + if (my_task == master_task) then + + im1 = 1 ; im2 = 2 ! lh , middle hand edge of first col + do i = 1, nx_global + jm1 = 1; jm2 = 2 ! bottom, middle of first row + do j = 1, ny_global + G_U(i,j) = work_mom(im1, jm1) ! ULAT/LON + G_N(i,j) = work_mom(im2, jm1) ! NLAT/LON + G_E(i,j) = work_mom(im1, jm2) ! ELAT/LON + G_T(i,j) = work_mom(im2, jm2) ! TLAT/LON + jm1 = jm1 + 2 ; jm2 = jm2 + 2 + enddo + im1 = im1 + 2 ; im2 = im2 + 2 + enddo + + ! fill last col + jm1 = 1; jm2 = 2 ! bottom, middle of first row + do j = 1, ny_global + G_U(nx_global+1,j) = work_mom(2*nx_global+1, jm1) + G_E(nx_global+1,j) = work_mom(2*nx_global+1, jm2) + jm1 = jm1 + 2 ; jm2 = jm2 + 2 + enddo + select case (trim(ew_boundary_type)) + case('cyclic') + G_T(nx_global+1,:) = G_T(1,:) + G_N(nx_global+1,:) = G_N(1,:) + case('open') + do j=1, ny_global+1 + G_T(nx_global+1,j) = 2 * G_T(nx_global, j) - G_T(nx_global-1, j) + G_N(nx_global+1,j) = 2 * G_N(nx_global, j) - G_N(nx_global-1, j) + enddo + end select + + ! fill last row + im1 = 1 ; im2 = 2 + do i = 1, nx_global+1 + G_U(i,ny_global + 1) = work_mom(im1, 2*ny_global+1) + G_N(i,ny_global + 1) = work_mom(im2, 2*ny_global+1) + im1 = im1 + 2 + enddo + select case (trim(ns_boundary_type)) + case ('tripole') + do i = 1, nx_global+1 + G_T(i,ny_global+1) = G_T(nx_global+1-i, ny_global) + G_E(i,ny_global+1) = G_E(nx_global+1-i, ny_global) + enddo + case ('cyclic') + G_T(:,ny_global+1) = G_T(:,1) + G_E(:,ny_global+1) = G_E(:,1) + case ('open') + do i = 1, nx_global+1 + G_T(i,ny_global+1) = 2 * G_T(i, ny_global) - G_T(i, ny_global-1) + G_E(i,ny_global+1) = 2 * G_E(i, ny_global) - G_E(i, ny_global-1) + enddo + end select + + endif + + end subroutine mom_corners_global + +!======================================================================= + + subroutine mom_bounds(G_corners, bounds) + + ! with an global array of corner points, subset and distribute + ! into a cice bounds variables + ! e.g. The tracer coordinates are the corner of the u-cells, + ! so use mom_bounds(G_TLON, lonu_bounds) + + real (kind=dbl_kind), dimension(:,:), intent(in) :: G_corners + real (kind=dbl_kind), dimension(:,:,:,:), intent(out) :: bounds + + ! local vars + + real (kind=dbl_kind), dimension (nx_block,ny_block,max_blocks) :: & + work_bounds + + character(len=*), parameter :: subname = '(mom_bounds)' + + ! Get bounds of grid boxes for each block as follows: + ! (1) SW corner, (2) SE corner, (3) NE corner, (4) NW corner + call scatter_global(work_bounds, G_corners(1:nx_global, 1:ny_global), & + master_task, distrb_info, & + field_loc_NEcorner, field_type_scalar) + bounds(1,:,:,:) = work_bounds(:,:,:) + call scatter_global(work_bounds, G_corners(2:nx_global+1, 1:ny_global), & + master_task, distrb_info, & + field_loc_NEcorner, field_type_scalar) + bounds(2,:,:,:) = work_bounds(:,:,:) + call scatter_global(work_bounds, G_corners(2:nx_global+1, 2:ny_global+1), & + master_task, distrb_info, & + field_loc_NEcorner, field_type_scalar) + bounds(3,:,:,:) = work_bounds(:,:,:) + call scatter_global(work_bounds, G_corners(1:nx_global, 2:ny_global+1), & + master_task, distrb_info, & + field_loc_NEcorner, field_type_scalar) + bounds(4,:,:,:) = work_bounds(:,:,:) + + end subroutine mom_bounds + +!======================================================================= + + subroutine mom_corners_scatter(G_U, G_T, G_E, G_N, U, T, E, N ) + + ! with a global array of corner points in degrees, convert to rad and scatter to workers + + real (kind=dbl_kind), dimension(:,:), intent(inout) :: G_U, G_T, G_E, G_N + ! global grids + + real (kind=dbl_kind), dimension(:,:,:), intent(out) :: U, T, E, N ! local grids + + real (kind=dbl_kind) :: deg_to_rad , pi + + character(len=*), parameter :: subname = '(mom_corners_scatter)' + + call icepack_query_parameters(pi_out=pi) + call icepack_warnings_flush(nu_diag) + if (icepack_warnings_aborted()) call abort_ice(error_message=subname, & + file=__FILE__, line=__LINE__) + + deg_to_rad = pi/c180 + + ! convert to rad + G_T = G_T * deg_to_rad + G_U = G_U * deg_to_rad + G_N = G_N * deg_to_rad + G_E = G_E * deg_to_rad + + ! distribute to processors + ! subset G_T to active cells by dropping right/top halo + call scatter_global(T, G_T(1:nx_global, 1:ny_global), & + master_task, distrb_info, & + field_loc_center, field_type_scalar) + call ice_HaloExtrapolate(T, distrb_info, & + ew_boundary_type, ns_boundary_type) + ! subset G_U/G_E/G_N to active cells by dropping left/bottom edge + call scatter_global(U, G_U(2:nx_global+1, 2:ny_global+1), & + master_task, distrb_info, & + field_loc_NEcorner, field_type_scalar) + call ice_HaloExtrapolate(U, distrb_info, & + ew_boundary_type, ns_boundary_type) + call scatter_global(N, G_N(1:nx_global, 2:ny_global+1), master_task, distrb_info, & + field_loc_Nface, field_type_scalar) + call ice_HaloExtrapolate(N, distrb_info, & + ew_boundary_type, ns_boundary_type) + call scatter_global(E, G_E(2:nx_global+1, 1:ny_global), master_task, distrb_info, & + field_loc_Eface, field_type_scalar) + call ice_HaloExtrapolate(E, distrb_info, & + ew_boundary_type, ns_boundary_type) + + end subroutine mom_corners_scatter + +!======================================================================= + + subroutine mom_dx(work_mom) + + ! mom supergrid has four cells for every model cell, sum the sidelengths to get model dx + + real (kind=dbl_kind), dimension(:,:) :: work_mom + + real (kind=dbl_kind), dimension(:,:), allocatable :: & + G_dxT, G_dxN, G_dxE, G_dxU + + integer (kind=int_kind) :: & + i, j , & + im1, im2, jm1, jm2, im3, jm3 , & ! i & j for mom supergrid + ierr + + character(len=*), parameter :: subname = '(mom_dx)' + + if (my_task == master_task) then + allocate( & + G_dxT(nx_global,ny_global), & + G_dxN(nx_global,ny_global), & + G_dxE(nx_global,ny_global), & + G_dxU(nx_global,ny_global), & + stat=ierr & + ) + else + allocate(G_dxT(1,1), G_dxE(1,1), G_dxU(1,1), G_dxN(1,1), stat=ierr) + endif + if (ierr/=0) call abort_ice(subname//' ERROR: Out of memory', file=__FILE__, line=__LINE__) + + if (my_task == master_task) then + im1 = 1 ; im2 = 2 ! left ; center column of first t-cell + im3 = 3 ! left column of second T-cell, (ie right column of U-cell) + do i = 1, nx_global - 1 + jm1 = 2 ; jm2 = 3 ! middle , top of first row + do j = 1, ny_global + G_dxT(i,j) = work_mom(im1, jm1) + work_mom(im2, jm1) !dxT + G_dxN(i,j) = work_mom(im1, jm2) + work_mom(im2, jm2) !dxN + G_dxE(i,j) = work_mom(im2, jm1) + work_mom(im3, jm1) !dxE + G_dxU(i,j) = work_mom(im2, jm2) + work_mom(im3, jm2) !dxU + jm1 = jm1 + 2 ; jm2 = jm2 + 2 + enddo + im1 = im1 + 2 ; im2 = im2 + 2 ; im3 = im3 + 2 + enddo + + ! fill the last col + jm1 = 2 ; jm2 = 3 ! middle , top of first row + do j = 1, ny_global + G_dxT(nx_global,j) = work_mom(2*nx_global - 1, jm1) + work_mom(2*nx_global, jm1) !dxT + G_dxN(nx_global,j) = work_mom(2*nx_global - 1, jm2) + work_mom(2*nx_global, jm2) !dxN + jm1 = jm1 + 2 ; jm2 = jm2 + 2 + enddo + jm1 = 2 ; jm2 = 3 ! middle , top of first row + if (trim(ew_boundary_type) == 'cyclic') then + do j = 1, ny_global + G_dxE(nx_global,j) = work_mom(2*nx_global, jm1) + work_mom(1, jm1) !dxE + G_dxU(nx_global,j) = work_mom(2*nx_global, jm2) + work_mom(1, jm2) !dxU + jm1 = jm1 + 2 ; jm2 = jm2 + 2 + enddo + else if (trim(ew_boundary_type) == 'open') then + do j = 1, ny_global + G_dxE(nx_global,j) = 4*work_mom(2*nx_global, jm1) - 2*work_mom(2*nx_global-1, jm1) !dxE + G_dxU(nx_global,j) = 4*work_mom(2*nx_global, jm2) - 2*work_mom(2*nx_global-1, jm2) !dxU + jm1 = jm1 + 2 ; jm2 = jm2 + 2 + enddo + endif + + if (save_ghte_ghtn) then + do j = 1, ny_global + do i = 1, nx_global + G_HTN(i+nghost,j+nghost) = G_dxN(i,j) + enddo + enddo + call global_ext_halo(G_HTN) + endif + endif + + call scatter_global(dxT, G_dxT, master_task, distrb_info, & + field_loc_center, field_type_scalar) + call scatter_global(HTN, G_dxN, master_task, distrb_info, & + field_loc_Nface, field_type_scalar) + dxN(:,:,:) = HTN(:,:,:) + call scatter_global(dxE, G_dxE, master_task, distrb_info, & + field_loc_center, field_type_scalar) + call scatter_global(dxU, G_dxU, master_task, distrb_info, & + field_loc_NEcorner, field_type_scalar) + + deallocate(G_dxT, G_dxE, G_dxU, G_dxN, stat=ierr) + if (ierr/=0) call abort_ice(subname//' ERROR: Dealloc error', file=__FILE__, line=__LINE__) + + end subroutine mom_dx + +!======================================================================= + + subroutine mom_dy(work_mom) + + ! mom supergrid has four cells for every model cell, sum the sidelengths to get model dy + + real (kind=dbl_kind), dimension(:,:) :: work_mom + + real (kind=dbl_kind), dimension(:,:), allocatable :: & + G_dyT, G_dyN, G_dyE, G_dyU + + integer (kind=int_kind) :: & + i, j, & + im1, im2, jm1, jm2, im3, jm3 , & ! i & j for mom supergrid + ierr + + character(len=*), parameter :: subname = '(mom_dy)' + + if (my_task == master_task) then + allocate( & + G_dyT(nx_global,ny_global), & + G_dyN(nx_global,ny_global), & + G_dyE(nx_global,ny_global), & + G_dyU(nx_global,ny_global), & + stat=ierr & + ) + else + allocate(G_dyT(1,1), G_dyE(1,1), G_dyU(1,1), G_dyN(1,1), stat=ierr) + endif + if (ierr/=0) call abort_ice(subname//' ERROR: Out of memory', file=__FILE__, line=__LINE__) + + if (my_task == master_task) then + im1 = 2 ; im2 = 3 ! middle , right edge of first T-cell + do i = 1, nx_global + jm1 = 1 ; jm2 = 2 ; jm3 = 3 + do j = 1, ny_global - 1 + G_dyT(i,j) = work_mom(im1, jm1) + work_mom(im1, jm2) !dyT + G_dyN(i,j) = work_mom(im1, jm2) + work_mom(im1, jm3) !dyN + G_dyE(i,j) = work_mom(im2, jm1) + work_mom(im2, jm2) !dyE + G_dyU(i,j) = work_mom(im2, jm2) + work_mom(im2, jm3) !dyU + jm1 = jm1 + 2 ; jm2 = jm2 + 2 ; jm3 = jm3 + 2 + enddo + im1 = im1 + 2 ; im2 = im2 + 2 + enddo + + ! fill the top row + im1 = 2 ; im2 = 3 ! middle , right edge of first column + do i = 1, nx_global + G_dyT(i,ny_global) = work_mom(im1, 2*ny_global - 1) + work_mom(im1, 2*ny_global) !dyT + G_dyE(i,ny_global) = work_mom(im2, 2*ny_global - 1) + work_mom(im2, 2*ny_global) !dyE + im1 = im1 + 2 ; im2 = im2 + 2 + enddo + im1 = 2 ; im2 = 3 + if (trim(ns_boundary_type) == 'tripole') then + do i = 1, nx_global + G_dyN(i,ny_global) = work_mom(im1, 2*ny_global) + work_mom(2*nx_global+2-im1, 2*ny_global) !dyN + G_dyU(i,ny_global) = work_mom(im2, 2*ny_global) + work_mom(2*nx_global+2-im2, 2*ny_global) !dyU + im1 = im1 + 2 ; im2 = im2 + 2 + enddo + else if (trim(ns_boundary_type) == 'cyclic') then + do i = 1, nx_global + G_dyN(i,ny_global) = work_mom(im1, 2*ny_global) + work_mom(im1, 1) !dyN + G_dyU(i,ny_global) = work_mom(im2, 2*ny_global) + work_mom(im2, 1) !dyU + im1 = im1 + 2 ; im2 = im2 + 2 + enddo + else if (trim(ns_boundary_type) == 'open') then + do i = 1, nx_global + G_dyN(i,ny_global) = 4*work_mom(im1, 2*ny_global) - 2*work_mom(im1, 2*ny_global-1) !dyN + G_dyU(i,ny_global) = 4*work_mom(im2, 2*ny_global) - 2*work_mom(im2, 2*ny_global-1) !dyU + im1 = im1 + 2 ; im2 = im2 + 2 + enddo + endif + + if (save_ghte_ghtn) then + do j = 1, ny_global + do i = 1, nx_global + G_HTE(i+nghost,j+nghost) = G_dyE(i,j) + enddo + enddo + call global_ext_halo(G_HTE) + endif + endif + + call scatter_global(dyT, G_dyT, master_task, distrb_info, & + field_loc_center, field_type_scalar) + call scatter_global(dyN, G_dyN, master_task, distrb_info, & + field_loc_Nface, field_type_scalar) + call scatter_global(HTE, G_dyE, master_task, distrb_info, & + field_loc_center, field_type_scalar) + dyE(:,:,:) = HTE(:,:,:) + call scatter_global(dyU, G_dyU, master_task, distrb_info, & + field_loc_NEcorner, field_type_scalar) + + deallocate(G_dyT, G_dyN, G_dyE, G_dyU) + if (ierr/=0) call abort_ice(subname//' ERROR: Dealloc error', file=__FILE__, line=__LINE__) + + end subroutine mom_dy + +!======================================================================= + + subroutine mom_area(work_mom) + + ! mom supergrid has four cells for every model cell, sum these + ! to get uarea and tarea + ! earea and narea are calculated from dx & dy - see https://github.com/NOAA-GFDL/MOM6/issues/740 + + real (kind=dbl_kind), dimension(:,:), intent(in) :: work_mom + + integer (kind=int_kind) :: & + i, j, iblk, & + im1, im2, jm1, jm2, im3, jm3 , & ! i & j for mom supergrid + ilo,ihi,jlo,jhi , & ! beginning and end of physical domain + ierr + + type (block) :: & + this_block ! block information for current block + + real (kind=dbl_kind), dimension(:,:), allocatable :: & + G_tarea, G_uarea + + character(len=*), parameter :: subname = '(mom_area)' - !$OMP PARALLEL DO PRIVATE(iblk,this_block,ilo,ihi,jlo,jhi,i,j) + ! calculate narea and earea + !$OMP PARALLEL DO PRIVATE(iblk,i,j,ilo,ihi,jlo,jhi,this_block) do iblk = 1, nblocks this_block = get_block(blocks_ice(iblk),iblk) ilo = this_block%ilo @@ -1254,98 +1950,303 @@ subroutine latlongrid jlo = this_block%jlo jhi = this_block%jhi - do j = jlo, jhi - do i = ilo, ihi - ! Convert from degrees to radians - TLON(i,j,iblk) = pi*TLON(i,j,iblk)/180._dbl_kind + do j = 1,ny_block + do i = 1,nx_block + narea(i,j,iblk) = dxN(i,j,iblk)*dyN(i,j,iblk) + earea(i,j,iblk) = dxE(i,j,iblk)*dyE(i,j,iblk) + enddo + enddo + enddo + !$OMP END PARALLEL DO - ! Convert from degrees to radians - TLAT(i,j,iblk) = pi*TLAT(i,j,iblk)/180._dbl_kind + if (my_task == master_task) then + allocate( & + G_tarea(nx_global,ny_global), & + G_uarea(nx_global,ny_global), & + stat=ierr & + ) + else + allocate(G_tarea(1,1), G_uarea(1,1), stat=ierr ) + endif + if (ierr/=0) call abort_ice(subname//' ERROR: Out of memory', file=__FILE__, line=__LINE__) - ! Convert from radians^2 to m^2 - ! (area in domain file is in radians^2 and tarea is in m^2) - tarea(i,j,iblk) = tarea(i,j,iblk) * (radius*radius) - end do - end do - end do - !$OMP END PARALLEL DO + ! load tarea and uarea + if (my_task == master_task) then + im1 = 1 ; im2 = 2 ! left/right -half of first column + im3 = 3 ! right of first U - cell + do i = 1, nx_global - 1 + jm1 = 1 ; jm2 = 2 ! bottom/top -half of first row + jm3 = 3 ! top of first U - cell + do j = 1, ny_global - 1 + G_tarea(i,j) = work_mom(im1, jm1) + work_mom(im1, jm2) & + + work_mom(im2, jm1) + work_mom(im2, jm2) + G_uarea(i,j) = work_mom(im2, jm2) + work_mom(im2, jm3) & + + work_mom(im3, jm2) + work_mom(im3, jm3) + jm1 = jm1 + 2 ; jm2 = jm2 + 2 ; jm3 = jm3 + 2 + enddo + im1 = im1 + 2 ; im2 = im2 + 2 ; im3 = im3 + 2 + enddo + + ! fill last column + jm1 = 1 ; jm2 = 2 ; jm3 = 3 + im1 = 2*nx_global - 1 ; im2 = 2*nx_global ; im3 = 1 + do j = 1, ny_global - 1 + G_tarea(nx_global,j) = work_mom(im1, jm1) + work_mom(im1, jm2) & + + work_mom(im2, jm1) + work_mom(im2, jm2) + if (trim(ew_boundary_type) == 'cyclic') then + G_uarea(nx_global,j) = work_mom(im2, jm2) + work_mom(im2, jm3) & + + work_mom(im3, jm2) + work_mom(im3, jm3) + else if (trim(ew_boundary_type) == 'open') then + G_uarea(nx_global,j) = 4*work_mom(im2, jm2) + 4*work_mom(im2, jm3) & + - 2*work_mom(im1, jm2) - 2*work_mom(im1, jm3) + endif + jm1 = jm1 + 2 ; jm2 = jm2 + 2 ; jm3 = jm3 + 2 + enddo + + ! fill last row + jm1 = ny_global*2 - 1 ; jm2 = ny_global*2 + im1 = 1 ; im2 = 2 ; im3 = 3 + do i = 1, nx_global -1 + G_tarea(i,ny_global) = work_mom(im1, jm1) + work_mom(im1, jm2) & + + work_mom(im2, jm1) + work_mom(im2, jm2) + if (trim(ns_boundary_type) == 'tripole') then + G_uarea(i,ny_global) = work_mom(im2, jm2) + work_mom(2*nx_global+1-im2, jm2) & + + work_mom(im3, jm2) + work_mom(2*nx_global+1-im3, jm2) + else if (trim(ns_boundary_type) == 'cyclic') then + G_uarea(i,ny_global) = work_mom(im2, jm2) + work_mom(im2, jm3) & + + work_mom(im3, jm2) + work_mom(im3, jm3) + else if (trim(ns_boundary_type) == 'open') then + G_uarea(i,ny_global) = 4*work_mom(im2, jm2) + 4*work_mom(im3, jm2) & + - 2*work_mom(im2, jm1) - 2*work_mom(im3, jm1) + endif + im1 = im1 + 2 ; im2 = im2 + 2 ; im3 = im3 + 2 + enddo + + ! the top right corner + im1 = nx_global*2-1 ; im2 = nx_global*2 + jm1 = ny_global*2-1 ; jm2 = ny_global*2 + G_tarea(nx_global,ny_global) = work_mom(im1, jm1) + work_mom(im1, jm2) & + + work_mom(im2, jm1) + work_mom(im2, jm2) + if (trim(ns_boundary_type) == 'tripole') then + G_uarea(nx_global,ny_global) = 2*(work_mom(im2, jm2) + work_mom(1, jm2)) + else if (trim(ns_boundary_type) == 'cyclic' & + .and. trim(ew_boundary_type) == 'cyclic') then + G_uarea(nx_global,ny_global) = work_mom(im2, jm2) + work_mom(1, jm2) & + + work_mom(im2, 1) + work_mom(1, 1) + else if (trim(ns_boundary_type) == 'cyclic' & + .and. trim(ew_boundary_type) == 'open') then + G_uarea(nx_global,ny_global) = 4*work_mom(im2, jm2) + 4*work_mom(im2, 1) & + - 2*work_mom(im1, jm2) - 2*work_mom(im1, 1) + else if (trim(ns_boundary_type) == 'open' & + .and. trim(ew_boundary_type) == 'cyclic') then + G_uarea(nx_global,ny_global) = 4*work_mom(im2, jm2) + 4*work_mom(1, jm2) & + - 2*work_mom(im2, jm1) - 2*work_mom(1, jm1) + else if (trim(ns_boundary_type) == 'open' & + .and. trim(ew_boundary_type) == 'open') then + G_uarea(nx_global,ny_global) = 8*work_mom(im2, jm2) & + - 2*work_mom(im2, jm1) - 2*work_mom(im1, jm2) + endif + + endif + + call scatter_global(tarea, G_tarea, master_task, distrb_info, & + field_loc_center, field_type_scalar) + call scatter_global(uarea, G_uarea, master_task, distrb_info, & + field_loc_NEcorner, field_type_scalar) + deallocate(G_tarea, G_uarea, stat=ierr) + if (ierr/=0) call abort_ice(subname//' ERROR: Dealloc error', file=__FILE__, line=__LINE__) + + end subroutine mom_area + +!======================================================================= + + subroutine mom_grid_rotation_angle(lon_cnr, lat_cnr, lon_cen, angle) + ! create angles in the same way mom6 creates the angle + ! based on https://github.com/mom-ocean/MOM6/blob/129e1bda02d454fb280819d1d87ae16347fd044c/src/initialization/MOM_shared_initialization.F90#L535 + ! the angle is between logical north on the grid and true north. + + ! global lat/lons/angles + real (kind=dbl_kind), dimension(:,:), intent(in) :: & + lon_cnr, & ! array of lon corner points + lat_cnr, & ! array of lat corner points + lon_cen ! array of lon centre points (i.e. the location the angle is calculated for) + real (kind=dbl_kind), dimension(:,:), intent(out) :: angle + + ! local vars + real (kind=dbl_kind) :: & + lon_scale, & ! The trigonometric scaling factor converting changes in longitude to equivalent distances in latitudes [nondim] + len_lon, & + lon_adj, & + lonB(2,2) + integer (kind=int_kind) :: i, j, m, n + + character(len=*), parameter :: subname = '(mom_grid_rotation_angle)' + + if (my_task == master_task) then + len_lon = maxval(lon_cnr)-minval(lon_cnr) ! The periodic range of longitudes, usually 2pi. + + do j=1,ny_global + do i=1,nx_global + lon_adj = lon_cen(i,j)-p5*len_lon + do n=1,2 ; do m=1,2 + ! shift 4 lon corner points to be similar range to centre point + ! e.g. upper limit of 0 might be shifted to 2*pi + lonB(m,n) = modulo(lon_cnr(i+m-1,j+n-1)-lon_adj, len_lon) & + + lon_adj + enddo ; enddo + lon_scale = cos(p25*(lat_cnr(I,J) + lat_cnr(I+1,J+1) + lat_cnr(I+1,J) + lat_cnr(I,J+1))) + angle(i,j) = atan2(lon_scale*((lonB(1,2) - lonB(2,1) + lonB(2,2) - lonB(1,1))), & + (lat_cnr(I,J+1) - lat_cnr(I+1,J) + lat_cnr(I+1,J+1) - lat_cnr(I,J)) ) + enddo + enddo + endif + + end subroutine mom_grid_rotation_angle + +!======================================================================= +! GEOS MOM grid +! Grid record number, field and units are: \\ +! (1) ULAT (radians) \\ +! (2) ULON (radians) \\ +! (3) ANGLE (radians) \\ +! (4) ANGLET (radians) \\ +! (5) HTN (cm) \\ +! (6) HTE (cm) \\ +! +! Land mask record number and field is (1) KMT. +! + + subroutine geosgrid_nc + + use ice_blocks, only: nx_block, ny_block + use ice_constants, only: c0, c1, & + field_loc_center, field_loc_NEcorner, & + field_type_scalar, field_type_angle + use ice_domain_size, only: max_blocks +#ifdef USE_NETCDF + use netcdf +#endif + + integer (kind=int_kind) :: & + i, j, iblk, & + ilo,ihi,jlo,jhi, & ! beginning and end of physical domain + fid_grid ! file id for netCDF grid file + + logical (kind=log_kind) :: diag + + character (char_len) :: & + fieldname ! field name in netCDF file + + real (kind=dbl_kind) :: & + pi + + real (kind=dbl_kind), dimension(:,:), allocatable :: & + work_g1 + + type (block) :: & + this_block ! block information for current block + + integer(kind=int_kind) :: & + varid + integer (kind=int_kind) :: & + status ! status flag + + character(len=*), parameter :: subname = '(geosgrid_nc)' + +#ifdef USE_NETCDF + call icepack_query_parameters(pi_out=pi) + call icepack_warnings_flush(nu_diag) + if (icepack_warnings_aborted()) call abort_ice(error_message=subname, & + file=__FILE__, line=__LINE__) + + call ice_open_nc(grid_file,fid_grid) + + diag = .true. ! write diagnostic info + l_readCenter = .false. !----------------------------------------------------------------- - ! Calculate various geometric 2d arrays - ! The U grid (velocity) is not used when run with sequential CAM - ! because we only use thermodynamic sea ice. However, ULAT is used - ! in the default initialization of CICE so we calculate it here as - ! a "dummy" so that CICE will initialize with ice. If a no ice - ! initialization is OK (or desired) this can be commented out and - ! ULAT will remain 0 as specified above. ULAT is located at the - ! NE corner of the grid cell, TLAT at the center, so here ULAT is - ! hacked by adding half the latitudinal spacing (in radians) to - ! TLAT. + ! lat, lon, angle !----------------------------------------------------------------- - !$OMP PARALLEL DO PRIVATE(iblk,this_block,ilo,ihi,jlo,jhi,i,j) - do iblk = 1, nblocks - this_block = get_block(blocks_ice(iblk),iblk) - ilo = this_block%ilo - ihi = this_block%ihi - jlo = this_block%jlo - jhi = this_block%jhi + allocate(work_g1(nx_global,ny_global)) - do j = jlo, jhi - do i = ilo, ihi + fieldname='ulat' + call ice_read_global_nc(fid_grid,1,fieldname,work_g1,diag) ! ULAT + call gridbox_verts(work_g1,latt_bounds) + call scatter_global(ULAT, work_g1, master_task, distrb_info, & + field_loc_NEcorner, field_type_scalar) + call ice_HaloExtrapolate(ULAT, distrb_info, & + ew_boundary_type, ns_boundary_type) - if (ny_global == 1) then - uarea(i,j,iblk) = tarea(i,j, iblk) - else - uarea(i,j,iblk) = p25* & - (tarea(i,j, iblk) + tarea(i+1,j, iblk) & - + tarea(i,j+1,iblk) + tarea(i+1,j+1,iblk)) - endif - tarear(i,j,iblk) = c1/tarea(i,j,iblk) - uarear(i,j,iblk) = c1/uarea(i,j,iblk) + fieldname='ulon' + call ice_read_global_nc(fid_grid,1,fieldname,work_g1,diag) ! ULON + call gridbox_verts(work_g1,lont_bounds) + call scatter_global(ULON, work_g1, master_task, distrb_info, & + field_loc_NEcorner, field_type_scalar) + call ice_HaloExtrapolate(ULON, distrb_info, & + ew_boundary_type, ns_boundary_type) - if (single_column) then - ULAT (i,j,iblk) = TLAT(i,j,iblk)+(pi/nj) - else - if (ny_global == 1) then - ULAT (i,j,iblk) = TLAT(i,j,iblk) - else - ULAT (i,j,iblk) = TLAT(i,j,iblk)+(pi/ny_global) - endif - endif - ULON (i,j,iblk) = c0 - NLON (i,j,iblk) = c0 - NLAT (i,j,iblk) = c0 - ELON (i,j,iblk) = c0 - ELAT (i,j,iblk) = c0 - ANGLE (i,j,iblk) = c0 + fieldname='angle' + call ice_read_global_nc(fid_grid,1,fieldname,work_g1,diag) ! ANGLE + call scatter_global(ANGLE, work_g1, master_task, distrb_info, & + field_loc_NEcorner, field_type_angle) + ! fix ANGLE: roundoff error due to single precision + where (ANGLE > pi) ANGLE = pi + where (ANGLE < -pi) ANGLE = -pi - ANGLET(i,j,iblk) = c0 - HTN (i,j,iblk) = 1.e36_dbl_kind - HTE (i,j,iblk) = 1.e36_dbl_kind - dxT (i,j,iblk) = 1.e36_dbl_kind - dyT (i,j,iblk) = 1.e36_dbl_kind - dxU (i,j,iblk) = 1.e36_dbl_kind - dyU (i,j,iblk) = 1.e36_dbl_kind - dxN (i,j,iblk) = 1.e36_dbl_kind - dyN (i,j,iblk) = 1.e36_dbl_kind - dxE (i,j,iblk) = 1.e36_dbl_kind - dyE (i,j,iblk) = 1.e36_dbl_kind - enddo - enddo - enddo - !$OMP END PARALLEL DO + ! if grid file includes anglet then read instead + fieldname='anglet' + if (my_task == master_task) then + status = nf90_inq_varid(fid_grid, trim(fieldname) , varid) + if (status /= nf90_noerr) then + write(nu_diag,*) subname//' CICE will calculate angleT, TLON and TLAT' + else + write(nu_diag,*) subname//' angleT, TLON and TLAT is read from grid file' + l_readCenter = .true. + endif + endif + call broadcast_scalar(l_readCenter,master_task) + if (l_readCenter) then + call ice_read_global_nc(fid_grid,1,fieldname,work_g1,diag) + call scatter_global(ANGLET, work_g1, master_task, distrb_info, & + field_loc_center, field_type_angle) + where (ANGLET > pi) ANGLET = pi + where (ANGLET < -pi) ANGLET = -pi + fieldname="tlon" + call ice_read_global_nc(fid_grid,1,fieldname,work_g1,diag) + call scatter_global(TLON, work_g1, master_task, distrb_info, & + field_loc_center, field_type_scalar) + fieldname="tlat" + call ice_read_global_nc(fid_grid,1,fieldname,work_g1,diag) + call scatter_global(TLAT, work_g1, master_task, distrb_info, & + field_loc_center, field_type_scalar) + endif + !----------------------------------------------------------------- + ! cell dimensions + ! calculate derived quantities from global arrays to preserve + ! information on boundaries + !----------------------------------------------------------------- - call makemask + fieldname='htn' + call ice_read_global_nc(fid_grid,1,fieldname,work_g1,diag) ! HTN + call primary_grid_lengths_HTN(work_g1) ! dxu, dxt + fieldname='hte' + call ice_read_global_nc(fid_grid,1,fieldname,work_g1,diag) ! HTE + call primary_grid_lengths_HTE(work_g1) ! dyu, dyt + + deallocate(work_g1) + + if (my_task == master_task) then + call ice_close_nc(fid_grid) + endif #else - call abort_ice(subname//' ERROR: USE_NETCDF cpp not defined', & + call abort_ice(subname//'ERROR: USE_NETCDF cpp not defined', & file=__FILE__, line=__LINE__) #endif - end subroutine latlongrid -#endif -!======================================================================= + end subroutine geosgrid_nc +!======================================================================= ! Regular rectangular grid and mask ! ! author: Elizabeth C. Hunke, LANL @@ -1703,7 +2604,6 @@ subroutine rectgrid_scale_dxdy end subroutine rectgrid_scale_dxdy !======================================================================= - ! Complex land mask for testing box cases ! Requires nx_global, ny_global > 20 ! Assumes work array has been initialized to 1 (ocean) and north and @@ -1831,7 +2731,6 @@ end subroutine grid_boxislands_kmt !======================================================================= - ! Calculate dxU and dxT from HTN on the global grid, to preserve ! ghost cell and/or land values that might otherwise be lost. Scatter ! dxU, dxT and HTN to all processors. @@ -1846,7 +2745,8 @@ subroutine primary_grid_lengths_HTN(work_g) integer (kind=int_kind) :: & i, j, & - ip1 ! i+1 + ip1 , & ! i+1 + ierr real (kind=dbl_kind), dimension(:,:), allocatable :: & work_g2 @@ -1854,10 +2754,11 @@ subroutine primary_grid_lengths_HTN(work_g) character(len=*), parameter :: subname = '(primary_grid_lengths_HTN)' if (my_task == master_task) then - allocate(work_g2(nx_global,ny_global)) + allocate(work_g2(nx_global,ny_global), stat=ierr) else - allocate(work_g2(1,1)) + allocate(work_g2(1,1), stat=ierr) endif + if (ierr/=0) call abort_ice(subname//' ERROR: Out of memory', file=__FILE__, line=__LINE__) ! HTN, dxU = average of 2 neighbor HTNs in i @@ -1932,7 +2833,8 @@ subroutine primary_grid_lengths_HTN(work_g) call scatter_global(dxE, work_g2, master_task, distrb_info, & field_loc_center, field_type_scalar) - deallocate(work_g2) + deallocate(work_g2, stat=ierr) + if (ierr/=0) call abort_ice(subname//' ERROR: Dealloc error', file=__FILE__, line=__LINE__) end subroutine primary_grid_lengths_HTN @@ -1951,7 +2853,8 @@ subroutine primary_grid_lengths_HTE(work_g) integer (kind=int_kind) :: & i, j, & - im1 ! i-1 + im1, & ! i-1 + ierr real (kind=dbl_kind), dimension(:,:), allocatable :: & work_g2 @@ -1959,10 +2862,11 @@ subroutine primary_grid_lengths_HTE(work_g) character(len=*), parameter :: subname = '(primary_grid_lengths_HTE)' if (my_task == master_task) then - allocate(work_g2(nx_global,ny_global)) + allocate(work_g2(nx_global,ny_global), stat=ierr) else - allocate(work_g2(1,1)) + allocate(work_g2(1,1), stat=ierr) endif + if (ierr/=0) call abort_ice(subname//' ERROR: Out of memory', file=__FILE__, line=__LINE__) ! HTE, dyU = average of 2 neighbor HTE in j @@ -2041,12 +2945,12 @@ subroutine primary_grid_lengths_HTE(work_g) dyE(:,:,:) = HTE(:,:,:) - deallocate(work_g2) + deallocate(work_g2, stat=ierr) + if (ierr/=0) call abort_ice(subname//' ERROR: Dealloc errro', file=__FILE__, line=__LINE__) end subroutine primary_grid_lengths_HTE !======================================================================= - ! This subroutine fills ghost cells in global extended grid subroutine global_ext_halo(array) @@ -2088,7 +2992,6 @@ subroutine global_ext_halo(array) end subroutine global_ext_halo !======================================================================= - ! Sets the boundary values for the T cell land mask (hm) and ! makes the logical land masks for T and U cells (tmask, umask) ! and N and E cells (nmask, emask). @@ -2100,7 +3003,8 @@ subroutine makemask integer (kind=int_kind) :: & i, j, iblk, & - ilo,ihi,jlo,jhi ! beginning and end of physical domain + ilo,ihi,jlo,jhi, & ! beginning and end of physical domain + ierr real (kind=dbl_kind) :: & puny @@ -2130,7 +3034,8 @@ subroutine makemask !----------------------------------------------------------------- bm = c0 - allocate(uvmCD(nx_block,ny_block,max_blocks)) + allocate(uvmCD(nx_block,ny_block,max_blocks), stat=ierr) + if (ierr/=0) call abort_ice(subname//' ERROR: Out of memory', file=__FILE__, line=__LINE__) !$OMP PARALLEL DO PRIVATE(iblk,i,j,ilo,ihi,jlo,jhi,this_block) do iblk = 1, nblocks @@ -2165,6 +3070,8 @@ subroutine makemask field_loc_Eface, field_type_scalar) call ice_HaloUpdate (bm, halo_info, & field_loc_center, field_type_scalar) + call ice_HaloUpdate (ocn_gridcell_frac, halo_info, & + field_loc_center, field_type_scalar) call ice_timer_stop(timer_bound) !$OMP PARALLEL DO PRIVATE(iblk,i,j,ilo,ihi,jlo,jhi,this_block) @@ -2181,6 +3088,7 @@ subroutine makemask umaskCD(:,:,iblk) = .false. nmask(:,:,iblk) = .false. emask(:,:,iblk) = .false. + opmask(:,:,iblk) = .false. do j = jlo-nghost, jhi+nghost do i = ilo-nghost, ihi+nghost if ( hm(i,j,iblk) > p5 ) tmask (i,j,iblk) = .true. @@ -2188,6 +3096,8 @@ subroutine makemask if (uvmCD(i,j,iblk) > c1p5) umaskCD(i,j,iblk) = .true. if (npm(i,j,iblk) > p5 ) nmask (i,j,iblk) = .true. if (epm(i,j,iblk) > p5 ) emask (i,j,iblk) = .true. + if (ocn_gridcell_frac(i,j,iblk) > puny .and. .not. tmask(i,j,iblk)) & + opmask(i,j,iblk) = .true. enddo enddo @@ -2235,12 +3145,12 @@ subroutine makemask enddo ! iblk !$OMP END PARALLEL DO - deallocate(uvmCD) + deallocate(uvmCD, stat=ierr) + if (ierr/=0) call abort_ice(subname//' ERROR: Dealloc errro', file=__FILE__, line=__LINE__) end subroutine makemask !======================================================================= - ! Initializes latitude and longitude on T grid ! ! author: Elizabeth C. Hunke, LANL; code originally based on POP grid @@ -2329,7 +3239,8 @@ subroutine Tlatlon enddo ! iblk !$OMP END PARALLEL DO - if (trim(grid_type) == 'regional') then + if (trim(grid_type) == 'regional' .or. & + trim(grid_type) == 'rectangular') then ! for W boundary extrapolate from interior !$OMP PARALLEL DO PRIVATE(iblk,i,j,ilo,ihi,jlo,jhi,this_block) do iblk = 1, nblocks @@ -2367,7 +3278,6 @@ subroutine Tlatlon end subroutine Tlatlon !======================================================================= - ! Initializes latitude and longitude on N, E grid ! ! author: T. Craig from Tlatlon @@ -2479,7 +3389,8 @@ subroutine NElatlon enddo ! iblk !$OMP END PARALLEL DO - if (trim(grid_type) == 'regional') then + if (trim(grid_type) == 'regional' .or. & + trim(grid_type) == 'rectangular') then ! for W boundary extrapolate from interior !$OMP PARALLEL DO PRIVATE(iblk,i,j,ilo,ihi,jlo,jhi,this_block) do iblk = 1, nblocks @@ -2564,7 +3475,6 @@ subroutine NElatlon end subroutine NElatlon !======================================================================= - ! Shifts quantities from one grid to another ! Constructs the shift based on the grid ! NOTE: Input array includes ghost cells that must be updated before @@ -2599,7 +3509,6 @@ subroutine grid_average_X2Y_base(type,work1,grid1,work2,grid2) end subroutine grid_average_X2Y_base !======================================================================= - ! Shifts quantities from one grid to another ! NOTE: Input array includes ghost cells that must be updated before ! calling this routine. @@ -2635,7 +3544,6 @@ subroutine grid_average_X2Y_userwghts(type,work1,grid1,wght1,mask1,work2,grid2) end subroutine grid_average_X2Y_userwghts !======================================================================= - ! Shifts quantities from one grid to another ! NOTE: Input array includes ghost cells that must be updated before ! calling this routine. @@ -2690,7 +3598,6 @@ subroutine grid_average_X2Y_NEversion(type,work1a,grid1a,work1b,grid1b,work2,gri end subroutine grid_average_X2Y_NEversion !======================================================================= - ! Shifts quantities from one grid to another ! NOTE: Input array includes ghost cells that must be updated before ! calling this routine. @@ -2799,7 +3706,6 @@ subroutine grid_average_X2Y_1(X2Y,work1,work2) end subroutine grid_average_X2Y_1 !======================================================================= - ! Shifts quantities from one grid to another ! NOTE: Input array includes ghost cells that must be updated before ! calling this routine. @@ -3135,7 +4041,7 @@ subroutine grid_average_X2YS(dir,work1,wght1,mask1,work2) case default call abort_ice(subname//' ERROR: unknown option '//trim(dir), file=__FILE__, line=__LINE__) - end select + end select end subroutine grid_average_X2YS @@ -3363,7 +4269,7 @@ subroutine grid_average_X2YA(dir,work1,wght1,work2) case default call abort_ice(subname//' ERROR: unknown option '//trim(dir), file=__FILE__, line=__LINE__) - end select + end select end subroutine grid_average_X2YA @@ -3565,7 +4471,7 @@ subroutine grid_average_X2YF(dir,work1,wght1,work2,wght2) case default call abort_ice(subname//' ERROR: unknown option '//trim(dir), file=__FILE__, line=__LINE__) - end select + end select end subroutine grid_average_X2YF @@ -3710,7 +4616,7 @@ subroutine grid_average_X2Y_2(dir,work1a,wght1a,mask1a,work1b,wght1b,mask1b,work case default call abort_ice(subname//' ERROR: unknown option '//trim(dir), file=__FILE__, line=__LINE__) - end select + end select end subroutine grid_average_X2Y_2 @@ -3790,8 +4696,9 @@ end function grid_neighbor_max subroutine gridbox_corners integer (kind=int_kind) :: & - i,j,iblk,icorner,& ! index counters - ilo,ihi,jlo,jhi ! beginning and end of physical domain + i,j,iblk,icorner,& ! index counters + ilo,ihi,jlo,jhi, & ! beginning and end of physical domain + ierr real (kind=dbl_kind), dimension(:,:), allocatable :: & work_g2 @@ -3851,10 +4758,11 @@ subroutine gridbox_corners !---------------------------------------------------------------- if (my_task == master_task) then - allocate(work_g2(nx_global,ny_global)) + allocate(work_g2(nx_global,ny_global), stat=ierr) else - allocate(work_g2(1,1)) + allocate(work_g2(1,1), stat=ierr) endif + if (ierr/=0) call abort_ice(subname//' ERROR: Out of memory', file=__FILE__, line=__LINE__) work1(:,:,:) = latu_bounds(2,:,:,:) ! work_g2 = c0 @@ -3944,13 +4852,15 @@ subroutine gridbox_corners field_loc_NEcorner, field_type_scalar) lonu_bounds(4,:,:,:) = work1(:,:,:) - deallocate(work_g2) + deallocate(work_g2, stat=ierr) + if (ierr/=0) call abort_ice(subname//' ERROR: Dealloc errro', file=__FILE__, line=__LINE__) !---------------------------------------------------------------- ! Convert longitude to Degrees East >0 for history output !---------------------------------------------------------------- - allocate(work_g2(nx_block,ny_block)) ! not used as global here + allocate(work_g2(nx_block,ny_block), stat=ierr) ! not used as global here + if (ierr/=0) call abort_ice(subname//' ERROR: Out of memory', file=__FILE__, line=__LINE__) !OMP fails in this loop do iblk = 1, nblocks do icorner = 1, 4 @@ -3964,7 +4874,8 @@ subroutine gridbox_corners lonu_bounds(icorner,:,:,iblk) = work_g2(:,:) enddo enddo - deallocate(work_g2) + deallocate(work_g2, stat=ierr) + if (ierr/=0) call abort_ice(subname//' ERROR: Out of memory', file=__FILE__, line=__LINE__) end subroutine gridbox_corners @@ -3981,8 +4892,9 @@ end subroutine gridbox_corners subroutine gridbox_edges integer (kind=int_kind) :: & - i,j,iblk,icorner,& ! index counters - ilo,ihi,jlo,jhi ! beginning and end of physical domain + i,j,iblk,icorner,& ! index counters + ilo,ihi,jlo,jhi , & ! beginning and end of physical domain + ierr real (kind=dbl_kind), dimension(:,:), allocatable :: & work_g2 @@ -4055,10 +4967,11 @@ subroutine gridbox_edges !---------------------------------------------------------------- if (my_task == master_task) then - allocate(work_g2(nx_global,ny_global)) + allocate(work_g2(nx_global,ny_global), stat=ierr) else - allocate(work_g2(1,1)) + allocate(work_g2(1,1), stat=ierr) endif + if (ierr/=0) call abort_ice(subname//' ERROR: Dealloc error', file=__FILE__, line=__LINE__) ! latn_bounds @@ -4240,13 +5153,15 @@ subroutine gridbox_edges field_loc_NEcorner, field_type_scalar) lone_bounds(3,:,:,:) = work1(:,:,:) - deallocate(work_g2) + deallocate(work_g2, stat=ierr) + if (ierr/=0) call abort_ice(subname//' ERROR: Dealloc error', file=__FILE__, line=__LINE__) !---------------------------------------------------------------- ! Convert longitude to Degrees East >0 for history output !---------------------------------------------------------------- - allocate(work_g2(nx_block,ny_block)) ! not used as global here + allocate(work_g2(nx_block,ny_block), stat=ierr) ! not used as global here + if (ierr/=0) call abort_ice(subname//' ERROR: Out of memory', file=__FILE__, line=__LINE__) !OMP fails in this loop do iblk = 1, nblocks do icorner = 1, 4 @@ -4260,12 +5175,11 @@ subroutine gridbox_edges lone_bounds(icorner,:,:,iblk) = work_g2(:,:) enddo enddo - deallocate(work_g2) + deallocate(work_g2, stat=ierr) end subroutine gridbox_edges !======================================================================= - ! NOTE: Boundary conditions for fields on NW, SW, SE corners ! have not been implemented; using NE corner location for all. ! Extrapolations are also used: these fields are approximate! @@ -4282,7 +5196,8 @@ subroutine gridbox_verts(work_g,vbounds) vbounds integer (kind=int_kind) :: & - i,j ! index counters + i,j , & ! index counters + ierr real (kind=dbl_kind) :: & rad_to_deg @@ -4301,10 +5216,11 @@ subroutine gridbox_verts(work_g,vbounds) file=__FILE__, line=__LINE__) if (my_task == master_task) then - allocate(work_g2(nx_global,ny_global)) + allocate(work_g2(nx_global,ny_global), stat=ierr) else - allocate(work_g2(1,1)) + allocate(work_g2(1,1), stat=ierr) endif + if (ierr/=0) call abort_ice(subname//' ERROR: Out of memory', file=__FILE__, line=__LINE__) !------------------------------------------------------------- ! Get coordinates of grid boxes for each block as follows: @@ -4378,7 +5294,8 @@ subroutine gridbox_verts(work_g,vbounds) field_loc_NEcorner, field_type_scalar) vbounds(4,:,:,:) = work1(:,:,:) - deallocate (work_g2) + deallocate (work_g2, stat=ierr) + if (ierr/=0) call abort_ice(subname//' ERROR: Dealloc error', file=__FILE__, line=__LINE__) end subroutine gridbox_verts @@ -4398,9 +5315,6 @@ subroutine get_bathymetry real (kind=dbl_kind), dimension(nlevel) :: & depth ! total depth, m - real (kind=dbl_kind) :: & - puny - logical (kind=log_kind) :: & calc_dragio @@ -4423,7 +5337,7 @@ subroutine get_bathymetry character(len=*), parameter :: subname = '(get_bathymetry)' - call icepack_query_parameters(puny_out=puny, calc_dragio_out=calc_dragio) + call icepack_query_parameters(calc_dragio_out=calc_dragio) call icepack_warnings_flush(nu_diag) if (icepack_warnings_aborted()) call abort_ice(error_message=subname, & file=__FILE__, line=__LINE__) @@ -4495,7 +5409,8 @@ subroutine get_bathymetry_popfile write(nu_diag,*) subname,' KMT max = ',nlevel endif - allocate(depth(nlevel),thick(nlevel)) + allocate(depth(nlevel),thick(nlevel), stat=ierr) + if (ierr/=0) call abort_ice(subname//' ERROR: Out of memory', file=__FILE__, line=__LINE__) thick = -999999. depth = -999999. @@ -4564,12 +5479,12 @@ subroutine get_bathymetry_popfile if (icepack_warnings_aborted()) call abort_ice(error_message=subname, & file=__FILE__, line=__LINE__) - deallocate(depth,thick) + deallocate(depth,thick, stat=ierr) + if (ierr/=0) call abort_ice(subname//' ERROR: Dealloc error', file=__FILE__, line=__LINE__) end subroutine get_bathymetry_popfile !======================================================================= - ! Read bathymetry data for seabed stress calculation (grounding scheme for ! landfast ice) in CICE stand-alone mode. When CICE is in coupled mode ! (e.g. CICE-NEMO), hwater should be uptated at each time level so that diff --git a/cicecore/cicedyn/infrastructure/ice_memusage_gptl.c b/cicecore/cicedyn/infrastructure/ice_memusage_gptl.c index 32b31171d..e321ea3e4 100644 --- a/cicecore/cicedyn/infrastructure/ice_memusage_gptl.c +++ b/cicecore/cicedyn/infrastructure/ice_memusage_gptl.c @@ -179,10 +179,12 @@ int ice_memusage_gptl (int *size, int *rss, int *share, int *text, int *datastac */ pid = (int) getpid (); - if (pid > 999999) { - fprintf (stderr, "get_memusage: pid %d is too large\n", pid); - return -1; - } + /* tcraig, not needed and can be problematic + ** if (pid > 999999) { + ** fprintf (stderr, "get_memusage: pid %d is too large\n", pid); + ** return -1; + ** } + */ sprintf (file, "%s%d%s", head, pid, tail); if ((fd = fopen (file, "r")) < 0) { diff --git a/cicecore/cicedyn/infrastructure/ice_restart_driver.F90 b/cicecore/cicedyn/infrastructure/ice_restart_driver.F90 index dd9d77807..8f11f7f5e 100644 --- a/cicecore/cicedyn/infrastructure/ice_restart_driver.F90 +++ b/cicecore/cicedyn/infrastructure/ice_restart_driver.F90 @@ -29,6 +29,7 @@ module ice_restart_driver use ice_restart use ice_exit, only: abort_ice use ice_fileunits, only: nu_diag, nu_rst_pointer, nu_restart, nu_dump + use ice_grid, only: tmask, opmask, grid_ice, grid_average_X2Y use icepack_intfc, only: icepack_warnings_flush, icepack_warnings_aborted use icepack_intfc, only: icepack_aggregate use icepack_intfc, only: icepack_query_tracer_indices, icepack_query_tracer_sizes @@ -64,11 +65,10 @@ subroutine dumpfile(filename_spec) stresspT, stressmT, stress12T, & stresspU, stressmU, stress12U use ice_flux, only: coszen - use ice_grid, only: grid_ice, tmask use ice_state, only: aicen, vicen, vsnon, trcrn, uvel, vvel, & uvelE, vvelE, uvelN, vvelN - character(len=char_len_long), intent(in), optional :: filename_spec + character(len=*), intent(in), optional :: filename_spec ! local variables @@ -92,7 +92,7 @@ subroutine dumpfile(filename_spec) file=__FILE__, line=__LINE__) if (present(filename_spec)) then - call init_restart_write(filename_spec) + call init_restart_write(filename_spec=filename_spec) else call init_restart_write endif @@ -107,7 +107,7 @@ subroutine dumpfile(filename_spec) do iblk = 1, nblocks do j = 1, ny_block do i = 1, nx_block - if (.not. tmask(i,j,iblk)) trcrn(i,j,:,:,iblk) = c0 + if (.not.tmask(i,j,iblk) .and. .not.opmask(i,j,iblk)) trcrn(i,j,:,:,iblk) = c0 enddo enddo enddo @@ -281,7 +281,7 @@ subroutine restartfile (ice_ic) use ice_boundary, only: ice_HaloUpdate_stress use ice_blocks, only: nghost, nx_block, ny_block use ice_calendar, only: istep0, npt, calendar - use ice_domain, only: nblocks, halo_info + use ice_domain, only: nblocks, halo_info, ns_boundary_type use ice_domain_size, only: nilyr, nslyr, ncat, & max_blocks use ice_dyn_shared, only: iceUmask, iceEmask, iceNmask,kdyn @@ -293,7 +293,6 @@ subroutine restartfile (ice_ic) stresspT, stressmT, stress12T, & stresspU, stressmU, stress12U use ice_flux, only: coszen, Tf - use ice_grid, only: tmask, grid_type, grid_ice, grid_average_X2Y use ice_state, only: trcr_depend, aice, vice, vsno, trcr, & aice0, aicen, vicen, vsnon, trcrn, aice_init, uvel, vvel, & uvelE, vvelE, uvelN, vvelN, & @@ -498,7 +497,8 @@ subroutine restartfile (ice_ic) 'stress12U',1,diag,field_loc_NEcorner,field_type_scalar) ! stress12U endif - if (trim(grid_type) == 'tripole') then + if (trim(ns_boundary_type) == 'tripole' .or. & + trim(ns_boundary_type) == 'tripoleT') then call ice_HaloUpdate_stress(stressp_1, stressp_3, halo_info, & field_loc_center, field_type_scalar) call ice_HaloUpdate_stress(stressp_3, stressp_1, halo_info, & @@ -608,7 +608,7 @@ subroutine restartfile (ice_ic) do iblk = 1, nblocks do j = 1, ny_block do i = 1, nx_block - if (.not. tmask(i,j,iblk)) trcrn(i,j,nt_Tsfc,:,iblk) = c0 + if (.not.tmask(i,j,iblk) .and. .not.opmask(i,j,iblk)) trcrn(i,j,nt_Tsfc,:,iblk) = c0 enddo enddo enddo @@ -685,7 +685,7 @@ subroutine restartfile (ice_ic) do j = 1, ny_block do i = 1, nx_block - if (tmask(i,j,iblk)) & + if (tmask(i,j,iblk) .or. opmask(i,j,iblk)) & call icepack_aggregate(aicen = aicen(i,j,:,iblk), & trcrn = trcrn(i,j,:,:,iblk), & vicen = vicen(i,j,:,iblk), & @@ -740,7 +740,6 @@ subroutine restartfile_v4 (ice_ic) stressm_1, stressm_2, stressm_3, stressm_4, & stress12_1, stress12_2, stress12_3, stress12_4 use ice_gather_scatter, only: scatter_global_stress - use ice_grid, only: tmask use ice_read_write, only: ice_open, ice_read, ice_read_global use ice_state, only: trcr_depend, aice, vice, vsno, trcr, & aice0, aicen, vicen, vsnon, trcrn, aice_init, uvel, vvel, & @@ -1052,7 +1051,7 @@ subroutine restartfile_v4 (ice_ic) do j = 1, ny_block do i = 1, nx_block - if (tmask(i,j,iblk)) & + if (tmask(i,j,iblk) .or. opmask(i,j,iblk)) & call icepack_aggregate(aicen = aicen(i,j,:,iblk), & trcrn = trcrn(i,j,:,:,iblk), & vicen = vicen(i,j,:,iblk), & diff --git a/cicecore/cicedyn/infrastructure/io/io_binary/ice_history_write.F90 b/cicecore/cicedyn/infrastructure/io/io_binary/ice_history_write.F90 index dae187eae..af4a88007 100644 --- a/cicecore/cicedyn/infrastructure/io/io_binary/ice_history_write.F90 +++ b/cicecore/cicedyn/infrastructure/io/io_binary/ice_history_write.F90 @@ -109,7 +109,7 @@ subroutine ice_write_hist(ns) write (nu_hdr, 999) 'runid',runid,' ' #endif if (use_leap_years) then - write (nu_hdr, 999) 'calendar','Gregorian',' ' + write (nu_hdr, 999) 'calendar','proleptic_gregorian',' ' write (title,'(a,i3,a)') 'This year has ',int(dayyr),' days' else write (nu_hdr, 999) 'calendar','noleap',' ' diff --git a/cicecore/cicedyn/infrastructure/io/io_binary/ice_restart.F90 b/cicecore/cicedyn/infrastructure/io/io_binary/ice_restart.F90 index 5866d7130..d8931866a 100644 --- a/cicecore/cicedyn/infrastructure/io/io_binary/ice_restart.F90 +++ b/cicecore/cicedyn/infrastructure/io/io_binary/ice_restart.F90 @@ -384,7 +384,7 @@ subroutine init_restart_write(filename_spec) use ice_dyn_shared, only: kdyn use ice_read_write, only: ice_open, ice_open_ext - character(len=char_len_long), intent(in), optional :: filename_spec + character(len=*), intent(in), optional :: filename_spec ! local variables diff --git a/cicecore/cicedyn/infrastructure/io/io_netcdf/ice_history_write.F90 b/cicecore/cicedyn/infrastructure/io/io_netcdf/ice_history_write.F90 index 92df8dad8..d7720cd1e 100644 --- a/cicecore/cicedyn/infrastructure/io/io_netcdf/ice_history_write.F90 +++ b/cicecore/cicedyn/infrastructure/io/io_netcdf/ice_history_write.F90 @@ -39,6 +39,7 @@ module ice_history_write character (len=11) :: short_name character (len=45) :: long_name character (len=30) :: units + character (len=8) :: axis END TYPE coord_attributes TYPE req_attributes ! req'd netcdf attributes @@ -103,6 +104,7 @@ subroutine ice_write_hist (ns) character (char_len) :: title, cal_units, cal_att character (char_len) :: time_period_freq = 'none' character (char_len_long) :: ncfile + character (len=512) :: extvars real (kind=dbl_kind) :: secday, rad_to_deg integer (kind=int_kind) :: ind,boundid, lprecision @@ -134,6 +136,7 @@ subroutine ice_write_hist (ns) if (icepack_warnings_aborted()) call abort_ice(error_message=subname, & file=__FILE__, line=__LINE__) + extvars = '' lprecision = nf90_float if (history_precision == 8) lprecision = nf90_double @@ -218,9 +221,13 @@ subroutine ice_write_hist (ns) call ice_check_nc(status, subname// ' ERROR: defining dim nkaer', & file=__FILE__, line=__LINE__) - status = nf90_def_dim(ncid,'time',NF90_UNLIMITED,timid) - call ice_check_nc(status, subname// ' ERROR: defining dim time', & - file=__FILE__, line=__LINE__) + ! do not write time axis on grid output file + timid = -99 + if (histfreq(ns)/='g') then + status = nf90_def_dim(ncid,'time',NF90_UNLIMITED,timid) + call ice_check_nc(status, subname// ' ERROR: defining dim time', & + file=__FILE__, line=__LINE__) + endif status = nf90_def_dim(ncid,'nvertices',nverts,nvertexid) call ice_check_nc(status, subname// ' ERROR: defining dim nvertices', & @@ -234,42 +241,46 @@ subroutine ice_write_hist (ns) ! define coordinate variables: time, time_bounds !----------------------------------------------------------------- - write(cdate,'(i8.8)') idate0 - write(cal_units,'(a,a4,a1,a2,a1,a2,a1,i2.2,a1,i2.2,a1,i2.2)') 'days since ', & - cdate(1:4),'-',cdate(5:6),'-',cdate(7:8),' ', & - hh_init,':',mm_init,':',ss_init - - if (days_per_year == 360) then - cal_att='360_day' - elseif (days_per_year == 365 .and. .not.use_leap_years ) then - cal_att='noleap' - elseif (use_leap_years) then - cal_att='Gregorian' - else - call abort_ice(subname//' ERROR: invalid calendar settings', file=__FILE__, line=__LINE__) - endif + ! do not write time axis on grid output file + if (histfreq(ns)/='g') then + + write(cdate,'(i8.8)') idate0 + write(cal_units,'(a,a4,a1,a2,a1,a2,a1,i2.2,a1,i2.2,a1,i2.2)') 'days since ', & + cdate(1:4),'-',cdate(5:6),'-',cdate(7:8),' ', & + hh_init,':',mm_init,':',ss_init + + if (days_per_year == 360) then + cal_att='360_day' + elseif (days_per_year == 365 .and. .not.use_leap_years ) then + cal_att='noleap' + elseif (use_leap_years) then + cal_att='proleptic_gregorian' + else + call abort_ice(subname//' ERROR: invalid calendar settings', file=__FILE__, line=__LINE__) + endif - time_coord = coord_attributes('time', 'time', trim(cal_units)) - call ice_hist_coord_def(ncid, time_coord, nf90_double, (/timid/), varid) + time_coord = coord_attributes('time', 'time', trim(cal_units),'T') + call ice_hist_coord_def(ncid, time_coord, nf90_double, (/timid/), varid) - status = nf90_put_att(ncid,varid,'calendar',cal_att) !extra attribute - call ice_check_nc(status, subname//' ERROR: defining att calendar: '//cal_att,file=__FILE__,line=__LINE__) - if (hist_avg(ns) .and. .not. write_ic) then - status = nf90_put_att(ncid,varid,'bounds','time_bounds') - call ice_check_nc(status, subname//' ERROR: defining att bounds time_bounds',file=__FILE__,line=__LINE__) - endif + status = nf90_put_att(ncid,varid,'calendar',cal_att) !extra attribute + call ice_check_nc(status, subname//' ERROR: defining att calendar: '//cal_att,file=__FILE__,line=__LINE__) + if (hist_avg(ns) .and. .not. write_ic) then + status = nf90_put_att(ncid,varid,'bounds','time_bounds') + call ice_check_nc(status, subname//' ERROR: defining att bounds time_bounds',file=__FILE__,line=__LINE__) + endif - ! Define coord time_bounds if hist_avg is true - if (hist_avg(ns) .and. .not. write_ic) then - time_coord = coord_attributes('time_bounds', 'time interval endpoints', trim(cal_units)) + ! Define coord time_bounds if hist_avg is true + ! bounds inherit attributes + if (hist_avg(ns) .and. .not. write_ic) then + time_coord = coord_attributes('time_bounds', 'undefined', 'undefined', 'undefined') - dimid(1) = boundid - dimid(2) = timid + dimid(1) = boundid + dimid(2) = timid - call ice_hist_coord_def(ncid, time_coord, nf90_double, dimid(1:2), varid) - status = nf90_put_att(ncid,varid,'calendar',cal_att) - call ice_check_nc(status, subname//' ERROR: defining att calendar: '//cal_att,file=__FILE__,line=__LINE__) - endif + call ice_hist_coord_def(ncid, time_coord, nf90_double, dimid(1:2), varid) + endif + + endif ! histfreq(ns)/='g' !----------------------------------------------------------------- ! define information for required time-invariant variables @@ -279,138 +290,131 @@ subroutine ice_write_hist (ns) select case (ind) case(n_tlon) var_coord(ind) = coord_attributes('TLON', & - 'T grid center longitude', 'degrees_east') + 'T grid center longitude', 'degrees_east', 'X') coord_bounds(ind) = 'lont_bounds' case(n_tlat) var_coord(ind) = coord_attributes('TLAT', & - 'T grid center latitude', 'degrees_north') + 'T grid center latitude', 'degrees_north', 'Y') coord_bounds(ind) = 'latt_bounds' case(n_ulon) var_coord(ind) = coord_attributes('ULON', & - 'U grid center longitude', 'degrees_east') + 'U grid center longitude', 'degrees_east', 'X') coord_bounds(ind) = 'lonu_bounds' case(n_ulat) var_coord(ind) = coord_attributes('ULAT', & - 'U grid center latitude', 'degrees_north') + 'U grid center latitude', 'degrees_north', 'Y') coord_bounds(ind) = 'latu_bounds' case(n_nlon) var_coord(ind) = coord_attributes('NLON', & - 'N grid center longitude', 'degrees_east') + 'N grid center longitude', 'degrees_east', 'X') coord_bounds(ind) = 'lonn_bounds' case(n_nlat) var_coord(ind) = coord_attributes('NLAT', & - 'N grid center latitude', 'degrees_north') + 'N grid center latitude', 'degrees_north', 'Y') coord_bounds(ind) = 'latn_bounds' case(n_elon) var_coord(ind) = coord_attributes('ELON', & - 'E grid center longitude', 'degrees_east') + 'E grid center longitude', 'degrees_east', 'X') coord_bounds(ind) = 'lone_bounds' case(n_elat) var_coord(ind) = coord_attributes('ELAT', & - 'E grid center latitude', 'degrees_north') + 'E grid center latitude', 'degrees_north', 'Y') coord_bounds(ind) = 'late_bounds' end select end do - var_grdz(1) = coord_attributes('NCAT', 'category maximum thickness', 'm') - var_grdz(2) = coord_attributes('VGRDi', 'vertical ice levels', '1') - var_grdz(3) = coord_attributes('VGRDs', 'vertical snow levels', '1') - var_grdz(4) = coord_attributes('VGRDb', 'vertical ice-bio levels', '1') - var_grdz(5) = coord_attributes('VGRDa', 'vertical snow-ice-bio levels', '1') - var_grdz(6) = coord_attributes('NFSD', 'category floe size (center)', 'm') + var_grdz(1) = coord_attributes('NCAT', 'category maximum thickness', 'm', 'undefined') + var_grdz(2) = coord_attributes('VGRDi', 'vertical ice levels', '1', 'undefined') + var_grdz(3) = coord_attributes('VGRDs', 'vertical snow levels', '1', 'undefined') + var_grdz(4) = coord_attributes('VGRDb', 'vertical ice-bio levels', '1', 'undefined') + var_grdz(5) = coord_attributes('VGRDa', 'vertical snow-ice-bio levels', '1', 'undefined') + var_grdz(6) = coord_attributes('NFSD', 'category floe size (center)', 'm', 'undefined') !----------------------------------------------------------------- ! define information for optional time-invariant variables !----------------------------------------------------------------- var_grd(n_tmask)%req = coord_attributes('tmask', & - 'mask of T grid cells, 0 = land, 1 = ocean', 'unitless') + 'mask of T grid cells, 0 = land, 1 = ocean', '1', 'undefined') var_grd(n_tmask)%coordinates = 'TLON TLAT' var_grd(n_umask)%req = coord_attributes('umask', & - 'mask of U grid cells, 0 = land, 1 = ocean', 'unitless') + 'mask of U grid cells, 0 = land, 1 = ocean', '1', 'undefined') var_grd(n_umask)%coordinates = 'ULON ULAT' var_grd(n_nmask)%req = coord_attributes('nmask', & - 'mask of N grid cells, 0 = land, 1 = ocean', 'unitless') + 'mask of N grid cells, 0 = land, 1 = ocean', '1', 'undefined') var_grd(n_nmask)%coordinates = 'NLON NLAT' var_grd(n_emask)%req = coord_attributes('emask', & - 'mask of E grid cells, 0 = land, 1 = ocean', 'unitless') + 'mask of E grid cells, 0 = land, 1 = ocean', '1', 'undefined') var_grd(n_emask)%coordinates = 'ELON ELAT' var_grd(n_tarea)%req = coord_attributes('tarea', & - 'area of T grid cells', 'm^2') + 'area of T grid cells', 'm^2', 'undefined') var_grd(n_tarea)%coordinates = 'TLON TLAT' var_grd(n_uarea)%req = coord_attributes('uarea', & - 'area of U grid cells', 'm^2') + 'area of U grid cells', 'm^2', 'undefined') var_grd(n_uarea)%coordinates = 'ULON ULAT' var_grd(n_narea)%req = coord_attributes('narea', & - 'area of N grid cells', 'm^2') + 'area of N grid cells', 'm^2', 'undefined') var_grd(n_narea)%coordinates = 'NLON NLAT' var_grd(n_earea)%req = coord_attributes('earea', & - 'area of E grid cells', 'm^2') + 'area of E grid cells', 'm^2', 'undefined') var_grd(n_earea)%coordinates = 'ELON ELAT' var_grd(n_blkmask)%req = coord_attributes('blkmask', & - 'block id of T grid cells, mytask + iblk/100', 'unitless') + 'block id of T grid cells, mytask + iblk/100', '1', 'undefined') var_grd(n_blkmask)%coordinates = 'TLON TLAT' var_grd(n_dxt)%req = coord_attributes('dxt', & - 'T cell width through middle', 'm') + 'T cell width through middle', 'm', 'undefined') var_grd(n_dxt)%coordinates = 'TLON TLAT' var_grd(n_dyt)%req = coord_attributes('dyt', & - 'T cell height through middle', 'm') + 'T cell height through middle', 'm', 'undefined') var_grd(n_dyt)%coordinates = 'TLON TLAT' var_grd(n_dxu)%req = coord_attributes('dxu', & - 'U cell width through middle', 'm') + 'U cell width through middle', 'm', 'undefined') var_grd(n_dxu)%coordinates = 'ULON ULAT' var_grd(n_dyu)%req = coord_attributes('dyu', & - 'U cell height through middle', 'm') + 'U cell height through middle', 'm', 'undefined') var_grd(n_dyu)%coordinates = 'ULON ULAT' var_grd(n_dxn)%req = coord_attributes('dxn', & - 'N cell width through middle', 'm') + 'N cell width through middle', 'm', 'undefined') var_grd(n_dxn)%coordinates = 'NLON NLAT' var_grd(n_dyn)%req = coord_attributes('dyn', & - 'N cell height through middle', 'm') + 'N cell height through middle', 'm', 'undefined') var_grd(n_dyn)%coordinates = 'NLON NLAT' var_grd(n_dxe)%req = coord_attributes('dxe', & - 'E cell width through middle', 'm') + 'E cell width through middle', 'm', 'undefined') var_grd(n_dxe)%coordinates = 'ELON ELAT' var_grd(n_dye)%req = coord_attributes('dye', & - 'E cell height through middle', 'm') + 'E cell height through middle', 'm', 'undefined') var_grd(n_dye)%coordinates = 'ELON ELAT' var_grd(n_HTN)%req = coord_attributes('HTN', & - 'T cell width on North side','m') + 'T cell width on North side','m', 'undefined') var_grd(n_HTN)%coordinates = 'TLON TLAT' var_grd(n_HTE)%req = coord_attributes('HTE', & - 'T cell width on East side', 'm') + 'T cell width on East side', 'm', 'undefined') var_grd(n_HTE)%coordinates = 'TLON TLAT' var_grd(n_ANGLE)%req = coord_attributes('ANGLE', & 'angle grid makes with latitude line on U grid', & - 'radians') + 'radians', 'undefined') var_grd(n_ANGLE)%coordinates = 'ULON ULAT' var_grd(n_ANGLET)%req = coord_attributes('ANGLET', & 'angle grid makes with latitude line on T grid', & - 'radians') + 'radians', 'undefined') var_grd(n_ANGLET)%coordinates = 'TLON TLAT' - ! These fields are required for CF compliance + ! bounds fields are required for CF compliance ! dimensions (nx,ny,nverts) - var_nverts(n_lont_bnds) = coord_attributes('lont_bounds', & - 'longitude boundaries of T cells', 'degrees_east') - var_nverts(n_latt_bnds) = coord_attributes('latt_bounds', & - 'latitude boundaries of T cells', 'degrees_north') - var_nverts(n_lonu_bnds) = coord_attributes('lonu_bounds', & - 'longitude boundaries of U cells', 'degrees_east') - var_nverts(n_latu_bnds) = coord_attributes('latu_bounds', & - 'latitude boundaries of U cells', 'degrees_north') - var_nverts(n_lonn_bnds) = coord_attributes('lonn_bounds', & - 'longitude boundaries of N cells', 'degrees_east') - var_nverts(n_latn_bnds) = coord_attributes('latn_bounds', & - 'latitude boundaries of N cells', 'degrees_north') - var_nverts(n_lone_bnds) = coord_attributes('lone_bounds', & - 'longitude boundaries of E cells', 'degrees_east') - var_nverts(n_late_bnds) = coord_attributes('late_bounds', & - 'latitude boundaries of E cells', 'degrees_north') + ! bounds inherit attributes + var_nverts(n_lont_bnds) = coord_attributes('lont_bounds','und','und','und') + var_nverts(n_latt_bnds) = coord_attributes('latt_bounds','und','und','und') + var_nverts(n_lonu_bnds) = coord_attributes('lonu_bounds','und','und','und') + var_nverts(n_latu_bnds) = coord_attributes('latu_bounds','und','und','und') + var_nverts(n_lonn_bnds) = coord_attributes('lonn_bounds','und','und','und') + var_nverts(n_latn_bnds) = coord_attributes('latn_bounds','und','und','und') + var_nverts(n_lone_bnds) = coord_attributes('lone_bounds','und','und','und') + var_nverts(n_late_bnds) = coord_attributes('late_bounds','und','und','und') !----------------------------------------------------------------- ! define attributes for time-invariant variables @@ -421,7 +425,7 @@ subroutine ice_write_hist (ns) dimid(3) = timid do i = 1, ncoord - if(icoord(i)) then + if(icoord(i) .or. histfreq(ns)=='g') then call ice_hist_coord_def(ncid, var_coord(i), lprecision, dimid(1:2), varid) call ice_write_hist_fill(ncid,varid,var_coord(i)%short_name,history_precision) if (var_coord(i)%short_name == 'ULAT') then @@ -430,11 +434,13 @@ subroutine ice_write_hist (ns) call ice_check_nc(status, subname// ' ERROR: defining comment for '//var_coord(i)%short_name, & file=__FILE__, line=__LINE__) endif - if (f_bounds) then + if (f_bounds .or. histfreq(ns)=='g') then status = nf90_put_att(ncid, varid, 'bounds', coord_bounds(i)) call ice_check_nc(status, subname// ' ERROR: defining bounds for '//var_coord(i)%short_name, & file=__FILE__, line=__LINE__) endif + else + extvars = trim(extvars)//' '//trim(var_coord(i)%short_name) endif enddo @@ -447,29 +453,33 @@ subroutine ice_write_hist (ns) dimidex(6)=fmtid do i = 1, nvar_grdz - if (igrdz(i)) then + if (igrdz(i) .or. histfreq(ns)=='g') then call ice_hist_coord_def(ncid, var_grdz(i), lprecision, dimidex(i:i), varid) + else + extvars = trim(extvars)//' '//trim(var_grdz(i)%short_name) endif enddo do i = 1, nvar_grd - if (igrd(i)) then + if (igrd(i) .or. histfreq(ns)=='g') then call ice_hist_coord_def(ncid, var_grd(i)%req, lprecision, dimid(1:2), varid) status = nf90_put_att(ncid, varid, 'coordinates', var_grd(i)%coordinates) call ice_check_nc(status, subname// ' ERROR: defining coordinates for '//var_grd(i)%req%short_name, & file=__FILE__, line=__LINE__) call ice_write_hist_fill(ncid,varid,var_grd(i)%req%short_name,history_precision) + else + extvars = trim(extvars)//' '//trim(var_grd(i)%req%short_name) endif enddo - ! Fields with dimensions (nverts,nx,ny) + ! bounds fields with dimensions (nverts,nx,ny) + ! bounds inherits attributes dimid_nverts(1) = nvertexid dimid_nverts(2) = imtid dimid_nverts(3) = jmtid do i = 1, nvar_verts - if (f_bounds) then + if (f_bounds .or. histfreq(ns)=='g') then call ice_hist_coord_def(ncid, var_nverts(i), lprecision, dimid_nverts, varid) - call ice_write_hist_fill(ncid,varid,var_nverts(i)%short_name,history_precision) endif enddo @@ -596,7 +606,7 @@ subroutine ice_write_hist (ns) call ice_check_nc(status, subname// ' ERROR: global attribute contents', & file=__FILE__, line=__LINE__) - write(title,'(2a)') 'Los Alamos Sea Ice Model, ', trim(version_name) + write(title,'(2a)') 'CICE Sea Ice Model, ', trim(version_name) status = nf90_put_att(ncid,nf90_global,'source',title) call ice_check_nc(status, subname// ' ERROR: global attribute source', & file=__FILE__, line=__LINE__) @@ -645,11 +655,15 @@ subroutine ice_write_hist (ns) file=__FILE__, line=__LINE__) endif - title = 'CF-1.0' - status = nf90_put_att(ncid,nf90_global,'conventions',title) + title = 'CF-1.8' + status = nf90_put_att(ncid,nf90_global,'Conventions',title) call ice_check_nc(status, subname// ' ERROR: in global attribute conventions', & file=__FILE__, line=__LINE__) + status = nf90_put_att(ncid,nf90_global,'external_variables',trim(extvars)) + call ice_check_nc(status, subname// ' ERROR: in global attribute external_variables', & + file=__FILE__, line=__LINE__) + call date_and_time(date=current_date, time=current_time) write(start_time,1000) current_date(1:4), current_date(5:6), & current_date(7:8), current_time(1:2), & @@ -661,7 +675,16 @@ subroutine ice_write_hist (ns) call ice_check_nc(status, subname// ' ERROR: global attribute history', & file=__FILE__, line=__LINE__) - status = nf90_put_att(ncid,nf90_global,'io_flavor','io_netcdf') + write(start_time,1001) current_date(1:4), current_date(5:6), & + current_date(7:8), current_time(1:2), & + current_time(3:4), current_time(5:8) +1001 format(a,'-',a,'-',a,' ',a,':',a,':',a) + + status = nf90_put_att(ncid,nf90_global,'date_created',start_time) + call ice_check_nc(status, subname// ' ERROR: global attribute date_created', & + file=__FILE__, line=__LINE__) + + status = nf90_put_att(ncid,nf90_global,'io_flavor','io_netcdf '//trim(history_format)) call ice_check_nc(status, subname// ' ERROR: global attribute io_flavor', & file=__FILE__, line=__LINE__) @@ -674,40 +697,41 @@ subroutine ice_write_hist (ns) file=__FILE__, line=__LINE__) !----------------------------------------------------------------- - ! write time variable + ! write time variable and time bounds info !----------------------------------------------------------------- - ltime2 = timesecs/secday ! hist_time_axis = 'end' (default) + ! do not write time axis on grid output file + if (histfreq(ns)/='g') then - ! Some coupled models require the time axis "stamp" to be in the middle - ! or even beginning of averaging interval. - if (hist_avg(ns)) then - if (trim(hist_time_axis) == "begin" ) ltime2 = time_beg(ns) - if (trim(hist_time_axis) == "middle") ltime2 = p5*(time_beg(ns)+time_end(ns)) - endif + ltime2 = timesecs/secday ! hist_time_axis = 'end' (default) - status = nf90_inq_varid(ncid,'time',varid) - call ice_check_nc(status, subname// ' ERROR: getting time varid', & - file=__FILE__, line=__LINE__) - status = nf90_put_var(ncid,varid,ltime2) - call ice_check_nc(status, subname// ' ERROR: writing time variable', & - file=__FILE__, line=__LINE__) - - !----------------------------------------------------------------- - ! write time_bounds info - !----------------------------------------------------------------- + ! Some coupled models require the time axis "stamp" to be in the middle + ! or even beginning of averaging interval. + if (hist_avg(ns)) then + if (trim(hist_time_axis) == "begin" ) ltime2 = time_beg(ns) + if (trim(hist_time_axis) == "middle") ltime2 = p5*(time_beg(ns)+time_end(ns)) + endif - if (hist_avg(ns) .and. .not. write_ic) then - status = nf90_inq_varid(ncid,'time_bounds',varid) - call ice_check_nc(status, subname// ' ERROR: getting time_bounds id', & + status = nf90_inq_varid(ncid,'time',varid) + call ice_check_nc(status, subname// ' ERROR: getting time varid', & file=__FILE__, line=__LINE__) - status = nf90_put_var(ncid,varid,time_beg(ns),start=(/1/)) - call ice_check_nc(status, subname// ' ERROR: writing time_beg', & + status = nf90_put_var(ncid,varid,ltime2) + call ice_check_nc(status, subname// ' ERROR: writing time variable', & file=__FILE__, line=__LINE__) - status = nf90_put_var(ncid,varid,time_end(ns),start=(/2/)) - call ice_check_nc(status, subname// ' ERROR: writing time_end', & - file=__FILE__, line=__LINE__) - endif + + if (hist_avg(ns) .and. .not. write_ic) then + status = nf90_inq_varid(ncid,'time_bounds',varid) + call ice_check_nc(status, subname// ' ERROR: getting time_bounds id', & + file=__FILE__, line=__LINE__) + status = nf90_put_var(ncid,varid,time_beg(ns),start=(/1/)) + call ice_check_nc(status, subname// ' ERROR: writing time_beg', & + file=__FILE__, line=__LINE__) + status = nf90_put_var(ncid,varid,time_end(ns),start=(/2/)) + call ice_check_nc(status, subname// ' ERROR: writing time_end', & + file=__FILE__, line=__LINE__) + endif + + endif ! histfreq(ns)/='g' endif ! master_task @@ -724,7 +748,7 @@ subroutine ice_write_hist (ns) !----------------------------------------------------------------- do i = 1,ncoord - if(icoord(i)) then + if(icoord(i) .or. histfreq(ns)=='g') then call broadcast_scalar(var_coord(i)%short_name,master_task) SELECT CASE (var_coord(i)%short_name) CASE ('TLON') @@ -770,7 +794,7 @@ subroutine ice_write_hist (ns) ! Extra dimensions (NCAT, NFSD, VGRD*) do i = 1, nvar_grdz - if (igrdz(i)) then + if (igrdz(i) .or. histfreq(ns)=='g') then call broadcast_scalar(var_grdz(i)%short_name,master_task) if (my_task == master_task) then status = nf90_inq_varid(ncid, var_grdz(i)%short_name, varid) @@ -801,7 +825,7 @@ subroutine ice_write_hist (ns) !----------------------------------------------------------------- do i = 1, nvar_grd - if (igrd(i)) then + if (igrd(i) .or. histfreq(ns)=='g') then call broadcast_scalar(var_grd(i)%req%short_name,master_task) SELECT CASE (var_grd(i)%req%short_name) CASE ('tmask') @@ -863,7 +887,7 @@ subroutine ice_write_hist (ns) ! Write coordinates of grid box vertices !---------------------------------------------------------------- - if (f_bounds) then + if (f_bounds .or. histfreq(ns)=='g') then if (my_task==master_task) then allocate(work1_3(nverts,nx_global,ny_global)) else @@ -1381,12 +1405,21 @@ subroutine ice_hist_coord_def(ncid, coord, lprecision, dimids, varid) endif #endif - status = nf90_put_att(ncid,varid,'long_name',trim(coord%long_name)) - call ice_check_nc(status, subname// ' ERROR: defining long_name for '//coord%short_name, & - file=__FILE__, line=__LINE__) - status = nf90_put_att(ncid, varid, 'units', trim(coord%units)) - call ice_check_nc(status, subname// ' ERROR: defining units for '//coord%short_name, & - file=__FILE__, line=__LINE__) + if (coord%long_name(1:3) /= 'und') then + status = nf90_put_att(ncid,varid,'long_name',trim(coord%long_name)) + call ice_check_nc(status, subname// ' ERROR: defining long_name for '//coord%short_name, & + file=__FILE__, line=__LINE__) + endif + if (coord%units(1:3) /= 'und') then + status = nf90_put_att(ncid, varid, 'units', trim(coord%units)) + call ice_check_nc(status, subname// ' ERROR: defining units for '//coord%short_name, & + file=__FILE__, line=__LINE__) + endif + if (coord%axis(1:3) /= 'und') then + status = nf90_put_att(ncid, varid, 'axis', trim(coord%axis)) + call ice_check_nc(status, subname// ' ERROR: defining axis for '//coord%short_name, & + file=__FILE__, line=__LINE__) + endif #else call abort_ice(subname//' ERROR: USE_NETCDF cpp not defined', & diff --git a/cicecore/cicedyn/infrastructure/io/io_netcdf/ice_restart.F90 b/cicecore/cicedyn/infrastructure/io/io_netcdf/ice_restart.F90 index 3c0c126b0..33fd0cd1f 100644 --- a/cicecore/cicedyn/infrastructure/io/io_netcdf/ice_restart.F90 +++ b/cicecore/cicedyn/infrastructure/io/io_netcdf/ice_restart.F90 @@ -147,14 +147,14 @@ subroutine init_restart_write(filename_spec) use ice_dyn_shared, only: kdyn use ice_grid, only: grid_ice - character(len=char_len_long), intent(in), optional :: filename_spec + character(len=*), intent(in), optional :: filename_spec ! local variables logical (kind=log_kind) :: & skl_bgc, z_tracers, tr_fsd, & tr_iage, tr_FY, tr_lvl, tr_iso, tr_aero, & - tr_pond_topo, tr_pond_lvl, tr_brine, tr_snow, & + tr_pond_topo, tr_pond_lvl, tr_pond_sealvl, tr_brine, tr_snow, & tr_bgc_N, tr_bgc_C, tr_bgc_Nit, & tr_bgc_Sil, tr_bgc_DMS, & tr_bgc_chl, tr_bgc_Am, & @@ -190,6 +190,7 @@ subroutine init_restart_write(filename_spec) tr_iage_out=tr_iage, tr_FY_out=tr_FY, tr_lvl_out=tr_lvl, tr_fsd_out=tr_fsd, & tr_iso_out=tr_iso, tr_aero_out=tr_aero, & tr_pond_topo_out=tr_pond_topo, tr_pond_lvl_out=tr_pond_lvl, & + tr_pond_sealvl_out=tr_pond_sealvl, & tr_snow_out=tr_snow, tr_brine_out=tr_brine, & tr_bgc_N_out=tr_bgc_N, tr_bgc_C_out=tr_bgc_C, tr_bgc_Nit_out=tr_bgc_Nit, & tr_bgc_Sil_out=tr_bgc_Sil, tr_bgc_DMS_out=tr_bgc_DMS, & @@ -357,7 +358,7 @@ subroutine init_restart_write(filename_spec) call define_rest_field(ncid,'a12_4',dims) endif - if (tr_pond_lvl) then + if (tr_pond_lvl .or. tr_pond_sealvl) then call define_rest_field(ncid,'fsnow',dims) endif @@ -449,7 +450,7 @@ subroutine init_restart_write(filename_spec) call define_rest_field(ncid,'ipnd',dims) end if - if (tr_pond_lvl) then + if (tr_pond_lvl .or. tr_pond_sealvl) then call define_rest_field(ncid,'apnd',dims) call define_rest_field(ncid,'hpnd',dims) call define_rest_field(ncid,'ipnd',dims) diff --git a/cicecore/cicedyn/infrastructure/io/io_pio2/ice_history_write.F90 b/cicecore/cicedyn/infrastructure/io/io_pio2/ice_history_write.F90 index 05f1144a3..d935f2577 100644 --- a/cicecore/cicedyn/infrastructure/io/io_pio2/ice_history_write.F90 +++ b/cicecore/cicedyn/infrastructure/io/io_pio2/ice_history_write.F90 @@ -30,9 +30,10 @@ module ice_history_write private TYPE coord_attributes ! netcdf coordinate attributes - character (len=11) :: short_name - character (len=45) :: long_name - character (len=30) :: units + character (len=11) :: short_name + character (len=45) :: long_name + character (len=30) :: units + character (len=8) :: axis END TYPE coord_attributes TYPE req_attributes ! req'd netcdf attributes @@ -94,6 +95,7 @@ subroutine ice_write_hist (ns) character (len=char_len_long) :: title, cal_units, cal_att character (len=char_len) :: time_period_freq = 'none' character (len=char_len_long) :: ncfile + character (len=512) :: extvars integer (kind=int_kind) :: icategory,ind,i_aice,boundid, lprecision @@ -155,6 +157,7 @@ subroutine ice_write_hist (ns) if (icepack_warnings_aborted()) call abort_ice(error_message=subname, & file=__FILE__, line=__LINE__) + extvars = '' if (my_task == master_task) then call construct_filename(ncfile,'nc',ns) @@ -220,8 +223,12 @@ subroutine ice_write_hist (ns) call ice_pio_check(pio_def_dim(File,'nkaer',nzalyr,kmtida), & subname//' ERROR: defining dim nkaer',file=__FILE__,line=__LINE__) - call ice_pio_check(pio_def_dim(File,'time',PIO_UNLIMITED,timid), & - subname//' ERROR: defining dim time',file=__FILE__,line=__LINE__) + ! do not write time axis on grid output file + timid = -99 + if (histfreq(ns)/='g') then + call ice_pio_check(pio_def_dim(File,'time',PIO_UNLIMITED,timid), & + subname//' ERROR: defining dim time',file=__FILE__,line=__LINE__) + endif call ice_pio_check(pio_def_dim(File,'nvertices',nverts,nvertexid), & subname//' ERROR: defining dim nvertices',file=__FILE__,line=__LINE__) @@ -233,41 +240,45 @@ subroutine ice_write_hist (ns) ! define coordinate variables: time, time_bounds !----------------------------------------------------------------- - write(cdate,'(i8.8)') idate0 - write(cal_units,'(a,a4,a1,a2,a1,a2,a1,i2.2,a1,i2.2,a1,i2.2)') 'days since ', & - cdate(1:4),'-',cdate(5:6),'-',cdate(7:8),' ', & - hh_init,':',mm_init,':',ss_init - - if (days_per_year == 360) then - cal_att='360_day' - elseif (days_per_year == 365 .and. .not.use_leap_years ) then - cal_att='noleap' - elseif (use_leap_years) then - cal_att='Gregorian' - else - call abort_ice(subname//' ERROR: invalid calendar settings') - endif + ! do not write time axis on grid output file + if (histfreq(ns)/='g') then + + write(cdate,'(i8.8)') idate0 + write(cal_units,'(a,a4,a1,a2,a1,a2,a1,i2.2,a1,i2.2,a1,i2.2)') 'days since ', & + cdate(1:4),'-',cdate(5:6),'-',cdate(7:8),' ', & + hh_init,':',mm_init,':',ss_init + + if (days_per_year == 360) then + cal_att='360_day' + elseif (days_per_year == 365 .and. .not.use_leap_years ) then + cal_att='noleap' + elseif (use_leap_years) then + cal_att='proleptic_gregorian' + else + call abort_ice(subname//' ERROR: invalid calendar settings') + endif - time_coord = coord_attributes('time', 'time', trim(cal_units)) - call ice_hist_coord_def(File, time_coord, pio_double, (/timid/), varid) - call ice_pio_check(pio_put_att(File,varid,'calendar',cal_att), & - subname//' ERROR: defining att calendar: '//cal_att,file=__FILE__,line=__LINE__) - if (hist_avg(ns) .and. .not. write_ic) then - call ice_pio_check(pio_put_att(File,varid,'bounds','time_bounds'), & - subname//' ERROR: defining att bounds time_bounds',file=__FILE__,line=__LINE__) - endif + time_coord = coord_attributes('time', 'time', trim(cal_units), 'T') + call ice_hist_coord_def(File, time_coord, pio_double, (/timid/), varid) + call ice_pio_check(pio_put_att(File,varid,'calendar',cal_att), & + subname//' ERROR: defining att calendar: '//cal_att,file=__FILE__,line=__LINE__) + if (hist_avg(ns) .and. .not. write_ic) then + call ice_pio_check(pio_put_att(File,varid,'bounds','time_bounds'), & + subname//' ERROR: defining att bounds time_bounds',file=__FILE__,line=__LINE__) + endif - ! Define coord time_bounds if hist_avg is true - if (hist_avg(ns) .and. .not. write_ic) then - time_coord = coord_attributes('time_bounds', 'time interval endpoints', trim(cal_units)) + ! Define coord time_bounds if hist_avg is true + ! bounds inherit attributes + if (hist_avg(ns) .and. .not. write_ic) then + time_coord = coord_attributes('time_bounds', 'undefined', 'undefined', 'undefined') - dimid2(1) = boundid - dimid2(2) = timid + dimid2(1) = boundid + dimid2(2) = timid - call ice_hist_coord_def(File, time_coord, pio_double, dimid2, varid) - call ice_pio_check(pio_put_att(File,varid,'calendar',cal_att), & - subname//' ERROR: defining att calendar: '//cal_att,file=__FILE__,line=__LINE__) - endif + call ice_hist_coord_def(File, time_coord, pio_double, dimid2, varid) + endif + + endif ! histfreq(ns)/='g' !----------------------------------------------------------------- ! define information for required time-invariant variables @@ -277,138 +288,131 @@ subroutine ice_write_hist (ns) select case (ind) case(n_tlon) var_coord(ind) = coord_attributes('TLON', & - 'T grid center longitude', 'degrees_east') + 'T grid center longitude', 'degrees_east', 'X') coord_bounds(ind) = 'lont_bounds' case(n_tlat) var_coord(ind) = coord_attributes('TLAT', & - 'T grid center latitude', 'degrees_north') + 'T grid center latitude', 'degrees_north', 'Y') coord_bounds(ind) = 'latt_bounds' case(n_ulon) var_coord(ind) = coord_attributes('ULON', & - 'U grid center longitude', 'degrees_east') + 'U grid center longitude', 'degrees_east', 'X') coord_bounds(ind) = 'lonu_bounds' case(n_ulat) var_coord(ind) = coord_attributes('ULAT', & - 'U grid center latitude', 'degrees_north') + 'U grid center latitude', 'degrees_north', 'Y') coord_bounds(ind) = 'latu_bounds' case(n_nlon) var_coord(ind) = coord_attributes('NLON', & - 'N grid center longitude', 'degrees_east') + 'N grid center longitude', 'degrees_east', 'X') coord_bounds(ind) = 'lonn_bounds' case(n_nlat) var_coord(ind) = coord_attributes('NLAT', & - 'N grid center latitude', 'degrees_north') + 'N grid center latitude', 'degrees_north', 'Y') coord_bounds(ind) = 'latn_bounds' case(n_elon) var_coord(ind) = coord_attributes('ELON', & - 'E grid center longitude', 'degrees_east') + 'E grid center longitude', 'degrees_east', 'X') coord_bounds(ind) = 'lone_bounds' case(n_elat) var_coord(ind) = coord_attributes('ELAT', & - 'E grid center latitude', 'degrees_north') + 'E grid center latitude', 'degrees_north', 'Y') coord_bounds(ind) = 'late_bounds' end select end do - var_grdz(1) = coord_attributes('NCAT', 'category maximum thickness', 'm') - var_grdz(2) = coord_attributes('VGRDi', 'vertical ice levels', '1') - var_grdz(3) = coord_attributes('VGRDs', 'vertical snow levels', '1') - var_grdz(4) = coord_attributes('VGRDb', 'vertical ice-bio levels', '1') - var_grdz(5) = coord_attributes('VGRDa', 'vertical snow-ice-bio levels', '1') - var_grdz(6) = coord_attributes('NFSD', 'category floe size (center)', 'm') + var_grdz(1) = coord_attributes('NCAT', 'category maximum thickness', 'm', 'undefined') + var_grdz(2) = coord_attributes('VGRDi', 'vertical ice levels', '1', 'undefined') + var_grdz(3) = coord_attributes('VGRDs', 'vertical snow levels', '1', 'undefined') + var_grdz(4) = coord_attributes('VGRDb', 'vertical ice-bio levels', '1', 'undefined') + var_grdz(5) = coord_attributes('VGRDa', 'vertical snow-ice-bio levels', '1', 'undefined') + var_grdz(6) = coord_attributes('NFSD', 'category floe size (center)', 'm', 'undefined') !----------------------------------------------------------------- ! define information for optional time-invariant variables !----------------------------------------------------------------- var_grd(n_tmask)%req = coord_attributes('tmask', & - 'mask of T grid cells, 0 = land, 1 = ocean', 'unitless') + 'mask of T grid cells, 0 = land, 1 = ocean', '1', 'undefined') var_grd(n_tmask)%coordinates = 'TLON TLAT' var_grd(n_umask)%req = coord_attributes('umask', & - 'mask of U grid cells, 0 = land, 1 = ocean', 'unitless') + 'mask of U grid cells, 0 = land, 1 = ocean', '1', 'undefined') var_grd(n_umask)%coordinates = 'ULON ULAT' var_grd(n_nmask)%req = coord_attributes('nmask', & - 'mask of N grid cells, 0 = land, 1 = ocean', 'unitless') + 'mask of N grid cells, 0 = land, 1 = ocean', '1', 'undefined') var_grd(n_nmask)%coordinates = 'NLON NLAT' var_grd(n_emask)%req = coord_attributes('emask', & - 'mask of E grid cells, 0 = land, 1 = ocean', 'unitless') + 'mask of E grid cells, 0 = land, 1 = ocean', '1', 'undefined') var_grd(n_emask)%coordinates = 'ELON ELAT' var_grd(n_blkmask)%req = coord_attributes('blkmask', & - 'ice grid block mask, mytask + iblk/100', 'unitless') + 'block id of T grid cells, mytask + iblk/100', '1', 'undefined') var_grd(n_blkmask)%coordinates = 'TLON TLAT' var_grd(n_tarea)%req = coord_attributes('tarea', & - 'area of T grid cells', 'm^2') + 'area of T grid cells', 'm^2', 'undefined') var_grd(n_tarea)%coordinates = 'TLON TLAT' var_grd(n_uarea)%req = coord_attributes('uarea', & - 'area of U grid cells', 'm^2') + 'area of U grid cells', 'm^2', 'undefined') var_grd(n_uarea)%coordinates = 'ULON ULAT' var_grd(n_narea)%req = coord_attributes('narea', & - 'area of N grid cells', 'm^2') + 'area of N grid cells', 'm^2', 'undefined') var_grd(n_narea)%coordinates = 'NLON NLAT' var_grd(n_earea)%req = coord_attributes('earea', & - 'area of E grid cells', 'm^2') + 'area of E grid cells', 'm^2', 'undefined') var_grd(n_earea)%coordinates = 'ELON ELAT' var_grd(n_dxt)%req = coord_attributes('dxt', & - 'T cell width through middle', 'm') + 'T cell width through middle', 'm', 'undefined') var_grd(n_dxt)%coordinates = 'TLON TLAT' var_grd(n_dyt)%req = coord_attributes('dyt', & - 'T cell height through middle', 'm') + 'T cell height through middle', 'm', 'undefined') var_grd(n_dyt)%coordinates = 'TLON TLAT' var_grd(n_dxu)%req = coord_attributes('dxu', & - 'U cell width through middle', 'm') + 'U cell width through middle', 'm', 'undefined') var_grd(n_dxu)%coordinates = 'ULON ULAT' var_grd(n_dyu)%req = coord_attributes('dyu', & - 'U cell height through middle', 'm') + 'U cell height through middle', 'm', 'undefined') var_grd(n_dyu)%coordinates = 'ULON ULAT' var_grd(n_dxn)%req = coord_attributes('dxn', & - 'N cell width through middle', 'm') + 'N cell width through middle', 'm', 'undefined') var_grd(n_dxn)%coordinates = 'NLON NLAT' var_grd(n_dyn)%req = coord_attributes('dyn', & - 'N cell height through middle', 'm') + 'N cell height through middle', 'm', 'undefined') var_grd(n_dyn)%coordinates = 'NLON NLAT' var_grd(n_dxe)%req = coord_attributes('dxe', & - 'E cell width through middle', 'm') + 'E cell width through middle', 'm', 'undefined') var_grd(n_dxe)%coordinates = 'ELON ELAT' var_grd(n_dye)%req = coord_attributes('dye', & - 'E cell height through middle', 'm') + 'E cell height through middle', 'm', 'undefined') var_grd(n_dye)%coordinates = 'ELON ELAT' var_grd(n_HTN)%req = coord_attributes('HTN', & - 'T cell width on North side','m') + 'T cell width on North side','m', 'undefined') var_grd(n_HTN)%coordinates = 'TLON TLAT' var_grd(n_HTE)%req = coord_attributes('HTE', & - 'T cell width on East side', 'm') + 'T cell width on East side', 'm', 'undefined') var_grd(n_HTE)%coordinates = 'TLON TLAT' var_grd(n_ANGLE)%req = coord_attributes('ANGLE', & 'angle grid makes with latitude line on U grid', & - 'radians') + 'radians', 'undefined') var_grd(n_ANGLE)%coordinates = 'ULON ULAT' var_grd(n_ANGLET)%req = coord_attributes('ANGLET', & 'angle grid makes with latitude line on T grid', & - 'radians') + 'radians', 'undefined') var_grd(n_ANGLET)%coordinates = 'TLON TLAT' - ! These fields are required for CF compliance + ! bounds fields are required for CF compliance ! dimensions (nx,ny,nverts) - var_nverts(n_lont_bnds) = coord_attributes('lont_bounds', & - 'longitude boundaries of T cells', 'degrees_east') - var_nverts(n_latt_bnds) = coord_attributes('latt_bounds', & - 'latitude boundaries of T cells', 'degrees_north') - var_nverts(n_lonu_bnds) = coord_attributes('lonu_bounds', & - 'longitude boundaries of U cells', 'degrees_east') - var_nverts(n_latu_bnds) = coord_attributes('latu_bounds', & - 'latitude boundaries of U cells', 'degrees_north') - var_nverts(n_lonn_bnds) = coord_attributes('lonn_bounds', & - 'longitude boundaries of N cells', 'degrees_east') - var_nverts(n_latn_bnds) = coord_attributes('latn_bounds', & - 'latitude boundaries of N cells', 'degrees_north') - var_nverts(n_lone_bnds) = coord_attributes('lone_bounds', & - 'longitude boundaries of E cells', 'degrees_east') - var_nverts(n_late_bnds) = coord_attributes('late_bounds', & - 'latitude boundaries of E cells', 'degrees_north') + ! bounds inherit attributes + var_nverts(n_lont_bnds) = coord_attributes('lont_bounds','und','und','und') + var_nverts(n_latt_bnds) = coord_attributes('latt_bounds','und','und','und') + var_nverts(n_lonu_bnds) = coord_attributes('lonu_bounds','und','und','und') + var_nverts(n_latu_bnds) = coord_attributes('latu_bounds','und','und','und') + var_nverts(n_lonn_bnds) = coord_attributes('lonn_bounds','und','und','und') + var_nverts(n_latn_bnds) = coord_attributes('latn_bounds','und','und','und') + var_nverts(n_lone_bnds) = coord_attributes('lone_bounds','und','und','und') + var_nverts(n_late_bnds) = coord_attributes('late_bounds','und','und','und') !----------------------------------------------------------------- ! define attributes for time-invariant variables @@ -418,7 +422,7 @@ subroutine ice_write_hist (ns) dimid2(2) = jmtid do i = 1, ncoord - if (icoord(i)) then + if (icoord(i) .or. histfreq(ns)=='g') then call ice_hist_coord_def(File, var_coord(i), lprecision, dimid2, varid) call ice_write_hist_fill(File,varid,var_coord(i)%short_name,history_precision) if (var_coord(i)%short_name == 'ULAT') then @@ -426,10 +430,12 @@ subroutine ice_write_hist (ns) trim('Latitude of NE corner of T grid cell')), & subname//' ERROR: defining att comment',file=__FILE__,line=__LINE__) endif - if (f_bounds) then + if (f_bounds .or. histfreq(ns)=='g') then call ice_pio_check(pio_put_att(File, varid, 'bounds', trim(coord_bounds(i))), & subname//' ERROR: defining att bounds '//trim(coord_bounds(i)),file=__FILE__,line=__LINE__) endif + else + extvars = trim(extvars)//' '//trim(var_coord(i)%short_name) endif enddo @@ -442,28 +448,32 @@ subroutine ice_write_hist (ns) dimidex(6)=fmtid do i = 1, nvar_grdz - if (igrdz(i)) then + if (igrdz(i) .or. histfreq(ns)=='g') then call ice_hist_coord_def(File, var_grdz(i), lprecision, dimidex(i:i), varid) + else + extvars = trim(extvars)//' '//trim(var_grdz(i)%short_name) endif enddo do i = 1, nvar_grd - if (igrd(i)) then + if (igrd(i) .or. histfreq(ns)=='g') then call ice_hist_coord_def(File, var_grd(i)%req, lprecision, dimid2, varid) call ice_pio_check(pio_put_att(File, varid, 'coordinates', trim(var_grd(i)%coordinates)), & subname//' ERROR: defining att coordinates '//trim(var_grd(i)%coordinates),file=__FILE__,line=__LINE__) call ice_write_hist_fill(File,varid,var_grd(i)%req%short_name,history_precision) + else + extvars = trim(extvars)//' '//trim(var_grd(i)%req%short_name) endif enddo - ! Fields with dimensions (nverts,nx,ny) + ! bounds fields with dimensions (nverts,nx,ny) + ! bounds inherit attributes dimid_nverts(1) = nvertexid dimid_nverts(2) = imtid dimid_nverts(3) = jmtid do i = 1, nvar_verts - if (f_bounds) then + if (f_bounds .or. histfreq(ns)=='g') then call ice_hist_coord_def(File, var_nverts(i), lprecision, dimid_nverts, varid) - call ice_write_hist_fill(File,varid,var_nverts(i)%short_name,history_precision) endif enddo @@ -640,10 +650,13 @@ subroutine ice_write_hist (ns) call ice_pio_check(pio_put_att(File,pio_global,'time_axis_position',trim(hist_time_axis)), & subname//' ERROR: defining att time_axis_position '//trim(hist_time_axis),file=__FILE__,line=__LINE__) - title = 'CF-1.0' - call ice_pio_check(pio_put_att(File,pio_global,'conventions',trim(title)), & + title = 'CF-1.8' + call ice_pio_check(pio_put_att(File,pio_global,'Conventions',trim(title)), & subname//' ERROR: defining att conventions '//trim(title),file=__FILE__,line=__LINE__) + call ice_pio_check(pio_put_att(File,pio_global,'external_variables',trim(extvars)), & + subname//' ERROR: defining att external_variables '//trim(extvars),file=__FILE__,line=__LINE__) + call date_and_time(date=current_date, time=current_time) write(start_time,1000) current_date(1:4), current_date(5:6), & current_date(7:8), current_time(1:2), & @@ -653,6 +666,13 @@ subroutine ice_write_hist (ns) call ice_pio_check(pio_put_att(File,pio_global,'history',trim(start_time)), & subname//' ERROR: defining att history '//trim(start_time),file=__FILE__,line=__LINE__) + write(start_time,1001) current_date(1:4), current_date(5:6), & + current_date(7:8), current_time(1:2), & + current_time(3:4) +1001 format(a,'-',a,'-',a,' ',a,':',a) + call ice_pio_check(pio_put_att(File,pio_global,'date_created',trim(start_time)), & + subname//' ERROR: defining att date_created '//trim(start_time),file=__FILE__,line=__LINE__) + #ifdef USE_PIO1 call ice_pio_check(pio_put_att(File,pio_global,'io_flavor','io_pio1 '//trim(history_format)), & subname//' ERROR: defining att io_flavor',file=__FILE__,line=__LINE__) @@ -669,36 +689,35 @@ subroutine ice_write_hist (ns) subname//' ERROR: ending pio definitions',file=__FILE__,line=__LINE__) !----------------------------------------------------------------- - ! write time variable + ! write time and time bounds info !----------------------------------------------------------------- - ltime2 = timesecs/secday ! hist_time_axis = 'end' (default) - - ! Some coupled models require the time axis "stamp" to be in the middle - ! or even beginning of averaging interval. - if (hist_avg(ns)) then - if (trim(hist_time_axis) == "begin" ) ltime2 = time_beg(ns) - if (trim(hist_time_axis) == "middle") ltime2 = p5*(time_beg(ns)+time_end(ns)) - endif + ! do not write time axis on grid output file + if (histfreq(ns)/='g') then + ltime2 = timesecs/secday ! hist_time_axis = 'end' (default) - call ice_pio_check(pio_inq_varid(File,'time',varid), & - subname//' ERROR: getting var time',file=__FILE__,line=__LINE__) - call ice_pio_check(pio_put_var(File,varid,(/1/),ltime2), & - subname//' ERROR: setting var time',file=__FILE__,line=__LINE__) - - !----------------------------------------------------------------- - ! write time_bounds info - !----------------------------------------------------------------- + ! Some coupled models require the time axis "stamp" to be in the middle + ! or even beginning of averaging interval. + if (hist_avg(ns)) then + if (trim(hist_time_axis) == "begin" ) ltime2 = time_beg(ns) + if (trim(hist_time_axis) == "middle") ltime2 = p5*(time_beg(ns)+time_end(ns)) + endif - if (hist_avg(ns) .and. .not. write_ic) then - call ice_pio_check(pio_inq_varid(File,'time_bounds',varid), & - subname//' ERROR: getting time_bounds' ,file=__FILE__,line=__LINE__) - time_bounds=(/time_beg(ns),time_end(ns)/) - bnd_start = (/1,1/) - bnd_length = (/2,1/) - call ice_pio_check(pio_put_var(File,varid,ival=time_bounds,start=bnd_start(:),count=bnd_length(:)), & - subname//' ERROR: setting time_bounds' ,file=__FILE__,line=__LINE__) - endif + call ice_pio_check(pio_inq_varid(File,'time',varid), & + subname//' ERROR: getting var time',file=__FILE__,line=__LINE__) + call ice_pio_check(pio_put_var(File,varid,(/1/),ltime2), & + subname//' ERROR: setting var time',file=__FILE__,line=__LINE__) + + if (hist_avg(ns) .and. .not. write_ic) then + call ice_pio_check(pio_inq_varid(File,'time_bounds',varid), & + subname//' ERROR: getting time_bounds' ,file=__FILE__,line=__LINE__) + time_bounds=(/time_beg(ns),time_end(ns)/) + bnd_start = (/1,1/) + bnd_length = (/2,1/) + call ice_pio_check(pio_put_var(File,varid,ival=time_bounds,start=bnd_start(:),count=bnd_length(:)), & + subname//' ERROR: setting time_bounds' ,file=__FILE__,line=__LINE__) + endif + endif ! histfreq(ns)/='g' !----------------------------------------------------------------- ! write coordinate variables @@ -708,7 +727,7 @@ subroutine ice_write_hist (ns) allocate(workr2(nx_block,ny_block,nblocks)) do i = 1,ncoord - if(icoord(i)) then + if(icoord(i) .or. histfreq(ns)=='g') then call ice_pio_check(pio_inq_varid(File, var_coord(i)%short_name, varid), & subname//' ERROR: getting '//var_coord(i)%short_name ,file=__FILE__,line=__LINE__) SELECT CASE (var_coord(i)%short_name) @@ -747,7 +766,7 @@ subroutine ice_write_hist (ns) ! Extra dimensions (NCAT, NFSD, VGRD*) do i = 1, nvar_grdz - if (igrdz(i)) then + if (igrdz(i) .or. histfreq(ns)=='g') then call ice_pio_check(pio_inq_varid(File, var_grdz(i)%short_name, varid), & subname//' ERROR: getting '//var_grdz(i)%short_name,file=__FILE__,line=__LINE__) SELECT CASE (var_grdz(i)%short_name) @@ -778,7 +797,7 @@ subroutine ice_write_hist (ns) !----------------------------------------------------------------- do i = 1, nvar_grd - if (igrd(i)) then + if (igrd(i) .or. histfreq(ns)=='g') then SELECT CASE (var_grd(i)%req%short_name) CASE ('tmask') workd2 = hm(:,:,1:nblocks) @@ -843,7 +862,7 @@ subroutine ice_write_hist (ns) ! Write coordinates of grid box vertices !---------------------------------------------------------------- - if (f_bounds) then + if (f_bounds .or. histfreq(ns)=='g') then allocate(workd3v(nverts,nx_block,ny_block,nblocks)) allocate(workr3v(nverts,nx_block,ny_block,nblocks)) workd3v (:,:,:,:) = c0 @@ -1115,8 +1134,8 @@ subroutine ice_write_hist (ns) deallocate(workd3) deallocate(workr3) - allocate(workd4(nx_block,ny_block,nblocks,ncat_hist,nzilyr)) - allocate(workr4(nx_block,ny_block,nblocks,ncat_hist,nzilyr)) + allocate(workd4(nx_block,ny_block,nblocks,nzilyr,ncat_hist)) + allocate(workr4(nx_block,ny_block,nblocks,nzilyr,ncat_hist)) ! 4D (categories, fsd) do n = n3Dfcum+1, n4Dicum nn = n - n3Dfcum @@ -1126,7 +1145,7 @@ subroutine ice_write_hist (ns) do j = 1, nblocks do i = 1, ncat_hist do k = 1, nzilyr - workd4(:,:,j,i,k) = a4Di(:,:,k,i,nn,j) + workd4(:,:,j,k,i) = a4Di(:,:,k,i,nn,j) enddo ! k enddo ! i enddo ! j @@ -1152,8 +1171,8 @@ subroutine ice_write_hist (ns) deallocate(workd4) deallocate(workr4) - allocate(workd4(nx_block,ny_block,nblocks,ncat_hist,nzslyr)) - allocate(workr4(nx_block,ny_block,nblocks,ncat_hist,nzslyr)) + allocate(workd4(nx_block,ny_block,nblocks,nzslyr,ncat_hist)) + allocate(workr4(nx_block,ny_block,nblocks,nzslyr,ncat_hist)) ! 4D (categories, vertical ice) do n = n4Dicum+1, n4Dscum nn = n - n4Dicum @@ -1163,7 +1182,7 @@ subroutine ice_write_hist (ns) do j = 1, nblocks do i = 1, ncat_hist do k = 1, nzslyr - workd4(:,:,j,i,k) = a4Ds(:,:,k,i,nn,j) + workd4(:,:,j,k,i) = a4Ds(:,:,k,i,nn,j) enddo ! k enddo ! i enddo ! j @@ -1190,8 +1209,8 @@ subroutine ice_write_hist (ns) deallocate(workd4) deallocate(workr4) - allocate(workd4(nx_block,ny_block,nblocks,ncat_hist,nfsd_hist)) - allocate(workr4(nx_block,ny_block,nblocks,ncat_hist,nfsd_hist)) + allocate(workd4(nx_block,ny_block,nblocks,nfsd_hist,ncat_hist)) + allocate(workr4(nx_block,ny_block,nblocks,nfsd_hist,ncat_hist)) ! 4D (categories, vertical ice) do n = n4Dscum+1, n4Dfcum nn = n - n4Dscum @@ -1201,7 +1220,7 @@ subroutine ice_write_hist (ns) do j = 1, nblocks do i = 1, ncat_hist do k = 1, nfsd_hist - workd4(:,:,j,i,k) = a4Df(:,:,k,i,nn,j) + workd4(:,:,j,k,i) = a4Df(:,:,k,i,nn,j) enddo ! k enddo ! i enddo ! j @@ -1315,10 +1334,18 @@ subroutine ice_hist_coord_def(File, coord,lprecision, dimids,varid) endif endif #endif - call ice_pio_check(pio_put_att(File,varid,'long_name',trim(coord%long_name)), & - subname//' ERROR: defining att long_name '//coord%long_name,file=__FILE__,line=__LINE__) - call ice_pio_check(pio_put_att(File, varid, 'units', trim(coord%units)), & - subname//' ERROR: defining att units '//coord%units,file=__FILE__,line=__LINE__) + if (coord%long_name(1:3) /= 'und') then + call ice_pio_check(pio_put_att(File,varid,'long_name',trim(coord%long_name)), & + subname//' ERROR: defining att long_name '//coord%long_name,file=__FILE__,line=__LINE__) + endif + if (coord%units(1:3) /= 'und') then + call ice_pio_check(pio_put_att(File, varid, 'units', trim(coord%units)), & + subname//' ERROR: defining att units '//coord%units,file=__FILE__,line=__LINE__) + endif + if (coord%axis(1:3) /= 'und') then + call ice_pio_check(pio_put_att(File, varid, 'axis', trim(coord%axis)), & + subname//' ERROR: defining att axis '//coord%units,file=__FILE__,line=__LINE__) + endif end subroutine ice_hist_coord_def diff --git a/cicecore/cicedyn/infrastructure/io/io_pio2/ice_restart.F90 b/cicecore/cicedyn/infrastructure/io/io_pio2/ice_restart.F90 index 0f9070fef..b06501483 100644 --- a/cicecore/cicedyn/infrastructure/io/io_pio2/ice_restart.F90 +++ b/cicecore/cicedyn/infrastructure/io/io_pio2/ice_restart.F90 @@ -156,7 +156,7 @@ subroutine init_restart_write(filename_spec) use ice_arrays_column, only: oceanmixed_ice use ice_grid, only: grid_ice - character(len=char_len_long), intent(in), optional :: filename_spec + character(len=*), intent(in), optional :: filename_spec ! local variables @@ -165,7 +165,7 @@ subroutine init_restart_write(filename_spec) logical (kind=log_kind) :: & tr_iage, tr_FY, tr_lvl, tr_iso, tr_aero, & - tr_pond_topo, tr_pond_lvl, tr_brine, tr_snow, & + tr_pond_topo, tr_pond_lvl, tr_pond_sealvl, tr_brine, tr_snow, & tr_bgc_N, tr_bgc_C, tr_bgc_Nit, & tr_bgc_Sil, tr_bgc_DMS, & tr_bgc_chl, tr_bgc_Am, & @@ -196,6 +196,7 @@ subroutine init_restart_write(filename_spec) tr_iage_out=tr_iage, tr_FY_out=tr_FY, tr_lvl_out=tr_lvl, & tr_iso_out=tr_iso, tr_aero_out=tr_aero, & tr_pond_topo_out=tr_pond_topo, tr_pond_lvl_out=tr_pond_lvl, & + tr_pond_sealvl_out=tr_pond_sealvl, & tr_snow_out=tr_snow, tr_brine_out=tr_brine, & tr_bgc_N_out=tr_bgc_N, tr_bgc_C_out=tr_bgc_C, tr_bgc_Nit_out=tr_bgc_Nit, & tr_bgc_Sil_out=tr_bgc_Sil, tr_bgc_DMS_out=tr_bgc_DMS, & @@ -342,7 +343,7 @@ subroutine init_restart_write(filename_spec) call define_rest_field(File,'a12_4',dims) endif - if (tr_pond_lvl) then + if (tr_pond_lvl .or. tr_pond_sealvl) then call define_rest_field(File,'fsnow',dims) endif @@ -434,7 +435,7 @@ subroutine init_restart_write(filename_spec) call define_rest_field(File,'ipnd',dims) end if - if (tr_pond_lvl) then + if (tr_pond_lvl .or. tr_pond_sealvl) then call define_rest_field(File,'apnd',dims) call define_rest_field(File,'hpnd',dims) call define_rest_field(File,'ipnd',dims) diff --git a/cicecore/drivers/direct/hadgem3/CICE.F90 b/cicecore/drivers/direct/hadgem3/CICE.F90 index 2cdac546a..a7233fe39 100644 --- a/cicecore/drivers/direct/hadgem3/CICE.F90 +++ b/cicecore/drivers/direct/hadgem3/CICE.F90 @@ -1,17 +1,17 @@ !======================================================================= -! Copyright (c) 2024, Triad National Security, LLC +! Copyright (c) 1998, 2017, Triad National Security, LLC ! All rights reserved. ! -! Copyright 2024. Triad National Security, LLC. This software was -! produced under U.S. Government contract DE-AC52-06NA25396 for Los -! Alamos National Laboratory (LANL), which is operated by Triad -! National Security, LLC for the U.S. Department of Energy. The U.S. -! Government has rights to use, reproduce, and distribute this software. -! NEITHER THE GOVERNMENT NOR TRIAD NATIONAL SECURITY, LLC MAKES ANY -! WARRANTY, EXPRESS OR IMPLIED, OR ASSUMES ANY LIABILITY FOR THE USE OF -! THIS SOFTWARE. If software is modified to produce derivative works, -! such modified software should be clearly marked, so as not to confuse -! it with the version available from LANL. +! This program was produced under U.S. Government contract 89233218CNA000001 +! for Los Alamos National Laboratory (LANL), which is operated by Triad +! National Security, LLC for the U.S. Department of Energy/National Nuclear +! Security Administration. All rights in the program are reserved by Triad +! National Security, LLC, and the U.S. Department of Energy/National Nuclear +! Security Administration. The Government is granted for itself and others +! acting on its behalf a nonexclusive, paid-up, irrevocable worldwide +! license in this material to reproduce, prepare. derivative works, +! distribute copies to the public, perform publicly and display publicly, +! and to permit others to do so. ! ! The full license and distribution policy are available from ! https://github.com/CICE-Consortium diff --git a/cicecore/drivers/direct/hadgem3/CICE_InitMod.F90 b/cicecore/drivers/direct/hadgem3/CICE_InitMod.F90 index c64bd463c..cc3a4caff 100644 --- a/cicecore/drivers/direct/hadgem3/CICE_InitMod.F90 +++ b/cicecore/drivers/direct/hadgem3/CICE_InitMod.F90 @@ -242,7 +242,7 @@ subroutine init_restart restart_fsd, read_restart_fsd, & restart_aero, read_restart_aero, & restart_hbrine, read_restart_hbrine, & - restart_zsal, restart_bgc + restart_bgc use ice_restart_driver, only: restartfile, restartfile_v4 use ice_restart_shared, only: runtype, restart use ice_state ! almost everything @@ -253,7 +253,7 @@ subroutine init_restart logical(kind=log_kind) :: & tr_iage, tr_FY, tr_lvl, tr_pond_lvl, & tr_pond_topo, tr_fsd, tr_aero, tr_brine, & - skl_bgc, z_tracers, solve_zsal + skl_bgc, z_tracers integer(kind=int_kind) :: & ntrcr integer(kind=int_kind) :: & @@ -268,7 +268,7 @@ subroutine init_restart file=__FILE__, line=__LINE__) call icepack_query_parameters(skl_bgc_out=skl_bgc, & - z_tracers_out=z_tracers, solve_zsal_out=solve_zsal) + z_tracers_out=z_tracers) call icepack_query_tracer_flags(tr_iage_out=tr_iage, tr_FY_out=tr_FY, & tr_lvl_out=tr_lvl, tr_pond_lvl_out=tr_pond_lvl, & tr_pond_topo_out=tr_pond_topo, tr_aero_out=tr_aero, tr_brine_out=tr_brine, & @@ -296,8 +296,7 @@ subroutine init_restart ! tracers ! ice age tracer if (tr_iage) then - if (trim(runtype) == 'continue') & - restart_age = .true. + if (trim(runtype) == 'continue') restart_age = .true. if (restart_age) then call read_restart_age else @@ -331,8 +330,7 @@ subroutine init_restart endif ! level-ice melt ponds if (tr_pond_lvl) then - if (trim(runtype) == 'continue') & - restart_pond_lvl = .true. + if (trim(runtype) == 'continue') restart_pond_lvl = .true. if (restart_pond_lvl) then call read_restart_pond_lvl else @@ -346,8 +344,7 @@ subroutine init_restart endif ! topographic melt ponds if (tr_pond_topo) then - if (trim(runtype) == 'continue') & - restart_pond_topo = .true. + if (trim(runtype) == 'continue') restart_pond_topo = .true. if (restart_pond_topo) then call read_restart_pond_topo else @@ -379,12 +376,8 @@ subroutine init_restart endif if (trim(runtype) == 'continue') then - if (tr_brine) & - restart_hbrine = .true. - if (solve_zsal) & - restart_zsal = .true. - if (skl_bgc .or. z_tracers) & - restart_bgc = .true. + if (tr_brine) restart_hbrine = .true. + if (skl_bgc .or. z_tracers) restart_bgc = .true. endif if (tr_brine .or. skl_bgc) then ! brine height tracer @@ -392,7 +385,7 @@ subroutine init_restart if (tr_brine .and. restart_hbrine) call read_restart_hbrine endif - if (solve_zsal .or. skl_bgc .or. z_tracers) then ! biogeochemistry + if (skl_bgc .or. z_tracers) then ! biogeochemistry if (tr_fsd) then write (nu_diag,*) 'FSD implementation incomplete for use with BGC' call icepack_warnings_flush(nu_diag) diff --git a/cicecore/drivers/direct/hadgem3/CICE_RunMod.F90 b/cicecore/drivers/direct/hadgem3/CICE_RunMod.F90 index 43a1a003f..ca0099680 100644 --- a/cicecore/drivers/direct/hadgem3/CICE_RunMod.F90 +++ b/cicecore/drivers/direct/hadgem3/CICE_RunMod.F90 @@ -134,7 +134,7 @@ subroutine ice_step use ice_boundary, only: ice_HaloUpdate use ice_calendar, only: dt, dt_dyn, ndtd, diagfreq, write_restart, istep use ice_diagnostics, only: init_mass_diags, runtime_diags - use ice_diagnostics_bgc, only: hbrine_diags, zsal_diags, bgc_diags + use ice_diagnostics_bgc, only: hbrine_diags, bgc_diags use ice_domain, only: halo_info, nblocks use ice_domain_size, only: nslyr use ice_dyn_eap, only: write_restart_eap @@ -169,12 +169,12 @@ subroutine ice_step logical (kind=log_kind) :: & tr_iage, tr_FY, tr_lvl, tr_fsd, & tr_pond_lvl, tr_pond_topo, tr_brine, tr_aero, & - calc_Tsfc, skl_bgc, solve_zsal, z_tracers, wave_spec + calc_Tsfc, skl_bgc, z_tracers, wave_spec character(len=*), parameter :: subname = '(ice_step)' call icepack_query_parameters(calc_Tsfc_out=calc_Tsfc, skl_bgc_out=skl_bgc, & - solve_zsal_out=solve_zsal, z_tracers_out=z_tracers, ktherm_out=ktherm, & + z_tracers_out=z_tracers, ktherm_out=ktherm, & wave_spec_out=wave_spec) call icepack_query_tracer_flags(tr_iage_out=tr_iage, tr_FY_out=tr_FY, & tr_lvl_out=tr_lvl, tr_pond_lvl_out=tr_pond_lvl, & @@ -307,7 +307,6 @@ subroutine ice_step call ice_timer_start(timer_diags) ! diagnostics if (mod(istep,diagfreq) == 0) then call runtime_diags(dt) ! log file - if (solve_zsal) call zsal_diags if (skl_bgc .or. z_tracers) call bgc_diags if (tr_brine) call hbrine_diags endif @@ -327,7 +326,7 @@ subroutine ice_step if (tr_pond_topo) call write_restart_pond_topo if (tr_fsd) call write_restart_fsd if (tr_aero) call write_restart_aero - if (solve_zsal .or. skl_bgc .or. z_tracers) & + if (skl_bgc .or. z_tracers) & call write_restart_bgc if (tr_brine) call write_restart_hbrine if (kdyn == 2) call write_restart_eap @@ -347,7 +346,7 @@ end subroutine ice_step subroutine coupling_prep (iblk) use ice_arrays_column, only: alvdfn, alidfn, alvdrn, alidrn, & - albicen, albsnon, albpndn, apeffn, fzsal_g, fzsal, snowfracn + albicen, albsnon, albpndn, apeffn, snowfracn use ice_blocks, only: nx_block, ny_block, get_block, block use ice_domain, only: blocks_ice use ice_calendar, only: dt, nstreams @@ -361,7 +360,7 @@ subroutine coupling_prep (iblk) swvdr, swidr, swvdf, swidf, Tf, Tair, Qa, strairxT, strairyt, & fsens, flat, fswabs, flwout, evap, Tref, Qref, & fsurfn_f, flatn_f, scale_fluxes, frzmlt_init, frzmlt - use ice_flux_bgc, only: faero_ocn, fzsal_ai, fzsal_g_ai, flux_bio, flux_bio_ai + use ice_flux_bgc, only: faero_ocn, flux_bio, flux_bio_ai use ice_grid, only: tmask use ice_state, only: aicen, aice, aice_init use ice_step_mod, only: ocean_mixed_layer @@ -508,8 +507,6 @@ subroutine coupling_prep (iblk) fsalt_ai (i,j,iblk) = fsalt (i,j,iblk) fhocn_ai (i,j,iblk) = fhocn (i,j,iblk) fswthru_ai(i,j,iblk) = fswthru(i,j,iblk) - fzsal_ai (i,j,iblk) = fzsal (i,j,iblk) - fzsal_g_ai(i,j,iblk) = fzsal_g(i,j,iblk) if (nbtrcr > 0) then do k = 1, nbtrcr @@ -553,7 +550,6 @@ subroutine coupling_prep (iblk) faero_ocn(:,:,:,iblk), & alvdr (:,:,iblk), alidr (:,:,iblk), & alvdf (:,:,iblk), alidf (:,:,iblk), & - fzsal (:,:,iblk), fzsal_g (:,:,iblk), & flux_bio(:,:,1:nbtrcr,iblk)) !echmod - comment this out for efficiency, if .not. calc_Tsfc diff --git a/cicecore/drivers/direct/nemo_concepts/CICE_InitMod.F90 b/cicecore/drivers/direct/nemo_concepts/CICE_InitMod.F90 index 47b158842..4921482a6 100644 --- a/cicecore/drivers/direct/nemo_concepts/CICE_InitMod.F90 +++ b/cicecore/drivers/direct/nemo_concepts/CICE_InitMod.F90 @@ -242,7 +242,7 @@ subroutine init_restart restart_fsd, read_restart_fsd, & restart_aero, read_restart_aero, & restart_hbrine, read_restart_hbrine, & - restart_zsal, restart_bgc + restart_bgc use ice_restart_driver, only: restartfile, restartfile_v4 use ice_restart_shared, only: runtype, restart use ice_state ! almost everything @@ -253,7 +253,7 @@ subroutine init_restart logical(kind=log_kind) :: & tr_iage, tr_FY, tr_lvl, tr_pond_lvl, & tr_pond_topo, tr_fsd, tr_aero, tr_brine, & - skl_bgc, z_tracers, solve_zsal + skl_bgc, z_tracers integer(kind=int_kind) :: & ntrcr integer(kind=int_kind) :: & @@ -268,7 +268,7 @@ subroutine init_restart file=__FILE__, line=__LINE__) call icepack_query_parameters(skl_bgc_out=skl_bgc, & - z_tracers_out=z_tracers, solve_zsal_out=solve_zsal) + z_tracers_out=z_tracers) call icepack_query_tracer_flags(tr_iage_out=tr_iage, tr_FY_out=tr_FY, & tr_lvl_out=tr_lvl, tr_pond_lvl_out=tr_pond_lvl, & tr_pond_topo_out=tr_pond_topo, tr_aero_out=tr_aero, tr_brine_out=tr_brine, & @@ -296,8 +296,7 @@ subroutine init_restart ! tracers ! ice age tracer if (tr_iage) then - if (trim(runtype) == 'continue') & - restart_age = .true. + if (trim(runtype) == 'continue') restart_age = .true. if (restart_age) then call read_restart_age else @@ -331,8 +330,7 @@ subroutine init_restart endif ! level-ice melt ponds if (tr_pond_lvl) then - if (trim(runtype) == 'continue') & - restart_pond_lvl = .true. + if (trim(runtype) == 'continue') restart_pond_lvl = .true. if (restart_pond_lvl) then call read_restart_pond_lvl else @@ -346,8 +344,7 @@ subroutine init_restart endif ! topographic melt ponds if (tr_pond_topo) then - if (trim(runtype) == 'continue') & - restart_pond_topo = .true. + if (trim(runtype) == 'continue') restart_pond_topo = .true. if (restart_pond_topo) then call read_restart_pond_topo else @@ -379,12 +376,8 @@ subroutine init_restart endif if (trim(runtype) == 'continue') then - if (tr_brine) & - restart_hbrine = .true. - if (solve_zsal) & - restart_zsal = .true. - if (skl_bgc .or. z_tracers) & - restart_bgc = .true. + if (tr_brine) restart_hbrine = .true. + if (skl_bgc .or. z_tracers) restart_bgc = .true. endif if (tr_brine .or. skl_bgc) then ! brine height tracer @@ -392,7 +385,7 @@ subroutine init_restart if (tr_brine .and. restart_hbrine) call read_restart_hbrine endif - if (solve_zsal .or. skl_bgc .or. z_tracers) then ! biogeochemistry + if (skl_bgc .or. z_tracers) then ! biogeochemistry if (tr_fsd) then write (nu_diag,*) 'FSD implementation incomplete for use with BGC' call icepack_warnings_flush(nu_diag) diff --git a/cicecore/drivers/direct/nemo_concepts/CICE_RunMod.F90 b/cicecore/drivers/direct/nemo_concepts/CICE_RunMod.F90 index 78c703c91..23eb990a0 100644 --- a/cicecore/drivers/direct/nemo_concepts/CICE_RunMod.F90 +++ b/cicecore/drivers/direct/nemo_concepts/CICE_RunMod.F90 @@ -134,7 +134,7 @@ subroutine ice_step use ice_boundary, only: ice_HaloUpdate use ice_calendar, only: dt, dt_dyn, ndtd, diagfreq, write_restart, istep use ice_diagnostics, only: init_mass_diags, runtime_diags - use ice_diagnostics_bgc, only: hbrine_diags, zsal_diags, bgc_diags + use ice_diagnostics_bgc, only: hbrine_diags, bgc_diags use ice_domain, only: halo_info, nblocks use ice_domain_size, only: nslyr use ice_dyn_eap, only: write_restart_eap @@ -169,12 +169,12 @@ subroutine ice_step logical (kind=log_kind) :: & tr_iage, tr_FY, tr_lvl, tr_fsd, & tr_pond_lvl, tr_pond_topo, tr_brine, tr_aero, & - calc_Tsfc, skl_bgc, solve_zsal, z_tracers, wave_spec + calc_Tsfc, skl_bgc, z_tracers, wave_spec character(len=*), parameter :: subname = '(ice_step)' call icepack_query_parameters(calc_Tsfc_out=calc_Tsfc, skl_bgc_out=skl_bgc, & - solve_zsal_out=solve_zsal, z_tracers_out=z_tracers, ktherm_out=ktherm, & + z_tracers_out=z_tracers, ktherm_out=ktherm, & wave_spec_out=wave_spec) call icepack_query_tracer_flags(tr_iage_out=tr_iage, tr_FY_out=tr_FY, & tr_lvl_out=tr_lvl, tr_pond_lvl_out=tr_pond_lvl, & @@ -307,7 +307,6 @@ subroutine ice_step call ice_timer_start(timer_diags) ! diagnostics if (mod(istep,diagfreq) == 0) then call runtime_diags(dt) ! log file - if (solve_zsal) call zsal_diags if (skl_bgc .or. z_tracers) call bgc_diags if (tr_brine) call hbrine_diags endif @@ -327,7 +326,7 @@ subroutine ice_step if (tr_pond_topo) call write_restart_pond_topo if (tr_fsd) call write_restart_fsd if (tr_aero) call write_restart_aero - if (solve_zsal .or. skl_bgc .or. z_tracers) & + if (skl_bgc .or. z_tracers) & call write_restart_bgc if (tr_brine) call write_restart_hbrine if (kdyn == 2) call write_restart_eap @@ -347,7 +346,7 @@ end subroutine ice_step subroutine coupling_prep (iblk) use ice_arrays_column, only: alvdfn, alidfn, alvdrn, alidrn, & - albicen, albsnon, albpndn, apeffn, fzsal_g, fzsal, snowfracn + albicen, albsnon, albpndn, apeffn, snowfracn use ice_blocks, only: nx_block, ny_block, get_block, block use ice_domain, only: blocks_ice use ice_calendar, only: dt, nstreams @@ -361,7 +360,7 @@ subroutine coupling_prep (iblk) swvdr, swidr, swvdf, swidf, Tf, Tair, Qa, strairxT, strairyt, & fsens, flat, fswabs, flwout, evap, Tref, Qref, & fsurfn_f, flatn_f, scale_fluxes, frzmlt_init, frzmlt - use ice_flux_bgc, only: faero_ocn, fzsal_ai, fzsal_g_ai, flux_bio, flux_bio_ai + use ice_flux_bgc, only: faero_ocn, flux_bio, flux_bio_ai use ice_grid, only: tmask use ice_state, only: aicen, aice, aice_init use ice_step_mod, only: ocean_mixed_layer @@ -508,8 +507,6 @@ subroutine coupling_prep (iblk) fsalt_ai (i,j,iblk) = fsalt (i,j,iblk) fhocn_ai (i,j,iblk) = fhocn (i,j,iblk) fswthru_ai(i,j,iblk) = fswthru(i,j,iblk) - fzsal_ai (i,j,iblk) = fzsal (i,j,iblk) - fzsal_g_ai(i,j,iblk) = fzsal_g(i,j,iblk) if (nbtrcr > 0) then do k = 1, nbtrcr @@ -555,7 +552,6 @@ subroutine coupling_prep (iblk) faero_ocn(:,:,:,iblk), & alvdr (:,:,iblk), alidr (:,:,iblk), & alvdf (:,:,iblk), alidf (:,:,iblk), & - fzsal (:,:,iblk), fzsal_g (:,:,iblk), & flux_bio(:,:,1:nbtrcr,iblk)) !echmod - comment this out for efficiency, if .not. calc_Tsfc diff --git a/cicecore/drivers/mapl/geos/CICE_FinalMod.F90 b/cicecore/drivers/mapl/geos/CICE_FinalMod.F90 new file mode 100644 index 000000000..389f638de --- /dev/null +++ b/cicecore/drivers/mapl/geos/CICE_FinalMod.F90 @@ -0,0 +1,150 @@ +!======================================================================= +! +! This module contains routines for the final exit of the CICE model, +! including final output and clean exit from any message passing +! environments and frameworks. +! +! authors: Philip W. Jones, LANL +! 2006: Converted to free source form (F90) by Elizabeth Hunke +! 2008: E. Hunke moved ESMF code to its own driver + + module CICE_FinalMod + + use ice_kinds_mod + use ice_communicate, only: my_task, master_task + use ice_exit, only: end_run, abort_ice + use ice_fileunits, only: nu_diag, release_all_fileunits + use icepack_intfc, only: icepack_warnings_flush, icepack_warnings_aborted + use icepack_intfc, only: icepack_query_parameters + use icepack_intfc, only: icepack_query_tracer_flags, icepack_query_tracer_sizes + + implicit none + private + public :: CICE_Finalize, ice_checkpoint + +!======================================================================= + + contains + +!======================================================================= +! +! This routine shuts down CICE by exiting all relevent environments. + + subroutine CICE_Finalize + + use ice_restart_shared, only: runid + use ice_timers, only: ice_timer_stop, ice_timer_print_all, timer_total + + character(len=*), parameter :: subname = '(CICE_Finalize)' + + + call ice_checkpoint + + !------------------------------------------------------------------- + ! stop timers and print timer info + !------------------------------------------------------------------- + + call ice_timer_stop(timer_total) ! stop timing entire run + call ice_timer_print_all(stats=.false.) ! print timing information + +!echmod if (nu_diag /= 6) close (nu_diag) ! diagnostic output + call release_all_fileunits + + !------------------------------------------------------------------- + ! quit MPI + !------------------------------------------------------------------- + +! standalone +! call end_run ! quit MPI + + end subroutine CICE_Finalize + +!======================================================================= + +!======================================================================= + subroutine ice_checkpoint(time_stamp) + + use ice_boundary, only: ice_HaloUpdate + use ice_calendar, only: dt, dt_dyn, ndtd, diagfreq, write_restart, istep + use ice_calendar, only: idate, msec + use ice_domain, only: halo_info, nblocks + use ice_dyn_shared, only: kdyn, kridge + use ice_dyn_eap, only: write_restart_eap + use ice_restart, only: final_restart + use ice_restart_shared, only: & + restart_ext, restart_dir, restart_file, pointer_file, & + runid, use_restart_time, lenstr, restart_coszen + use ice_restart_column, only: write_restart_age, write_restart_FY, & + write_restart_lvl, write_restart_pond_lvl, & + write_restart_pond_topo, write_restart_aero, write_restart_fsd, & + write_restart_iso, write_restart_bgc, write_restart_hbrine, & + write_restart_snow + use ice_restart_driver, only: dumpfile + use ice_timers, only: ice_timer_start, ice_timer_stop, & + timer_readwrite + use ice_communicate, only: MPI_COMM_ICE + + + character(len=*), intent(in), optional :: & + time_stamp + + integer (kind=int_kind) :: & + iblk , & ! block index + k , & ! dynamics supercycling index + ktherm ! thermodynamics is off when ktherm = -1 + + real (kind=dbl_kind) :: & + offset ! d(age)/dt time offset + + character(len=char_len_long) :: filename + + logical (kind=log_kind) :: & + tr_iage, tr_FY, tr_lvl, tr_fsd, tr_snow, & + tr_pond_lvl, tr_pond_topo, tr_brine, tr_iso, tr_aero, & + calc_Tsfc, skl_bgc, z_tracers, wave_spec + + character(len=*), parameter :: subname = '(ice_checkpoint)' + + call icepack_query_parameters(calc_Tsfc_out=calc_Tsfc, skl_bgc_out=skl_bgc, & + z_tracers_out=z_tracers, ktherm_out=ktherm, & + wave_spec_out=wave_spec) + call icepack_query_tracer_flags(tr_iage_out=tr_iage, tr_FY_out=tr_FY, & + tr_lvl_out=tr_lvl, tr_pond_lvl_out=tr_pond_lvl, & + tr_pond_topo_out=tr_pond_topo, tr_brine_out=tr_brine, tr_aero_out=tr_aero, & + tr_iso_out=tr_iso, tr_fsd_out=tr_fsd, tr_snow_out=tr_snow) + call icepack_warnings_flush(nu_diag) + if (icepack_warnings_aborted()) call abort_ice(error_message=subname, & + file=__FILE__, line=__LINE__) + + call ice_timer_start(timer_readwrite) ! reading/writing + + if(present(time_stamp)) then + filename = trim(restart_dir) // trim(restart_file) // '.' // trim(time_stamp) + else + filename = trim(restart_dir) // trim(restart_file) + endif + + call dumpfile(filename_spec=trim(filename)) ! core variables for restarting + if (tr_iage) call write_restart_age + if (tr_FY) call write_restart_FY + if (tr_lvl) call write_restart_lvl + !if (tr_pond_cesm) call write_restart_pond_cesm + if (tr_pond_lvl) call write_restart_pond_lvl + if (tr_pond_topo) call write_restart_pond_topo + if (tr_snow) call write_restart_snow + if (tr_fsd) call write_restart_fsd + if (tr_iso) call write_restart_iso + if (tr_aero) call write_restart_aero + if (skl_bgc .or. z_tracers) & + call write_restart_bgc + if (tr_brine) call write_restart_hbrine + if (kdyn == 2) call write_restart_eap + call final_restart + + call ice_timer_stop(timer_readwrite) ! reading/writing + + end subroutine ice_checkpoint + + end module CICE_FinalMod + +!======================================================================= diff --git a/cicecore/drivers/mapl/geos/CICE_InitMod.F90 b/cicecore/drivers/mapl/geos/CICE_InitMod.F90 new file mode 100644 index 000000000..f187b9eb7 --- /dev/null +++ b/cicecore/drivers/mapl/geos/CICE_InitMod.F90 @@ -0,0 +1,525 @@ +module CICE_InitMod + + ! Initialize CICE model. + + use ice_kinds_mod + use ice_exit , only: abort_ice + use ice_fileunits, only: init_fileunits, nu_diag + use icepack_intfc, only: icepack_aggregate + use icepack_intfc, only: icepack_init_itd, icepack_init_itd_hist + use icepack_intfc, only: icepack_init_fsd_bounds, icepack_init_wave + use icepack_intfc, only: icepack_init_snow, icepack_init_radiation + use icepack_intfc, only: icepack_configure + use icepack_intfc, only: icepack_warnings_flush, icepack_warnings_aborted + use icepack_intfc, only: icepack_query_parameters, icepack_query_tracer_flags + use icepack_intfc, only: icepack_init_parameters + use icepack_intfc, only: icepack_query_tracer_indices, icepack_query_tracer_sizes + + implicit none + private + public :: cice_init1 + public :: cice_init2 + public :: cice_delayed_init + public :: cice_cal_init + + private :: init_restart + +!======================================================================= +contains +!======================================================================= + + subroutine cice_init1(mpi_comm, npes, blkx, blky, dtg, k2c, alhl, alhs) + + ! Initialize the basic state, grid and all necessary parameters for + ! running the CICE model. + + use ice_init , only: input_data + use ice_communicate , only: init_communicate, my_task, master_task + use ice_init_column , only: input_zbgc, count_tracers + use ice_grid , only: init_grid1, alloc_grid + !use ice_calendar , only: set_time_step + use ice_domain , only: init_domain_blocks + use ice_arrays_column , only: alloc_arrays_column + use ice_state , only: alloc_state + !use ice_dyn_shared , only: alloc_dyn_shared + use ice_flux_bgc , only: alloc_flux_bgc + use ice_flux , only: alloc_flux + use ice_timers , only: timer_total, init_ice_timers, ice_timer_start + + integer (kind=int_kind), intent(in) :: & + mpi_comm ! communicator for sequential geos + + integer (kind=int_kind), intent(in) :: & + npes, blkx, blky, dtg ! + + real(kind=real_kind), intent(in) :: & + k2c, alhl, alhs ! + + character(len=*), parameter :: subname = '(cice_init1)' + !---------------------------------------------------- + call init_communicate(mpi_comm) ! initial setup for message passing + + call init_fileunits ! unit numbers + call icepack_init_parameters(Tffresh_in = real(k2c, kind=dbl_kind)) + call icepack_init_parameters(Lvap_in = real(alhl, kind=dbl_kind)) + call icepack_init_parameters(Lsub_in = real(alhs, kind=dbl_kind)) + call icepack_configure() ! initialize icepack + call icepack_warnings_flush(nu_diag) + if (icepack_warnings_aborted()) call abort_ice(trim(subname), & + file=__FILE__,line= __LINE__) + + call input_data ! namelist variables + !call set_time_step(dtg) ! reset time step from coupler + call input_zbgc ! vertical biogeochemistry namelist + call count_tracers ! count tracers + + !call init_domain_blocks(npes, blkx, blky) ! set up block decomposition + call init_domain_blocks ! set up block decomposition + call init_grid1 ! domain distribution + call alloc_grid ! allocate grid arrays + call alloc_arrays_column ! allocate column arrays + call alloc_state ! allocate state arrays + !call alloc_dyn_shared ! allocate dyn shared arrays + call alloc_flux_bgc ! allocate flux_bgc arrays + call alloc_flux ! allocate flux arrays + call init_ice_timers ! initialize all timers + call ice_timer_start(timer_total) ! start timing entire run + + end subroutine cice_init1 + + subroutine cice_delayed_init + + ! Initialize the basic state, and all necessary parameters for + ! running the CICE model. + + use ice_grid , only: init_grid2 + + character(len=*), parameter :: subname = '(cice_delayed_init)' + !---------------------------------------------------- + + call init_grid2 ! finish building grid + + end subroutine cice_delayed_init + + subroutine cice_cal_init(yr, mo, dy, hr, mn, sc) + + ! Initialize the basic state, and all necessary parameters for + ! running the CICE model. + + use ice_calendar , only: dt, dt_dyn, istep, istep1, write_ic, init_calendar, calendar + + character(len=*), parameter :: subname = '(cice_delayed_init)' + !---------------------------------------------------- + + integer (kind=int_kind), intent(in) :: & + yr, mo, dy, hr, mn, sc + + !call init_calendar(yr, mo, dy, hr, mn, sc) ! initialize some calendar stuff + call init_calendar ! initialize some calendar stuff + + end subroutine cice_cal_init + + !======================================================================= + subroutine cice_init2!(yr, mo, dy, hr, mn, sc) + + ! Initialize the basic state, and all necessary parameters for + ! running the CICE model. + + use ice_grid , only: init_grid2 + use ice_arrays_column , only: hin_max, c_hi_range + use ice_arrays_column , only: floe_rad_l, floe_rad_c, floe_binwidth, c_fsd_range + use ice_calendar , only: dt, dt_dyn, istep, istep1, write_ic, init_calendar, calendar + use ice_communicate , only: my_task, master_task + use ice_diagnostics , only: init_diags + use ice_domain_size , only: ncat, nfsd + !use ice_dyn_eap , only: init_eap, alloc_dyn_eap + use ice_dyn_eap , only: init_eap + use ice_dyn_evp , only: init_evp + !use ice_dyn_shared , only: kdyn, init_dyn + use ice_dyn_shared , only: kdyn + use ice_grid , only: dealloc_grid + use ice_dyn_vp , only: init_vp + use ice_flux , only: init_coupler_flux, init_history_therm + use ice_flux , only: init_history_dyn, init_flux_atm, init_flux_ocn + use ice_forcing , only: init_snowtable + use ice_forcing_bgc , only: get_forcing_bgc, get_atm_bgc + use ice_forcing_bgc , only: faero_default, alloc_forcing_bgc, fiso_default + use ice_history , only: init_hist, accum_hist + use ice_restart_shared , only: restart, runtype + use ice_init , only: input_data, init_state + use ice_init_column , only: init_thermo_vertical, init_shortwave, init_zbgc + use ice_restoring , only: ice_HaloRestore_init + use ice_timers , only: timer_total, init_ice_timers, ice_timer_start + use ice_transport_driver , only: init_transport + + + ! integer (kind=int_kind), intent(in) :: & + ! yr, mo, dy, hr, mn, sc + + logical(kind=log_kind) :: tr_aero, tr_zaero, skl_bgc, z_tracers + logical(kind=log_kind) :: tr_iso, tr_fsd, wave_spec, tr_snow + character(len=char_len) :: snw_aging_table + character(len=*), parameter :: subname = '(cice_init2)' + !---------------------------------------------------- + + call init_grid2 ! finish building grid + call init_zbgc ! vertical biogeochemistry initialization + !call init_calendar(yr, mo, dy, hr, mn, sc) ! initialize some calendar stuff + call init_hist (dt) ! initialize output history file + + !call init_dyn (dt_dyn) ! define dynamics parameters, variables + if (kdyn == 1) then + call init_evp ! define evp dynamics parameters, variables + else if (kdyn == 2) then + !call alloc_dyn_eap ! allocate dyn_eap arrays + call init_eap ! define eap dynamics parameters, variables + else if (kdyn == 3) then + call init_vp ! define vp dynamics parameters, variables + endif + + call init_coupler_flux ! initialize fluxes exchanged with coupler + call init_thermo_vertical ! initialize vertical thermodynamics + + call icepack_init_itd(hin_max=hin_max) ! ice thickness distribution + if (my_task == master_task) then + call icepack_init_itd_hist(hin_max=hin_max, c_hi_range=c_hi_range) ! output + endif + + call icepack_query_tracer_flags(tr_fsd_out=tr_fsd) + call icepack_warnings_flush(nu_diag) + if (icepack_warnings_aborted()) call abort_ice(trim(subname), & + file=__FILE__,line= __LINE__) + + if (tr_fsd) call icepack_init_fsd_bounds ( & + floe_rad_l, & ! fsd size lower bound in m (radius) + floe_rad_c, & ! fsd size bin centre in m (radius) + floe_binwidth, & ! fsd size bin width in m (radius) + c_fsd_range, & ! string for history output + write_diags=(my_task == master_task)) ! write diag on master only + + call icepack_warnings_flush(nu_diag) + if (icepack_warnings_aborted()) call abort_ice(error_message=subname, & + file=__FILE__, line=__LINE__) + + call calendar() ! determine the initial date + + call init_state ! initialize the ice state + call init_transport ! initialize horizontal transport + call ice_HaloRestore_init ! restored boundary conditions + + call icepack_query_parameters(skl_bgc_out=skl_bgc, z_tracers_out=z_tracers, & + wave_spec_out=wave_spec, snw_aging_table_out=snw_aging_table) + call icepack_warnings_flush(nu_diag) + if (icepack_warnings_aborted()) call abort_ice(trim(subname), & + file=__FILE__,line= __LINE__) + + if (skl_bgc .or. z_tracers) call alloc_forcing_bgc ! allocate biogeochemistry arrays + + call init_restart ! initialize restart variables + call init_diags ! initialize diagnostic output points + call init_history_therm ! initialize thermo history variables + call init_history_dyn ! initialize dynamic history variables + call icepack_init_radiation ! initialize icepack shortwave tables + + call icepack_query_tracer_flags(tr_aero_out=tr_aero, tr_zaero_out=tr_zaero) + call icepack_query_tracer_flags(tr_iso_out=tr_iso, tr_snow_out=tr_snow) + call icepack_warnings_flush(nu_diag) + if (icepack_warnings_aborted()) call abort_ice(trim(subname), & + file=__FILE__,line= __LINE__) + + ! snow aging lookup table initialization + if (tr_snow) then ! advanced snow physics + call icepack_init_snow() + call icepack_warnings_flush(nu_diag) + if (icepack_warnings_aborted()) call abort_ice(error_message=subname, & + file=__FILE__, line=__LINE__) + if (snw_aging_table(1:4) /= 'test') then + call init_snowtable() + endif + endif + + ! Initialize shortwave components using swdn from previous timestep + ! if restarting. These components will be scaled to current forcing + ! in prep_radiation. + + if (trim(runtype) == 'continue' .or. restart) then + call init_shortwave ! initialize radiative transfer + end if + + !-------------------------------------------------------------------- + ! coupler communication or forcing data initialization + !-------------------------------------------------------------------- + + if (z_tracers) call get_atm_bgc ! biogeochemistry + + if (runtype == 'initial' .and. .not. restart) then + call init_shortwave ! initialize radiative transfer using current swdn + end if + + call init_flux_atm ! initialize atmosphere fluxes sent to coupler + call init_flux_ocn ! initialize ocean fluxes sent to coupler + + if (write_ic) then + call accum_hist(dt) ! write initial conditions + end if + + call dealloc_grid ! deallocate temporary grid arrays + + end subroutine cice_init2 + + !======================================================================= + + subroutine init_restart() + + use ice_arrays_column, only: dhsn + use ice_blocks, only: nx_block, ny_block + use ice_calendar, only: calendar + use ice_constants, only: c0 + use ice_domain, only: nblocks + use ice_domain_size, only: ncat, n_iso, n_aero, nfsd, nslyr + use ice_dyn_eap, only: read_restart_eap + use ice_dyn_shared, only: kdyn + use ice_flux, only: Tf + use ice_grid, only: tmask, opmask + use ice_init, only: ice_ic + use ice_init_column, only: init_age, init_FY, init_lvl, init_snowtracers, & + init_meltponds_lvl, init_meltponds_topo, & + init_isotope, init_aerosol, init_hbrine, init_bgc, init_fsd + use ice_restart_column, only: restart_age, read_restart_age, & + restart_FY, read_restart_FY, restart_lvl, read_restart_lvl, & + restart_pond_lvl, read_restart_pond_lvl, & + restart_pond_topo, read_restart_pond_topo, & + restart_snow, read_restart_snow, & + restart_fsd, read_restart_fsd, & + restart_iso, read_restart_iso, & + restart_aero, read_restart_aero, & + restart_hbrine, read_restart_hbrine, & + restart_bgc + use ice_restart_driver, only: restartfile + use ice_restart_shared, only: runtype, restart + use ice_state ! almost everything + + integer(kind=int_kind) :: & + i, j , & ! horizontal indices + iblk ! block index + logical(kind=log_kind) :: & + tr_iage, tr_FY, tr_lvl, tr_pond_cesm, tr_pond_lvl, & + tr_pond_topo, tr_fsd, tr_iso, tr_aero, tr_brine, tr_snow, & + skl_bgc, z_tracers + integer(kind=int_kind) :: & + ntrcr + integer(kind=int_kind) :: & + nt_alvl, nt_vlvl, nt_apnd, nt_hpnd, nt_ipnd, & + nt_smice, nt_smliq, nt_rhos, nt_rsnw, & + nt_iage, nt_FY, nt_aero, nt_fsd, nt_isosno, nt_isoice + + character(len=*), parameter :: subname = '(init_restart)' + !---------------------------------------------------- + + call icepack_query_tracer_sizes(ntrcr_out=ntrcr) + call icepack_warnings_flush(nu_diag) + if (icepack_warnings_aborted()) call abort_ice(error_message=subname, & + file=__FILE__, line=__LINE__) + + call icepack_query_parameters(skl_bgc_out=skl_bgc, & + z_tracers_out=z_tracers) + call icepack_query_tracer_flags(tr_iage_out=tr_iage, tr_FY_out=tr_FY, & + tr_lvl_out=tr_lvl, tr_pond_lvl_out=tr_pond_lvl, & + tr_pond_topo_out=tr_pond_topo, tr_aero_out=tr_aero, tr_brine_out=tr_brine, & + tr_snow_out=tr_snow, tr_fsd_out=tr_fsd, tr_iso_out=tr_iso) + call icepack_query_tracer_indices(nt_alvl_out=nt_alvl, nt_vlvl_out=nt_vlvl, & + nt_apnd_out=nt_apnd, nt_hpnd_out=nt_hpnd, nt_ipnd_out=nt_ipnd, & + nt_iage_out=nt_iage, nt_FY_out=nt_FY, nt_aero_out=nt_aero, nt_fsd_out=nt_fsd, & + nt_smice_out=nt_smice, nt_smliq_out=nt_smliq, & + nt_rhos_out=nt_rhos, nt_rsnw_out=nt_rsnw, & + nt_isosno_out=nt_isosno, nt_isoice_out=nt_isoice) + call icepack_warnings_flush(nu_diag) + if (icepack_warnings_aborted()) call abort_ice(error_message=subname, & + file=__FILE__, line=__LINE__) + + if (trim(runtype) == 'continue') then + ! start from core restart file + call restartfile() ! given by pointer in ice_in + call calendar() ! update time parameters + if (kdyn == 2) call read_restart_eap ! EAP + else if (restart) then ! ice_ic = core restart file + call restartfile (ice_ic) ! or 'default' or 'none' +!!! uncomment to create netcdf + ! call restartfile_v4 (ice_ic) ! CICE v4.1 binary restart file +!!! uncomment if EAP restart data exists + ! if (kdyn == 2) call read_restart_eap + endif + + ! tracers + ! ice age tracer + if (tr_iage) then + if (trim(runtype) == 'continue') restart_age = .true. + if (restart_age) then + call read_restart_age + else + do iblk = 1, nblocks + call init_age(trcrn(:,:,nt_iage,:,iblk)) + enddo ! iblk + endif + endif + ! first-year area tracer + if (tr_FY) then + if (trim(runtype) == 'continue') restart_FY = .true. + if (restart_FY) then + call read_restart_FY + else + do iblk = 1, nblocks + call init_FY(trcrn(:,:,nt_FY,:,iblk)) + enddo ! iblk + endif + endif + ! level ice tracer + if (tr_lvl) then + if (trim(runtype) == 'continue') restart_lvl = .true. + if (restart_lvl) then + call read_restart_lvl + else + do iblk = 1, nblocks + call init_lvl(iblk,trcrn(:,:,nt_alvl,:,iblk), & + trcrn(:,:,nt_vlvl,:,iblk)) + enddo ! iblk + endif + endif + ! level-ice melt ponds + if (tr_pond_lvl) then + if (trim(runtype) == 'continue') restart_pond_lvl = .true. + if (restart_pond_lvl) then + call read_restart_pond_lvl + else + do iblk = 1, nblocks + call init_meltponds_lvl(trcrn(:,:,nt_apnd,:,iblk), & + trcrn(:,:,nt_hpnd,:,iblk), & + trcrn(:,:,nt_ipnd,:,iblk), & + dhsn(:,:,:,iblk)) + enddo ! iblk + endif + endif + ! topographic melt ponds + if (tr_pond_topo) then + if (trim(runtype) == 'continue') restart_pond_topo = .true. + if (restart_pond_topo) then + call read_restart_pond_topo + else + do iblk = 1, nblocks + call init_meltponds_topo(trcrn(:,:,nt_apnd,:,iblk), & + trcrn(:,:,nt_hpnd,:,iblk), & + trcrn(:,:,nt_ipnd,:,iblk)) + enddo ! iblk + endif ! .not. restart_pond + endif + ! snow redistribution/metamorphism + if (tr_snow) then + if (trim(runtype) == 'continue') restart_snow = .true. + if (restart_snow) then + call read_restart_snow + else + do iblk = 1, nblocks + call init_snowtracers(trcrn(:,:,nt_smice:nt_smice+nslyr-1,:,iblk), & + trcrn(:,:,nt_smliq:nt_smliq+nslyr-1,:,iblk), & + trcrn(:,:,nt_rhos :nt_rhos +nslyr-1,:,iblk), & + trcrn(:,:,nt_rsnw :nt_rsnw +nslyr-1,:,iblk)) + enddo ! iblk + endif + endif + + ! floe size distribution + if (tr_fsd) then + if (trim(runtype) == 'continue') restart_fsd = .true. + if (restart_fsd) then + call read_restart_fsd + else + call init_fsd(trcrn(:,:,nt_fsd:nt_fsd+nfsd-1,:,:)) + endif + endif + ! isotopes + if (tr_iso) then + if (trim(runtype) == 'continue') restart_iso = .true. + if (restart_iso) then + call read_restart_iso + else + do iblk = 1, nblocks + call init_isotope(trcrn(:,:,nt_isosno:nt_isosno+n_iso-1,:,iblk), & + trcrn(:,:,nt_isoice:nt_isoice+n_iso-1,:,iblk)) + enddo ! iblk + endif + endif + + if (tr_aero) then ! ice aerosol + if (trim(runtype) == 'continue') restart_aero = .true. + if (restart_aero) then + call read_restart_aero + else + do iblk = 1, nblocks + call init_aerosol(trcrn(:,:,nt_aero:nt_aero+4*n_aero-1,:,iblk)) + enddo ! iblk + endif ! .not. restart_aero + endif + + if (trim(runtype) == 'continue') then + if (tr_brine) restart_hbrine = .true. + if (skl_bgc .or. z_tracers) restart_bgc = .true. + endif + + if (tr_brine .or. skl_bgc) then ! brine height tracer + call init_hbrine + if (tr_brine .and. restart_hbrine) call read_restart_hbrine + endif + + if (skl_bgc .or. z_tracers) then ! biogeochemistry + if (tr_fsd) then + write (nu_diag,*) 'FSD implementation incomplete for use with BGC' + call icepack_warnings_flush(nu_diag) + if (icepack_warnings_aborted()) call abort_ice(error_message=subname, & + file=__FILE__, line=__LINE__) + endif + call init_bgc + endif + + !----------------------------------------------------------------- + ! aggregate tracers + !----------------------------------------------------------------- + + !$OMP PARALLEL DO PRIVATE(iblk) + do iblk = 1, nblocks + do j = 1, ny_block + do i = 1, nx_block + if (tmask(i,j,iblk) .or. opmask(i,j,iblk)) then + call icepack_aggregate( & + aicen = aicen(i,j,:,iblk), & + trcrn = trcrn(i,j,:,:,iblk), & + vicen = vicen(i,j,:,iblk), & + vsnon = vsnon(i,j,:,iblk), & + aice = aice (i,j, iblk), & + trcr = trcr (i,j,:,iblk), & + vice = vice (i,j, iblk), & + vsno = vsno (i,j, iblk), & + aice0 = aice0(i,j, iblk), & + trcr_depend = trcr_depend, & + trcr_base = trcr_base, & + n_trcr_strata = n_trcr_strata, & + nt_strata = nt_strata, & + Tf = Tf(i,j,iblk)) + else + ! tcraig, reset all tracer values on land to zero + trcrn(i,j,:,:,iblk) = c0 + endif + enddo + enddo + enddo + !$OMP END PARALLEL DO + + call icepack_warnings_flush(nu_diag) + if (icepack_warnings_aborted()) call abort_ice(error_message=subname, & + file=__FILE__, line=__LINE__) + end subroutine init_restart + + !======================================================================= + +end module CICE_InitMod + +!======================================================================= diff --git a/cicecore/drivers/mapl/geos/CICE_RunMod.F90 b/cicecore/drivers/mapl/geos/CICE_RunMod.F90 new file mode 100644 index 000000000..ca5cf8739 --- /dev/null +++ b/cicecore/drivers/mapl/geos/CICE_RunMod.F90 @@ -0,0 +1,1304 @@ +!======================================================================= +! +! Main driver for time stepping of CICE. +! +! authors Elizabeth C. Hunke, LANL +! Philip W. Jones, LANL +! William H. Lipscomb, LANL +! +! 2006 ECH: moved exit timeLoop to prevent execution of unnecessary timestep +! 2006 ECH: Streamlined for efficiency +! 2006 ECH: Converted to free source form (F90) +! 2007 BPB: Modified Delta-Eddington shortwave interface +! 2008 ECH: moved ESMF code to its own driver + + module CICE_RunMod + + use ice_kinds_mod + use ice_fileunits, only: nu_diag + use ice_arrays_column, only: oceanmixed_ice + use ice_domain_size, only: max_blocks, ncat, max_nstrm, nilyr + use ice_constants, only: c0, c1, c5, c10, c20, c180 + use ice_constants, only: field_loc_center, field_type_scalar + use ice_exit, only: abort_ice + use icepack_intfc, only: icepack_warnings_flush, icepack_warnings_aborted + use icepack_intfc, only: icepack_max_iso, icepack_max_aero + use icepack_intfc, only: icepack_query_parameters + use icepack_intfc, only: icepack_query_tracer_flags, icepack_query_tracer_sizes + + implicit none + private + public :: CICE_Run, ice_step, ice_fast_physics, ice_radiation + +!======================================================================= + + contains + +!======================================================================= +! +! This is the main driver routine for advancing CICE forward in time. +! +! author Elizabeth C. Hunke, LANL +! Philip W. Jones, LANL +! William H. Lipscomb, LANL + + subroutine CICE_Run + + use ice_calendar, only: istep, istep1, dt, calendar, advance_timestep + use ice_forcing, only: get_forcing_atmo, get_forcing_ocn, & + get_wave_spec + use ice_forcing_bgc, only: get_forcing_bgc, get_atm_bgc, & + fiso_default, faero_default + use ice_flux, only: init_flux_atm, init_flux_ocn + use ice_timers, only: ice_timer_start, ice_timer_stop, & + timer_couple, timer_step + logical (kind=log_kind) :: & + tr_iso, tr_aero, tr_zaero, skl_bgc, z_tracers, wave_spec, tr_fsd + character(len=*), parameter :: subname = '(CICE_Run)' + + !-------------------------------------------------------------------- + ! initialize error code and step timer + !-------------------------------------------------------------------- + + call ice_timer_start(timer_step) ! start timing entire run + + call icepack_query_parameters(skl_bgc_out=skl_bgc, & + z_tracers_out=z_tracers, & + wave_spec_out=wave_spec) + call icepack_query_tracer_flags(tr_iso_out=tr_iso, & + tr_aero_out=tr_aero, & + tr_zaero_out=tr_zaero, & + tr_fsd_out=tr_fsd) + call icepack_warnings_flush(nu_diag) + if (icepack_warnings_aborted()) call abort_ice(error_message=subname, & + file=__FILE__, line=__LINE__) + + !-------------------------------------------------------------------- + ! timestep loop + !-------------------------------------------------------------------- + + !call ice_timer_start(timer_couple) ! atm/ocn coupling + + call advance_timestep() ! advance timestep and update calendar data + + !if (z_tracers) call get_atm_bgc ! biogeochemistry + + !call init_flux_atm ! Initialize atmosphere fluxes sent to coupler + !call init_flux_ocn ! initialize ocean fluxes sent to coupler + + !call ice_timer_stop(timer_couple) ! atm/ocn coupling + + call ice_step + + !-------------------------------------------------------------------- + ! end of timestep loop + !-------------------------------------------------------------------- + + call ice_timer_stop(timer_step) ! end timestepping loop timer + + end subroutine CICE_Run + +!======================================================================= +! +! Calls drivers for physics components, some initialization, and output +! +! author Elizabeth C. Hunke, LANL +! William H. Lipscomb, LANL + + subroutine ice_step + + use ice_boundary, only: ice_HaloUpdate + use ice_calendar, only: dt, dt_dyn, ndtd, diagfreq, write_restart, istep + use ice_calendar, only: idate, msec + use ice_diagnostics, only: init_mass_diags, runtime_diags, debug_model, debug_ice + use ice_diagnostics_bgc, only: hbrine_diags, bgc_diags + use ice_domain, only: halo_info, nblocks + use ice_dyn_eap, only: write_restart_eap + use ice_dyn_shared, only: kdyn, kridge + use ice_flux, only: scale_factor, init_history_therm, & + daidtt, daidtd, dvidtt, dvidtd, dvsdtt, dvsdtd, dagedtt, dagedtd + use ice_history, only: accum_hist + use ice_history_bgc, only: init_history_bgc + use ice_restart, only: final_restart + use ice_restart_column, only: write_restart_age, write_restart_FY, & + write_restart_lvl, write_restart_pond_lvl, & + write_restart_pond_topo, write_restart_aero, write_restart_fsd, & + write_restart_iso, write_restart_bgc, write_restart_hbrine, & + write_restart_snow + use ice_restart_driver, only: dumpfile + use ice_restoring, only: restore_ice, ice_HaloRestore + use ice_step_mod, only: prep_radiation, step_therm1, step_therm2, & + update_state, step_dyn_horiz, step_dyn_ridge, step_radiation, & + biogeochemistry, step_prep, step_dyn_wave, step_snow + use ice_timers, only: ice_timer_start, ice_timer_stop, & + timer_diags, timer_column, timer_thermo, timer_bound, & + timer_hist, timer_readwrite + use ice_communicate, only: MPI_COMM_ICE + use ice_prescribed_mod + + integer (kind=int_kind) :: & + iblk , & ! block index + k , & ! dynamics supercycling index + ktherm ! thermodynamics is off when ktherm = -1 + + real (kind=dbl_kind) :: & + offset ! d(age)/dt time offset + + logical (kind=log_kind) :: & + tr_iage, tr_FY, tr_lvl, tr_fsd, tr_snow, & + tr_pond_lvl, tr_pond_topo, tr_brine, tr_iso, tr_aero, & + calc_Tsfc, skl_bgc, z_tracers, wave_spec + + character(len=*), parameter :: subname = '(ice_step)' + + character (len=char_len) :: plabeld + + !if (debug_model) then + ! plabeld = 'beginning time step' + ! do iblk = 1, nblocks + ! call debug_ice (iblk, plabeld) + ! enddo + !endif + + call icepack_query_parameters(calc_Tsfc_out=calc_Tsfc, skl_bgc_out=skl_bgc, & + z_tracers_out=z_tracers, ktherm_out=ktherm, wave_spec_out=wave_spec) + call icepack_query_tracer_flags(tr_iage_out=tr_iage, tr_FY_out=tr_FY, & + tr_lvl_out=tr_lvl, tr_pond_lvl_out=tr_pond_lvl, & + tr_pond_topo_out=tr_pond_topo, tr_brine_out=tr_brine, tr_aero_out=tr_aero, & + tr_iso_out=tr_iso, tr_fsd_out=tr_fsd, tr_snow_out=tr_snow) + call icepack_warnings_flush(nu_diag) + if (icepack_warnings_aborted()) call abort_ice(error_message=subname, & + file=__FILE__, line=__LINE__) + + + call ice_timer_start(timer_column) ! continue column physics + call ice_timer_start(timer_thermo) ! thermodynamics + + !$OMP PARALLEL DO PRIVATE(iblk) + do iblk = 1, nblocks + + if (ktherm >= 0) then + + !----------------------------------------------------------------- + ! thermodynamics and biogeochemistry + !----------------------------------------------------------------- + + call biogeochemistry (dt, iblk) ! biogeochemistry + !if (debug_model) then + ! plabeld = 'post biogeochemistry' + ! call debug_ice (iblk, plabeld) + !endif + + if (.not.prescribed_ice) & + call step_therm2 (dt, iblk) ! ice thickness distribution thermo + if (debug_model) then + plabeld = 'post step_therm2' + call debug_ice (iblk, plabeld) + endif + + endif ! ktherm > 0 + + enddo ! iblk + !$OMP END PARALLEL DO + + ! clean up, update tendency diagnostics + offset = dt + call update_state (dt=dt, daidt=daidtt, dvidt=dvidtt, dvsdt=dvsdtt, & + dagedt=dagedtt, offset=offset) + + call ice_timer_stop(timer_thermo) ! thermodynamics + call ice_timer_stop(timer_column) ! column physics + + !----------------------------------------------------------------- + ! dynamics, transport, ridging + !----------------------------------------------------------------- + + if (.not.prescribed_ice) then + + ! wave fracture of the floe size distribution + ! note this is called outside of the dynamics subcycling loop + if (tr_fsd .and. wave_spec) call step_dyn_wave(dt) + + do k = 1, ndtd + + ! momentum, stress, transport + call step_dyn_horiz (dt_dyn) + !if (debug_model) then + ! plabeld = 'post step_dyn_horiz' + ! do iblk = 1, nblocks + ! call debug_ice (iblk, plabeld) + ! enddo ! iblk + !endif + + ! ridging + !$OMP PARALLEL DO PRIVATE(iblk) + do iblk = 1, nblocks + if (kridge > 0) call step_dyn_ridge (dt_dyn, ndtd, iblk) + enddo + !$OMP END PARALLEL DO + !if (debug_model) then + ! plabeld = 'post step_dyn_ridge' + ! do iblk = 1, nblocks + ! call debug_ice (iblk, plabeld) + ! enddo ! iblk + !endif + + ! clean up, update tendency diagnostics + offset = c0 + call update_state (dt=dt_dyn, daidt=daidtd, dvidt=dvidtd, dvsdt=dvsdtd, & + dagedt=dagedtd, offset=offset) + + enddo + !if (debug_model) then + ! plabeld = 'post dynamics' + ! do iblk = 1, nblocks + ! call debug_ice (iblk, plabeld) + ! enddo + !endif + + endif ! not prescribed ice + + !----------------------------------------------------------------- + ! albedo, shortwave radiation + !----------------------------------------------------------------- + + call ice_timer_start(timer_column) ! column physics + call ice_timer_start(timer_thermo) ! thermodynamics + + !----------------------------------------------------------------- + ! snow redistribution and metamorphosis + !----------------------------------------------------------------- + + if (tr_snow) then ! advanced snow physics + do iblk = 1, nblocks + call step_snow (dt, iblk) + enddo + call update_state (dt=dt) ! clean up + endif + +!MHRI: CHECK THIS OMP + !$OMP PARALLEL DO PRIVATE(iblk) + do iblk = 1, nblocks + + !if (ktherm >= 0) call step_radiation (dt, iblk) + !if (debug_model) then + ! plabeld = 'post step_radiation' + ! call debug_ice (iblk, plabeld) + !endif + + !----------------------------------------------------------------- + ! get ready for coupling and the next time step + !----------------------------------------------------------------- + + call coupling_ocn (iblk) + if (debug_model) then + plabeld = 'post coupling_ocn' + call debug_ice (iblk, plabeld) + endif + enddo ! iblk + !$OMP END PARALLEL DO + + !call ice_timer_start(timer_bound) + !call ice_HaloUpdate (scale_factor, halo_info, & + ! field_loc_center, field_type_scalar) + !call ice_timer_stop(timer_bound) + + call ice_timer_stop(timer_thermo) ! thermodynamics + call ice_timer_stop(timer_column) ! column physics + + !----------------------------------------------------------------- + ! write data + !----------------------------------------------------------------- + + call ice_timer_start(timer_diags) ! diagnostics + if (mod(istep,diagfreq) == 0) then + call runtime_diags(dt) ! log file + if (skl_bgc .or. z_tracers) call bgc_diags + if (tr_brine) call hbrine_diags + endif + call ice_timer_stop(timer_diags) ! diagnostics + + call ice_timer_start(timer_hist) ! history + call accum_hist (dt) ! history file + call ice_timer_stop(timer_hist) ! history + + call ice_timer_start(timer_readwrite) ! reading/writing + if (write_restart == 1) then + call dumpfile ! core variables for restarting + if (tr_iage) call write_restart_age + if (tr_FY) call write_restart_FY + if (tr_lvl) call write_restart_lvl + !if (tr_pond_cesm) call write_restart_pond_cesm + if (tr_pond_lvl) call write_restart_pond_lvl + if (tr_pond_topo) call write_restart_pond_topo + if (tr_snow) call write_restart_snow + if (tr_fsd) call write_restart_fsd + if (tr_iso) call write_restart_iso + if (tr_aero) call write_restart_aero + if (skl_bgc .or. z_tracers) & + call write_restart_bgc + if (tr_brine) call write_restart_hbrine + if (kdyn == 2) call write_restart_eap + call final_restart + endif + + call ice_timer_stop(timer_readwrite) ! reading/writing + + end subroutine ice_step + +!======================================================================= +! +! Prepare for coupling +! +! authors: Elizabeth C. Hunke, LANL + + subroutine coupling_prep (iblk) + + use ice_arrays_column, only: alvdfn, alidfn, alvdrn, alidrn, & + fswthrun_vdr, fswthrun_vdf, fswthrun_idr, fswthrun_idf, & + fswthrun_uvrdr, fswthrun_uvrdf, fswthrun_pardr, fswthrun_pardf, & + albicen, albsnon, albpndn, apeffn, snowfracn + use ice_blocks, only: nx_block, ny_block, get_block, block + use ice_domain, only: blocks_ice + use ice_calendar, only: dt, nstreams + use ice_domain_size, only: ncat + use ice_flux, only: alvdf, alidf, alvdr, alidr, albice, albsno, & + albpnd, albcnt, apeff_ai, fpond, fresh, l_mpond_fresh, & + alvdf_ai, alidf_ai, alvdr_ai, alidr_ai, fhocn_ai, & + fresh_ai, fsalt_ai, fsalt, & + fswthru_ai, fhocn, fswthru, scale_factor, snowfrac, & + fswthru_vdr, fswthru_vdf, fswthru_idr, fswthru_idf, & + fswthru_uvrdr, fswthru_uvrdf, fswthru_pardr, fswthru_pardf, & + swvdr, swidr, swvdf, swidf, Tf, Tair, Qa, strairxT, strairyT, & + fsens, flat, fswabs, flwout, evap, Tref, Qref, & + scale_fluxes, frzmlt_init, frzmlt, Uref, wind + use ice_flux_bgc, only: faero_ocn, fiso_ocn, Qref_iso, fiso_evap, & + flux_bio, flux_bio_ai, & + fnit, fsil, famm, fdmsp, fdms, fhum, fdust, falgalN, & + fdoc, fdic, fdon, ffep, ffed, bgcflux_ice_to_ocn + use ice_grid, only: tmask + use ice_state, only: aicen, aice + use ice_state, only: aice_init + use ice_flux, only: flatn_f, fsurfn_f + use ice_step_mod, only: ocean_mixed_layer + use ice_timers, only: timer_couple, ice_timer_start, ice_timer_stop + + integer (kind=int_kind), intent(in) :: & + iblk ! block index + + ! local variables + + integer (kind=int_kind) :: & + ilo,ihi,jlo,jhi, & ! beginning and end of physical domain + n , & ! thickness category index + i,j , & ! horizontal indices + k , & ! tracer index + nbtrcr ! + + type (block) :: & + this_block ! block information for current block + + logical (kind=log_kind) :: & + skl_bgc , & ! + calc_Tsfc ! + + real (kind=dbl_kind) :: & + cszn , & ! counter for history averaging + puny , & ! + rhofresh , & ! + netsw ! flag for shortwave radiation presence + + character(len=*), parameter :: subname = '(coupling_prep)' + + !----------------------------------------------------------------- + + call icepack_query_parameters(puny_out=puny, rhofresh_out=rhofresh) + call icepack_query_parameters(skl_bgc_out=skl_bgc) + call icepack_query_tracer_sizes(nbtrcr_out=nbtrcr) + call icepack_query_parameters(calc_Tsfc_out=calc_Tsfc) + call icepack_warnings_flush(nu_diag) + if (icepack_warnings_aborted()) call abort_ice(error_message=subname, & + file=__FILE__, line=__LINE__) + + !----------------------------------------------------------------- + ! Save current value of frzmlt for diagnostics. + ! Update mixed layer with heat and radiation from ice. + !----------------------------------------------------------------- + + do j = 1, ny_block + do i = 1, nx_block + frzmlt_init (i,j,iblk) = frzmlt(i,j,iblk) + enddo + enddo + + call ice_timer_start(timer_couple,iblk) ! atm/ocn coupling + + if (oceanmixed_ice) & + call ocean_mixed_layer (dt,iblk) ! ocean surface fluxes and sst + + !----------------------------------------------------------------- + ! Aggregate albedos + !----------------------------------------------------------------- + + do j = 1, ny_block + do i = 1, nx_block + alvdf(i,j,iblk) = c0 + alidf(i,j,iblk) = c0 + alvdr(i,j,iblk) = c0 + alidr(i,j,iblk) = c0 + + fswthru_vdr(i,j,iblk) = c0 + fswthru_vdf(i,j,iblk) = c0 + fswthru_idr(i,j,iblk) = c0 + fswthru_idf(i,j,iblk) = c0 + + fswthru_uvrdr(i,j,iblk) = c0 + fswthru_uvrdf(i,j,iblk) = c0 + fswthru_pardr(i,j,iblk) = c0 + fswthru_pardf(i,j,iblk) = c0 + + albice(i,j,iblk) = c0 + albsno(i,j,iblk) = c0 + albpnd(i,j,iblk) = c0 + apeff_ai(i,j,iblk) = c0 + snowfrac(i,j,iblk) = c0 + + ! for history averaging + cszn = c0 + netsw = swvdr(i,j,iblk)+swidr(i,j,iblk)+swvdf(i,j,iblk)+swidf(i,j,iblk) + if (netsw > puny) cszn = c1 + do n = 1, nstreams + albcnt(i,j,iblk,n) = albcnt(i,j,iblk,n) + cszn + enddo + enddo + enddo + + this_block = get_block(blocks_ice(iblk),iblk) + ilo = this_block%ilo + ihi = this_block%ihi + jlo = this_block%jlo + jhi = this_block%jhi + + do n = 1, ncat + do j = jlo, jhi + do i = ilo, ihi + if (aicen(i,j,n,iblk) > puny) then + + alvdf(i,j,iblk) = alvdf(i,j,iblk) & + + alvdfn(i,j,n,iblk)*aicen(i,j,n,iblk) + alidf(i,j,iblk) = alidf(i,j,iblk) & + + alidfn(i,j,n,iblk)*aicen(i,j,n,iblk) + alvdr(i,j,iblk) = alvdr(i,j,iblk) & + + alvdrn(i,j,n,iblk)*aicen(i,j,n,iblk) + alidr(i,j,iblk) = alidr(i,j,iblk) & + + alidrn(i,j,n,iblk)*aicen(i,j,n,iblk) + + fswthru_vdr(i,j,iblk) = fswthru_vdr(i,j,iblk) & + + fswthrun_vdr(i,j,n,iblk)*aicen(i,j,n,iblk) + fswthru_vdf(i,j,iblk) = fswthru_vdf(i,j,iblk) & + + fswthrun_vdf(i,j,n,iblk)*aicen(i,j,n,iblk) + fswthru_idr(i,j,iblk) = fswthru_idr(i,j,iblk) & + + fswthrun_idr(i,j,n,iblk)*aicen(i,j,n,iblk) + fswthru_idf(i,j,iblk) = fswthru_idf(i,j,iblk) & + + fswthrun_idf(i,j,n,iblk)*aicen(i,j,n,iblk) + + fswthru_uvrdr(i,j,iblk) = fswthru_uvrdr(i,j,iblk) & + + fswthrun_uvrdr(i,j,n,iblk)*aicen(i,j,n,iblk) + fswthru_uvrdf(i,j,iblk) = fswthru_uvrdf(i,j,iblk) & + + fswthrun_uvrdf(i,j,n,iblk)*aicen(i,j,n,iblk) + fswthru_pardr(i,j,iblk) = fswthru_pardr(i,j,iblk) & + + fswthrun_pardr(i,j,n,iblk)*aicen(i,j,n,iblk) + fswthru_pardf(i,j,iblk) = fswthru_pardf(i,j,iblk) & + + fswthrun_pardf(i,j,n,iblk)*aicen(i,j,n,iblk) + + netsw = swvdr(i,j,iblk) + swidr(i,j,iblk) & + + swvdf(i,j,iblk) + swidf(i,j,iblk) + if (netsw > puny) then ! sun above horizon + albice(i,j,iblk) = albice(i,j,iblk) & + + albicen(i,j,n,iblk)*aicen(i,j,n,iblk) + albsno(i,j,iblk) = albsno(i,j,iblk) & + + albsnon(i,j,n,iblk)*aicen(i,j,n,iblk) + albpnd(i,j,iblk) = albpnd(i,j,iblk) & + + albpndn(i,j,n,iblk)*aicen(i,j,n,iblk) + endif + + apeff_ai(i,j,iblk) = apeff_ai(i,j,iblk) & ! for history + + apeffn(i,j,n,iblk)*aicen(i,j,n,iblk) + snowfrac(i,j,iblk) = snowfrac(i,j,iblk) & ! for history + + snowfracn(i,j,n,iblk)*aicen(i,j,n,iblk) + + endif ! aicen > puny + enddo + enddo + enddo + + do j = 1, ny_block + do i = 1, nx_block + + !----------------------------------------------------------------- + ! reduce fresh by fpond for coupling + !----------------------------------------------------------------- + + if (l_mpond_fresh) then + fpond(i,j,iblk) = fpond(i,j,iblk) * rhofresh/dt + fresh(i,j,iblk) = fresh(i,j,iblk) - fpond(i,j,iblk) + endif + + !---------------------------------------------------------------- + ! Store grid box mean albedos and fluxes before scaling by aice + !---------------------------------------------------------------- + + alvdf_ai (i,j,iblk) = alvdf (i,j,iblk) + alidf_ai (i,j,iblk) = alidf (i,j,iblk) + alvdr_ai (i,j,iblk) = alvdr (i,j,iblk) + alidr_ai (i,j,iblk) = alidr (i,j,iblk) + fresh_ai (i,j,iblk) = fresh (i,j,iblk) + fsalt_ai (i,j,iblk) = fsalt (i,j,iblk) + fhocn_ai (i,j,iblk) = fhocn (i,j,iblk) + fswthru_ai(i,j,iblk) = fswthru(i,j,iblk) + + if (nbtrcr > 0) then + do k = 1, nbtrcr + flux_bio_ai (i,j,k,iblk) = flux_bio (i,j,k,iblk) + enddo + endif + + !----------------------------------------------------------------- + ! Save net shortwave for scaling factor in scale_factor + !----------------------------------------------------------------- + scale_factor(i,j,iblk) = & + swvdr(i,j,iblk)*(c1 - alvdr_ai(i,j,iblk)) & + + swvdf(i,j,iblk)*(c1 - alvdf_ai(i,j,iblk)) & + + swidr(i,j,iblk)*(c1 - alidr_ai(i,j,iblk)) & + + swidf(i,j,iblk)*(c1 - alidf_ai(i,j,iblk)) + + enddo + enddo + + !----------------------------------------------------------------- + ! Divide fluxes by ice area + ! - the CESM coupler assumes fluxes are per unit ice area + ! - also needed for global budget in diagnostics + !----------------------------------------------------------------- + + call scale_fluxes (nx_block, ny_block, & + tmask (:,:,iblk), nbtrcr, & + icepack_max_aero, & + aice (:,:,iblk), Tf (:,:,iblk), & + Tair (:,:,iblk), Qa (:,:,iblk), & + strairxT (:,:,iblk), strairyT(:,:,iblk), & + fsens (:,:,iblk), flat (:,:,iblk), & + fswabs (:,:,iblk), flwout (:,:,iblk), & + evap (:,:,iblk), & + Tref (:,:,iblk), Qref (:,:,iblk), & + fresh (:,:,iblk), fsalt (:,:,iblk), & + fhocn (:,:,iblk), & + fswthru (:,:,iblk), & + fswthru_vdr(:,:,iblk), & + fswthru_vdf(:,:,iblk), & + fswthru_idr(:,:,iblk), & + fswthru_idf(:,:,iblk), & + faero_ocn(:,:,:,iblk), & + alvdr (:,:,iblk), alidr (:,:,iblk), & + alvdf (:,:,iblk), alidf (:,:,iblk), & + flux_bio (:,:,1:nbtrcr,iblk), & + Qref_iso =Qref_iso (:,:,:,iblk), & + fiso_evap=fiso_evap(:,:,:,iblk), & + fiso_ocn =fiso_ocn (:,:,:,iblk), & + Uref=Uref(:,:,iblk), wind=wind(:,:,iblk) ) + + !----------------------------------------------------------------- + ! Define ice-ocean bgc fluxes + !----------------------------------------------------------------- + + if (nbtrcr > 0 .or. skl_bgc) then + call bgcflux_ice_to_ocn (nx_block, ny_block, & + flux_bio(:,:,1:nbtrcr,iblk), & + fnit(:,:,iblk), fsil(:,:,iblk), & + famm(:,:,iblk), fdmsp(:,:,iblk), & + fdms(:,:,iblk), fhum(:,:,iblk), & + fdust(:,:,iblk), falgalN(:,:,:,iblk), & + fdoc(:,:,:,iblk), fdic(:,:,:,iblk), & + fdon(:,:,:,iblk), ffep(:,:,:,iblk), & + ffed(:,:,:,iblk)) + endif + + call ice_timer_stop(timer_couple,iblk) ! atm/ocn coupling + + end subroutine coupling_prep + + subroutine coupling_atm (iblk) + + use ice_arrays_column, only: alvdfn, alidfn, alvdrn, alidrn, & + fswthrun_vdr, fswthrun_vdf, fswthrun_idr, fswthrun_idf, & + fswthrun_uvrdr, fswthrun_uvrdf, fswthrun_pardr, fswthrun_pardf, & + albicen, albsnon, albpndn, apeffn, snowfracn + use ice_blocks, only: nx_block, ny_block, get_block, block + use ice_domain, only: blocks_ice + use ice_calendar, only: dt, nstreams + use ice_domain_size, only: ncat + use ice_flux, only: alvdf, alidf, alvdr, alidr, albice, albsno, & + albpnd, albcnt, apeff_ai, fpond, fresh, l_mpond_fresh, & + alvdf_ai, alidf_ai, alvdr_ai, alidr_ai, fhocn_ai, & + fresh_ai, fsalt_ai, fsalt, fsurf, fcondtop, & + fswthru_ai, fhocn, fswthru, scale_factor, snowfrac, & + fswthru_vdr, fswthru_vdf, fswthru_idr, fswthru_idf, & + fswthru_uvrdr, fswthru_uvrdf, fswthru_pardr, fswthru_pardf, & + swvdr, swidr, swvdf, swidf, Tf, Tair, Qa, strairxT, strairyT, & + fsens, flat, fswabs, flwout, evap, Tref, Qref, & + scale_fluxes, frzmlt_init, frzmlt, Uref, wind + use ice_flux_bgc, only: faero_ocn, fiso_ocn, Qref_iso, fiso_evap, & + flux_bio, flux_bio_ai, & + fnit, fsil, famm, fdmsp, fdms, fhum, fdust, falgalN, & + fdoc, fdic, fdon, ffep, ffed, bgcflux_ice_to_ocn + use ice_grid, only: tmask, opmask + use ice_state, only: aicen, aice, aicen_init, aice_init + use ice_flux, only: flatn_f, fsurfn_f + use ice_step_mod, only: ocean_mixed_layer + use ice_timers, only: timer_couple, ice_timer_start, ice_timer_stop + + integer (kind=int_kind), intent(in) :: & + iblk ! block index + + ! local variables + + integer (kind=int_kind) :: & + ilo,ihi,jlo,jhi, & ! beginning and end of physical domain + n , & ! thickness category index + i,j , & ! horizontal indices + k , & ! tracer index + nbtrcr ! + + type (block) :: & + this_block ! block information for current block + + logical (kind=log_kind) :: & + skl_bgc , & ! + calc_Tsfc ! + + real (kind=dbl_kind) :: & + cszn , & ! counter for history averaging + puny , & ! + ar , & + stefan_boltzmann, & + Tffresh , & + rhofresh , & ! + netsw ! flag for shortwave radiation presence + + character(len=*), parameter :: subname = '(coupling_atm)' + + !----------------------------------------------------------------- + + call icepack_query_parameters(puny_out=puny, rhofresh_out=rhofresh) + call icepack_query_parameters(skl_bgc_out=skl_bgc) + call icepack_query_tracer_sizes(nbtrcr_out=nbtrcr) + call icepack_query_parameters(calc_Tsfc_out=calc_Tsfc) + call icepack_query_parameters(stefan_boltzmann_out=stefan_boltzmann, & + Tffresh_out=Tffresh) + call icepack_warnings_flush(nu_diag) + if (icepack_warnings_aborted()) call abort_ice(error_message=subname, & + file=__FILE__, line=__LINE__) + + !----------------------------------------------------------------- + ! Save current value of frzmlt for diagnostics. + ! Update mixed layer with heat and radiation from ice. + !----------------------------------------------------------------- + + do j = 1, ny_block + do i = 1, nx_block + frzmlt_init (i,j,iblk) = frzmlt(i,j,iblk) + enddo + enddo + + call ice_timer_start(timer_couple,iblk) ! atm/ocn coupling + + !----------------------------------------------------------------- + ! Aggregate albedos + !----------------------------------------------------------------- + + do j = 1, ny_block + do i = 1, nx_block + alvdf(i,j,iblk) = c0 + alidf(i,j,iblk) = c0 + alvdr(i,j,iblk) = c0 + alidr(i,j,iblk) = c0 + + albice(i,j,iblk) = c0 + albsno(i,j,iblk) = c0 + albpnd(i,j,iblk) = c0 + apeff_ai(i,j,iblk) = c0 + snowfrac(i,j,iblk) = c0 + + ! for history averaging + !cszn = c0 + !netsw = swvdr(i,j,iblk)+swidr(i,j,iblk)+swvdf(i,j,iblk)+swidf(i,j,iblk) + !if (netsw > puny) cszn = c1 + cszn = c1 + do n = 1, nstreams + albcnt(i,j,iblk,n) = albcnt(i,j,iblk,n) + cszn + enddo + enddo + enddo + + this_block = get_block(blocks_ice(iblk),iblk) + ilo = this_block%ilo + ihi = this_block%ihi + jlo = this_block%jlo + jhi = this_block%jhi + + do n = 1, ncat + do j = jlo, jhi + do i = ilo, ihi + if (aicen_init(i,j,n,iblk) > puny) then + + alvdf(i,j,iblk) = alvdf(i,j,iblk) & + + alvdfn(i,j,n,iblk)*aicen_init(i,j,n,iblk) + alidf(i,j,iblk) = alidf(i,j,iblk) & + + alidfn(i,j,n,iblk)*aicen_init(i,j,n,iblk) + alvdr(i,j,iblk) = alvdr(i,j,iblk) & + + alvdrn(i,j,n,iblk)*aicen_init(i,j,n,iblk) + alidr(i,j,iblk) = alidr(i,j,iblk) & + + alidrn(i,j,n,iblk)*aicen_init(i,j,n,iblk) + + netsw = swvdr(i,j,iblk) + swidr(i,j,iblk) & + + swvdf(i,j,iblk) + swidf(i,j,iblk) + !if (netsw > puny) then ! sun above horizon + albice(i,j,iblk) = albice(i,j,iblk) & + + albicen(i,j,n,iblk)*aicen_init(i,j,n,iblk) + albsno(i,j,iblk) = albsno(i,j,iblk) & + + albsnon(i,j,n,iblk)*aicen_init(i,j,n,iblk) + albpnd(i,j,iblk) = albpnd(i,j,iblk) & + + albpndn(i,j,n,iblk)*aicen_init(i,j,n,iblk) + !endif + + apeff_ai(i,j,iblk) = apeff_ai(i,j,iblk) & ! for history + + apeffn(i,j,n,iblk)*aicen_init(i,j,n,iblk) + snowfrac(i,j,iblk) = snowfrac(i,j,iblk) & ! for history + + snowfracn(i,j,n,iblk)*aicen_init(i,j,n,iblk) + + endif ! aicen_init > puny + enddo + enddo + enddo + + do j = 1, ny_block + do i = 1, nx_block + + !---------------------------------------------------------------- + ! Store grid box mean albedos and fluxes before scaling by aice + !---------------------------------------------------------------- + + alvdf_ai (i,j,iblk) = alvdf (i,j,iblk) + alidf_ai (i,j,iblk) = alidf (i,j,iblk) + alvdr_ai (i,j,iblk) = alvdr (i,j,iblk) + alidr_ai (i,j,iblk) = alidr (i,j,iblk) + fswthru_ai(i,j,iblk) = fswthru(i,j,iblk) + + + !----------------------------------------------------------------- + ! Save net shortwave for scaling factor in scale_factor + !----------------------------------------------------------------- + scale_factor(i,j,iblk) = & + swvdr(i,j,iblk)*(c1 - alvdr_ai(i,j,iblk)) & + + swvdf(i,j,iblk)*(c1 - alvdf_ai(i,j,iblk)) & + + swidr(i,j,iblk)*(c1 - alidr_ai(i,j,iblk)) & + + swidf(i,j,iblk)*(c1 - alidf_ai(i,j,iblk)) + + enddo + enddo + + !----------------------------------------------------------------- + ! Divide fluxes by ice area + ! - the CESM coupler assumes fluxes are per unit ice area + ! - also needed for global budget in diagnostics + !----------------------------------------------------------------- + + do j = 1, ny_block + do i = 1, nx_block + if ((tmask(i,j,iblk) .or. opmask(i,j,iblk)) .and. aice_init(i,j,iblk) > c0) then + ar = c1 / aice_init(i,j,iblk) + fsens (i,j,iblk) = fsens (i,j,iblk) * ar + flat (i,j,iblk) = flat (i,j,iblk) * ar + fswabs (i,j,iblk) = fswabs (i,j,iblk) * ar + flwout (i,j,iblk) = flwout (i,j,iblk) * ar + fsurf (i,j,iblk) = fsurf (i,j,iblk) * ar + fcondtop(i,j,iblk) = fcondtop(i,j,iblk) * ar + evap (i,j,iblk) = evap (i,j,iblk) * ar + Tref (i,j,iblk) = Tref (i,j,iblk) * ar + Qref (i,j,iblk) = Qref (i,j,iblk) * ar + Uref (i,j,iblk) = Uref (i,j,iblk) * ar + fswthru (i,j,iblk) = fswthru (i,j,iblk) * ar + fswthru_vdr (i,j,iblk) = fswthru_vdr (i,j,iblk) * ar + fswthru_vdf (i,j,iblk) = fswthru_vdf (i,j,iblk) * ar + fswthru_idr (i,j,iblk) = fswthru_idr (i,j,iblk) * ar + fswthru_idf (i,j,iblk) = fswthru_idf (i,j,iblk) * ar + alvdr (i,j,iblk) = alvdr (i,j,iblk) * ar + alidr (i,j,iblk) = alidr (i,j,iblk) * ar + alvdf (i,j,iblk) = alvdf (i,j,iblk) * ar + alidf (i,j,iblk) = alidf (i,j,iblk) * ar + fswthru_uvrdr (i,j,iblk) = fswthru_uvrdr (i,j,iblk) * ar + fswthru_uvrdf (i,j,iblk) = fswthru_uvrdf (i,j,iblk) * ar + fswthru_pardr (i,j,iblk) = fswthru_pardr (i,j,iblk) * ar + fswthru_pardf (i,j,iblk) = fswthru_pardf (i,j,iblk) * ar + else + fsens (i,j,iblk) = c0 + flat (i,j,iblk) = c0 + fswabs (i,j,iblk) = c0 + flwout (i,j,iblk) = -stefan_boltzmann *(Tf(i,j,iblk) + Tffresh)**4 + fsurf (i,j,iblk) = c0 + fcondtop(i,j,iblk) = c0 + evap (i,j,iblk) = c0 + Tref (i,j,iblk) = Tair (i,j,iblk) + Qref (i,j,iblk) = Qa (i,j,iblk) + Uref (i,j,iblk) = wind (i,j,iblk) + fswthru (i,j,iblk) = c0 + fswthru_vdr (i,j,iblk) = c0 + fswthru_vdf (i,j,iblk) = c0 + fswthru_idr (i,j,iblk) = c0 + fswthru_idf (i,j,iblk) = c0 + alvdr (i,j,iblk) = c0 + alidr (i,j,iblk) = c0 + alvdf (i,j,iblk) = c0 + alidf (i,j,iblk) = c0 + fswthru_uvrdr (i,j,iblk) = c0 + fswthru_uvrdf (i,j,iblk) = c0 + fswthru_pardr (i,j,iblk) = c0 + fswthru_pardf (i,j,iblk) = c0 + endif + + enddo + enddo + + + call ice_timer_stop(timer_couple,iblk) ! atm/ocn coupling + + end subroutine coupling_atm + + subroutine coupling_ocn (iblk) + + use ice_blocks, only: nx_block, ny_block, get_block, block + use ice_domain, only: blocks_ice + use ice_calendar, only: dt, nstreams + use ice_domain_size, only: ncat + use ice_flux, only: fpond, fresh, l_mpond_fresh, & + fhocn_ai, fresh_ai, fsalt_ai, fsalt, & + fhocn, strairxT, strairyT + use ice_flux_bgc, only: faero_ocn, fiso_ocn, Qref_iso, fiso_evap, & + flux_bio, flux_bio_ai, & + fnit, fsil, famm, fdmsp, fdms, fhum, fdust, falgalN, & + fdoc, fdic, fdon, ffep, ffed, bgcflux_ice_to_ocn + use ice_grid, only: tmask, opmask + use ice_state, only: aicen, aice, aicen_init, aice_init + use ice_flux, only: flatn_f, fsurfn_f + use ice_timers, only: timer_couple, ice_timer_start, ice_timer_stop + + integer (kind=int_kind), intent(in) :: & + iblk ! block index + + ! local variables + + integer (kind=int_kind) :: & + ilo,ihi,jlo,jhi, & ! beginning and end of physical domain + n , & ! thickness category index + i,j , & ! horizontal indices + k , & ! tracer index + nbtrcr ! + + type (block) :: & + this_block ! block information for current block + + logical (kind=log_kind) :: & + skl_bgc , & ! + calc_Tsfc ! + + real (kind=dbl_kind) :: & + cszn , & ! counter for history averaging + puny , & ! + ar , & ! + rhofresh , & ! + netsw ! flag for shortwave radiation presence + + character(len=*), parameter :: subname = '(coupling_ocn)' + + !----------------------------------------------------------------- + + call icepack_query_parameters(puny_out=puny, rhofresh_out=rhofresh) + call icepack_query_parameters(skl_bgc_out=skl_bgc) + call icepack_query_tracer_sizes(nbtrcr_out=nbtrcr) + call icepack_query_parameters(calc_Tsfc_out=calc_Tsfc) + call icepack_warnings_flush(nu_diag) + if (icepack_warnings_aborted()) call abort_ice(error_message=subname, & + file=__FILE__, line=__LINE__) + + call ice_timer_start(timer_couple,iblk) ! atm/ocn coupling + + do j = 1, ny_block + do i = 1, nx_block + + !----------------------------------------------------------------- + ! reduce fresh by fpond for coupling + !----------------------------------------------------------------- + + if (l_mpond_fresh) then + fpond(i,j,iblk) = fpond(i,j,iblk) * rhofresh/dt + fresh(i,j,iblk) = fresh(i,j,iblk) - fpond(i,j,iblk) + endif + + !---------------------------------------------------------------- + ! Store grid box mean albedos and fluxes before scaling by aice + !---------------------------------------------------------------- + + fresh_ai (i,j,iblk) = fresh (i,j,iblk) + fsalt_ai (i,j,iblk) = fsalt (i,j,iblk) + fhocn_ai (i,j,iblk) = fhocn (i,j,iblk) + + if (nbtrcr > 0) then + do k = 1, nbtrcr + flux_bio_ai (i,j,k,iblk) = flux_bio (i,j,k,iblk) + enddo + endif + + enddo + enddo + + do j = 1, ny_block + do i = 1, nx_block + if ((tmask(i,j,iblk) .or. opmask(i,j,iblk)) .and. aice(i,j,iblk) > c0) then + ar = c1 / aice(i,j,iblk) + strairxT(i,j,iblk) = strairxT(i,j,iblk) * ar + strairyT(i,j,iblk) = strairyT(i,j,iblk) * ar + fresh(i,j,iblk) = fresh(i,j,iblk) * ar + fhocn(i,j,iblk) = fhocn(i,j,iblk) * ar + fsalt(i,j,iblk) = fsalt(i,j,iblk) * ar + flux_bio (i,j,:,iblk) = flux_bio (i,j,:,iblk) * ar + faero_ocn(i,j,:,iblk) = faero_ocn(i,j,:,iblk) * ar + Qref_iso (i,j,:,iblk) = Qref_iso (i,j,:,iblk) * ar + fiso_evap(i,j,:,iblk) = fiso_evap(i,j,:,iblk) * ar + fiso_ocn (i,j,:,iblk) = fiso_ocn (i,j,:,iblk) * ar + else + strairxT(i,j,iblk) = c0 + strairyT(i,j,iblk) = c0 + fresh(i,j,iblk) = c0 + fhocn(i,j,iblk) = c0 + fsalt(i,j,iblk) = c0 + flux_bio (i,j,:,iblk) = c0 + faero_ocn(i,j,:,iblk) = c0 + Qref_iso (i,j,:,iblk) = c0 + fiso_evap(i,j,:,iblk) = c0 + fiso_ocn (i,j,:,iblk) = c0 + endif + + enddo + enddo + + !----------------------------------------------------------------- + ! Define ice-ocean bgc fluxes + !----------------------------------------------------------------- + + if (nbtrcr > 0 .or. skl_bgc) then + call bgcflux_ice_to_ocn (nx_block, ny_block, & + flux_bio(:,:,1:nbtrcr,iblk), & + fnit(:,:,iblk), fsil(:,:,iblk), & + famm(:,:,iblk), fdmsp(:,:,iblk), & + fdms(:,:,iblk), fhum(:,:,iblk), & + fdust(:,:,iblk), falgalN(:,:,:,iblk), & + fdoc(:,:,:,iblk), fdic(:,:,:,iblk), & + fdon(:,:,:,iblk), ffep(:,:,:,iblk), & + ffed(:,:,:,iblk)) + endif + + call ice_timer_stop(timer_couple,iblk) ! atm/ocn coupling + + end subroutine coupling_ocn + +!======================================================================= + + subroutine ice_fast_physics + + use ice_boundary, only: ice_HaloUpdate + use ice_calendar, only: dt, dt_dyn, ndtd, diagfreq, write_restart, istep + use ice_calendar, only: istep1, calendar, advance_timestep + use ice_calendar, only: idate, msec + use ice_diagnostics, only: init_mass_diags, runtime_diags, debug_model, debug_ice + use ice_diagnostics_bgc, only: hbrine_diags, bgc_diags + use ice_domain, only: halo_info, nblocks + use ice_dyn_eap, only: write_restart_eap + use ice_dyn_shared, only: kdyn, kridge + use ice_flux, only: scale_factor, init_history_therm, & + daidtt, daidtd, dvidtt, dvidtd, dagedtt, dagedtd + use ice_flux, only: init_flux_atm, init_flux_ocn + use ice_history, only: accum_hist + use ice_history_bgc, only: init_history_bgc + use ice_restart, only: final_restart + use ice_restart_column, only: write_restart_age, write_restart_FY, & + write_restart_lvl, write_restart_pond_lvl, & + write_restart_pond_topo, write_restart_aero, write_restart_fsd, & + write_restart_iso, write_restart_bgc, write_restart_hbrine, & + write_restart_snow + use ice_restart_driver, only: dumpfile + use ice_restoring, only: restore_ice, ice_HaloRestore + use ice_step_mod, only: prep_radiation, step_therm1, step_therm2, & + update_state, step_dyn_horiz, step_dyn_ridge, step_radiation, & + biogeochemistry, step_prep, step_dyn_wave, step_snow + use ice_timers, only: ice_timer_start, ice_timer_stop, & + timer_diags, timer_column, timer_step, timer_thermo, & + timer_bound, timer_couple, timer_hist, timer_readwrite + + integer (kind=int_kind) :: & + iblk , & ! block index + k , & ! dynamics supercycling index + ktherm ! thermodynamics is off when ktherm = -1 + + real (kind=dbl_kind) :: & + offset ! d(age)/dt time offset + + logical (kind=log_kind) :: & + tr_iage, tr_FY, tr_lvl, tr_fsd, tr_snow, & + tr_pond_lvl, tr_pond_topo, tr_brine, tr_iso, tr_aero, & + calc_Tsfc, skl_bgc, z_tracers, wave_spec + + character(len=*), parameter :: subname = '(ice_fast_physics)' + + character (len=char_len) :: plabeld + + call ice_timer_start(timer_step) ! start timing entire run + + if (debug_model) then + plabeld = 'beginning time step' + do iblk = 1, nblocks + call debug_ice (iblk, plabeld) + enddo + endif + + call icepack_query_parameters(calc_Tsfc_out=calc_Tsfc, skl_bgc_out=skl_bgc, & + z_tracers_out=z_tracers, ktherm_out=ktherm, & + wave_spec_out=wave_spec) + call icepack_query_tracer_flags(tr_iage_out=tr_iage, tr_FY_out=tr_FY, & + tr_lvl_out=tr_lvl, tr_pond_lvl_out=tr_pond_lvl, & + tr_pond_topo_out=tr_pond_topo, tr_brine_out=tr_brine, tr_aero_out=tr_aero, & + tr_iso_out=tr_iso, tr_fsd_out=tr_fsd, tr_snow_out=tr_snow) + call icepack_warnings_flush(nu_diag) + if (icepack_warnings_aborted()) call abort_ice(error_message=subname, & + file=__FILE__, line=__LINE__) + + call ice_timer_start(timer_couple) ! atm/ocn coupling + + !call advance_timestep() ! advance timestep and update calendar data + + !if (z_tracers) call get_atm_bgc ! biogeochemistry + + call init_flux_atm ! Initialize atmosphere fluxes sent to coupler + call init_flux_ocn ! initialize ocean fluxes sent to coupler + + call ice_timer_stop(timer_couple) ! atm/ocn coupling + !----------------------------------------------------------------- + ! restoring on grid boundaries + !----------------------------------------------------------------- + + if (restore_ice) call ice_HaloRestore + + + !----------------------------------------------------------------- + ! initialize diagnostics and save initial state values + !----------------------------------------------------------------- + + call ice_timer_start(timer_diags) ! diagnostics/history + call init_mass_diags ! diagnostics per timestep + call init_history_therm + call init_history_bgc + call ice_timer_stop(timer_diags) ! diagnostics/history + + call step_prep + + call ice_timer_start(timer_column) ! column physics + call ice_timer_start(timer_thermo) ! thermodynamics + + !$OMP PARALLEL DO PRIVATE(iblk) + do iblk = 1, nblocks + + if (ktherm >= 0) then + + !----------------------------------------------------------------- + ! scale radiation fields + !----------------------------------------------------------------- + + !if (calc_Tsfc) call prep_radiation (iblk) + !if (debug_model) then + ! plabeld = 'post prep_radiation' + ! call debug_ice (iblk, plabeld) + !endif + + call step_radiation (dt, iblk) + if (debug_model) then + plabeld = 'post step_radiation' + call debug_ice (iblk, plabeld) + endif + + !----------------------------------------------------------------- + ! get ready for coupling and the next time step + !----------------------------------------------------------------- + + !call coupling_prep (iblk) + !if (debug_model) then + ! plabeld = 'post coupling_prep' + ! call debug_ice (iblk, plabeld) + !endif + + !----------------------------------------------------------------- + ! thermodynamics and biogeochemistry + !----------------------------------------------------------------- + + call step_therm1 (dt, iblk) ! vertical thermodynamics + if (debug_model) then + plabeld = 'post step_therm1' + call debug_ice (iblk, plabeld) + endif + + call coupling_atm (iblk) + if (debug_model) then + plabeld = 'post coupling_atm' + call debug_ice (iblk, plabeld) + endif + + endif ! ktherm > 0 + + enddo ! iblk + !$OMP END PARALLEL DO + + call ice_timer_stop(timer_thermo) ! thermodynamics + call ice_timer_stop(timer_column) ! column physics + + call ice_timer_stop(timer_step) ! start timing entire run + + end subroutine ice_fast_physics + +!======================================================================= + + subroutine ice_radiation + + use ice_calendar, only: dt + use ice_domain, only: nblocks + use ice_step_mod, only: step_radiation + use ice_timers, only: ice_timer_start, ice_timer_stop, & + timer_column, timer_thermo + use ice_arrays_column, only: alvdfn, alidfn, alvdrn, alidrn, & + fswthrun_vdr, fswthrun_vdf, fswthrun_idr, fswthrun_idf, & + fswthrun_uvrdr, fswthrun_uvrdf, fswthrun_pardr, fswthrun_pardf, & + albicen, albsnon, albpndn, apeffn, snowfracn + use ice_blocks, only: nx_block, ny_block, get_block, block + use ice_domain, only: blocks_ice + use ice_calendar, only: dt, nstreams + use ice_domain_size, only: ncat + use ice_flux, only: alvdf, alidf, alvdr, alidr, albice, albsno, & + albpnd, albcnt, apeff_ai, fpond, fresh, l_mpond_fresh, & + alvdf_ai, alidf_ai, alvdr_ai, alidr_ai, fhocn_ai, & + fresh_ai, fsalt_ai, fsalt, & + fswthru_ai, fhocn, fswthru, scale_factor, snowfrac, & + fswthru_vdr, fswthru_vdf, fswthru_idr, fswthru_idf, & + fswthru_uvrdr, fswthru_uvrdf, fswthru_pardr, fswthru_pardf, & + swvdr, swidr, swvdf, swidf, Tf, Tair, Qa, strairxT, strairyT, & + fsens, flat, fswabs, flwout, evap, Tref, Qref, & + scale_fluxes, frzmlt_init, frzmlt, Uref, wind + use ice_flux_bgc, only: faero_ocn, fiso_ocn, Qref_iso, fiso_evap, & + flux_bio, flux_bio_ai, & + fnit, fsil, famm, fdmsp, fdms, fhum, fdust, falgalN, & + fdoc, fdic, fdon, ffep, ffed, bgcflux_ice_to_ocn + use ice_grid, only: tmask, opmask + use ice_state, only: aicen, aice, aicen_init, aice_init + use ice_flux, only: flatn_f, fsurfn_f + use ice_step_mod, only: ocean_mixed_layer + + integer (kind=int_kind) :: & + i,j,n,iblk ! block index + + integer (kind=int_kind) :: & + ilo, ihi, jlo, jhi + + type (block) :: & + this_block ! block information for current block + + real (kind=dbl_kind) :: & + ar, puny + + character(len=*), parameter :: subname = '(ice_radiation)' + + call ice_timer_start(timer_column) ! column physics + call ice_timer_start(timer_thermo) ! thermodynamics + + call icepack_query_parameters(puny_out=puny) + + + !$OMP PARALLEL DO PRIVATE(iblk) + do iblk = 1, nblocks + !call step_albedo_only(dt, iblk) + call step_radiation(dt, iblk) + enddo ! iblk + !$OMP END PARALLEL DO + + do iblk = 1, nblocks + do j = 1, ny_block + do i = 1, nx_block + alvdf(i,j,iblk) = c0 + alidf(i,j,iblk) = c0 + alvdr(i,j,iblk) = c0 + alidr(i,j,iblk) = c0 + enddo + enddo + enddo + + do iblk = 1, nblocks + this_block = get_block(blocks_ice(iblk),iblk) + ilo = this_block%ilo + ihi = this_block%ihi + jlo = this_block%jlo + jhi = this_block%jhi + + do n = 1, ncat + do j = jlo, jhi + do i = ilo, ihi + if (aicen_init(i,j,n,iblk) > puny) then + + alvdf(i,j,iblk) = alvdf(i,j,iblk) & + + alvdfn(i,j,n,iblk)*aicen_init(i,j,n,iblk) + alidf(i,j,iblk) = alidf(i,j,iblk) & + + alidfn(i,j,n,iblk)*aicen_init(i,j,n,iblk) + alvdr(i,j,iblk) = alvdr(i,j,iblk) & + + alvdrn(i,j,n,iblk)*aicen_init(i,j,n,iblk) + alidr(i,j,iblk) = alidr(i,j,iblk) & + + alidrn(i,j,n,iblk)*aicen_init(i,j,n,iblk) + + endif ! aicen_init > puny + enddo + enddo + enddo + enddo + + do iblk = 1, nblocks + do j = 1, ny_block + do i = 1, nx_block + if ((tmask(i,j,iblk) .or. opmask(i,j,iblk)) .and. aice_init(i,j,iblk) > c0) then + ar = c1 / aice_init(i,j,iblk) + alvdr (i,j,iblk) = alvdr (i,j,iblk) * ar + alidr (i,j,iblk) = alidr (i,j,iblk) * ar + alvdf (i,j,iblk) = alvdf (i,j,iblk) * ar + alidf (i,j,iblk) = alidf (i,j,iblk) * ar + else + alvdr (i,j,iblk) = c0 + alidr (i,j,iblk) = c0 + alvdf (i,j,iblk) = c0 + alidf (i,j,iblk) = c0 + endif + enddo ! i + enddo ! j + enddo ! iblk + + call ice_timer_stop(timer_thermo) ! thermodynamics + call ice_timer_stop(timer_column) ! column physics + + + end subroutine ice_radiation + + + end module CICE_RunMod + +!======================================================================= diff --git a/cicecore/drivers/mapl/geos/CICE_copyright.txt b/cicecore/drivers/mapl/geos/CICE_copyright.txt new file mode 100644 index 000000000..9ee3d2c60 --- /dev/null +++ b/cicecore/drivers/mapl/geos/CICE_copyright.txt @@ -0,0 +1,17 @@ +! Copyright (c) 1998, 2017, Triad National Security, LLC +! All rights reserved. +! +! This program was produced under U.S. Government contract 89233218CNA000001 +! for Los Alamos National Laboratory (LANL), which is operated by Triad +! National Security, LLC for the U.S. Department of Energy/National Nuclear +! Security Administration. All rights in the program are reserved by Triad +! National Security, LLC, and the U.S. Department of Energy/National Nuclear +! Security Administration. The Government is granted for itself and others +! acting on its behalf a nonexclusive, paid-up, irrevocable worldwide +! license in this material to reproduce, prepare. derivative works, +! distribute copies to the public, perform publicly and display publicly, +! and to permit others to do so. +! +! The full license and distribution policy are available from +! https://github.com/CICE-Consortium +! diff --git a/cicecore/drivers/mapl/geos/ice_import_export.F90 b/cicecore/drivers/mapl/geos/ice_import_export.F90 new file mode 100644 index 000000000..ce87289a7 --- /dev/null +++ b/cicecore/drivers/mapl/geos/ice_import_export.F90 @@ -0,0 +1,1092 @@ +module ice_import_export + + use ESMF + use ice_kinds_mod , only : int_kind, dbl_kind, real_kind, char_len, log_kind + use ice_constants , only : c0, c1, c2, p5, p25, spval_dbl, radius + use ice_constants , only : field_loc_center, field_type_scalar, field_type_vector + use ice_blocks , only : block, get_block, nx_block, ny_block, nghost + use ice_domain , only : nblocks, blocks_ice, halo_info, distrb_info + use ice_domain_size , only : nx_global, ny_global, block_size_x, block_size_y, max_blocks, ncat + use ice_exit , only : abort_ice + use ice_flux , only : strairxt, strairyt, strocnxT_iavg, strocnyT_iavg + use ice_flux , only : alvdr, alidr, alvdf, alidf, Tref, Qref, Uref + use ice_flux , only : flat, fsens, flwout, evap, fswabs, fhocn, fswthru + use ice_flux , only : evapn_f, fsurfn_f, dfsurfndTsfc_f, dflatndTsfc_f + use ice_flux , only : flatn_f, coszen + use ice_flux , only : fswthru_uvrdr, fswthru_uvrdf, fswthru_pardr, fswthru_pardf + use ice_flux , only : send_i2x_per_cat, fswthrun_ai + use ice_flux_bgc , only : faero_atm, faero_ocn + use ice_flux_bgc , only : fiso_atm, fiso_ocn, fiso_evap + use ice_flux_bgc , only : Qa_iso, Qref_iso, HDO_ocn, H2_18O_ocn, H2_16O_ocn + use ice_flux , only : fresh, fsalt, zlvl, uatm, vatm, potT, Tair, Qa + use ice_flux , only : fresh_ai, fsalt_ai, fhocn_ai + use ice_flux , only : rhoa, swvdr, swvdf, swidr, swidf, flw, frain + use ice_flux , only : swuvrdr, swuvrdf, swpardr, swpardf + use ice_flux , only : fcondtop + use ice_flux , only : fsnow, uocn, vocn, sst, ss_tltx, ss_tlty, frzmlt + use ice_flux , only : send_i2x_per_cat + use ice_flux , only : sss, Tf, wind, fsw + use ice_state , only : vice, vsno, aice, aicen, trcr, trcrn + use ice_state , only : Tsfcn_init, aice_init, uvel, vvel + use ice_grid , only : tlon, tlat, tarea, tmask, umask, anglet, ocn_gridcell_frac, hm + use ice_grid , only : dxu, dyu, dxE, dyE, dxN, dyN, nmask, emask + use ice_grid , only : dxT, dyT + use ice_grid , only : grid_ice, grid_ocn + use ice_boundary , only : ice_HaloUpdate + use ice_shr_methods , only : chkerr + use ice_fileunits , only : nu_diag, flush_fileunit + use ice_communicate , only : my_task, master_task, MPI_COMM_ICE + use ice_prescribed_mod , only : prescribed_ice + use icepack_intfc , only : icepack_warnings_flush, icepack_warnings_aborted + use icepack_intfc , only : icepack_query_parameters, icepack_query_tracer_flags + use icepack_intfc , only : icepack_liquidus_temperature + use icepack_intfc , only : icepack_sea_freezing_temperature + + implicit none + public + + public :: ice_import_thermo1 + public :: ice_export_thermo1 + public :: ice_import_grid + !public :: ice_import_thermo2 + !public :: ice_export_thermo2 + public :: ice_import_dyna + public :: ice_export_dyna + public :: ice_export_field + + interface ice_export_field + module procedure ice_export_field_2d + module procedure ice_export_field_3d + end interface ice_export_field + + private :: state_FldChk + + interface state_getfldptr + module procedure state_getfldptr_1d + module procedure state_getfldptr_2d + module procedure state_getfldptr_3d + end interface state_getfldptr + private :: state_getfldptr + + interface state_getimport + module procedure state_getimport_4d + module procedure state_getimport_3d + end interface state_getimport + private :: state_getimport + + interface state_setexport + module procedure state_setexport_4d + module procedure state_setexport_3d + end interface state_setexport + private :: state_setexport + + interface arr_setexport + module procedure arr_setexport_4d + module procedure arr_setexport_3d + end interface arr_setexport + private :: arr_setexport + + ! Private module data + + type fld_list_type + character(len=128) :: stdname + integer :: ungridded_lbound = 0 + integer :: ungridded_ubound = 0 + end type fld_list_type + + ! area correction factors for fluxes send and received from mediator + real(dbl_kind), allocatable :: mod2med_areacor(:) ! ratios of model areas to input mesh areas + real(dbl_kind), allocatable :: med2mod_areacor(:) ! ratios of input mesh areas to model areas + + integer, parameter :: fldsMax = 100 + integer :: fldsToIce_num = 0 + integer :: fldsFrIce_num = 0 + type (fld_list_type) :: fldsToIce(fldsMax) + type (fld_list_type) :: fldsFrIce(fldsMax) + + integer , parameter :: io_dbug = 10 ! i/o debug messages + character(*), parameter :: u_FILE_u = & + __FILE__ + +!============================================================================== +contains +!============================================================================== + subroutine ice_import_grid( fro, rc ) + + ! input/output variables + real(kind=real_kind), dimension(:,:), intent(in) :: fro + integer , intent(out) :: rc + + integer :: i, j, i1, j1, k, iblk, n + integer :: ilo, ihi, jlo, jhi !beginning and end of physical domain + type(block) :: this_block ! block information for current block + + do iblk = 1, nblocks + this_block = get_block(blocks_ice(iblk),iblk) + ilo = this_block%ilo + ihi = this_block%ihi + jlo = this_block%jlo + jhi = this_block%jhi + do j = jlo, jhi + j1 = j - nghost + do i = ilo, ihi + i1 = i - nghost + ocn_gridcell_frac(i,j,iblk) = real(fro(i1, j1), kind=dbl_kind) + enddo + enddo + enddo + + rc = ESMF_SUCCESS + + end subroutine ice_import_grid + !=============================================================================== + + subroutine ice_import_thermo1( importState, rc ) + + ! input/output variables + type(ESMF_State) , intent(in) :: importState + integer , intent(out) :: rc + + ! local variables + integer,parameter :: nfldu=5 + integer,parameter :: nfld=12 + integer :: i, j, k, iblk, n + integer :: ilo, ihi, jlo, jhi !beginning and end of physical domain + type(block) :: this_block ! block information for current block + real (kind=dbl_kind) :: Tffresh + real (kind=dbl_kind),allocatable :: afldu(:,:,:,:,:) + real (kind=dbl_kind),allocatable :: afld(:,:,:,:) + character(len=*), parameter :: subname = 'ice_import_thermo1' + character(len=1024) :: msgString + !----------------------------------------------------- + + call icepack_query_parameters(Tffresh_out=Tffresh) + call icepack_warnings_flush(nu_diag) + if (icepack_warnings_aborted()) call abort_ice(error_message=subname, & + file=u_FILE_u, line=__LINE__) + + + allocate(afldu(nx_block,ny_block,ncat,nfldu,nblocks)) + afldu = c0 + allocate( afld(nx_block,ny_block, nfld,nblocks)) + afld = c0 + + !call state_getimport(importState, 'TSKINICE', output=afldu, index=1, rc=rc) + !if (ChkErr(rc,__LINE__,u_FILE_u)) return + call state_getimport(importState, 'EVAP', output=afldu, index=1, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + call state_getimport(importState, 'FSURF', output=afldu, index=2, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + call state_getimport(importState, 'DFSURFDTS', output=afldu, index=3, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + call state_getimport(importState, 'DLHFDTS', output=afldu, index=4, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + call state_getimport(importState, 'LHF', output=afldu, index=5, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + + + call state_getimport(importState, 'SNOW', output=afld, index=1, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + call state_getimport(importState, 'RAIN', output=afld, index=2, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + call state_getimport(importState, 'DRPAR', output=afld, index=3, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + call state_getimport(importState, 'DFPAR', output=afld, index=4, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + call state_getimport(importState, 'DRNIR', output=afld, index=5, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + call state_getimport(importState, 'DFNIR', output=afld, index=6, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + call state_getimport(importState, 'DRUVR', output=afld, index=7, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + call state_getimport(importState, 'DFUVR', output=afld, index=8, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + call state_getimport(importState, 'COSZ', output=afld, index=9, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + + call state_getimport(importState, 'SST', output=afld, index=10, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + call state_getimport(importState, 'SSS', output=afld, index=11, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + call state_getimport(importState, 'FRZMLT', output=afld, index=12, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + + ! now fill in the ice internal data types + do k = 1, ncat + !$OMP PARALLEL DO PRIVATE(iblk,i,j) + do iblk = 1, nblocks + do j = 1,ny_block + do i = 1,nx_block + !trcrn (i,j,1,k,iblk) = afldu(i,j,k,1,iblk) - Tffresh + evapn_f (i,j,k,iblk) = afldu(i,j,k,1,iblk) + fsurfn_f (i,j,k,iblk) = afldu(i,j,k,2,iblk) + dfsurfndTsfc_f(i,j,k,iblk) = afldu(i,j,k,3,iblk) + dflatndTsfc_f(i,j,k,iblk) = afldu(i,j,k,4,iblk) + flatn_f (i,j,k,iblk) = afldu(i,j,k,5,iblk) + end do + end do + end do + !$OMP END PARALLEL DO + end do + + !$OMP PARALLEL DO PRIVATE(iblk,i,j) + do iblk = 1, nblocks + do j = 1,ny_block + do i = 1,nx_block + fsnow (i,j,iblk) = afld(i,j,1,iblk) + frain (i,j,iblk) = afld(i,j,2,iblk) + swvdr (i,j,iblk) = afld(i,j,3,iblk) + afld(i,j,7,iblk) + swidr (i,j,iblk) = afld(i,j,5,iblk) + swvdf (i,j,iblk) = afld(i,j,4,iblk) + afld(i,j,8,iblk) + swidf (i,j,iblk) = afld(i,j,6,iblk) + swuvrdr(i,j,iblk) = afld(i,j,7,iblk) + swuvrdf(i,j,iblk) = afld(i,j,8,iblk) + swpardr(i,j,iblk) = afld(i,j,3,iblk) + swpardf(i,j,iblk) = afld(i,j,4,iblk) + coszen(i,j,iblk) = afld(i,j,9,iblk) + sst (i,j,iblk) = afld(i,j,10,iblk) - Tffresh + sss (i,j,iblk) = afld(i,j,11,iblk) + frzmlt(i,j,iblk) = afld(i,j,12,iblk) + fsw (i,j,iblk) = swvdr(i,j,iblk) + swvdf(i,j,iblk) & + + swidr(i,j,iblk) + swidf(i,j,iblk) + end do + end do + end do + !$OMP END PARALLEL DO + + + + !== will change to read in from coupler once Tf from MOM is ready + !$OMP PARALLEL DO PRIVATE(iblk,i,j) + do iblk = 1, nblocks + do j = 1,ny_block + do i = 1,nx_block + Tf(i,j,iblk) = icepack_sea_freezing_temperature(sss(i,j,iblk)) + end do + end do + end do + !$OMP END PARALLEL DO + + deallocate(afldu) + deallocate(afld) + + rc = ESMF_SUCCESS + + end subroutine ice_import_thermo1 + + subroutine ice_import_radiation( importState, rc ) + + ! input/output variables + type(ESMF_State) , intent(in) :: importState + integer , intent(out) :: rc + + ! local variables + integer,parameter :: nfld=1 + integer :: i, j, k, iblk + integer :: ilo, ihi, jlo, jhi !beginning and end of physical domain + type(block) :: this_block ! block information for current block + real (kind=dbl_kind),allocatable :: afld(:,:,:,:) + character(len=*), parameter :: subname = 'ice_import_radiation' + character(len=1024) :: msgString + !----------------------------------------------------- + + + allocate( afld(nx_block,ny_block, nfld,nblocks)) + afld = c0 + + call state_getimport(importState, 'COSZ', output=afld, index=1, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + + !$OMP PARALLEL DO PRIVATE(iblk,i,j) + do iblk = 1, nblocks + do j = 1,ny_block + do i = 1,nx_block + coszen(i,j,iblk) = afld(i,j,1,iblk) + end do + end do + end do + !$OMP END PARALLEL DO + + deallocate(afld) + + rc = ESMF_SUCCESS + + end subroutine ice_import_radiation + + subroutine ice_import_dyna( taux, tauy, slv, uoa, voa, uob, vob, uoc, voc, rc ) + + ! input/output variables + real(kind=real_kind) , intent(in) :: taux(:,:) + real(kind=real_kind) , intent(in) :: tauy(:,:) + real(kind=real_kind) , intent(in) :: slv(:,:) + real(kind=real_kind) , intent(in) :: uoa(:,:) + real(kind=real_kind) , intent(in) :: voa(:,:) + real(kind=real_kind) , intent(in) :: uob(:,:) + real(kind=real_kind) , intent(in) :: vob(:,:) + real(kind=real_kind) , intent(in) :: uoc(:,:) + real(kind=real_kind) , intent(in) :: voc(:,:) + integer , intent(out):: rc + + ! local variables + integer :: i, j, k, iblk + integer :: i1, j1 + integer :: ilo, ihi, jlo, jhi !beginning and end of physical domain + type(block) :: this_block ! block information for current block + real(kind=dbl_kind) :: workx, worky + real(kind=dbl_kind) :: slp_L, slp_R, slp_C + real(kind=dbl_kind) :: u_min, u_max, slope + real(kind=dbl_kind) :: ssh(nx_block,ny_block,max_blocks) + character(len=*), parameter :: subname = 'ice_import_dyna' + character(len=1024) :: msgString + !----------------------------------------------------- + + + do iblk = 1, nblocks + this_block = get_block(blocks_ice(iblk),iblk) + ilo = this_block%ilo + ihi = this_block%ihi + jlo = this_block%jlo + jhi = this_block%jhi + do j = jlo, jhi + j1 = j - nghost + do i = ilo, ihi + i1 = i - nghost + if(tmask(i,j,iblk)) then + workx = real(taux(i1, j1), kind=dbl_kind) + worky = real(tauy(i1, j1), kind=dbl_kind) + strairxT(i,j,iblk) = workx*cos(ANGLET(i,j,iblk)) & ! convert to POP grid + + worky*sin(ANGLET(i,j,iblk)) ! note strax, stray, wind + strairyT(i,j,iblk) = worky*cos(ANGLET(i,j,iblk)) & ! are on the T-grid here + - workx*sin(ANGLET(i,j,iblk)) + ! multiply by aice to properly treat free drift + strairxT(i,j,iblk) = strairxT(i,j,iblk) * aice_init(i,j,iblk) + strairyT(i,j,iblk) = strairyT(i,j,iblk) * aice_init(i,j,iblk) + ssh(i,j,iblk) = real(slv(i1,j1), kind=dbl_kind) + else + strairxT(i,j,iblk) = c0 + strairyT(i,j,iblk) = c0 + ssh(i,j,iblk) = c0 + endif + if(trim(grid_ocn) == 'A') then + if(tmask(i,j,iblk)) then + workx = real(uoa(i1,j1), kind=dbl_kind) + worky = real(voa(i1,j1), kind=dbl_kind) + uocn(i,j,iblk) = workx*cos(ANGLET(i,j,iblk)) & ! convert to POP grid + + worky*sin(ANGLET(i,j,iblk)) ! note strax, stray, wind + vocn(i,j,iblk) = worky*cos(ANGLET(i,j,iblk)) & ! are on the T-grid here + - workx*sin(ANGLET(i,j,iblk)) + else + uocn(i,j,iblk) = c0 + vocn(i,j,iblk) = c0 + endif + elseif(trim(grid_ice) == 'B') then + if(umask(i,j,iblk)) then + uocn(i,j,iblk) = real(uob(i1,j1), kind=dbl_kind) + vocn(i,j,iblk) = real(vob(i1,j1), kind=dbl_kind) + else + uocn(i,j,iblk) = c0 + vocn(i,j,iblk) = c0 + endif + elseif(trim(grid_ice) == 'C') then + if(emask(i,j,iblk)) then + uocn(i,j,iblk) = real(uoc(i1,j1), kind=dbl_kind) + else + uocn(i,j,iblk) = c0 + endif + if(nmask(i,j,iblk)) then + vocn(i,j,iblk) = real(voc(i1,j1), kind=dbl_kind) + else + vocn(i,j,iblk) = c0 + endif + else + call abort_ice(error_message='unknown grid_ice', & + file=u_FILE_u, line=__LINE__) + endif + enddo + enddo + enddo + + call ice_HaloUpdate (ssh, halo_info, & + field_loc_center, field_type_scalar) + + !*** if C-grid ice dynamics is on, the following needs to be revised + !*** so a query of which dynamics (B- or C-) should be made and branch into + !*** different computation of ss_tlt* terms + do iblk = 1, nblocks + this_block = get_block(blocks_ice(iblk),iblk) + ilo = this_block%ilo + ihi = this_block%ihi + jlo = this_block%jlo + jhi = this_block%jhi + do j = jlo, jhi + do i = ilo, ihi + if(trim(grid_ocn) == 'A') then + if(tmask(i,j,iblk)) then + slp_L = ssh(I,j,iblk) - ssh(I-1,j,iblk) + if(.not. emask(i-1,j,iblk)) slp_L = c0 + slp_R = ssh(I+1,j,iblk) - ssh(I,j,iblk) + if(.not. emask(i,j,iblk)) slp_R = c0 + slp_C = p5 * (slp_L + slp_R) + if ( (slp_L * slp_R) > c0 ) then + ! This limits the slope so that the edge values are bounded by the + ! two cell averages spanning the edge. + u_min = min( ssh(i-1,j,iblk), ssh(i,j,iblk), ssh(i+1,j,iblk) ) + u_max = max( ssh(i-1,j,iblk), ssh(i,j,iblk), ssh(i+1,j,iblk) ) + slope = sign( min( abs(slp_C), c2*min( ssh(i,j,iblk) - u_min, u_max - ssh(i,j,iblk) ) ), slp_C ) + else + ! Extrema in the mean values require a PCM reconstruction avoid generating + ! larger extreme values. + slope = c0 + endif + ss_tltx(i,j,iblk) = slope / dxT(i,j,iblk) + + slp_L = ssh(I,j,iblk) - ssh(I,j-1,iblk) + if(.not. nmask(i,j-1,iblk)) slp_L = c0 + slp_R = ssh(I,j+1,iblk) - ssh(I,j,iblk) + if(.not. nmask(i,j,iblk)) slp_R = c0 + slp_C = p5 * (slp_L + slp_R) + if ( (slp_L * slp_R) > c0 ) then + ! This limits the slope so that the edge values are bounded by the + ! two cell averages spanning the edge. + u_min = min( ssh(i,j-1,iblk), ssh(i,j,iblk), ssh(i,j+1,iblk) ) + u_max = max( ssh(i,j-1,iblk), ssh(i,j,iblk), ssh(i,j+1,iblk) ) + slope = sign( min( abs(slp_C), c2*min( ssh(i,j,iblk) - u_min, u_max - ssh(i,j,iblk) ) ), slp_C ) + else + ! Extrema in the mean values require a PCM reconstruction avoid generating + ! larger extreme values. + slope = c0 + endif + ss_tlty(i,j,iblk) = slope / dyT(i,j,iblk) + else + ss_tltx(i,j,iblk) = c0 + ss_tlty(i,j,iblk) = c0 + endif + elseif(trim(grid_ice) == 'B') then + if(umask(i,j,iblk)) then + ss_tltx(i,j,iblk) = p5*(ssh(i+1,j+1,iblk)-ssh(i,j+1,iblk) & + +ssh(i+1,j ,iblk)-ssh(i,j ,iblk)) & + /dxu(i,j,iblk) + ss_tlty(i,j,iblk) = p5*(ssh(i+1,j+1,iblk)+ssh(i,j+1,iblk) & + -ssh(i+1,j ,iblk)-ssh(i,j ,iblk)) & + /dyu(i,j,iblk) + else + ss_tltx(i,j,iblk) = c0 + ss_tlty(i,j,iblk) = c0 + endif + elseif(trim(grid_ice) == 'C') then + if(emask(i,j,iblk)) then + ss_tltx(i,j,iblk) = (ssh(i+1,j ,iblk)-ssh(i,j ,iblk)) & + /dxE(i,j,iblk) + else + ss_tltx(i,j,iblk) = c0 + endif + if(nmask(i,j,iblk)) then + ss_tlty(i,j,iblk) = (ssh(i,j+1,iblk) - ssh(i,j ,iblk)) & + /dyN(i,j,iblk) + else + ss_tlty(i,j,iblk) = c0 + endif + else + call abort_ice(error_message='unknown grid_ice', & + file=u_FILE_u, line=__LINE__) + endif + enddo + enddo + enddo + + rc = ESMF_SUCCESS + + end subroutine ice_import_dyna + + subroutine ice_export_dyna( tauxo, tauyo, ui, vi, rc ) + + ! input/output variables + real(kind=real_kind) , intent(out) :: tauxo(:,:) + real(kind=real_kind) , intent(out) :: tauyo(:,:) + real(kind=real_kind) , intent(out) :: ui (:,:) + real(kind=real_kind) , intent(out) :: vi (:,:) + integer , intent(out):: rc + + ! local variables + integer :: i, j, k, iblk + integer :: i1, j1 + integer :: ilo, ihi, jlo, jhi !beginning and end of physical domain + type(block) :: this_block ! block information for current block + real(kind=dbl_kind) :: workx, worky + character(len=*), parameter :: subname = 'ice_export_dyna' + character(len=1024) :: msgString + !----------------------------------------------------- + + + do iblk = 1, nblocks + this_block = get_block(blocks_ice(iblk),iblk) + ilo = this_block%ilo + ihi = this_block%ihi + jlo = this_block%jlo + jhi = this_block%jhi + do j = jlo, jhi + j1 = j - nghost + do i = ilo, ihi + i1 = i - nghost + ! ice/ocean stress (on POP T-grid: convert to lat-lon) + workx = strocnxT_iavg(i,j,iblk) ! N/m^2 + worky = strocnyT_iavg(i,j,iblk) ! N/m^2 + tauxo(i1,j1) = real(workx*cos(ANGLET(i,j,iblk)) - & + worky*sin(ANGLET(i,j,iblk)), kind=real_kind) + tauyo(i1,j1) = real(worky*cos(ANGLET(i,j,iblk)) + & + workx*sin(ANGLET(i,j,iblk)), kind=real_kind) + workx = p25*(uvel(i,j ,iblk) + uvel(i-1,j ,iblk) & ! cell-centered velocity + + uvel(i,j-1,iblk) + uvel(i-1,j-1,iblk)) ! assumes wind components + worky = p25*(vvel(i,j ,iblk) + vvel(i-1,j ,iblk) & ! are also cell-centered + + vvel(i,j-1,iblk) + vvel(i-1,j-1,iblk)) + ui(i1,j1) = real(workx*cos(ANGLET(i,j,iblk)) - & + worky*sin(ANGLET(i,j,iblk)), kind=real_kind) + vi(i1,j1) = real(worky*cos(ANGLET(i,j,iblk)) + & + workx*sin(ANGLET(i,j,iblk)), kind=real_kind) + enddo + enddo + enddo + + rc = ESMF_SUCCESS + + end subroutine ice_export_dyna + + !=============================================================================== + subroutine ice_export_thermo1( exportState, rc ) + + ! input/output variables + type(ESMF_State), intent(inout) :: exportState + integer , intent(out) :: rc + + ! local variables + type(block) :: this_block ! block information for current block + integer :: i, j, iblk, n ! incides + integer :: n2 ! thickness category index + integer :: ilo, ihi, jlo, jhi ! beginning and end of physical domain + real (kind=dbl_kind) :: workx, worky ! tmps for converting grid + logical :: flag + integer (kind=int_kind) :: indxi (nx_block*ny_block) ! compressed indices in i + integer (kind=int_kind) :: indxj (nx_block*ny_block) ! compressed indices in i + real (kind=dbl_kind) :: dTsrf (nx_block,ny_block,ncat,max_blocks) ! surface temperature + real (kind=dbl_kind) :: Tffresh + !integer, parameter :: nfldu=1 + !real (kind=dbl_kind),allocatable :: afldu(:,:,:,:,:) + character(len=*),parameter :: subname = 'ice_export_thermo1' + !----------------------------------------------------- + + rc = ESMF_SUCCESS + if (io_dbug > 5) call ESMF_LogWrite(subname//' called', ESMF_LOGMSG_INFO) + + call icepack_query_parameters(Tffresh_out=Tffresh) + ! call icepack_query_parameters(tfrz_option_out=tfrz_option, & + ! modal_aero_out=modal_aero, z_tracers_out=z_tracers, skl_bgc_out=skl_bgc, & + ! Tffresh_out=Tffresh) + ! call icepack_query_tracer_flags(tr_aero_out=tr_aero, tr_iage_out=tr_iage, & + ! tr_FY_out=tr_FY, tr_pond_out=tr_pond, tr_lvl_out=tr_lvl, & + ! tr_zaero_out=tr_zaero, tr_bgc_Nit_out=tr_bgc_Nit) + + call icepack_warnings_flush(nu_diag) + if (icepack_warnings_aborted()) call abort_ice(error_message=subname, & + file=u_FILE_u, line=__LINE__) + + !--------------------------------- + ! Create the export state + !--------------------------------- + !allocate(afldu(nx_block,ny_block,ncat,nfldu,nblocks)) + !afldu = c0 + !call state_getimport(exportState, 'TSKINICE', output=afldu, index=1, rc=rc) + !if (ChkErr(rc,__LINE__,u_FILE_u)) return + + dTsrf = trcrn(:,:,1,:,:) - Tsfcn_init + + call state_setexport(exportState, 'DTS', input=dTsrf, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + + call state_setexport(exportState, 'ALBVR', input=alvdr, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + call state_setexport(exportState, 'ALBVF', input=alvdf, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + call state_setexport(exportState, 'ALBNR', input=alidr, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + call state_setexport(exportState, 'ALBNF', input=alidf, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + + call state_setexport(exportState, 'PENUVR', input=fswthru_uvrdr, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + call state_setexport(exportState, 'PENUVF', input=fswthru_uvrdf, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + call state_setexport(exportState, 'PENPAR', input=fswthru_pardr, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + call state_setexport(exportState, 'PENPAF', input=fswthru_pardf, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + + call state_setexport(exportState, 'GHTSKIN', input=fcondtop, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + + !deallocate(afldu) + + end subroutine ice_export_thermo1 + + subroutine ice_export_radiation( exportState, rc ) + + ! input/output variables + type(ESMF_State), intent(inout) :: exportState + integer , intent(out) :: rc + + ! local variables + character(len=*),parameter :: subname = 'ice_export_radiation' + !----------------------------------------------------- + + rc = ESMF_SUCCESS + if (io_dbug > 5) call ESMF_LogWrite(subname//' called', ESMF_LOGMSG_INFO) + + call state_setexport(exportState, 'ALBVR', input=alvdr, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + call state_setexport(exportState, 'ALBVF', input=alvdf, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + call state_setexport(exportState, 'ALBNR', input=alidr, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + call state_setexport(exportState, 'ALBNF', input=alidf, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + + end subroutine ice_export_radiation + + subroutine ice_export_field_3d(fldname, fld, rc) + + ! input/output variables + character(len=*) , intent(in) :: fldname + real(kind=real_kind) , intent(out) :: fld(:,:,:) + integer , intent(out) :: rc + + ! local variables + character(len=*),parameter :: subname = 'ice_export_field_3d' + real(kind=dbl_kind) :: Tffresh + + rc = ESMF_SUCCESS + + call icepack_query_parameters(Tffresh_out=Tffresh) + ! call icepack_query_parameters(tfrz_option_out=tfrz_option, & + ! modal_aero_out=modal_aero, z_tracers_out=z_tracers, skl_bgc_out=skl_bgc, & + ! Tffresh_out=Tffresh) + ! call icepack_query_tracer_flags(tr_aero_out=tr_aero, tr_iage_out=tr_iage, & + ! tr_FY_out=tr_FY, tr_pond_out=tr_pond, tr_lvl_out=tr_lvl, & + ! tr_zaero_out=tr_zaero, tr_bgc_Nit_out=tr_bgc_Nit) + + call icepack_warnings_flush(nu_diag) + if (icepack_warnings_aborted()) call abort_ice(error_message=subname, & + file=u_FILE_u, line=__LINE__) + + if (trim(fldname) == 'TI') then + call arr_setexport_4d(fld, trcrn(:,:,1,:,:), rc) + fld(:,:,:) = real(Tffresh, kind=real_kind) + fld(:,:,:) !Kelvin (original ???) + elseif (trim(fldname) == 'FRSEAICE') then + call arr_setexport_4d(fld, aicen, rc) + else + call ESMF_LogWrite(trim(subname)//": "//trim(fldname)//" not available for export", ESMF_LOGMSG_ERROR) + rc = ESMF_FAILURE + return + endif + + end subroutine ice_export_field_3d + + subroutine ice_export_field_2d(fldname, fld, rc) + + ! input/output variables + character(len=*) , intent(in) :: fldname + real(kind=real_kind) , intent(out) :: fld(:,:) + integer , intent(out) :: rc + + ! local variables + character(len=*),parameter :: subname = 'ice_export_field_2d' + + + rc = ESMF_SUCCESS + + if (trim(fldname) == 'FRACICE') then + call arr_setexport_3d(fld, aice, rc) + elseif (trim(fldname) == 'FHOCN') then + call arr_setexport_3d(fld, fhocn_ai, rc) + elseif (trim(fldname) == 'FRESH') then + call arr_setexport_3d(fld, fresh_ai, rc) + elseif (trim(fldname) == 'FSALT') then + call arr_setexport_3d(fld, fsalt_ai, rc) + else + call ESMF_LogWrite(trim(subname)//": "//trim(fldname)//" not available for export", ESMF_LOGMSG_ERROR) + rc = ESMF_FAILURE + return + endif + + end subroutine ice_export_field_2d + + !=============================================================================== + logical function State_FldChk(State, fldname) + ! ---------------------------------------------- + ! Determine if field is in state + ! ---------------------------------------------- + + ! input/output variables + type(ESMF_State) , intent(in) :: State + character(len=*) , intent(in) :: fldname + + ! local variables + type(ESMF_StateItem_Flag) :: itemType + ! ---------------------------------------------- + + call ESMF_StateGet(State, trim(fldname), itemType) + State_FldChk = (itemType /= ESMF_STATEITEM_NOTFOUND) + + end function State_FldChk + + !=============================================================================== + subroutine state_getimport_4d(state, fldname, output, index, rc) + + ! ---------------------------------------------- + ! Map import state field to output array + ! ---------------------------------------------- + + ! input/output variables + type(ESMF_State) , intent(in) :: state + character(len=*) , intent(in) :: fldname + real (kind=dbl_kind) , intent(inout) :: output(:,:,:,:,:) + integer , intent(in) :: index + integer , intent(out) :: rc + + ! local variables + type(block) :: this_block ! block information for current block + integer :: ilo, ihi, jlo, jhi ! beginning and end of physical domain + integer :: i, j, k, iblk, n, i1, j1 ! incides + !real(kind=real_kind), pointer :: dataPtr1d(:,:) ! mesh + real(kind=real_kind), pointer :: dataPtr3d(:,:,:) ! mesh + + character(len=*), parameter :: subname='(ice_import_export:state_getimport_4d)' + ! ---------------------------------------------- + + rc = ESMF_SUCCESS + + ! check that fieldname exists + if (.not. State_FldChk(state, trim(fldname))) return + + ! get field pointer + call state_getfldptr(state, trim(fldname), dataPtr3d, rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + + ! set values of output array + do k = 1, ncat + do iblk = 1, nblocks + this_block = get_block(blocks_ice(iblk),iblk) + ilo = this_block%ilo + ihi = this_block%ihi + jlo = this_block%jlo + jhi = this_block%jhi + do j = jlo, jhi + j1 = j - nghost + do i = ilo, ihi + i1 = i - nghost + output(i,j,k,index,iblk) = real(dataPtr3d(i1,j1,k), kind=dbl_kind) + end do + end do + end do + end do + + end subroutine state_getimport_4d + + !=============================================================================== + subroutine state_getimport_3d(state, fldname, output, index, rc) + + ! ---------------------------------------------- + ! Map import state field to output array + ! ---------------------------------------------- + + ! input/output variables + type(ESMF_State) , intent(in) :: state + character(len=*) , intent(in) :: fldname + real (kind=dbl_kind) , intent(inout) :: output(:,:,:,:) + integer , intent(in) :: index + integer , intent(out) :: rc + + ! local variables + type(block) :: this_block ! block information for current block + integer :: ilo, ihi, jlo, jhi ! beginning and end of physical domain + integer :: i, j, iblk, n, i1, j1 ! incides + real(kind=real_kind),pointer :: dataPtr2d(:,:) ! mesh + character(len=*) , parameter :: subname='(ice_import_export:state_getimport_3d)' + ! ---------------------------------------------- + + rc = ESMF_SUCCESS + + ! check that fieldname exists + if (.not. State_FldChk(state, trim(fldname))) return + + ! get field pointer + call state_getfldptr(state, trim(fldname), dataPtr2d, rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + + ! determine output array + do iblk = 1, nblocks + this_block = get_block(blocks_ice(iblk),iblk) + ilo = this_block%ilo + ihi = this_block%ihi + jlo = this_block%jlo + jhi = this_block%jhi + do j = jlo, jhi + j1 = j - nghost + do i = ilo, ihi + i1 = i - nghost + output(i,j,index,iblk) = real(dataPtr2d(i1, j1), kind=dbl_kind) + end do + end do + end do + + end subroutine state_getimport_3d + + !=============================================================================== + subroutine arr_setexport_4d(output, input, rc) + + ! ---------------------------------------------- + ! Map 4d input array to export state field + ! ---------------------------------------------- + + ! input/output variables + real(kind=real_kind) , intent(out) :: output(:,:,:) + real(kind=dbl_kind) , intent(in) :: input(:,:,:,:) + integer , intent(out) :: rc + + ! local variables + type(block) :: this_block ! block information for current block + integer :: ilo, ihi, jlo, jhi ! beginning and end of physical domain + integer :: i, j, k, iblk, n, i1, j1 ! indices + character(len=*), parameter :: subname='(ice_import_export:arr_setexport_4d)' + ! ---------------------------------------------- + + + do k = 1, ncat + do iblk = 1, nblocks + this_block = get_block(blocks_ice(iblk),iblk) + ilo = this_block%ilo; ihi = this_block%ihi + jlo = this_block%jlo; jhi = this_block%jhi + do j = jlo, jhi + j1 = j - nghost + do i = ilo, ihi + i1 = i - nghost + output(i1,j1,k) = real(input(i,j,k,iblk), kind=real_kind) + end do + end do + end do + end do + + rc = ESMF_SUCCESS + + end subroutine arr_setexport_4d + + !=============================================================================== + subroutine arr_setexport_3d(output, input, rc) + + ! ---------------------------------------------- + ! Map 3d input array to export array + ! ---------------------------------------------- + + ! input/output variables + real(kind=real_kind) , intent(out) :: output(:,:) + real(kind=dbl_kind) , intent(in) :: input(:,:,:) + integer , intent(out) :: rc + + ! local variables + type(block) :: this_block ! block information for current block + integer :: ilo, ihi, jlo, jhi ! beginning and end of physical domain + integer :: i, j, k, iblk, n, i1, j1 ! indices + character(len=*), parameter :: subname='(ice_import_export:arr_setexport_3d)' + ! ---------------------------------------------- + + rc = ESMF_SUCCESS + + do iblk = 1, nblocks + this_block = get_block(blocks_ice(iblk),iblk) + ilo = this_block%ilo; ihi = this_block%ihi + jlo = this_block%jlo; jhi = this_block%jhi + do j = jlo, jhi + j1 = j - nghost + do i = ilo, ihi + i1 = i - nghost + output(i1,j1) = real(input(i,j,iblk), kind=real_kind) + end do + end do + end do + + end subroutine arr_setexport_3d + + !=============================================================================== + subroutine state_setexport_4d(state, fldname, input, rc) + + ! ---------------------------------------------- + ! Map 4d input array to export state field + ! ---------------------------------------------- + + ! input/output variables + type(ESMF_State) , intent(inout) :: state + character(len=*) , intent(in) :: fldname + real(kind=dbl_kind) , intent(in) :: input(:,:,:,:) + integer , intent(out) :: rc + + ! local variables + type(block) :: this_block ! block information for current block + integer :: ilo, ihi, jlo, jhi ! beginning and end of physical domain + integer :: i, j, k, iblk, n, i1, j1 ! indices + real(kind=real_kind), pointer :: dataPtr3d(:,:,:) ! mesh + character(len=*), parameter :: subname='(ice_import_export:state_setexport_4d)' + ! ---------------------------------------------- + + rc = ESMF_SUCCESS + + ! check that fieldname exists + if (.not. State_FldChk(state, trim(fldname))) return + + ! get field pointer + call state_getfldptr(state, trim(fldname), dataPtr3d, rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + do k = 1, ncat + do iblk = 1, nblocks + this_block = get_block(blocks_ice(iblk),iblk) + ilo = this_block%ilo; ihi = this_block%ihi + jlo = this_block%jlo; jhi = this_block%jhi + do j = jlo, jhi + j1 = j - nghost + do i = ilo, ihi + i1 = i - nghost + dataPtr3d(i1,j1,k) = real(input(i,j,k,iblk), kind=real_kind) + end do + end do + end do + end do + + end subroutine state_setexport_4d + + !=============================================================================== + subroutine state_setexport_3d(state, fldname, input, rc) + + ! ---------------------------------------------- + ! Map 3d input array to export state field + ! ---------------------------------------------- + + ! input/output variables + type(ESMF_State) , intent(inout) :: state + character(len=*) , intent(in) :: fldname + real(kind=dbl_kind) , intent(in) :: input(:,:,:) + integer , intent(out) :: rc + + ! local variables + type(block) :: this_block ! block information for current block + integer :: ilo, ihi, jlo, jhi ! beginning and end of physical domain + integer :: i, j, iblk, n, i1, j1 ! incides + real(kind=real_kind), pointer :: dataPtr2d(:,:) ! mesh + integer :: num_ice + character(len=*), parameter :: subname='(ice_import_export:state_setexport_3d)' + ! ---------------------------------------------- + + rc = ESMF_SUCCESS + + ! check that fieldname exists + if (.not. State_FldChk(state, trim(fldname))) return + + ! get field pointer + call state_getfldptr(state, trim(fldname), dataPtr2d, rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + + n = 0 + do iblk = 1, nblocks + this_block = get_block(blocks_ice(iblk),iblk) + ilo = this_block%ilo + ihi = this_block%ihi + jlo = this_block%jlo + jhi = this_block%jhi + do j = jlo, jhi + j1 = j - nghost + do i = ilo, ihi + i1 = i - nghost + dataPtr2d(i1, j1) = input(i,j,iblk) + end do + end do + end do + + end subroutine state_setexport_3d + + !=============================================================================== + subroutine State_GetFldPtr_1d(State, fldname, fldptr, rc) + ! ---------------------------------------------- + ! Get pointer to a state field + ! ---------------------------------------------- + + ! input/output variables + type(ESMF_State) , intent(in) :: State + character(len=*) , intent(in) :: fldname + real(kind=real_kind), pointer , intent(inout) :: fldptr(:) + integer, optional , intent(out) :: rc + + ! local variables + type(ESMF_Field) :: lfield + character(len=*),parameter :: subname='(ice_import_export:State_GetFldPtr_1d)' + ! ---------------------------------------------- + + rc = ESMF_SUCCESS + + call ESMF_StateGet(State, itemName=trim(fldname), field=lfield, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + + call ESMF_FieldGet(lfield, farrayPtr=fldptr, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + + end subroutine State_GetFldPtr_1d + + !=============================================================================== + subroutine state_getfldptr_2d(state, fldname, fldptr, rc) + ! ---------------------------------------------- + ! Get pointer to a state field + ! ---------------------------------------------- + + ! input/output variables + type(ESMF_State) , intent(in) :: state + character(len=*) , intent(in) :: fldname + real(kind=real_kind), pointer , intent(inout) :: fldptr(:,:) + integer , optional , intent(out) :: rc + + ! local variables + type(ESMF_Field) :: lfield + character(len=*),parameter :: subname='(ice_import_export:State_GetFldPtr_2d)' + ! ---------------------------------------------- + + rc = ESMF_SUCCESS + + call ESMF_StateGet(State, itemName=trim(fldname), field=lfield, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + + call ESMF_FieldGet(lfield, farrayPtr=fldptr, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + + end subroutine state_getfldptr_2d + + subroutine State_GetFldPtr_3d(State, fldname, fldptr, rc) + ! ---------------------------------------------- + ! Get pointer to a state field + ! ---------------------------------------------- + + ! input/output variables + type(ESMF_State) , intent(in) :: State + character(len=*) , intent(in) :: fldname + real(kind=real_kind), pointer , intent(inout) :: fldptr(:,:,:) + integer , optional , intent(out) :: rc + + ! local variables + type(ESMF_Field) :: lfield + character(len=*),parameter :: subname='(ice_import_export:State_GetFldPtr_3d)' + ! ---------------------------------------------- + + rc = ESMF_SUCCESS + + call ESMF_StateGet(State, itemName=trim(fldname), field=lfield, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + + call ESMF_FieldGet(lfield, farrayPtr=fldptr, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + + end subroutine State_GetFldPtr_3d + +end module ice_import_export diff --git a/cicecore/drivers/mapl/geos/ice_prescribed_mod.F90 b/cicecore/drivers/mapl/geos/ice_prescribed_mod.F90 new file mode 100644 index 000000000..a25c81ab5 --- /dev/null +++ b/cicecore/drivers/mapl/geos/ice_prescribed_mod.F90 @@ -0,0 +1,489 @@ +module ice_prescribed_mod + + ! !DESCRIPTION: + ! The prescribed ice model reads in ice concentration data from a netCDF + ! file. Ice thickness, temperature, the ice temperature profile are + ! prescribed. Air/ice fluxes are computed to get surface temperature, + ! Ice/ocean fluxes are set to zero, and ice dynamics are not calculated. + ! Regridding and data cycling capabilities are included. + + +#ifndef CESMCOUPLED + + use ice_kinds_mod + implicit none + private ! except + public :: ice_prescribed_init ! initialize input data stream + logical(kind=log_kind), parameter, public :: prescribed_ice = .false. ! true if prescribed ice +contains + ! This is a stub routine for now + subroutine ice_prescribed_init(rc) + integer , intent(out) :: rc + ! do nothing + end subroutine ice_prescribed_init + +#else + + use ESMF + use ice_kinds_mod + use shr_nl_mod , only : shr_nl_find_group_name + use dshr_strdata_mod , only : shr_strdata_type, shr_strdata_print + use dshr_strdata_mod , only : shr_strdata_init_from_inline, shr_strdata_advance + use dshr_methods_mod , only : dshr_fldbun_getfldptr + use ice_broadcast + use ice_communicate , only : my_task, master_task, MPI_COMM_ICE + use ice_fileunits + use ice_exit , only : abort_ice + use ice_domain_size , only : nx_global, ny_global, ncat, nilyr, nslyr, max_blocks + use ice_constants + use ice_blocks , only : nx_block, ny_block, block, get_block + use ice_domain , only : nblocks, distrb_info, blocks_ice + use ice_grid , only : TLAT, TLON, hm, tmask, tarea, ocn_gridcell_frac + use ice_calendar , only : idate, calendar_type + use ice_arrays_column , only : hin_max + use ice_read_write + use ice_exit , only: abort_ice + use icepack_intfc , only: icepack_warnings_flush, icepack_warnings_aborted + use icepack_intfc , only: icepack_query_tracer_indices, icepack_query_tracer_sizes + use icepack_intfc , only: icepack_query_parameters + use ice_shr_methods , only: chkerr + + implicit none + private ! except + + ! public member functions: + public :: ice_prescribed_init ! initialize input data stream + public :: ice_prescribed_run ! get time slices and time interp + public :: ice_prescribed_phys ! set prescribed ice state and fluxes + + ! public data members: + logical(kind=log_kind), public :: prescribed_ice ! true if prescribed ice + + ! private data members: + type(shr_strdata_type) :: sdat ! prescribed data stream + real(kind=dbl_kind),allocatable :: ice_cov(:,:,:) ! ice cover + + character(*), parameter :: u_FILE_u = & + __FILE__ + +!======================================================================= +contains +!=============================================================================== + + subroutine ice_prescribed_init(clock, mesh, rc) + + ! Prescribed ice initialization + + include 'mpif.h' + + ! input/output parameters + type(ESMF_Clock) , intent(in) :: clock + type(ESMF_Mesh) , intent(in) :: mesh + integer , intent(out) :: rc + + ! local parameters + integer(kind=int_kind),parameter :: nFilesMaximum = 400 ! max number of files + integer(kind=int_kind) :: n, nFile, ierr + integer(kind=int_kind) :: nml_error ! namelist i/o error flag + character(len=char_len_long) :: stream_meshFile + character(len=char_len_long) :: stream_dataFiles(nFilesMaximum) + character(len=char_len_long) :: stream_varname + character(len=char_len_long) :: stream_mapalgo + integer(kind=int_kind) :: stream_yearfirst ! first year in stream to use + integer(kind=int_kind) :: stream_yearlast ! last year in stream to use + integer(kind=int_kind) :: stream_yearalign ! align stream_year_first + integer(kind=int_kind) :: nu_nml + logical :: prescribed_ice_mode + character(*),parameter :: subName = "('ice_prescribed_init')" + character(*),parameter :: F00 = "('(ice_prescribed_init) ',4a)" + character(*),parameter :: F01 = "('(ice_prescribed_init) ',a,i0)" + character(*),parameter :: F02 = "('(ice_prescribed_init) ',2a,i0,)" + !-------------------------------- + + namelist /ice_prescribed_nml/ & + prescribed_ice_mode, & + stream_meshfile, & + stream_varname , & + stream_datafiles, & + stream_mapalgo, & + stream_yearalign, & + stream_yearfirst , & + stream_yearlast + + rc = ESMF_SUCCESS + + ! default values for namelist + prescribed_ice_mode = .false. ! if true, prescribe ice + stream_yearfirst = 1 ! first year in pice stream to use + stream_yearlast = 1 ! last year in pice stream to use + stream_yearalign = 1 ! align stream_year_first with this model year + stream_varname = 'ice_cov' + stream_meshfile = ' ' + stream_datafiles(:) = ' ' + stream_mapalgo = 'bilinear' + + ! read namelist on master task + if (my_task == master_task) then + open (newunit=nu_nml, file=nml_filename, status='old',iostat=nml_error) + call shr_nl_find_group_name(nu_nml, 'ice_prescribed_nml', status=nml_error) + if (nml_error /= 0) then + write(nu_diag,F00) "ERROR: problem on read of ice_prescribed_nml namelist" + call abort_ice(subName) + endif + read(nu_nml, ice_prescribed_nml, iostat=nml_error) + close(nu_nml) + end if + + ! broadcast namelist input + call broadcast_scalar(prescribed_ice_mode, master_task) + + ! set module variable 'prescribed_ice' + prescribed_ice = prescribed_ice_mode + + ! -------------------------------------------------- + ! only do the following if prescribed ice mode is on + ! -------------------------------------------------- + + if (prescribed_ice_mode) then + + call broadcast_scalar(stream_yearalign , master_task) + call broadcast_scalar(stream_yearfirst , master_task) + call broadcast_scalar(stream_yearlast , master_task) + call broadcast_scalar(stream_meshfile , master_task) + call broadcast_scalar(stream_mapalgo , master_task) + call broadcast_scalar(stream_varname , master_task) + call mpi_bcast(stream_dataFiles, len(stream_datafiles(1))*NFilesMaximum, MPI_CHARACTER, 0, MPI_COMM_ICE, ierr) + + nFile = 0 + do n = 1,nFilesMaximum + if (stream_datafiles(n) /= ' ') nFile = nFile + 1 + end do + + if (my_task == master_task) then + write(nu_diag,*) ' ' + write(nu_diag,F00) 'This is the prescribed ice coverage option.' + write(nu_diag,F01) ' stream_yearfirst = ',stream_yearfirst + write(nu_diag,F01) ' stream_yearlast = ',stream_yearlast + write(nu_diag,F01) ' stream_yearalign = ',stream_yearalign + write(nu_diag,F00) ' stream_meshfile = ',trim(stream_meshfile) + write(nu_diag,F00) ' stream_varname = ',trim(stream_varname) + write(nu_diag,F00) ' stream_mapalgo = ',trim(stream_mapalgo) + do n = 1,nFile + write(nu_diag,F00) ' stream_datafiles = ',trim(stream_dataFiles(n)) + end do + write(nu_diag,*) ' ' + endif + + ! initialize sdat + call shr_strdata_init_from_inline(sdat, & + my_task = my_task, & + logunit = nu_diag, & + compname = 'ICE', & + model_clock = clock, & + model_mesh = mesh, & + stream_meshfile = stream_meshfile, & + stream_lev_dimname = 'null', & + stream_mapalgo = trim(stream_mapalgo), & + stream_filenames = stream_datafiles(1:nfile), & + stream_fldlistFile = (/'ice_cov'/), & + stream_fldListModel = (/'ice_cov'/), & + stream_yearFirst = stream_yearFirst, & + stream_yearLast = stream_yearLast, & + stream_yearAlign = stream_yearAlign , & + stream_offset = 0, & + stream_taxmode = 'cycle', & + stream_dtlimit = 1.5_dbl_kind, & + stream_tintalgo = 'linear', & + rc = rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + + ! print out sdat info + if (my_task == master_task) then + call shr_strdata_print(sdat,'ice coverage prescribed data') + endif + + ! For one ice category, set hin_max(1) to something big + if (ncat == 1) then + hin_max(1) = 999._dbl_kind + end if + + end if ! end of if prescribed ice mode + + end subroutine ice_prescribed_init + + !======================================================================= + subroutine ice_prescribed_run(mDateIn, secIn) + + ! Finds two time slices bounding current model time, remaps if necessary + ! Interpolate to new ice coverage + + ! input/output parameters: + integer(kind=int_kind), intent(in) :: mDateIn ! Current model date (yyyymmdd) + integer(kind=int_kind), intent(in) :: secIn ! Elapsed seconds on model date + + ! local variables + integer(kind=int_kind) :: i,j,n,iblk ! loop indices and counter + integer(kind=int_kind) :: ilo,ihi,jlo,jhi ! beginning and end of physical domain + type (block) :: this_block + real(kind=dbl_kind) :: aice_max ! maximun ice concentration + real(kind=dbl_kind), pointer :: dataptr(:) + integer :: rc ! ESMF return code + character(*),parameter :: subName = "('ice_prescribed_run')" + character(*),parameter :: F00 = "('(ice_prescribed_run) ',a,2g20.13)" + logical :: first_time = .true. + !------------------------------------------------------------------------ + + rc = ESMF_SUCCESS + + ! Advance sdat stream + call shr_strdata_advance(sdat, ymd=mDateIn, tod=SecIn, logunit=nu_diag, istr='cice_pice', rc=rc) + if (ESMF_LogFoundError(rcToCheck=rc, msg=ESMF_LOGERR_PASSTHRU, line=__LINE__, file=__FILE__)) then + call ESMF_Finalize(endflag=ESMF_END_ABORT) + end if + + ! Get pointer for stream data that is time and spatially interpolate to model time and grid + call dshr_fldbun_getFldPtr(sdat%pstrm(1)%fldbun_model, 'ice_cov', dataptr, rc=rc) + if (ESMF_LogFoundError(rcToCheck=rc, msg=ESMF_LOGERR_PASSTHRU, line=__LINE__, file=__FILE__)) then + call ESMF_Finalize(endflag=ESMF_END_ABORT) + end if + + ! Fill in module ice_cov array + if (.not. allocated(ice_cov)) then + allocate(ice_cov(nx_block,ny_block,max_blocks)) + end if + ice_cov(:,:,:) = c0 ! This initializes ghost cells as well + n = 0 + do iblk = 1, nblocks + this_block = get_block(blocks_ice(iblk),iblk) + ilo = this_block%ilo + ihi = this_block%ihi + jlo = this_block%jlo + jhi = this_block%jhi + do j = jlo, jhi + do i = ilo, ihi + n = n+1 + ice_cov(i,j,iblk) = dataptr(n) + end do + end do + end do + + ! Check to see that ice concentration is in fraction, not percent + if (first_time) then + aice_max = maxval(ice_cov) + if (aice_max > c10) then + write(nu_diag,F00) "ERROR: Ice conc data must be in fraction, aice_max= ", aice_max + rc = ESMF_FAILURE + if (ESMF_LogFoundError(rcToCheck=rc, msg=ESMF_LOGERR_PASSTHRU, line=__LINE__, file=__FILE__)) then + call ESMF_Finalize(endflag=ESMF_END_ABORT) + end if + end if + first_time = .false. + end if + + ! Set prescribed ice state and fluxes + call ice_prescribed_phys() + + end subroutine ice_prescribed_run + + !======================================================================= + subroutine ice_prescribed_phys() + + ! Set prescribed ice state using input ice concentration; + ! set surface ice temperature to atmospheric value; use + ! linear temperature gradient in ice to ocean temperature. + + use ice_flux + use ice_state + use icepack_intfc, only : icepack_aggregate + use ice_dyn_evp + + !----- Local ------ + integer(kind=int_kind) :: layer ! level index + integer(kind=int_kind) :: nc ! ice category index + integer(kind=int_kind) :: i,j,k ! longitude, latitude and level indices + integer(kind=int_kind) :: iblk + integer(kind=int_kind) :: nt_Tsfc + integer(kind=int_kind) :: nt_sice + integer(kind=int_kind) :: nt_qice + integer(kind=int_kind) :: nt_qsno + integer(kind=int_kind) :: ntrcr + real(kind=dbl_kind) :: slope ! diff in underlying ocean tmp and ice surface tmp + real(kind=dbl_kind) :: Ti ! ice level temperature + real(kind=dbl_kind) :: Tmlt ! ice level melt temperature + real(kind=dbl_kind) :: qin_save(nilyr) + real(kind=dbl_kind) :: qsn_save(nslyr) + real(kind=dbl_kind) :: hi ! ice prescribed (hemispheric) ice thickness + real(kind=dbl_kind) :: hs ! snow thickness + real(kind=dbl_kind) :: zn ! normalized ice thickness + real(kind=dbl_kind) :: salin(nilyr) ! salinity (ppt) + real(kind=dbl_kind) :: rad_to_deg, pi, puny + real(kind=dbl_kind) :: rhoi + real(kind=dbl_kind) :: rhos + real(kind=dbl_kind) :: cp_ice + real(kind=dbl_kind) :: cp_ocn + real(kind=dbl_kind) :: lfresh + real(kind=dbl_kind) :: depressT + real(kind=dbl_kind), parameter :: nsal = 0.407_dbl_kind + real(kind=dbl_kind), parameter :: msal = 0.573_dbl_kind + real(kind=dbl_kind), parameter :: saltmax = 3.2_dbl_kind ! max salinity at ice base (ppm) + character(*),parameter :: subName = '(ice_prescribed_phys)' + !----------------------------------------------------------------- + + call icepack_query_tracer_indices(nt_Tsfc_out=nt_Tsfc, nt_sice_out=nt_sice, & + nt_qice_out=nt_qice, nt_qsno_out=nt_qsno) + call icepack_query_tracer_sizes(ntrcr_out=ntrcr) + call icepack_query_parameters(rad_to_deg_out=rad_to_deg, pi_out=pi, & + puny_out=puny, rhoi_out=rhoi, rhos_out=rhos, cp_ice_out=cp_ice, cp_ocn_out=cp_ocn, & + lfresh_out=lfresh, depressT_out=depressT) + call icepack_warnings_flush(nu_diag) + if (icepack_warnings_aborted()) call abort_ice(error_message=subname, & + file=__FILE__, line=__LINE__) + + !----------------------------------------------------------------- + ! Set ice cover over land to zero, not sure if this should be + ! be done earier, before time/spatial interp?????? + !----------------------------------------------------------------- + do iblk = 1,nblocks + do j = 1,ny_block + do i = 1,nx_block + if (tmask(i,j,iblk)) then + if (ice_cov(i,j,iblk) .lt. eps04) ice_cov(i,j,iblk) = c0 + if (ice_cov(i,j,iblk) .gt. c1) ice_cov(i,j,iblk) = c1 + else + ice_cov(i,j,iblk) = c0 + end if + enddo + enddo + enddo + + do iblk = 1,nblocks + do j = 1,ny_block + do i = 1,nx_block + + if (tmask(i,j,iblk)) then ! Over ocean points + + !-------------------------------------------------------------- + ! Place ice where ice concentration > .0001 + !-------------------------------------------------------------- + + if (ice_cov(i,j,iblk) >= eps04) then + + hi = 0.0_dbl_kind + !---------------------------------------------------------- + ! Set ice thickness in each hemisphere + !---------------------------------------------------------- + if(TLAT(i,j,iblk)*rad_to_deg > 40.0_dbl_kind) then + hi = 2.0_dbl_kind + else if(TLAT(i,j,iblk)*rad_to_deg < -40.0_dbl_kind) then + hi = 1.0_dbl_kind + end if + + !---------------------------------------------------------- + ! All ice in appropriate thickness category + !---------------------------------------------------------- + do nc = 1,ncat + + if(hin_max(nc-1) < hi .and. hi < hin_max(nc)) then + + if (aicen(i,j,nc,iblk) > c0) then + hs = vsnon(i,j,nc,iblk) / aicen(i,j,nc,iblk) + else + hs = c0 + endif + + aicen(i,j,nc,iblk) = ice_cov(i,j,iblk) + vicen(i,j,nc,iblk) = hi*aicen(i,j,nc,iblk) + vsnon(i,j,nc,iblk) = hs*aicen(i,j,nc,iblk) + + !--------------------------------------------------------- + ! make linear temp profile and compute enthalpy + !--------------------------------------------------------- + + if (abs(trcrn(i,j,nt_qice,nc,iblk)) < puny) then + + if (aice(i,j,iblk) < puny) & + trcrn(i,j,nt_Tsfc,nc,iblk) = Tf(i,j,iblk) + + slope = Tf(i,j,iblk) - trcrn(i,j,nt_Tsfc,nc,iblk) + do k = 1, nilyr + zn = (real(k,kind=dbl_kind)-p5) / real(nilyr,kind=dbl_kind) + Ti = trcrn(i,j,nt_Tsfc,nc,iblk) + slope*zn + salin(k) = (saltmax/c2)*(c1-cos(pi*zn**(nsal/(msal+zn)))) + Tmlt = -salin(k)*depressT + trcrn(i,j,nt_sice+k-1,nc,iblk) = salin(k) + trcrn(i,j,nt_qice+k-1,nc,iblk) = & + -(rhoi * (cp_ice*(Tmlt-Ti) & + + Lfresh*(c1-Tmlt/Ti) - cp_ocn*Tmlt)) + enddo + + do k=1,nslyr + trcrn(i,j,nt_qsno+k-1,nc,iblk) = & + -rhos*(Lfresh - cp_ice*trcrn(i,j,nt_Tsfc,nc,iblk)) + enddo + + endif ! aice < puny + end if ! hin_max + enddo ! ncat + else + trcrn(i,j,nt_Tsfc,:,iblk) = Tf(i,j,iblk) + aicen(i,j,:,iblk) = c0 + vicen(i,j,:,iblk) = c0 + vsnon(i,j,:,iblk) = c0 + trcrn(i,j,nt_sice:nt_sice+nilyr-1,:,iblk) = c0 + trcrn(i,j,nt_qice:nt_qice+nilyr-1,:,iblk) = c0 + trcrn(i,j,nt_qsno:nt_qsno+nslyr-1,:,iblk) = c0 + end if ! ice_cov >= eps04 + + !-------------------------------------------------------------------- + ! compute aggregate ice state and open water area + !-------------------------------------------------------------------- + call icepack_aggregate(ncat = ncat, & + aicen = aicen(i,j,:,iblk), & + trcrn = trcrn(i,j,1:ntrcr,:,iblk), & + vicen = vicen(i,j,:,iblk), & + vsnon = vsnon(i,j,:,iblk), & + aice = aice (i,j, iblk), & + trcr = trcr (i,j,1:ntrcr,iblk), & + vice = vice (i,j, iblk), & + vsno = vsno (i,j, iblk), & + aice0 = aice0(i,j, iblk), & + ntrcr = ntrcr, & + trcr_depend = trcr_depend(1:ntrcr), & + trcr_base = trcr_base(1:ntrcr,:), & + n_trcr_strata = n_trcr_strata(1:ntrcr), & + nt_strata = nt_strata(1:ntrcr,:)) + + end if ! tmask + enddo ! i + enddo ! j + enddo ! iblk + + do iblk = 1, nblocks + do j = 1, ny_block + do i = 1, nx_block + aice_init(i,j,iblk) = aice(i,j,iblk) + enddo + enddo + enddo + + !-------------------------------------------------------------------- + ! set non-computed fluxes, ice velocities, ice-ocn stresses to zero + !-------------------------------------------------------------------- + + frzmlt (:,:,:) = c0 + uvel (:,:,:) = c0 + vvel (:,:,:) = c0 + strocnxT (:,:,:) = c0 + strocnyT (:,:,:) = c0 + + !----------------------------------------------------------------- + ! other atm and ocn fluxes + !----------------------------------------------------------------- + call init_flux_atm + call init_flux_ocn + + end subroutine ice_prescribed_phys + +#endif + +end module ice_prescribed_mod diff --git a/cicecore/drivers/mapl/geos/ice_record_mod.F90 b/cicecore/drivers/mapl/geos/ice_record_mod.F90 new file mode 100644 index 000000000..b8cdbf0d6 --- /dev/null +++ b/cicecore/drivers/mapl/geos/ice_record_mod.F90 @@ -0,0 +1,165 @@ + + module ice_record_mod + + use ice_kinds_mod + use ice_constants, only: field_loc_center, field_type_scalar, c0 + use ice_domain_size, only: max_blocks, ncat + use ice_communicate, only: my_task, master_task + use ice_blocks, only: nx_block, ny_block + use ice_state, only: aicen, vicen, vsnon, trcrn + use ice_flux + use ice_exit, only: abort_ice + use ice_fileunits, only: nu_diag + use icepack_intfc, only: icepack_query_tracer_sizes + use icepack_intfc, only: icepack_query_parameters + use icepack_intfc, only: icepack_warnings_flush, icepack_warnings_aborted + + implicit none + private + public :: alloc_record_state, save_record_state, restore_record_state + + real (kind=dbl_kind), & + dimension (:,:,:,:), allocatable :: & + aicen_save , & ! concentration of ice + vicen_save , & ! volume per unit area of ice (m) + vsnon_save ! volume per unit area of snow (m) + + + real (kind=dbl_kind), & + dimension (:,:,:,:,:), allocatable :: & + trcrn_save ! tracers + ! 1: surface temperature of ice/snow (C) + + contains + + subroutine alloc_record_state + integer (int_kind) :: ntrcr, ierr + character(len=*),parameter :: subname='(alloc_record_state)' + + call icepack_query_tracer_sizes(ntrcr_out=ntrcr) + call icepack_warnings_flush(nu_diag) + if (icepack_warnings_aborted()) call abort_ice(error_message=subname, & + file=__FILE__, line=__LINE__) + + allocate ( aicen_save(nx_block,ny_block,ncat,max_blocks) , & ! concentration of ice + vicen_save(nx_block,ny_block,ncat,max_blocks) , & ! volume per unit area of ice (m) + vsnon_save(nx_block,ny_block,ncat,max_blocks) , & ! volume per unit area of snow (m) + trcrn_save(nx_block,ny_block,ntrcr,ncat,max_blocks) , & ! tracers: 1: surface temperature of ice/snow (C) + stat=ierr) + if (ierr/=0) call abort_ice('(alloc_record_state): Out of memory1') + + + aicen_save = c0 + vicen_save = c0 + vsnon_save = c0 + trcrn_save = c0 + + end subroutine alloc_record_state + + subroutine save_record_state + + character(len=*),parameter :: subname='(save_record_state)' + + if (.not. allocated(trcrn_save)) & + call abort_ice(error_message=subname//': trcrn_save not allocated', & + file=__FILE__, line=__LINE__) + + + aicen_save(:,:,:,:) = aicen(:,:,:,:) + vicen_save(:,:,:,:) = vicen(:,:,:,:) + vsnon_save(:,:,:,:) = vsnon(:,:,:,:) + trcrn_save(:,:,:,:,:) = trcrn(:,:,:,:,:) + + if(my_task == master_task) then + write(*,*), 'CICE6 thermo state saved' + endif + + end subroutine save_record_state + + subroutine restore_record_state + + use ice_flux_bgc, only: flux_bio_atm, flux_bio, faero_atm, fiso_atm, & + fnit, famm, fsil, fdmsp, fdms, fhum, fdust, falgalN, & + fdoc, fdon, fdic, ffed, ffep + + + character(len=*),parameter :: subname='(restore_record_state)' + real (kind=dbl_kind) :: stefan_boltzmann, Tffresh + + call icepack_query_parameters(stefan_boltzmann_out=stefan_boltzmann, & + Tffresh_out=Tffresh) + call icepack_warnings_flush(nu_diag) + if (icepack_warnings_aborted()) call abort_ice(error_message=subname, & + file=__FILE__, line=__LINE__) + + + if (.not. allocated(trcrn_save)) & + call abort_ice(error_message=subname//': trcrn_save not allocated', & + file=__FILE__, line=__LINE__) + + aicen(:,:,:,:) = aicen_save(:,:,:,:) + vicen(:,:,:,:) = vicen_save(:,:,:,:) + vsnon(:,:,:,:) = vsnon_save(:,:,:,:) + trcrn(:,:,:,:,:) = trcrn_save(:,:,:,:,:) + + + fsens (:,:,:) = c0 + flat (:,:,:) = c0 + fswabs (:,:,:) = c0 + fswint_ai(:,:,:) = c0 + flwout (:,:,:) = -stefan_boltzmann*Tffresh**4 + ! in case atm model diagnoses Tsfc from flwout + evap (:,:,:) = c0 + evaps (:,:,:) = c0 + evapi (:,:,:) = c0 + Tref (:,:,:) = c0 + Qref (:,:,:) = c0 + Uref (:,:,:) = c0 + + + + fresh (:,:,:) = c0 + fsalt (:,:,:) = c0 + fpond (:,:,:) = c0 + fhocn (:,:,:) = c0 + fswthru (:,:,:) = c0 + fswthru_vdr (:,:,:) = c0 + fswthru_vdf (:,:,:) = c0 + fswthru_idr (:,:,:) = c0 + fswthru_idf (:,:,:) = c0 + fswthru_uvrdr (:,:,:) = c0 + fswthru_uvrdf (:,:,:) = c0 + fswthru_pardr (:,:,:) = c0 + fswthru_pardf (:,:,:) = c0 + + alvdr (:,:,:) = c0 + alidr (:,:,:) = c0 + alvdf (:,:,:) = c0 + alidf (:,:,:) = c0 + + + fresh_da(:,:,:) = c0 ! data assimilation + fsalt_da(:,:,:) = c0 + flux_bio(:,:,:,:) = c0 ! bgc + fnit (:,:,:) = c0 + fsil (:,:,:) = c0 + famm (:,:,:) = c0 + fdmsp (:,:,:) = c0 + fdms (:,:,:) = c0 + fhum (:,:,:) = c0 + fdust (:,:,:) = c0 + falgalN(:,:,:,:)= c0 + fdoc (:,:,:,:)= c0 + fdic (:,:,:,:)= c0 + fdon (:,:,:,:)= c0 + ffep (:,:,:,:)= c0 + ffed (:,:,:,:)= c0 + + + if(my_task == master_task) then + write(*,*), 'CICE6 thermo state restored' + endif + + end subroutine restore_record_state + + end module ice_record_mod diff --git a/cicecore/drivers/mapl/geos/ice_shr_methods.F90 b/cicecore/drivers/mapl/geos/ice_shr_methods.F90 new file mode 100644 index 000000000..2e9bfb3ad --- /dev/null +++ b/cicecore/drivers/mapl/geos/ice_shr_methods.F90 @@ -0,0 +1,33 @@ +module ice_shr_methods + + use ESMF , only : ESMF_LOGERR_PASSTHRU, ESMF_LogFoundError, ESMF_LOGMSG_ERROR, ESMF_MAXSTR + use ESMF , only : ESMF_SUCCESS, ESMF_LogWrite, ESMF_LOGMSG_INFO, ESMF_FAILURE + + implicit none + private + + public :: chkerr + + +!=============================================================================== +contains +!=============================================================================== + + + logical function chkerr(rc, line, file) + + integer, intent(in) :: rc + integer, intent(in) :: line + character(len=*), intent(in) :: file + + integer :: lrc + character(len=*), parameter :: subname='(chkerr)' + + chkerr = .false. + lrc = rc + if (ESMF_LogFoundError(rcToCheck=lrc, msg=ESMF_LOGERR_PASSTHRU, line=line, file=file)) then + chkerr = .true. + endif + end function chkerr + +end module ice_shr_methods diff --git a/cicecore/drivers/mct/cesm1/CICE_InitMod.F90 b/cicecore/drivers/mct/cesm1/CICE_InitMod.F90 index 0a5e27840..8af7704fb 100644 --- a/cicecore/drivers/mct/cesm1/CICE_InitMod.F90 +++ b/cicecore/drivers/mct/cesm1/CICE_InitMod.F90 @@ -332,8 +332,7 @@ subroutine init_restart ! tracers ! ice age tracer if (tr_iage) then - if (trim(runtype) == 'continue') & - restart_age = .true. + if (trim(runtype) == 'continue') restart_age = .true. if (restart_age) then call read_restart_age else @@ -367,8 +366,7 @@ subroutine init_restart endif ! level-ice melt ponds if (tr_pond_lvl) then - if (trim(runtype) == 'continue') & - restart_pond_lvl = .true. + if (trim(runtype) == 'continue') restart_pond_lvl = .true. if (restart_pond_lvl) then call read_restart_pond_lvl else @@ -382,8 +380,7 @@ subroutine init_restart endif ! topographic melt ponds if (tr_pond_topo) then - if (trim(runtype) == 'continue') & - restart_pond_topo = .true. + if (trim(runtype) == 'continue') restart_pond_topo = .true. if (restart_pond_topo) then call read_restart_pond_topo else @@ -445,10 +442,8 @@ subroutine init_restart endif if (trim(runtype) == 'continue') then - if (tr_brine) & - restart_hbrine = .true. - if (skl_bgc .or. z_tracers) & - restart_bgc = .true. + if (tr_brine) restart_hbrine = .true. + if (skl_bgc .or. z_tracers) restart_bgc = .true. endif if (tr_brine .or. skl_bgc) then ! brine height tracer diff --git a/cicecore/drivers/mct/cesm1/CICE_RunMod.F90 b/cicecore/drivers/mct/cesm1/CICE_RunMod.F90 index 6ff6b1270..d22570ae1 100644 --- a/cicecore/drivers/mct/cesm1/CICE_RunMod.F90 +++ b/cicecore/drivers/mct/cesm1/CICE_RunMod.F90 @@ -127,7 +127,7 @@ subroutine ice_step use ice_calendar, only: dt, dt_dyn, ndtd, diagfreq, write_restart, istep use ice_calendar, only: idate, msec use ice_diagnostics, only: init_mass_diags, runtime_diags, debug_model, debug_ice - use ice_diagnostics_bgc, only: hbrine_diags, zsal_diags, bgc_diags + use ice_diagnostics_bgc, only: hbrine_diags, bgc_diags use ice_domain, only: halo_info, nblocks use ice_dyn_eap, only: write_restart_eap use ice_dyn_shared, only: kdyn, kridge @@ -163,7 +163,7 @@ subroutine ice_step logical (kind=log_kind) :: & tr_iage, tr_FY, tr_lvl, tr_fsd, tr_snow, & tr_pond_lvl, tr_pond_topo, tr_brine, tr_iso, tr_aero, & - calc_Tsfc, skl_bgc, solve_zsal, z_tracers, wave_spec + calc_Tsfc, skl_bgc, z_tracers, wave_spec character(len=*), parameter :: subname = '(ice_step)' @@ -177,7 +177,7 @@ subroutine ice_step endif call icepack_query_parameters(calc_Tsfc_out=calc_Tsfc, skl_bgc_out=skl_bgc, & - solve_zsal_out=solve_zsal, z_tracers_out=z_tracers, ktherm_out=ktherm, & + z_tracers_out=z_tracers, ktherm_out=ktherm, & wave_spec_out=wave_spec) call icepack_query_tracer_flags(tr_iage_out=tr_iage, tr_FY_out=tr_FY, & tr_lvl_out=tr_lvl, tr_pond_lvl_out=tr_pond_lvl, & @@ -374,7 +374,6 @@ subroutine ice_step call ice_timer_start(timer_diags) ! diagnostics if (mod(istep,diagfreq) == 0) then call runtime_diags(dt) ! log file - if (solve_zsal) call zsal_diags if (skl_bgc .or. z_tracers) call bgc_diags if (tr_brine) call hbrine_diags if (my_task == master_task) then @@ -399,7 +398,7 @@ subroutine ice_step if (tr_fsd) call write_restart_fsd if (tr_iso) call write_restart_iso if (tr_aero) call write_restart_aero - if (solve_zsal .or. skl_bgc .or. z_tracers) & + if (skl_bgc .or. z_tracers) & call write_restart_bgc if (tr_brine) call write_restart_hbrine if (kdyn == 2) call write_restart_eap @@ -418,7 +417,7 @@ end subroutine ice_step subroutine coupling_prep (iblk) use ice_arrays_column, only: alvdfn, alidfn, alvdrn, alidrn, & - albicen, albsnon, albpndn, apeffn, fzsal_g, fzsal, snowfracn + albicen, albsnon, albpndn, apeffn, snowfracn use ice_blocks, only: nx_block, ny_block, get_block, block use ice_domain, only: blocks_ice use ice_calendar, only: dt, nstreams @@ -433,7 +432,7 @@ subroutine coupling_prep (iblk) fsens, flat, fswabs, flwout, evap, Tref, Qref, & scale_fluxes, frzmlt_init, frzmlt, Uref, wind use ice_flux_bgc, only: faero_ocn, fiso_ocn, Qref_iso, fiso_evap, & - fzsal_ai, fzsal_g_ai, flux_bio, flux_bio_ai, & + flux_bio, flux_bio_ai, & fnit, fsil, famm, fdmsp, fdms, fhum, fdust, falgalN, & fdoc, fdic, fdon, ffep, ffed, bgcflux_ice_to_ocn use ice_grid, only: tmask @@ -586,8 +585,6 @@ subroutine coupling_prep (iblk) fsalt_ai (i,j,iblk) = fsalt (i,j,iblk) fhocn_ai (i,j,iblk) = fhocn (i,j,iblk) fswthru_ai(i,j,iblk) = fswthru(i,j,iblk) - fzsal_ai (i,j,iblk) = fzsal (i,j,iblk) - fzsal_g_ai(i,j,iblk) = fzsal_g(i,j,iblk) if (nbtrcr > 0) then do k = 1, nbtrcr @@ -633,7 +630,6 @@ subroutine coupling_prep (iblk) faero_ocn(:,:,:,iblk), & alvdr (:,:,iblk), alidr (:,:,iblk), & alvdf (:,:,iblk), alidf (:,:,iblk), & - fzsal (:,:,iblk), fzsal_g (:,:,iblk), & flux_bio (:,:,1:nbtrcr,iblk), & Qref_iso =Qref_iso (:,:,:,iblk), & fiso_evap=fiso_evap(:,:,:,iblk), & diff --git a/cicecore/drivers/mct/cesm1/CICE_copyright.txt b/cicecore/drivers/mct/cesm1/CICE_copyright.txt index 3f81ec782..9ee3d2c60 100644 --- a/cicecore/drivers/mct/cesm1/CICE_copyright.txt +++ b/cicecore/drivers/mct/cesm1/CICE_copyright.txt @@ -1,16 +1,16 @@ -! Copyright (c) 2024, Triad National Security, LLC +! Copyright (c) 1998, 2017, Triad National Security, LLC ! All rights reserved. ! -! Copyright 2024. Triad National Security, LLC. This software was -! produced under U.S. Government contract DE-AC52-06NA25396 for Los -! Alamos National Laboratory (LANL), which is operated by Triad -! National Security, LLC for the U.S. Department of Energy. The U.S. -! Government has rights to use, reproduce, and distribute this software. -! NEITHER THE GOVERNMENT NOR TRIAD NATIONAL SECURITY, LLC MAKES ANY -! WARRANTY, EXPRESS OR IMPLIED, OR ASSUMES ANY LIABILITY FOR THE USE OF -! THIS SOFTWARE. If software is modified to produce derivative works, -! such modified software should be clearly marked, so as not to confuse -! it with the version available from LANL. +! This program was produced under U.S. Government contract 89233218CNA000001 +! for Los Alamos National Laboratory (LANL), which is operated by Triad +! National Security, LLC for the U.S. Department of Energy/National Nuclear +! Security Administration. All rights in the program are reserved by Triad +! National Security, LLC, and the U.S. Department of Energy/National Nuclear +! Security Administration. The Government is granted for itself and others +! acting on its behalf a nonexclusive, paid-up, irrevocable worldwide +! license in this material to reproduce, prepare. derivative works, +! distribute copies to the public, perform publicly and display publicly, +! and to permit others to do so. ! ! The full license and distribution policy are available from ! https://github.com/CICE-Consortium diff --git a/cicecore/drivers/mct/cesm1/ice_import_export.F90 b/cicecore/drivers/mct/cesm1/ice_import_export.F90 index 110bcd39c..b950a3f99 100644 --- a/cicecore/drivers/mct/cesm1/ice_import_export.F90 +++ b/cicecore/drivers/mct/cesm1/ice_import_export.F90 @@ -29,7 +29,7 @@ module ice_import_export use ice_domain , only: nblocks, blocks_ice, halo_info, distrb_info use ice_domain_size , only: nx_global, ny_global, block_size_x, block_size_y, max_blocks use ice_grid , only: tlon, tlat, tarea, tmask, anglet, hm - use ice_grid , only: grid_type, grid_average_X2Y + use ice_grid , only: grid_average_X2Y use ice_boundary , only: ice_HaloUpdate use ice_communicate , only: my_task, master_task, MPI_COMM_ICE, get_num_procs use ice_calendar , only: istep, istep1, diagfreq diff --git a/cicecore/drivers/nuopc/cmeps/CICE_InitMod.F90 b/cicecore/drivers/nuopc/cmeps/CICE_InitMod.F90 index 29df8626a..c46e05a01 100644 --- a/cicecore/drivers/nuopc/cmeps/CICE_InitMod.F90 +++ b/cicecore/drivers/nuopc/cmeps/CICE_InitMod.F90 @@ -221,11 +221,12 @@ subroutine init_restart() use ice_grid, only: tmask use ice_init, only: ice_ic use ice_init_column, only: init_age, init_FY, init_lvl, init_snowtracers, & - init_meltponds_lvl, init_meltponds_topo, & + init_meltponds_lvl, init_meltponds_topo, init_meltponds_sealvl, & init_isotope, init_aerosol, init_hbrine, init_bgc, init_fsd use ice_restart_column, only: restart_age, read_restart_age, & restart_FY, read_restart_FY, restart_lvl, read_restart_lvl, & restart_pond_lvl, read_restart_pond_lvl, & + restart_pond_sealvl, read_restart_pond_sealvl, & restart_pond_topo, read_restart_pond_topo, & restart_snow, read_restart_snow, & restart_fsd, read_restart_fsd, & @@ -241,7 +242,7 @@ subroutine init_restart() i, j , & ! horizontal indices iblk ! block index logical(kind=log_kind) :: & - tr_iage, tr_FY, tr_lvl, tr_pond_lvl, & + tr_iage, tr_FY, tr_lvl, tr_pond_lvl, tr_pond_sealvl, & tr_pond_topo, tr_fsd, tr_iso, tr_aero, tr_brine, tr_snow, & skl_bgc, z_tracers integer(kind=int_kind) :: & @@ -261,7 +262,7 @@ subroutine init_restart() call icepack_query_parameters(skl_bgc_out=skl_bgc, z_tracers_out=z_tracers) call icepack_query_tracer_flags(tr_iage_out=tr_iage, tr_FY_out=tr_FY, & - tr_lvl_out=tr_lvl, tr_pond_lvl_out=tr_pond_lvl, & + tr_lvl_out=tr_lvl, tr_pond_lvl_out=tr_pond_lvl, tr_pond_sealvl_out=tr_pond_sealvl, & tr_pond_topo_out=tr_pond_topo, tr_aero_out=tr_aero, tr_brine_out=tr_brine, & tr_snow_out=tr_snow, tr_fsd_out=tr_fsd, tr_iso_out=tr_iso) call icepack_query_tracer_indices(nt_alvl_out=nt_alvl, nt_vlvl_out=nt_vlvl, & @@ -277,7 +278,7 @@ subroutine init_restart() if (trim(runtype) == 'continue') then ! start from core restart file call restartfile() ! given by pointer in ice_in - call calendar() ! update time parameters + call calendar() ! update time parameters if (kdyn == 2) call read_restart_eap ! EAP else if (restart) then ! ice_ic = core restart file call restartfile (ice_ic) ! or 'default' or 'none' @@ -290,8 +291,7 @@ subroutine init_restart() ! tracers ! ice age tracer if (tr_iage) then - if (trim(runtype) == 'continue') & - restart_age = .true. + if (trim(runtype) == 'continue') restart_age = .true. if (restart_age) then call read_restart_age else @@ -325,8 +325,7 @@ subroutine init_restart() endif ! level-ice melt ponds if (tr_pond_lvl) then - if (trim(runtype) == 'continue') & - restart_pond_lvl = .true. + if (trim(runtype) == 'continue') restart_pond_lvl = .true. if (restart_pond_lvl) then call read_restart_pond_lvl else @@ -338,10 +337,23 @@ subroutine init_restart() enddo ! iblk endif endif + ! sealvl melt ponds + if (tr_pond_sealvl) then + if (trim(runtype) == 'continue') restart_pond_sealvl = .true. + if (restart_pond_sealvl) then + call read_restart_pond_sealvl + else + do iblk = 1, nblocks + call init_meltponds_sealvl(trcrn(:,:,nt_apnd,:,iblk), & + trcrn(:,:,nt_hpnd,:,iblk), & + trcrn(:,:,nt_ipnd,:,iblk), & + dhsn(:,:,:,iblk)) + enddo ! iblk + endif ! .not. restart_pond + endif ! topographic melt ponds if (tr_pond_topo) then - if (trim(runtype) == 'continue') & - restart_pond_topo = .true. + if (trim(runtype) == 'continue') restart_pond_topo = .true. if (restart_pond_topo) then call read_restart_pond_topo else @@ -401,10 +413,8 @@ subroutine init_restart() endif if (trim(runtype) == 'continue') then - if (tr_brine) & - restart_hbrine = .true. - if (skl_bgc .or. z_tracers) & - restart_bgc = .true. + if (tr_brine) restart_hbrine = .true. + if (skl_bgc .or. z_tracers) restart_bgc = .true. endif if (tr_brine .or. skl_bgc) then ! brine height tracer diff --git a/cicecore/drivers/nuopc/cmeps/CICE_RunMod.F90 b/cicecore/drivers/nuopc/cmeps/CICE_RunMod.F90 index 80905080e..876f10512 100644 --- a/cicecore/drivers/nuopc/cmeps/CICE_RunMod.F90 +++ b/cicecore/drivers/nuopc/cmeps/CICE_RunMod.F90 @@ -124,7 +124,7 @@ subroutine ice_step use ice_history_bgc, only: init_history_bgc use ice_restart, only: final_restart use ice_restart_column, only: write_restart_age, write_restart_FY, & - write_restart_lvl, write_restart_pond_lvl, & + write_restart_lvl, write_restart_pond_lvl, write_restart_pond_sealvl, & write_restart_pond_topo, write_restart_aero, write_restart_fsd, & write_restart_iso, write_restart_bgc, write_restart_hbrine, & write_restart_snow @@ -149,7 +149,7 @@ subroutine ice_step logical (kind=log_kind) :: & tr_iage, tr_FY, tr_lvl, tr_fsd, tr_snow, & - tr_pond_lvl, tr_pond_topo, tr_brine, tr_iso, tr_aero, & + tr_pond_lvl, tr_pond_sealvl, tr_pond_topo, tr_brine, tr_iso, tr_aero, & calc_Tsfc, skl_bgc, z_tracers, wave_spec character(len=*), parameter :: subname = '(ice_step)' @@ -168,7 +168,7 @@ subroutine ice_step call icepack_query_parameters(calc_Tsfc_out=calc_Tsfc, skl_bgc_out=skl_bgc, & z_tracers_out=z_tracers, ktherm_out=ktherm, wave_spec_out=wave_spec) call icepack_query_tracer_flags(tr_iage_out=tr_iage, tr_FY_out=tr_FY, & - tr_lvl_out=tr_lvl, tr_pond_lvl_out=tr_pond_lvl, & + tr_lvl_out=tr_lvl, tr_pond_lvl_out=tr_pond_lvl, tr_pond_sealvl_out=tr_pond_sealvl, & tr_pond_topo_out=tr_pond_topo, tr_brine_out=tr_brine, tr_aero_out=tr_aero, & tr_iso_out=tr_iso, tr_fsd_out=tr_fsd, tr_snow_out=tr_snow) call icepack_warnings_flush(nu_diag) @@ -374,6 +374,7 @@ subroutine ice_step if (tr_FY) call write_restart_FY if (tr_lvl) call write_restart_lvl if (tr_pond_lvl) call write_restart_pond_lvl + if (tr_pond_sealvl) call write_restart_pond_sealvl if (tr_pond_topo) call write_restart_pond_topo if (tr_snow) call write_restart_snow if (tr_fsd) call write_restart_fsd diff --git a/cicecore/drivers/nuopc/cmeps/CICE_copyright.txt b/cicecore/drivers/nuopc/cmeps/CICE_copyright.txt index 3f81ec782..9ee3d2c60 100644 --- a/cicecore/drivers/nuopc/cmeps/CICE_copyright.txt +++ b/cicecore/drivers/nuopc/cmeps/CICE_copyright.txt @@ -1,16 +1,16 @@ -! Copyright (c) 2024, Triad National Security, LLC +! Copyright (c) 1998, 2017, Triad National Security, LLC ! All rights reserved. ! -! Copyright 2024. Triad National Security, LLC. This software was -! produced under U.S. Government contract DE-AC52-06NA25396 for Los -! Alamos National Laboratory (LANL), which is operated by Triad -! National Security, LLC for the U.S. Department of Energy. The U.S. -! Government has rights to use, reproduce, and distribute this software. -! NEITHER THE GOVERNMENT NOR TRIAD NATIONAL SECURITY, LLC MAKES ANY -! WARRANTY, EXPRESS OR IMPLIED, OR ASSUMES ANY LIABILITY FOR THE USE OF -! THIS SOFTWARE. If software is modified to produce derivative works, -! such modified software should be clearly marked, so as not to confuse -! it with the version available from LANL. +! This program was produced under U.S. Government contract 89233218CNA000001 +! for Los Alamos National Laboratory (LANL), which is operated by Triad +! National Security, LLC for the U.S. Department of Energy/National Nuclear +! Security Administration. All rights in the program are reserved by Triad +! National Security, LLC, and the U.S. Department of Energy/National Nuclear +! Security Administration. The Government is granted for itself and others +! acting on its behalf a nonexclusive, paid-up, irrevocable worldwide +! license in this material to reproduce, prepare. derivative works, +! distribute copies to the public, perform publicly and display publicly, +! and to permit others to do so. ! ! The full license and distribution policy are available from ! https://github.com/CICE-Consortium diff --git a/cicecore/drivers/nuopc/cmeps/ice_comp_nuopc.F90 b/cicecore/drivers/nuopc/cmeps/ice_comp_nuopc.F90 index 8ced569a5..e8f019343 100644 --- a/cicecore/drivers/nuopc/cmeps/ice_comp_nuopc.F90 +++ b/cicecore/drivers/nuopc/cmeps/ice_comp_nuopc.F90 @@ -25,8 +25,8 @@ module ice_comp_nuopc use ice_communicate , only : init_communicate, my_task, master_task, mpi_comm_ice use ice_calendar , only : force_restart_now, write_ic use ice_calendar , only : idate, idate0, mday, mmonth, myear, year_init, month_init, day_init - use ice_calendar , only : msec, dt, calendar, calendar_type, nextsw_cday, istep - use ice_calendar , only : ice_calendar_noleap, ice_calendar_gregorian, use_leap_years + use ice_calendar , only : msec, dt, calendar, calendar_type, nextsw_cday, istep, use_leap_years + use ice_calendar , only : ice_calendar_noleap, ice_calendar_proleptic_gregorian, ice_calendar_gregorian use ice_kinds_mod , only : dbl_kind, int_kind, char_len, char_len_long use ice_fileunits , only : nu_diag, nu_diag_set, inst_index, inst_name use ice_fileunits , only : inst_suffix, release_all_fileunits, flush_fileunit @@ -499,7 +499,7 @@ subroutine InitializeAdvertise(gcomp, importState, exportState, clock, rc) if (esmf_caltype == ESMF_CALKIND_NOLEAP) then calendar_type = ice_calendar_noleap else if (esmf_caltype == ESMF_CALKIND_GREGORIAN) then - calendar_type = ice_calendar_gregorian + calendar_type = ice_calendar_proleptic_gregorian else call abort_ice( subname//'ERROR:: bad calendar for ESMF' ) end if @@ -859,7 +859,7 @@ subroutine InitializeRealize(gcomp, importState, exportState, clock, rc) day_init = idate0-year_init*10000-month_init*100 ! - Set use_leap_years based on calendar (as some CICE calls use this instead of the calendar type) - if (calendar_type == ice_calendar_gregorian) then + if (calendar_type == ice_calendar_proleptic_gregorian) then use_leap_years = .true. else use_leap_years = .false. ! no_leap calendars diff --git a/cicecore/drivers/nuopc/cmeps/ice_import_export.F90 b/cicecore/drivers/nuopc/cmeps/ice_import_export.F90 index 6b539a051..412b2cce5 100644 --- a/cicecore/drivers/nuopc/cmeps/ice_import_export.F90 +++ b/cicecore/drivers/nuopc/cmeps/ice_import_export.F90 @@ -79,7 +79,7 @@ module ice_import_export ! Private module data type fld_list_type - character(len=128) :: stdname + character(char_len) :: stdname integer :: ungridded_lbound = 0 integer :: ungridded_ubound = 0 end type fld_list_type @@ -1409,7 +1409,7 @@ subroutine fldlist_realize(state, fldList, numflds, flds_scalar_name, flds_scala ! local variables integer :: n type(ESMF_Field) :: field - character(len=80) :: stdname + character(char_len) :: stdname character(ESMF_MAXSTR) :: msg character(len=*),parameter :: subname='(ice_import_export:fld_list_realize)' ! ---------------------------------------------- diff --git a/cicecore/drivers/nuopc/cmeps/ice_prescribed_mod.F90 b/cicecore/drivers/nuopc/cmeps/ice_prescribed_mod.F90 index 7113fa915..77b8688e2 100644 --- a/cicecore/drivers/nuopc/cmeps/ice_prescribed_mod.F90 +++ b/cicecore/drivers/nuopc/cmeps/ice_prescribed_mod.F90 @@ -28,8 +28,8 @@ module ice_prescribed_mod use ice_constants use ice_blocks , only : nx_block, ny_block, block, get_block use ice_domain , only : nblocks, distrb_info, blocks_ice - use ice_grid , only : TLAT, TLON, hm, tmask, tarea, grid_type, ocn_gridcell_frac - use ice_calendar , only : idate, msec, calendar_type + use ice_grid , only : TLAT, TLON, hm, tmask, tarea, ocn_gridcell_frac + use ice_calendar , only : idate, msec use ice_arrays_column , only : hin_max use ice_read_write use ice_exit , only: abort_ice diff --git a/cicecore/drivers/nuopc/cmeps/ice_shr_methods.F90 b/cicecore/drivers/nuopc/cmeps/ice_shr_methods.F90 index 0a3a72840..0a2feea11 100644 --- a/cicecore/drivers/nuopc/cmeps/ice_shr_methods.F90 +++ b/cicecore/drivers/nuopc/cmeps/ice_shr_methods.F90 @@ -971,8 +971,7 @@ subroutine timeInit( Time, ymd, cal, tod, rc) ! local variables integer :: year, mon, day ! year, month, day as integers - integer :: tdate ! temporary date - integer :: date ! coded-date (yyyymmdd) + integer :: tdate ! temporary date (yyyymmdd) character(len=*), parameter :: subname='(timeInit)' !------------------------------------------------------------------------------- @@ -982,9 +981,9 @@ subroutine timeInit( Time, ymd, cal, tod, rc) call abort_ice( subname//'ERROR yymmdd is a negative number or time-of-day out of bounds' ) end if - tdate = abs(date) + tdate = abs(ymd) year = int(tdate/10000) - if (date < 0) year = -year + if (ymd < 0) year = -year mon = int( mod(tdate,10000)/ 100) day = mod(tdate, 100) diff --git a/cicecore/drivers/nuopc/dmi/CICE.F90 b/cicecore/drivers/nuopc/dmi/CICE.F90 index f993686e8..c92f0ea24 100644 --- a/cicecore/drivers/nuopc/dmi/CICE.F90 +++ b/cicecore/drivers/nuopc/dmi/CICE.F90 @@ -1,17 +1,17 @@ !======================================================================= -! Copyright (c) 2024, Triad National Security, LLC +! Copyright (c) 1998, 2017, Triad National Security, LLC ! All rights reserved. ! -! Copyright 2024. Triad National Security, LLC. This software was -! produced under U.S. Government contract DE-AC52-06NA25396 for Los -! Alamos National Laboratory (LANL), which is operated by Triad -! National Security, LLC for the U.S. Department of Energy. The U.S. -! Government has rights to use, reproduce, and distribute this software. -! NEITHER THE GOVERNMENT NOR TRIAD NATIONAL SECURITY, LLC MAKES ANY -! WARRANTY, EXPRESS OR IMPLIED, OR ASSUMES ANY LIABILITY FOR THE USE OF -! THIS SOFTWARE. If software is modified to produce derivative works, -! such modified software should be clearly marked, so as not to confuse -! it with the version available from LANL. +! This program was produced under U.S. Government contract 89233218CNA000001 +! for Los Alamos National Laboratory (LANL), which is operated by Triad +! National Security, LLC for the U.S. Department of Energy/National Nuclear +! Security Administration. All rights in the program are reserved by Triad +! National Security, LLC, and the U.S. Department of Energy/National Nuclear +! Security Administration. The Government is granted for itself and others +! acting on its behalf a nonexclusive, paid-up, irrevocable worldwide +! license in this material to reproduce, prepare. derivative works, +! distribute copies to the public, perform publicly and display publicly, +! and to permit others to do so. ! ! The full license and distribution policy are available from ! https://github.com/CICE-Consortium diff --git a/cicecore/drivers/nuopc/dmi/CICE_InitMod.F90 b/cicecore/drivers/nuopc/dmi/CICE_InitMod.F90 index 2cc29cb9c..4f4449546 100644 --- a/cicecore/drivers/nuopc/dmi/CICE_InitMod.F90 +++ b/cicecore/drivers/nuopc/dmi/CICE_InitMod.F90 @@ -351,8 +351,7 @@ subroutine init_restart ! tracers ! ice age tracer if (tr_iage) then - if (trim(runtype) == 'continue') & - restart_age = .true. + if (trim(runtype) == 'continue') restart_age = .true. if (restart_age) then call read_restart_age else @@ -386,8 +385,7 @@ subroutine init_restart endif ! level-ice melt ponds if (tr_pond_lvl) then - if (trim(runtype) == 'continue') & - restart_pond_lvl = .true. + if (trim(runtype) == 'continue') restart_pond_lvl = .true. if (restart_pond_lvl) then call read_restart_pond_lvl else @@ -401,8 +399,7 @@ subroutine init_restart endif ! topographic melt ponds if (tr_pond_topo) then - if (trim(runtype) == 'continue') & - restart_pond_topo = .true. + if (trim(runtype) == 'continue') restart_pond_topo = .true. if (restart_pond_topo) then call read_restart_pond_topo else @@ -464,10 +461,8 @@ subroutine init_restart endif if (trim(runtype) == 'continue') then - if (tr_brine) & - restart_hbrine = .true. - if (skl_bgc .or. z_tracers) & - restart_bgc = .true. + if (tr_brine) restart_hbrine = .true. + if (skl_bgc .or. z_tracers) restart_bgc = .true. endif if (tr_brine .or. skl_bgc) then ! brine height tracer diff --git a/cicecore/drivers/standalone/cice/CICE.F90 b/cicecore/drivers/standalone/cice/CICE.F90 index f993686e8..c92f0ea24 100644 --- a/cicecore/drivers/standalone/cice/CICE.F90 +++ b/cicecore/drivers/standalone/cice/CICE.F90 @@ -1,17 +1,17 @@ !======================================================================= -! Copyright (c) 2024, Triad National Security, LLC +! Copyright (c) 1998, 2017, Triad National Security, LLC ! All rights reserved. ! -! Copyright 2024. Triad National Security, LLC. This software was -! produced under U.S. Government contract DE-AC52-06NA25396 for Los -! Alamos National Laboratory (LANL), which is operated by Triad -! National Security, LLC for the U.S. Department of Energy. The U.S. -! Government has rights to use, reproduce, and distribute this software. -! NEITHER THE GOVERNMENT NOR TRIAD NATIONAL SECURITY, LLC MAKES ANY -! WARRANTY, EXPRESS OR IMPLIED, OR ASSUMES ANY LIABILITY FOR THE USE OF -! THIS SOFTWARE. If software is modified to produce derivative works, -! such modified software should be clearly marked, so as not to confuse -! it with the version available from LANL. +! This program was produced under U.S. Government contract 89233218CNA000001 +! for Los Alamos National Laboratory (LANL), which is operated by Triad +! National Security, LLC for the U.S. Department of Energy/National Nuclear +! Security Administration. All rights in the program are reserved by Triad +! National Security, LLC, and the U.S. Department of Energy/National Nuclear +! Security Administration. The Government is granted for itself and others +! acting on its behalf a nonexclusive, paid-up, irrevocable worldwide +! license in this material to reproduce, prepare. derivative works, +! distribute copies to the public, perform publicly and display publicly, +! and to permit others to do so. ! ! The full license and distribution policy are available from ! https://github.com/CICE-Consortium diff --git a/cicecore/drivers/standalone/cice/CICE_InitMod.F90 b/cicecore/drivers/standalone/cice/CICE_InitMod.F90 index 9e212799e..66a5256e0 100644 --- a/cicecore/drivers/standalone/cice/CICE_InitMod.F90 +++ b/cicecore/drivers/standalone/cice/CICE_InitMod.F90 @@ -265,11 +265,12 @@ subroutine init_restart use ice_grid, only: tmask use ice_init, only: ice_ic use ice_init_column, only: init_age, init_FY, init_lvl, init_snowtracers, & - init_meltponds_lvl, init_meltponds_topo, & + init_meltponds_lvl, init_meltponds_sealvl, init_meltponds_topo, & init_isotope, init_aerosol, init_hbrine, init_bgc, init_fsd use ice_restart_column, only: restart_age, read_restart_age, & restart_FY, read_restart_FY, restart_lvl, read_restart_lvl, & restart_pond_lvl, read_restart_pond_lvl, & + restart_pond_sealvl, read_restart_pond_sealvl, & restart_pond_topo, read_restart_pond_topo, & restart_snow, read_restart_snow, & restart_fsd, read_restart_fsd, & @@ -286,7 +287,7 @@ subroutine init_restart i, j , & ! horizontal indices iblk ! block index logical(kind=log_kind) :: & - tr_iage, tr_FY, tr_lvl, tr_pond_lvl, & + tr_iage, tr_FY, tr_lvl, tr_pond_lvl, tr_pond_sealvl, & tr_pond_topo, tr_snow, tr_fsd, tr_iso, tr_aero, tr_brine, & skl_bgc, z_tracers integer(kind=int_kind) :: & @@ -307,6 +308,7 @@ subroutine init_restart z_tracers_out=z_tracers) call icepack_query_tracer_flags(tr_iage_out=tr_iage, tr_FY_out=tr_FY, & tr_lvl_out=tr_lvl, tr_pond_lvl_out=tr_pond_lvl, & + tr_pond_sealvl_out = tr_pond_sealvl, & tr_pond_topo_out=tr_pond_topo, tr_aero_out=tr_aero, tr_brine_out=tr_brine, & tr_snow_out=tr_snow, tr_fsd_out=tr_fsd, tr_iso_out=tr_iso) call icepack_query_tracer_indices(nt_alvl_out=nt_alvl, nt_vlvl_out=nt_vlvl, & @@ -335,8 +337,7 @@ subroutine init_restart ! tracers ! ice age tracer if (tr_iage) then - if (trim(runtype) == 'continue') & - restart_age = .true. + if (trim(runtype) == 'continue') restart_age = .true. if (restart_age) then call read_restart_age else @@ -370,8 +371,7 @@ subroutine init_restart endif ! level-ice melt ponds if (tr_pond_lvl) then - if (trim(runtype) == 'continue') & - restart_pond_lvl = .true. + if (trim(runtype) == 'continue') restart_pond_lvl = .true. if (restart_pond_lvl) then call read_restart_pond_lvl else @@ -383,10 +383,23 @@ subroutine init_restart enddo ! iblk endif endif + ! sealvl melt ponds + if (tr_pond_sealvl) then + if (trim(runtype) == 'continue') restart_pond_sealvl = .true. + if (restart_pond_sealvl) then + call read_restart_pond_sealvl + else + do iblk = 1, nblocks + call init_meltponds_sealvl(trcrn(:,:,nt_apnd,:,iblk), & + trcrn(:,:,nt_hpnd,:,iblk), & + trcrn(:,:,nt_ipnd,:,iblk), & + dhsn(:,:,:,iblk)) + enddo ! iblk + endif + endif ! topographic melt ponds if (tr_pond_topo) then - if (trim(runtype) == 'continue') & - restart_pond_topo = .true. + if (trim(runtype) == 'continue') restart_pond_topo = .true. if (restart_pond_topo) then call read_restart_pond_topo else @@ -448,10 +461,8 @@ subroutine init_restart endif if (trim(runtype) == 'continue') then - if (tr_brine) & - restart_hbrine = .true. - if (skl_bgc .or. z_tracers) & - restart_bgc = .true. + if (tr_brine) restart_hbrine = .true. + if (skl_bgc .or. z_tracers) restart_bgc = .true. endif if (tr_brine .or. skl_bgc) then ! brine height tracer diff --git a/cicecore/drivers/standalone/cice/CICE_RunMod.F90 b/cicecore/drivers/standalone/cice/CICE_RunMod.F90 index 59213f728..53476776b 100644 --- a/cicecore/drivers/standalone/cice/CICE_RunMod.F90 +++ b/cicecore/drivers/standalone/cice/CICE_RunMod.F90 @@ -151,7 +151,7 @@ subroutine ice_step use ice_history_bgc, only: init_history_bgc use ice_restart, only: final_restart use ice_restart_column, only: write_restart_age, write_restart_FY, & - write_restart_lvl, write_restart_pond_lvl, & + write_restart_lvl, write_restart_pond_lvl, write_restart_pond_sealvl,& write_restart_pond_topo, write_restart_aero, write_restart_fsd, & write_restart_iso, write_restart_bgc, write_restart_hbrine, & write_restart_snow @@ -174,7 +174,8 @@ subroutine ice_step logical (kind=log_kind) :: & tr_iage, tr_FY, tr_lvl, tr_fsd, tr_snow, & - tr_pond_lvl, tr_pond_topo, tr_brine, tr_iso, tr_aero, & + tr_pond_lvl, tr_pond_sealvl, tr_pond_topo, & + tr_brine, tr_iso, tr_aero, & calc_Tsfc, skl_bgc, z_tracers, wave_spec character(len=*), parameter :: subname = '(ice_step)' @@ -191,7 +192,7 @@ subroutine ice_step call icepack_query_parameters(calc_Tsfc_out=calc_Tsfc, skl_bgc_out=skl_bgc, & z_tracers_out=z_tracers, ktherm_out=ktherm, wave_spec_out=wave_spec) call icepack_query_tracer_flags(tr_iage_out=tr_iage, tr_FY_out=tr_FY, & - tr_lvl_out=tr_lvl, tr_pond_lvl_out=tr_pond_lvl, & + tr_lvl_out=tr_lvl, tr_pond_lvl_out=tr_pond_lvl, tr_pond_sealvl_out=tr_pond_sealvl, & tr_pond_topo_out=tr_pond_topo, tr_brine_out=tr_brine, tr_aero_out=tr_aero, & tr_iso_out=tr_iso, tr_fsd_out=tr_fsd, tr_snow_out=tr_snow) call icepack_warnings_flush(nu_diag) @@ -397,6 +398,7 @@ subroutine ice_step if (tr_FY) call write_restart_FY if (tr_lvl) call write_restart_lvl if (tr_pond_lvl) call write_restart_pond_lvl + if (tr_pond_sealvl) call write_restart_pond_sealvl if (tr_pond_topo) call write_restart_pond_topo if (tr_snow) call write_restart_snow if (tr_fsd) call write_restart_fsd diff --git a/cicecore/drivers/unittest/gridavgchk/CICE_InitMod.F90 b/cicecore/drivers/unittest/gridavgchk/CICE_InitMod.F90 index 9e212799e..66a5256e0 100644 --- a/cicecore/drivers/unittest/gridavgchk/CICE_InitMod.F90 +++ b/cicecore/drivers/unittest/gridavgchk/CICE_InitMod.F90 @@ -265,11 +265,12 @@ subroutine init_restart use ice_grid, only: tmask use ice_init, only: ice_ic use ice_init_column, only: init_age, init_FY, init_lvl, init_snowtracers, & - init_meltponds_lvl, init_meltponds_topo, & + init_meltponds_lvl, init_meltponds_sealvl, init_meltponds_topo, & init_isotope, init_aerosol, init_hbrine, init_bgc, init_fsd use ice_restart_column, only: restart_age, read_restart_age, & restart_FY, read_restart_FY, restart_lvl, read_restart_lvl, & restart_pond_lvl, read_restart_pond_lvl, & + restart_pond_sealvl, read_restart_pond_sealvl, & restart_pond_topo, read_restart_pond_topo, & restart_snow, read_restart_snow, & restart_fsd, read_restart_fsd, & @@ -286,7 +287,7 @@ subroutine init_restart i, j , & ! horizontal indices iblk ! block index logical(kind=log_kind) :: & - tr_iage, tr_FY, tr_lvl, tr_pond_lvl, & + tr_iage, tr_FY, tr_lvl, tr_pond_lvl, tr_pond_sealvl, & tr_pond_topo, tr_snow, tr_fsd, tr_iso, tr_aero, tr_brine, & skl_bgc, z_tracers integer(kind=int_kind) :: & @@ -307,6 +308,7 @@ subroutine init_restart z_tracers_out=z_tracers) call icepack_query_tracer_flags(tr_iage_out=tr_iage, tr_FY_out=tr_FY, & tr_lvl_out=tr_lvl, tr_pond_lvl_out=tr_pond_lvl, & + tr_pond_sealvl_out = tr_pond_sealvl, & tr_pond_topo_out=tr_pond_topo, tr_aero_out=tr_aero, tr_brine_out=tr_brine, & tr_snow_out=tr_snow, tr_fsd_out=tr_fsd, tr_iso_out=tr_iso) call icepack_query_tracer_indices(nt_alvl_out=nt_alvl, nt_vlvl_out=nt_vlvl, & @@ -335,8 +337,7 @@ subroutine init_restart ! tracers ! ice age tracer if (tr_iage) then - if (trim(runtype) == 'continue') & - restart_age = .true. + if (trim(runtype) == 'continue') restart_age = .true. if (restart_age) then call read_restart_age else @@ -370,8 +371,7 @@ subroutine init_restart endif ! level-ice melt ponds if (tr_pond_lvl) then - if (trim(runtype) == 'continue') & - restart_pond_lvl = .true. + if (trim(runtype) == 'continue') restart_pond_lvl = .true. if (restart_pond_lvl) then call read_restart_pond_lvl else @@ -383,10 +383,23 @@ subroutine init_restart enddo ! iblk endif endif + ! sealvl melt ponds + if (tr_pond_sealvl) then + if (trim(runtype) == 'continue') restart_pond_sealvl = .true. + if (restart_pond_sealvl) then + call read_restart_pond_sealvl + else + do iblk = 1, nblocks + call init_meltponds_sealvl(trcrn(:,:,nt_apnd,:,iblk), & + trcrn(:,:,nt_hpnd,:,iblk), & + trcrn(:,:,nt_ipnd,:,iblk), & + dhsn(:,:,:,iblk)) + enddo ! iblk + endif + endif ! topographic melt ponds if (tr_pond_topo) then - if (trim(runtype) == 'continue') & - restart_pond_topo = .true. + if (trim(runtype) == 'continue') restart_pond_topo = .true. if (restart_pond_topo) then call read_restart_pond_topo else @@ -448,10 +461,8 @@ subroutine init_restart endif if (trim(runtype) == 'continue') then - if (tr_brine) & - restart_hbrine = .true. - if (skl_bgc .or. z_tracers) & - restart_bgc = .true. + if (tr_brine) restart_hbrine = .true. + if (skl_bgc .or. z_tracers) restart_bgc = .true. endif if (tr_brine .or. skl_bgc) then ! brine height tracer diff --git a/cicecore/drivers/unittest/halochk/CICE_InitMod.F90 b/cicecore/drivers/unittest/halochk/CICE_InitMod.F90 index 9e212799e..66a5256e0 100644 --- a/cicecore/drivers/unittest/halochk/CICE_InitMod.F90 +++ b/cicecore/drivers/unittest/halochk/CICE_InitMod.F90 @@ -265,11 +265,12 @@ subroutine init_restart use ice_grid, only: tmask use ice_init, only: ice_ic use ice_init_column, only: init_age, init_FY, init_lvl, init_snowtracers, & - init_meltponds_lvl, init_meltponds_topo, & + init_meltponds_lvl, init_meltponds_sealvl, init_meltponds_topo, & init_isotope, init_aerosol, init_hbrine, init_bgc, init_fsd use ice_restart_column, only: restart_age, read_restart_age, & restart_FY, read_restart_FY, restart_lvl, read_restart_lvl, & restart_pond_lvl, read_restart_pond_lvl, & + restart_pond_sealvl, read_restart_pond_sealvl, & restart_pond_topo, read_restart_pond_topo, & restart_snow, read_restart_snow, & restart_fsd, read_restart_fsd, & @@ -286,7 +287,7 @@ subroutine init_restart i, j , & ! horizontal indices iblk ! block index logical(kind=log_kind) :: & - tr_iage, tr_FY, tr_lvl, tr_pond_lvl, & + tr_iage, tr_FY, tr_lvl, tr_pond_lvl, tr_pond_sealvl, & tr_pond_topo, tr_snow, tr_fsd, tr_iso, tr_aero, tr_brine, & skl_bgc, z_tracers integer(kind=int_kind) :: & @@ -307,6 +308,7 @@ subroutine init_restart z_tracers_out=z_tracers) call icepack_query_tracer_flags(tr_iage_out=tr_iage, tr_FY_out=tr_FY, & tr_lvl_out=tr_lvl, tr_pond_lvl_out=tr_pond_lvl, & + tr_pond_sealvl_out = tr_pond_sealvl, & tr_pond_topo_out=tr_pond_topo, tr_aero_out=tr_aero, tr_brine_out=tr_brine, & tr_snow_out=tr_snow, tr_fsd_out=tr_fsd, tr_iso_out=tr_iso) call icepack_query_tracer_indices(nt_alvl_out=nt_alvl, nt_vlvl_out=nt_vlvl, & @@ -335,8 +337,7 @@ subroutine init_restart ! tracers ! ice age tracer if (tr_iage) then - if (trim(runtype) == 'continue') & - restart_age = .true. + if (trim(runtype) == 'continue') restart_age = .true. if (restart_age) then call read_restart_age else @@ -370,8 +371,7 @@ subroutine init_restart endif ! level-ice melt ponds if (tr_pond_lvl) then - if (trim(runtype) == 'continue') & - restart_pond_lvl = .true. + if (trim(runtype) == 'continue') restart_pond_lvl = .true. if (restart_pond_lvl) then call read_restart_pond_lvl else @@ -383,10 +383,23 @@ subroutine init_restart enddo ! iblk endif endif + ! sealvl melt ponds + if (tr_pond_sealvl) then + if (trim(runtype) == 'continue') restart_pond_sealvl = .true. + if (restart_pond_sealvl) then + call read_restart_pond_sealvl + else + do iblk = 1, nblocks + call init_meltponds_sealvl(trcrn(:,:,nt_apnd,:,iblk), & + trcrn(:,:,nt_hpnd,:,iblk), & + trcrn(:,:,nt_ipnd,:,iblk), & + dhsn(:,:,:,iblk)) + enddo ! iblk + endif + endif ! topographic melt ponds if (tr_pond_topo) then - if (trim(runtype) == 'continue') & - restart_pond_topo = .true. + if (trim(runtype) == 'continue') restart_pond_topo = .true. if (restart_pond_topo) then call read_restart_pond_topo else @@ -448,10 +461,8 @@ subroutine init_restart endif if (trim(runtype) == 'continue') then - if (tr_brine) & - restart_hbrine = .true. - if (skl_bgc .or. z_tracers) & - restart_bgc = .true. + if (tr_brine) restart_hbrine = .true. + if (skl_bgc .or. z_tracers) restart_bgc = .true. endif if (tr_brine .or. skl_bgc) then ! brine height tracer diff --git a/cicecore/drivers/unittest/opticep/CICE.F90 b/cicecore/drivers/unittest/opticep/CICE.F90 index f993686e8..c92f0ea24 100644 --- a/cicecore/drivers/unittest/opticep/CICE.F90 +++ b/cicecore/drivers/unittest/opticep/CICE.F90 @@ -1,17 +1,17 @@ !======================================================================= -! Copyright (c) 2024, Triad National Security, LLC +! Copyright (c) 1998, 2017, Triad National Security, LLC ! All rights reserved. ! -! Copyright 2024. Triad National Security, LLC. This software was -! produced under U.S. Government contract DE-AC52-06NA25396 for Los -! Alamos National Laboratory (LANL), which is operated by Triad -! National Security, LLC for the U.S. Department of Energy. The U.S. -! Government has rights to use, reproduce, and distribute this software. -! NEITHER THE GOVERNMENT NOR TRIAD NATIONAL SECURITY, LLC MAKES ANY -! WARRANTY, EXPRESS OR IMPLIED, OR ASSUMES ANY LIABILITY FOR THE USE OF -! THIS SOFTWARE. If software is modified to produce derivative works, -! such modified software should be clearly marked, so as not to confuse -! it with the version available from LANL. +! This program was produced under U.S. Government contract 89233218CNA000001 +! for Los Alamos National Laboratory (LANL), which is operated by Triad +! National Security, LLC for the U.S. Department of Energy/National Nuclear +! Security Administration. All rights in the program are reserved by Triad +! National Security, LLC, and the U.S. Department of Energy/National Nuclear +! Security Administration. The Government is granted for itself and others +! acting on its behalf a nonexclusive, paid-up, irrevocable worldwide +! license in this material to reproduce, prepare. derivative works, +! distribute copies to the public, perform publicly and display publicly, +! and to permit others to do so. ! ! The full license and distribution policy are available from ! https://github.com/CICE-Consortium diff --git a/cicecore/drivers/unittest/opticep/CICE_InitMod.F90 b/cicecore/drivers/unittest/opticep/CICE_InitMod.F90 index 9e212799e..66a5256e0 100644 --- a/cicecore/drivers/unittest/opticep/CICE_InitMod.F90 +++ b/cicecore/drivers/unittest/opticep/CICE_InitMod.F90 @@ -265,11 +265,12 @@ subroutine init_restart use ice_grid, only: tmask use ice_init, only: ice_ic use ice_init_column, only: init_age, init_FY, init_lvl, init_snowtracers, & - init_meltponds_lvl, init_meltponds_topo, & + init_meltponds_lvl, init_meltponds_sealvl, init_meltponds_topo, & init_isotope, init_aerosol, init_hbrine, init_bgc, init_fsd use ice_restart_column, only: restart_age, read_restart_age, & restart_FY, read_restart_FY, restart_lvl, read_restart_lvl, & restart_pond_lvl, read_restart_pond_lvl, & + restart_pond_sealvl, read_restart_pond_sealvl, & restart_pond_topo, read_restart_pond_topo, & restart_snow, read_restart_snow, & restart_fsd, read_restart_fsd, & @@ -286,7 +287,7 @@ subroutine init_restart i, j , & ! horizontal indices iblk ! block index logical(kind=log_kind) :: & - tr_iage, tr_FY, tr_lvl, tr_pond_lvl, & + tr_iage, tr_FY, tr_lvl, tr_pond_lvl, tr_pond_sealvl, & tr_pond_topo, tr_snow, tr_fsd, tr_iso, tr_aero, tr_brine, & skl_bgc, z_tracers integer(kind=int_kind) :: & @@ -307,6 +308,7 @@ subroutine init_restart z_tracers_out=z_tracers) call icepack_query_tracer_flags(tr_iage_out=tr_iage, tr_FY_out=tr_FY, & tr_lvl_out=tr_lvl, tr_pond_lvl_out=tr_pond_lvl, & + tr_pond_sealvl_out = tr_pond_sealvl, & tr_pond_topo_out=tr_pond_topo, tr_aero_out=tr_aero, tr_brine_out=tr_brine, & tr_snow_out=tr_snow, tr_fsd_out=tr_fsd, tr_iso_out=tr_iso) call icepack_query_tracer_indices(nt_alvl_out=nt_alvl, nt_vlvl_out=nt_vlvl, & @@ -335,8 +337,7 @@ subroutine init_restart ! tracers ! ice age tracer if (tr_iage) then - if (trim(runtype) == 'continue') & - restart_age = .true. + if (trim(runtype) == 'continue') restart_age = .true. if (restart_age) then call read_restart_age else @@ -370,8 +371,7 @@ subroutine init_restart endif ! level-ice melt ponds if (tr_pond_lvl) then - if (trim(runtype) == 'continue') & - restart_pond_lvl = .true. + if (trim(runtype) == 'continue') restart_pond_lvl = .true. if (restart_pond_lvl) then call read_restart_pond_lvl else @@ -383,10 +383,23 @@ subroutine init_restart enddo ! iblk endif endif + ! sealvl melt ponds + if (tr_pond_sealvl) then + if (trim(runtype) == 'continue') restart_pond_sealvl = .true. + if (restart_pond_sealvl) then + call read_restart_pond_sealvl + else + do iblk = 1, nblocks + call init_meltponds_sealvl(trcrn(:,:,nt_apnd,:,iblk), & + trcrn(:,:,nt_hpnd,:,iblk), & + trcrn(:,:,nt_ipnd,:,iblk), & + dhsn(:,:,:,iblk)) + enddo ! iblk + endif + endif ! topographic melt ponds if (tr_pond_topo) then - if (trim(runtype) == 'continue') & - restart_pond_topo = .true. + if (trim(runtype) == 'continue') restart_pond_topo = .true. if (restart_pond_topo) then call read_restart_pond_topo else @@ -448,10 +461,8 @@ subroutine init_restart endif if (trim(runtype) == 'continue') then - if (tr_brine) & - restart_hbrine = .true. - if (skl_bgc .or. z_tracers) & - restart_bgc = .true. + if (tr_brine) restart_hbrine = .true. + if (skl_bgc .or. z_tracers) restart_bgc = .true. endif if (tr_brine .or. skl_bgc) then ! brine height tracer diff --git a/cicecore/drivers/unittest/opticep/CICE_RunMod.F90 b/cicecore/drivers/unittest/opticep/CICE_RunMod.F90 index 59213f728..53476776b 100644 --- a/cicecore/drivers/unittest/opticep/CICE_RunMod.F90 +++ b/cicecore/drivers/unittest/opticep/CICE_RunMod.F90 @@ -151,7 +151,7 @@ subroutine ice_step use ice_history_bgc, only: init_history_bgc use ice_restart, only: final_restart use ice_restart_column, only: write_restart_age, write_restart_FY, & - write_restart_lvl, write_restart_pond_lvl, & + write_restart_lvl, write_restart_pond_lvl, write_restart_pond_sealvl,& write_restart_pond_topo, write_restart_aero, write_restart_fsd, & write_restart_iso, write_restart_bgc, write_restart_hbrine, & write_restart_snow @@ -174,7 +174,8 @@ subroutine ice_step logical (kind=log_kind) :: & tr_iage, tr_FY, tr_lvl, tr_fsd, tr_snow, & - tr_pond_lvl, tr_pond_topo, tr_brine, tr_iso, tr_aero, & + tr_pond_lvl, tr_pond_sealvl, tr_pond_topo, & + tr_brine, tr_iso, tr_aero, & calc_Tsfc, skl_bgc, z_tracers, wave_spec character(len=*), parameter :: subname = '(ice_step)' @@ -191,7 +192,7 @@ subroutine ice_step call icepack_query_parameters(calc_Tsfc_out=calc_Tsfc, skl_bgc_out=skl_bgc, & z_tracers_out=z_tracers, ktherm_out=ktherm, wave_spec_out=wave_spec) call icepack_query_tracer_flags(tr_iage_out=tr_iage, tr_FY_out=tr_FY, & - tr_lvl_out=tr_lvl, tr_pond_lvl_out=tr_pond_lvl, & + tr_lvl_out=tr_lvl, tr_pond_lvl_out=tr_pond_lvl, tr_pond_sealvl_out=tr_pond_sealvl, & tr_pond_topo_out=tr_pond_topo, tr_brine_out=tr_brine, tr_aero_out=tr_aero, & tr_iso_out=tr_iso, tr_fsd_out=tr_fsd, tr_snow_out=tr_snow) call icepack_warnings_flush(nu_diag) @@ -397,6 +398,7 @@ subroutine ice_step if (tr_FY) call write_restart_FY if (tr_lvl) call write_restart_lvl if (tr_pond_lvl) call write_restart_pond_lvl + if (tr_pond_sealvl) call write_restart_pond_sealvl if (tr_pond_topo) call write_restart_pond_topo if (tr_snow) call write_restart_snow if (tr_fsd) call write_restart_fsd diff --git a/cicecore/drivers/unittest/opticep/ice_init_column.F90 b/cicecore/drivers/unittest/opticep/ice_init_column.F90 index 7140454ba..34f28cdba 100644 --- a/cicecore/drivers/unittest/opticep/ice_init_column.F90 +++ b/cicecore/drivers/unittest/opticep/ice_init_column.F90 @@ -44,21 +44,23 @@ module ice_init_column private public :: init_thermo_vertical, init_shortwave, & init_age, init_FY, init_lvl, init_fsd, & - init_meltponds_lvl, init_meltponds_topo, & + init_meltponds_lvl, init_meltponds_topo, init_meltponds_sealvl, & init_aerosol, init_bgc, init_hbrine, init_zbgc, input_zbgc, & count_tracers, init_isotope, init_snowtracers ! namelist parameters needed locally real (kind=dbl_kind) :: & - tau_min , tau_max , & - nitratetype , ammoniumtype , silicatetype, & - dmspptype , dmspdtype , humtype + tau_min , tau_max , & + nitratetype , ammoniumtype , silicatetype, & + dmspptype , dmspdtype , humtype + + real (kind=dbl_kind) :: & + grid_oS, l_skS ! deprecated with zsalinity real (kind=dbl_kind) :: & grid_o, l_sk, grid_o_t, initbio_frac, & - frazil_scav, grid_oS, l_skS, & - phi_snow, & + frazil_scav, 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 , & @@ -163,6 +165,7 @@ subroutine init_shortwave use ice_arrays_column, only: fswpenln, Iswabsn, Sswabsn, albicen, & albsnon, alvdrn, alidrn, alvdfn, alidfn, fswsfcn, & fswthrun, fswthrun_vdr, fswthrun_vdf, fswthrun_idr, fswthrun_idf, & + fswthrun_uvrdr, fswthrun_uvrdf, fswthrun_pardr, fswthrun_pardf, & fswintn, albpndn, apeffn, trcrn_sw, dhsn, ffracn, snowfracn, & swgrid, igrid use ice_blocks, only: block, get_block @@ -173,8 +176,9 @@ subroutine init_shortwave use ice_flux, only: alvdf, alidf, alvdr, alidr, & alvdr_ai, alidr_ai, alvdf_ai, alidf_ai, & swvdr, swvdf, swidr, swidf, scale_factor, snowfrac, & + swuvrdr, swuvrdf, swpardr, swpardf, & albice, albsno, albpnd, apeff_ai, coszen, fsnow - use ice_grid, only: tlat, tlon, tmask + use ice_grid, only: tlat, tlon, tmask, opmask use ice_restart_shared, only: restart, runtype use ice_state, only: aicen, vicen, vsnon, trcrn @@ -285,6 +289,11 @@ subroutine init_shortwave alidrn(i,j,n,iblk) = c0 alvdfn(i,j,n,iblk) = c0 alidfn(i,j,n,iblk) = c0 + albpndn(i,j,n,iblk) = c0 + albicen(i,j,n,iblk) = c0 + albsnon(i,j,n,iblk) = c0 + apeffn(i,j,n,iblk) = c0 + snowfracn(i,j,n,iblk) = c0 fswsfcn(i,j,n,iblk) = c0 fswintn(i,j,n,iblk) = c0 fswthrun(i,j,n,iblk) = c0 @@ -292,6 +301,10 @@ subroutine init_shortwave fswthrun_vdf(i,j,n,iblk) = c0 fswthrun_idr(i,j,n,iblk) = c0 fswthrun_idf(i,j,n,iblk) = c0 + fswthrun_uvrdr(i,j,n,iblk) = c0 + fswthrun_uvrdf(i,j,n,iblk) = c0 + fswthrun_pardr(i,j,n,iblk) = c0 + fswthrun_pardf(i,j,n,iblk) = c0 enddo ! ncat enddo @@ -301,7 +314,9 @@ subroutine init_shortwave if (shortwave(1:4) == 'dEdd') then ! delta Eddington -#ifndef CESMCOUPLED +#if defined (CESMCOUPLED) || defined (GEOSCOUPLED) + ! initialized externally +#else ! initialize orbital parameters ! These come from the driver in the coupled model. call icepack_init_orbit() @@ -323,7 +338,7 @@ subroutine init_shortwave endif enddo - if (tmask(i,j,iblk)) then + if (tmask(i,j,iblk) .or. opmask(i,j,iblk)) then call icepack_step_radiation (dt=dt, & fbri=fbri(:), & aicen=aicen(i,j,:,iblk), & @@ -345,6 +360,8 @@ subroutine init_shortwave sec=msec, & swvdr=swvdr(i,j,iblk), swvdf=swvdf(i,j,iblk),& swidr=swidr(i,j,iblk), swidf=swidf(i,j,iblk),& + swuvrdr=swuvrdr(i,j,iblk), swuvrdf=swuvrdf (i,j,iblk), & + swpardr=swpardr(i,j,iblk), swpardf=swpardf (i,j,iblk), & coszen=coszen(i,j,iblk), fsnow=fsnow(i,j,iblk),& alvdrn=alvdrn(i,j,:,iblk), alvdfn=alvdfn(i,j,:,iblk), & alidrn=alidrn(i,j,:,iblk), alidfn=alidfn(i,j,:,iblk), & @@ -354,6 +371,10 @@ subroutine init_shortwave !opt fswthrun_vdf=fswthrun_vdf(i,j,:,iblk), & !opt fswthrun_idr=fswthrun_idr(i,j,:,iblk), & !opt fswthrun_idf=fswthrun_idf(i,j,:,iblk), & +!opt fswthrun_uvrdr=fswthrun_uvrdr (i,j,: ,iblk), & +!opt fswthrun_uvrdf=fswthrun_uvrdf (i,j,: ,iblk), & +!opt fswthrun_pardr=fswthrun_pardr (i,j,: ,iblk), & +!opt fswthrun_pardf=fswthrun_pardf (i,j,: ,iblk), & fswpenln=fswpenln(i,j,:,:,iblk), & Sswabsn=Sswabsn(i,j,:,:,iblk), Iswabsn=Iswabsn(i,j,:,:,iblk), & albicen=albicen(i,j,:,iblk), albsnon=albsnon(i,j,:,iblk), & @@ -536,6 +557,27 @@ end subroutine init_meltponds_lvl !======================================================================= +! Initialize melt ponds. + + subroutine init_meltponds_sealvl(apnd, hpnd, ipnd, dhsn) + + real(kind=dbl_kind), dimension(:,:,:), intent(out) :: & + apnd , & ! melt pond area fraction + hpnd , & ! melt pond depth + ipnd , & ! melt pond refrozen lid thickness + dhsn ! depth difference for snow on sea ice and pond ice + + character(len=*),parameter :: subname='(init_meltponds_sealvl)' + + apnd(:,:,:) = c0 + hpnd(:,:,:) = c0 + ipnd(:,:,:) = c0 + dhsn(:,:,:) = c0 + + end subroutine init_meltponds_sealvl + +!======================================================================= + ! Initialize melt ponds. subroutine init_meltponds_topo(apnd, hpnd, ipnd) @@ -946,8 +988,11 @@ subroutine input_zbgc ktherm logical (kind=log_kind) :: & - solve_zsal, skl_bgc, z_tracers, scale_bgc, solve_zbgc, dEdd_algae, & - modal_aero, restart_zsal + skl_bgc, z_tracers, scale_bgc, solve_zbgc, dEdd_algae, & + modal_aero + + logical (kind=log_kind) :: & + solve_zsal, restart_zsal ! deprecated with zsalinity character (char_len) :: & bgc_flux_type @@ -1058,7 +1103,7 @@ subroutine input_zbgc ! z biology parameters grid_o = 0.006 ! for bottom flux grid_o_t = 0.006 ! for top flux - l_sk = 2.0_dbl_kind ! characteristic diffusive scale (m) + l_sk = 2.0_dbl_kind ! characteristic diffusive scale brine (m) initbio_frac = c1 ! fraction of ocean trcr concentration in bio trcrs frazil_scav = 0.8_dbl_kind ! increase in initial bio tracer from ocean scavenging ratio_Si2N_diatoms = 1.8_dbl_kind ! algal Si to N (mol/mol) @@ -1179,10 +1224,6 @@ subroutine input_zbgc F_abs_chl_phaeo = 5.0 ratio_C2N_proteins = 5.0_dbl_kind ! ratio of C to N in proteins (mol/mol) - ! z salinity parameters - grid_oS = c0 ! for bottom flux - l_skS = 0.028_dbl_kind ! characteristic diffusive scale (m) - !----------------------------------------------------------------- ! read from input file !----------------------------------------------------------------- @@ -1220,8 +1261,6 @@ subroutine input_zbgc call broadcast_scalar(restart_hbrine, master_task) call broadcast_scalar(phi_snow, master_task) - call broadcast_scalar(grid_oS, master_task) - call broadcast_scalar(l_skS, master_task) call broadcast_scalar(solve_zbgc, master_task) call broadcast_scalar(skl_bgc, master_task) @@ -1377,9 +1416,9 @@ subroutine input_zbgc restart_hbrine = .false. endif - if (solve_zsal) then + if (solve_zsal .or. restart_zsal) then if (my_task == master_task) then - write(nu_diag,*) subname,' ERROR: solve_zsal=T deprecated' + write(nu_diag,*) subname,' ERROR: solve_zsal=T, restart_zsal=T deprecated' endif abort_flag = 101 endif @@ -1574,10 +1613,6 @@ subroutine input_zbgc write(nu_diag,1010) ' restart_hbrine = ', restart_hbrine write(nu_diag,1005) ' phi_snow = ', phi_snow endif - write(nu_diag,1010) ' solve_zsal (deprecated) = ', solve_zsal - write(nu_diag,* ) ' WARNING: zsalinity has been deprecated. Namelists and interfaces' - write(nu_diag,* ) ' will be removed in a future version' - write(nu_diag,1010) ' skl_bgc = ', skl_bgc write(nu_diag,1010) ' restart_bgc = ', restart_bgc write(nu_diag,1010) ' tr_bgc_N = ', tr_bgc_N @@ -1646,7 +1681,7 @@ subroutine input_zbgc dEdd_algae_in=dEdd_algae, solve_zbgc_in=solve_zbgc, & bgc_flux_type_in=bgc_flux_type, grid_o_in=grid_o, l_sk_in=l_sk, & initbio_frac_in=initbio_frac, frazil_scav_in=frazil_scav, & - grid_oS_in=grid_oS, l_skS_in=l_skS, phi_snow_in=phi_snow, & + phi_snow_in=phi_snow, & algal_vel_in=algal_vel, R_dFe2dust_in=R_dFe2dust, & dustFe_sol_in=dustFe_sol, T_max_in=T_max, fsal_in=fsal, & op_dep_min_in=op_dep_min, fr_graze_s_in=fr_graze_s, & @@ -1792,7 +1827,7 @@ subroutine count_tracers integer (kind=int_kind) :: ntrcr logical (kind=log_kind) :: tr_iage, tr_FY, tr_lvl, tr_pond, tr_aero, tr_fsd logical (kind=log_kind) :: tr_snow - logical (kind=log_kind) :: tr_iso, tr_pond_lvl, tr_pond_topo + logical (kind=log_kind) :: tr_iso, tr_pond_lvl, tr_pond_topo, tr_pond_sealvl integer (kind=int_kind) :: nt_Tsfc, nt_sice, nt_qice, nt_qsno, nt_iage, nt_FY integer (kind=int_kind) :: nt_alvl, nt_vlvl, nt_apnd, nt_hpnd, nt_ipnd, nt_aero integer (kind=int_kind) :: nt_fsd, nt_isosno, nt_isoice @@ -1876,7 +1911,7 @@ subroutine count_tracers call icepack_query_tracer_flags(tr_iage_out=tr_iage, tr_FY_out=tr_FY, & tr_lvl_out=tr_lvl, tr_aero_out=tr_aero, tr_pond_out=tr_pond, & - tr_pond_lvl_out=tr_pond_lvl, & + tr_pond_lvl_out=tr_pond_lvl, tr_pond_sealvl_out=tr_pond_sealvl, & tr_pond_topo_out=tr_pond_topo, tr_brine_out=tr_brine, tr_fsd_out=tr_fsd, & tr_snow_out=tr_snow, tr_iso_out=tr_iso, & tr_bgc_Nit_out=tr_bgc_Nit, tr_bgc_Am_out =tr_bgc_Am, tr_bgc_Sil_out=tr_bgc_Sil, & @@ -1935,6 +1970,10 @@ subroutine count_tracers ntrcr = ntrcr + 1 ! refrozen pond ice lid thickness nt_ipnd = ntrcr ! on level-ice ponds (if frzpnd='hlid') endif + if (tr_pond_sealvl) then + ntrcr = ntrcr + 1 ! refrozen pond ice lid thickness + nt_ipnd = ntrcr ! on sea level ponds (if frzpnd='hlid') + endif if (tr_pond_topo) then ntrcr = ntrcr + 1 ! nt_ipnd = ntrcr ! refrozen pond ice lid thickness @@ -2818,7 +2857,7 @@ subroutine init_zbgc call icepack_init_zbgc( & !opt zbgc_init_frac_in=zbgc_init_frac, tau_ret_in=tau_ret, tau_rel_in=tau_rel, & !opt zbgc_frac_init_in=zbgc_frac_init, bgc_tracer_type_in=bgc_tracer_type) - ) + ) call icepack_warnings_flush(nu_diag) if (icepack_warnings_aborted()) call abort_ice(error_message=subname, & file=__FILE__, line=__LINE__) diff --git a/cicecore/drivers/unittest/opticep/ice_step_mod.F90 b/cicecore/drivers/unittest/opticep/ice_step_mod.F90 index 69f49a6f5..6d8fff7f9 100644 --- a/cicecore/drivers/unittest/opticep/ice_step_mod.F90 +++ b/cicecore/drivers/unittest/opticep/ice_step_mod.F90 @@ -60,7 +60,10 @@ subroutine save_init ! saves initial values for aice, aicen, vicen, vsnon use ice_state, only: aice, aicen, aice_init, aicen_init, & - vicen, vicen_init, vsnon, vsnon_init + vicen, vicen_init, vsnon, vsnon_init, trcrn, Tsfcn_init + + integer (kind=int_kind) :: & + nt_Tsfc ! Tsfc index in trcrn character(len=*), parameter :: subname = '(save_init)' @@ -70,10 +73,13 @@ subroutine save_init ! Save the initial ice area and volume in each category. !----------------------------------------------------------------- + call icepack_query_tracer_indices(nt_Tsfc_out=nt_Tsfc) + aice_init = aice aicen_init = aicen vicen_init = vicen vsnon_init = vsnon + Tsfcn_init = trcrn(:,:,nt_Tsfc,:,:) end subroutine save_init @@ -222,7 +228,8 @@ subroutine step_therm1 (dt, iblk) Cdn_atm, Cdn_atm_skin, Cdn_atm_floe, Cdn_atm_rdg, Cdn_atm_pond, & hfreebd, hdraft, hridge, distrdg, hkeel, dkeel, lfloe, dfloe, & fswsfcn, fswintn, Sswabsn, Iswabsn, meltsliqn, meltsliq, & - fswthrun, fswthrun_vdr, fswthrun_vdf, fswthrun_idr, fswthrun_idf + fswthrun, fswthrun_vdr, fswthrun_vdf, fswthrun_idr, fswthrun_idf, & + fswthrun_uvrdr, fswthrun_uvrdf, fswthrun_pardr, fswthrun_pardf use ice_calendar, only: yday use ice_domain_size, only: ncat, nilyr, nslyr, n_iso, n_aero, nfsd use ice_flux, only: frzmlt, sst, Tf, strocnxT_iavg, strocnyT_iavg, rsiden, fbot, Tbot, Tsnice, & @@ -232,12 +239,16 @@ subroutine step_therm1 (dt, iblk) frain, Tair, strairxT, strairyT, fsurf, fcondtop, fsens, & flat, fswabs, flwout, evap, evaps, evapi, Tref, Qref, Uref, fresh, fsalt, fhocn, & fswthru, fswthru_vdr, fswthru_vdf, fswthru_idr, fswthru_idf, & + fswthru_uvrdr, fswthru_uvrdf, fswthru_pardr, fswthru_pardf, & meltt, melts, meltb, congel, snoice, & flatn_f, fsensn_f, fsurfn_f, fcondtopn_f, & + dfsurfndTsfc_f, dflatndTsfc_f, & send_i2x_per_cat, fswthrun_ai, dsnow + use ice_flux, only: dpnd_flush, dpnd_expon, dpnd_freebd, dpnd_initial, & + dpnd_dlid, dpnd_flushn, dpnd_exponn, dpnd_freebdn, dpnd_initialn, dpnd_dlidn use ice_flux_bgc, only: dsnown, faero_atm, faero_ocn, fiso_atm, fiso_ocn, & Qa_iso, Qref_iso, fiso_evap, HDO_ocn, H2_16O_ocn, H2_18O_ocn - use ice_grid, only: lmask_n, lmask_s, tmask + use ice_grid, only: lmask_n, lmask_s, tmask, opmask use ice_state, only: aice, aicen, aicen_init, vicen_init, & vice, vicen, vsno, vsnon, trcrn, vsnon_init #ifdef CICE_IN_NEMO @@ -273,8 +284,7 @@ subroutine step_therm1 (dt, iblk) nt_isosno, nt_isoice, nt_rsnw, nt_smice, nt_smliq logical (kind=log_kind) :: & - tr_iage, tr_FY, tr_iso, tr_aero, tr_pond, & - tr_pond_lvl, tr_pond_topo, calc_Tsfc, snwgrain + tr_iage, tr_FY, tr_iso, tr_aero, calc_Tsfc, snwgrain real (kind=dbl_kind) :: & puny ! a very small number @@ -299,8 +309,7 @@ subroutine step_therm1 (dt, iblk) call icepack_query_tracer_sizes(ntrcr_out=ntrcr) call icepack_query_tracer_flags( & tr_iage_out=tr_iage, tr_FY_out=tr_FY, tr_iso_out=tr_iso, & - tr_aero_out=tr_aero, tr_pond_out=tr_pond, & - tr_pond_lvl_out=tr_pond_lvl, tr_pond_topo_out=tr_pond_topo) + tr_aero_out=tr_aero ) call icepack_query_tracer_indices( & nt_apnd_out=nt_apnd, nt_hpnd_out=nt_hpnd, nt_ipnd_out=nt_ipnd, & nt_alvl_out=nt_alvl, nt_vlvl_out=nt_vlvl, nt_Tsfc_out=nt_Tsfc, & @@ -387,7 +396,7 @@ subroutine step_therm1 (dt, iblk) enddo endif ! tr_aero - if (tmask(i,j,iblk)) then + if (tmask(i,j,iblk) .or. opmask(i,j,iblk)) then call icepack_step_therm1(dt=dt, & aicen_init = aicen_init (i,j,:,iblk), & @@ -484,6 +493,10 @@ subroutine step_therm1 (dt, iblk) !opt fswthrun_vdf = fswthrun_vdf (i,j,:,iblk),& !opt fswthrun_idr = fswthrun_idr (i,j,:,iblk),& !opt fswthrun_idf = fswthrun_idf (i,j,:,iblk),& +!opt fswthrun_uvrdr = fswthrun_uvrdr (i,j,:,iblk),& +!opt fswthrun_uvrdf = fswthrun_uvrdf (i,j,:,iblk),& +!opt fswthrun_pardr = fswthrun_pardr (i,j,:,iblk),& +!opt fswthrun_pardf = fswthrun_pardf (i,j,:,iblk),& fswabs = fswabs (i,j, iblk), & flwout = flwout (i,j, iblk), & Sswabsn = Sswabsn (i,j,:,:,iblk), & @@ -504,10 +517,16 @@ subroutine step_therm1 (dt, iblk) !opt fswthru_vdf = fswthru_vdf (i,j, iblk), & !opt fswthru_idr = fswthru_idr (i,j, iblk), & !opt fswthru_idf = fswthru_idf (i,j, iblk), & +!opt fswthru_uvrdr = fswthru_uvrdr (i,j, iblk), & +!opt fswthru_uvrdf = fswthru_uvrdf (i,j, iblk), & +!opt fswthru_pardr = fswthru_pardr (i,j, iblk), & +!opt fswthru_pardf = fswthru_pardf (i,j, iblk), & flatn_f = flatn_f (i,j,:,iblk), & fsensn_f = fsensn_f (i,j,:,iblk), & fsurfn_f = fsurfn_f (i,j,:,iblk), & fcondtopn_f = fcondtopn_f (i,j,:,iblk), & +!opt dfsurfdT = dfsurfndTsfc_f(i,j,:,iblk), & +!opt dflatdT = dflatndTsfc_f (i,j,:,iblk), & faero_atm = faero_atm (i,j,1:n_aero,iblk), & faero_ocn = faero_ocn (i,j,1:n_aero,iblk), & !opt fiso_atm = fiso_atm (i,j,:,iblk), & @@ -536,8 +555,18 @@ subroutine step_therm1 (dt, iblk) lmask_s = lmask_s (i,j, iblk), & mlt_onset = mlt_onset (i,j, iblk), & frz_onset = frz_onset (i,j, iblk), & +!opt dpnd_flush = dpnd_flush (i,j, iblk), & +!opt dpnd_expon = dpnd_expon (i,j, iblk), & +!opt dpnd_freebd = dpnd_freebd (i,j, iblk), & +!opt dpnd_initial = dpnd_initial(i,j, iblk), & +!opt dpnd_dlid = dpnd_dlid (i,j, iblk), & +!opt dpnd_flushn = dpnd_flushn (i,j,:,iblk), & +!opt dpnd_exponn = dpnd_exponn (i,j,:,iblk), & +!opt dpnd_freebdn = dpnd_freebdn(i,j,:,iblk), & +!opt dpnd_initialn=dpnd_initialn(i,j,:,iblk), & +!opt dpnd_dlidn = dpnd_dlidn (i,j,:,iblk), & yday=yday) -!opt prescribed_ice=prescribed_ice) +!opt prescribed_ice=prescribed_ice) !----------------------------------------------------------------- ! handle per-category i2x fields, no merging @@ -618,10 +647,10 @@ subroutine step_therm2 (dt, iblk) use ice_domain_size, only: ncat, nilyr, nslyr, nblyr, nfsd use ice_flux, only: fresh, frain, fpond, frzmlt, frazil, frz_onset, & fsalt, Tf, sss, salinz, fhocn, rsiden, wlat, & - meltl, frazil_diag + meltl, frazil_diag, dpnd_melt use ice_flux_bgc, only: flux_bio, faero_ocn, & fiso_ocn, HDO_ocn, H2_16O_ocn, H2_18O_ocn - use ice_grid, only: tmask + use ice_grid, only: tmask, opmask use ice_state, only: aice, aicen, aice0, trcr_depend, & aicen_init, vicen_init, trcrn, vicen, vsnon, & trcr_base, n_trcr_strata, nt_strata @@ -673,7 +702,7 @@ subroutine step_therm2 (dt, iblk) do j = jlo, jhi do i = ilo, ihi - if (tmask(i,j,iblk)) then + if (tmask(i,j,iblk) .or. opmask(i,j,iblk)) then ! significant wave height for FSD if (tr_fsd) & @@ -717,15 +746,15 @@ subroutine step_therm2 (dt, iblk) !opt HDO_ocn = HDO_ocn (i,j, iblk), & !opt H2_16O_ocn = H2_16O_ocn(i,j, iblk), & !opt H2_18O_ocn = H2_18O_ocn(i,j, iblk), & -!opt nfsd = nfsd, & -!opt wave_sig_ht= wave_sig_ht(i,j,iblk), & -!opt wave_spectrum = wave_spectrum(i,j,:,iblk), & -!opt wavefreq = wavefreq(:), & -!opt dwavefreq = dwavefreq(:), & -!opt d_afsd_latg= d_afsd_latg(i,j,:,iblk),& -!opt d_afsd_newi= d_afsd_newi(i,j,:,iblk),& -!opt d_afsd_latm= d_afsd_latm(i,j,:,iblk),& -!opt d_afsd_weld= d_afsd_weld(i,j,:,iblk)) +!opt wave_sig_ht= wave_sig_ht(i,j, iblk), & +!opt wave_spectrum=wave_spectrum(i,j,:,iblk), & +!opt wavefreq = wavefreq (:), & +!opt dwavefreq = dwavefreq (:), & +!opt d_afsd_latg=d_afsd_latg(i,j,:,iblk), & +!opt d_afsd_newi=d_afsd_newi(i,j,:,iblk), & +!opt d_afsd_latm=d_afsd_latm(i,j,:,iblk), & +!opt d_afsd_weld=d_afsd_weld(i,j,:,iblk), & +!opt dpnd_melt = dpnd_melt( i,j, iblk)) ) endif ! tmask @@ -1034,7 +1063,7 @@ subroutine step_dyn_ridge (dt, ndtd, iblk) use ice_domain_size, only: ncat, nilyr, nslyr, n_aero, nblyr use ice_flux, only: & rdg_conv, rdg_shear, dardg1dt, dardg2dt, & - dvirdgdt, opening, fpond, fresh, fhocn, & + dvirdgdt, opening, fpond, fresh, fhocn, dpnd_ridge, & aparticn, krdgn, aredistn, vredistn, dardg1ndt, dardg2ndt, & dvirdgndt, araftn, vraftn, fsalt, Tf use ice_flux_bgc, only: flux_bio, faero_ocn, fiso_ocn @@ -1127,8 +1156,9 @@ subroutine step_dyn_ridge (dt, ndtd, iblk) fsalt = fsalt (i,j, iblk), & first_ice = first_ice(i,j,:,iblk), & flux_bio = flux_bio (i,j,1:nbtrcr,iblk), & - Tf = Tf(i,j,iblk)) - + Tf = Tf (i,j, iblk) & +!opt dpnd_ridge=dpnd_ridge(i,j,iblk)) + ) endif ! tmask enddo ! i @@ -1263,13 +1293,15 @@ subroutine step_radiation (dt, iblk) use ice_arrays_column, only: ffracn, dhsn, & fswsfcn, fswintn, fswpenln, Sswabsn, Iswabsn, & fswthrun, fswthrun_vdr, fswthrun_vdf, fswthrun_idr, fswthrun_idf, & + fswthrun_uvrdr, fswthrun_uvrdf, fswthrun_pardr, fswthrun_pardf, & albicen, albsnon, albpndn, & alvdrn, alidrn, alvdfn, alidfn, apeffn, trcrn_sw, snowfracn, & swgrid, igrid use ice_calendar, only: calendar_type, days_per_year, nextsw_cday, yday, msec use ice_domain_size, only: ncat, n_aero, nilyr, nslyr, n_zaero, n_algae, nblyr - use ice_flux, only: swvdr, swvdf, swidr, swidf, coszen, fsnow - use ice_grid, only: TLAT, TLON, tmask + use ice_flux, only: swvdr, swvdf, swidr, swidf, coszen, fsnow, & + swuvrdr, swuvrdf, swpardr, swpardf + use ice_grid, only: TLAT, TLON, tmask, opmask use ice_state, only: aicen, vicen, vsnon, trcrn use ice_timers, only: ice_timer_start, ice_timer_stop, timer_sw use ice_communicate, only: my_task @@ -1370,7 +1402,7 @@ subroutine step_radiation (dt, iblk) endif enddo - if (tmask(i,j,iblk)) then + if (tmask(i,j,iblk) .or. opmask(i,j,iblk)) then call icepack_step_radiation (dt=dt, & fbri=fbri(:), & @@ -1393,6 +1425,8 @@ subroutine step_radiation (dt, iblk) sec=msec, & swvdr =swvdr (i,j ,iblk), swvdf =swvdf (i,j ,iblk), & swidr =swidr (i,j ,iblk), swidf =swidf (i,j ,iblk), & + swuvrdr =swuvrdr (i,j ,iblk), swuvrdf =swuvrdf (i,j ,iblk), & + swpardr =swpardr (i,j ,iblk), swpardf =swpardf (i,j ,iblk), & coszen =coszen (i,j ,iblk), fsnow =fsnow (i,j ,iblk), & alvdrn =alvdrn (i,j,: ,iblk), alvdfn =alvdfn (i,j,: ,iblk), & alidrn =alidrn (i,j,: ,iblk), alidfn =alidfn (i,j,: ,iblk), & @@ -1402,7 +1436,11 @@ subroutine step_radiation (dt, iblk) !opt fswthrun_vdf =fswthrun_vdf (i,j,: ,iblk), & !opt fswthrun_idr =fswthrun_idr (i,j,: ,iblk), & !opt fswthrun_idf =fswthrun_idf (i,j,: ,iblk), & - fswpenln=fswpenln(i,j,:,:,iblk), & +!opt fswthrun_uvrdr =fswthrun_uvrdr (i,j,: ,iblk), & +!opt fswthrun_uvrdf =fswthrun_uvrdf (i,j,: ,iblk), & +!opt fswthrun_pardr =fswthrun_pardr (i,j,: ,iblk), & +!opt fswthrun_pardf =fswthrun_pardf (i,j,: ,iblk), & + fswpenln =fswpenln (i,j,:,:,iblk), & Sswabsn =Sswabsn (i,j,:,:,iblk), Iswabsn =Iswabsn (i,j,:,:,iblk), & albicen =albicen (i,j,: ,iblk), albsnon =albsnon (i,j,: ,iblk), & albpndn =albpndn (i,j,: ,iblk), apeffn =apeffn (i,j,: ,iblk), & diff --git a/cicecore/drivers/unittest/sumchk/CICE_InitMod.F90 b/cicecore/drivers/unittest/sumchk/CICE_InitMod.F90 index 9e212799e..66a5256e0 100644 --- a/cicecore/drivers/unittest/sumchk/CICE_InitMod.F90 +++ b/cicecore/drivers/unittest/sumchk/CICE_InitMod.F90 @@ -265,11 +265,12 @@ subroutine init_restart use ice_grid, only: tmask use ice_init, only: ice_ic use ice_init_column, only: init_age, init_FY, init_lvl, init_snowtracers, & - init_meltponds_lvl, init_meltponds_topo, & + init_meltponds_lvl, init_meltponds_sealvl, init_meltponds_topo, & init_isotope, init_aerosol, init_hbrine, init_bgc, init_fsd use ice_restart_column, only: restart_age, read_restart_age, & restart_FY, read_restart_FY, restart_lvl, read_restart_lvl, & restart_pond_lvl, read_restart_pond_lvl, & + restart_pond_sealvl, read_restart_pond_sealvl, & restart_pond_topo, read_restart_pond_topo, & restart_snow, read_restart_snow, & restart_fsd, read_restart_fsd, & @@ -286,7 +287,7 @@ subroutine init_restart i, j , & ! horizontal indices iblk ! block index logical(kind=log_kind) :: & - tr_iage, tr_FY, tr_lvl, tr_pond_lvl, & + tr_iage, tr_FY, tr_lvl, tr_pond_lvl, tr_pond_sealvl, & tr_pond_topo, tr_snow, tr_fsd, tr_iso, tr_aero, tr_brine, & skl_bgc, z_tracers integer(kind=int_kind) :: & @@ -307,6 +308,7 @@ subroutine init_restart z_tracers_out=z_tracers) call icepack_query_tracer_flags(tr_iage_out=tr_iage, tr_FY_out=tr_FY, & tr_lvl_out=tr_lvl, tr_pond_lvl_out=tr_pond_lvl, & + tr_pond_sealvl_out = tr_pond_sealvl, & tr_pond_topo_out=tr_pond_topo, tr_aero_out=tr_aero, tr_brine_out=tr_brine, & tr_snow_out=tr_snow, tr_fsd_out=tr_fsd, tr_iso_out=tr_iso) call icepack_query_tracer_indices(nt_alvl_out=nt_alvl, nt_vlvl_out=nt_vlvl, & @@ -335,8 +337,7 @@ subroutine init_restart ! tracers ! ice age tracer if (tr_iage) then - if (trim(runtype) == 'continue') & - restart_age = .true. + if (trim(runtype) == 'continue') restart_age = .true. if (restart_age) then call read_restart_age else @@ -370,8 +371,7 @@ subroutine init_restart endif ! level-ice melt ponds if (tr_pond_lvl) then - if (trim(runtype) == 'continue') & - restart_pond_lvl = .true. + if (trim(runtype) == 'continue') restart_pond_lvl = .true. if (restart_pond_lvl) then call read_restart_pond_lvl else @@ -383,10 +383,23 @@ subroutine init_restart enddo ! iblk endif endif + ! sealvl melt ponds + if (tr_pond_sealvl) then + if (trim(runtype) == 'continue') restart_pond_sealvl = .true. + if (restart_pond_sealvl) then + call read_restart_pond_sealvl + else + do iblk = 1, nblocks + call init_meltponds_sealvl(trcrn(:,:,nt_apnd,:,iblk), & + trcrn(:,:,nt_hpnd,:,iblk), & + trcrn(:,:,nt_ipnd,:,iblk), & + dhsn(:,:,:,iblk)) + enddo ! iblk + endif + endif ! topographic melt ponds if (tr_pond_topo) then - if (trim(runtype) == 'continue') & - restart_pond_topo = .true. + if (trim(runtype) == 'continue') restart_pond_topo = .true. if (restart_pond_topo) then call read_restart_pond_topo else @@ -448,10 +461,8 @@ subroutine init_restart endif if (trim(runtype) == 'continue') then - if (tr_brine) & - restart_hbrine = .true. - if (skl_bgc .or. z_tracers) & - restart_bgc = .true. + if (tr_brine) restart_hbrine = .true. + if (skl_bgc .or. z_tracers) restart_bgc = .true. endif if (tr_brine .or. skl_bgc) then ! brine height tracer diff --git a/cicecore/shared/ice_arrays_column.F90 b/cicecore/shared/ice_arrays_column.F90 index 337828d60..38f3ee0f7 100644 --- a/cicecore/shared/ice_arrays_column.F90 +++ b/cicecore/shared/ice_arrays_column.F90 @@ -112,7 +112,11 @@ module ice_arrays_column fswthrun_vdf , & ! vis dif SW through ice to ocean (W/m^2) fswthrun_idr , & ! nir dir SW through ice to ocean (W/m^2) fswthrun_idf , & ! nir dif SW through ice to ocean (W/m^2) - fswintn ! SW absorbed in ice interior, below surface (W m-2) + fswthrun_uvrdr,& ! vis uvr dir SW through ice to ocean (W/m^2) + fswthrun_uvrdf,& ! vis uvr dif SW through ice to ocean (W/m^2) + fswthrun_pardr,& ! vis par dir SW through ice to ocean (W/m^2) + fswthrun_pardf,& ! vis par dif SW through ice to ocean (W/m^2) + fswintn ! SW absorbed in ice interior, below surface (W m-2) real (kind=dbl_kind), dimension (:,:,:,:,:), allocatable, public :: & fswpenln ! visible SW entering ice layers (W m-2) @@ -320,6 +324,10 @@ subroutine alloc_arrays_column fswthrun_vdf (nx_block,ny_block,ncat,max_blocks), & ! vis dif SW through ice to ocean (W/m^2) fswthrun_idr (nx_block,ny_block,ncat,max_blocks), & ! nir dir SW through ice to ocean (W/m^2) fswthrun_idf (nx_block,ny_block,ncat,max_blocks), & ! nir dif SW through ice to ocean (W/m^2) + fswthrun_uvrdr(nx_block,ny_block,ncat,max_blocks), & ! vis uvr dir SW uhrough ice to ocean (W/m^2) + fswthrun_uvrdf(nx_block,ny_block,ncat,max_blocks), & ! vis uvr dif SW through ice to ocean (W/m^2) + fswthrun_pardr(nx_block,ny_block,ncat,max_blocks), & ! vis par dir SW through ice to ocean (W/m^2) + fswthrun_pardf(nx_block,ny_block,ncat,max_blocks), & ! vis par dif SW through ice to ocean (W/m^2) fswintn (nx_block,ny_block,ncat,max_blocks), & ! SW absorbed in ice interior, below surface (W m-2) first_ice_real & (nx_block,ny_block,ncat,max_blocks), & ! .true. = c1, .false. = c0 diff --git a/cicecore/shared/ice_calendar.F90 b/cicecore/shared/ice_calendar.F90 index 17f18edb2..829e78218 100644 --- a/cicecore/shared/ice_calendar.F90 +++ b/cicecore/shared/ice_calendar.F90 @@ -57,7 +57,8 @@ module ice_calendar ! PUBLIC character(len=*), public, parameter :: & - ice_calendar_gregorian = 'Gregorian', & ! calendar name, actually proleptic gregorian here + ice_calendar_proleptic_gregorian = 'proleptic_gregorian' , & ! calendar name + ice_calendar_gregorian = 'Gregorian', & ! actually proleptic gregorian here, legacy name ice_calendar_noleap = 'NO_LEAP', & ! 365 day per year calendar ice_calendar_360day = '360day' ! 360 day calendar with 30 days per month @@ -136,8 +137,10 @@ module ice_calendar dumpfreq_base(max_nstrm), & ! restart frequency basetime ('zero', 'init') histfreq_base(max_nstrm), & ! history frequency basetime ('zero', 'init') calendar_type ! define calendar type - data dumpfreq_base / 'init', 'init', 'init', 'init', 'init' / - data histfreq_base / 'zero', 'zero', 'zero', 'zero', 'zero' / + + ! This is needed for the calendar unit tester + data dumpfreq_base / max_nstrm*'init' / + data histfreq_base / max_nstrm*'zero' / ! PRIVATE @@ -210,13 +213,13 @@ subroutine init_calendar ! this avoids using it uninitialzed in 'calendar' below nstreams = 0 -#ifdef CESMCOUPLED +#if defined (CESMCOUPLED) || defined (GEOSCOUPLED) ! calendar_type set by coupling #else calendar_type = '' if (use_leap_years) then if (days_per_year == 365) then - calendar_type = trim(ice_calendar_gregorian) + calendar_type = trim(ice_calendar_proleptic_gregorian) else call abort_ice(subname//'ERROR: use_leap_years is true, must set days_per_year to 365') endif @@ -231,6 +234,14 @@ subroutine init_calendar endif #endif + ! prevent coupling setting invalid calendars + if (trim(calendar_type) /= ice_calendar_gregorian .and. & + trim(calendar_type) /= ice_calendar_proleptic_gregorian .and. & + trim(calendar_type) /= ice_calendar_noleap .and. & + trim(calendar_type) /= ice_calendar_360day) then + call abort_ice(subname//'Error: '//trim(calendar_type)//' not supported') + endif + call set_calendar(myear) call calendar() @@ -399,7 +410,9 @@ subroutine calendar() !--- compute other stuff -#ifndef CESMCOUPLED +#if defined (CESMCOUPLED) || defined (GEOSCOUPLED) + ! skip setting stop_now and dump_last write_restart +#else if (istep >= npt+1) stop_now = 1 if (istep == npt .and. dump_last) write_restart = 1 ! last timestep #endif @@ -440,6 +453,9 @@ subroutine calendar() if (mod(istep1, histfreq_n(ns))==0) & write_history(ns)=.true. endif + case ("g") + ! grid file + write_history(ns)=.true. end select enddo @@ -692,7 +708,8 @@ subroutine compute_calendar_data(ayear,adaymo,adaycal,adayyr) call abort_ice(subname//'ERROR: in argument sizes') endif - if (trim(calendar_type) == trim(ice_calendar_gregorian)) then + if (trim(calendar_type) == ice_calendar_gregorian .or. & + trim(calendar_type) == ice_calendar_proleptic_gregorian ) then isleap = .false. ! not a leap year if (mod(ayear, 4) == 0) isleap = .true. @@ -754,7 +771,8 @@ integer function compute_elapsed_days(ayear,amonth,aday) ! compute days from year 0000-01-01 to year-01-01 ! don't loop thru years for performance reasons - if (trim(calendar_type) == trim(ice_calendar_gregorian)) then + if (trim(calendar_type) == ice_calendar_gregorian .or. & + trim(calendar_type) == ice_calendar_proleptic_gregorian) then if (lyear == 0) then ced_nday = 0 else diff --git a/cicecore/shared/ice_domain_size.F90 b/cicecore/shared/ice_domain_size.F90 index b0ac9b036..a2826f6e1 100644 --- a/cicecore/shared/ice_domain_size.F90 +++ b/cicecore/shared/ice_domain_size.F90 @@ -45,7 +45,8 @@ module ice_domain_size nfreq ! number of wave frequencies integer (kind=int_kind), public, parameter :: & - max_nstrm = 5 ! max number of history output streams + max_nstrm = 6 ! max number of history output streams + ! 5 streams plus 1 one-time grid output file !======================================================================= diff --git a/cicecore/shared/ice_init_column.F90 b/cicecore/shared/ice_init_column.F90 index 73f11a93b..5f04a49d6 100644 --- a/cicecore/shared/ice_init_column.F90 +++ b/cicecore/shared/ice_init_column.F90 @@ -44,21 +44,23 @@ module ice_init_column private public :: init_thermo_vertical, init_shortwave, & init_age, init_FY, init_lvl, init_fsd, & - init_meltponds_lvl, init_meltponds_topo, & + init_meltponds_lvl, init_meltponds_topo, init_meltponds_sealvl, & init_aerosol, init_bgc, init_hbrine, init_zbgc, input_zbgc, & count_tracers, init_isotope, init_snowtracers ! namelist parameters needed locally real (kind=dbl_kind) :: & - tau_min , tau_max , & - nitratetype , ammoniumtype , silicatetype, & - dmspptype , dmspdtype , humtype + tau_min , tau_max , & + nitratetype , ammoniumtype , silicatetype, & + dmspptype , dmspdtype , humtype + + real (kind=dbl_kind) :: & + grid_oS, l_skS ! deprecated with zsalinity real (kind=dbl_kind) :: & grid_o, l_sk, grid_o_t, initbio_frac, & - frazil_scav, grid_oS, l_skS, & - phi_snow, & + frazil_scav, 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 , & @@ -163,6 +165,7 @@ subroutine init_shortwave use ice_arrays_column, only: fswpenln, Iswabsn, Sswabsn, albicen, & albsnon, alvdrn, alidrn, alvdfn, alidfn, fswsfcn, & fswthrun, fswthrun_vdr, fswthrun_vdf, fswthrun_idr, fswthrun_idf, & + fswthrun_uvrdr, fswthrun_uvrdf, fswthrun_pardr, fswthrun_pardf, & fswintn, albpndn, apeffn, trcrn_sw, dhsn, ffracn, snowfracn, & swgrid, igrid use ice_blocks, only: block, get_block @@ -173,8 +176,9 @@ subroutine init_shortwave use ice_flux, only: alvdf, alidf, alvdr, alidr, & alvdr_ai, alidr_ai, alvdf_ai, alidf_ai, & swvdr, swvdf, swidr, swidf, scale_factor, snowfrac, & + swuvrdr, swuvrdf, swpardr, swpardf, & albice, albsno, albpnd, apeff_ai, coszen, fsnow - use ice_grid, only: tlat, tlon, tmask + use ice_grid, only: tlat, tlon, tmask, opmask use ice_restart_shared, only: restart, runtype use ice_state, only: aicen, vicen, vsnon, trcrn @@ -285,6 +289,11 @@ subroutine init_shortwave alidrn(i,j,n,iblk) = c0 alvdfn(i,j,n,iblk) = c0 alidfn(i,j,n,iblk) = c0 + albpndn(i,j,n,iblk) = c0 + albicen(i,j,n,iblk) = c0 + albsnon(i,j,n,iblk) = c0 + apeffn(i,j,n,iblk) = c0 + snowfracn(i,j,n,iblk) = c0 fswsfcn(i,j,n,iblk) = c0 fswintn(i,j,n,iblk) = c0 fswthrun(i,j,n,iblk) = c0 @@ -292,6 +301,10 @@ subroutine init_shortwave fswthrun_vdf(i,j,n,iblk) = c0 fswthrun_idr(i,j,n,iblk) = c0 fswthrun_idf(i,j,n,iblk) = c0 + fswthrun_uvrdr(i,j,n,iblk) = c0 + fswthrun_uvrdf(i,j,n,iblk) = c0 + fswthrun_pardr(i,j,n,iblk) = c0 + fswthrun_pardf(i,j,n,iblk) = c0 enddo ! ncat enddo @@ -301,7 +314,9 @@ subroutine init_shortwave if (shortwave(1:4) == 'dEdd') then ! delta Eddington -#ifndef CESMCOUPLED +#if defined (CESMCOUPLED) || defined (GEOSCOUPLED) + ! initialized externally +#else ! initialize orbital parameters ! These come from the driver in the coupled model. call icepack_init_orbit() @@ -323,7 +338,7 @@ subroutine init_shortwave endif enddo - if (tmask(i,j,iblk)) then + if (tmask(i,j,iblk) .or. opmask(i,j,iblk)) then call icepack_step_radiation (dt=dt, & fbri=fbri(:), & aicen=aicen(i,j,:,iblk), & @@ -345,6 +360,8 @@ subroutine init_shortwave sec=msec, & swvdr=swvdr(i,j,iblk), swvdf=swvdf(i,j,iblk),& swidr=swidr(i,j,iblk), swidf=swidf(i,j,iblk),& + swuvrdr=swuvrdr(i,j,iblk), swuvrdf=swuvrdf (i,j,iblk), & + swpardr=swpardr(i,j,iblk), swpardf=swpardf (i,j,iblk), & coszen=coszen(i,j,iblk), fsnow=fsnow(i,j,iblk),& alvdrn=alvdrn(i,j,:,iblk), alvdfn=alvdfn(i,j,:,iblk), & alidrn=alidrn(i,j,:,iblk), alidfn=alidfn(i,j,:,iblk), & @@ -354,6 +371,10 @@ subroutine init_shortwave fswthrun_vdf=fswthrun_vdf(i,j,:,iblk), & fswthrun_idr=fswthrun_idr(i,j,:,iblk), & fswthrun_idf=fswthrun_idf(i,j,:,iblk), & + fswthrun_uvrdr=fswthrun_uvrdr (i,j,: ,iblk), & + fswthrun_uvrdf=fswthrun_uvrdf (i,j,: ,iblk), & + fswthrun_pardr=fswthrun_pardr (i,j,: ,iblk), & + fswthrun_pardf=fswthrun_pardf (i,j,: ,iblk), & fswpenln=fswpenln(i,j,:,:,iblk), & Sswabsn=Sswabsn(i,j,:,:,iblk), Iswabsn=Iswabsn(i,j,:,:,iblk), & albicen=albicen(i,j,:,iblk), albsnon=albsnon(i,j,:,iblk), & @@ -536,6 +557,27 @@ end subroutine init_meltponds_lvl !======================================================================= +! Initialize melt ponds. + + subroutine init_meltponds_sealvl(apnd, hpnd, ipnd, dhsn) + + real(kind=dbl_kind), dimension(:,:,:), intent(out) :: & + apnd , & ! melt pond area fraction + hpnd , & ! melt pond depth + ipnd , & ! melt pond refrozen lid thickness + dhsn ! depth difference for snow on sea ice and pond ice + + character(len=*),parameter :: subname='(init_meltponds_sealvl)' + + apnd(:,:,:) = c0 + hpnd(:,:,:) = c0 + ipnd(:,:,:) = c0 + dhsn(:,:,:) = c0 + + end subroutine init_meltponds_sealvl + +!======================================================================= + ! Initialize melt ponds. subroutine init_meltponds_topo(apnd, hpnd, ipnd) @@ -946,8 +988,11 @@ subroutine input_zbgc ktherm logical (kind=log_kind) :: & - solve_zsal, skl_bgc, z_tracers, scale_bgc, solve_zbgc, dEdd_algae, & - modal_aero, restart_zsal + skl_bgc, z_tracers, scale_bgc, solve_zbgc, dEdd_algae, & + modal_aero + + logical (kind=log_kind) :: & + solve_zsal, restart_zsal ! deprecated with zsalinity character (char_len) :: & bgc_flux_type @@ -1058,7 +1103,7 @@ subroutine input_zbgc ! z biology parameters grid_o = 0.006 ! for bottom flux grid_o_t = 0.006 ! for top flux - l_sk = 2.0_dbl_kind ! characteristic diffusive scale (m) + l_sk = 2.0_dbl_kind ! characteristic diffusive scale brine (m) initbio_frac = c1 ! fraction of ocean trcr concentration in bio trcrs frazil_scav = 0.8_dbl_kind ! increase in initial bio tracer from ocean scavenging ratio_Si2N_diatoms = 1.8_dbl_kind ! algal Si to N (mol/mol) @@ -1179,10 +1224,6 @@ subroutine input_zbgc F_abs_chl_phaeo = 5.0 ratio_C2N_proteins = 5.0_dbl_kind ! ratio of C to N in proteins (mol/mol) - ! z salinity parameters - grid_oS = c0 ! for bottom flux - l_skS = 0.028_dbl_kind ! characteristic diffusive scale (m) - !----------------------------------------------------------------- ! read from input file !----------------------------------------------------------------- @@ -1220,8 +1261,6 @@ subroutine input_zbgc call broadcast_scalar(restart_hbrine, master_task) call broadcast_scalar(phi_snow, master_task) - call broadcast_scalar(grid_oS, master_task) - call broadcast_scalar(l_skS, master_task) call broadcast_scalar(solve_zbgc, master_task) call broadcast_scalar(skl_bgc, master_task) @@ -1377,9 +1416,9 @@ subroutine input_zbgc restart_hbrine = .false. endif - if (solve_zsal) then + if (solve_zsal .or. restart_zsal) then if (my_task == master_task) then - write(nu_diag,*) subname,' ERROR: solve_zsal=T deprecated' + write(nu_diag,*) subname,' ERROR: solve_zsal=T, restart_zsal=T deprecated' endif abort_flag = 101 endif @@ -1574,10 +1613,6 @@ subroutine input_zbgc write(nu_diag,1010) ' restart_hbrine = ', restart_hbrine write(nu_diag,1005) ' phi_snow = ', phi_snow endif - write(nu_diag,1010) ' solve_zsal (deprecated) = ', solve_zsal - write(nu_diag,* ) ' WARNING: zsalinity has been deprecated. Namelists and interfaces' - write(nu_diag,* ) ' will be removed in a future version' - write(nu_diag,1010) ' skl_bgc = ', skl_bgc write(nu_diag,1010) ' restart_bgc = ', restart_bgc write(nu_diag,1010) ' tr_bgc_N = ', tr_bgc_N @@ -1646,7 +1681,7 @@ subroutine input_zbgc dEdd_algae_in=dEdd_algae, solve_zbgc_in=solve_zbgc, & bgc_flux_type_in=bgc_flux_type, grid_o_in=grid_o, l_sk_in=l_sk, & initbio_frac_in=initbio_frac, frazil_scav_in=frazil_scav, & - grid_oS_in=grid_oS, l_skS_in=l_skS, phi_snow_in=phi_snow, & + phi_snow_in=phi_snow, & algal_vel_in=algal_vel, R_dFe2dust_in=R_dFe2dust, & dustFe_sol_in=dustFe_sol, T_max_in=T_max, fsal_in=fsal, & op_dep_min_in=op_dep_min, fr_graze_s_in=fr_graze_s, & @@ -1792,7 +1827,7 @@ subroutine count_tracers integer (kind=int_kind) :: ntrcr logical (kind=log_kind) :: tr_iage, tr_FY, tr_lvl, tr_pond, tr_aero, tr_fsd logical (kind=log_kind) :: tr_snow - logical (kind=log_kind) :: tr_iso, tr_pond_lvl, tr_pond_topo + logical (kind=log_kind) :: tr_iso, tr_pond_lvl, tr_pond_topo, tr_pond_sealvl integer (kind=int_kind) :: nt_Tsfc, nt_sice, nt_qice, nt_qsno, nt_iage, nt_FY integer (kind=int_kind) :: nt_alvl, nt_vlvl, nt_apnd, nt_hpnd, nt_ipnd, nt_aero integer (kind=int_kind) :: nt_fsd, nt_isosno, nt_isoice @@ -1876,7 +1911,7 @@ subroutine count_tracers call icepack_query_tracer_flags(tr_iage_out=tr_iage, tr_FY_out=tr_FY, & tr_lvl_out=tr_lvl, tr_aero_out=tr_aero, tr_pond_out=tr_pond, & - tr_pond_lvl_out=tr_pond_lvl, & + tr_pond_lvl_out=tr_pond_lvl, tr_pond_sealvl_out=tr_pond_sealvl, & tr_pond_topo_out=tr_pond_topo, tr_brine_out=tr_brine, tr_fsd_out=tr_fsd, & tr_snow_out=tr_snow, tr_iso_out=tr_iso, & tr_bgc_Nit_out=tr_bgc_Nit, tr_bgc_Am_out =tr_bgc_Am, tr_bgc_Sil_out=tr_bgc_Sil, & @@ -1935,6 +1970,10 @@ subroutine count_tracers ntrcr = ntrcr + 1 ! refrozen pond ice lid thickness nt_ipnd = ntrcr ! on level-ice ponds (if frzpnd='hlid') endif + if (tr_pond_sealvl) then + ntrcr = ntrcr + 1 ! refrozen pond ice lid thickness + nt_ipnd = ntrcr ! on sea level ponds (if frzpnd='hlid') + endif if (tr_pond_topo) then ntrcr = ntrcr + 1 ! nt_ipnd = ntrcr ! refrozen pond ice lid thickness diff --git a/cicecore/shared/ice_restart_column.F90 b/cicecore/shared/ice_restart_column.F90 index 2c5b18c36..6d1bf2017 100644 --- a/cicecore/shared/ice_restart_column.F90 +++ b/cicecore/shared/ice_restart_column.F90 @@ -30,6 +30,7 @@ module ice_restart_column write_restart_FY, read_restart_FY, & write_restart_lvl, read_restart_lvl, & write_restart_pond_lvl, read_restart_pond_lvl, & + write_restart_pond_sealvl, read_restart_pond_sealvl, & write_restart_pond_topo, read_restart_pond_topo, & write_restart_snow, read_restart_snow, & write_restart_fsd, read_restart_fsd, & @@ -43,6 +44,7 @@ module ice_restart_column restart_FY , & ! if .true., read FY tracer restart file restart_lvl , & ! if .true., read lvl tracer restart file restart_pond_lvl , & ! if .true., read meltponds restart file + restart_pond_sealvl , & ! if .true., read meltponds restart file restart_pond_topo, & ! if .true., read meltponds restart file restart_snow , & ! if .true., read snow tracer restart file restart_fsd , & ! if .true., read floe size restart file @@ -415,6 +417,95 @@ end subroutine read_restart_pond_topo !======================================================================= +! Dumps all values needed for restarting +! +! authors Elizabeth C. Hunke, LANL +! David A. Bailey, NCAR + + subroutine write_restart_pond_sealvl() + + use ice_arrays_column, only: dhsn, ffracn + use ice_fileunits, only: nu_dump_pond + use ice_flux, only: fsnow + use ice_state, only: trcrn + + ! local variables + + logical (kind=log_kind) :: diag + integer (kind=int_kind) :: nt_apnd, nt_hpnd, nt_ipnd + character(len=*),parameter :: subname='(write_restart_pond_sealvl)' + + call icepack_query_tracer_indices(nt_apnd_out=nt_apnd, nt_hpnd_out=nt_hpnd, & + nt_ipnd_out=nt_ipnd) + call icepack_warnings_flush(nu_diag) + if (icepack_warnings_aborted()) call abort_ice(error_message=subname, & + file=__FILE__, line=__LINE__) + + diag = .true. + + call write_restart_field(nu_dump_pond,0,trcrn(:,:,nt_apnd,:,:),'ruf8', & + 'apnd',ncat,diag) + call write_restart_field(nu_dump_pond,0,trcrn(:,:,nt_hpnd,:,:),'ruf8', & + 'hpnd',ncat,diag) + call write_restart_field(nu_dump_pond,0,trcrn(:,:,nt_ipnd,:,:),'ruf8', & + 'ipnd',ncat,diag) + call write_restart_field(nu_dump_pond,0, fsnow(:,:, :),'ruf8', & + 'fsnow',1,diag) + call write_restart_field(nu_dump_pond,0, dhsn(:,:, :,:),'ruf8', & + 'dhs',ncat,diag) + call write_restart_field(nu_dump_pond,0,ffracn(:,:, :,:),'ruf8', & + 'ffrac',ncat,diag) + + end subroutine write_restart_pond_sealvl + +!======================================================================= + +! Reads all values needed for a meltpond volume restart +! +! authors Elizabeth C. Hunke, LANL +! David A. Bailey, NCAR + + subroutine read_restart_pond_sealvl() + + use ice_arrays_column, only: dhsn, ffracn + use ice_fileunits, only: nu_restart_pond + use ice_flux, only: fsnow + use ice_state, only: trcrn + + ! local variables + + logical (kind=log_kind) :: & + diag + integer (kind=int_kind) :: nt_apnd, nt_hpnd, nt_ipnd + character(len=*),parameter :: subname='(read_restart_pond_sealvl)' + + call icepack_query_tracer_indices(nt_apnd_out=nt_apnd, nt_hpnd_out=nt_hpnd, & + nt_ipnd_out=nt_ipnd) + call icepack_warnings_flush(nu_diag) + if (icepack_warnings_aborted()) call abort_ice(error_message=subname, & + file=__FILE__, line=__LINE__) + + diag = .true. + + if (my_task == master_task) write(nu_diag,*) subname,'min/max sea level ponds' + + call read_restart_field(nu_restart_pond,0,trcrn(:,:,nt_apnd,:,:),'ruf8', & + 'apnd',ncat,diag,field_loc_center,field_type_scalar) + call read_restart_field(nu_restart_pond,0,trcrn(:,:,nt_hpnd,:,:),'ruf8', & + 'hpnd',ncat,diag,field_loc_center,field_type_scalar) + call read_restart_field(nu_restart_pond,0,trcrn(:,:,nt_ipnd,:,:),'ruf8', & + 'ipnd',ncat,diag,field_loc_center,field_type_scalar) + call read_restart_field(nu_restart_pond,0, fsnow(:,:, :),'ruf8', & + 'fsnow',1,diag,field_loc_center,field_type_scalar) + call read_restart_field(nu_restart_pond,0, dhsn(:,:, :,:),'ruf8', & + 'dhs',ncat,diag,field_loc_center,field_type_scalar) + call read_restart_field(nu_restart_pond,0,ffracn(:,:, :,:),'ruf8', & + 'ffrac',ncat,diag,field_loc_center,field_type_scalar) + + end subroutine read_restart_pond_sealvl + +!======================================================================= + ! Dumps all values needed for restarting snow redistribution/metamorphism ! author Elizabeth C. Hunke, LANL diff --git a/cicecore/version.txt b/cicecore/version.txt index b5b0c4a76..0a244794e 100644 --- a/cicecore/version.txt +++ b/cicecore/version.txt @@ -1 +1 @@ -CICE 6.6.0 +CICE 6.6.1 diff --git a/configuration/scripts/cice.batch.csh b/configuration/scripts/cice.batch.csh index bb2edc17e..220313bfa 100755 --- a/configuration/scripts/cice.batch.csh +++ b/configuration/scripts/cice.batch.csh @@ -137,6 +137,23 @@ cat >> ${jobfile} << EOFB ###PBS -m be EOFB +else if (${ICE_MACHINE} =~ blueback*) then +if (${runlength} > 0) set queue = "standard" +cat >> ${jobfile} << EOFB +#SBATCH --job-name=${ICE_CASENAME} +#SBATCH --account=${acct} +#SBATCH --qos=${queue} +#SBATCH --time=${batchtime} +#SBATCH --nodes=${nnodes} +#SBATCH --ntasks=${ntasks} +#SBATCH --ntasks-per-node=${taskpernode} +#SBATCH --constraint standard +###SBATCH -e filename +###SBATCH -o filename +###SBATCH --mail-type FAIL +###SBATCH --mail-user username@domain.com +EOFB + else if (${ICE_MACHINE} =~ narwhal*) then if (${runlength} <= 0) then set batchtime = "00:29:59" @@ -349,13 +366,30 @@ cat >> ${jobfile} << EOFB #PBS -l walltime=${batchtime} EOFB -else if (${ICE_MACHINE} =~ gaea*) then +else if (${ICE_MACHINE} =~ gaeac5*) then cat >> ${jobfile} << EOFB #SBATCH -J ${ICE_CASENAME} #SBATCH --partition=batch #SBATCH --qos=${queue} #SBATCH --account=nggps_emc -#SBATCH --clusters=c3 +#SBATCH --clusters=c5 +#SBATCH --time=${batchtime} +#SBATCH --nodes=${nnodes} +#SBATCH --ntasks-per-node=${taskpernodelimit} +#SBATCH --cpus-per-task=${nthrds} +#SBATCH -e slurm%j.err +#SBATCH -o slurm%j.out +##SBATCH --mail-type FAIL +##SBATCH --mail-user=xxx@noaa.gov +EOFB + +else if (${ICE_MACHINE} =~ gaeac6*) then +cat >> ${jobfile} << EOFB +#SBATCH -J ${ICE_CASENAME} +#SBATCH --partition=batch +#SBATCH --qos=${queue} +#SBATCH --account=sfs_emc +#SBATCH --clusters=c6 #SBATCH --time=${batchtime} #SBATCH --nodes=${nnodes} #SBATCH --ntasks-per-node=${taskpernodelimit} @@ -382,6 +416,34 @@ cat >> ${jobfile} << EOFB ##SBATCH --mail-user=xxx@noaa.gov EOFB +else if (${ICE_MACHINE} =~ ursa*) then +cat >> ${jobfile} << EOFB +#SBATCH -J ${ICE_CASENAME} +#SBATCH --partition=u1-compute +#SBATCH --qos=${queue} +#SBATCH -A ${acct} +#SBATCH --time=${batchtime} +#SBATCH --nodes=${nnodes} +#SBATCH --ntasks-per-node=${taskpernodelimit} +#SBATCH --cpus-per-task=${nthrds} +#SBATCH -e slurm%j.err +#SBATCH -o slurm%j.out +##SBATCH --mail-type FAIL +##SBATCH --mail-user=xxx@noaa.gov +EOFB + +else if (${ICE_MACHINE} =~ wcoss2*) then +cat >> ${jobfile} << EOFB +#PBS -N ${ICE_CASENAME} +#PBS -o ${ICE_CASENAME} +#PBS -j oe +#PBS -A ICE-DEV +#PBS -l walltime=${batchtime} +##PBS -l select=${nnodes}:ncpus=${taskpernodelimit} +##PBS -l select=${nnodes}:ncpus=${corespernode}:mpiprocs=${taskpernodelimit}:ompthreads=${nthrds} +#PBS -l place=vscatter,select=${nnodes}:ncpus=${corespernode}:mpiprocs=${corespernode}:mem=256M +EOFB + else if (${ICE_MACHINE} =~ orion*) then cat >> ${jobfile} << EOFB #SBATCH -J ${ICE_CASENAME} diff --git a/configuration/scripts/cice.launch.csh b/configuration/scripts/cice.launch.csh index f8eb0a5d2..bc68a7ce1 100755 --- a/configuration/scripts/cice.launch.csh +++ b/configuration/scripts/cice.launch.csh @@ -127,15 +127,15 @@ endif endif #======= -else if (${ICE_MACHCOMP} =~ cori* || ${ICE_MACHCOMP} =~ perlmutter*) then +else if (${ICE_MACHCOMP} =~ cori* || ${ICE_MACHCOMP} =~ perlmutter* || ${ICE_MACHCOMP} =~ blueback*) then if (${ICE_COMMDIR} =~ serial*) then cat >> ${jobfile} << EOFR #./cice >&! \$ICE_RUNLOG_FILE -srun --cpu-bind=cores ./cice >&! \$ICE_RUNLOG_FILE +srun --cpu-bind=cores --kill-on-bad-exit ./cice >&! \$ICE_RUNLOG_FILE EOFR else cat >> ${jobfile} << EOFR -srun --cpu-bind=cores ./cice >&! \$ICE_RUNLOG_FILE +srun --cpu-bind=cores -n ${ntasks} -c ${nthrds} --kill-on-bad-exit ./cice >&! \$ICE_RUNLOG_FILE EOFR endif @@ -163,6 +163,18 @@ srun -n ${ntasks} -c ${nthrds} ./cice >&! \$ICE_RUNLOG_FILE EOFR endif +#======= +else if (${ICE_MACHCOMP} =~ discover*) then +if (${ICE_COMMDIR} =~ serial*) then +cat >> ${jobfile} << EOFR +./cice >&! \$ICE_RUNLOG_FILE +EOFR +else +cat >> ${jobfile} << EOFR +mpirun -np ${ntasks} ./cice >&! \$ICE_RUNLOG_FILE +EOFR +endif + #======= else if (${ICE_MACHCOMP} =~ fram*) then if (${ICE_COMMDIR} =~ serial*) then @@ -267,7 +279,7 @@ srun -n ${ntasks} -c ${nthrds} ./cice >&! \$ICE_RUNLOG_FILE EOFR #======= -else if (${ICE_MACHCOMP} =~ hera*) then +else if (${ICE_MACHCOMP} =~ hera* || ${ICE_MACHCOMP} =~ ursa*) then cat >> ${jobfile} << EOFR srun -n ${ntasks} -c ${nthrds} ./cice >&! \$ICE_RUNLOG_FILE EOFR diff --git a/configuration/scripts/ice_in b/configuration/scripts/ice_in index b3fc5404d..776f9f966 100644 --- a/configuration/scripts/ice_in +++ b/configuration/scripts/ice_in @@ -86,6 +86,7 @@ bathymetry_format = 'default' use_bathymetry = .false. gridcpl_file = 'unknown_gridcpl_file' + grid_outfile = .false. kcatbound = 0 dxrect = 30.e5 dyrect = 30.e5 @@ -122,6 +123,8 @@ restart_pond_topo = .false. tr_pond_lvl = .true. restart_pond_lvl = .false. + tr_pond_sealvl = .false. + restart_pond_sealvl = .false. tr_snow = .false. restart_snow = .false. tr_iso = .false. @@ -147,6 +150,7 @@ Tliquidus_max = -0.1d0 hfrazilmin = 0.05d0 floediam = 300.0d0 + tscale_pnd_drain = 10.0d0 / &dynamics_nml @@ -197,6 +201,8 @@ reltol_pgmres = 1e-6 algo_nonlin = 'picard' use_mean_vrel = .true. + dyn_area_min = 0.001d0 + dyn_mass_min = 0.01d0 / &shortwave_nml @@ -220,6 +226,7 @@ / &ponds_nml + apnd_sl = 0.27d0 hp1 = 0.01 hs0 = 0. hs1 = 0.03 @@ -299,6 +306,8 @@ ocn_data_format = 'bin' ocn_data_dir = '/unknown_ocn_data_dir' oceanmixed_file = 'unknown_oceanmixed_file' + semi_implicit_Tsfc = .false. + vapor_flux_correction = .false. / &domain_nml @@ -334,8 +343,6 @@ restore_bgc = .false. restart_bgc = .false. scale_bgc = .false. - solve_zsal = .false. - restart_zsal = .false. tr_bgc_Nit = .false. tr_bgc_C = .false. tr_bgc_chl = .false. @@ -349,8 +356,6 @@ grid_o = 0.006 grid_o_t = 0.006 l_sk = 2.0 - grid_oS = 0.0 - l_skS = 0.028 phi_snow = -1.0 initbio_frac = 1.0 frazil_scav = 0.8 @@ -651,10 +656,22 @@ f_apondn = 'x' f_apeffn = 'x' f_hpondn = 'x' + f_dpnd_flushn = 'x' + f_dpnd_exponn = 'x' + f_dpnd_freebdn = 'x' + f_dpnd_initialn= 'x' + f_dpnd_dlidn = 'x' f_apond = 'm' f_hpond = 'm' f_ipond = 'm' f_apeff = 'm' + f_dpnd_flush = 'x' + f_dpnd_expon = 'x' + f_dpnd_freebd = 'x' + f_dpnd_initial = 'x' + f_dpnd_dlid = 'x' + f_dpnd_melt = 'x' + f_dpnd_ridge = 'x' f_apond_ai = 'm' f_hpond_ai = 'm' f_ipond_ai = 'm' diff --git a/configuration/scripts/machines/Macros.blueback_aocc b/configuration/scripts/machines/Macros.blueback_aocc new file mode 100644 index 000000000..194bb8736 --- /dev/null +++ b/configuration/scripts/machines/Macros.blueback_aocc @@ -0,0 +1,59 @@ +#============================================================================== +# Macros file for NavyDSRC blueback, aocc compiler +#============================================================================== + +CPP := ftn -E +CPPDEFS := -DFORTRANUNDERSCORE -DNO_R16 ${ICE_CPPDEFS} +CFLAGS := -c -O2 + +FIXEDFLAGS := -ffixed-form +FREEFLAGS := -ffree-form +FFLAGS := -byteswapio +FFLAGS_NOOPT:= -O0 + +ifeq ($(ICE_BLDDEBUG), true) + FFLAGS += -O0 -g -fsanitize=integer-divide-by-zero,float-divide-by-zero,bounds +else + FFLAGS += -O2 +endif + +SCC := cc +SFC := ftn +MPICC := cc +MPIFC := ftn + +ifeq ($(ICE_COMMDIR), mpi) + FC := $(MPIFC) + CC := $(MPICC) +else + FC := $(SFC) + CC := $(SCC) +endif +LD:= $(FC) + +# defined by module +#NETCDF_PATH := $(NETCDF) +#PNETCDF_PATH := $(PNETCDF) +#PNETCDF_PATH := /glade/apps/opt/pnetcdf/1.3.0/intel/default +#LAPACK_LIBDIR := /glade/apps/opt/lapack/3.4.2/intel/12.1.5/lib + +#PIO_CONFIG_OPTS:= --enable-filesystem-hints=gpfs + +INCLDIR := $(INCLDIR) +#INCLDIR += -I$(NETCDF_PATH)/include + +#LIB_NETCDF := $(NETCDF_PATH)/lib +#LIB_PNETCDF := $(PNETCDF_PATH)/lib +#LIB_MPI := $(IMPILIBDIR) +#SLIBS := -L$(LIB_NETCDF) -lnetcdf -lnetcdff + +ifeq ($(ICE_THREADED), true) + LDFLAGS += -mp +# CFLAGS += -mp + FFLAGS += -mp +else + LDFLAGS += -nomp +# CFLAGS += -nomp + FFLAGS += -nomp +endif + diff --git a/configuration/scripts/machines/Macros.blueback_cray b/configuration/scripts/machines/Macros.blueback_cray new file mode 100644 index 000000000..a0b13abcb --- /dev/null +++ b/configuration/scripts/machines/Macros.blueback_cray @@ -0,0 +1,61 @@ +#============================================================================== +# Macros file for NavyDSRC blueback, cray compiler +#============================================================================== + +CPP := ftn -e P +CPPDEFS := -DFORTRANUNDERSCORE -DNO_R16 ${ICE_CPPDEFS} +CFLAGS := -c -O2 + +FIXEDFLAGS := -132 +FREEFLAGS := +FFLAGS := -hbyteswapio +FFLAGS_NOOPT:= -O0 +LDFLAGS := -hbyteswapio + +ifeq ($(ICE_BLDDEBUG), true) + FFLAGS += -O0 -hfp0 -g -Rbcdps -Ktrap=fp +else +# FFLAGS += -O2 -hfp0 # -eo + FFLAGS += -O1 -hfp0 # -eo +endif + +SCC := cc +SFC := ftn +MPICC := cc +MPIFC := ftn + +ifeq ($(ICE_COMMDIR), mpi) + FC := $(MPIFC) + CC := $(MPICC) +else + FC := $(SFC) + CC := $(SCC) +endif +LD:= $(FC) + +# defined by module +#NETCDF_PATH := $(NETCDF) +#PNETCDF_PATH := $(PNETCDF) +#PNETCDF_PATH := /glade/apps/opt/pnetcdf/1.3.0/intel/default +#LAPACK_LIBDIR := /glade/apps/opt/lapack/3.4.2/intel/12.1.5/lib + +#PIO_CONFIG_OPTS:= --enable-filesystem-hints=gpfs + +INCLDIR := $(INCLDIR) +#INCLDIR += -I$(NETCDF_PATH)/include + +#LIB_NETCDF := $(NETCDF_PATH)/lib +#LIB_PNETCDF := $(PNETCDF_PATH)/lib +#LIB_MPI := $(IMPILIBDIR) +#SLIBS := -L$(LIB_NETCDF) -lnetcdf -lnetcdff + +ifeq ($(ICE_THREADED), true) + LDFLAGS += -fopenmp + CFLAGS += -fopenmp + FFLAGS += -fopenmp +else + LDFLAGS += -hnoomp +# CFLAGS += -hnoomp + FFLAGS += -hnoomp +endif + diff --git a/configuration/scripts/machines/Macros.blueback_gnu b/configuration/scripts/machines/Macros.blueback_gnu new file mode 100644 index 000000000..17d0f4a3b --- /dev/null +++ b/configuration/scripts/machines/Macros.blueback_gnu @@ -0,0 +1,71 @@ +#============================================================================== +# Macros file for NavyDSRC blueback, gnu compiler +#============================================================================== + +CPP := ftn -E +CPPDEFS := -DFORTRANUNDERSCORE ${ICE_CPPDEFS} +CFLAGS := -c + +FIXEDFLAGS := -ffixed-line-length-132 +FREEFLAGS := -ffree-form +FFLAGS := -fconvert=big-endian -fbacktrace -ffree-line-length-none -fallow-argument-mismatch +FFLAGS_NOOPT:= -O0 + +ifeq ($(ICE_BLDDEBUG), true) + # ffpe-trap=invalid produces an abort in hdf5 ~v1.14 which is fixed in 1.14.4.2 + FFLAGS += -O0 -g -fcheck=bounds -finit-real=nan -fimplicit-none -ffpe-trap=zero,overflow +# FFLAGS += -O0 -g -fcheck=bounds -finit-real=nan -fimplicit-none -ffpe-trap=invalid,zero,overflow + CFLAGS += -O0 +endif + +ifeq ($(ICE_COVERAGE), true) + FFLAGS += -O0 -g -fprofile-arcs -ftest-coverage + CFLAGS += -O0 -g -coverage + LDFLAGS += -g -ftest-coverage -fprofile-arcs +endif + +ifneq ($(ICE_BLDDEBUG), true) +ifneq ($(ICE_COVERAGE), true) + FFLAGS += -O2 + CFLAGS += -O2 +endif +endif + +#SCC := gcc +#SFC := gfortran +SCC := cc +SFC := ftn +MPICC := cc +MPIFC := ftn + +ifeq ($(ICE_COMMDIR), mpi) + FC := $(MPIFC) + CC := $(MPICC) +else + FC := $(SFC) + CC := $(SCC) +endif +LD:= $(FC) + +# defined by module +#NETCDF_PATH := $(NETCDF) +#PNETCDF_PATH := $(PNETCDF) +#PNETCDF_PATH := /glade/apps/opt/pnetcdf/1.3.0/intel/default +#LAPACK_LIBDIR := /glade/apps/opt/lapack/3.4.2/intel/12.1.5/lib + +#PIO_CONFIG_OPTS:= --enable-filesystem-hints=gpfs + +INCLDIR := $(INCLDIR) +INCLDIR += -I$(NETCDF_PATH)/include + +LIB_NETCDF := $(NETCDF_PATH)/lib +#LIB_PNETCDF := $(PNETCDF_PATH)/lib +#LIB_MPI := $(IMPILIBDIR) +SLIBS := -L$(LIB_NETCDF) -lnetcdf -lnetcdff + +ifeq ($(ICE_THREADED), true) + LDFLAGS += -fopenmp + CFLAGS += -fopenmp + FFLAGS += -fopenmp +endif + diff --git a/configuration/scripts/machines/Macros.blueback_intel b/configuration/scripts/machines/Macros.blueback_intel new file mode 100644 index 000000000..834b58b7b --- /dev/null +++ b/configuration/scripts/machines/Macros.blueback_intel @@ -0,0 +1,61 @@ +#============================================================================== +# Macros file for NavyDSRC blueback, intel compiler +#============================================================================== + +CPP := fpp +CPPDEFS := -DFORTRANUNDERSCORE ${ICE_CPPDEFS} +CFLAGS := -c -O2 -fp-model precise -fcommon + +FIXEDFLAGS := -132 +FREEFLAGS := -FR +FFLAGS := -fp-model precise -convert big_endian -assume byterecl -ftz -traceback +# -mcmodel medium -shared-intel +FFLAGS_NOOPT:= -O0 + +ifeq ($(ICE_BLDDEBUG), true) + # fpe0 produces an abort in hdf5 ~v1.14 which is fixed in 1.14.4.2 + FFLAGS += -O0 -g -check uninit -check bounds -check pointers -fpe1 -check noarg_temp_created +# FFLAGS += -O0 -g -check uninit -check bounds -check pointers -fpe0 -check noarg_temp_created +# FFLAGS += -O0 -g -check all -fpe0 -ftrapuv -fp-model except -check noarg_temp_created -init=snan,arrays +else + FFLAGS += -O2 +endif + +#SCC := icx +#SFC := ifort +SCC := cc +SFC := ftn +MPICC := cc +MPIFC := ftn + +ifeq ($(ICE_COMMDIR), mpi) + FC := $(MPIFC) + CC := $(MPICC) +else + FC := $(SFC) + CC := $(SCC) +endif +LD:= $(FC) + +# defined by module +#NETCDF_PATH := $(NETCDF) +#PNETCDF_PATH := $(PNETCDF) +#PNETCDF_PATH := /glade/apps/opt/pnetcdf/1.3.0/intel/default +#LAPACK_LIBDIR := /glade/apps/opt/lapack/3.4.2/intel/12.1.5/lib + +#PIO_CONFIG_OPTS:= --enable-filesystem-hints=gpfs + +INCLDIR := $(INCLDIR) +INCLDIR += -I$(NETCDF_PATH)/include + +LIB_NETCDF := $(NETCDF_PATH)/lib +#LIB_PNETCDF := $(PNETCDF_PATH)/lib +#LIB_MPI := $(IMPILIBDIR) +SLIBS := -L$(LIB_NETCDF) -lnetcdf -lnetcdff + +ifeq ($(ICE_THREADED), true) + LDFLAGS += -qopenmp + CFLAGS += -qopenmp + FFLAGS += -qopenmp +endif + diff --git a/configuration/scripts/machines/Macros.blueback_nvhpc b/configuration/scripts/machines/Macros.blueback_nvhpc new file mode 100644 index 000000000..47b4c59f0 --- /dev/null +++ b/configuration/scripts/machines/Macros.blueback_nvhpc @@ -0,0 +1,74 @@ +#============================================================================== +# Makefile macros for NavyDSRC blueback, nvhpc compiler +#============================================================================== + +CPP := nvc -Mcpp +CPPDEFS := -DFORTRANUNDERSCORE -DNO_R16 ${ICE_CPPDEFS} +CFLAGS := -c -Kieee + +FIXEDFLAGS := -Mfixed +FREEFLAGS := -Mfree +FFLAGS := -Kieee -byteswapio -traceback +FFLAGS_NOOPT:= -O0 + +ifeq ($(ICE_BLDDEBUG), true) +# FFLAGS += -O0 -g -Ktrap=fp -Mbounds -Mchkptr +# FFLAGS += -O0 -g -Ktrap=fp -Mbounds +# FFLAGS += -O0 -Ktrap=fp -Mbounds -Mchkptr + # -Ktrap=fp produces an abort in hdf5 ~v1.14 which is fixed in 1.14.4.2 + FFLAGS += -O0 +# FFLAGS += -O0 -Ktrap=fp + CFLAGS += -O0 +else +# FFLAGS += -O2 -Mnofma -target=zen3 + FFLAGS += -O2 + CFLAGS += -O2 +endif + +#SCC := nvc +#SFC := nvfortran +#MPICC := mpicc +#MPIFC := mpif90 +SCC := cc +SFC := ftn +MPICC := cc +MPIFC := ftn + +ifeq ($(ICE_COMMDIR), mpi) + FC := $(MPIFC) + CC := $(MPICC) +else + FC := $(SFC) + CC := $(SCC) +endif +LD:= $(FC) + +NETCDF_PATH := $(NETCDF) + +#PIO_CONFIG_OPTS:= --enable-filesystem-hints=gpfs + +#INCLDIR := $(INCLDIR) + +LIB_NETCDF := $(NETCDF_PATH)/lib +#LIB_PNETCDF := $(PNETCDF_PATH)/lib +#LIB_MPI := $(IMPILIBDIR) + +#SLIBS := -L$(LIB_NETCDF) -lnetcdf -lnetcdff -L$(LIB_PNETCDF) -lpnetcdf +SLIBS := -L$(LIB_NETCDF) -lnetcdf -lnetcdff + +ifeq ($(ICE_THREADED), true) + LDFLAGS += -mp + CFLAGS += -mp + FFLAGS += -mp +endif + +ifeq ($(ICE_IOTYPE), pio1) + LIB_PIO := $(PIO)/lib + SLIBS := $(SLIBS) -L$(LIB_PIO) -lpio +endif + +ifeq ($(ICE_IOTYPE), pio2) + LIB_PIO := $(PIO)/lib + SLIBS := $(SLIBS) -L$(LIB_PIO) -lpiof -lpioc +endif + diff --git a/configuration/scripts/machines/Macros.carpenter_intel b/configuration/scripts/machines/Macros.carpenter_intel index d53f959e4..deb6f1549 100644 --- a/configuration/scripts/machines/Macros.carpenter_intel +++ b/configuration/scripts/machines/Macros.carpenter_intel @@ -13,7 +13,9 @@ FFLAGS := -fp-model precise -convert big_endian -assume byterecl -ftz -trace FFLAGS_NOOPT:= -O0 ifeq ($(ICE_BLDDEBUG), true) - FFLAGS += -O0 -g -check uninit -check bounds -check pointers -fpe0 -check noarg_temp_created +# fpe0 produces an abort in hdf5 ~v1.14 which is fixed in 1.14.4.2 + FFLAGS += -O0 -g -check uninit -check bounds -check pointers -fpe1 -check noarg_temp_created +# FFLAGS += -O0 -g -check uninit -check bounds -check pointers -fpe0 -check noarg_temp_created # FFLAGS += -O0 -g -check all -fpe0 -ftrapuv -fp-model except -check noarg_temp_created -init=snan,arrays else FFLAGS += -O2 diff --git a/configuration/scripts/machines/Macros.carpenter_intelimpi b/configuration/scripts/machines/Macros.carpenter_intelimpi index 0c1aa5812..b20ed04e7 100644 --- a/configuration/scripts/machines/Macros.carpenter_intelimpi +++ b/configuration/scripts/machines/Macros.carpenter_intelimpi @@ -13,7 +13,9 @@ FFLAGS := -fp-model precise -convert big_endian -assume byterecl -ftz -trace FFLAGS_NOOPT:= -O0 ifeq ($(ICE_BLDDEBUG), true) - FFLAGS += -O0 -g -check uninit -check bounds -check pointers -fpe0 -check noarg_temp_created +# fpe0 produces an abort in hdf5 ~v1.14 which is fixed in 1.14.4.2 + FFLAGS += -O0 -g -check uninit -check bounds -check pointers -fpe1 -check noarg_temp_created +# FFLAGS += -O0 -g -check uninit -check bounds -check pointers -fpe0 -check noarg_temp_created # FFLAGS += -O0 -g -check all -fpe0 -ftrapuv -fp-model except -check noarg_temp_created -init=snan,arrays else FFLAGS += -O2 diff --git a/configuration/scripts/machines/Macros.carpenter_inteloneapi b/configuration/scripts/machines/Macros.carpenter_inteloneapi new file mode 100644 index 000000000..685e99c36 --- /dev/null +++ b/configuration/scripts/machines/Macros.carpenter_inteloneapi @@ -0,0 +1,62 @@ +#============================================================================== +# Macros file for ERDC carpenter, inteloneapi compiler +#============================================================================== + +CPP := fpp +CPPDEFS := -DFORTRANUNDERSCORE ${ICE_CPPDEFS} +CFLAGS := -c -O2 -fp-model precise -fcommon + +FIXEDFLAGS := -132 +FREEFLAGS := -FR +FFLAGS := -fp-model precise -convert big_endian -assume byterecl -ftz -traceback +# -mcmodel medium -shared-intel +FFLAGS_NOOPT:= -O0 + +ifeq ($(ICE_BLDDEBUG), true) +# -check uninit is needed on the ld step but it still throws errors in 2023.* and 2024.0.*, likely compiler bug + FFLAGS += -O0 -g -check bounds -check pointers -fpe1 -check noarg_temp_created -link_mpi=dbg +# FFLAGS += -O0 -g -check bounds -check pointers -fpe0 -check noarg_temp_created -link_mpi=dbg +# FFLAGS += -O0 -g -check_uninit -check bounds -check pointers -fpe0 -check noarg_temp_created -link_mpi=dbg +# LDFLAGS += -check uninit +else + FFLAGS += -O2 +endif + +SCC := icx +SFC := ifx +#SCC := cc +#SFC := ftn +MPICC := cc +MPIFC := ftn + +ifeq ($(ICE_COMMDIR), mpi) + FC := $(MPIFC) + CC := $(MPICC) +else + FC := $(SFC) + CC := $(SCC) +endif +LD:= $(FC) + +# defined by module +#NETCDF_PATH := $(NETCDF) +#PNETCDF_PATH := $(PNETCDF) +#PNETCDF_PATH := /glade/apps/opt/pnetcdf/1.3.0/intel/default +#LAPACK_LIBDIR := /glade/apps/opt/lapack/3.4.2/intel/12.1.5/lib + +#PIO_CONFIG_OPTS:= --enable-filesystem-hints=gpfs + +INCLDIR := $(INCLDIR) +INCLDIR += -I$(NETCDF_PATH)/include + +LIB_NETCDF := $(NETCDF_PATH)/lib +#LIB_PNETCDF := $(PNETCDF_PATH)/lib +#LIB_MPI := $(IMPILIBDIR) +SLIBS := -L$(LIB_NETCDF) -lnetcdf -lnetcdff + +ifeq ($(ICE_THREADED), true) + LDFLAGS += -qopenmp + CFLAGS += -qopenmp + FFLAGS += -qopenmp +endif + diff --git a/configuration/scripts/machines/Macros.discover_intel b/configuration/scripts/machines/Macros.discover_intel new file mode 100644 index 000000000..173646777 --- /dev/null +++ b/configuration/scripts/machines/Macros.discover_intel @@ -0,0 +1,42 @@ +#============================================================================== +# Makefile macros for NASA NCCS discover, intel compiler +#============================================================================== + +CPP := fpp +CPPDEFS := -DFORTRANUNDERSCORE ${ICE_CPPDEFS} +CFLAGS := -c -O2 -fp-model precise -xHost + +FIXEDFLAGS := -132 +FREEFLAGS := -FR +FFLAGS := -fp-model precise -convert big_endian -assume byterecl -ftz -traceback -xHost +FFLAGS_NOOPT:= -O0 + +ifeq ($(ICE_BLDDEBUG), true) + FFLAGS += -O0 -g -check uninit -check bounds -check pointers -fpe0 -check noarg_temp_created +else + FFLAGS += -O2 +endif + +SCC := mpiicc +SFC := mpiifort +CC := $(SCC) +FC := $(SFC) +LD := $(FC) + +NETCDF_INCLUDES := $(shell $$BASEDIR/Linux/bin/nf-config --cflags) +NETCDF_LIBS := $(shell $$BASEDIR/Linux/bin/nf-config --flibs) + +INCLDIR := $(INCLDIR) +INCLDIR += $(NETCDF_INCLUDES) + +LIB_NETCDF := $(NETCDF_LIBS) +#LIB_MPI := $(IMPILIBDIR) + +SLIBS := $(LIB_NETCDF) + +ifeq ($(ICE_THREADED), true) + LDFLAGS += -qopenmp + CFLAGS += -qopenmp + FFLAGS += -qopenmp +endif + diff --git a/configuration/scripts/machines/Macros.gaea_cray b/configuration/scripts/machines/Macros.gaea_cray new file mode 100644 index 000000000..851134514 --- /dev/null +++ b/configuration/scripts/machines/Macros.gaea_cray @@ -0,0 +1,57 @@ +#============================================================================== +# Makefile macros for NOAA hera, intel compiler +#============================================================================== + +CPP := fpp +CPPDEFS := -DFORTRANUNDERSCORE ${ICE_CPPDEFS} +CFLAGS := -c -O2 + +FIXEDFLAGS := -132 +FREEFLAGS := +FFLAGS := -hbyteswapio +FFLAGS_NOOPT:= -O0 +LDLAGS := -hbyteswapio + +ifeq ($(ICE_BLDDEBUG), true) + FFLAGS += -O0 -hfp0 -g -Rbcdps -Ktrap=fp +else + FFLAGS += -O2 -hfp0 +endif + +SCC := cc +SFC := ftn +MPICC := cc +MPIFC := ftn + +ifeq ($(ICE_COMMDIR), mpi) + FC := $(MPIFC) + CC := $(MPICC) +else + FC := $(SFC) + CC := $(SCC) +endif +LD:= $(FC) + +NETCDF_PATH := $(NETCDF) + +#PIO_CONFIG_OPTS:= --enable-filesystem-hints=gpfs + +#PNETCDF_PATH := $(PNETCDF) +#PNETCDF_PATH := /glade/u/apps/ch/opt/pio/2.2/mpt/2.15f/intel/17.0.1/lib + +INC_NETCDF := $(NETCDF_PATH)/include +LIB_NETCDF := $(NETCDF_PATH)/lib + +#LIB_PNETCDF := $(PNETCDF_PATH)/lib +#LIB_MPI := $(IMPILIBDIR) + +INCLDIR := $(INCLDIR) -I$(INC_NETCDF) +#SLIBS := -L$(LIB_NETCDF) -lnetcdf -lnetcdff -L$(LIB_PNETCDF) -lpnetcdf -lgptl +SLIBS := -L$(LIB_NETCDF) -lnetcdf -lnetcdff + +ifeq ($(ICE_THREADED), true) + LDFLAGS += -fopenmp + CFLAGS += -fopenmp + FFLAGS += -fopenmp +endif + diff --git a/configuration/scripts/machines/Macros.gaeac5_intel b/configuration/scripts/machines/Macros.gaeac5_intel new file mode 100644 index 000000000..794070214 --- /dev/null +++ b/configuration/scripts/machines/Macros.gaeac5_intel @@ -0,0 +1,56 @@ +#============================================================================== +# Makefile macros for NOAA gaeac5, intel compiler +#============================================================================== + +CPP := fpp +CPPDEFS := -DFORTRANUNDERSCORE ${ICE_CPPDEFS} +CFLAGS := -c -O2 -fp-model precise -xHost + +FIXEDFLAGS := -132 +FREEFLAGS := -FR +FFLAGS := -fp-model precise -convert big_endian -assume byterecl -ftz -traceback -align array64byte -xHost +FFLAGS_NOOPT:= -O0 + +ifeq ($(ICE_BLDDEBUG), true) + FFLAGS += -O0 -g -check uninit -check bounds -check pointers -fpe0 -check noarg_temp_created -link_mpi=dbg +else + FFLAGS += -O2 +endif + +SCC := cc +SFC := ftn +MPICC := cc +MPIFC := ftn + +ifeq ($(ICE_COMMDIR), mpi) + FC := $(MPIFC) + CC := $(MPICC) +else + FC := $(SFC) + CC := $(SCC) +endif +LD:= $(FC) + +NETCDF_PATH := $(NETCDF) + +PIO_CONFIG_OPTS:= --enable-filesystem-hints=gpfs + +#PNETCDF_PATH := $(PNETCDF) +#PNETCDF_PATH := /glade/u/apps/ch/opt/pio/2.2/mpt/2.15f/intel/17.0.1/lib + +INC_NETCDF := $(NETCDF_PATH)/include +LIB_NETCDF := $(NETCDF_PATH)/lib + +#LIB_PNETCDF := $(PNETCDF_PATH)/lib +#LIB_MPI := $(IMPILIBDIR) + +INCLDIR := $(INCLDIR) -I$(INC_NETCDF) +#SLIBS := -L$(LIB_NETCDF) -lnetcdf -lnetcdff -L$(LIB_PNETCDF) -lpnetcdf -lgptl +SLIBS := -L$(LIB_NETCDF) -lnetcdf -lnetcdff + +ifeq ($(ICE_THREADED), true) + LDFLAGS += -qopenmp + CFLAGS += -qopenmp + FFLAGS += -qopenmp +endif + diff --git a/configuration/scripts/machines/Macros.ursa_intel b/configuration/scripts/machines/Macros.ursa_intel new file mode 100644 index 000000000..dbd920d08 --- /dev/null +++ b/configuration/scripts/machines/Macros.ursa_intel @@ -0,0 +1,59 @@ +#============================================================================== +# Makefile macros for NOAA ursa, intel compiler +#============================================================================== + +CPP := fpp +CPPDEFS := -DFORTRANUNDERSCORE ${ICE_CPPDEFS} +CFLAGS := -c -O2 -fp-model precise -xHost + +FIXEDFLAGS := -132 +FREEFLAGS := -FR +FFLAGS := -fp-model precise -convert big_endian -assume byterecl -ftz -traceback -align array64byte -xHost +FFLAGS_NOOPT:= -O0 + +ifeq ($(ICE_BLDDEBUG), true) + #FFLAGS += -O0 -g -check uninit -check bounds -check pointers -fpe0 -check noarg_temp_created -link_mpi=dbg + # check uninit triggers link failure on ursa + FFLAGS += -O0 -g -check bounds -check pointers -fpe0 -check noarg_temp_created -link_mpi=dbg +else + #FFLAGS += -O2 +endif + +SCC := icx +SFC := ifx +MPICC := mpiicx +MPIFC := mpiifx + +ifeq ($(ICE_COMMDIR), mpi) + FC := $(MPIFC) + CC := $(MPICC) +else + FC := $(SFC) + CC := $(SCC) +endif +LD:= $(FC) + +#NETCDF_PATH := $(NETCDF) +NETCDF_PATH := $(NETCDF_FORTRAN_ROOT) + +PIO_CONFIG_OPTS:= --enable-filesystem-hints=gpfs + +#PNETCDF_PATH := $(PNETCDF) + +INC_NETCDF := $(NETCDF_PATH)/include +LIB_NETCDF := $(NETCDF_PATH)/lib + +#LIB_PNETCDF := $(PNETCDF_PATH)/lib +#LIB_MPI := $(IMPILIBDIR) + +INCLDIR := $(INCLDIR) -I$(INC_NETCDF) +#SLIBS := -L$(LIB_NETCDF) -lnetcdf -lnetcdff -L$(LIB_PNETCDF) -lpnetcdf -lgptl +#SLIBS := -L$(LIB_NETCDF) -lnetcdf -lnetcdff +SLIBS := -L$(LIB_NETCDF) -lnetcdff + +ifeq ($(ICE_THREADED), true) + LDFLAGS += -qopenmp + CFLAGS += -qopenmp + FFLAGS += -qopenmp +endif + diff --git a/configuration/scripts/machines/env.blueback_aocc b/configuration/scripts/machines/env.blueback_aocc new file mode 100644 index 000000000..973ae046c --- /dev/null +++ b/configuration/scripts/machines/env.blueback_aocc @@ -0,0 +1,58 @@ +#!/bin/csh -f +set inp = "undefined" +if ($#argv == 1) then + set inp = $1 +endif + +if ("$inp" != "-nomodules") then + +source ${MODULESHOME}/init/csh + +module unload PrgEnv-cray +module unload PrgEnv-gnu +module unload PrgEnv-intel +module unload PrgEnv-nvhpc +module unload PrgEnv-aocc +module load PrgEnv-aocc/8.5.0 + +module unload aocc +module load aocc/4.1.0 + +module unload cray-mpich +module unload mpi +module unload openmpi +module load cray-mpich/8.1.30 +#module load mpi/2021.11 +#module load openmpi/4.1.6 + +module unload cray-hdf5 +module unload cray-hdf5-parallel +module unload cray-netcdf-hdf5parallel +module unload cray-parallel-netcdf +module unload netcdf +module load cray-netcdf/4.9.0.13 +module load cray-hdf5/1.14.3.1 + +setenv NETCDF_PATH ${NETCDF_DIR} +limit coredumpsize unlimited +limit stacksize unlimited +setenv OMP_STACKSIZE 128M +setenv OMP_WAIT_POLICY PASSIVE +setenv FI_CXI_RX_MATCH_MODE hybrid + +endif + +setenv ICE_MACHINE_MACHNAME blueback +setenv ICE_MACHINE_MACHINFO "Cray EX4000 AMD Genoa, Slingshot-11 Interconnect" +setenv ICE_MACHINE_ENVNAME intel +setenv ICE_MACHINE_ENVINFO "AMD clang version 16.0.3 (CLANG: AOCC_4.1.0-Build#270 2023_07_10, cray-mpich/8.1.30, netcdf/4.9.0.13" +setenv ICE_MACHINE_MAKE gmake +setenv ICE_MACHINE_WKDIR $WORKDIR/CICE_RUNS +setenv ICE_MACHINE_INPUTDATA /p/work1/projects/RASM/cice_consortium +setenv ICE_MACHINE_BASELINE $WORKDIR/CICE_BASELINE +setenv ICE_MACHINE_SUBMIT "sbatch " +setenv ICE_MACHINE_ACCT P00000000 +setenv ICE_MACHINE_QUEUE "debug" +setenv ICE_MACHINE_TPNODE 192 # tasks per node +setenv ICE_MACHINE_BLDTHRDS 12 +setenv ICE_MACHINE_QSTAT "squeue --jobs=" diff --git a/configuration/scripts/machines/env.blueback_cray b/configuration/scripts/machines/env.blueback_cray new file mode 100644 index 000000000..00369a16d --- /dev/null +++ b/configuration/scripts/machines/env.blueback_cray @@ -0,0 +1,58 @@ +#!/bin/csh -f +set inp = "undefined" +if ($#argv == 1) then + set inp = $1 +endif + +if ("$inp" != "-nomodules") then + +source ${MODULESHOME}/init/csh + +module unload PrgEnv-cray +module unload PrgEnv-gnu +module unload PrgEnv-intel +module unload PrgEnv-nvhpc +module unload PrgEnv-aocc +module load PrgEnv-cray/8.5.0 + +module unload cce +module load cce/18.0.0 + +module unload cray-mpich +module unload mpi +module unload openmpi +module load cray-mpich/8.1.30 +#module load mpi/2021.11 +#module load openmpi/4.1.6 + +module unload cray-hdf5 +module unload cray-hdf5-parallel +module unload cray-netcdf-hdf5parallel +module unload cray-parallel-netcdf +module unload netcdf +module load cray-netcdf/4.9.0.13 +module load cray-hdf5/1.14.3.1 + +setenv NETCDF_PATH ${NETCDF_DIR} +limit coredumpsize unlimited +limit stacksize unlimited +setenv OMP_STACKSIZE 128M +setenv OMP_WAIT_POLICY PASSIVE +setenv FI_CXI_RX_MATCH_MODE hybrid + +endif + +setenv ICE_MACHINE_MACHNAME blueback +setenv ICE_MACHINE_MACHINFO "Cray EX4000 AMD Genoa, Slingshot-11 Interconnect" +setenv ICE_MACHINE_ENVNAME intel +setenv ICE_MACHINE_ENVINFO "Cray Fortran/Clang 18.0.0, cray-mpich/8.1.30, netcdf/4.9.0.13" +setenv ICE_MACHINE_MAKE gmake +setenv ICE_MACHINE_WKDIR $WORKDIR/CICE_RUNS +setenv ICE_MACHINE_INPUTDATA /p/work1/projects/RASM/cice_consortium +setenv ICE_MACHINE_BASELINE $WORKDIR/CICE_BASELINE +setenv ICE_MACHINE_SUBMIT "sbatch " +setenv ICE_MACHINE_ACCT P00000000 +setenv ICE_MACHINE_QUEUE "debug" +setenv ICE_MACHINE_TPNODE 192 # tasks per node +setenv ICE_MACHINE_BLDTHRDS 12 +setenv ICE_MACHINE_QSTAT "squeue --jobs=" diff --git a/configuration/scripts/machines/env.blueback_gnu b/configuration/scripts/machines/env.blueback_gnu new file mode 100644 index 000000000..5bf77d73c --- /dev/null +++ b/configuration/scripts/machines/env.blueback_gnu @@ -0,0 +1,58 @@ +#!/bin/csh -f +set inp = "undefined" +if ($#argv == 1) then + set inp = $1 +endif + +if ("$inp" != "-nomodules") then + +source ${MODULESHOME}/init/csh + +module unload PrgEnv-cray +module unload PrgEnv-gnu +module unload PrgEnv-intel +module unload PrgEnv-nvhpc +module unload PrgEnv-aocc +module load PrgEnv-gnu/8.5.0 + +module unload gcc +module load gcc-native/13.2 + +module unload cray-mpich +module unload mpi +module unload openmpi +module load cray-mpich/8.1.30 +#module load mpi/2021.11 +#module load openmpi/4.1.6 + +module unload cray-hdf5 +module unload cray-hdf5-parallel +module unload cray-netcdf-hdf5parallel +module unload cray-parallel-netcdf +module unload netcdf +module load cray-netcdf/4.9.0.13 +module load cray-hdf5/1.14.3.1 + +setenv NETCDF_PATH ${NETCDF_DIR} +limit coredumpsize unlimited +limit stacksize unlimited +setenv OMP_STACKSIZE 128M +setenv OMP_WAIT_POLICY PASSIVE +setenv FI_CXI_RX_MATCH_MODE hybrid + +endif + +setenv ICE_MACHINE_MACHNAME blueback +setenv ICE_MACHINE_MACHINFO "Cray EX4000 AMD Genoa, Slingshot-11 Interconnect" +setenv ICE_MACHINE_ENVNAME intel +setenv ICE_MACHINE_ENVINFO "gfortran/gcc 13.3.0, cray-mpich/8.1.30, netcdf/4.9.0.13" +setenv ICE_MACHINE_MAKE gmake +setenv ICE_MACHINE_WKDIR $WORKDIR/CICE_RUNS +setenv ICE_MACHINE_INPUTDATA /p/work1/projects/RASM/cice_consortium +setenv ICE_MACHINE_BASELINE $WORKDIR/CICE_BASELINE +setenv ICE_MACHINE_SUBMIT "sbatch " +setenv ICE_MACHINE_ACCT P00000000 +setenv ICE_MACHINE_QUEUE "debug" +setenv ICE_MACHINE_TPNODE 192 # tasks per node +setenv ICE_MACHINE_BLDTHRDS 12 +setenv ICE_MACHINE_QSTAT "squeue --jobs=" diff --git a/configuration/scripts/machines/env.blueback_intel b/configuration/scripts/machines/env.blueback_intel new file mode 100644 index 000000000..db233c874 --- /dev/null +++ b/configuration/scripts/machines/env.blueback_intel @@ -0,0 +1,58 @@ +#!/bin/csh -f +set inp = "undefined" +if ($#argv == 1) then + set inp = $1 +endif + +if ("$inp" != "-nomodules") then + +source ${MODULESHOME}/init/csh + +module unload PrgEnv-cray +module unload PrgEnv-gnu +module unload PrgEnv-intel +module unload PrgEnv-nvhpc +module unload PrgEnv-aocc +module load PrgEnv-intel/8.5.0 + +module unload intel +module load intel/2023.2.0 + +module unload cray-mpich +module unload mpi +module unload openmpi +module load cray-mpich/8.1.30 +#module load mpi/2021.11 +#module load openmpi/4.1.6 + +module unload cray-hdf5 +module unload cray-hdf5-parallel +module unload cray-netcdf-hdf5parallel +module unload cray-parallel-netcdf +module unload netcdf +module load cray-netcdf/4.9.0.13 +module load cray-hdf5/1.14.3.1 + +setenv NETCDF_PATH ${NETCDF_DIR} +limit coredumpsize unlimited +limit stacksize unlimited +setenv OMP_STACKSIZE 128M +setenv OMP_WAIT_POLICY PASSIVE +setenv FI_CXI_RX_MATCH_MODE hybrid + +endif + +setenv ICE_MACHINE_MACHNAME blueback +setenv ICE_MACHINE_MACHINFO "Cray EX4000 AMD Genoa, Slingshot-11 Interconnect" +setenv ICE_MACHINE_ENVNAME intel +setenv ICE_MACHINE_ENVINFO "ifort 2021.10.0 20230609, icx 2023.2.0.20230622, cray-mpich/8.1.30, netcdf/4.9.0.13" +setenv ICE_MACHINE_MAKE gmake +setenv ICE_MACHINE_WKDIR $WORKDIR/CICE_RUNS +setenv ICE_MACHINE_INPUTDATA /p/work1/projects/RASM/cice_consortium +setenv ICE_MACHINE_BASELINE $WORKDIR/CICE_BASELINE +setenv ICE_MACHINE_SUBMIT "sbatch " +setenv ICE_MACHINE_ACCT P00000000 +setenv ICE_MACHINE_QUEUE "debug" +setenv ICE_MACHINE_TPNODE 192 # tasks per node +setenv ICE_MACHINE_BLDTHRDS 12 +setenv ICE_MACHINE_QSTAT "squeue --jobs=" diff --git a/configuration/scripts/machines/env.blueback_nvhpc b/configuration/scripts/machines/env.blueback_nvhpc new file mode 100644 index 000000000..4bcf3a8ef --- /dev/null +++ b/configuration/scripts/machines/env.blueback_nvhpc @@ -0,0 +1,58 @@ +#!/bin/csh -f +set inp = "undefined" +if ($#argv == 1) then + set inp = $1 +endif + +if ("$inp" != "-nomodules") then + +source ${MODULESHOME}/init/csh + +module unload PrgEnv-cray +module unload PrgEnv-gnu +module unload PrgEnv-intel +module unload PrgEnv-nvhpc +module unload PrgEnv-aocc +module load PrgEnv-nvhpc/8.5.0 + +module unload nvhpc +module load nvhpc/24.3 + +module unload cray-mpich +module unload mpi +module unload openmpi +module load cray-mpich/8.1.30 +#module load mpi/2021.11 +#module load openmpi/4.1.6 + +module unload cray-hdf5 +module unload cray-hdf5-parallel +module unload cray-netcdf-hdf5parallel +module unload cray-parallel-netcdf +module unload netcdf +module load cray-netcdf/4.9.0.13 +module load cray-hdf5/1.14.3.1 + +setenv NETCDF_PATH ${NETCDF_DIR} +limit coredumpsize unlimited +limit stacksize unlimited +setenv OMP_STACKSIZE 128M +setenv OMP_WAIT_POLICY PASSIVE +setenv FI_CXI_RX_MATCH_MODE hybrid + +endif + +setenv ICE_MACHINE_MACHNAME blueback +setenv ICE_MACHINE_MACHINFO "Cray EX4000 AMD Genoa, Slingshot-11 Interconnect" +setenv ICE_MACHINE_ENVNAME intel +setenv ICE_MACHINE_ENVINFO "nvfortran 24.3-0, cray-mpich/8.1.30, netcdf/4.9.0.13" +setenv ICE_MACHINE_MAKE gmake +setenv ICE_MACHINE_WKDIR $WORKDIR/CICE_RUNS +setenv ICE_MACHINE_INPUTDATA /p/work1/projects/RASM/cice_consortium +setenv ICE_MACHINE_BASELINE $WORKDIR/CICE_BASELINE +setenv ICE_MACHINE_SUBMIT "sbatch " +setenv ICE_MACHINE_ACCT P00000000 +setenv ICE_MACHINE_QUEUE "debug" +setenv ICE_MACHINE_TPNODE 192 # tasks per node +setenv ICE_MACHINE_BLDTHRDS 12 +setenv ICE_MACHINE_QSTAT "squeue --jobs=" diff --git a/configuration/scripts/machines/env.carpenter_intel b/configuration/scripts/machines/env.carpenter_intel index c97a7d25a..141a5a82a 100644 --- a/configuration/scripts/machines/env.carpenter_intel +++ b/configuration/scripts/machines/env.carpenter_intel @@ -12,7 +12,7 @@ module unload PrgEnv-cray module unload PrgEnv-gnu module unload PrgEnv-intel module unload PrgEnv-pgi -module load PrgEnv-intel/8.4.0 +module load PrgEnv-intel/8.5.0 module unload intel module load intel/2023.0.0 @@ -20,7 +20,7 @@ module load intel/2023.0.0 module unload cray-mpich module unload mpi module unload openmpi -module load cray-mpich/8.1.26 +module load cray-mpich/8.1.30 #module load mpi/2021.11 #module load openmpi/4.1.6 @@ -30,7 +30,7 @@ module unload cray-netcdf-hdf5parallel module unload cray-parallel-netcdf module unload netcdf module load cray-netcdf/4.9.0.3 -module load cray-hdf5/1.12.2.3 +module load cray-hdf5/1.14.3.1 setenv NETCDF_PATH ${NETCDF_DIR} limit coredumpsize unlimited @@ -44,7 +44,7 @@ endif setenv ICE_MACHINE_MACHNAME carpenter setenv ICE_MACHINE_MACHINFO "Cray EX4000 AMD 9654 Genoa 2.1GHz, Slingshot Interconnect" setenv ICE_MACHINE_ENVNAME intel -setenv ICE_MACHINE_ENVINFO "ifort 2021.8.0 20221119, cray-mpich/8.1.26, netcdf/4.9.0.3" +setenv ICE_MACHINE_ENVINFO "ifort 2021.8.0 20221119, cray-mpich/8.1.30, netcdf/4.9.0.3" setenv ICE_MACHINE_MAKE gmake setenv ICE_MACHINE_WKDIR $WORKDIR/CICE_RUNS setenv ICE_MACHINE_INPUTDATA /p/app/unsupported/RASM/cice_consortium diff --git a/configuration/scripts/machines/env.carpenter_intelimpi b/configuration/scripts/machines/env.carpenter_intelimpi index 25385b09a..ef43363cd 100644 --- a/configuration/scripts/machines/env.carpenter_intelimpi +++ b/configuration/scripts/machines/env.carpenter_intelimpi @@ -12,7 +12,7 @@ module unload PrgEnv-cray module unload PrgEnv-gnu module unload PrgEnv-intel module unload PrgEnv-pgi -module load PrgEnv-intel/8.4.0 +module load PrgEnv-intel/8.5.0 module unload intel module load intel/2023.0.0 @@ -21,7 +21,7 @@ module unload cray-mpich module unload mpi module unload openmpi #module load cray-mpich/8.1.26 -module load mpi/2021.11 +module load mpi/2021.13 #module load openmpi/4.1.6 module unload cray-hdf5 @@ -30,7 +30,7 @@ module unload cray-netcdf-hdf5parallel module unload cray-parallel-netcdf module unload netcdf module load cray-netcdf/4.9.0.3 -module load cray-hdf5/1.12.2.3 +module load cray-hdf5/1.14.3.1 setenv NETCDF_PATH ${NETCDF_DIR} limit coredumpsize unlimited @@ -44,7 +44,7 @@ endif setenv ICE_MACHINE_MACHNAME carpenter setenv ICE_MACHINE_MACHINFO "Cray EX4000 AMD 9654 Genoa 2.1GHz, Slingshot Interconnect" setenv ICE_MACHINE_ENVNAME intelimpi -setenv ICE_MACHINE_ENVINFO "ifort 2021.8.0 20221119, intel mpi 2021.11, netcdf/4.9.0.3" +setenv ICE_MACHINE_ENVINFO "ifort 2021.8.0 20221119, intel mpi 2021.13, netcdf/4.9.0.3" setenv ICE_MACHINE_MAKE gmake setenv ICE_MACHINE_WKDIR $WORKDIR/CICE_RUNS setenv ICE_MACHINE_INPUTDATA /p/app/unsupported/RASM/cice_consortium diff --git a/configuration/scripts/machines/env.carpenter_inteloneapi b/configuration/scripts/machines/env.carpenter_inteloneapi new file mode 100644 index 000000000..2480918c1 --- /dev/null +++ b/configuration/scripts/machines/env.carpenter_inteloneapi @@ -0,0 +1,57 @@ +#!/bin/csh -f +set inp = "undefined" +if ($#argv == 1) then + set inp = $1 +endif + +if ("$inp" != "-nomodules") then + +source ${MODULESHOME}/init/csh + +module unload PrgEnv-cray +module unload PrgEnv-gnu +module unload PrgEnv-intel +module unload PrgEnv-pgi +module load PrgEnv-intel/8.5.0 + +module unload intel +module load intel-oneapi/2024.2 + +module unload cray-mpich +module unload mpi +module unload openmpi +module load cray-mpich/8.1.30 +#module load mpi/2021.11 +#module load openmpi/4.1.6 + +module unload cray-hdf5 +module unload cray-hdf5-parallel +module unload cray-netcdf-hdf5parallel +module unload cray-parallel-netcdf +module unload netcdf +module load cray-netcdf/4.9.0.13 +module load cray-hdf5/1.14.3.1 + +setenv NETCDF_PATH ${NETCDF_DIR} +limit coredumpsize unlimited +limit stacksize unlimited +setenv OMP_STACKSIZE 128M +setenv OMP_WAIT_POLICY PASSIVE +setenv FI_CXI_RX_MATCH_MODE hybrid + +endif + +setenv ICE_MACHINE_MACHNAME carpenter +setenv ICE_MACHINE_MACHINFO "Cray EX4000 AMD 9654 Genoa 2.1GHz, Slingshot Interconnect" +setenv ICE_MACHINE_ENVNAME inteloneapi +setenv ICE_MACHINE_ENVINFO "Intel oneAPI DPC++/C++/icx/ifx 2024.2.0 20240602, cray-mpich/8.1.30, netcdf/4.9.0.13" +setenv ICE_MACHINE_MAKE gmake +setenv ICE_MACHINE_WKDIR $WORKDIR/CICE_RUNS +setenv ICE_MACHINE_INPUTDATA /p/app/unsupported/RASM/cice_consortium +setenv ICE_MACHINE_BASELINE $WORKDIR/CICE_BASELINE +setenv ICE_MACHINE_SUBMIT "qsub " +setenv ICE_MACHINE_ACCT P00000000 +setenv ICE_MACHINE_QUEUE "debug" +setenv ICE_MACHINE_TPNODE 192 # tasks per node +setenv ICE_MACHINE_BLDTHRDS 12 +setenv ICE_MACHINE_QSTAT "qstat " diff --git a/configuration/scripts/machines/env.discover_intel b/configuration/scripts/machines/env.discover_intel new file mode 100755 index 000000000..9a4e81ff2 --- /dev/null +++ b/configuration/scripts/machines/env.discover_intel @@ -0,0 +1,54 @@ +#!/bin/csh -f + +set inp = "undefined" +if ($#argv == 1) then + set inp = $1 +endif + +if ("$inp" != "-nomodules") then + +source /usr/share/modules/init/csh + +module use -a /discover/swdev/gmao_SIteam/modulefiles-SLES12 + +module purge +module load GEOSenv +module load comp/gcc/10.1.0 +module load comp/intel/2021.3.0 +module load mpi/impi/2021.3.0 +module load python/GEOSpyD/Min4.11.0_py3.9 + +endif + +## Baselibs + +set basedir = /discover/swdev/gmao_SIteam/Baselibs/ESMA-Baselibs-6.2.13/x86_64-pc-linux-gnu/ifort_2021.3.0-intelmpi_2021.3.0 +setenv BASEDIR $basedir + +set arch = `uname -s` +if ($?LD_LIBRARY_PATH) then + echo $LD_LIBRARY_PATH | grep $BASEDIR/$arch/lib > /dev/null + if ($status) then # == 1, if not found + setenv LD_LIBRARY_PATH ${LD_LIBRARY_PATH}:$BASEDIR/$arch/lib + endif +else + setenv LD_LIBRARY_PATH $BASEDIR/$arch/lib +endif + +setenv PATH $BASEDIR/$arch/bin:$PATH + + +setenv ICE_MACHINE_MACHNAME discover +setenv ICE_MACHINE_MACHINFO "Discover" +setenv ICE_MACHINE_ENVNAME intel +setenv ICE_MACHINE_ENVINFO "ifort (IFORT) 2021.3.0 20210609" +setenv ICE_MACHINE_MAKE gmake +setenv ICE_MACHINE_WKDIR /discover/nobackup/$user/CICE_RUNS +setenv ICE_MACHINE_INPUTDATA /home/bzhao/aogcm/CICE_INPUT +setenv ICE_MACHINE_BASELINE /discover/nobackup/$user/CICE_BASELINE +setenv ICE_MACHINE_SUBMIT "sbatch" +setenv ICE_MACHINE_ACCT g0609 +setenv ICE_MACHINE_QUEUE "share" +setenv ICE_MACHINE_TPNODE 36 +setenv ICE_MACHINE_BLDTHRDS 1 +setenv ICE_MACHINE_QSTAT "squeue " diff --git a/configuration/scripts/machines/env.gaea_cray b/configuration/scripts/machines/env.gaea_cray new file mode 100644 index 000000000..db62615ee --- /dev/null +++ b/configuration/scripts/machines/env.gaea_cray @@ -0,0 +1,44 @@ +#!/bin/csh -f + +set inp = "undefined" +if ($#argv == 1) then + set inp = $1 +endif + +if ("$inp" != "-nomodules") then + +#source /lustre/f2/pdata/esrl/gsd/contrib/lua-5.1.4.9/init/init_lmod.csh +source $MODULESHOME/init/csh +module purge +module load PrgEnv-cray +module load cce/18.0.0 +module load cray-libsci/24.07.0 +module load cray-hdf5/1.14.3.1 +module load cray-netcdf/4.9.0.13 +setenv NETCDF $NETCDF_DIR +module list + +# May be needed for OpenMP memory +#setenv OMP_STACKSIZE 64M + +endif + +# May be needed for OpenMP memory +#setenv OMP_STACKSIZE 64M + +endif + +setenv ICE_MACHINE_MACHNAME gaea +setenv ICE_MACHINE_MACHINFO "Cray XC40 Intel Haswell/Broadwell 2.3GHz, Gemini Interconnect" +setenv ICE_MACHINE_ENVNAME intel +setenv ICE_MACHINE_ENVINFO "ifort 18.0.5 20180823, cray-mpich, cray-netcdf" +setenv ICE_MACHINE_MAKE gmake +setenv ICE_MACHINE_WKDIR $HOME/scratch/CICE_RUNS +setenv ICE_MACHINE_INPUTDATA /ncrc/home1/Robert.Grumbine/rgdev/CICE_INPUTDATA +setenv ICE_MACHINE_BASELINE $HOME/scratch/CICE_BASELINE +setenv ICE_MACHINE_SUBMIT "sbatch" +setenv ICE_MACHINE_TPNODE 40 +setenv ICE_MACHINE_ACCT P0000000 +setenv ICE_MACHINE_QUEUE "normal" +setenv ICE_MACHINE_BLDTHRDS 1 +setenv ICE_MACHINE_QSTAT "squeue --jobs=" diff --git a/configuration/scripts/machines/env.gaea_intel b/configuration/scripts/machines/env.gaea_intel index 3601bfcfb..69bddb428 100644 --- a/configuration/scripts/machines/env.gaea_intel +++ b/configuration/scripts/machines/env.gaea_intel @@ -7,20 +7,27 @@ endif if ("$inp" != "-nomodules") then -source /lustre/f2/pdata/esrl/gsd/contrib/lua-5.1.4.9/init/init_lmod.csh +#source /lustre/f2/pdata/esrl/gsd/contrib/lua-5.1.4.9/init/init_lmod.csh +source $MODULESHOME/init/csh #module list -module purge +module load PrgEnv-intel module load intel -module load cray-mpich -module load cray-netcdf -module load PrgEnv-intel/6.0.5 +#module load intel/2023.2.0 +#module load cce/18.0.0 +module load cray-hdf5/1.14.3.1 +module load cray-netcdf/4.9.0.13 +setenv NETCDF $NETCDF_DIR +echo zzz final module list module list +#module avail intel # May be needed for OpenMP memory -#setenv OMP_STACKSIZE 64M +setenv OMP_STACKSIZE 64M endif - + +env | grep NETCDF + setenv ICE_MACHINE_MACHNAME gaea setenv ICE_MACHINE_MACHINFO "Cray XC40 Intel Haswell/Broadwell 2.3GHz, Gemini Interconnect" setenv ICE_MACHINE_ENVNAME intel diff --git a/configuration/scripts/machines/env.gaeac5_intel b/configuration/scripts/machines/env.gaeac5_intel new file mode 100644 index 000000000..69bddb428 --- /dev/null +++ b/configuration/scripts/machines/env.gaeac5_intel @@ -0,0 +1,44 @@ +#!/bin/csh -f + +set inp = "undefined" +if ($#argv == 1) then + set inp = $1 +endif + +if ("$inp" != "-nomodules") then + +#source /lustre/f2/pdata/esrl/gsd/contrib/lua-5.1.4.9/init/init_lmod.csh +source $MODULESHOME/init/csh +#module list +module load PrgEnv-intel +module load intel +#module load intel/2023.2.0 +#module load cce/18.0.0 +module load cray-hdf5/1.14.3.1 +module load cray-netcdf/4.9.0.13 +setenv NETCDF $NETCDF_DIR +echo zzz final module list +module list +#module avail intel + +# May be needed for OpenMP memory +setenv OMP_STACKSIZE 64M + +endif + +env | grep NETCDF + +setenv ICE_MACHINE_MACHNAME gaea +setenv ICE_MACHINE_MACHINFO "Cray XC40 Intel Haswell/Broadwell 2.3GHz, Gemini Interconnect" +setenv ICE_MACHINE_ENVNAME intel +setenv ICE_MACHINE_ENVINFO "ifort 18.0.5 20180823, cray-mpich, cray-netcdf" +setenv ICE_MACHINE_MAKE gmake +setenv ICE_MACHINE_WKDIR $HOME/scratch/CICE_RUNS +setenv ICE_MACHINE_INPUTDATA /ncrc/home1/Robert.Grumbine/rgdev/CICE_INPUTDATA +setenv ICE_MACHINE_BASELINE $HOME/scratch/CICE_BASELINE +setenv ICE_MACHINE_SUBMIT "sbatch" +setenv ICE_MACHINE_TPNODE 40 +setenv ICE_MACHINE_ACCT P0000000 +setenv ICE_MACHINE_QUEUE "normal" +setenv ICE_MACHINE_BLDTHRDS 1 +setenv ICE_MACHINE_QSTAT "squeue --jobs=" diff --git a/configuration/scripts/machines/env.ursa_intel b/configuration/scripts/machines/env.ursa_intel new file mode 100644 index 000000000..a4defc9e6 --- /dev/null +++ b/configuration/scripts/machines/env.ursa_intel @@ -0,0 +1,39 @@ +#!/bin/csh -f + +set inp = "undefined" +if ($#argv == 1) then + set inp = $1 +endif + +if ("$inp" != "-nomodules") then + +source /etc/profile.d/modules.csh +#module list +module purge +module load intel-oneapi-compilers/2025.1.1 +module load intel-oneapi-mpi/2021.15.0 +#module load intel-oneapi-mpi/2021.13.1 +#module load hpcx-mpi/2.18.1 +module load netcdf-c/4.9.2 +module load netcdf-fortran/4.6.1 +#module list + +endif + +# May be needed for OpenMP memory +setenv OMP_STACKSIZE 64M + +setenv ICE_MACHINE_MACHNAME ursa +setenv ICE_MACHINE_MACHINFO "AMD Genoa 9654, NDR-200-IB interconnect" +setenv ICE_MACHINE_ENVNAME intel +setenv ICE_MACHINE_ENVINFO "icx/ifx 2025.1.1.20250418, intel-oneapi-mpi-2021.15.0, netcdf-c 4.9.2, netcdf-fortran 4.6.1" +setenv ICE_MACHINE_MAKE gmake +setenv ICE_MACHINE_WKDIR $HOME/scratch/CICE_RUNS +setenv ICE_MACHINE_INPUTDATA /home/Anthony.Craig/scratch/CICE_INPUTDATA +setenv ICE_MACHINE_BASELINE $HOME/scratch/CICE_BASELINE +setenv ICE_MACHINE_SUBMIT "sbatch" +setenv ICE_MACHINE_TPNODE 192 +setenv ICE_MACHINE_ACCT marine-cpu +setenv ICE_MACHINE_QUEUE "batch" +setenv ICE_MACHINE_BLDTHRDS 1 +setenv ICE_MACHINE_QSTAT "squeue --jobs=" diff --git a/configuration/scripts/options/set_nml.bgcsklclim b/configuration/scripts/options/set_nml.bgcsklclim index c71c7bca4..885dec477 100644 --- a/configuration/scripts/options/set_nml.bgcsklclim +++ b/configuration/scripts/options/set_nml.bgcsklclim @@ -12,6 +12,7 @@ n_fed = 1 n_fep = 1 year_init = 2005 istep0 = 0 +npt_unit = '1' npt = 168 ice_ic = 'none' tr_brine = .true. diff --git a/configuration/scripts/options/set_nml.box2001 b/configuration/scripts/options/set_nml.box2001 index 2cd5923ac..ad42a4236 100644 --- a/configuration/scripts/options/set_nml.box2001 +++ b/configuration/scripts/options/set_nml.box2001 @@ -2,6 +2,7 @@ grid_atm = 'B' grid_ocn = 'B' days_per_year = 360 use_leap_years = .false. +npt_unit = '1' npt = 240 ice_ic = 'internal' restart_ext = .true. diff --git a/configuration/scripts/options/set_nml.boxnodyn b/configuration/scripts/options/set_nml.boxnodyn index 61210b5e9..fadee9994 100644 --- a/configuration/scripts/options/set_nml.boxnodyn +++ b/configuration/scripts/options/set_nml.boxnodyn @@ -2,6 +2,7 @@ nilyr = 1 ice_ic = 'internal' days_per_year = 360 use_leap_years = .false. +npt_unit = '1' npt = 72 dumpfreq = 'd' dumpfreq_n = 2 diff --git a/configuration/scripts/options/set_nml.boxopen b/configuration/scripts/options/set_nml.boxopen index bdc832f7d..84badd373 100644 --- a/configuration/scripts/options/set_nml.boxopen +++ b/configuration/scripts/options/set_nml.boxopen @@ -1,3 +1,4 @@ +npt_unit = '1' npt = 48 ice_ic = 'internal' use_leap_years = .false. diff --git a/configuration/scripts/options/set_nml.boxslotcyl b/configuration/scripts/options/set_nml.boxslotcyl index 3edd33ad8..10f0518c8 100644 --- a/configuration/scripts/options/set_nml.boxslotcyl +++ b/configuration/scripts/options/set_nml.boxslotcyl @@ -4,6 +4,7 @@ nilyr = 1 ice_ic = 'internal' restart_ext = .false. dt = 3600.0 +npt_unit = '1' npt = 288 grid_type = 'rectangular' kmt_type = 'default' diff --git a/configuration/scripts/options/set_nml.boxwallblock b/configuration/scripts/options/set_nml.boxwallblock index 5ef4cce7a..2e9a34728 100644 --- a/configuration/scripts/options/set_nml.boxwallblock +++ b/configuration/scripts/options/set_nml.boxwallblock @@ -1,5 +1,6 @@ days_per_year = 360 use_leap_years = .false. +npt_unit = '1' npt = 240 ice_ic = 'internal' restart_ext = .true. diff --git a/configuration/scripts/options/set_nml.gbox12 b/configuration/scripts/options/set_nml.gbox12 index b8a07840b..a507246b7 100644 --- a/configuration/scripts/options/set_nml.gbox12 +++ b/configuration/scripts/options/set_nml.gbox12 @@ -1,3 +1,5 @@ +dxrect = 30.e5 +dyrect = 30.e5 ice_ic = 'internal' grid_type = 'rectangular' kmt_type = 'default' diff --git a/configuration/scripts/options/set_nml.gbox128 b/configuration/scripts/options/set_nml.gbox128 index 275c02607..8d0bdb4f9 100644 --- a/configuration/scripts/options/set_nml.gbox128 +++ b/configuration/scripts/options/set_nml.gbox128 @@ -1,3 +1,5 @@ +dxrect = 3.e5 +dyrect = 3.e5 grid_ocn = 'B' ice_ic = 'internal' grid_type = 'rectangular' diff --git a/configuration/scripts/options/set_nml.gbox180 b/configuration/scripts/options/set_nml.gbox180 index b8a07840b..0fac54bd6 100644 --- a/configuration/scripts/options/set_nml.gbox180 +++ b/configuration/scripts/options/set_nml.gbox180 @@ -1,3 +1,6 @@ +dxrect = 2.e5 +dyrect = 2.e5 +dt = 1800.0 ice_ic = 'internal' grid_type = 'rectangular' kmt_type = 'default' diff --git a/configuration/scripts/options/set_nml.gbox80 b/configuration/scripts/options/set_nml.gbox80 index b8a07840b..3036d59e6 100644 --- a/configuration/scripts/options/set_nml.gbox80 +++ b/configuration/scripts/options/set_nml.gbox80 @@ -1,3 +1,5 @@ +dxrect = 5.e5 +dyrect = 5.e5 ice_ic = 'internal' grid_type = 'rectangular' kmt_type = 'default' diff --git a/configuration/scripts/options/set_nml.gx3nc b/configuration/scripts/options/set_nml.gx3nc index 1440fd676..43bde51f4 100644 --- a/configuration/scripts/options/set_nml.gx3nc +++ b/configuration/scripts/options/set_nml.gx3nc @@ -1,3 +1,3 @@ -grid_format = 'nc' +grid_format = 'pop_nc' grid_file = 'ICE_MACHINE_INPUTDATA/CICE_data/grid/gx3/grid_gx3t.nc' kmt_file = 'ICE_MACHINE_INPUTDATA/CICE_data/grid/gx3/kmt_gx3t.nc' diff --git a/configuration/scripts/options/set_nml.histall b/configuration/scripts/options/set_nml.histall index 83421aca0..2b9810bdd 100644 --- a/configuration/scripts/options/set_nml.histall +++ b/configuration/scripts/options/set_nml.histall @@ -1,3 +1,4 @@ + grid_outfile = .true. histfreq = 'm','d','1','h','x' histfreq_n = 1,2,6,4,1 histfreq_base = 'zero','zero','zero','zero','zero' @@ -159,10 +160,22 @@ f_apondn = 'md' f_apeffn = 'md' f_hpondn = 'md' + f_dpnd_flushn = 'md' + f_dpnd_exponn = 'md' + f_dpnd_freebdn = 'md' + f_dpnd_initialn= 'md' + f_dpnd_dlidn = 'md' f_apond = 'md' f_hpond = 'md' f_ipond = 'md' f_apeff = 'md' + f_dpnd_flush = 'md' + f_dpnd_expon = 'md' + f_dpnd_freebd = 'md' + f_dpnd_initial = 'md' + f_dpnd_dlid = 'md' + f_dpnd_melt = 'md' + f_dpnd_ridge = 'md' f_apond_ai = 'md' f_hpond_ai = 'md' f_ipond_ai = 'md' diff --git a/configuration/scripts/options/set_nml.pondsealvl b/configuration/scripts/options/set_nml.pondsealvl new file mode 100644 index 000000000..b92be0b90 --- /dev/null +++ b/configuration/scripts/options/set_nml.pondsealvl @@ -0,0 +1,30 @@ +apnd_sl = 0.27d0 +rfracmin = 1.0d0 +rfracmax = 1.0d0 +tr_pond_topo = .false. +tr_pond_lvl = .false. +tr_pond_sealvl = .true. +tscale_pnd_drain = 0.5d0 +f_apondn = 'm' +f_apeffn = 'm' +f_hpondn = 'm' +f_dpnd_flushn = 'm' +f_dpnd_exponn = 'm' +f_dpnd_freebdn = 'm' +f_dpnd_initialn= 'm' +f_dpnd_dlidn = 'm' +f_apond = 'm' +f_hpond = 'm' +f_ipond = 'm' +f_apeff = 'm' +f_dpnd_flush = 'm' +f_dpnd_expon = 'm' +f_dpnd_freebd = 'm' +f_dpnd_initial = 'm' +f_dpnd_dlid = 'm' +f_dpnd_melt = 'm' +f_dpnd_ridge = 'm' +f_apond_ai = 'm' +f_hpond_ai = 'm' +f_ipond_ai = 'm' +f_apeff_ai = 'm' diff --git a/configuration/scripts/options/set_nml.run10day b/configuration/scripts/options/set_nml.run10day index 05160c42d..17e711743 100644 --- a/configuration/scripts/options/set_nml.run10day +++ b/configuration/scripts/options/set_nml.run10day @@ -2,6 +2,4 @@ npt_unit = 'd' npt = 10 dumpfreq = 'd' dumpfreq_n = 10 -histfreq = 'd','x','x','x','x' -f_aice = 'd' diff --git a/configuration/scripts/options/set_nml.run10year b/configuration/scripts/options/set_nml.run10year index 0eb95071a..545c3e7c9 100644 --- a/configuration/scripts/options/set_nml.run10year +++ b/configuration/scripts/options/set_nml.run10year @@ -3,5 +3,4 @@ npt = 10 dumpfreq = 'y' dumpfreq_n = 1 diagfreq = 24 -histfreq = 'm','x','x','x','x' diff --git a/configuration/scripts/options/set_nml.run1day b/configuration/scripts/options/set_nml.run1day index a4ed751d5..1a543740f 100644 --- a/configuration/scripts/options/set_nml.run1day +++ b/configuration/scripts/options/set_nml.run1day @@ -4,5 +4,3 @@ dumpfreq = 'd' dumpfreq_n = 1 diag_type = 'stdout' print_global = .true. -histfreq = 'd','x','x','x','x' -f_aice = 'd' diff --git a/configuration/scripts/options/set_nml.run1year b/configuration/scripts/options/set_nml.run1year index 4e481870c..be66c9e41 100644 --- a/configuration/scripts/options/set_nml.run1year +++ b/configuration/scripts/options/set_nml.run1year @@ -3,5 +3,4 @@ npt = 1 dumpfreq = 'm' dumpfreq_n = 12 diagfreq = 24 -histfreq = 'm','x','x','x','x' diff --git a/configuration/scripts/options/set_nml.run2day b/configuration/scripts/options/set_nml.run2day index 60ece02f0..e846ecd34 100644 --- a/configuration/scripts/options/set_nml.run2day +++ b/configuration/scripts/options/set_nml.run2day @@ -2,6 +2,4 @@ npt_unit = 'd' npt = 2 dumpfreq = 'd' dumpfreq_n = 2 -histfreq = 'd','x','x','x','x' -f_aice = 'd' diff --git a/configuration/scripts/options/set_nml.run3day b/configuration/scripts/options/set_nml.run3day index 1a839468e..22b8a97b2 100644 --- a/configuration/scripts/options/set_nml.run3day +++ b/configuration/scripts/options/set_nml.run3day @@ -4,6 +4,3 @@ dumpfreq = 'd' dumpfreq_n = 2 diag_type = 'stdout' print_global = .true. -histfreq = 'd','x','x','x','x' -histfreq_n = 2,1,1,1,1 -f_aice = 'd' diff --git a/configuration/scripts/options/set_nml.run3dt b/configuration/scripts/options/set_nml.run3dt index 11a8c0f85..a1fc23d3e 100644 --- a/configuration/scripts/options/set_nml.run3dt +++ b/configuration/scripts/options/set_nml.run3dt @@ -1,7 +1,3 @@ npt_unit = '1' npt = 3 dump_last = .true. -histfreq = '1','x','x','x','x' -hist_avg = .false.,.false.,.false.,.false.,.false. -f_uvel = '1' -f_vvel = '1' diff --git a/configuration/scripts/options/set_nml.run5day b/configuration/scripts/options/set_nml.run5day index 88d498a89..e05318710 100644 --- a/configuration/scripts/options/set_nml.run5day +++ b/configuration/scripts/options/set_nml.run5day @@ -2,6 +2,4 @@ npt_unit = 'd' npt = 5 dumpfreq = 'd' dumpfreq_n = 5 -histfreq = 'd','x','x','x','x' -f_aice = 'd' diff --git a/configuration/scripts/options/set_nml.run60day b/configuration/scripts/options/set_nml.run60day index 96f6dea1c..d2976c129 100644 --- a/configuration/scripts/options/set_nml.run60day +++ b/configuration/scripts/options/set_nml.run60day @@ -2,5 +2,3 @@ npt_unit = 'd' npt = 60 dumpfreq = 'd' dumpfreq_n = 30 -histfreq = 'd','x','x','x','x' -f_aice = 'd' diff --git a/configuration/scripts/options/set_nml.run8year b/configuration/scripts/options/set_nml.run8year index 1515fa7c9..03eec68ed 100644 --- a/configuration/scripts/options/set_nml.run8year +++ b/configuration/scripts/options/set_nml.run8year @@ -3,5 +3,4 @@ npt = 8 dumpfreq = 'y' dumpfreq_n = 1 diagfreq = 24 -histfreq = 'm','x','x','x','x' diff --git a/configuration/scripts/options/set_nml.run90day b/configuration/scripts/options/set_nml.run90day index 34d31166f..b9ad59f96 100644 --- a/configuration/scripts/options/set_nml.run90day +++ b/configuration/scripts/options/set_nml.run90day @@ -2,5 +2,3 @@ npt_unit = 'd' npt = 90 dumpfreq = 'd' dumpfreq_n = 30 -histfreq = 'd','x','x','x','x' -f_aice = 'd' diff --git a/configuration/scripts/set_version_number.csh b/configuration/scripts/set_version_number.csh index 71cde9b48..ad14a00b3 100755 --- a/configuration/scripts/set_version_number.csh +++ b/configuration/scripts/set_version_number.csh @@ -10,6 +10,7 @@ if ( $#argv > 1 ) then endif set versno = $1 +set cdate = `date +%Y-%m-%d` #echo "$0 versno = $versno" cp -f doc/source/conf.py doc/source/conf.py.bu @@ -17,6 +18,12 @@ cp -f doc/source/conf.py doc/source/conf.py.bu sed -i 's|^.*version.*=.*$|version = u'"'"${versno}"'"' | g' doc/source/conf.py sed -i 's|^.*release.*=.*$|version = u'"'"${versno}"'"' | g' doc/source/conf.py +cp -f .zenodo.json .zenodo.json.bu + +sed -i 's|^\(.*CICE-Consortium/CICE:\).*$|\1 CICE Version '${versno}'", | g' .zenodo.json +sed -i 's|^\(.*"version":\).*$|\1 "'${versno}'", | g' .zenodo.json +sed -i 's|^\(.*"publication_date":\).*$|\1 "'${cdate}'", | g' .zenodo.json + echo "CICE ${versno}" >! cicecore/version.txt echo "$0 completed successfully" diff --git a/configuration/scripts/tests/base_suite.ts b/configuration/scripts/tests/base_suite.ts index 1e5302461..46f2c1900 100644 --- a/configuration/scripts/tests/base_suite.ts +++ b/configuration/scripts/tests/base_suite.ts @@ -24,6 +24,7 @@ restart gx3 12x2 alt03,maskhalo,droundrobin restart gx3 4x4 alt04 restart gx3 4x4 alt05,medium restart gx3 8x2 alt06 +restart gx3 8x2 pondsealvl restart gx3 16x2 snicar restart gx3 18x2 debug,maskhalo restart gx3 6x2 alt01,debug,short diff --git a/configuration/scripts/tests/io_suite.ts b/configuration/scripts/tests/io_suite.ts index 015336416..71bcd00a5 100644 --- a/configuration/scripts/tests/io_suite.ts +++ b/configuration/scripts/tests/io_suite.ts @@ -2,6 +2,11 @@ smoke gx3 32x1 run1year,histhrly,ionetcdf,iocdf2,short smoke gx3 32x1 run1year,histhrly,iopio2,iocdf5,short +# Need to check with cprnc manually, CICE tools always produce diffs between netcdf and pio +smoke gx3 8x2 histall,ionetcdf,iocdf5,run5day +#smoke gx3 8x2 histall,iopio2,iocdf5 smoke_gx3_8x2_histall_iocdf5_ionetcdf +smoke gx3 8x2 histall,iopio2,iocdf5,run5day + # some iobinary configurations fail due to bathymetry netcdf file requirement, remove them # iobinary cannot work with JRA55 because netcdf is turned off restart gx3 8x4 gx3ncarbulk,debug,histall,iobinary,precision8 @@ -48,7 +53,7 @@ restart gx3 8x4 isotope,histall,iopio1,iopnetcdf1 restart gx3 12x2 fsd12,histall,iopio1,iopnetcdf2 restart gx3 16x2 debug,histall,iopio1,iopnetcdf5,histinst -restart gx3 16x2x100x2x4 debug,histall,iopio2,iopioopts,run5day +restart gx3 16x2x100x2x4 debug,histall,iopio2,iopioopts restart gx3 16x2 debug,histall,iopio2,iopnetcdf1,precision8 restart gx3 14x2 alt01,histall,iopio2,iopnetcdf2,precision8 restart gx3 32x1 alt02,histall,iopio2,iopnetcdf5,precision8 diff --git a/configuration/scripts/tests/poll_queue.csh b/configuration/scripts/tests/poll_queue.csh index 0272a1aa9..41759ebed 100755 --- a/configuration/scripts/tests/poll_queue.csh +++ b/configuration/scripts/tests/poll_queue.csh @@ -13,10 +13,9 @@ foreach line ("`cat suite.jobs`") set qstatjob = 1 if (${job} =~ [0-9]*) then while ($qstatjob) - ${ICE_MACHINE_QSTAT} $job >&/dev/null - set qstatus = $status + set qstatus = `${ICE_MACHINE_QSTAT} $job | grep $job | wc -l` # echo $job $qstatus - if ($qstatus != 0) then + if ($qstatus == 0) then echo "Job $job completed" set qstatjob = 0 else diff --git a/configuration/tools/jra55_datasets/interp_jra55_ncdf_bilinear.py b/configuration/tools/jra55_datasets/interp_jra55_ncdf_bilinear.py index 6cc796481..00cd93832 100755 --- a/configuration/tools/jra55_datasets/interp_jra55_ncdf_bilinear.py +++ b/configuration/tools/jra55_datasets/interp_jra55_ncdf_bilinear.py @@ -287,7 +287,7 @@ def init_ncout(ncout,nc1,llat,llon): # with dimension 'time' times = dsout.createVariable('time','f8',('time',)) times.units = nc1['initial_time0_hours'].units - times.calendar = 'gregorian' + times.calendar = 'proleptic_gregorian' # loop over nc1 times dates = [] diff --git a/doc/requirements.txt b/doc/requirements.txt index 218e06d1f..8788d6ac3 100644 --- a/doc/requirements.txt +++ b/doc/requirements.txt @@ -1,5 +1,5 @@ # # -sphinxcontrib-bibtex<2.0.0 +sphinxcontrib-bibtex # # diff --git a/doc/source/cice_index.rst b/doc/source/cice_index.rst index 6b97d2b8f..949ab80b6 100644 --- a/doc/source/cice_index.rst +++ b/doc/source/cice_index.rst @@ -7,7 +7,9 @@ Index of primary variables and parameters This index defines many (but not all) of the symbols used frequently in the CICE model code. All quantities in the code are expressed in MKS units (temperatures may take -either Celsius or Kelvin units). Deprecated parameters are listed at the end. +either Celsius or Kelvin units). Deprecated parameters are listed at the end. Units are +as defined inside the model. Units on history files may be different and are documented +in history file metadata. Namelist variables are partly included here, but they are fully documented in section :ref:`tabnamelist`. @@ -27,7 +29,6 @@ section :ref:`tabnamelist`. "a4Db", "history field accumulations, 4D categories, vertical bio grid", "" "a4Ds", "history field accumulations, 4D categories, vertical snow", "" "a4Df", "history field accumulations, 4D categories, fsd", "" - "a_min", "minimum area concentration for computing velocity", "0.001" "a_rapid_mode", "brine channel diameter", "" "add_mpi_barriers", "turns on MPI barriers for communication throttling", "" "advection", "type of advection algorithm used (‘remap’ or ‘upwind’)", "remap" @@ -55,6 +56,7 @@ section :ref:`tabnamelist`. "ANGLET", "ANGLE converted to T-cells", "radians" "aparticn", "participation function", "" "apeff_ai", "grid-cell-mean effective pond fraction", "" + "apnd_sl", "equilibrium pond fraction in sealvl ponds", "" "apondn", "area concentration of melt ponds", "" "arlx1i", "relaxation constant for dynamics (stress)", "" "araftn", "area fraction of rafted ice", "" @@ -110,6 +112,8 @@ section :ref:`tabnamelist`. "cm_to_m", "cm to meters conversion", "0.01" "coldice", "value for constant albedo parameterization", "0.70" "coldsnow", "value for constant albedo parameterization", "0.81" + "cona", "history units conversion variable, multiplication term", "1.0" + "conb", "history units conversion variable, additive term", "0.0" "conduct", "conductivity parameterization", "" "congel", "basal ice growth", "m" "conserv_check", "if true, check conservation", "" @@ -204,6 +208,8 @@ section :ref:`tabnamelist`. "dvidtd", "ice volume tendency due to dynamics/transport", "m/s" "dvidtt", "ice volume tendency due to thermodynamics", "m/s" "dvirdg(n)dt", "ice volume ridging rate (category n)", "m/s" + "dyn_area_min", "minimum area concentration for computing velocity", "0.001" + "dyn_mass_min", "minimum mass for computing velocity", "0.01 kg/m\ :math:`^2`" "**E**", "", "" "e11, e12, e22", "strain rate tensor components", "" "earea", "area of E-cell", "m\ :math:`^2`" @@ -303,7 +309,8 @@ section :ref:`tabnamelist`. "grid_ocn_dynu", "grid for ocn dynamic-u forcing/coupling fields, 'T', 'U', 'N', 'E'", "" "grid_ocn_dynv", "grid for ocn dynamic-v forcing/coupling fields, 'T', 'U', 'N', 'E'", "" "grid_ocn_thrm", "grid for ocn thermodynamic forcing/coupling fields, 'T', 'U', 'N', 'E'", "" - "grid_type", "‘rectangular’, ‘displaced_pole’, ‘column’ or ‘regional’", "" + "grid_outfile", "write one-time grid history file", "" + "grid_type", "grid input file type, ‘rectangular’, ‘displaced_pole’, 'tripole', etc", "" "gridcpl_file", "input file for coupling grid info", "" "grow_net", "specific biogeochemistry growth rate per grid cell", "s :math:`^{-1}`" "Gstar", "piecewise-linear ridging participation function parameter", "0.15" @@ -402,7 +409,7 @@ section :ref:`tabnamelist`. "ktherm", "thermodynamic formulation (-1 = off, 1 = :cite:`Bitz99`, 2 = mushy)", "" "**L**", "", "" "l_brine", "flag for brine pocket effects", "" - "l_fixed_area", "flag for prescribing remapping fluxes", "" + "l_edge_flux_adj", "flag for prescribing remapping fluxes", "" "l_mpond_fresh", "if true, retain (topo) pond water until ponds drain", "" "latpnt", "desired latitude of diagnostic points", "degrees N" "latt(u)_bounds", "latitude of T(U) grid cell corners", "degrees N" @@ -418,7 +425,6 @@ section :ref:`tabnamelist`. "ltripole_grid", "flag to signal use of tripole grid", "" "Lvap", "latent heat of vaporization for fresh water", "2.501\ :math:`\times` 10\ :math:`^6` J/kg" "**M**", "", "" - "m_min", "minimum mass for computing velocity", "0.01 kg/m\ :math:`^2`" "m_to_cm", "meters to cm conversion", "100." "m1", "constant for lateral melt rate", "1.6\ :math:`\times`\ 10\ :math:`^{-6}` m/s deg\ :math:`^{-m2}`" "m2", "constant for lateral melt rate", "1.36" @@ -624,6 +630,7 @@ section :ref:`tabnamelist`. "runtype", "type of initialization used", "" "**S**", "", "" "s11, s12, s22", "stress tensor components", "" + "saltflux_option", "form of coupled salt flux ", "" "saltmax", "max salinity, at ice base (:cite:`Bitz99`)", "3.2 ppt" "scale_factor", "scaling factor for shortwave radiation components", "" "seabed_stress", "if true, calculate seabed stress", "F" @@ -692,7 +699,6 @@ section :ref:`tabnamelist`. "Tf", "freezing temperature", "C" "Tffresh", "freezing temp of fresh ice", "273.15 K" "tfrz_option", "form of ocean freezing temperature", "" - "saltflux_option", "form of coupled salt flux ", "" "thinS", "minimum ice thickness for brine tracer", "" "timer_stats", "logical to turn on extra timer statistics", ".false." "timesecs", "total elapsed time in seconds", "s" @@ -717,6 +723,7 @@ section :ref:`tabnamelist`. "tr_iage", "if true, use ice age tracer", "" "tr_lvl", "if true, use level ice area and volume tracers", "" "tr_pond_lvl", "if true, use level-ice melt pond scheme", "" + "tr_pond_sealvl", "if true, use sea level melt pond scheme", "" "tr_pond_topo", "if true, use topo melt pond scheme", "" "trcr", "ice tracers", "" "trcr_depend", "tracer dependency on basic state variables", "" @@ -724,6 +731,7 @@ section :ref:`tabnamelist`. "trestore", "restoring time scale", "days" "tripole", "if true, block lies along tripole boundary", "" "tripoleT", "if true, tripole boundary is T-fold; if false, U-fold", "" + "tscale_pnd_drain", "mushy macroscopic drainage timescale", "days" "Tsf_errmax", "max allowed :math:`T_{\mathit sf}` error (thermodynamics)", "5.\ :math:`\times`\ 10\ :math:`^{-4}`\ deg" "Tsfc(n)", "temperature of ice/snow top surface (in category n)", "C" "Tsnz", "Internal snow temperature", "C" diff --git a/doc/source/conf.py b/doc/source/conf.py index 86760baaa..a71bef070 100644 --- a/doc/source/conf.py +++ b/doc/source/conf.py @@ -57,7 +57,7 @@ # General information about the project. project = u'CICE' -copyright = u'2024, Triad National Security, LLC (code) and National Center for Atmospheric Research (documentation)' +copyright = u'1998, 2017, Triad National Security, LLC (code) and National Center for Atmospheric Research (documentation)' author = u'CICE-Consortium' # The version info for the project you're documenting, acts as replacement for @@ -65,9 +65,9 @@ # built documents. # # The short X.Y version. -version = u'6.6.0' +version = u'6.6.1' # The full version, including alpha/beta/rc tags. -version = u'6.6.0' +version = u'6.6.1' # The language for content autogenerated by Sphinx. Refer to documentation # for a list of supported languages. diff --git a/doc/source/intro/copyright.rst b/doc/source/intro/copyright.rst index 8ddeef022..c72da7fbd 100644 --- a/doc/source/intro/copyright.rst +++ b/doc/source/intro/copyright.rst @@ -5,37 +5,9 @@ Copyright ============================= -© Copyright 2024, Triad National Security LLC. All rights reserved. -This software was produced under U.S. Government contract -89233218CNA000001 for Los Alamos National Laboratory (LANL), which is -operated by Triad National Security, LLC for the U.S. Department -of Energy. The U.S. Government has rights to use, reproduce, and distribute -this software. NEITHER THE GOVERNMENT NOR TRIAD NATIONAL SECURITY, LLC -MAKES ANY WARRANTY, EXPRESS OR IMPLIED, OR ASSUMES ANY LIABILITY FOR THE USE -OF THIS SOFTWARE. If software is modified to produce derivative works, such -modified software should be clearly marked, so as not to confuse it with the -version available from LANL. - -Additionally, redistribution and use in source and binary forms, with or -without modification, are permitted provided that the following conditions -are met: - -- Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. - -- Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. - -- Neither the name of Triad National Security, LLC, Los Alamos National Laboratory, LANL, the U.S. Government, nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY TRIAD NATIONAL SECURITY, LLC AND -CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT -NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL TRIAD NATIONAL -SECURITY, LLC OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED -TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR -PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF -LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING -NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +© Copyright 1998, 2017, Triad National Security, LLC +All rights reserved. +This program was produced under U.S. Government contract 89233218CNA000001 for Los Alamos National Laboratory (LANL), which is operated by Triad National Security, LLC for the U.S. Department of Energy/National Nuclear Security Administration. All rights in the program are reserved by Triad National Security, LLC, and the U.S. Department of Energy/National Nuclear Security Administration. The Government is granted for itself and others acting on its behalf a nonexclusive, paid-up, irrevocable worldwide license in this material to reproduce, prepare. derivative works, distribute copies to the public, perform publicly and display publicly, and to permit others to do so. +This program is Open-Source under the BSD-3 License. diff --git a/doc/source/master_list.bib b/doc/source/master_list.bib index a7c3a1174..6e3bb9b40 100644 --- a/doc/source/master_list.bib +++ b/doc/source/master_list.bib @@ -1092,6 +1092,18 @@ @Article{Dupont22 url = {https://doi.org/10.5194/tc-16-1963-2022} } +@Article{Lemieux24, +AUTHOR = {Lemieux, J.-F. and Lipscomb, W. H. and Craig, A. and Bailey, D. A. and Hunke, E. C. and Blain, P. and Rasmussen, T. A. S. and Bentsen, M. and Dupont, F. and Hebert, D. and Allard, R.}, +TITLE = {CICE on a C-grid: new momentum, stress, and transport schemes for CICEv6.5}, +JOURNAL = {GMD}, +VOLUME = {17}, +YEAR = {2024}, +NUMBER = {17}, +PAGES = {6703--6724}, +URL = {https://gmd.copernicus.org/articles/17/6703/2024/}, +DOI = {10.5194/gmd-17-6703-2024} +} + @Article{Tsujino18, author = "H. Tsujino and S. Urakawa and R.J. Small and W.M. Kim and S.G. Yeager and et al.", title = "{JRA‐55 based surface dataset for driving ocean–sea‐ice models (JRA55‐do)}", diff --git a/doc/source/science_guide/sg_dynamics.rst b/doc/source/science_guide/sg_dynamics.rst index 978da7fcb..ce9c3c4ee 100644 --- a/doc/source/science_guide/sg_dynamics.rst +++ b/doc/source/science_guide/sg_dynamics.rst @@ -96,6 +96,10 @@ Note that the VP solver has not yet been tested on the ``tx1`` grid. The EVP, rEVP, EAP and VP approaches are all available with the B grid. However, at the moment, only the EVP and rEVP schemes are possible with the C grid. +The dynamics are solved for all gridcells with area concentration greater than ``dyn_area_min`` and mass +greater than ``dyn_mass_min``. These parameters are respectively 0.001 and 0.01 by default but can be set in +namelist. Lower values can improve the solution but also lead to instabilities. + Here we summarize the equations and direct the reader to the above references for details. diff --git a/doc/source/science_guide/sg_horiztrans.rst b/doc/source/science_guide/sg_horiztrans.rst index 4ccf00e9b..590d007ba 100644 --- a/doc/source/science_guide/sg_horiztrans.rst +++ b/doc/source/science_guide/sg_horiztrans.rst @@ -453,7 +453,7 @@ Each departure triangle is defined by three of the seven points (CL, CR, DL, DR, IL, IR, IC). Given a 2D velocity field **u**, the divergence -:math:`\nabla\cdot{\bf u}` in a given grid cell can be computed from the +:math:`\nabla\cdot{\bf u}` in a given grid cell (B grid) can be computed from the local velocities and written in terms of fluxes across each cell edge: .. math:: @@ -466,11 +466,11 @@ the divergence computed in the EVP dynamics (Section :ref:`dynam`). In general, the fluxes in this expression are not equal to those implied by the above scheme for locating departure regions. For some applications it may be desirable to prescribe the divergence by -prescribing the area of the departure region for each edge. This can be -done by setting `l\_fixed\_area` = true in -**ice\_transport\_driver.F90** and passing the prescribed departure -areas (`edgearea\_e` and `edgearea\_n`) into the remapping routine. An extra -triangle is then constructed for each departure region to ensure that +prescribing the area of the departure region for each edge. We refer to +this as the edge flux adjustment (EFA) method. The EFA method is used +when `l\_edge_flux_adj` = true. In this case the prescribed departure +areas (`edgearea\_e` and `edgearea\_n`) are calculated in the remapping routine. +An extra triangle is then constructed for each departure region to ensure that the total area is equal to the prescribed value. This idea was suggested and first implemented by Mats Bentsen of the Nansen Environmental and Remote Sensing Center (Norway), who applied an earlier version of the @@ -479,15 +479,14 @@ is somewhat more general, allowing for departure regions lying on both sides of a cell edge. The extra triangle is constrained to lie in one but not both of the grid cells that share the edge. -The default value for the B grid is `l\_fixed\_area` = false. However, +The default value for the B grid is `l\_edge_flux_adj` = false. However, idealized tests with the C grid have shown that prognostic fields such as sea ice concentration exhibit a checkerboard pattern with -`l\_fixed\_area` = false. The logical `l\_fixed\_area` is therefore set +`l\_edge_flux_adj` = false :cite:`Lemieux24`. The logical `l\_edge_flux_adj` is therefore set to true when using the C grid. The edge areas `edgearea\_e` and `edgearea\_n` are in this case calculated with the C grid velocity components :math:`uvelE` and :math:`vvelN`. - We made one other change in the scheme of :cite:`Dukowicz00` for locating triangles. In their paper, departure points are defined by projecting cell corner velocities directly backward. That is, diff --git a/doc/source/science_guide/sg_tracers.rst b/doc/source/science_guide/sg_tracers.rst index 5935fe67e..31747d20c 100644 --- a/doc/source/science_guide/sg_tracers.rst +++ b/doc/source/science_guide/sg_tracers.rst @@ -78,7 +78,10 @@ is not in use. "tr_FY", "1", "aice", "nt_FY", " " "tr_lvl", "2", "aice", "nt_alvl", " " " ", " ", "vice", "nt_vlvl", " " - "tr_pond_lvl", "3", "aice", "nt_apnd", " " + "tr_pond_lvl", "3", "alvl", "nt_apnd", " " + " ", " ", "apnd", "nt_vpnd", " " + " ", " ", "apnd", "nt_ipnd", " " + "tr_pond_sealvl", "3", "aice", "nt_apnd", " " " ", " ", "apnd", "nt_vpnd", " " " ", " ", "apnd", "nt_ipnd", " " "tr_pond_topo", "3", "aice", "nt_apnd", " " diff --git a/doc/source/user_guide/ug_case_settings.rst b/doc/source/user_guide/ug_case_settings.rst index 9bfd3a65b..2f705e64c 100644 --- a/doc/source/user_guide/ug_case_settings.rst +++ b/doc/source/user_guide/ug_case_settings.rst @@ -185,8 +185,8 @@ setup_nml "", "``y1``", "write restart once after ``dumpfreq_n`` years", "" "", "``1``", "write restart every ``dumpfreq_n`` time steps", "" "", "``11``", "write restart once after ``dumpfreq_n`` time steps", "" - "``dumpfreq_base``", "init", "restart output frequency relative to year_init, month_init, day_init", "'init','init','init','init','init'" - "", "zero", "restart output frequency relative to year-month-day of 0000-01-01", "" + "``dumpfreq_base``", "``init``", "restart output frequency relative to year_init, month_init, day_init", "'init','init','init','init','init'" + "", "``zero``", "restart output frequency relative to year-month-day of 0000-01-01", "" "``dumpfreq_n``", "integer array", "write restart frequency with ``dumpfreq``", "1,1,1,1,1" "``dump_last``", "logical", "write restart on last time step of simulation", "``.false.``" "``histfreq``", "``d``", "write history every ``histfreq_n`` days", "'1','h','d','m','y'" @@ -195,8 +195,8 @@ setup_nml "", "``x``", "unused frequency stream (not written)", "" "", "``y``", "write history every ``histfreq_n`` years", "" "", "``1``", "write history every ``histfreq_n`` time step", "" - "``histfreq_base``", "init", "history output frequency relative to year_init, month_init, day_init", "'zero','zero','zero','zero','zero'" - "", "zero", "history output frequency relative to year-month-day of 0000-01-01", "" + "``histfreq_base``", "``init``", "history output frequency relative to year_init, month_init, day_init", "'zero','zero','zero','zero','zero'" + "", "``zero``", "history output frequency relative to year-month-day of 0000-01-01", "" "``histfreq_n``", "integer array", "frequency history output is written with ``histfreq``", "1,1,1,1,1" "``history_chunksize``", "integer array", "chunksizes (x,y) for history output (hdf5 only)", "0,0" "``history_deflate``", "integer", "compression level (0 to 9) for history output (hdf5 only)", "0" @@ -215,9 +215,9 @@ setup_nml "", "``pnetcdf5``", "write history files with pnetcdf cdf5 (netcdf3-64bit-data) format", "" "``history_iotasks``", "integer", "pe io tasks for history output with history_root and history_stride (PIO only), -99=internal default", "-99" "``history_precision``", "integer", "history file precision: 4 or 8 byte", "4" - "``history_rearranger``", "box", "box io rearranger option for history output (PIO only)", "default" - "", "default", "internal default io rearranger option for history output", "" - "", "subset", "subset io rearranger option for history output", "" + "``history_rearranger``", "``box``", "box io rearranger option for history output (PIO only)", "default" + "", "``default``", "internal default io rearranger option for history output", "" + "", "``subset``", "subset io rearranger option for history output", "" "``history_root``", "integer", "pe root task for history output with history_iotasks and history_stride (PIO only), -99=internal default", "-99" "``history_stride``", "integer", "pe stride for history output with history_iotasks and history_root (PIO only), -99=internal default", "-99" "``hist_avg``", "logical", "write time-averaged data", "``.true.,.true.,.true.,.true.,.true.``" @@ -266,9 +266,9 @@ setup_nml "", "``pnetcdf2``", "write restart files with pnetcdf cdf2 (netcdf3-64bit-offset) format", "" "", "``pnetcdf5``", "write restart files with pnetcdf cdf5 (netcdf3-64bit-data) format", "" "``restart_iotasks``", "integer", "pe io tasks for restart output with restart_root and restart_stride (PIO only), -99=internal default", "-99" - "``restart_rearranger``", "box", "box io rearranger option for restart output (PIO only)", "default" - "", "default", "internal default io rearranger option for restart output", "" - "", "subset", "subset io rearranger option for restart output", "" + "``restart_rearranger``", "``box``", "box io rearranger option for restart output (PIO only)", "default" + "", "``default``", "internal default io rearranger option for restart output", "" + "", "``subset``", "subset io rearranger option for restart output", "" "``restart_root``", "integer", "pe root task for restart output with restart_iotasks and restart_stride (PIO only), -99=internal default", "-99" "``restart_stride``", "integer", "pe stride for restart output with restart_iotasks and restart_root (PIO only), -99=internal default", "-99" "``runid``", "string", "label for run (currently CESM only)", "'unknown'" @@ -293,7 +293,7 @@ grid_nml "", "", "", "" "``bathymetry_file``", "string", "name of bathymetry file to be read", "'unknown_bathymetry_file'" "``bathymetry_format``", "``default``", "NetCDF depth field", "'default'" - "", "``pop``", "pop thickness file in cm in ascii format", "" + "", "``pop``", "POP thickness file in cm in ascii format", "" "``close_boundaries``", "logical", "force two gridcell wide land mask on boundaries for rectangular grids", "``.false.``" "``dxrect``", "real", "x-direction grid spacing for rectangular grid in cm", "0.0" "``dxscale``", "real", "user defined rectgrid x-grid scale factor", "1.0" @@ -306,30 +306,37 @@ grid_nml "", "``CD``", "atm forcing/coupling grid, thermo fields on T grid, dyn fields on N and E grid", "" "``grid_file``", "string", "name of grid file to be read", "'unknown_grid_file'" "``grid_format``", "``bin``", "read direct access grid and kmt files", "``bin``" - "", "``nc``", "read grid and kmt files", "" + "", "``geosnc``", "read grid and kmt file in GEOS netcdf format", "" + "", "``pop_nc``", "read grid and kmt files in POP netcdf format", "" + "", "``meshnc``", "coupled model grid option, no CICE code support", "" + "", "``mom_nc``", "read grid in MOM (supergrid) format and kmt files", "" "``grid_ice``", "``B``", "use B grid structure with T at center and U at NE corner", "``B``" "", "``C``", "use C grid structure with T at center, U at E edge, V at N edge", "" "``grid_ocn``", "``A``", "ocn forcing/coupling grid, all fields on T grid", "``A``" "", "``B``", "ocn forcing/coupling grid, thermo fields on T grid, dyn fields on U grid", "" "", "``C``", "ocn forcing/coupling grid, thermo fields on T grid, dynu fields on E grid, dynv fields on N grid", "" "", "``CD``", "ocn forcing/coupling grid, thermo fields on T grid, dyn fields on N and E grid", "" - "``grid_type``", "``displaced_pole``", "read from file in *popgrid*", "``rectangular``" - "", "``rectangular``", "defined in *rectgrid*", "" - "", "``regional``", "read from file in *popgrid*", "" - "", "``tripole``", "read from file in *popgrid*", "" + "``grid_outfile``", "logical", "write one-time grid history file", "``.false.``" + "``grid_type``", "``column``", "latlon grid with single column set", "``rectangular``" + "", "``displaced_pole``", "read from file of type grid_format", "" + "", "``latlon``", "read in from file in subroutine *latlongrid*", "" + "", "``rectangular``", "defined in subroutine *rectgrid*", "" + "", "``regional``", "read from file of type grid_format", "" + "", "``tripole``", "read from file of type grid_format", "" "``kcatbound``", "``-1``", "single category formulation", "1" "", "``0``", "old formulation", "" "", "``1``", "new formulation with round numbers", "" "", "``2``", "WMO standard categories", "" "", "``3``", "asymptotic scheme", "" "``kmt_file``", "string", "name of land mask file to be read", "``unknown_kmt_file``" - "``kmt_type``", "boxislands", "ocean/land mask set internally, complex test geometory", "file" - "", "channel", "ocean/land mask set internally as zonal channel", "" - "", "channel_oneeast", "ocean/land mask set internally as single gridcell east-west zonal channel", "" - "", "channel_onenorth", "ocean/land mask set internally as single gridcell north-south zonal channel", "" - "", "default", "ocean/land mask set internally, land in upper left and lower right of domain, ", "" - "", "file", "ocean/land mask setup read from file, see kmt_file", "" - "", "wall", "ocean/land mask set at right edge of domain", "" + "``kmt_type``", "``boxislands``", "ocean/land mask set internally, complex test geometory", "file" + "", "``channel``", "ocean/land mask set internally as zonal channel", "" + "", "``channel_oneeast``", "ocean/land mask set internally as single gridcell east-west zonal channel", "" + "", "``channel_onenorth``", "ocean/land mask set internally as single gridcell north-south zonal channel", "" + "", "``default``", "ocean/land mask set internally, land in upper left and lower right of domain, ", "" + "", "``file``", "ocean/land mask setup read from file, see kmt_file", "" + "", "``wall``", "ocean/land mask set at right edge of domain", "" + "", "``none``", "no ocean/land mask set, i.e. no land cells, for idealized testing and development only", "" "``latrefrect``","real","lower left corner lat for rectgrid in deg", "71.35" "``lonrefrect``","real","lower left corner lon for rectgrid in deg", "-156.5" "``nblyr``", "integer", "number of zbgc layers", "0" @@ -361,8 +368,9 @@ domain_nml "", "``spacecurve``", "distribute blocks via space-filling curves", "" "", "``spiralcenter``", "distribute blocks via roundrobin from center of grid outward in a spiral", "" "", "``wghtfile``", "distribute blocks based on weights specified in ``distribution_wght_file``", "" - "``distribution_wght``", "``block``", "full block weight method with land block elimination", "``latitude``" - "", "``blockall``", "full block weight method without land block elimination", "" + "``distribution_wght``", "``block``", "block weighted method with land block elimination", "``latitude``" + "", "``blockall``", "block method with NO land block elimination and minimum weight given to land blocks", "" + "", "``blockfull``", "block method with NO land block elimination and full weight given to land blocks", "" "", "``latitude``", "latitude/ocean sets ``work_per_block``", "" "``distribution_wght_file``", "string", "distribution weight file when distribution_type is ``wghtfile``", "'unknown'" "``ew_boundary_type``", "``cyclic``", "periodic boundary conditions in x-direction", "``cyclic``" @@ -410,8 +418,9 @@ tracer_nml "``tr_iage``", "logical", "ice age", "``.false.``" "``tr_iso``", "logical", "isotopes", "``.false.``" "``tr_lvl``", "logical", "level ice area and volume", "``.false.``" - "``tr_pond_lvl``", "logical", "level-ice melt ponds", "``.false.``" "``tr_pond_cesm``", " ", "DEPRECATED", " " + "``tr_pond_lvl``", "logical", "level-ice melt ponds", "``.false.``" + "``tr_pond_sealvl``", "logical", "sea-level melt ponds", "``.false.``" "``tr_pond_topo``", "logical", "topo melt ponds", "``.false.``" "``tr_snow``", "logical", "advanced snow physics", "``.false.``" "``restart_aero``", "logical", "restart tracer values from file", "``.false.``" @@ -421,6 +430,7 @@ tracer_nml "``restart_iso``", "logical", "restart tracer values from file", "``.false.``" "``restart_lvl``", "logical", "restart tracer values from file", "``.false.``" "``restart_pond_lvl``", "logical", "restart tracer values from file", "``.false.``" + "``restart_pond_sealvl``", "logical", "restart tracer values from file", "``.false.``" "``restart_pond_topo``", "logical", "restart tracer values from file", "``.false.``" "``restart_snow``", "logical", "restart snow tracer values from file", "``.false.``" "", "", "", "" @@ -455,6 +465,7 @@ thermo_nml "``phi_i_mushy``", ":math:`0<\phi_i < 1`", "solid fraction at lower boundary", "0.85" "``Rac_rapid_mode``", "real", "critical Rayleigh number", "10.0" "``Tliquidus_max``", "real", "maximum liquidus temperature of mush (C)", "0.0" + "``tscale_pnd_drain``", "real", "mushy macroscopic drainage timescale (days)", "10" "", "", "", "" @@ -496,6 +507,8 @@ dynamics_nml "``deltaminVP``", "real", "minimum delta for viscosities", "2e-9" "``dim_fgmres``", "integer", "maximum number of Arnoldi iterations for FGMRES solver", "50" "``dim_pgmres``", "integer", "maximum number of Arnoldi iterations for PGMRES preconditioner", "5" + "``dyn_area_min``", "real", "min ice area concentration to activate dynamics", "0.001" + "``dyn_mass_min``", "real", "min ice mass to activate dynamics (kg/m\ :math:`^2`)", "0.01" "``e_plasticpot``", "real", "aspect ratio of elliptical plastic potential", "2.0" "``e_yieldcurve``", "real", "aspect ratio of elliptical yield curve", "2.0" "``elasticDamp``", "real", "elastic damping parameter", "0.36" @@ -558,7 +571,7 @@ shortwave_nml "", "", "", "" "``ahmax``", "real", "albedo is constant above this thickness in meters", "0.3" - "``albedo_type``", "`ccsm3``", "NCAR CCSM3 albedo implementation", "``ccsm3``" + "``albedo_type``", "``ccsm3``", "NCAR CCSM3 albedo implementation", "``ccsm3``" "", "``constant``", "four constant albedos", "" "``albicei``", ":math:`0<\alpha <1`", "near infrared ice albedo for thicker ice", "0.36" "``albicev``", ":math:`0<\alpha <1`", "visible ice albedo for thicker ice", "0.78" @@ -588,6 +601,7 @@ ponds_nml :widths: 15, 15, 30, 15 "", "", "", "" + "``apnd_sl``", "real", "equilibrium pond fraction in sealvl ponds", "0.27" "``dpscale``", "real", "time scale for flushing in permeable ice", "1.0" "``frzpnd``", "``cesm``", "CESM pond refreezing forumulation", "``cesm``" "", "``hlid``", "Stefan refreezing with pond ice thickness", "" @@ -619,9 +633,9 @@ snow_nml "", "``ITD``", "ITD snow redistribution scheme", "" "", "``ITDrdg``", "ITDrdg snow redistribution scheme", "" "", "``none``", "snow redistribution scheme off", "" - "``snw_aging_table``", "file", "read 1D and 3D fields for dry metamorophsis lookup table", "test" - "", "snicar", "read 3D fields for dry metamorophsis lookup table", "" - "", "test", "internally generated dry metamorophsis lookup table for testing", "" + "``snw_aging_table``", "'file'", "read 1D and 3D fields for dry metamorophsis lookup table", "test" + "", "``snicar``", "read 3D fields for dry metamorophsis lookup table", "" + "", "``test``", "internally generated dry metamorophsis lookup table for testing", "" "``snw_drdt0_fname``", "string", "snow aging file drdt0 fieldname", "unknown" "``snw_filename``", "string", "snow aging table data filename", "unknown" "``snw_kappa_fname``", "string", "snow aging file kappa fieldname", "unknown" @@ -647,10 +661,9 @@ forcing_nml :widths: 15, 15, 30, 15 "", "", "", "" - "``atmbndy``", "string", "bulk transfer coefficients", "``similarity``" - "", "``similarity``", "stability-based boundary layer", "" - "", "``constant``", "constant-based boundary layer", "" + "``atmbndy``", "``constant``", "constant-based bulk transfer coeff boundary layer", "``similarity``" "", "``mixed``", "stability-based boundary layer for wind stress, constant-based for sensible+latent heat fluxes", "" + "", "``similarity``", "stability-based bulk transfer coeff boundary layer", "" "``atmiter_conv``", "real", "convergence criteria for ustar", "0.0" "``atm_data_dir``", "string", "path or partial path to atmospheric forcing data directory", "" "``atm_data_format``", "``bin``", "read direct access binary atmo forcing file format", "``bin``" @@ -708,8 +721,7 @@ forcing_nml "", "``uniform``", "ice defined at all grid points", "" "``ice_ref_salinity``", "real", "sea ice salinity for coupling fluxes (ppt)", "4.0" "``iceruf``", "real", "ice surface roughness at atmosphere interface in meters", "0.0005" - "``l_mpond_fresh``", "``.false.``", "release pond water immediately to ocean", "``.false.``" - "", "``true``", "retain (topo) pond water until ponds drain", "" + "``l_mpond_fresh``", "logical", "retain (topo) pond water until ponds drain", "``.false.``" "``natmiter``", "integer", "number of atmo boundary layer iterations", "5" "``nfreq``", "integer", "number of frequencies in ocean surface wave spectral forcing", "25" "``oceanmixed_file``", "string", "data file containing ocean forcing data", "'unknown_oceanmixed_file'" @@ -731,6 +743,7 @@ forcing_nml "``rotate_wind``", "logical", "rotate wind from east/north to computation grid", "``.true.``" "``saltflux_option``", "``constant``", "computed using ice_ref_salinity", "``constant``" "", "``prognostic``", "computed using prognostic salinity", "" + "``semi-implicit_Tsfc``", "logical", "surface temperature coupling option based on d(hf)/dTs", "``.false.``" "``tfrz_option``","``constant``", "constant ocean freezing temperature (Tocnfrz)","``mushy``" "", "``linear_salt``", "linear function of salinity (ktherm=1)", "", "``minus1p8``", "constant ocean freezing temperature (:math:`-1.8^{\circ} C`)", "" @@ -739,6 +752,7 @@ forcing_nml "``ustar_min``", "real", "minimum value of ocean friction velocity in m/s", "0.0005" "``update_ocn_f``", "``.false.``", "do not include frazil water/salt fluxes in ocn fluxes", "``.false.``" "", "``true``", "include frazil water/salt fluxes in ocn fluxes", "" + "``vapor_flux_correction``", "logical", "water vapor deposition/sublimation correction associated with an assumed temperature", "``.false.``" "``wave_spec_file``", "string", "data file containing wave spectrum forcing data", "" "``wave_spec_type``", "``constant``", "wave data file is provided, constant wave spectrum, for testing", "``none``" "", "``none``", "no wave data provided, no wave-ice interactions", "" @@ -802,7 +816,6 @@ zbgc_nml "``f_exude_s``", "real", "fraction of exudation to DOC saccharids", "1.0" "``grid_o``", "real", "z biology for bottom flux", "0.006" "``grid_o_t``", "real", "z biology for top flux", "0.006" - "``grid_oS``", "real", "zsalinity DEPRECATED", "" "``grow_Tdep_diatoms``", "real", "temperature dependence growth diatoms per degC", "0.063" "``grow_Tdep_phaeo``", "real", "temperature dependence growth phaeocystis per degC", "0.063" "``grow_Tdep_sp``", "real", "temperature dependence growth small plankton per degC", "0.063" @@ -828,7 +841,6 @@ zbgc_nml "``K_Sil_sp``", "real", "silicate half saturation small plankton mmol/m^3", "0.0" "``kn_bac_protein``", "real", "bacterial degradation of DON per day", "0.2" "``l_sk``", "real", "characteristic diffusive scale in m", "2.0" - "``l_skS``", "real", "zsalinity DEPRECATED", "" "``max_dfe_doc1``", "real", "max ratio of dFe to saccharides in the ice in nm Fe / muM C", "0.2" "``max_loss``", "real", "restrict uptake to percent of remaining value", "0.9" "``modal_aero``", "logical", "modal aerosols", "``.false.``" @@ -868,14 +880,12 @@ zbgc_nml "``ratio_S2N_sp``", "real", "algal S to N in mol/mol small plankton", "0.03" "``restart_bgc``", "logical", "restart tracer values from file", "``.false.``" "``restart_hbrine``", "logical", "", "``.false.``" - "``restart_zsal``", "logical", "zsalinity DEPRECATED", "``.false.``" "``restore_bgc``", "logical", "restore bgc to data", "``.false.``" "``R_dFe2dust``", "real", "g/g :cite:`Tagliabue09`", "0.035" "``scale_bgc``", "logical", "", "``.false.``" "``silicatetype``", "real", "mobility type between stationary and mobile silicate", "-1.0" "``skl_bgc``", "logical", "skeletal biogeochemistry DEPRECATED", "``.false.``" "``solve_zbgc``", "logical", "", "``.false.``" - "``solve_zsal``", "logical", "zsalinity DEPRECATED, update salinity tracer profile", "``.false.``" "``tau_max``", "real", "long time mobile to stationary exchanges", "604800." "``tau_min``", "real", "rapid module to stationary exchanges", "3600." "``tr_bgc_Am``", "logical", "ammonium tracer", "``.false.``" diff --git a/doc/source/user_guide/ug_implementation.rst b/doc/source/user_guide/ug_implementation.rst index 0e03c2f13..69c288ee8 100644 --- a/doc/source/user_guide/ug_implementation.rst +++ b/doc/source/user_guide/ug_implementation.rst @@ -32,6 +32,9 @@ The present code distribution includes source code and scripts. Forcing data is available from the ftp site. The directory structure of CICE is as follows +**COPYRIGHT.pdf** + copyright notice + **LICENSE.pdf** license for using and sharing the code @@ -133,8 +136,10 @@ The user has several ways to initialize the grid, which can be read from files or created internally. The *rectgrid* code creates a regular rectangular grid (use the namelist option ``grid_type='rectangular'``). The *popgrid* and *popgrid_nc* code reads grid lengths and other parameters for a nonuniform grid (including tripole -and regional grids). -The input files **grid_gx3.bin** and **kmt_gx3.bin** contain the +and regional grids). The *mom_grid* code reads grids for a nonuniform grid defined +in the mom mosaic (supergrid) format. + +For the *popgrid* formats, the input files **grid_gx3.bin** and **kmt_gx3.bin** contain the :math:`\left<3^\circ\right>` POP grid and land mask; **grid_gx1.bin** and **kmt_gx1.bin** contain the :math:`\left<1^\circ\right>` grid and land mask, and **grid_tx1.bin** @@ -146,14 +151,22 @@ The are also input files in netcdf format for the **gx3** grid, (**grid_gx3.nc** and **kmt_gx3.nc**) which can serve as a template for defining other grids. At a minimum the grid file needs to to contain ULAT, ULON, HTN, HTE and ANGLE variables. If the variables exist, ANGLET, TLON and TLAT will also be -read from a netcdf grid file. The kmt (mask) netcdf file needs a variable named -kmt or mask, set to 0 for land and 1 for ocean. +read from a netcdf grid file, otherwise they will be derived internally. + +For the *mom_nc* formats (``grid_format='mom_nc'``), a grid file following +the MOM supergrid convention as generated by `FRE-NCTools `_ +and described in `this short summary `_ +is required. CICE derives the required grid variables to match the grid implementation +in MOM6. All lat/lon and grid lengths are read from the file. Cell areas for A & B grid +cells are loaded from the file, and cell areas for C grid cells are calculated internally. +Rotation angles for cells are also calculated interally. All calculations match the methods +used in MOM6 for consistency. + +The kmt (mask) netcdf file is used with both pop netcdf and mom netcdf grids. +It needs a variable named kmt or mask, set to 0 for land and 1 for ocean. -The input grid file for the B-grid and CD-grid is identical. That file -contains each cells' HTN, HTE, ULON, ULAT, and kmt value. From those -variables, the longitude, latitude, grid lengths (dx and dy), areas, -and masks can be derived for all grids. Table :ref:`tab-gridvars` lists -the primary prognostic grid variable names on the different grids. +The input grid file for the B-grid and CD-grid is identical. +Table :ref:`tab-gridvars` lists the primary prognostic grid variable names on the different grids. .. _tab-gridvars: @@ -723,8 +736,10 @@ each block and is written with a lot of array syntax requiring calculations over entire blocks (whether or not land is present). This option is provided in CICE as well for direct-communication compatibility with POP. Blocks that contain 100% -land grid cells are eliminated with 'block'. The 'blockall' option is identical -to 'block' but does not do land block elimination. The ‘latitude’ option +land grid cells are eliminated with 'block'. The 'blockfull' option is identical +to 'block' but does not do land block elimination. The 'blockall' option +does not do land block elimination and blocks with all land are given +minimal weight. The ‘latitude’ option weights the blocks based on latitude and the number of ocean grid cells they contain. Many of the non-cartesian decompositions support automatic land block elimination and provide alternative ways to @@ -868,26 +883,28 @@ date is always used to initialize the model run. More information about the restart capability can be found in :ref:`restartfiles`. Several different calendars are supported including noleap (365 days -per year), 360-day (twelve 30 day months per year), and gregorian +per year), 360-day (twelve 30 day months per year), and proleptic gregorian (leap days every 4 years except every 100 years except every 400 -years). The gregorian calendar in CICE is formally a proleptic gregorian -calendar without any discontinuties over time. The calendar is set -by specifying ``days_per_year`` and ``use_leap_years`` in the +years). The proleptic gregorian calendar avoids any discontinuties over time by +following the same pattern of leap years before the first year of the gregorian +calendar (1582, see +`cf-conventions `_). +The calendar is set by specifying ``days_per_year`` and ``use_leap_years`` in the namelist, and the following combinations are supported, .. _tab-cal: .. table:: Supported Calendar Options - +----------------------+----------------------+------------+ - | ``days_per_year`` | ``use_leap_years`` | calendar | - +======================+======================+============+ - | 365 | false | noleap | - +----------------------+----------------------+------------+ - | 365 | true | gregorian | - +----------------------+----------------------+------------+ - | 360 | false | 360-day | - +----------------------+----------------------+------------+ + +----------------------+----------------------+----------------------+ + | ``days_per_year`` | ``use_leap_years`` | calendar | + +======================+======================+======================+ + | 365 | false | noleap | + +----------------------+----------------------+----------------------+ + | 365 | true | proleptic gregorian | + +----------------------+----------------------+----------------------+ + | 360 | false | 360-day | + +----------------------+----------------------+----------------------+ The history (:ref:`history`) and restart (:ref:`restartfiles`) @@ -1347,6 +1364,13 @@ directory in **iceh_ic.[timeID].nc(da)**. Several history variables are hard-coded for instantaneous output regardless of the ``hist_avg`` averaging flag, at the frequency given by their namelist flag. +A one-time grid history file can be turned on with the ``grid_outfile`` namelist +variable. If ``grid_outfile`` is true, all the grid variables will be written +to a history file once at the start of the run. The grid data will only be written +for blocks that have not been eliminated by the decomposition. To generate a one-time +grid history file without land block elimination, set ``distribution_wght = 'blockall'`` +and ``grid_outfile = .true.`` in the namelist. + The normalized principal components of internal ice stress (``sig1``, ``sig2``) are computed in *principal_stress* and written to the history file. This calculation is not necessary for the simulation; principal stresses are merely @@ -1359,6 +1383,13 @@ another that is multiplied by :math:`a_i`, representing an average over the grid cell area. Our naming convention attaches the suffix “_ai" to the grid-cell-mean variable names. +The units of the variables on the history file may not match internal model units. For +netCDF files, variable units are defined in metadata. History variable conversion from +internal model units is carried out by the ``cona`` and ``conb`` arguments defined in +subroutine **define_hist_field**. ``cona`` and ``conb`` are multiplicative and additive +terms respectively that are hardwired into the source code to convert model units to +history units. + Beginning with CICE v6, history variables requested by the Sea Ice Model Intercomparison Project (SIMIP) :cite:`Notz16` have been added as possible history output variables (e.g. ``f_sithick``, ``f_sidmassgrowthbottom``, etc.). The lists of @@ -1375,6 +1406,9 @@ It may also be helpful for debugging to increase the precision of the history fi output from 4 bytes to 8 bytes. This is changed through the ``history_precision`` namelist flag. +Note that the dpnd pond history fields have not yet been implemented for the topo +ponds scheme and are turned off in the code. + **************** Diagnostic files **************** diff --git a/doc/source/user_guide/ug_testing.rst b/doc/source/user_guide/ug_testing.rst index 4fea329fb..e0cbd2c2a 100644 --- a/doc/source/user_guide/ug_testing.rst +++ b/doc/source/user_guide/ug_testing.rst @@ -239,11 +239,11 @@ Ocean stresses are computed as in :cite:`Hunke01` where they are circular and ce in the square domain. The ice distribution is fixed, with a constant 2 meter ice thickness and a concentration field that varies linearly in the x-direction from ``0`` to ``1`` and is constant in the y-direction. No islands are included in this -configuration. The test is configured to run on a single processor. +configuration. To run the test:: - ./cice.setup -m --test smoke -s box2001 --testid --grid gbox80 --acct -p 1x1 + ./cice.setup -m --test smoke -s box2001 --testid --grid gbox80 --acct .. _boxslotcyl: diff --git a/doc/source/user_guide/ug_troubleshooting.rst b/doc/source/user_guide/ug_troubleshooting.rst index b5ed34bba..8686c5f47 100644 --- a/doc/source/user_guide/ug_troubleshooting.rst +++ b/doc/source/user_guide/ug_troubleshooting.rst @@ -245,12 +245,13 @@ With the addition of several alternative parameterizations for sea ice processes, a number of subprocesses now appear in multiple parts of the code with differing descriptions. For instance, sea ice porosity and permeability, along with associated flushing and flooding, are -calculated separately for mushy thermodynamics, topo and level-ice melt -ponds, and for the brine height tracer, each employing its own +calculated separately for mushy thermodynamics and various pond schemes, +and for the brine height tracer, each employing its own equations. Likewise, the BL99 and mushy thermodynamics compute freeboard and snow–ice formation differently, and the topo and level-ice melt pond schemes both allow fresh ice to grow atop melt ponds, using slightly -different formulations for Stefan freezing. These various process +different formulations for Stefan freezing. Mass calculations throughout +the code are inconsistent with respect to pond water. These various process parameterizations will be compared and their subprocess descriptions possibly unified in the future. diff --git a/icepack b/icepack index 43ead5638..6a5c51e9e 160000 --- a/icepack +++ b/icepack @@ -1 +1 @@ -Subproject commit 43ead56380bf11ecad66f165dcd736ed0c278763 +Subproject commit 6a5c51e9e6c643da0760a315e452755661d7d745