- Timestamp:
- 2017-03-09T13:52:43+01:00 (7 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
branches/UKMO/dev_r5785_SSS_obsoper/NEMOGCM/NEMO/OPA_SRC/OBS/obs_oper.F90
- Property svn:keywords deleted
r5704 r7773 49 49 !!---------------------------------------------------------------------- 50 50 51 !! * Substitutions 52 # include "domzgr_substitute.h90" 51 53 CONTAINS 52 54 53 55 SUBROUTINE obs_prof_opt( prodatqc, kt, kpi, kpj, kpk, & 54 56 & kit000, kdaystp, & 55 & pvar1, pvar2, pgdept, pmask1, pmask2, & 57 & pvar1, pvar2, pgdept, pgdepw, 58 & pmask1, pmask2, & 56 59 & plam1, plam2, pphi1, pphi2, & 57 60 & k1dint, k2dint, kdailyavtypes ) … … 104 107 !! ! 07-03 (K. Mogensen) General handling of profiles 105 108 !! ! 15-02 (M. Martin) Combined routine for all profile types 109 !! ! 17-02 (M. Martin) Include generalised vertical coordinate changes 106 110 !!----------------------------------------------------------------------- 107 111 … … 133 137 & pphi1, & ! Model latitudes for variable 1 134 138 & pphi2 ! Model latitudes for variable 2 135 REAL(KIND=wp), INTENT(IN), DIMENSION(kpk) :: & 136 & pgdept ! Model array of depth levels 139 REAL(KIND=wp), INTENT(IN), DIMENSION(kpi,kpj,kpk) :: & 140 & pgdept, & ! Model array of depth T levels 141 & pgdepw ! Model array of depth W levels 137 142 INTEGER, DIMENSION(imaxavtypes), OPTIONAL :: & 138 143 & kdailyavtypes ! Types for daily averages … … 164 169 & zobsk, & 165 170 & zobs2k 166 REAL(KIND=wp), DIMENSION(2,2, kpk) :: &171 REAL(KIND=wp), DIMENSION(2,2,1) :: & 167 172 & zweig1, & 168 & zweig2 173 & zweig2, & 174 & zweig 169 175 REAL(wp), DIMENSION(:,:,:,:), ALLOCATABLE :: & 170 176 & zmask1, & 171 177 & zmask2, & 172 & zint1, & 173 & zint2, & 174 & zinm1, & 175 & zinm2 178 & zint1, & 179 & zint2, & 180 & zinm1, & 181 & zinm2, & 182 & zgdept, & 183 & zgdepw 176 184 REAL(wp), DIMENSION(:,:,:), ALLOCATABLE :: & 177 185 & zglam1, & … … 179 187 & zgphi1, & 180 188 & zgphi2 189 REAL(KIND=wp), DIMENSION(1) :: zmsk_1, zmsk_2 190 REAL(KIND=wp), DIMENSION(:,:,:), ALLOCATABLE :: interp_corner 191 181 192 LOGICAL :: ld_dailyav 182 193 … … 259 270 & zmask1(2,2,kpk,ipro), & 260 271 & zmask2(2,2,kpk,ipro), & 261 & zint1(2,2,kpk,ipro), & 262 & zint2(2,2,kpk,ipro) & 272 & zint1(2,2,kpk,ipro), & 273 & zint2(2,2,kpk,ipro), & 274 & zgdept(2,2,kpk,ipro), & 275 & zgdepw(2,2,kpk,ipro) & 263 276 & ) 264 277 … … 283 296 END DO 284 297 298 ! Initialise depth arrays 299 zgdept(:,:,:,:) = 0.0 300 zgdepw(:,:,:,:) = 0.0 301 285 302 CALL obs_int_comm_2d( 2, 2, ipro, kpi, kpj, igrdi1, igrdj1, plam1, zglam1 ) 286 303 CALL obs_int_comm_2d( 2, 2, ipro, kpi, kpj, igrdi1, igrdj1, pphi1, zgphi1 ) … … 293 310 CALL obs_int_comm_3d( 2, 2, ipro, kpi, kpj, kpk, igrdi2, igrdj2, pvar2, zint2 ) 294 311 312 CALL obs_int_comm_3d( 2, 2, ipro, kpi, kpj, kpk, igrdi1, igrdj1, pgdept, zgdept ) 313 CALL obs_int_comm_3d( 2, 2, ipro, kpi, kpj, kpk, igrdi1, igrdj1, pgdepw, zgdepw ) 314 295 315 ! At the end of the day also get interpolated means 296 316 IF ( ld_dailyav .AND. idayend == 0 ) THEN … … 307 327 308 328 ENDIF 329 330 ! Return if no observations to process 331 ! Has to be done after comm commands to ensure processors 332 ! stay in sync 333 IF ( ipro == 0 ) RETURN 309 334 310 335 DO jobs = prodatqc%nprofup + 1, prodatqc%nprofup + ipro … … 332 357 zphi = prodatqc%rphi(jobs) 333 358 334 ! Horizontal weights and vertical mask335 359 ! Horizontal weights 360 ! Masked values are calculated later. 336 361 IF ( prodatqc%npvend(jobs,1) > 0 ) THEN 337 362 338 CALL obs_int_h2d_init( kpk, kpk, k2dint, zlam, zphi, &363 CALL obs_int_h2d_init( 1, 1, k2dint, zlam, zphi, & 339 364 & zglam1(:,:,iobs), zgphi1(:,:,iobs), & 340 & zmask1(:,:, :,iobs), zweig1, zobsmask1 )365 & zmask1(:,:,1,iobs), zweig1, zmsk_1 ) 341 366 342 367 ENDIF … … 344 369 IF ( prodatqc%npvend(jobs,2) > 0 ) THEN 345 370 346 CALL obs_int_h2d_init( kpk, kpk, k2dint, zlam, zphi, &371 CALL obs_int_h2d_init( 1, 1, k2dint, zlam, zphi, & 347 372 & zglam2(:,:,iobs), zgphi2(:,:,iobs), & 348 & zmask2(:,:, :,iobs), zweig2, zobsmask2 )373 & zmask2(:,:,1,iobs), zweig2, zmsk_2 ) 349 374 350 375 ENDIF … … 358 383 IF ( idayend == 0 ) THEN 359 384 ! Daily averaged data 360 CALL obs_int_h2d( kpk, kpk, & 361 & zweig1, zinm1(:,:,:,iobs), zobsk ) 362 363 ENDIF 364 365 ELSE 366 367 ! Point data 368 CALL obs_int_h2d( kpk, kpk, & 369 & zweig1, zint1(:,:,:,iobs), zobsk ) 370 371 ENDIF 372 373 !------------------------------------------------------------- 374 ! Compute vertical second-derivative of the interpolating 375 ! polynomial at obs points 376 !------------------------------------------------------------- 377 378 IF ( k1dint == 1 ) THEN 379 CALL obs_int_z1d_spl( kpk, zobsk, zobs2k, & 380 & pgdept, zobsmask1 ) 381 ENDIF 382 383 !----------------------------------------------------------------- 384 ! Vertical interpolation to the observation point 385 !----------------------------------------------------------------- 386 ista = prodatqc%npvsta(jobs,1) 387 iend = prodatqc%npvend(jobs,1) 388 CALL obs_int_z1d( kpk, & 389 & prodatqc%var(1)%mvk(ista:iend), & 390 & k1dint, iend - ista + 1, & 391 & prodatqc%var(1)%vdep(ista:iend), & 392 & zobsk, zobs2k, & 393 & prodatqc%var(1)%vmod(ista:iend), & 394 & pgdept, zobsmask1 ) 395 396 ENDIF 397 385 386 ! vertically interpolate all 4 corners 387 ista = prodatqc%npvsta(jobs,1) 388 iend = prodatqc%npvend(jobs,1) 389 inum_obs = iend - ista + 1 390 ALLOCATE(interp_corner(2,2,inum_obs),iv_indic(inum_obs)) 391 392 DO iin=1,2 393 DO ijn=1,2 394 395 IF ( k1dint == 1 ) THEN 396 CALL obs_int_z1d_spl( kpk, & 397 & zinm1(iin,ijn,:,iobs), & 398 & zobs2k, zgdept(iin,ijn,:,iobs), & 399 & zmask1(iin,ijn,:,iobs)) 400 ENDIF 401 402 CALL obs_level_search(kpk, & 403 & zgdept(iin,ijn,:,iobs), & 404 & inum_obs, prodatqc%var(1)%vdep(ista:iend), & 405 & iv_indic) 406 407 CALL obs_int_z1d(kpk, iv_indic, k1dint, inum_obs, & 408 & prodatqc%var(1)%vdep(ista:iend), & 409 & zinm1(iin,ijn,:,iobs), & 410 & zobs2k, interp_corner(iin,ijn,:), & 411 & zgdept(iin,ijn,:,iobs), & 412 & zmask1(iin,ijn,:,iobs)) 413 414 ENDDO 415 ENDDO 416 417 ENDIF !idayend 418 419 ELSE 420 421 ! Point data 422 423 ! vertically interpolate all 4 corners 424 ista = prodatqc%npvsta(jobs,1) 425 iend = prodatqc%npvend(jobs,1) 426 inum_obs = iend - ista + 1 427 ALLOCATE(interp_corner(2,2,inum_obs), iv_indic(inum_obs)) 428 DO iin=1,2 429 DO ijn=1,2 430 431 IF ( k1dint == 1 ) THEN 432 CALL obs_int_z1d_spl( kpk, & 433 & zint1(iin,ijn,:,iobs),& 434 & zobs2k, zgdept(iin,ijn,:,iobs), & 435 & zmask1(iin,ijn,:,iobs)) 436 437 ENDIF 438 439 CALL obs_level_search(kpk, & 440 & zgdept(iin,ijn,:,iobs),& 441 & inum_obs, prodatqc%var(1)%vdep(ista:iend), & 442 & iv_indic) 443 444 CALL obs_int_z1d(kpk, iv_indic, k1dint, inum_obs, & 445 & prodatqc%var(1)%vdep(ista:iend), & 446 & zint1(iin,ijn,:,iobs), & 447 & zobs2k,interp_corner(iin,ijn,:), & 448 & zgdept(iin,ijn,:,iobs), & 449 & zmask1(iin,ijn,:,iobs) ) 450 451 ENDDO 452 ENDDO 453 454 ENDIF 455 456 !------------------------------------------------------------- 457 ! Compute the horizontal interpolation for every profile level 458 !------------------------------------------------------------- 459 460 DO ikn=1,inum_obs 461 iend=ista+ikn-1 462 463 zweig(:,:,1) = 0._wp 464 465 ! This code forces the horizontal weights to be 466 ! zero IF the observation is below the bottom of the 467 ! corners of the interpolation nodes, Or if it is in 468 ! the mask. This is important for observations near 469 ! steep bathymetry 470 DO iin=1,2 471 DO ijn=1,2 472 473 depth_loop1: DO ik=kpk,2,-1 474 IF(zmask1(iin,ijn,ik-1,iobs ) > 0.9 )THEN 475 476 zweig(iin,ijn,1) = & 477 & zweig1(iin,ijn,1) * & 478 & MAX( SIGN(1._wp,(zgdepw(iin,ijn,ik,iobs) ) & 479 & - prodatqc%var(1)%vdep(iend)),0._wp) 480 481 EXIT depth_loop1 482 483 ENDIF 484 485 ENDDO depth_loop1 486 487 ENDDO 488 ENDDO 489 490 CALL obs_int_h2d( 1, 1, zweig, interp_corner(:,:,ikn), & 491 & prodatqc%var(1)%vmod(iend:iend) ) 492 493 ! Set QC flag for any observations found below the bottom 494 ! needed as the check here is more strict than that in obs_prep 495 IF (sum(zweig) == 0.0_wp) prodatqc%var(1)%nvqc(iend:iend)=4 496 497 ENDDO 498 499 DEALLOCATE(interp_corner,iv_indic) 500 501 ENDIF 502 503 ! For the second variable 398 504 IF ( prodatqc%npvend(jobs,2) > 0 ) THEN 399 505 … … 403 509 404 510 IF ( idayend == 0 ) THEN 405 406 511 ! Daily averaged data 407 CALL obs_int_h2d( kpk, kpk, & 408 & zweig2, zinm2(:,:,:,iobs), zobsk ) 409 410 ENDIF 411 412 ELSE 413 414 ! Point data 415 CALL obs_int_h2d( kpk, kpk, & 416 & zweig2, zint2(:,:,:,iobs), zobsk ) 417 418 ENDIF 419 420 421 !------------------------------------------------------------- 422 ! Compute vertical second-derivative of the interpolating 423 ! polynomial at obs points 424 !------------------------------------------------------------- 425 426 IF ( k1dint == 1 ) THEN 427 CALL obs_int_z1d_spl( kpk, zobsk, zobs2k, & 428 & pgdept, zobsmask2 ) 429 ENDIF 430 431 !---------------------------------------------------------------- 432 ! Vertical interpolation to the observation point 433 !---------------------------------------------------------------- 434 ista = prodatqc%npvsta(jobs,2) 435 iend = prodatqc%npvend(jobs,2) 436 CALL obs_int_z1d( kpk, & 437 & prodatqc%var(2)%mvk(ista:iend),& 438 & k1dint, iend - ista + 1, & 439 & prodatqc%var(2)%vdep(ista:iend),& 440 & zobsk, zobs2k, & 441 & prodatqc%var(2)%vmod(ista:iend),& 442 & pgdept, zobsmask2 ) 443 444 ENDIF 445 446 END DO 512 513 ! vertically interpolate all 4 corners 514 ista = prodatqc%npvsta(jobs,2) 515 iend = prodatqc%npvend(jobs,2) 516 inum_obs = iend - ista + 1 517 ALLOCATE(interp_corner(2,2,inum_obs),iv_indic(inum_obs)) 518 519 DO iin=1,2 520 DO ijn=1,2 521 522 IF ( k1dint == 1 ) THEN 523 CALL obs_int_z1d_spl( kpk, & 524 & zinm2(iin,ijn,:,iobs), & 525 & zobs2k, zgdept(iin,ijn,:,iobs), & 526 & zmask2(iin,ijn,:,iobs)) 527 ENDIF 528 529 CALL obs_level_search(kpk, & 530 & zgdept(iin,ijn,:,iobs), & 531 & inum_obs, prodatqc%var(2)%vdep(ista:iend), & 532 & iv_indic) 533 534 CALL obs_int_z1d(kpk, iv_indic, k1dint, inum_obs, & 535 & prodatqc%var(2)%vdep(ista:iend), & 536 & zinm2(iin,ijn,:,iobs), & 537 & zobs2k, interp_corner(iin,ijn,:), & 538 & zgdept(iin,ijn,:,iobs), & 539 & zmask2(iin,ijn,:,iobs)) 540 541 ENDDO 542 ENDDO 543 544 ENDIF !idayend 545 546 ELSE 547 548 ! Point data 549 550 ! vertically interpolate all 4 corners 551 ista = prodatqc%npvsta(jobs,2) 552 iend = prodatqc%npvend(jobs,2) 553 inum_obs = iend - ista + 1 554 ALLOCATE(interp_corner(2,2,inum_obs), iv_indic(inum_obs)) 555 DO iin=1,2 556 DO ijn=1,2 557 558 IF ( k1dint == 1 ) THEN 559 CALL obs_int_z1d_spl( kpk, & 560 & zint2(iin,ijn,:,iobs),& 561 & zobs2k, zgdept(iin,ijn,:,iobs), & 562 & zmask2(iin,ijn,:,iobs)) 563 564 ENDIF 565 566 CALL obs_level_search(kpk, & 567 & zgdept(iin,ijn,:,iobs),& 568 & inum_obs, prodatqc%var(2)%vdep(ista:iend), & 569 & iv_indic) 570 571 CALL obs_int_z1d(kpk, iv_indic, k1dint, inum_obs, & 572 & prodatqc%var(2)%vdep(ista:iend), & 573 & zint2(iin,ijn,:,iobs), & 574 & zobs2k,interp_corner(iin,ijn,:), & 575 & zgdept(iin,ijn,:,iobs), & 576 & zmask2(iin,ijn,:,iobs) ) 577 578 ENDDO 579 ENDDO 580 581 ENDIF 582 583 !------------------------------------------------------------- 584 ! Compute the horizontal interpolation for every profile level 585 !------------------------------------------------------------- 586 587 DO ikn=1,inum_obs 588 iend=ista+ikn-1 589 590 zweig(:,:,1) = 0._wp 591 592 ! This code forces the horizontal weights to be 593 ! zero IF the observation is below the bottom of the 594 ! corners of the interpolation nodes, Or if it is in 595 ! the mask. This is important for observations near 596 ! steep bathymetry 597 DO iin=1,2 598 DO ijn=1,2 599 600 depth_loop2: DO ik=kpk,2,-1 601 IF(zmask2(iin,ijn,ik-1,iobs ) > 0.9 )THEN 602 603 zweig(iin,ijn,1) = & 604 & zweig2(iin,ijn,1) * & 605 & MAX( SIGN(1._wp,(zgdepw(iin,ijn,ik,iobs) ) & 606 & - prodatqc%var(2)%vdep(iend)),0._wp) 607 608 EXIT depth_loop2 609 610 ENDIF 611 612 ENDDO depth_loop2 613 614 ENDDO 615 ENDDO 616 617 CALL obs_int_h2d( 1, 1, zweig, interp_corner(:,:,ikn), & 618 & prodatqc%var(2)%vmod(iend:iend) ) 619 620 ! Set QC flag for any observations found below the bottom 621 ! needed as the check here is more strict than that in obs_prep 622 IF (sum(zweig) == 0.0_wp) prodatqc%var(2)%nvqc(iend:iend)=4 623 624 ENDDO 625 626 DEALLOCATE(interp_corner,iv_indic) 627 628 ENDIF 447 629 448 630 ! Deallocate the data for interpolation … … 459 641 & zmask2, & 460 642 & zint1, & 461 & zint2 & 643 & zint2, & 644 & zgdept, & 645 & zgdepw & 462 646 & ) 463 647
Note: See TracChangeset
for help on using the changeset viewer.