subroutine gosbc (is, ie, js, je) #if defined O_mom || defined O_embm !======================================================================= ! calculate the average fluxes for next ocean time step !======================================================================= implicit none integer ie, is, je, js, i, j, nc integer iem1, isp1, jem1, jsp1, k real f1, f1a, f1l, fh, fs, fwcflx, fwaflx, time real area, tarea, tsflx, rsocn, tmp, fgs include "size.h" include "param.h" include "pconst.h" include "stdunits.h" include "calendar.h" include "csbc.h" include "grdvar.h" include "tmngr.h" include "switch.h" # if defined O_embm include "cembm.h" include "atm.h" # endif # if defined O_mom include "mw.h" # endif # if defined O_ice # if defined O_ice_cpts include "cpts.h" # endif include "ice.h" # endif # if defined O_mtlm include "mtlm.h" # endif include "levind.h" # if defined O_fwa include "fwa.h" include "cregin.h" include "tmngr.h" # endif # if defined O_sed && !defined O_sed_uncoupled include "sed.h" # endif # if defined O_sulphate_data_transient real cosz(is:ie,js:je), tot, twt, cz(1), sindec, zero(1) # endif # if defined O_embm_read_sflx || defined O_embm_write_sflx integer ntrec save ntrec data ntrec /0/ # endif isp1 = is + 1 iem1 = ie - 1 jsp1 = js + 1 jem1 = je - 1 # if defined O_mom && defined O_embm f1 = 1./atatm fh = 2.389e-8/atatm fs = -socn/atatm !----------------------------------------------------------------------- ! calculate average net fluxes. convert heat flux to cal/cm**2/s ! from kW/m**2 and fresh water flux (cm/s) to an apparent salt ! flux (g/cm**2/s) using global ocean average salinity, socn !----------------------------------------------------------------------- do j=2,jmtm1 do i=2,imtm1 if (tmsk(i,j) .ge. 0.5) then # if defined O_plume # if !defined O_plume_brine subflux(i,j,1) = flux(i,j,isat) if (subflux(i,j,1) .gt. 0.) subflux(i,j,1) = 0. flux(i,j,isat) = flux(i,j,isat) - subflux(i,j,1) subflux(i,j,1) = fh*subflux(i,j,1) subflux(i,j,2) = flux(i,j,ishum) # endif if (subflux(i,j,2) .gt. 0.) subflux(i,j,2) = 0. flux(i,j,ishum) = flux(i,j,ishum) - subflux(i,j,2) subflux(i,j,2) = fs*subflux(i,j,2) # endif # if defined O_convect_brine cba0(i,j) = 0. do nc=0,ncat cba(i,j,nc) = f1*cba(i,j,nc) if (cba(i,j,nc) .gt. 0.) then cbf(i,j,nc) = fs*cbf(i,j,nc)/cba(i,j,nc) cba0(i,j) = cba0(i,j) + cba(i,j,nc) else cbf(i,j,nc) = 0. cba(i,j,nc) = 0. endif enddo if (cba0(i,j) .gt. 1.) then if (cba0(i,j) .gt. 1.000001) then print*, "==> Warning: ice area > 1: ", cba0(i,j) endif cba0(i,j) = 1. endif cba0(i,j) = 1. - cba0(i,j) # endif sbc(i,j,ihflx) = sbc(i,j,ihflx) + fh*flux(i,j,isat) ! add virtual fluxes of salinity sbc(i,j,isflx) = sbc(i,j,isflx) + fs*flux(i,j,ishum) else # if defined O_plume subflux(i,j,1) = 0. subflux(i,j,2) = 0. # endif # if defined O_convect_brine cbf(i,j,:) = 0. cba(i,j,:) = 0. cba0(i,j) = 1. # endif sbc(i,j,ihflx) = 0. sbc(i,j,isflx) = 0. endif if (umsk(i,j) .ge. 0.5) then # if defined O_ice_evp || defined O_embm_awind sbc(i,j,itaux) = f1*flux(i,j,nat+1) sbc(i,j,itauy) = f1*flux(i,j,nat+2) # endif else sbc(i,j,itaux) = 0. sbc(i,j,itauy) = 0. endif enddo enddo call setbcx (sbc(1,1,ihflx), imt, jmt) call setbcx (sbc(1,1,isflx), imt, jmt) call setbcx (sbc(1,1,itaux), imt, jmt) call setbcx (sbc(1,1,itauy), imt, jmt) # if defined O_convect_brine do nc=0,ncat call setbcx (cbf(1,1,nc), imt, jmt) call setbcx (cba(1,1,nc), imt, jmt) enddo call setbcx (cba0, imt, jmt) # endif # endif !----------------------------------------------------------------------- ! update boundary conditions from the land model ! do this now instead of in gasbc so fields can be written out !----------------------------------------------------------------------- f1l = 0. f1a = 0. # if defined O_embm if (atatm .ne. 0.) f1a = 1.0/atatm # endif # if defined O_mtlm if (atlnd .ne. 0.) f1l = 1.0/atlnd do j=2,jmtm1 do i=2,imtm1 if (land_map(i,j) .ne. 0) then sbc(i,j,iro) = sbc(i,j,iro)*f1l sbc(i,j,isca) = sbc(i,j,isca)*f1l sbc(i,j,ievap) = sbc(i,j,ievap)*f1l sbc(i,j,ilwr) = sbc(i,j,ilwr)*f1l sbc(i,j,isens) = sbc(i,j,isens)*f1l # if defined O_carbon sbc(i,j,inpp) = sbc(i,j,inpp)*f1l sbc(i,j,isr) = sbc(i,j,isr)*f1l sbc(i,j,iburn) = sbc(i,j,iburn)*f1l # endif else sbc(i,j,iro) = sbc(i,j,iro)*f1a sbc(i,j,ievap) = 0. sbc(i,j,ilwr) = 0. sbc(i,j,isens) = 0. # if defined O_mtlm && defined O_carbon sbc(i,j,inpp) = 0. sbc(i,j,isr) = 0. sbc(i,j,iburn) = 0. # endif endif enddo enddo call setbcx (sbc(1,1,isca), imt, jmt) call setbcx (sbc(1,1,ievap), imt, jmt) call setbcx (sbc(1,1,ilwr), imt, jmt) call setbcx (sbc(1,1,isens), imt, jmt) # if defined O_carbon call setbcx (sbc(1,1,inpp), imt, jmt) call setbcx (sbc(1,1,isr), imt, jmt) # endif # else sbc(:,:,iro) = sbc(:,:,iro)*f1a # endif call setbcx (sbc(1,1,iro), imt, jmt) # if defined O_embm !----------------------------------------------------------------------- ! zero diagnostic for river discharge and call river model !----------------------------------------------------------------------- disch(:,:) = 0. call rivmodel # if defined O_sed && !defined O_sed_uncoupled !----------------------------------------------------------------------- ! apply CaCO3 weathering flux proportional to discharge !----------------------------------------------------------------------- if (weathflx .gt. 0) then tmp = 0. do j=2,jmtm1 do i=2,imtm1 if (tmsk(i,j) .ge. 0.5) then tmp = tmp + disch(i,j)*dxt(i)*dyt(j)*cst(j) endif enddo enddo tmp = weathflx/tmp do j=2,jmtm1 # if defined O_global_sums fgs = tmp*dyt(j)*cst(j)*segtim/secday # endif do i=2,imtm1 if (tmsk(i,j) .ge. 0.5) then # if defined O_carbon sbc(i,j,idicflx) = sbc(i,j,idicflx) + disch(i,j)*tmp # if defined O_global_sums dtoic = dtoic - disch(i,j)*dxt(i)*fgs # endif # endif # if defined O_npzd_alk sbc(i,j,ialkflx) = sbc(i,j,ialkflx) + disch(i,j)*2.*tmp # endif endif enddo enddo endif # endif # endif # if defined O_sealev_data_transient && defined O_sealev_salinity !----------------------------------------------------------------------- ! add in flux from sea level change !----------------------------------------------------------------------- do j=2,jmtm1 do i=2,imtm1 if (kmt(i,j) .gt. 0) & sbc(i,j,isflx) = sbc(i,j,isflx) + fs*dsealev enddo enddo # endif # if defined O_mom && defined O_embm # if defined O_fwa !----------------------------------------------------------------------- ! add additional fresh water flux anomaly !----------------------------------------------------------------------- time = year0 + accel_yr0 + (relyr - accel_yr0)*accel if (time .ge. fwayri .and. time .le. fwayrf) then if (areafwa .gt. 0) then ! fwaflxi is in Sv (1e6 m3 s-1) and fwarate is in Sv/yr fwaflx = fwaflxi + (time - fwayri)*fwarate ! convert to flux in g salt cm-2 s-1 fwaflx = -socn*fwaflx*1.e12/areafwa # if defined O_fwa_precip call areaavg (precip, fwawt, tmp) if (tmp .gt. 0) fwaflx = fwaflx/tmp # endif do j=2,jmtm1 do i=2,imtm1 sbc(i,j,isflx) = sbc(i,j,isflx) + fwaflx*fwawt(i,j) # if defined O_fwa_precip & *precip(i,j) # endif enddo enddo endif if (compensate .and. areafwc .gt. 0) then ! fwaflxi is in Sv (1e6 m3 s-1) and fwarate is in Sv/yr fwcflx = fwaflxi + (time - fwayri)*fwarate ! convert to opposite flux in g salt cm-2 s-1 fwcflx = socn*fwcflx*1.e12/areafwc # if defined O_fwa_compevap call areaavg (evap, fwcwt, tmp) if (tmp .gt. 0) fwcflx = fwcflx/tmp # endif do j=2,jmtm1 do i=2,imtm1 sbc(i,j,isflx) = sbc(i,j,isflx) + fwcflx*fwcwt(i,j) # if defined O_fwa_compevap & *evap(i,j) # endif enddo enddo endif endif # endif # if defined O_carbon || defined O_npzd_alk || defined O_npzd_o2 || defined O_npzd || defined O_cfcs_data_transient !----------------------------------------------------------------------- ! add normalized virtual fluxes to other tracers !----------------------------------------------------------------------- tarea = 0. tsflx = 0. rsocn = 1./socn do j=2,jmtm1 do i=2,imtm1 if (tmsk(i,j) .ge. 0.5) then area = dxt(i)*dyt(j)*cst(j) tarea = tarea + area tsflx = tsflx + sbc(i,j,isflx)*area endif enddo enddo tsflx = tsflx/tarea do j=2,jmtm1 do i=2,imtm1 if (tmsk(i,j) .ge. 0.5) then tmp = (sbc(i,j,isflx) - tsflx)*rsocn vflux(i,j) = tmp # if defined O_carbon sbc(i,j,idicflx) = sbc(i,j,idicflx) + gaost(idic)*tmp # if defined O_carbon_14 sbc(i,j,ic14flx) = sbc(i,j,ic14flx) + gaost(ic14)*tmp # endif # endif # if defined O_npzd_alk sbc(i,j,ialkflx) = sbc(i,j,ialkflx) + gaost(ialk)*tmp # endif # if defined O_npzd_o2 sbc(i,j,io2flx) = sbc(i,j,io2flx) + gaost(io2)*tmp # endif # if defined O_npzd sbc(i,j,ipo4flx) = sbc(i,j,ipo4flx) + gaost(ipo4)*tmp # if !defined O_npzd_no_vflux sbc(i,j,iphytflx) = sbc(i,j,iphytflx) + gaost(iphyt)*tmp sbc(i,j,izoopflx) = sbc(i,j,izoopflx) + gaost(izoop)*tmp sbc(i,j,idetrflx) = sbc(i,j,idetrflx) + gaost(idetr)*tmp # endif # if defined O_npzd_nitrogen sbc(i,j,ino3flx) = sbc(i,j,ino3flx) + gaost(ino3)*tmp # if !defined O_npzd_no_vflux sbc(i,j,idiazflx) = sbc(i,j,idiazflx) + gaost(idiaz)*tmp # endif # endif # endif # if defined O_cfcs_data_transient sbc(i,j,icfc11flx) = sbc(i,j,icfc11flx) + gaost(icfc11)*tmp sbc(i,j,icfc12flx) = sbc(i,j,icfc12flx) + gaost(icfc12)*tmp # endif endif enddo enddo # if defined O_carbon call setbcx (sbc(1,1,idicflx), imt, jmt) # if defined O_carbon_14 call setbcx (sbc(1,1,ic14flx), imt, jmt) # endif # endif # if defined O_npzd_alk call setbcx (sbc(1,1,ialkflx), imt, jmt) # endif # if defined O_npzd_o2 call setbcx (sbc(1,1,io2flx), imt, jmt) # endif # if defined O_npzd call setbcx (sbc(1,1,ipo4flx), imt, jmt) # if !defined O_npzd_no_vflux call setbcx (sbc(1,1,iphytflx), imt, jmt) call setbcx (sbc(1,1,izoopflx), imt, jmt) call setbcx (sbc(1,1,idetrflx), imt, jmt) # endif # if defined O_npzd_nitrogen call setbcx (sbc(1,1,ino3flx), imt, jmt) # if !defined O_npzd_no_vflux call setbcx (sbc(1,1,idiazflx), imt, jmt) # endif # endif # endif # if defined O_cfcs_data_transient call setbcx (sbc(1,1,icfc11flx), imt, jmt) call setbcx (sbc(1,1,icfc12flx), imt, jmt) # endif # endif # endif # if defined O_embm_read_sflx call read_var ("F_salt.nc", "F_salt", sbc(1,1,isflx), ntrec) # elif defined O_embm_write_sflx call write_var ("F_salt.nc", "F_salt", sbc(1,1,isflx), ntrec) # endif #endif # if defined O_sulphate_data_transient !----------------------------------------------------------------------- ! set anthropogenic sulphate forcing (increase in surface albedo) ! for the next atmospheric step from updated surface albedo !----------------------------------------------------------------------- call sulphdata zero(1) = 0. cz(1) = 0. sindec = 0. do j=jsp1,jem1 do i=isp1,iem1 if (sulph(i,j,2) .gt. 0. .and. solins(i,j) .gt. 0.) then tot = 0. twt = 0. ! calculate sunlight weighted daily average zenith angle do k=1,24 call zenith (1, (k-1)*3600., 3600., daylen, tlat(i,j) &, zero(1), sindec, cz(1)) tot = tot + cz(1)*cz(1) twt = twt + cz(1) enddo cz(1) = 0. if (twt .gt. 0) cz(1) = tot/twt ! convert from optical depth to albedo if (cz(1) .gt. 0.05) then ! reonstruct surface coalbedo tmp = solins(i,j) - solins(i,j)*(1. - sbc(i,j,iaca)) & - solins(i,j)*sbc(i,j,iaca)*scatter if (tmp .gt. 0.) then tmp = dnswr(i,j)/tmp sulph(i,j,2) = 0.29*sulph(i,j,2)*tmp**2/cz(1) else sulph(i,j,2) = 0. endif else sulph(i,j,2) = 0. endif endif enddo enddo # endif return end #if defined O_embm_read_sflx subroutine read_var (fname, vname, var, ntrec) implicit none character (*) :: fname, vname integer ib(10), ic(10), iou, ntrec include "size.h" include "param.h" include "pconst.h" include "stdunits.h" include "tmngr.h" real var(imt,jmt), tmpij(imtm2,jmtm2) ntrec = ntrec + 1 call openfile (trim(fname), iou) ib(:) = 1 ib(3) = ntrec ic(:) = 1 ic(1) = imtm2 ic(2) = jmtm2 call getvara (trim(vname), iou, imtm2*jmtm2, ib, ic, tmpij &, 1., 0.) var(2:imtm1,2:jmtm1) = tmpij(1:imtm2:1:jmtm2) embmbc (var) return end #endif #if defined O_embm_write_sflx subroutine write_var (fname, vname, var, ntrec) implicit none character (*) :: fname, vname integer ib(10), ic(10), it(10), id_time, id_xt, id_yt, iou, ntrec integer nyear, nmonth, nday, nhour, nmin, nsec real tmp include "size.h" include "param.h" include "pconst.h" include "stdunits.h" include "coord.h" include "tmngr.h" real var(imt,jmt), tmpij(imtm2,jmtm2), tmpi(imtm2), tmpj(jmtm2) ntrec = ntrec + 1 call openfile (trim(fname), iou) if (ntrec .eq. 1) then call redef (iou) call defdim ('time', iou, 0, id_time) call defdim ('longitude', iou, imtm2, id_xt) call defdim ('latitude', iou, jmtm2, id_yt) it(:) = id_time call defvar ('time', iou, 1, it, c0, c0, 'T', 'D' &, 'time', 'time', 'years since 0-1-1') call putatttext (iou, 'time', 'calendar', calendar) it(1) = id_xt call defvar ('longitude', iou, 1, it, 0., 0., 'X', 'D' &, 'longitude', 'longitude', 'degrees_east') it(1) = id_yt call defvar ('latitude', iou, 1, it, 0., 0., 'Y', 'D' &, 'latitude', 'latitude', 'degrees_north') it(:) = id_xt it(2) = id_yt it(3) = id_time call defvar (trim(vname), iou, 3, it, -1.e20, 1.e20, ' ', 'D' &, ' ',' ', ' ') call enddef (iou) !----------------------------------------------------------------------- ! write 1d data (t) !----------------------------------------------------------------------- call rdstmp (stamp, nyear, nmonth, nday, nhour, nmin, nsec) ib(:) = 1 ic(:) = imtm2 tmpi(1:imtm2) = xt(2:imtm1) call putvara ('longitude', iou, imtm2, ib, ic, tmpi, c1, c0) ic(:) = jmtm2 tmpj(1:jmtm2) = xt(2:jmtm1) call putvara ('latitude', iou, jmtm2, ib, ic, tmpj, c1, c0) endif call putvars ('time', iou, ntrec, relyr, c1, c0) ib(:) = 1 ib(3) = ntrec ic(:) = 1 ic(1) = imtm2 ic(2) = jmtm2 tmpij(1:imtm2:1:jmtm2) = var(2:imtm1,2:jmtm1) call putvara (trim(vname), iou, imtm2*jmtm2, ib, ic, tmpij &, 1., 0.) return end #endif