!-------------------------------------- LICENCE BEGIN ------------------------------------
!Environment Canada - Atmospheric Science and Technology License/Disclaimer,
! version 3; Last Modified: May 7, 2008.
!This is free but copyrighted software; you can use/redistribute/modify it under the terms
!of the Environment Canada - Atmospheric Science and Technology License/Disclaimer
!version 3 or (at your option) any later version that should be found at:
!http://collaboration.cmc.ec.gc.ca/science/rpn.comm/license.html
!
!This software is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
!without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
!See the above mentioned License/Disclaimer for more details.
!You should have received a copy of the License/Disclaimer along with this software;
!if not, you can write to: EC-RPN COMM Group, 2121 TransCanada, suite 500, Dorval (Quebec),
!CANADA, H9P 1J3; or send e-mail to service.rpn@ec.gc.ca
!-------------------------------------- LICENCE END --------------------------------------
***s/r v4d_gem - Control 4-D variational job based on GEM model
*
#include "model_macros_f.h"
*
subroutine v4d_gem 1,15
*
implicit none
*
*author
* M.Tanguay
*
*revision
* v2_10 - Tanguay M. - initial MPI version
* v2_31 - Tanguay M. - Move v4d_setscalp after set_dync
* v3_00 - Tanguay M. - add V4dg_twin_L and V4dg_4dvar_L
* v3_01 - Morneau J. - add V4dg_sensib_L
* v3_11 - Tanguay M. - Introduce V4dg_oktrcv_L
* - Add V4dg_part=2 before first call to indata
*
*object
* see id section
*
*arguments
* none
*
*implicits
#include "lun.cdk"
#include "v4dg.cdk"
#include "v4dm.cdk"
#include "v4dc.cdk"
#include "lctl.cdk"
#include "schm.cdk"
#include "ptopo.cdk"
#include "rstr.cdk"
#include "step.cdk"
#include "tr3d.cdk"
#include "v4dj.cdk"
*
*modules
integer fnom
external fnom,v4d_simul0,v4d_scalpro0,v4d_ctonb,v4d_ctcab
*
integer n,indic,pnerr,iun_newguess,iun_hotstart,wrt_out
*
real pj,df1prev
real*8 gnorm_8
*
* Additional minimization (M1QN3) parameters
* -----------------------------------------
integer izs(1),iz(5)
real rzs(1)
real*8 dzs_8(1)
* ______________________________________________________
*
* --------------------------------------
* Read given analysis of model variables
* --------------------------------------
if( Lun_out.gt.0 ) then
write(Lun_out,
$ fmt='('' 4D-VARIATIONAL JOB with CONF = '',I6)') V4dg_conf
write(Lun_out,
$ fmt='('' ----------------------------------'')')
write(Lun_out, fmt='(//''-------------------'')')
write(Lun_out, fmt='( ''READ GIVEN ANALYSIS'')')
write(Lun_out, fmt='( ''-------------------'')')
endif
*
V4dg_part = 2
call indata
()
*
* ------------------------------------------------------------------
* Set inner product in control space variables (done after set_dync)
* ------------------------------------------------------------------
call v4d_setscalp
()
*
* -----------------------------
* Set IDENTICAL TWIN experiment
* ---------------------------------------------------------------------------------
* Build simulated OBSERVATIONS and initialize CURRENT (first iterate) initial state
* ---------------------------------------------------------------------------------
if( V4dg_twin_L ) then
*
* Initialize REFERENCE initial control var. in V4dc_ycv
* from model var.
* -----------------------------------------------------
call v4d_cainin
(V4dc_ncv,V4dc_ycv)
*
* Run REFERENCE integration to build simulated OBSERVATIONS
* ---------------------------------------------------------
if( Lun_out.gt.0 ) then
write(Lun_out,
% fmt='(//''-------------------------------------------'')')
write(Lun_out,
% fmt='( ''REFERENCE INTEGRATION TO BUILD OBSERVATIONS'')')
write(Lun_out,
% fmt='( ''-------------------------------------------'')')
endif
*
* Set status of the integration (REFERENCE integration)
* -----------------------------------------------------
V4dg_status = 5
*
* Set over-riding switch for dynout and blocstat
* ----------------------------------------------
V4dg_output_L = .true.
*
* Deactivate WRITE option on TRAJECTORY VMM WA file
* -------------------------------------------------
V4dg_oktr_L = .false.
*
* Deactivate WRITE option on TRAJECTORY Conversion WA file
* --------------------------------------------------------
V4dg_oktrcv_L = .false.
*
* Call 4D-Var simulator without gradient
* --------------------------------------
indic = 99
call v4d_simul
(indic,V4dc_ncv,V4dc_ycv,pj,V4dc_gcv)
*
* Reactivate WRITE option on TRAJECTORY VMM WA file
* -------------------------------------------------
V4dg_oktr_L = .true.
*
* Reactivate WRITE option on TRAJECTORY Conversion WA file
* --------------------------------------------------------
V4dg_oktrcv_L = .true.
*
* Initialize CURRENT (first iterate) initial state
* ------------------------------------------------
*
* Initialize CURRENT initial control var. in V4dc_xcv
* from REFERENCE final model var. with true winds
* ---------------------------------------------------
*
* Convert wind images to true winds
* ---------------------------------
call v4d_img2uv
()
*
* Initialize V4dc_xcv from model var.
* -----------------------------------
call v4d_cainin
(V4dc_ncv,V4dc_xcv)
*
* ------------------------
* Set SENSITIVITY ANALYSIS
* ------------------------
else if ( V4dg_sensib_L ) then
* ----------------------------------------------------
* If requested :
* Read Observation location (mask) in observation file
* ----------------------------------------------------
if (V4dj_mask_L) call v4d_rdmask
*
* ----------------------------------------------------
* Build trajectory for TLM in cost function
* AND
* Convert observations from random file to WA file
* ----------------------------------------------------
*
* Initialize REFERENCE initial control var. in V4dc_ycv
* from model var.
* -----------------------------------------------------
call v4d_cainin
(V4dc_ncv,V4dc_ycv)
*
* Run REFERENCE integration to build TRAJECTORY
* ---------------------------------------------------------
if( Lun_out.gt.0 ) then
write(Lun_out,
% fmt='(//''-------------------------------------------'')')
write(Lun_out,
% fmt='( ''REFERENCE INTEGRATION TO BUILD TRAJECTORY '')')
write(Lun_out,
% fmt='( ''-------------------------------------------'')')
endif
*
* Set status of the integration (REFERENCE integration)
* -----------------------------------------------------
V4dg_status = 5
*
* Set over-riding switch for dynout and blocstat
* ----------------------------------------------
V4dg_output_L = .true.
*
* Call 4D-Var simulator without gradient
* --------------------------------------
indic = 99
call v4d_simul
(indic,V4dc_ncv,V4dc_ycv,pj,V4dc_gcv)
*
* Initialize CURRENT (first iterate) initial state
* ------------------------------------------------
*
do n = 1,V4dc_ncv
V4dc_xcv(n) = 0.0
enddo
*
endif
*
* ----------------------------------------------------------------------
* 4D-VAR minimization starting from CURRENT (first iterate) control var.
* ----------------------------------------------------------------------
*
* ---------------
* Initializations
* ---------------
*
* COLD START
* ----------
if(V4dm_hot.eq.0) then
*
V4dm_mode = 0
V4dm_nsim = 0
*
* WARM START = restart from previously stored iterate
* ---------------------------------------------------
else
*
V4dm_mode = 2
*
iun_newguess = 0
iun_hotstart = 0
pnerr = fnom( iun_newguess, 'newguess', 'FTN+SEQ+UNF' , 0)
pnerr = fnom( iun_hotstart, 'hotstart', 'FTN+SEQ+UNF' , 0)
*
read(iun_newguess) (V4dc_xcv(n),n=1,V4dc_ncv),df1prev,pj,
% (V4dc_gcv(n),n=1,V4dc_ncv)
read(iun_hotstart) iz,V4dm_nsim
read(iun_hotstart) (V4dc_wkmin(n),n=1,V4dc_ncv)
*
call fclos(iun_newguess)
call fclos(iun_hotstart)
*
endif
*
* -------------------------------------------------------
* Run CURRENT (first iterate) DIRECT and ADJ integrations
* -------------------------------------------------------
*
if( Lun_out.gt.0 ) then
write(Lun_out, fmt='(//''-----------------------------------------------'')')
write(Lun_out, fmt='( ''Run CURRENT (FIRST ITERATE) DIRECT and ADJ INT.'')')
write(Lun_out, fmt='( ''-----------------------------------------------'')')
endif
*
* Set status of the integration [CURRENT integration (first iterate)]
* -------------------------------------------------------------------
V4dg_status = 0
*
* Set over-riding switch for dynout and blocstat
* ----------------------------------------------
V4dg_output_L = .true.
*
* ----------------------
* Don't do gradient test
* ----------------------
if(.not.V4dg_grd_L) then
*
* Call 4D-Var simulator with gradient
* -----------------------------------
indic = 4
call v4d_simul
(indic,V4dc_ncv,V4dc_xcv,pj,V4dc_gcv)
*
* Computation of norm**2 of gradient
* ----------------------------------
call v4d_scalpro
(V4dc_ncv,V4dc_gcv,V4dc_gcv,gnorm_8)
*
if( Lun_out.gt.0 ) then
write(Lun_out, fmt='(''------------------------------'')')
write(Lun_out, fmt='(''COST FUNCTION :'',E14.8 )') pj
write(Lun_out, fmt='(''GRADIENT NORM :'',E14.8 )') sqrt(sngl(gnorm_8))
write(Lun_out, fmt='(''------------------------------'')')
endif
*
* ----------------
* Do gradient test
* ----------------
else
call v4d_testgrd
(V4dc_ncv,V4dc_xcv,V4dc_gcv,V4dc_wkmin,
% pj,V4dg_start,V4dg_range)
endif
*
* -------------------------
* QUASI NEWTON minimization
* -------------------------
*
* Set status of the integration (Integration associated to Minimization)
* ----------------------------------------------------------------------
V4dg_status = 999
*
* Set over-riding switch for dynout and blocstat
* ----------------------------------------------
V4dg_output_L = .false.
*
* Cancel write(Lun_out)
* ---------------------
wrt_out = Lun_out
Lun_out = -99
*
C V4dm_df1 = pj
V4dm_df1 = pj/4
*
call m1qn3 (v4d_simul0, v4d_scalpro0, v4d_ctonb, v4d_ctcab,
% V4dc_ncv, V4dc_xcv, pj, V4dc_gcv,
% V4dm_dxmin, V4dm_df1, V4dm_epsg, V4dm_impres, wrt_out,
% V4dm_mode, V4dm_itmax, V4dm_simax,
% iz, V4dc_wkmin, V4dc_nwkmin,
% izs,rzs,dzs_8,Ptopo_myproc,Ptopo_numproc)
*
* Reset write(Lun_out)
* --------------------
Lun_out = wrt_out
*
* ---------------------------------------
* STORE information needed for WARM START
* ---------------------------------------
iun_newguess = 0
iun_hotstart = 0
pnerr = fnom( iun_newguess, 'newguessn', 'FTN+SEQ+UNF' , 0)
pnerr = fnom( iun_hotstart, 'hotstartn', 'FTN+SEQ+UNF' , 0)
*
write(iun_newguess) (V4dc_xcv(n),n=1,V4dc_ncv),df1prev,pj,
% (V4dc_gcv(n),n=1,V4dc_ncv)
write(iun_hotstart) iz,V4dm_nsim
write(iun_hotstart) (V4dc_wkmin(n),n=1,V4dc_ncv)
*
call fclos(iun_newguess)
call fclos(iun_hotstart)
*
* ------------------------------------------------------
* Run CURRENT (last iterate) DIRECT and ADJ integrations
* ------------------------------------------------------
*
if( Lun_out.gt.0 ) then
write(Lun_out, fmt='(//''----------------------------------------------'')')
write(Lun_out, fmt='( ''Run CURRENT (LAST ITERATE) DIRECT and ADJ INT.'')')
write(Lun_out, fmt='( ''----------------------------------------------'')')
endif
*
* Set status of the integration [CURRENT integration (last iterate)]
* ------------------------------------------------------------------
V4dg_status = 4
*
* Set over-riding switch for dynout and blocstat
* ----------------------------------------------
V4dg_output_L = .true.
*
* ----------------------
* Don't do gradient test
* ----------------------
if(.not.V4dg_grd_L) then
*
* Call 4D-Var simulator with gradient
* -----------------------------------
indic = 4
call v4d_simul
(indic,V4dc_ncv,V4dc_xcv,pj,V4dc_gcv)
*
* Computation of norm**2 of gradient
* ----------------------------------
call v4d_scalpro
(V4dc_ncv,V4dc_gcv,V4dc_gcv,gnorm_8)
*
if( Lun_out.gt.0 ) then
write(Lun_out, fmt='(''------------------------------'')')
write(Lun_out, fmt='(''COST FUNCTION :'',E14.8 )') pj
write(Lun_out, fmt='(''GRADIENT NORM :'',E14.8 )') sqrt(sngl(gnorm_8))
write(Lun_out, fmt='(''------------------------------'')')
endif
*
* ----------------
* Do gradient test
* ----------------
else
call v4d_testgrd
(V4dc_ncv,V4dc_xcv,V4dc_gcv,V4dc_wkmin,
% pj,V4dg_start,V4dg_range)
endif
*
* ---------------------------------------------------------------
*
return
end