!------------------------------------------------------------------------- ! NASA/GSFC, Global Modeling and Assimilation Office, Code 601.1 ! !------------------------------------------------------------------------- !BOP ! ! !ROUTINE: model_tl: Main interface to AGCM tangent linear model ! ! !INTERFACE: subroutine model_tl(xini,xobs,ldprt) ! !USES: use kinds, only: r_kind,i_kind use gsi_4dvar, only: nsubwin,nobs_bins,winlen,winsub,hr_obsbin use gsi_4dvar, only: iadatebgn,idmodel use constants, only: zero,r3600 use state_vectors use geos_pertmod, only: ndtpert use m_tick, only: tick use timermod, only: timer_ini,timer_fnl #ifdef GEOS_PERT use prognostics, only: dyn_prog use prognostics, only: prognostics_initial use prognostics, only: prognostics_final use geos_pertmod, only: gsi2pgcm use geos_pertmod, only: pgcm2gsi use m_model_tl, only: initial_tl use m_model_tl, only: amodel_tl use m_model_tl, only: final_tl #endif /* GEOS_PERT */ use lag_fields, only: nlocal_orig_lag, ntotal_orig_lag use lag_fields, only: lag_tl_vec,lag_ad_vec,lag_tl_spec_i,lag_tl_spec_r use lag_fields, only: lag_u_full,lag_v_full use lag_fields, only: lag_gather_stateuv use lag_traj, only: lag_rk2iter_tl ! use lag_traj, only: lag_rk4iter_tl implicit none ! !INPUT PARAMETERS: type(state_vector), intent(in ) :: xini(nsubwin) ! State variable at control times logical , intent(in ) :: ldprt ! Print-out flag ! !OUTPUT PARAMETERS: type(state_vector), intent(inout) :: xobs(nobs_bins) ! State variable at observations times ! !DESCRIPTION: Run AGCM tangent linear model. ! ! !REMARKS: ! ! !REVISION HISTORY: ! ! 19Apr2007 tremolet - initial code ! 29May2007 todling - add actual calls to interface and AGCM TL model ! 30Sep2007 todling - add timer ! 30Apr2009 meunier - add trajectory model for lagrangian data ! !EOP !----------------------------------------------------------------------- ! Declare local variables character(len=*), parameter :: myname = 'model_tl' type(state_vector) :: xx integer(i_kind) :: nstep,istep,nfrctl,nfrobs,ii,jj,ierr integer(i_kind) :: nymdi,nhmsi,ndt,dt real(r_kind) :: tstep,zz,d0 #ifdef GEOS_PERT type(dyn_prog) :: xpert #endif /* GEOS_PERT */ !****************************************************************************** ! Initialize timer call timer_ini('model_tl') ! Initialize variables d0=zero if (idmodel) then tstep = r3600 dt = tstep ndt = 1 else ! tstep = REAL(ndtpert,r_kind) ndt = NINT(hr_obsbin*r3600/ndtpert) dt = ndt*ndtpert tstep = dt endif nstep = NINT(winlen*r3600/tstep) nfrctl = NINT(winsub*r3600/tstep) nfrobs = NINT(hr_obsbin*r3600/tstep) nymdi = iadatebgn/100 nhmsi = (iadatebgn-100*nymdi)*10000 call allocate_state(xx) xx=zero ! Checks zz=real(nstep,r_kind)*tstep if (ABS(winlen*r3600 -zz)>epsilon(zz)) then write(6,*)'model_tl: error nstep',winlen,zz call stop2(147) end if zz=real(nfrctl,r_kind)*tstep if (ABS(winsub*r3600 -zz)>epsilon(zz)) then write(6,*)'model_tl: error nfrctl',winsub,zz call stop2(148) end if zz=real(nfrobs,r_kind)*tstep if (ABS(hr_obsbin*r3600-zz)>epsilon(zz)) then write(6,*)'model_tl: error nfrobs',hr_obsbin,zz call stop2(149) end if if (ndt<1)then write(6,*)'model_tl: error ndt',ndt call stop2(150) end if if (ldprt) write(6,'(a,3(1x,i4))')'model_tl: nstep,nfrctl,nfrobs=',nstep,nfrctl,nfrobs ! Initialize GCM TLM and its perturbation vector #ifdef GEOS_PERT if (.not.idmodel) then call initial_tl call prognostics_initial ( xpert ) endif #endif /* GEOS_PERT */ ! Initialize trajectory TLM and vectors lag_tl_vec(:,:,:)=zero lag_ad_vec(:,:,:)=zero ! Run TL model do istep=0,nstep-1 ! Apply control vector to x_{istep} if (MOD(istep,nfrctl)==0) then ii=istep/nfrctl+1 if (ldprt) write(6,'(a,i8.8,1x,i6.6,2(1x,i4))')'model_tl: adding WC nymd,nhms,istep,ii=',nymdi,nhmsi,istep,ii if (ii<1.or.ii>nsubwin) then write(6,*)'model_tl: error xini',ii,nsubwin call stop2(151) end if call self_add(xx,xini(ii)) endif ! Post-process x_{istep} if (MOD(istep,nfrobs)==0) then ii=istep/nfrobs+1 if (ldprt) write(6,'(a,i8.8,1x,i6.6,2(1x,i4))')'model_tl: saving state nymd,nhms,istep,ii=',nymdi,nhmsi,istep,ii if (ii<1.or.ii>nobs_bins) then write(6,*)'model_tl: error xobs',ii,nobs_bins call stop2(152) end if xobs(ii) = xx d0=d0+dot_product(xx,xx) endif ! Apply TL trajectory model (same time steps as obsbin) if (MOD(istep,nfrobs)==0 .and. ntotal_orig_lag>0) then ii=istep/nfrobs+1 if (ldprt) write(6,'(a,i8.8,1x,i6.6,2(1x,i4))')'model_tl: trajectory model nymd,nhms,istep,ii=',nymdi,nhmsi,istep,ii if (ii<1.or.ii>nobs_bins) call abor1('model_tl: error xobs') ! Gather winds from the increment call lag_gather_stateuv(xx%u,xx%v,ii) ! Execute TL model do jj=1,nlocal_orig_lag lag_tl_vec(jj,ii+1,:)=lag_tl_vec(jj,ii,:) ! if (.not.idmodel) then call lag_rk2iter_tl(lag_tl_spec_i(jj,ii,:),lag_tl_spec_r(jj,ii,:),& &lag_tl_vec(jj,ii+1,1),lag_tl_vec(jj,ii+1,2),lag_tl_vec(jj,ii+1,3),& &lag_u_full(:,:,ii),lag_v_full(:,:,ii)) print '(A,I3,A,F14.6,F14.6)',"TLiter: ",ii+1," location",lag_tl_vec(jj,ii+1,1),lag_tl_vec(jj,ii+1,2) ! endif end do endif ! Apply TL model #ifdef GEOS_PERT if (.not.idmodel) then call gsi2pgcm ( xx, xpert, 'tlm', ierr ) ! T call amodel_tl (xpert,nymdi=nymdi,nhmsi=nhmsi,ntsteps=ndt,g5pert=.true.) ! M call pgcm2gsi ( xpert, xx, 'tlm', ierr ) ! T(-1) endif #endif /* GEOS_PERT */ call tick (nymdi,nhmsi,dt) enddo ! Post-process final state if (nobs_bins>1) then if (ldprt) write(6,'(a,i8.8,1x,i6.6,2(1x,i4))')'model_tl: saving state nymdi,nhmsi,nobs_bins=',nymdi,nhmsi,nobs_bins xobs(nobs_bins) = xx d0=d0+dot_product(xx,xx) endif if(ldprt) print *, myname, ': total (gsi) dot product ', d0 ! Finalize GCM TLM and its perturbation vector #ifdef GEOS_PERT if (.not.idmodel) then call prognostics_final ( xpert ) call final_tl endif #endif /* GEOS_PERT */ call deallocate_state(xx) ! Finalize timer call timer_fnl('model_tl') return end subroutine model_tl