midas_extractBmatrixFor1Dvar sourceΒΆ
1program midas_extractBmatrixFor1Dvar 2 ! 3 !:Purpose: Main program to extract B matrix to binary file Bmatrix.bin suitable for 1Dvar applications 4 ! The B matrix is defined at a set of locations specified by the variable lonlatExtract and date 5 ! extractDate 6 ! 7 ! --- 8 ! 9 !:Algorithm: The B matrix is computed column by column by application of operators bmat_sqrtBT and bmat_sqrtB 10 ! 11 ! -- 12 ! 13 !:File I/O: The required input files and produced output files are listed as follows. 14 ! 15 !============================================== ============================================================== 16 ! Input and Output Files Description of file 17 !============================================== ============================================================== 18 ! ``flnml`` In - Main namelist file with parameters user may modify 19 ! ``flnml_static`` In - The "static" namelist that should not be modified 20 ! ``bgcov`` In - The B NMC matrix file 21 ! ``analysisgrid`` In - analysis grid 22 ! ``Bmatrix.bin`` Out - The Bmatrix binary file for 1DVar 23 !============================================== ============================================================== 24 ! 25 ! -- 26 ! 27 !:Synopsis: Below is a summary of the ``extractBmatrixFor1Dvar`` program calling sequence: 28 ! 29 ! - **Initial setups:** 30 ! 31 ! - Read parameters from the program namelist section NAMEXTRACT 32 ! 33 ! - Setup temporal grid 34 ! 35 ! - Get vertical and horizontal grid information from analysisgrid file 36 ! 37 ! - Allocate a gridStatevector object 38 ! 39 ! - Initialize the B matrix 40 ! 41 ! - Initialize the gridded variable transform module 42 ! 43 ! - **Computation:** 44 ! 45 ! - For each location specified in the namelist: 46 ! 47 ! - for each element of the stateVector 48 ! 49 ! - set this elemnt to one and the other to zero 50 ! 51 ! - apply bmat_sqrtBT 52 ! 53 ! - apply bmat_sqrtB 54 ! 55 ! - get the corresponding column of the B matrix 56 ! 57 ! - write the resulting B matrix to file 58 ! -- 59 !:Options: `List of namelist blocks <../namelists_in_each_program.html#extractbmatrixfor1dvar>`_ 60 ! that can affect the ``extractBmatrixFor1Dvar`` program. 61 ! 62 ! - The use of ``extractBmatrixFor1Dvar`` program is controlled by the namelist block 63 ! ``&namextract`` read by the ``extractBmatrixFor1Dvar`` program. 64 ! * ``extractdate`` date (YYYYMMDDHH format) for the B matrix extracted 65 ! * ``lonlatExtract`` (longitudes, latitudes) pairs definining the locations where the B matrix is to be extracted 66 ! * ``varNameExtract`` name of the variable to extract or ``all`` to extract everything in namstate 67 ! * ``stepBinExtract`` should be one of ``first``, ``middle`` or ``last`` to define when in the assimilation window the B matrix is valid 68 ! 69 use version_mod 70 use midasMpi_mod 71 use mathPhysConstants_mod 72 use controlVector_mod 73 use gridVariableTransforms_mod 74 use varNameList_mod 75 use gridStateVector_mod 76 use bMatrix_mod 77 use horizontalCoord_mod 78 use verticalCoord_mod 79 use timeCoord_mod 80 use utilities_mod 81 use ramDisk_mod 82 implicit none 83 84 type(struct_gsv) :: statevector 85 type(struct_hco), pointer :: hco_anl => null() 86 type(struct_hco), pointer :: hco_core => null() 87 type(struct_vco), pointer :: vco_anl => null() 88 real(4) :: factor1, factor2 89 real(8), pointer :: field4d(:,:,:,:) 90 real(8), allocatable :: controlVector(:) 91 integer, parameter :: nmaxLevs = 100 92 real(4) :: latitude, longitude 93 integer, external :: fclos, fnom, fstopc, newdate, get_max_rss 94 integer :: ierr 95 integer :: varIndex, nkgdim, levIndex1, lonIndex, latIndex, levIndex2 96 integer :: kIndex1, kIndex2, columnProcIdLocal, columnProcIdGlobal, nulmat, varCount 97 integer :: idate, itime, nulnam, dateStamp 98 integer :: stepBinExtractIndex 99 integer :: nLonLatPos, lonLatPosIndex 100 101 integer, parameter :: lonColumn = 1 102 integer, parameter :: latColumn = 2 103 104 character(len=10) :: datestr 105 character(len=4) :: varName1, varName2 106 character(len=4),allocatable :: varList(:) 107 real(8), allocatable :: Bmatrix(:,:) 108 109 ! namelist variables 110 integer :: extractdate ! date for the B matrix extracted 111 integer :: lonlatExtract(nmaxLevs,2) ! lon lat pairs definining the locations where the B matrix is to be extracted 112 character(len=128) :: stepBinExtract ! number of step bins to extract (1 typically for B NMC) 113 character(len=4) :: varNameExtract ! variable to extract (all to extract everything in namstate) 114 namelist /namextract/ extractdate, lonlatExtract, & 115 varNameExtract, stepBinExtract 116 117 call ver_printNameAndVersion('extractBmatrix', 'Extract 1Dvar B matrix') 118 119 ! MPI, tmg initialization 120 call mmpi_initialize 121 call tmg_init(mmpi_myid, 'TMG_INFO') 122 call utl_tmg_start(0, 'Main') 123 ierr = fstopc('MSGLVL', 'ERRORS', 0) 124 125 ! Set default values for namelist NAMEXTRACT parameters 126 extractdate = 2011020100 127 varNameExtract = 'all' 128 stepBinExtract = 'middle' 129 lonlatExtract(:,:) = -1 130 131 ! Read the parameters from NAMEXTRACT 132 nulnam = 0 133 ierr = fnom(nulnam, './flnml', 'FTN+SEQ+R/O', 0) 134 read(nulnam, nml=namextract, iostat=ierr) 135 if (ierr /= 0) call utl_abort('midas-extractBmatrix: Error reading namelist') 136 write(*, nml=namextract) 137 ierr = fclos(nulnam) 138 139 nLonLatPos = 0 140 do lonlatPosIndex = 1, size(lonlatExtract(:,lonColumn)) 141 if (lonlatExtract(lonlatPosIndex,lonColumn) >= 1 .and. lonlatExtract(lonlatPosIndex,latColumn) >= 1) nLonLatPos = nLonLatPos + 1 142 end do 143 144 if ( nLonLatPos == 0 ) then 145 call utl_abort('midas-extractBmatrix: You should specify at least one lonlat position !') 146 end if 147 148 ! Decompose extractdate(yyyymmddhh) into idate(YYYYMMDD) itime(HHMMSShh) 149 ! and calculate date-time stamp 150 idate = extractdate/100 151 itime = (extractdate-idate*100)*1000000 152 ierr = newdate(dateStamp, idate, itime, 3) 153 write(datestr,'(i10.10)') extractdate 154 write(*,*)' idate= ',idate,' time= ',itime 155 write(*,*)' date= ',extractdate,' stamp= ',dateStamp 156 157 ! Top Level Control setup 158 call ram_setup 159 !- Initialize the Temporal grid 160 call tim_setup 161 if (tim_getDateStamp() == 0) then 162 call tim_setDatestamp(dateStamp) 163 else 164 call utl_abort('midas-extractBmatrix: Code changes needed to use dateStamp from env variable') 165 end if 166 ! Initialize variables of the model states 167 call gsv_setup 168 ! Initialize the Analysis horizontal grid 169 call hco_SetupFromFile( hco_anl, './analysisgrid', 'ANALYSIS', 'Analysis' ) ! IN 170 if ( hco_anl % global ) then 171 hco_core => hco_anl 172 else 173 !- Iniatilized the core (Non-Extended) analysis grid 174 call hco_SetupFromFile( hco_core, './analysisgrid', 'COREGRID', 'AnalysisCore' ) ! IN 175 end if 176 write(*,*) 'Memory Used: ', get_max_rss()/1024, 'Mb' 177 178 ! Initialize the vertical coordinate from the statistics file 179 call vco_SetupFromFile( vco_anl, & ! OUT 180 './analysisgrid') ! IN 181 ! Allocate the statevector 182 call gsv_allocate(statevector, tim_nstepobsinc, hco_anl, vco_anl, & 183 datestamp_opt=tim_getDatestamp(), mpi_local_opt=.true., & 184 allocHeight_opt=.false., allocPressure_opt=.false.) 185 call gsv_zero(statevector) 186 nkgdim = statevector%nk 187 allocate( Bmatrix(nkgdim, nkgdim) ) 188 ! Setup the B matrix 189 call bmat_setup(hco_anl, hco_core, vco_anl) 190 !- Initialize the gridded variable transform module 191 call gvt_setup(hco_anl, hco_core, vco_anl) 192 call gvt_setupRefFromTrialFiles('HU') 193 write(*,*) 'Memory Used: ', get_max_rss()/1024, 'Mb' 194 195 ! 196 !============================================== 197 !- Compute columns of B matrix 198 !============================================== 199 ! 200 select case(trim(stepBinExtract)) 201 case ('first') 202 stepBinExtractIndex = 1 203 case ('middle') 204 if (mod(tim_nstepobsinc,2) == 0) then 205 write(*,*) 206 write(*,*) 'odd number of nstepobsinc a required for obs place in the middle of the analysis window ' 207 write(*,*) 'tim_nstepobsinc = ', tim_nstepobsinc 208 call utl_abort('midas-extractBmatrix') 209 end if 210 stepBinExtractIndex = (tim_nstepobsinc+1)/2 211 case ('last') 212 stepBinExtractIndex = tim_nstepobsinc 213 case default 214 write(*,*) 215 write(*,*) 'Unsupported stepBinExtract : ', trim(stepBinExtract) 216 call utl_abort('midas-extractBmatrix') 217 end select 218 219 allocate(controlVector(cvm_nvadim)) 220 221 write(*,*) '************************************************************' 222 write(*,*) 'midas-extractBmatrix: Compute columns of B matrix for 1Dvar' 223 write(*,*) '************************************************************' 224 write(*,*) 225 write(*,*) ' temporal location = ', trim(stepBinExtract), stepBinExtractIndex 226 write(*,*) ' number of lon-lat positions = ', nLonLatPos 227 228 if (mmpi_myId == 0) then 229 varCount = 0 230 do varIndex=1, vnl_numvarmax 231 if ( .not. gsv_varExist(varName=vnl_varNameList(varIndex)) ) cycle 232 if ( trim(varNameExtract) /= 'all' .and. (trim(varNameExtract) /= trim(vnl_varNameList(varIndex))) ) cycle 233 varCount = varCount + 1 234 end do 235 allocate(varList(varCount)) 236 varCount = 0 237 do varIndex=1, vnl_numvarmax 238 if ( .not. gsv_varExist(varName=vnl_varNameList(varIndex)) ) cycle 239 if ( trim(varNameExtract) /= 'all' .and. (trim(varNameExtract) /= trim(vnl_varNameList(varIndex))) ) cycle 240 varCount = varCount + 1 241 varList(varCount) = vnl_varNameList(varIndex) 242 end do 243 nulmat = 0 244 ierr = fnom(nulmat, './Bmatrix.bin', 'FTN+SEQ+UNF', 0) 245 write(nulmat) extractDate, vco_anl % nlev_T, vco_anl % nlev_M, vco_anl % Vcode, & 246 vco_anl % ip1_sfc, vco_anl % ip1_T_2m, vco_anl % ip1_M_10m, varCount, nkgdim, nLonLatPos 247 write(nulmat) vco_anl % ip1_T(:), vco_anl % ip1_M(:), varList(:) 248 end if 249 250 locationLoop:do lonLatPosIndex = 1, nLonLatPos 251 252 Bmatrix(:,:) = MPC_missingValue_R8 253 254 latIndex = lonlatExtract(lonLatPosIndex,latColumn) 255 lonIndex = lonlatExtract(lonLatPosIndex,lonColumn) 256 257 latitude = hco_anl%lat2d_4(lonIndex, latIndex) 258 longitude = hco_anl%lon2d_4(lonIndex, latIndex) 259 260 variableLoop1:do kIndex1 = 1, nkgdim 261 varName1 = gsv_getVarNameFromK(statevector, kIndex1) 262 if ( .not. gsv_varExist(varName=varName1) ) cycle 263 if ( trim(varNameExtract) /= 'all' .and. trim(varNameExtract) /= trim(varName1) ) cycle 264 265 write(*,*) 266 write(*,*) 'midas-extractBmatrix: simulating a pseudo-observation of ', trim(varName1) 267 268 factor1 = getConversionFactor( varName1 ) 269 levIndex1 = gsv_getLevFromK(statevector, kIndex1) 270 call gsv_zero(statevector) 271 call gsv_getField(statevector,field4d, varName1) 272 if ( latIndex >= statevector%myLatBeg .and. latIndex <= statevector%myLatEnd .and. & 273 lonIndex >= statevector%myLonBeg .and. lonIndex <= statevector%myLonEnd ) then 274 if (vnl_varLevelFromVarname(varName1) == 'SF') then 275 field4d(lonIndex, latIndex, 1, stepBinExtractIndex) = 1.0D0 276 else 277 field4d(lonIndex, latIndex, levIndex1, stepBinExtractIndex) = 1.0D0 278 end if 279 end if 280 !ici field4d est initialise a zero sauf au point qui nous interesse ou on a 1 281 !et donc aussi statevector (puisque field4V est un pointeur vers la partie correspondante de statevector) 282 controlVector(:) = 0.0d0 283 call bmat_sqrtBT(controlVector, cvm_nvadim, statevector) 284 call bmat_sqrtB (controlVector, cvm_nvadim, statevector) 285 ! ici statevector contient la colonne correspondante de la matrice B 286 write(*,*) 'midas-extractBmatrix: writing out the column of B. levIndex1,lonIndex,latIndex=', & 287 levIndex1,lonIndex,latIndex 288 289 variableLoop2:do kIndex2 = 1, nkgdim 290 varName2 = gsv_getVarNameFromK(statevector, kIndex2) 291 if ( .not. gsv_varExist(varName= varName2) ) cycle 292 if ( trim(varNameExtract) /= 'all' .and. trim(varNameExtract) /= trim(varName2) ) cycle 293 columnProcIdLocal = -1 294 if ( latIndex >= statevector % myLatBeg .and. latIndex <= statevector % myLatEnd .and. & 295 lonIndex >= statevector % myLonBeg .and. lonIndex <= statevector % myLonEnd ) then 296 columnProcIdLocal = mmpi_myId 297 call gsv_getField(statevector, field4d, varName2) 298 factor2 = getConversionFactor( varName2 ) 299 levIndex2 = gsv_getLevFromK(statevector, kIndex2) 300 bmatrix(kIndex2, kIndex1) = factor1 * factor2 * field4d(lonIndex, latIndex, levIndex2, stepBinExtractIndex) 301 end if 302 call rpn_comm_allreduce(columnProcIdLocal, columnProcIdGlobal, 1, "mpi_integer", "mpi_max", "GRID", ierr) 303 end do variableLoop2 304 305 end do variableLoop1 306 307 call RPN_COMM_bcast(Bmatrix, nkgdim * nkgdim, 'MPI_REAL8', columnProcIdGlobal, 'GRID', ierr ) 308 if (mmpi_myId ==0) then 309 write(nulmat) latitude, longitude, Bmatrix(:,:) 310 end if 311 312 end do locationLoop 313 314 ierr = fclos(nulmat) 315 316 deallocate(Bmatrix) 317 deallocate(controlVector) 318 319 write(*,*) 'Memory Used: ', get_max_rss()/1024, 'Mb' 320 321 call gsv_deallocate(statevector) 322 323 write(*,*) 'Memory Used: ', get_max_rss()/1024, 'Mb' 324 325 ! MPI, tmg finalize 326 call utl_tmg_stop(0) 327 call tmg_terminate(mmpi_myid, 'TMG_INFO') 328 call rpn_comm_finalize(ierr) 329 330 write(*,*) ' --------------------------------' 331 write(*,*) ' midas-extractBmatrix ENDS' 332 write(*,*) ' --------------------------------' 333 334contains 335 336 real(4) function getConversionFactor(varName) 337 character(len=*), intent(in) :: varName 338 if ( trim(varName) == 'UU' .or. trim(varName) == 'VV') then 339 getConversionFactor = mpc_knots_per_m_per_s_r4 ! m/s -> knots 340 else if ( trim(varName) == 'P0' ) then 341 getConversionFactor = 0.01 ! Pa -> hPa 342 else 343 getConversionFactor = 1.0 ! no conversion 344 end if 345 end function getConversionFactor 346 347end program midas_extractBmatrixFor1Dvar