subroutine bcgen (mon1, iyr1, monn, iyrn, mon1rd, & iyr1rd, monnrd, iyrnrd, mon1clm, iyr1clm, & monnclm, iyrnclm, nlat, nlon, mon1out, & iyr1out, monnout, iyrnout, ncidin, outfilclim, & outfilamip, nmon, oldttcalc, history) use prec use types !------------------------------------------------------------------------ ! 21 August 1997 ! Karl E. Taylor ! PCMDI ! taylor13@llnl.gov ! ! 14 February 2003 ! Jim Rosinski ! NCAR ! Modified to be CAM-specific, and use namelist input ! ! Documentation provided by Karl Taylor ! ! Purpose: ! to create on some specified "target" grid an artificial mid-month ! sea ice fraction and SST data set (referred to here as the ! "boundary condition data" set) that, when linearly interpolated ! (in time), produces the observed monthly means (referred to here ! as the "observed data"). ! REFERENCE: ! ! Taylor, K.E., D. Williamson, and F. Zwiers (2000): The sea surface ! temperature and sea-ice concentration boundary conditions for ! AMIP II simulations. PCMDI Report No. 60 and UCRL-MI-125597, ! Lawrence Livermore National Laboratory, Livermore, CA, 25 pp. ! ! pdf file available at ! http://www-pcmdi.llnl.gov/pcmdi/pubs/ab60.html ! Input files: ! monthly mean (observed) SSTs and sea ice fraction on the target grid ! fortran namelist defining input and output filenames, and time periods ! of input and output data. ! Output files: ! (1) The boundary condition data set for the years requested. ! (The filenames contain the string "bc" and don't ! include the string "clim" (e.g. amipbc_sst_1978.nc).) ! (2) A climatological boundary condition data set based on the ! years specified for computing this climatology. ! (The filenames contain the strings "bc" and "clim" ! (e.g., amipbc_sic_360x180_1979_2001_clim.nc).) ! Libraries used: ! netcdf library: interface to netCDF files ! Overview of algorithm: ! The following assumes familiarity with the information contained ! in the reference listed above. ! Away from regions of near-freezing temperature, the SSTs are ! generated by solving a set of N linear equations where N ! is the number of months considered. The mid-month (boundary ! condition) temperatures for a given month depend on the observed ! monthly-mean temperature of that month, and also the temperatures ! of the preceeding month and following month. Thus, ! the mid-month temperature for the first and last months ! formally require observed temperatures before and after ! the time period considered. In practice the dependence ! on the temperatures outside the period considered is fairly weak. ! To close the problem mathematically, however, we must impose some ! sort of condition on the temperatures before and following the ! period of interest. ! If observations are available for several months before and ! after the period of interest, then these can be used along with ! imposition of a periodic boundary condition to fully constrain the ! problem. (By "periodic boundary condition," we mean that the ! first month of the available observations is assumed to follow ! the last month). The periodic boundary condition should only be ! imposed on an observational period that comprises an integral ! number of years, so, for example, if the first month is March, the ! last month must be February. ! The periodic condition is a convenient way of closing the ! problem mathematically, but is of course unrealistic. In ! practice, however, it really affects only the mid-month ! temperatures of a few months: the temperatures for the 2 or 3 ! months at the beginning and end of the observational period ! considered. If the observational record extends well outside ! (both before and after) the period for which boundary condition ! data are needed, then this is not a problem. If, however, we need ! boundary condition data for every month for which observations are ! available, then the months at the beginning and end will be ! sensitive to this assumption. ! If you really want to simulate the full time period for which ! observed monthly means are available, the "end" effects ! can be reduced by generating artifical "observed" temperatures ! for a brief period preceeding and following the actual ! observational period. In this code we do this as follows: The ! artificial "observed" temperature anomalies are assumed to decay ! to zero in the first few months prior to and following the ! observational period, so that the temperature approaches ! climatology. The rate of decay is based on the the ! autocorrelation function for the monthly mean SST time-series ! (analyzed for the years 1979-1998). The spatial mean ! (area-weighted over all ocean grid cells) of the autocorrelation ! function, at lags of 1, 2, 3, ..., and 8 months have been ! computed and are specified within this code. The correlations ! for lags greater than 8 months are small, and are assigned so ! that the correlation reaches zero (in a smooth way) at month 12. ! [Note: for sea ice fraction the correlations are based on ! observations for lags less than 6 months, and the correlation is ! assumed to be zero for lags greater than 7 months.] ! In summary, to minimize dependence on the boundary end ! conditions (i.e., the values of "observations" specfied for the ! period before and after the interval where observations are ! actually available), it is best to use only the mid-month values ! that are generated for a subinterval away from the boundary. In ! practice this means the mid-month values for the 2 or 3 months at ! the beginning and the end of the observational period should be ! excluded from use in forcing a GCM simulation. ! Consider the following example. Suppose observations ! are available for the months January, 1956 through August, 2002. ! Suppose, further, we would like to prescribe the SST boundary ! condition in an atmospheric GCM simulation of these same months ! (1/1956 - 8/2002). The recommended approach would be to generate ! artificial observational data for the year preceeding 1/56 and the ! year following 8/02. We also require that we treat an integral ! number of years. We could conservatively choose to extend the ! "observations" to 12/03 at the end, and to also tack on a year ! at the beginning (i.e., 12 months starting at 1/55). ! Since the artifical "observational" data approaches climatology ! outside the time period of interest, the user must also ! specify which years will contribute to the climatology. If there ! is no significant temperature trend over the period considered, ! the climatology could be justifiably based on any interval of ! several (say, 10 or more) years. ! If, however, the data exhibit a noticable trend, then the ! user should probably avoid trying to simulate the entire ! period because the current code is unable to handle this case ! accurately; it assumes that the artificial data outside both ends ! of the observational period "decay" toward (i.e., approach) the ! same climatology. It would be better to assume that at the ! beginning of the period and at the end of the period, the values ! approached the different characteristic climatologies. ! In any case, it is wise to avoid the last few months for which ! observations are currently available. This is because as ! observations become available for succeeding months, these ! will replace the artificially generated "observations" and will ! have some effect on boundary condition data for the few months ! near the end of the observational period. ! The user can specify the beginning and ending months of the ! following: ! ! 1) the interval for which observational monthly mean data ! are available. ! 2) the entire interval over which the analysis will be ! performed, including buffer periods prior to and ! following the observed data, which are recommended to ! total a year or two. ! 3) the interval over which the climatology is computed. ! 4) the interval defining which months will be included ! as output (in the form of SST mid-month boundary ! conditions). ! Away from regions of near-freezing temperature, the mid-month ! SSTs [represented here by S] satisfy: ! A S = B ! where S is a column vector of dimension N representing the ! mid-month values that constitute the SST boundary condition, ! B is a column vector of dimension N, representing the ! observed monthly mean time-series, and A (except for 2 ! elements) is a tri-diagnal matrix of dimension NxN. The ! two unconforming elements account for the assumption of ! periodicity. (The following shows the matrix structure.) ! ! |b(1) c(1) ... a(1) | ! |a(2) b(2) c(2) | ! | . a(3) b(3) c(3) ... | ! A = | . | ! | . | ! | . | ! | ... a(N-1) b(N-1) c(N-1)| ! |c(N) ... . a(N) b(N) | ! where ! a(i) = aa(i)/8 ! b(i) = 1 - aa(i)/8 - cc(i)/8 ! c(i) = cc(i)/8 ! aa(i) = 2*n(i)/(n(i)*n(i-1)) ! cc(i) = 2*n(i)/(n(i)*n(i+1)) ! where n(i) = number of days in month i. ! Note that if all the months were of equal length, then aa=cc=1 ! and a=1/8, b=3/4, and c=1/8. ! For sea ice, the above procedure has to be modified because ! the sea ice fraction is constrained to be between 0 and 1. ! Similarly, the water temperature cannot fall below its freezing ! point, so this also places a physical constraint that is not ! always consistent with the above procedure. In these cases ! the equations that must be solved have a similar structure as ! shown above, but the coefficients (a's, b's, and c's) depend on ! temperature or the sea ice fraction. Thus, the equations in this ! case are no longer linear, but they can be solved using an ! iterative Newton-Raphson approach. ! The Jacobian that is required under this approach is ! not generated analytically, but is approximated numerically. ! There is another constraint necessary to ensure a unique ! solution in the nonlinear case. To see why the constraint ! is needed, consider a grid cell where the ocean is ice-free ! year around, except for 1 month, when the ice fraction is ! 10%. The mid-month value for this month is not uniquely ! determined because the cell could be covered by little ! ice over the entire month, or by lots of ice for only a short ! time in the middle of the month. The algorithm relied on ! in this code tries to minimize the absolute difference between ! mid-month values that exceed the maximum physically allowed ! value (S_max=100% for sea ice) and S_max, while still yielding ! the correct monthly means: i.e., ! where S > S_max, minimize (S - S_max) ! Similarly, for values that are less than the minimum physically ! allowed value (S_min = 0% for sea ice): ! where S < S_min, minimize (S_min - S) ! In the example above this results in the following mid-month ! values for sea ice (assuming for simplicity that all months ! are of the same length): S(i-1) = S(i+1) = -20% and ! S(i) = 20% where i is the month with mean sea ice fraction of ! 10%. These mid-month values when linearly interpolated give a ! sea ice fraction for month i that starts at 0%, linearly grows to ! 20% at the middle of the month, and then linearly decreases to 0% ! at the end of the month. For the month preceeding and the month ! following month i, the linear interpolation leads to negative ! values, but recall that the model's alogrithm will "clip" these ! values, setting them to 0%. ! Namelist details: ! ! SPECIFY the first and last month and year for period in which ! observed monthly mean data will be read. (The first month ! read must not preceed mon1, iyr1, and the last month must ! not follow monn, iyrn). For example: ! mon1rd = 1 !AMIP ! iyr1rd = 1956 !AMIP ! monnrd = 8 !AMIP ! iyrnrd = 2002 !AMIP ! SPECIFY first and last month and year for entire period that will ! be treated (i.e., the period of interest plus buffers at ends). ! Note that the entire period treated should be an integral ! number of years. For example: ! mon1 = 1 !AMIP ! iyr1 = 1955 !AMIP ! monn = 12 !AMIP ! iyrn = 2003 !AMIP ! SPECIFY the first and last month and year that will be included in ! climatological mean. (This must be an interval within the ! observed period). For example: ! mon1clm = 1 !AMIP ! iyr1clm = 1979 !AMIP ! monnclm = 12 !AMIP ! iyrnclm = 2000 !AMIP ! SPECIFY the first and last month and year written to the output ! file. (Try to begin at east a few months after the mon1rd, ! iyr1rd, and end a few months before monnrd, iyrnrd, to avoid ! sensitivity to the artificial data outside the observed ! period.) For example: ! mon1out = 1 !AMIP ! iyr1out = 1956 !AMIP ! ! monnout = 6 !AMIP ! iyrnout = 2002 !AMIP ! ! SPECIFY input dataset (as output by the program regrid) on the ! target grid. For example: ! ! infil = 'regrid.T42.nc' ! ! SPECIFY output climatological boundary condition dataset name. ! For example: ! ! outfilclim = 'outfilclim.T42.nc' ! ! SPECIFY output AMIP-style boundary condition dataset name ! ! outfilclim = 'outfilclim.T42.nc' !------------------------------------------------------------------------ implicit none include 'netcdf.inc' ! ! Input arguments ! integer, intent(in) :: mon1 ! start month of period of interest plus buffer integer, intent(in) :: iyr1 ! start year of period of interest plus buffer integer, intent(in) :: monn ! end month of period of interest plus buffer integer, intent(in) :: iyrn ! end year of period of interest plus buffer integer, intent(in) :: mon1rd ! start month to read from input data integer, intent(in) :: iyr1rd ! start year to read from input data integer, intent(in) :: monnrd ! end month to read from input data integer, intent(in) :: iyrnrd ! end year to read from input data integer, intent(in) :: mon1clm ! start month to use for climatology integer, intent(in) :: iyr1clm ! start year to use for climatology integer, intent(in) :: monnclm ! end month to use for climatology integer, intent(in) :: iyrnclm ! end year to use for climatology integer, intent(in) :: nlat ! number of latitudes (e.g. 64 for typical T42) integer, intent(in) :: nlon ! number of longitudes (e.g. 128 for typical T42) integer, intent(in) :: mon1out ! start month written to output file (default mon1rd) integer, intent(in) :: iyr1out ! start year written to output file (default iyr1rd) integer, intent(in) :: monnout ! end month written to output file (default monnrd) integer, intent(in) :: iyrnout ! end year written to output file (default iyrnrd) integer, intent(in) :: ncidin ! input file netcdf id integer, intent(in) :: nmon ! total number of months of period of interest plus buffer logical, intent(in) :: oldttcalc ! for bfb agreement with original code character*120, intent(in) :: outfilclim ! output filename for climatology character*120, intent(in) :: outfilamip ! output filename for year-by-year output character(len=*), intent(in) :: history ! history attribute ! ! Local workspace ! integer :: i, j ! lon, lat indices integer :: k ! index value 1=ice, 2=sst integer :: m, mp, n, mm, l ! month indices integer :: m1, m2 ! month indices integer :: ismc ! number of monthly means smoothed (climatology) integer :: jsmc ! number of grid cells affected by smoothing (climatology) integer :: ismf ! number of year-by-year monthly means smoothed (year-by-year) integer :: jsmf ! number of grid cells affected by smoothing (year-by-year) integer :: isea ! number of ocean grid cells integer :: nmonout ! number of output months integer :: prvyr, prvmo ! previous year, month index from input file integer :: yr, mo ! year, month index from input file logical :: dateok ! flag indicates acceptable input date format ! ! netcdf info ! integer :: ncidclim = -1 ! output filehandle (climatology) integer :: ncidamip = -1 ! output filehandle (year-by-year) integer :: varid = -1 ! variable id integer :: lonid = -1 ! longitude id (input) integer :: latid = -1 ! latitude id (input) integer :: dateidclim = -1 ! date id (climatology) integer :: dateidamip = -1 ! date id (year-by-year) integer :: datesecidclim = -1 ! seconds of date id (climatology) integer :: datesecidamip = -1 ! seconds of date id (year-by-year) integer :: timeidclim = -1 ! time id (clim) integer :: timeidamip = -1 ! time id (year-by-year) integer :: dateidin = -1 ! date info on input file integer :: date(1) = -1 ! input date (yyyymmdd) integer :: start(3) = (/-1,-1,-1/) ! for reading/writing non-contiguous data in netcdf file integer :: start1d(1) = -1 ! date start index on input file integer :: start1dtst(1) = -1 ! test date index on input file integer :: kount(3) = (/-1,-1,-1/) ! for reading/writing non-contiguous data in netcdf file integer, parameter :: maxiter = 100 ! max iterations in solving time-diddling real(r8), parameter :: fac = 1.0 ! factor to multiply input data by (before any cropping). real(r8), parameter :: bbmin = 0.001 ! smallest diagonal element allowed in Jacobian ! i.e. will change 0.0005 to 0.001 real(r8) :: obsclim(nlon,nlat,12) ! climatological values real(r8) :: obsamip(nlon,nmon) ! year-by-year values real(r8) :: arr(nlon,nmon) ! sst or ice conc. (1 latitude) real(r8) :: centmon(nlon,nlat,12) ! sst or ice conc. climatology (all latitudes) real(r8) :: a(nmon) ! lower diagonal matrix coeffs (year-by-year) real(r8) :: c(nmon) ! upper diagonal matrix coeffs (year-by-year) real(r8) :: ac(12) ! lower diagonal matrix coeffs (climatology) real(r8) :: cc(12) ! upper diagonal matrix coeffs (climatology) real(r8) :: xlon(nlon) ! longitudes on input file (between 0 and 360) real(r8) :: xlat(nlat) ! latitudes on input file (between -90 and 90) integer :: monlen(12,2) ! length of months data monlen/31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31, & 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31/ character(len=80) :: center = 'NCAR' ! research center creating data type(icesstparms) :: icesst(2) ! struct containing variable-specific info ! ! Set ice parms. dt value: Not much smoothing => 0->100 becomes 2->98 between months ! icesst(1) = icesstparms ('ICEFRAC', -1, & ! inname, invarid 'ice_cov', & ! climname 'ice_cov_prediddle', & ! climname_pre 'BCS Pseudo Sea-ice concentration', & ! climlongname 'Sea-ice concentration before time diddling', & ! climlongname_pre 'ice_cov', & ! amipname 'ice_cov_prediddle', & ! amipname_pre 'BCS Pseudo Sea-ice concentration', & ! amiplongname 'Sea-ice concentration before time diddling', & ! amiplongname_pre 'fraction', & ! units -1, -1, -1, -1, & ! varids 1.e-4, 0., 1., 1.e-4, 0.02, & ! conv, tmin, tmax, varmin, dt (/0.53, 0.23, 0.13, 0.08, 0.05, 0.02, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00/)) ! correl ! ! With Karl's bugfix to tt calc, convergence criterion for ice can be tightened. ! Leave as is for now since halving this number can lead to big excursions in ice ! concentration. ! if (oldttcalc) then icesst(1)%dt = (icesst(1)%tmax - icesst(1)%tmin) / 50. else icesst(1)%dt = (icesst(1)%tmax - icesst(1)%tmin) / 100. icesst(1)%dt = (icesst(1)%tmax - icesst(1)%tmin) / 50. end if ! ! Set sst parms. Cropping SST at 1000. effectively means do not crop ! icesst(2) = icesstparms ('SST', -1, & ! inname, invarid 'SST_cpl', & ! climname 'SST_cpl_prediddle', & ! climname_pre 'BCS Pseudo SST', & ! climlongname 'SST before time diddling', & ! climlongname_pre 'SST_cpl', & ! amipname 'SST_cpl_prediddle', & ! amipname_pre 'BCS Pseudo SST', & ! amiplongname 'SST before time diddling', & ! amiplongname_pre 'deg_C', & ! units -1, -1, -1, -1, & ! varids 1.e-3, -1.8, 1000., 0., 0.001, & ! conv,tmin, tmax, varmin, dt (/0.68, 0.46, 0.33, 0.26, 0.20, 0.17, 0.14, 0.11, 0.08, 0.05, 0.02, 0.00/)) ! correl ! ***************************************************************** monlen(2,2) = 28 ! JR for no leap year ! ! Copy dimension vars from input to output ! call wrap_nf_inq_varid (ncidin, 'lon', lonid) call wrap_nf_inq_varid (ncidin, 'lat', latid) call wrap_nf_get_var_double (ncidin, lonid, xlon) call wrap_nf_get_var_double (ncidin, latid, xlat) ! ! Open output files and define metadata ! call setup_outfile (ncidclim, outfilclim, 'CLIM', dateidclim, datesecidclim, & timeidclim, icesst, nlon, nlat, xlon, & xlat, 0, 1, history) call setup_outfile (ncidamip, outfilamip, 'AMIP', dateidamip, datesecidamip, & timeidamip, icesst, nlon, nlat, xlon, & xlat, iyr1out, mon1out, history) ! ! Determine starting index of data to be read. Assume this and subsequent data are monthly ! values, centered in the middle of the month. ! start1d(1) = 1 call wrap_nf_inq_varid (ncidin, 'date', dateidin) do while (.true.) call wrap_nf_get_vara_int (ncidin, dateidin, start1d, 1, date) if (date(1)/10000 == iyr1rd .and. mod(date(1)/100,100) == mon1rd) then write(6,*)'Input data at iyr1rd, mon1rd=', iyr1rd, mon1rd, ' are record # ', start1d(1) exit end if start1d(1) = start1d(1) + 1 end do ! ! Ensure that enough data are present, and that they increment properly in time ! start1dtst(1) = start1d(1) call wrap_nf_get_vara_int (ncidin, dateidin, start1dtst, 1, date) prvyr = date(1)/10000 prvmo = mod(date(1)/100,100) do while (.true.) start1dtst(1) = start1dtst(1) + 1 call wrap_nf_get_vara_int (ncidin, dateidin, start1dtst, 1, date) yr = date(1)/10000 mo = mod(date(1)/100,100) ! ! Exit loop when date read in extend beyond requested data ! if (yr > iyrnrd) exit if (yr == iyrnrd .and. mo >= monnrd) then write(6,*)'Input yr,mo=', yr, mo,' will be the last date read from input file' exit end if dateok = (yr == prvyr .and. (mo == prvmo+1 .and. mo >= 1 .and. mo <= 12)) .or. & yr == prvyr+1 .and. mo == 1 if (.not. dateok) then write(6,*)'Bad date info read: yr,mo=',yr,mo stop 999 end if write(6,*)'Input yr,mo=', yr, mo, ' OK' prvyr = yr prvmo = mo end do ! ! Set kount array for netcdf calls ! kount(1) = nlon kount(2) = 1 kount(3) = 1 ! ! Loop 1 to 2 to do ice first then sst ! do 22 k=1,2 write(6,*) 'Output from monthly boundary condition generator ' write(6,*) 'clim var name = ', icesst(k)%climname write(6,*) 'climlong name = ', icesst(k)%climlongname write(6,*) 'amip var name = ', icesst(k)%amipname write(6,*) 'amiplong name = ', icesst(k)%amiplongname write(6,*) 'units = ', icesst(k)%units write(6,*) 'center = ', center write(6,*) 'nlon = ', nlon write(6,*) 'nlat = ', nlat write(6,*) 'nmon = ', nmon write(6,*) 'mon1rd = ', mon1rd write(6,*) 'iyr1rd = ', iyr1rd write(6,*) 'monnrd = ', monnrd write(6,*) 'iyrnrd = ', iyrnrd write(6,*) 'mon1clm = ', mon1clm write(6,*) 'iyr1clm = ', iyr1clm write(6,*) 'monnclm = ', monnclm write(6,*) 'iyrnclm = ', iyrnclm write(6,*) 'mon1 = ', mon1 write(6,*) 'iyr1 = ', iyr1 write(6,*) 'monn = ', monn write(6,*) 'iyrn = ', iyrn write(6,*) 'mon1out = ', mon1out write(6,*) 'iyr1out = ', iyr1out write(6,*) 'monnout = ', monnout write(6,*) 'iyrnout = ', iyrnout write(6,'(a,1pe14.7)') 'conv = ', icesst(k)%conv write(6,*) 'maxiter = ', maxiter write(6,'(a,1pe14.7)') 'bbmin = ', bbmin write(6,'(a,1pe14.7)') 'varmin = ', icesst(k)%varmin write(6,'(a,1p,12(e10.3))') 'correl = ', icesst(k)%correl write(6,*) 'monlen = ', monlen write(6,'(a,1pe14.7)') 'tmin = ', icesst(k)%tmin write(6,'(a,1pe14.7)') 'tmax = ', icesst(k)%tmax write(6,'(a,1pe14.7)') 'dt = ', icesst(k)%dt write(6,'(a,1pe14.7)') 'fac = ', fac write(6,*) 'oldttcalc=', oldttcalc ! Calculate jacobian elements for climatological years m = 12 mp = 1 do n=1,12 mm = m m = mp mp = mp + 1 if (mp == (12+1)) mp = 1 ac(n) = 2.0_r8*monlen(m,1)/(monlen(m,1) + monlen(mm,1)) cc(n) = 2.0_r8*monlen(m,1)/(monlen(m,1) + monlen(mp,1)) end do ! Calculate jacobian elements for all years i = iyr1 j = 1 if (((mod(i,4) == 0) .and. (mod(i,100) /= 0)) .or. (mod(i,400) == 0)) j = 2 m = mod((mon1+12-2), 12) + 1 mp = mod((mon1-1), 12) + 1 do n=1,nmon mm = m m = mp mp = mp + 1 if (mp == (12+1)) then mp = 1 i = i + 1 j = 1 if (((mod(i,4) == 0) .and. (mod(i,100) /= 0)) .or. (mod(i,400) == 0)) j = 2 end if a(n) = 2.0_r8*monlen(m,j)/(monlen(m,j) + monlen(mm,j)) c(n) = 2.0_r8*monlen(m,j)/(monlen(m,j) + monlen(mp,j)) end do ! ! Get input variable id ! call wrap_nf_inq_varid (ncidin, icesst(k)%inname, icesst(k)%invarid) ! ! Monthly mean computation section: save memory by computing and writing one ! latitude slice at a time ! ismc = 0 jsmc = 0 ismf = 0 jsmf = 0 isea = 0 do j=1,nlat m1 = (iyr1rd-iyr1)*12 + mon1rd - mon1 + 1 m2 = (iyrnrd-iyr1)*12 + monnrd - mon1 + 1 ! ! Read in all time values of the j'th latitude slice ! start(1) = 1 start(2) = j start(3) = start1d(1) ! ! Note data read in to array index starting at m1 not 1 to allow for padding at start of ! period. ! do l=m1,m2 call wrap_nf_get_vara_double (ncidin, icesst(k)%invarid, start, kount, arr(1,l)) start(3) = start(3) + 1 end do ! ! Save off obs for writing to output file ! obsamip(:nlon,1:m1-1) = 0. obsamip(:nlon,m1:m2) = arr(:nlon,m1:m2) obsamip(:nlon,m2+1:) = 0. write(6,*) 'latitude ', j, ' read successfully.' ! Compute climatological means call calcclim (j, nlon, nlat, nmon, ismc, & jsmc, mon1clm, iyr1clm, iyr1, mon1, & iyr1rd, mon1rd, iyrnrd, monnrd, monnclm, & iyrnclm, maxiter, icesst(k)%tmin, & icesst(k)%tmax, icesst(k)%dt, & icesst(k)%conv, bbmin, isea, obsclim, arr, & centmon, ac, cc) ! Solve for full mid-month values call calcfull (j, nlon, nlat, nmon, ismf, & jsmf, iyr1rd, mon1rd, iyr1, mon1, & iyrn, monn, iyrnrd, monnrd, maxiter, & icesst(k)%tmin, icesst(k)%tmax, icesst(k)%dt, & icesst(k)%conv, bbmin, & obsclim, arr, centmon, a, c, & icesst(k)%correl, oldttcalc) ! ! Add climatology back on to output data ! call finish (nlon, nlat, mon1, nmon, centmon, & arr, j) ! ! Write 1 latitude of pre- and post-time-diddled variable to output file. ! start(1) = 1 start(2) = j nmonout = (iyrnout - iyr1out)*12 + (monnout - mon1out + 1) ! ! l is the output time index for the netcdf file ! m indexes into output arrays with a buffer offset ! m = (iyr1out - iyr1)*12 + (mon1out - mon1) do l=1,nmonout m = m + 1 start(3) = l varid = icesst(k)%varidamip call wrap_nf_put_vara_double (ncidamip, varid, start, kount, arr(1,m)) varid = icesst(k)%varidamip_pre call wrap_nf_put_vara_double (ncidamip, varid, start, kount, obsamip(1,m)) end do do l=1,12 start(3) = l varid = icesst(k)%varidclim call wrap_nf_put_vara_double (ncidclim, varid, start, kount, centmon(1,j,l)) varid = icesst(k)%varidclim_pre call wrap_nf_put_vara_double (ncidclim, varid, start, kount, obsclim(1,j,l)) end do end do ! j=1,nlat write(6,*) ' ' write(6,*) ismc, ' climatological monthly means were smoothed' write(6,*) jsmc, ' grid cells were affected' write(6,*) ' ' write(6,*) ismf, ' monthly means were smoothed' write(6,*) jsmf, ' grid cells were affected' write(6,*) ' ' 22 continue ! 1=ice 2=sst ! ! Write model-readable date and datesec info to output files ! call output_dateinfo (ncidclim, dateidclim, datesecidclim, timeidclim, 0, & 1, 0, 12, monlen(1,1)) call output_dateinfo (ncidamip, dateidamip, datesecidamip, timeidamip, iyr1out, & mon1out, iyrnout, monnout, monlen(1,1)) call wrap_nf_close (ncidclim) call wrap_nf_close (ncidamip) call wrap_nf_close (ncidin) return end subroutine bcgen subroutine finish (nlon, nlat, mon1, nmon, centmon, & arr, j) ! ! Add climatology back on to year-by-year data ! use prec implicit none integer, intent(in) :: nlon, nlat ! number of lons, lats integer, intent(in) :: mon1 ! starting month index of arr integer, intent(in) :: nmon ! total number of months integer, intent(in) :: j ! latitude index real(r8), intent(in) :: centmon(nlon,nlat,12) ! climatology real(r8), intent(inout) :: arr(nlon,nmon) ! year-by-year data integer :: i ! longitude index integer :: m ! month index cycling 1-12 integer :: n ! month index for entire period ! Calculate full mid-month time-series do n=1,nmon m = mod((n+mon1-2), 12) + 1 do i=1,nlon arr(i,n) = arr(i,n) + centmon(i,j,m) end do end do return end subroutine finish