subroutine minvar,1 use mod4dv, only : l4dvar use oda_shared, only : dg_vbar ! #if defined (DOC) ! !Purpose: ! Setup of 3D/4D VAR minimization ! *Author : P. Gauthier *ARMA/AES June 9, 1992 *Revision: * * . P. Koclas *CMC/CMDA February 94 * -comdeck comgdpar added for argument in call to postproc * . -new definition for zxmin * . C. Charette *ARMA/AES Jan 96 * . -Etikette for analysed increments * -Open restart files and call to DEMARRE if LRSTART = .T. * -Write restart files. Do test of the gradient * according the status of the minimization * -Added call supost. Added trial fields to RPN standard file * . S. Pellerin *ARMA/AES Sept 97. * -Control of GRTEST and its output to fst file * . S. Pellerin *ARMA/AES . * -Added call to PRINTREV * . C. Charette *ARMA/AES Jul 98. * -Changed etiket of gradient fields (NGRTEST=1) * . S. Pellerin *ARMA/SMC May 2000 * -Control for minimization with preproc and postproc * subroutine calls at cnt0 level * . C. Charette *ARMA/SMC Nov 2000 * -Move call RSETCMA completely to the end * . B. Brasnett *CMC/CMDA Dec 200 * -Control the use of VarQC * . JM Belanger CMDA/SMC April 2001 * - 32 bits conversion * - Replace call to M1QN3 by N1QN3 * . S. Pellerin SMC/ARMA Nov. 2001 * - Send of an end of simulation signal to TLM-ADJ unit * . M. Buehner *ARMA/SMC April 2002 * - Added call to suprecon for Hessian eigenvector * preconditioning * . P. Gauthier *ARMA/MSC July 2003 * . - Numerous changes to insure that the printouts do reflect * what the minimization * . has seen. Improvements to the clarity of printouts. * . PRNTHDR and PRNTBDY have been restricted to print results * for assimilated data only * . GRTEST is now called after the minimization when NGRTEST = 1 * (in NAMELIST) * . S. Pellerin *ARMA/SMC August 2004 * - Modification of the preconditioning file for multi-dataset * outer-loop need * . S. Pellerin *ARMA/MSC January 2005 * - Dynamical Multi-Inc. : Call to rw_vatra * . M. Tanguay *ARMN/MSC Jan. 2005 * - Introduction of minimizer N1CG1 * . J. Halle *CMDA/SMC May. 2006 * - Added non-linear treatment of 'TO' data * - Req'd addition of partov.cdk, comtov.cdk, and namtov.cdk. * . S. Pellerin, ARMA, August 2008 * - Added calls to 'tmg_*' subroutines * . S. Pellerin, ARMA, January 2009 * - Subroutine minimize renamed under minvar * - Introduction of the new simulator (simvar) * - Introduction of a new global vbar variable (instead of vazxbar) * - Introduction of new grtest2 * Y. Yang Feb. 2010 * - added comnumbr.cdk due to dependencies on JPNBRELEM in cvcord.cdk * - straighten indentation in the DOC section * . Y.J. Rochon *ARQX March 2010 * - Added test with IMODE.eq.6. * ------------------- #endif ! *Arguments * -NONE- IMPLICIT NONE *implicits #include "comdim.cdk"
#include "comlun.cdk"
#include "comcst.cdk"
#include "comcva.cdk"
#include "comgdpar.cdk"
#include "comvarqc.cdk"
#include "comvfiles.cdk"
#include "comanl.cdk"
#include "comnumbr.cdk"
#include "cvcord.cdk"
#include "partov.cdk"
#include "comtov.cdk"
* C INTEGER IZS(1),IZTRL(10) REAL ZZSUNUSED(1) REAL*8 DLDS(1) LOGICAL LLTEST,llvarqc, llstop, lldf1, lrdvatra, llvazx, llxbar C INTEGER IMPRES, IMODE, ITERMAX, iterdone, ISIMMAX, INDIC, IITNOVQC INTEGER IERR,ITERTOT,isimdone,isimtot,jdata, ISIMNOVQC integer ireslun,ibrpstamp,isim3d INTEGER IPRECON,ILEN REAL*8 ZJSP, ZXMIN, ZDF1, ZEPS0, ZEPS1 REAL*8 DLGNORM, DLXNORM, ZJOTOV C INTEGER FNOM,FCLOS,II, remove_c EXTERNAL FNOM,FCLOS,MVPROD EXTERNAL TESTSP, M1QN2, N1QN3 S , DSCALQN, DCANAB, DCANONB, PRSCAL , DEMARRE S , TRANSFER, SUPOST, simvar real*8 :: zeps0_000,zdf1_000 integer :: iterdone_000,isimdone_000 character(len=128) :: clfname C logical bid_L C C Additional parameters for minimization (N1CG1) C ---------------------------------------------- real*8 xx,bb,a_not_use,r8_not_use,pj0 integer in_mode(3),out_mode,i_not_use,nilm,ilm0(10),ilm1(10) integer i_pmat1,nl_stat, dl_bidon C C ------------------------------------------ C allocate(dg_vbar(nvadim),STAT=nl_stat) if (nl_stat .ne. 0) then write(nulout,*) 'MINVAR: PROBLEM allocating state vectors' call abort3d(NULOUT,'MINVAR: allocation problem') endif dg_vbar = 0.d0 C Initialization and allocation specific to (N1CG1) C ------------------------------------------------- if( N1GC.EQ.4.and.lvarqc ) call abort3d(nulout & ,' MINIMIZE N1CG1 with lvarqc not done ') if( BFGSB.EQ.1 ) call abort3d(nulout & ,' MINIMIZE n1cg1: option not validated ') C C Define i_pmat1 even if BFGSB.NE.1 (Otherwise abort in n1cg1) C ------------------------------------------------------------ i_pmat1 = NVADIM**2 C in_mode(2) = 0 in_mode(3) = IMODE3 C nilm = NVAMAJ + 3 if( nilm.gt.10 .and. N1GC.EQ.4) call abort3d(nulout & ,' MINIMIZE n1cg1: ilm0,ilm1 incorrect ') C C ------------------------------------------------- c Prepare for non-linear processing of 'TO' data: c - fill PZDBLPRIM8 with Z" = H(xb_lr) + Z' c = H(xb_lr) - H(xb_hr) + Z c if ( lnlvtov ) then call tmg_start(60,'RTTOV') call tovs_obs ('LR', ZJOTOV) call tmg_stop(60) endif c ITERTOT = 0 isimtot = 0 C ZXMIN = RPRECIS C * 2. Set-up the minimization C . ----------------------- llvarqc = lvarqc c If minimization start without qcvar : turn off varqc to compute c innovations and test the gradients ireslun=0 lldf1 = .true. if(niterjob /= -1 .and. lrestart) then if( N1GC.EQ.4 ) call abort3d(nulout,' MINIMIZE N1CG1 with restart not done ') write(nulout,*) 'Minimize : Restart mode' lrdvatra = .true. clfname = crestart imode = 2 llvazx = .true. llxbar = .true. elseif (lpcon .and. nprecon <= 0) then write(nulout,*) 'Minimize : Preconditioning mode' lrdvatra = .true. clfname = cpconf imode = 2 llvazx = .false. llxbar = lxbar ! from namcva (default is .true.) else lrdvatra = .false. imode = 0 zeps0 = repsg endif if(.not.(imode.eq.0.or.imode.eq.2)) call abort3d(nulout,' RW_VATRA not done ') if (lrdvatra) then ibrpstamp = nbrpstamp ! ibrpstamp is a I/O argument of rw_vatra * if(n1gc.eq.3) then call rw_vatra (clfname,0, % isim3d,ibrpstamp,zeps0_000,zdf1_000,iterdone_000 & ,isimdone_000,iztrl,vatra,nmtra,dg_vbar,nvadim, & vazx,ntrunc,nksdim,nvamaj,llxbar,llvazx,n1gc,imode) * elseif(n1gc.eq.4) then call rw_vatra (clfname,0, % isim3d,ibrpstamp,zeps0_000,zdf1_000,iterdone_000 & ,isimdone_000,ilm0,vatra,nmtra,dg_vbar,nvadim, & vazx,ntrunc,nksdim,nvamaj,llxbar,llvazx,n1gc,imode) endif if(niterjob /= -1 .and. lrestart) then ierr = remove_c(clfname) nsim3d = isim3d write(nulout,*) 'MINVAR : NSIM3D read from precon file: ' & ,nsim3d zeps0 = zeps0_000 zdf1 = zdf1_000 lldf1 = .false. ! don't re-compute df1 base on Cost function iterdone = iterdone_000 isimdone = isimdone_000 - 1 itermax = min(nitermax - iterdone + 1, niterjob) isimmax = nsimmax - isimdone + 1 if (iterdone < nwoqcv) lvarqc = .false. else if (ibrpstamp == nbrpstamp .and. lxbar) then zeps0 = zeps0_000 zdf1 = zdf1_000 lldf1 = .false. ! don't re-compute df1 base on Cost function else zeps0 = repsg lldf1 = .true. ! Compute df1 base on Cost function endif endif endif if(niterjob == -1 .or. .not. lrestart) then iterdone = 0 isimdone = 0 if (niterjob /= -1) then itermax = min(nitermax,niterjob) else itermax = nitermax endif isimmax = nsimmax c if (nwoqcv > 0) lvarqc = .false. c if(ngrtest.ne.0) then call grtest2(simvar,nulout,nvadim,vazx,ngrange) endif endif C zeps1 = zeps0 itertot = iterdone isimtot = isimdone C * 2. Set-up the minimization C . ----------------------- c c Calculate Hessian Eigenvectors c IF(NPRECON.ge.1) THEN NCV=2*NPRECON NCORDIM=NVADIM ILEN = NCORDIM*NCV CALL HPALLOC(PTRRNK1,MAX(ILEN,1),IERR,8) ILEN = NCORDIM*NPRECON CALL HPALLOC(PTRRNK2,MAX(ILEN,1),IERR,8) ILEN = NPRECON CALL HPALLOC(PTHESEVAL,MAX(ILEN,1),IERR,8) CALL SUPRECON
ENDIF C C * . Test the gradient again at the initial point WITH PRECON C . -------------------------------------------------------- C C . 2.1.4 Test the complete functional C IF(NPRECON.gt.0 .and. ngrtest.ne.0) THEN WRITE(NULOUT,*) '***STARTING GRTEST WITH PRECON***' call grtest2(simvar,nulout,nvadim,vazx,ngrange) ENDIF C C * . 2.2 Compute the value of J(X) and the gradient C . at the initial point C INDIC =2 call simvar(indic,nvadim,vazx,zjsp,vazg) if (lldf1) ZDF1 = rdf1fac * ABS(ZJSP) C Put QCVAR logical to its original values lvarqc=llvarqc C CALL PRSCAL(NVADIM,VAZG,VAZG,DLGNORM) DLGNORM = DSQRT(DLGNORM) CALL PRSCAL(NVADIM,VAZX,VAZX,DLXNORM) DLXNORM = DSQRT(DLXNORM) WRITE(NULOUT,*)' |X| = ', DLXNORM WRITE(NULOUT,FMT=9220) ZJSP, DLGNORM 9220 FORMAT(/4X,'J(X) = ',G23.16,4X,'|Grad J(X)| = ',G23.16) C C * . 2.4. Constants required by MODULOPT C . ------------------------------ C IMPRES = NIMPRES C C * 3. Iterations of the minimization algorithm C . ---------------------------------------- C C C * . 3.2 Starting point of the minimization written to C . RPN standard output file C IF(N1GC.EQ.3) THEN WRITE(NULOUT,FMT=9320)ZXMIN,ZDF1,ZEPS0,IMPRES,NITERMAX,NSIMMAX ELSEIF(N1GC.EQ.4) THEN WRITE(NULOUT,FMT=9321)ZXMIN,ZDF1,ZEPS0,EPSNEG,SELECT0,BFGSB,IMODE3,IMPRES,NITERMAX,NSIMMAX ENDIF c 9320 FORMAT(//,10X,' Minimization N1QN3 starts ...',/ S 10x,'DXMIN =',G23.16,2X,'DF1 =',G23.16,2X,'EPSG =',G23.16 S /,10X,'IMPRES =',I3,2X,'NITER = ',I3,2X,'NSIM = ',I3,// S ,15X,'-STARTING POINT IS WRITTEN TO FILE ...') 9321 FORMAT(//,10X,' Minimization N1CG1 starts ...',/ S 10x,'DXMIN =',G23.16,2X,'DF1 =',G23.16,2X,'EPSG =',G23.16,2X,'EPSNEG =',G23.16,/, $ 10x,'SELECT0 = ',I3,2X,'BFGSB = ',I3,2X,'IMODE3 = ',I3, S /,10X,'IMPRES =',I3,2X,'NITER = ',I3,2X,'NSIM = ',I3,2X,'NHESS = ',I3,// S ,15X,'-STARTING POINT IS WRITTEN TO FILE ...') C C * . 3.3 Beginning the minimization C . -------------------------- c llstop = .false. if (lvarqc .and. nwoqcv > 0 .and. iterdone < nwoqcv) then iitnovqc = min(nwoqcv - iterdone,itermax) isimnovqc = isimmax lvarqc = .false. call tmg_start(21,'QN') call n1qn3(simvar, dscalqn, dcanonb, dcanab, nvadim, vazx, & zjsp,vazg, zxmin, zdf1, zeps1, impres, nulout, imode & ,iitnovqc, isimnovqc ,iztrl, vatra, nmtra, izs, zzsunused & ,dlds) call tmg_stop (21) isimnovqc = isimnovqc - 1 itermax = itermax - iitnovqc + 1 isimmax = isimmax - isimnovqc + 1 itertot = itertot + iitnovqc isimtot = isimtot + isimnovqc zeps1 = zeps0/zeps1 zeps0 = zeps1 lvarqc = .true. if (imode == 4 .and. itertot < nitermax) then imode = 2 INDIC = 2 call simvar(indic,nvadim,vazx,zjsp,vazg) c CALL SIM3D(INDIC,NVADIM,VAZX,ZJSP,VAZG) else llstop = .true. endif endif if (.not. llstop) then C if(N1GC.EQ.3) then C call tmg_start(21,'QN') call n1qn3(simvar, dscalqn, dcanonb, dcanab, nvadim, vazx, & zjsp,vazg, zxmin, zdf1, zeps1, impres, nulout, imode, & itermax,isimmax, iztrl, vatra, nmtra, izs, zzsunused, & dlds) call tmg_stop (21) itertot = itertot + itermax isimtot = isimtot + isimmax C zeps1 = zeps0/zeps1 C elseif(N1GC.EQ.4) then C C Set VAZB = - VAZG (Valid only if VAZX = ZERO) C --------------------------------------------- VAZB = - VAZG C C Keep constant term in pj0 (Valid only if VAZX = ZERO) C ----------------------------------------------------- pj0 = ZJSP C C Print cost function at iter 0 (Valid only if VAZX = ZERO) C --------------------------------------------------------- WRITE(NULOUT,FMT=9700) 0,0.d0+pj0,pj0,0.d0 9700 FORMAT (4x,"n1cga:",i5,1x,e15.8,1x,e15.8,1x,e15.8) C if(imode.eq.0) in_mode(1) = 0 if(imode.eq.2) in_mode(1) = 1 C call n1cg1 (mvprod,NVADIM,VAZX,VAZB,a_not_use,pj0,xx,bb,.false & .,EPSNEG,zeps1,itermax,impres,NULOUT,in_mode,out_mode & ,VWORK,NWORK,imode,r8_not_use,i_not_use,NVAMAJ,ilm0,nilm & ,VATRA,NMTRA,BFGSB,r8_not_use,i_pmat1, NVAMAJ,ilm1,nilm & ,VATR1,NMTRA,SELECT0,izs,zzsunused,dlds) C zeps1 = zeps0/zeps1 zeps0 = zeps1 C imode = out_mode C isimmax = itermax C itertot = itertot + itermax isimtot = isimtot + isimmax C C Call 4D-Var simulator without gradient to get ZJSP C -------------------------------------------------- INDIC = 2 call simvar(indic,nvadim,vazx,zjsp,vazg) c CALL SIM3D(INDIC,NVADIM,VAZX,ZJSP,VAZG) C endif C endif c if lrestart remain false... postmin will execute lrestart = .false. ireslun=0 if (niterjob /= -1 .and. itertot < nitermax .and. imode == 4) then clfname = crestart c Careful: lrestart before minimisation was used to trigger a C read of restart file... now it is set to .true. to avoid C execution of postmin. lrestart = .true. else do jdata = 1, nvadim dg_vbar(jdata) = vazx(jdata) + dg_vbar(jdata) enddo clfname = 'pm1q' endif if(n1gc.eq.3) then call rw_vatra (clfname,1, % nsim3d,nbrpstamp,zeps1,zdf1,itertot,isimtot, % iztrl,vatra,nmtra, % dg_vbar,nvadim, % vazx,ntrunc,nksdim,nvamaj,.true.,llvazx,n1gc,imode) elseif(n1gc.eq.4) then call rw_vatra (clfname,1, % nsim3d,nbrpstamp,zeps1,zdf1,itertot,isimtot, % ilm1,vatr1,nmtra, % dg_vbar,nvadim, % vazx,ntrunc,nksdim,nvamaj,.true.,llvazx,n1gc,imode) ENDIF WRITE(NULOUT,FMT=9500) imode,iterdone,itertot-iterdone,itertot & ,isimdone,isimtot-isimdone,isimtot if (imode.eq.6) call abort3d(nulout,' MINIMIZE: Aborted minimization due to MODE value ') 9500 FORMAT(//,20X,20('*'),2X & ,/,20X,' Minimization ended with MODE:',I4 S ,/,20X,' Number of iterations done in previous job:',I4 S ,/,20X,' Number of iterations in this job:',I4 S ,/,20X,' Total number of iterations:',I4 S ,/,20X,'Number of simulations done in previous job:',I4 S ,/,20X,' Number of simulations in this job:',I4 S ,/,20X,' Total number of simulations:',I4) c niter = itertot C C * 4. Test the gradient at the final point if NGRTEST=1 C . ------------------------------------ C 400 CONTINUE C if ((NGRTEST.ne.0 .and. IMODE.ne.4 .and. .not. LRSTART)) then WRITE(NULOUT,FMT=9400) 9400 FORMAT(//,12X,40('**'),/,12X, S 'TESTING THE GRADIENT AT THE FINAL POINT',/,40('**')) ! call grtest2(simvar,nulout,nvadim,vazx,ngrange) ! END IF if(l4dvar) call endsim2(nvadim,vazx) C RETURN END