00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057
00058
00059
00060
00061
00062
00063
00064
00065
00066
00067
00068
00069
00070
00071
00072
00073
00074 module shr_map_mod
00075
00076
00077
00078 use shr_const_mod
00079 use shr_kind_mod
00080 use shr_sys_mod
00081 use shr_timer_mod
00082 use shr_log_mod, only: s_loglev => shr_log_Level
00083 use shr_log_mod, only: s_logunit => shr_log_Unit
00084
00085 implicit none
00086 private
00087
00088
00089
00090 public :: shr_map_maptype
00091
00092 type shr_map_mapType
00093 private
00094 character(SHR_KIND_CS) :: name
00095 character(SHR_KIND_CS) :: type
00096 character(SHR_KIND_CS) :: algo
00097 character(SHR_KIND_CS) :: mask
00098 character(SHR_KIND_CS) :: vect
00099 integer(SHR_KIND_IN) :: nsrc
00100 integer(SHR_KIND_IN) :: ndst
00101 integer(SHR_KIND_IN) :: nwts
00102 real(SHR_KIND_R8) ,pointer :: xsrc(:)
00103 real(SHR_KIND_R8) ,pointer :: ysrc(:)
00104 real(SHR_KIND_R8) ,pointer :: xdst(:)
00105 real(SHR_KIND_R8) ,pointer :: ydst(:)
00106 real(SHR_KIND_R8) ,pointer :: wgts(:)
00107 integer(SHR_KIND_IN),pointer :: isrc(:)
00108 integer(SHR_KIND_IN),pointer :: idst(:)
00109 character(SHR_KIND_CS) :: fill
00110 character(SHR_KIND_CS) :: init
00111 end type shr_map_mapType
00112
00113
00114
00115 public :: shr_map_checkInit
00116 public :: shr_map_checkFilled
00117 public :: shr_map_put
00118 public :: shr_map_get
00119 public :: shr_map_mapSet
00120 public :: shr_map_mapData
00121 public :: shr_map_listValidOpts
00122 public :: shr_map_print
00123 public :: shr_map_clean
00124 public :: shr_map_setAbort
00125 public :: shr_map_setDebug
00126 public :: shr_map_setDopole
00127
00128
00129
00130
00131 character(SHR_KIND_CS),public,parameter :: shr_map_fs_name = 'name'
00132 character(SHR_KIND_CS),public,parameter :: shr_map_fs_type = 'type'
00133 character(SHR_KIND_CS),public,parameter :: shr_map_fs_algo = 'algo'
00134 character(SHR_KIND_CS),public,parameter :: shr_map_fs_mask = 'mask'
00135 character(SHR_KIND_CS),public,parameter :: shr_map_fs_vect = 'vect'
00136 character(SHR_KIND_CS),public,parameter :: shr_map_fs_nwts = 'nwts'
00137 character(SHR_KIND_CS),public,parameter :: shr_map_fs_nsrc = 'nsrc'
00138 character(SHR_KIND_CS),public,parameter :: shr_map_fs_ndst = 'ndst'
00139
00140
00141 character(len=*),public,parameter :: shr_map_fs_fill = 'fill '
00142 character(len=*),public,parameter :: shr_map_fs_cfill = 'cfill '
00143 character(len=*),public,parameter :: shr_map_fs_remap = 'remap '
00144
00145
00146 character(len=*),public,parameter :: shr_map_fs_copy = 'copy '
00147 character(len=*),public,parameter :: shr_map_fs_bilinear = 'bilinear'
00148 character(len=*),public,parameter :: shr_map_fs_nn = 'nn '
00149 character(len=*),public,parameter :: shr_map_fs_nnoni = 'nnoni '
00150 character(len=*),public,parameter :: shr_map_fs_nnonj = 'nnonj '
00151 character(len=*),public,parameter :: shr_map_fs_spval = 'spval '
00152
00153
00154 character(len=*),public,parameter :: shr_map_fs_srcmask = 'srcmask '
00155 character(len=*),public,parameter :: shr_map_fs_dstmask = 'dstmask '
00156 character(len=*),public,parameter :: shr_map_fs_nomask = 'nomask '
00157 character(len=*),public,parameter :: shr_map_fs_bothmask = 'bothmask'
00158
00159
00160 character(len=*),public,parameter :: shr_map_fs_scalar = 'scalar '
00161 character(len=*),public,parameter :: shr_map_fs_vector = 'vector '
00162
00163
00164 character(SHR_KIND_CS),public,parameter :: shr_map_setTru = 'TRUE map'
00165 character(SHR_KIND_CS),public,parameter :: shr_map_setFal = 'FALSE m '
00166 integer(SHR_KIND_IN) ,public,parameter :: shr_map_ispval = -99
00167 real(SHR_KIND_R8) ,public,parameter :: shr_map_spval = shr_const_spval
00168
00169
00170
00171
00172 integer(SHR_KIND_IN),public,parameter :: shr_map_fs_ntype = 3
00173 character(len=*),public,parameter ::
00174 shr_map_fs_types(shr_map_fs_ntype) = (/shr_map_fs_fill,
00175 shr_map_fs_cfill,
00176 shr_map_fs_remap /)
00177
00178 integer(SHR_KIND_IN),public,parameter :: shr_map_fs_nalgo = 6
00179 character(len=*),public,parameter ::
00180 shr_map_fs_algos(shr_map_fs_nalgo) = (/shr_map_fs_copy,
00181 shr_map_fs_bilinear,
00182 shr_map_fs_nn,
00183 shr_map_fs_nnoni,
00184 shr_map_fs_nnonj,
00185 shr_map_fs_spval /)
00186
00187 integer(SHR_KIND_IN),public,parameter :: shr_map_fs_nmask = 4
00188 character(len=*),public,parameter ::
00189 shr_map_fs_masks(shr_map_fs_nmask) = (/shr_map_fs_srcmask,
00190 shr_map_fs_dstmask,
00191 shr_map_fs_nomask ,
00192 shr_map_fs_bothmask /)
00193
00194 integer(SHR_KIND_IN),public,parameter :: shr_map_fs_nvect = 2
00195 character(len=*),public,parameter ::
00196 shr_map_fs_vects(shr_map_fs_nvect) = (/shr_map_fs_scalar,
00197 shr_map_fs_vector /)
00198
00199 interface shr_map_put ; module procedure &
00200 shr_map_putCS, &
00201 shr_map_putR8, &
00202 shr_map_putIN
00203 end interface
00204
00205 interface shr_map_get ; module procedure &
00206 shr_map_getCS, &
00207 shr_map_getR8, &
00208 shr_map_getIN, &
00209 shr_map_getAR
00210 end interface
00211
00212 interface shr_map_mapSet ; module procedure &
00213 shr_map_mapSet_global, &
00214 shr_map_mapSet_dest
00215 end interface
00216
00217 interface shr_map_mapData ; module procedure &
00218 shr_map_mapDatam, &
00219 shr_map_mapDatanm
00220 end interface
00221
00222 logical,save :: doabort = .true.
00223 logical,save :: dopole = .true.
00224 integer(SHR_KIND_IN),save :: debug = 0
00225 character(SHR_KIND_CS),parameter :: fillstring = 'mapisfilled'
00226 character(SHR_KIND_CS),parameter :: inispval = 'spval'
00227 character(SHR_KIND_CS),parameter :: initcopy = 'copy'
00228 real(SHR_KIND_R8) ,parameter :: c0 = 0._SHR_KIND_R8
00229 real(SHR_KIND_R8) ,parameter :: c1 = 1._SHR_KIND_R8
00230 real(SHR_KIND_R8) ,parameter :: c2 = 2._SHR_KIND_R8
00231 real(SHR_KIND_R8) ,parameter :: eps = 1.0e-12_SHR_KIND_R8
00232 real(SHR_KIND_R8) ,parameter :: pi = shr_const_pi
00233
00234
00235 contains
00236
00237
00238
00239
00240
00241
00242
00243
00244
00245
00246
00247
00248
00249
00250
00251
00252 logical function shr_map_checkInit(map)
00253
00254 implicit none
00255
00256
00257
00258 type(shr_map_mapType),intent(in) :: map
00259
00260
00261
00262
00263
00264
00265 character(*),parameter :: subName = "('shr_map_checkInit') "
00266
00267
00268
00269 if (shr_map_checkFldStrOpt(shr_map_fs_type,map%type) .and. &
00270 shr_map_checkFldStrOpt(shr_map_fs_algo,map%algo) .and. &
00271 shr_map_checkFldStrOpt(shr_map_fs_mask,map%mask)) then
00272 shr_map_checkInit = .true.
00273 else
00274 shr_map_checkInit = .false.
00275 endif
00276
00277 end function shr_map_checkInit
00278
00279
00280
00281
00282
00283
00284
00285
00286
00287
00288
00289
00290
00291
00292
00293
00294
00295
00296
00297 logical function shr_map_checkFilled(map)
00298
00299 implicit none
00300
00301
00302
00303 type(shr_map_mapType),intent(in) :: map
00304
00305
00306
00307
00308 integer(SHR_KIND_IN) :: nwts
00309
00310
00311 character(*),parameter :: subName = "('shr_map_checkFilled') "
00312
00313
00314
00315 shr_map_checkFilled = .false.
00316
00317 nwts = map%nwts
00318 if (map%fill == fillstring .and. nwts >= 0) then
00319 if (size(map%wgts) == nwts .and. size(map%isrc) == nwts &
00320 .and. size(map%idst) == nwts ) then
00321 shr_map_checkFilled = .true.
00322 endif
00323 endif
00324
00325 end function shr_map_checkFilled
00326
00327
00328
00329
00330
00331
00332
00333
00334
00335
00336
00337
00338
00339
00340
00341
00342 logical function shr_map_checkFldStr(fldStr)
00343
00344 implicit none
00345
00346
00347
00348 character(*) :: fldStr
00349
00350
00351
00352
00353
00354
00355 character(*),parameter :: subName = "('shr_map_checkFldStr') "
00356
00357
00358
00359 shr_map_checkFldStr = .false.
00360
00361 if (trim(fldStr) == trim(shr_map_fs_type).or. &
00362 trim(fldStr) == trim(shr_map_fs_name).or. &
00363 trim(fldStr) == trim(shr_map_fs_algo).or. &
00364 trim(fldStr) == trim(shr_map_fs_mask).or. &
00365 trim(fldStr) == trim(shr_map_fs_vect).or. &
00366 trim(fldStr) == trim(shr_map_fs_nsrc).or. &
00367 trim(fldStr) == trim(shr_map_fs_ndst).or. &
00368 trim(fldStr) == trim(shr_map_fs_nwts)) then
00369 shr_map_checkFldStr = .true.
00370 endif
00371
00372 end function shr_map_checkFldStr
00373
00374
00375
00376
00377
00378
00379
00380
00381
00382
00383
00384
00385
00386
00387
00388
00389
00390 logical function shr_map_checkFldStrOpt(fldStr,cval)
00391
00392 implicit none
00393
00394
00395
00396 character(*),intent(in) :: fldStr
00397 character(*),intent(in) :: cval
00398
00399
00400
00401
00402 integer(SHR_KIND_IN) :: n
00403
00404
00405 character(*),parameter :: subName = "('shr_map_checkFldStrOpt') "
00406
00407
00408
00409 shr_map_checkFldStrOpt = .false.
00410
00411 if (.not.shr_map_checkFldStr(fldStr)) return
00412
00413 if (trim(fldStr) == trim(shr_map_fs_name)) then
00414 shr_map_checkFldStrOpt = .true.
00415 elseif (trim(fldStr) == trim(shr_map_fs_type)) then
00416 do n = 1,shr_map_fs_ntype
00417 if (trim(cval) == trim(shr_map_fs_types(n))) shr_map_checkFldStrOpt = .true.
00418 enddo
00419 elseif (trim(fldStr) == trim(shr_map_fs_algo)) then
00420 do n = 1,shr_map_fs_nalgo
00421 if (trim(cval) == trim(shr_map_fs_algos(n))) shr_map_checkFldStrOpt = .true.
00422 enddo
00423 elseif (trim(fldStr) == trim(shr_map_fs_mask)) then
00424 do n = 1,shr_map_fs_nmask
00425 if (trim(cval) == trim(shr_map_fs_masks(n))) shr_map_checkFldStrOpt = .true.
00426 enddo
00427 elseif (trim(fldStr) == trim(shr_map_fs_vect)) then
00428 do n = 1,shr_map_fs_nvect
00429 if (trim(cval) == trim(shr_map_fs_vects(n))) shr_map_checkFldStrOpt = .true.
00430 enddo
00431 endif
00432
00433 end function shr_map_checkFldStrOpt
00434
00435
00436
00437
00438
00439
00440
00441
00442
00443
00444
00445
00446
00447
00448
00449
00450
00451 subroutine shr_map_getCS(map,fldStr,cval)
00452
00453 implicit none
00454
00455
00456
00457 type(shr_map_mapType) ,intent(in) :: map
00458 character(*) ,intent(in) :: fldStr
00459 character(*) ,intent(out):: cval
00460
00461
00462
00463
00464
00465
00466 character(*),parameter :: subName = "('shr_map_getCS') "
00467
00468
00469
00470 cval = shr_map_setFal
00471 if (.not.shr_map_checkFldStr(fldStr)) then
00472 call shr_map_abort(subName//' ERROR illegal fldStr '//trim(fldStr))
00473 return
00474 endif
00475
00476 if (trim(fldStr) == trim(shr_map_fs_name)) then
00477 cval = map%name
00478 elseif (trim(fldStr) == trim(shr_map_fs_type)) then
00479 cval = map%type
00480 elseif (trim(fldStr) == trim(shr_map_fs_algo)) then
00481 cval = map%algo
00482 elseif (trim(fldStr) == trim(shr_map_fs_mask)) then
00483 cval = map%mask
00484 elseif (trim(fldStr) == trim(shr_map_fs_vect)) then
00485 cval = map%vect
00486 else
00487 call shr_map_abort(subName//' ERROR illegal fldStr '//trim(fldStr))
00488 endif
00489
00490 end subroutine shr_map_getCS
00491
00492
00493
00494
00495
00496
00497
00498
00499
00500
00501
00502
00503
00504
00505
00506
00507
00508 subroutine shr_map_getIN(map,fldStr,ival)
00509
00510 implicit none
00511
00512
00513
00514 type(shr_map_mapType) ,intent(in) :: map
00515 character(*) ,intent(in) :: fldStr
00516 integer(SHR_KIND_IN) ,intent(out):: ival
00517
00518
00519
00520
00521
00522
00523 character(*),parameter :: subName = "('shr_map_getIN') "
00524
00525
00526
00527 ival = shr_map_ispval
00528 if (.not.shr_map_checkFldStr(fldStr)) then
00529 call shr_map_abort(subName//' ERROR illegal fldStr '//trim(fldStr))
00530 return
00531 endif
00532
00533 if (trim(fldStr) == trim(shr_map_fs_nwts)) then
00534 ival = map%nwts
00535 elseif (trim(fldStr) == trim(shr_map_fs_nsrc)) then
00536 ival = map%nsrc
00537 elseif (trim(fldStr) == trim(shr_map_fs_ndst)) then
00538 ival = map%ndst
00539 else
00540 call shr_map_abort(subName//' ERROR illegal fldStr '//trim(fldStr))
00541 endif
00542
00543 end subroutine shr_map_getIN
00544
00545
00546
00547
00548
00549
00550
00551
00552
00553
00554
00555
00556
00557
00558
00559 subroutine shr_map_getR8(map,fldStr,rval)
00560
00561 implicit none
00562
00563
00564
00565 type(shr_map_mapType) ,intent(in) :: map
00566 character(*) ,intent(in) :: fldStr
00567 real(SHR_KIND_R8) ,intent(out):: rval
00568
00569
00570
00571
00572
00573
00574 character(*),parameter :: subName = "('shr_map_getR8') "
00575
00576
00577
00578 rval = shr_map_spval
00579 if (.not.shr_map_checkFldStr(fldStr)) then
00580 call shr_map_abort(subName//' ERROR illegal fldStr '//trim(fldStr))
00581 return
00582 endif
00583
00584 call shr_map_abort(subName//' ERROR illegal fldStr '//trim(fldStr))
00585
00586 end subroutine shr_map_getR8
00587
00588
00589
00590
00591
00592
00593
00594
00595
00596
00597
00598
00599
00600
00601
00602
00603
00604 subroutine shr_map_getAR(map,isrc,idst,wgts)
00605
00606 implicit none
00607
00608
00609
00610 type(shr_map_mapType) ,intent(in) :: map
00611 integer(SHR_KIND_IN),pointer,optional :: isrc(:)
00612 integer(SHR_KIND_IN),pointer,optional :: idst(:)
00613 real (SHR_KIND_R8),pointer,optional :: wgts(:)
00614
00615
00616
00617
00618 integer(SHR_KIND_IN) :: nwts
00619
00620
00621 character(*),parameter :: subName = "('shr_map_getAR') "
00622
00623
00624
00625 nwts = map%nwts
00626
00627 if (present(isrc)) then
00628 if (size(isrc) < nwts) then
00629 call shr_sys_abort(subName//' ERROR is isrc size')
00630 endif
00631 isrc(1:nwts) = map%isrc(1:nwts)
00632 endif
00633
00634 if (present(idst)) then
00635 if (size(idst) < nwts) then
00636 call shr_sys_abort(subName//' ERROR is idst size')
00637 endif
00638 idst(1:nwts) = map%idst(1:nwts)
00639 endif
00640
00641 if (present(wgts)) then
00642 if (size(wgts) < nwts) then
00643 call shr_sys_abort(subName//' ERROR is wgts size')
00644 endif
00645 wgts(1:nwts) = map%wgts(1:nwts)
00646 endif
00647
00648 end subroutine shr_map_getAR
00649
00650
00651
00652
00653
00654
00655
00656
00657
00658
00659
00660
00661
00662
00663
00664
00665
00666
00667
00668 subroutine shr_map_putCS(map,fldStr,cval,verify)
00669
00670 implicit none
00671
00672
00673
00674 type(shr_map_mapType) ,intent(inout):: map
00675 character(*) ,intent(in) :: fldStr
00676 character(*) ,intent(in) :: cval
00677 logical,optional ,intent(in) :: verify
00678
00679
00680
00681
00682 logical :: lverify
00683
00684
00685 character(*),parameter :: subName = "('shr_map_putCS') "
00686
00687
00688
00689 lverify = .true.
00690 if (present(verify)) lverify = verify
00691 if (lverify .and. .not.shr_map_checkFldStrOpt(fldStr,cval)) then
00692 call shr_map_abort(subName//' ERROR illegal fldStr '//trim(fldStr)//' '//trim(cval))
00693 return
00694 endif
00695
00696 if (trim(fldStr) == trim(shr_map_fs_name)) then
00697 map%name = cval
00698 elseif (trim(fldStr) == trim(shr_map_fs_type)) then
00699 map%type = cval
00700 elseif (trim(fldStr) == trim(shr_map_fs_algo)) then
00701 map%algo = cval
00702 elseif (trim(fldStr) == trim(shr_map_fs_mask)) then
00703 map%mask = cval
00704 elseif (trim(fldStr) == trim(shr_map_fs_vect)) then
00705 map%vect = cval
00706 else
00707 call shr_map_abort(subName//' ERROR illegal fldStr '//trim(fldStr))
00708 endif
00709
00710 end subroutine shr_map_putCS
00711
00712
00713
00714
00715
00716
00717
00718
00719
00720
00721
00722
00723
00724
00725
00726
00727
00728
00729
00730 subroutine shr_map_putIN(map,fldStr,ival,verify)
00731
00732 implicit none
00733
00734
00735
00736 type(shr_map_mapType) ,intent(inout):: map
00737 character(*) ,intent(in) :: fldStr
00738 integer(SHR_KIND_IN) ,intent(in) :: ival
00739 logical,optional ,intent(in) :: verify
00740
00741
00742
00743
00744 logical :: lverify
00745
00746
00747 character(*),parameter :: subName = "('shr_map_putIN') "
00748 character(*),parameter :: F01 = "('(shr_map_putIN) ',a,i8) "
00749
00750
00751
00752 lverify = .true.
00753 if (present(verify)) lverify = verify
00754 if (lverify .and. .not.shr_map_checkFldStr(fldStr)) then
00755 call shr_map_abort(subName//' ERROR illegal fldStr '//trim(fldStr))
00756 return
00757 endif
00758
00759 if (trim(fldStr) == trim(shr_map_fs_nwts)) then
00760 map%nwts = ival
00761 elseif (trim(fldStr) == trim(shr_map_fs_nsrc)) then
00762 map%nsrc = ival
00763 elseif (trim(fldStr) == trim(shr_map_fs_ndst)) then
00764 map%ndst = ival
00765 else
00766 call shr_map_abort(subName//' ERROR illegal fldStr '//trim(fldStr))
00767 endif
00768
00769 end subroutine shr_map_putIN
00770
00771
00772
00773
00774
00775
00776
00777
00778
00779
00780
00781
00782
00783
00784
00785
00786
00787 subroutine shr_map_putR8(map,fldStr,rval,verify)
00788
00789 implicit none
00790
00791
00792
00793 type(shr_map_mapType) ,intent(inout):: map
00794 character(*) ,intent(in) :: fldStr
00795 real(SHR_KIND_R8) ,intent(in) :: rval
00796 logical,optional ,intent(in) :: verify
00797
00798
00799
00800
00801 logical :: lverify
00802
00803
00804 character(*),parameter :: subName = "('shr_map_putR8') "
00805
00806
00807
00808 lverify = .true.
00809 if (present(verify)) lverify = verify
00810 if (lverify .and. .not.shr_map_checkFldStr(fldStr)) then
00811 call shr_map_abort(subName//' ERROR illegal fldStr '//trim(fldStr))
00812 return
00813 endif
00814
00815 call shr_map_abort(subName//' ERROR illegal fldStr '//trim(fldStr))
00816
00817 end subroutine shr_map_putR8
00818
00819
00820
00821
00822
00823
00824
00825
00826
00827
00828
00829
00830
00831
00832
00833
00834 subroutine shr_map_print(map)
00835
00836 implicit none
00837
00838
00839
00840 type(shr_map_mapType) ,intent(in) :: map
00841
00842
00843
00844
00845
00846
00847 character(*),parameter :: subName = "('shr_map_print') "
00848 character(*),parameter :: F00 = "('(shr_map_print) ',a) "
00849 character(*),parameter :: F01 = "('(shr_map_print) ',a,2l2) "
00850 character(*),parameter :: F02 = "('(shr_map_print) ',a,i8) "
00851 character(*),parameter :: F03 = "('(shr_map_print) ',a,3i8) "
00852 character(*),parameter :: F04 = "('(shr_map_print) ',a,2i8) "
00853 character(*),parameter :: F05 = "('(shr_map_print) ',a,2e20.13) "
00854
00855 if (s_loglev > 0) then
00856 write(s_logunit,*) ' '
00857 write(s_logunit,F01) ' name : '//trim(map%name),shr_map_checkInit(map),shr_map_checkFilled(map)
00858 write(s_logunit,F00) ' type : '//trim(map%type)
00859 write(s_logunit,F00) ' algo : '//trim(map%algo)
00860 write(s_logunit,F00) ' mask : '//trim(map%mask)
00861 write(s_logunit,F00) ' vect : '//trim(map%vect)
00862 write(s_logunit,F04) ' gsiz : ',map%nsrc,map%ndst
00863 write(s_logunit,F05) ' xsrc : ',minval(map%xsrc),maxval(map%xsrc)
00864 write(s_logunit,F05) ' ysrc : ',minval(map%ysrc),maxval(map%ysrc)
00865 write(s_logunit,F05) ' xdst : ',minval(map%xdst),maxval(map%xdst)
00866 write(s_logunit,F05) ' ydst : ',minval(map%ydst),maxval(map%ydst)
00867 write(s_logunit,F02) ' nwts : ',map%nwts
00868 write(s_logunit,F03) ' wsiz : ',size(map%wgts),size(map%isrc),size(map%idst)
00869 write(s_logunit,F00) ' init : '//trim(map%init)
00870
00871 call shr_sys_flush(s_logunit)
00872 endif
00873
00874 end subroutine shr_map_print
00875
00876
00877
00878
00879
00880
00881
00882
00883
00884
00885
00886
00887
00888
00889
00890
00891 subroutine shr_map_listValidOpts()
00892
00893 implicit none
00894
00895
00896
00897
00898
00899
00900 integer(SHR_KIND_IN) :: n
00901
00902
00903 character(*),parameter :: subName = "('shr_map_listValidOpts') "
00904 character(*),parameter :: F00 = "('(shr_map_listValidOpts) ',a) "
00905
00906
00907
00908 if (s_loglev > 0) then
00909 write(s_logunit,F00) ':'
00910 write(s_logunit,F00) ' '//trim(shr_map_fs_name)//' : any character string'
00911 do n = 1,shr_map_fs_ntype
00912 write(s_logunit,F00) ' '//trim(shr_map_fs_type)//' : '//trim(shr_map_fs_types(n))
00913 enddo
00914 do n = 1,shr_map_fs_nalgo
00915 write(s_logunit,F00) ' '//trim(shr_map_fs_algo)//' : '//trim(shr_map_fs_algos(n))
00916 enddo
00917 do n = 1,shr_map_fs_nmask
00918 write(s_logunit,F00) ' '//trim(shr_map_fs_mask)//' : '//trim(shr_map_fs_masks(n))
00919 enddo
00920 do n = 1,shr_map_fs_nvect
00921 write(s_logunit,F00) ' '//trim(shr_map_fs_vect)//' : '//trim(shr_map_fs_vects(n))
00922 enddo
00923 call shr_sys_flush(s_logunit)
00924 endif
00925
00926 end subroutine shr_map_listValidOpts
00927
00928
00929
00930
00931
00932
00933
00934
00935
00936
00937
00938
00939
00940
00941
00942
00943 subroutine shr_map_clean(map)
00944
00945 implicit none
00946
00947
00948
00949 type(shr_map_mapType) ,intent(inout):: map
00950
00951
00952
00953
00954 integer :: rc
00955
00956
00957 character(*),parameter :: subName = "('shr_map_clean') "
00958 character(*),parameter :: F00 = "('(shr_map_clean) ',a) "
00959
00960
00961
00962 map%fill = ' '
00963 map%init = ' '
00964 call shr_map_put(map,shr_map_fs_name,shr_map_setFal,verify=.false.)
00965 call shr_map_put(map,shr_map_fs_type,shr_map_setFal,verify=.false.)
00966 call shr_map_put(map,shr_map_fs_algo,shr_map_setFal,verify=.false.)
00967 call shr_map_put(map,shr_map_fs_mask,shr_map_setFal,verify=.false.)
00968 call shr_map_put(map,shr_map_fs_mask,shr_map_setFal,verify=.false.)
00969 call shr_map_put(map,shr_map_fs_nwts,shr_map_ispval)
00970 call shr_map_put(map,shr_map_fs_nsrc,shr_map_ispval)
00971 call shr_map_put(map,shr_map_fs_ndst,shr_map_ispval)
00972 deallocate(map%xsrc,stat=rc)
00973 if (rc > 0.and.debug > 1 .and. s_loglev > 0) write(s_logunit,F00) 'Warning: unable to deallocate map wgts'
00974 deallocate(map%ysrc,stat=rc)
00975 if (rc > 0.and.debug > 1 .and. s_loglev > 0) write(s_logunit,F00) 'Warning: unable to deallocate map wgts'
00976 deallocate(map%xdst,stat=rc)
00977 if (rc > 0.and.debug > 1 .and. s_loglev > 0) write(s_logunit,F00) 'Warning: unable to deallocate map wgts'
00978 deallocate(map%ydst,stat=rc)
00979 if (rc > 0.and.debug > 1 .and. s_loglev > 0) write(s_logunit,F00) 'Warning: unable to deallocate map wgts'
00980 deallocate(map%wgts,stat=rc)
00981 if (rc > 0.and.debug > 1 .and. s_loglev > 0) write(s_logunit,F00) 'Warning: unable to deallocate map wgts'
00982 deallocate(map%isrc,stat=rc)
00983 if (rc > 0.and.debug > 1 .and. s_loglev > 0) write(s_logunit,F00) 'Warning: unable to deallocate map isrc'
00984 deallocate(map%idst,stat=rc)
00985 if (rc > 0.and.debug > 1 .and. s_loglev > 0) write(s_logunit,F00) 'Warning: unable to deallocate map idst'
00986
00987 end subroutine shr_map_clean
00988
00989
00990
00991
00992
00993
00994
00995
00996
00997
00998
00999
01000
01001
01002
01003
01004
01005
01006
01007
01008
01009
01010
01011
01012
01013
01014
01015
01016
01017
01018
01019
01020
01021
01022
01023
01024
01025
01026
01027 subroutine shr_map_mapSet_global(map,Xsrc,Ysrc,Msrc,Xdst_in,Ydst,Mdst,name,type,algo,mask,vect,rc)
01028
01029 implicit none
01030
01031
01032
01033 type(shr_map_mapType) ,intent(inout):: map
01034 real(SHR_KIND_R8) ,intent(in) :: Xsrc(:,:)
01035 real(SHR_KIND_R8) ,intent(in) :: Ysrc(:,:)
01036 integer(SHR_KIND_IN) ,intent(in) :: Msrc(:,:)
01037 real(SHR_KIND_R8) ,intent(in) :: Xdst_in(:,:)
01038 real(SHR_KIND_R8) ,intent(in) :: Ydst(:,:)
01039 integer(SHR_KIND_IN) ,intent(in) :: Mdst(:,:)
01040 character(*) ,optional,intent(in) :: name
01041 character(*) ,optional,intent(in) :: type
01042 character(*) ,optional,intent(in) :: algo
01043 character(*) ,optional,intent(in) :: mask
01044 character(*) ,optional,intent(in) :: vect
01045 integer(SHR_KIND_IN),optional,intent(out) :: rc
01046
01047
01048
01049
01050 integer(SHR_KIND_IN) :: nis,njs,nid,njd
01051 integer(SHR_KIND_IN) :: nwts,n,n1,n2,ncnt,i,j,inn,jnn
01052 integer(SHR_KIND_IN) :: irc,lrc
01053 real(SHR_KIND_R8) :: rmin,rmax
01054 real(SHR_KIND_R8) :: cang
01055 real(SHR_KIND_R8),allocatable :: Xdst(:,:)
01056
01057 integer(SHR_KIND_IN) :: pmax
01058 integer(SHR_KIND_IN) :: ptot,ptot2
01059 integer(SHR_KIND_IN) :: pnum
01060 integer(SHR_KIND_IN),allocatable :: pti(:)
01061 integer(SHR_KIND_IN),allocatable :: ptj(:)
01062 real(SHR_KIND_R8) ,allocatable :: ptw(:)
01063
01064 integer(SHR_KIND_IN),allocatable :: lis(:)
01065 integer(SHR_KIND_IN),allocatable :: lid(:)
01066 real(SHR_KIND_R8) ,allocatable :: lwt(:)
01067 real(SHR_KIND_R8) ,allocatable :: sum(:)
01068 integer(SHR_KIND_IN),allocatable :: ltmp(:)
01069 real(SHR_KIND_R8) ,allocatable :: lwtmp(:)
01070
01071 character(len=8) :: units
01072
01073 logical :: masksrc
01074 logical :: maskdst
01075 logical :: maskdstbysrc
01076
01077 logical :: renorm
01078
01079
01080 character(*),parameter :: subName = "('shr_map_mapSet_global') "
01081 character(*),parameter :: F00 = "('(shr_map_mapSet_global) ',a) "
01082 character(*),parameter :: F01 = "('(shr_map_mapSet_global) ',a,l2) "
01083 character(*),parameter :: F02 = "('(shr_map_mapSet_global) ',a,2i8) "
01084 character(*),parameter :: F03 = "('(shr_map_mapSet_global) ',a,2e20.13) "
01085
01086
01087
01088 lrc = 0
01089 if (present(rc)) rc = lrc
01090
01091 if (present(name)) call shr_map_put(map,shr_map_fs_name,name)
01092 if (present(type)) call shr_map_put(map,shr_map_fs_type,type,verify=.true.)
01093 if (present(algo)) call shr_map_put(map,shr_map_fs_algo,algo,verify=.true.)
01094 if (present(mask)) call shr_map_put(map,shr_map_fs_mask,mask,verify=.true.)
01095 if (present(vect)) call shr_map_put(map,shr_map_fs_vect,vect,verify=.true.)
01096 map%init = inispval
01097
01098 if (.NOT.shr_map_checkInit(map)) then
01099 call shr_map_abort(subName//' ERROR map not initialized')
01100 endif
01101
01102
01103 cang = 360._SHR_KIND_R8
01104 units = 'degrees'
01105 if (shr_map_checkRad(Ysrc)) then
01106 cang=c2*pi
01107 units = 'radians'
01108 endif
01109
01110 nis = size(Xsrc,1)
01111 njs = size(Xsrc,2)
01112 nid = size(Xdst_in,1)
01113 njd = size(Xdst_in,2)
01114
01115
01116 allocate(Xdst(nid,njd))
01117 rmin = minval(Xsrc)
01118 rmax = maxval(Xsrc)
01119 do j=1,njd
01120 do i=1,nid
01121 Xdst(i,j) = Xdst_in(i,j)
01122 do while ((Xdst(i,j) < rmin .and. Xdst(i,j)+cang <= rmax).or. &
01123 (Xdst(i,j) > rmax .and. Xdst(i,j)-cang >= rmin))
01124 if (Xdst(i,j) < rmin) then
01125 Xdst(i,j) = Xdst(i,j) + cang
01126 elseif (Xdst(i,j) > rmax) then
01127 Xdst(i,j) = Xdst(i,j) - cang
01128 else
01129 call shr_sys_abort(subName//' ERROR in Xdst wrap')
01130 endif
01131 enddo
01132 enddo
01133 enddo
01134
01135 call shr_map_checkGrids_global(Xsrc,Ysrc,Msrc,Xdst,Ydst,Mdst,map,lrc)
01136
01137 map%nwts = 0
01138 map%nsrc = nis*njs
01139 map%ndst = nid*njd
01140
01141
01142
01143
01144
01145 allocate(map%xsrc(nis*njs))
01146 allocate(map%ysrc(nis*njs))
01147 allocate(map%xdst(nid*njd))
01148 allocate(map%ydst(nid*njd))
01149 do j=1,njs
01150 do i=1,nis
01151 call shr_map_2dto1d(n1,nis,njs,i,j)
01152 map%xsrc(n1) = Xsrc(i,j)*c2*pi/cang
01153 map%ysrc(n1) = Ysrc(i,j)*c2*pi/cang
01154 enddo
01155 enddo
01156 do j=1,njd
01157 do i=1,nid
01158 call shr_map_2dto1d(n1,nid,njd,i,j)
01159 map%xdst(n1) = Xdst(i,j)*c2*pi/cang
01160 map%ydst(n1) = Ydst(i,j)*c2*pi/cang
01161 enddo
01162 enddo
01163
01164 masksrc = .false.
01165 maskdstbysrc = .false.
01166 maskdst = .false.
01167 renorm = .true.
01168
01169 if (trim(map%type) /= trim(shr_map_fs_fill) .and. &
01170 trim(map%type) /= trim(shr_map_fs_cfill)) then
01171 if (trim(map%mask) == trim(shr_map_fs_bothmask) .or. &
01172 trim(map%mask) == trim(shr_map_fs_srcmask)) masksrc = .true.
01173 if (trim(map%mask) == trim(shr_map_fs_bothmask) .or. &
01174 trim(map%mask) == trim(shr_map_fs_dstmask)) maskdst = .true.
01175 endif
01176 if (trim(map%algo) == trim(shr_map_fs_spval)) then
01177 masksrc = .false.
01178 renorm = .false.
01179 endif
01180
01181 if (debug > 1) then
01182 if (s_loglev > 0) write(s_logunit,*) ' '
01183 call shr_map_print(map)
01184 endif
01185
01186 if (lrc /= 0) then
01187 if (present(rc)) rc = lrc
01188 return
01189 endif
01190
01191 if (trim(map%algo) == trim(shr_map_fs_bilinear)) then
01192 if (dopole) then
01193 pmax = nis+2
01194 ptot = 4*nid*njd
01195 else
01196 pmax = 4
01197 ptot = 4*nid*njd
01198 endif
01199 else
01200 pmax = 1
01201 ptot = 1*nid*njd
01202 endif
01203 allocate(lis(ptot))
01204 allocate(lid(ptot))
01205 allocate(lwt(ptot))
01206 allocate(pti(pmax))
01207 allocate(ptj(pmax))
01208 allocate(ptw(pmax))
01209
01210
01211 nwts = nid*njd
01212 do n=1,nwts
01213 lid(n) = n
01214 lis(n) = mod(n-1,nis*njs)+1
01215 lwt(n) = c1
01216 enddo
01217
01218
01219 if (trim(map%algo) == trim(shr_map_fs_copy)) then
01220 map%init = initcopy
01221
01222
01223
01224 elseif (trim(map%type) == trim(shr_map_fs_fill) .or. &
01225 trim(map%type) == trim(shr_map_fs_cfill)) then
01226 map%init = initcopy
01227 if (trim(map%algo) == trim(shr_map_fs_spval)) then
01228 maskdstbysrc = .true.
01229 elseif (trim(map%algo) == trim(shr_map_fs_nn)) then
01230 do n=1,nwts
01231 call shr_map_1dto2d(lis(n),nis,njs,i,j)
01232 if (Msrc(i,j) == 0) then
01233 call shr_map_findnn(Xsrc(i,j),Ysrc(i,j),Xsrc,Ysrc,Msrc,inn,jnn)
01234 call shr_map_2dto1d(lis(n),nis,njs,inn,jnn)
01235 endif
01236 enddo
01237 elseif (trim(map%algo) == trim(shr_map_fs_nnoni)) then
01238 do n=1,nwts
01239 call shr_map_1dto2d(lis(n),nis,njs,i,j)
01240 if (Msrc(i,j) == 0) then
01241 call shr_map_findnnon('i',Xsrc(i,j),Ysrc(i,j),Xsrc,Ysrc,Msrc,inn,jnn)
01242 call shr_map_2dto1d(lis(n),nis,njs,inn,jnn)
01243 endif
01244 enddo
01245 elseif (trim(map%algo) == trim(shr_map_fs_nnonj)) then
01246 do n=1,nwts
01247 call shr_map_1dto2d(lis(n),nis,njs,i,j)
01248 if (Msrc(i,j) == 0) then
01249 call shr_map_findnnon('j',Xsrc(i,j),Ysrc(i,j),Xsrc,Ysrc,Msrc,inn,jnn)
01250 call shr_map_2dto1d(lis(n),nis,njs,inn,jnn)
01251 endif
01252 enddo
01253 else
01254 call shr_map_abort(subName//' ERROR: unsupported map option combo')
01255 endif
01256
01257
01258 elseif (trim(map%type) == trim(shr_map_fs_remap)) then
01259 map%init = inispval
01260 if (trim(map%algo) == trim(shr_map_fs_spval)) then
01261 nwts = 0
01262 elseif (trim(map%algo) == trim(shr_map_fs_nn)) then
01263 do n=1,nwts
01264 call shr_map_1dto2d(lid(n),nid,njd,i,j)
01265 call shr_map_findnn(Xdst(i,j),Ydst(i,j),Xsrc,Ysrc,Msrc,inn,jnn)
01266 call shr_map_2dto1d(lis(n),nis,njs,inn,jnn)
01267 enddo
01268 elseif (trim(map%algo) == trim(shr_map_fs_nnoni)) then
01269 do n=1,nwts
01270 call shr_map_1dto2d(lid(n),nid,njd,i,j)
01271 call shr_map_findnnon('i',Xdst(i,j),Ydst(i,j),Xsrc,Ysrc,Msrc,inn,jnn)
01272 call shr_map_2dto1d(lis(n),nis,njs,inn,jnn)
01273 enddo
01274 elseif (trim(map%algo) == trim(shr_map_fs_nnonj)) then
01275 do n=1,nwts
01276 call shr_map_1dto2d(lid(n),nid,njd,i,j)
01277 call shr_map_findnnon('j',Xdst(i,j),Ydst(i,j),Xsrc,Ysrc,Msrc,inn,jnn)
01278 call shr_map_2dto1d(lis(n),nis,njs,inn,jnn)
01279 enddo
01280 elseif (trim(map%algo) == trim(shr_map_fs_bilinear)) then
01281 nwts = 0
01282 do n=1,nid*njd
01283 call shr_map_1dto2d(n,nid,njd,i,j)
01284 call shr_map_getWts(Xdst(i,j),Ydst(i,j),Xsrc,Ysrc,pti,ptj,ptw,pnum,units)
01285 if (nwts + pnum > size(lwt)) then
01286
01287 ptot = size(lwt)
01288 ptot2 = ptot + max(ptot/2,pnum*10)
01289 if (debug > 1 .and. s_loglev > 0) write(s_logunit,F02) 'resize wts ',ptot,ptot2
01290 allocate(ltmp(ptot))
01291 ltmp(1:nwts) = lis(1:nwts)
01292 deallocate(lis)
01293 allocate(lis(ptot2))
01294 lis(1:nwts) = ltmp(1:nwts)
01295 ltmp(1:nwts) = lid(1:nwts)
01296 deallocate(lid)
01297 allocate(lid(ptot2))
01298 lid(1:nwts) = ltmp(1:nwts)
01299 deallocate(ltmp)
01300 allocate(lwtmp(ptot))
01301 lwtmp(1:nwts) = lwt(1:nwts)
01302 deallocate(lwt)
01303 allocate(lwt(ptot2))
01304 lwt(1:nwts) = lwtmp(1:nwts)
01305 deallocate(lwtmp)
01306 endif
01307 do n1 = 1,pnum
01308 nwts = nwts + 1
01309 lid(nwts) = n
01310 call shr_map_2dto1d(lis(nwts),nis,njs,pti(n1),ptj(n1))
01311 lwt(nwts) = ptw(n1)
01312 enddo
01313 enddo
01314 else
01315 call shr_map_abort(subName//' ERROR: unsupported map option combo')
01316 if (present(rc)) rc = 1
01317 return
01318 endif
01319 else
01320 call shr_map_abort(subName//' ERROR: unsupported map option combo')
01321 if (present(rc)) rc = 1
01322 return
01323 endif
01324
01325
01326
01327 if (debug > 1 .and. s_loglev > 0) write(s_logunit,F01) 'init: ',map%init
01328 if (map%init == initcopy .and. &
01329 trim(map%type) /= trim(shr_map_fs_cfill)) then
01330 ncnt = 0
01331 do n=1,nwts
01332 if (lid(n) == lis(n) .and. abs(lwt(n)-c1) < eps) then
01333
01334 else
01335 ncnt = ncnt+1
01336 lid(ncnt) = lid(n)
01337 lis(ncnt) = lis(n)
01338 lwt(ncnt) = lwt(n)
01339 endif
01340 enddo
01341 if (debug > 1 .and. s_loglev > 0) write(s_logunit,F02) ' rm dst grid points, nwts old/new = ',nwts,ncnt
01342 nwts = ncnt
01343 endif
01344
01345
01346 if (debug > 1 .and. s_loglev > 0) write(s_logunit,F01) 'maskdst: ',maskdst
01347 if (maskdst) then
01348 ncnt = 0
01349 do n=1,nwts
01350 call shr_map_1dto2d(lid(n),nid,njd,i,j)
01351 if (Mdst(i,j) /= 0) then
01352 ncnt = ncnt+1
01353 lid(ncnt) = lid(n)
01354 lis(ncnt) = lis(n)
01355 lwt(ncnt) = lwt(n)
01356 endif
01357 enddo
01358 if (debug > 1 .and. s_loglev > 0) write(s_logunit,F02) ' rm dst grid points, nwts old/new = ',nwts,ncnt
01359 nwts = ncnt
01360 endif
01361
01362
01363 if (debug > 1 .and. s_loglev > 0) write(s_logunit,F01) 'maskdstbysrc: ',maskdstbysrc
01364 if (maskdstbysrc) then
01365 ncnt = 0
01366 do n=1,nwts
01367 call shr_map_1dto2d(lid(n),nid,njd,i,j)
01368 if (Msrc(i,j) /= 0) then
01369 ncnt = ncnt+1
01370 lid(ncnt) = lid(n)
01371 lis(ncnt) = lis(n)
01372 lwt(ncnt) = lwt(n)
01373 endif
01374 enddo
01375 if (debug > 1 .and. s_loglev > 0) write(s_logunit,F02) ' rm dst grid points by src, nwts old/new = ',nwts,ncnt
01376 nwts = ncnt
01377 endif
01378
01379
01380 if (debug > 1 .and. s_loglev > 0) write(s_logunit,F01) 'masksrc: ',masksrc
01381 if (masksrc) then
01382 ncnt = 0
01383 do n=1,nwts
01384 call shr_map_1dto2d(lis(n),nis,njs,i,j)
01385 if (Msrc(i,j) /= 0) then
01386 ncnt = ncnt+1
01387 lid(ncnt) = lid(n)
01388 lis(ncnt) = lis(n)
01389 lwt(ncnt) = lwt(n)
01390 endif
01391 enddo
01392 if (debug > 1 .and. s_loglev > 0) write(s_logunit,F02) ' rm src grid points, nwts old/new = ',nwts,ncnt
01393 nwts = ncnt
01394 endif
01395
01396
01397 allocate(sum(nid*njd))
01398
01399 sum(:) = c0
01400 do n=1,nwts
01401 sum(lid(n)) = sum(lid(n)) + lwt(n)
01402 enddo
01403
01404 rmin = maxval(sum)
01405 rmax = minval(sum)
01406 do n=1,nid*njd
01407 if (sum(n) > eps) then
01408 rmin = min(rmin,sum(n))
01409 rmax = max(rmax,sum(n))
01410 endif
01411 enddo
01412 if (debug > 1 .and. s_loglev > 0) write(s_logunit,F03) 'sum wts min/max ',rmin,rmax
01413
01414 if (debug > 1 .and. s_loglev > 0) write(s_logunit,F01) 'renorm: ',renorm
01415 if (renorm) then
01416 do n=1,nwts
01417 if (sum(lid(n)) > eps) then
01418 lwt(n) = lwt(n) / sum(lid(n))
01419 endif
01420 enddo
01421
01422 sum(:) = c0
01423 do n=1,nwts
01424 sum(lid(n)) = sum(lid(n)) + lwt(n)
01425 enddo
01426
01427 rmin = maxval(sum)
01428 rmax = minval(sum)
01429 do n=1,nid*njd
01430 if (sum(n) > eps) then
01431 rmin = min(rmin,sum(n))
01432 rmax = max(rmax,sum(n))
01433 endif
01434 enddo
01435 if (debug > 1 .and. s_loglev > 0) write(s_logunit,F03) 'sum wts min/max ',rmin,rmax
01436 endif
01437
01438 map%nwts = nwts
01439
01440
01441
01442 allocate(map%idst(nwts))
01443 allocate(map%isrc(nwts))
01444 allocate(map%wgts(nwts))
01445 do n=1,nwts
01446 map%idst(n) = lid(n)
01447 map%isrc(n) = lis(n)
01448 map%wgts(n) = lwt(n)
01449 enddo
01450
01451 deallocate(Xdst)
01452
01453 deallocate(lis)
01454 deallocate(lid)
01455 deallocate(lwt)
01456 deallocate(sum)
01457
01458 deallocate(pti)
01459 deallocate(ptj)
01460 deallocate(ptw)
01461
01462 map%fill = fillstring
01463 call shr_map_checkWgts_global(Msrc,Mdst,map)
01464
01465 if (present(rc)) rc = lrc
01466
01467 end subroutine shr_map_mapSet_global
01468
01469
01470
01471
01472
01473
01474
01475
01476
01477
01478
01479
01480
01481
01482
01483
01484
01485
01486
01487
01488
01489
01490
01491
01492
01493
01494
01495
01496
01497
01498
01499
01500
01501
01502
01503
01504
01505
01506
01507 subroutine shr_map_mapSet_dest(map,Xsrc,Ysrc,Msrc,Xdst_in,Ydst,Mdst,ndst,Idst,name,type,algo,mask,vect,rc)
01508
01509 implicit none
01510
01511
01512
01513 type(shr_map_mapType) ,intent(inout):: map
01514 real(SHR_KIND_R8) ,intent(in) :: Xsrc(:,:)
01515 real(SHR_KIND_R8) ,intent(in) :: Ysrc(:,:)
01516 integer(SHR_KIND_IN) ,intent(in) :: Msrc(:,:)
01517 real(SHR_KIND_R8) ,intent(in) :: Xdst_in(:)
01518 real(SHR_KIND_R8) ,intent(in) :: Ydst(:)
01519 integer(SHR_KIND_IN) ,intent(in) :: Mdst(:)
01520 integer(SHR_KIND_IN) ,intent(in) :: ndst
01521 integer(SHR_KIND_IN) ,intent(in) :: Idst(:)
01522 character(*) ,optional,intent(in) :: name
01523 character(*) ,optional,intent(in) :: type
01524 character(*) ,optional,intent(in) :: algo
01525 character(*) ,optional,intent(in) :: mask
01526 character(*) ,optional,intent(in) :: vect
01527 integer(SHR_KIND_IN),optional,intent(out) :: rc
01528
01529
01530
01531
01532 integer(SHR_KIND_IN) :: nis,njs,nid,njd
01533 integer(SHR_KIND_IN) :: nwts,n,n1,n2,ncnt,i,j,inn,jnn
01534 integer(SHR_KIND_IN) :: irc,lrc
01535 real(SHR_KIND_R8) :: rmin,rmax
01536 real(SHR_KIND_R8) :: cang
01537 real(SHR_KIND_R8),allocatable :: Xdst(:)
01538
01539 integer(SHR_KIND_IN) :: pmax
01540 integer(SHR_KIND_IN) :: ptot,ptot2
01541 integer(SHR_KIND_IN) :: pnum
01542 integer(SHR_KIND_IN),allocatable :: pti(:)
01543 integer(SHR_KIND_IN),allocatable :: ptj(:)
01544 real(SHR_KIND_R8) ,allocatable :: ptw(:)
01545
01546 integer(SHR_KIND_IN),allocatable :: lis(:)
01547 integer(SHR_KIND_IN),allocatable :: lid(:)
01548 real(SHR_KIND_R8) ,allocatable :: lwt(:)
01549 real(SHR_KIND_R8) ,allocatable :: sum(:)
01550 integer(SHR_KIND_IN),allocatable :: ltmp(:)
01551 real(SHR_KIND_R8) ,allocatable :: lwtmp(:)
01552
01553 character(len=8) :: units
01554
01555 logical :: masksrc
01556 logical :: maskdst
01557 logical :: maskdstbysrc
01558
01559 logical :: renorm
01560
01561
01562 character(*),parameter :: subName = "('shr_map_mapSet_dest') "
01563 character(*),parameter :: F00 = "('(shr_map_mapSet_dest) ',a) "
01564 character(*),parameter :: F01 = "('(shr_map_mapSet_dest) ',a,l2) "
01565 character(*),parameter :: F02 = "('(shr_map_mapSet_dest) ',a,2i8) "
01566 character(*),parameter :: F03 = "('(shr_map_mapSet_dest) ',a,2e20.13) "
01567
01568
01569
01570 write(s_logunit,F00) 'ERROR this routine is not validated'
01571 call shr_sys_abort(subName//' ERROR subroutine not validated')
01572
01573 lrc = 0
01574 if (present(rc)) rc = lrc
01575
01576 if (present(name)) call shr_map_put(map,shr_map_fs_name,name)
01577 if (present(type)) call shr_map_put(map,shr_map_fs_type,type,verify=.true.)
01578 if (present(algo)) call shr_map_put(map,shr_map_fs_algo,algo,verify=.true.)
01579 if (present(mask)) call shr_map_put(map,shr_map_fs_mask,mask,verify=.true.)
01580 if (present(vect)) call shr_map_put(map,shr_map_fs_vect,vect,verify=.true.)
01581 map%init = inispval
01582
01583 if (.NOT.shr_map_checkInit(map)) then
01584 call shr_map_abort(subName//' ERROR map not initialized')
01585 endif
01586
01587
01588 cang = 360._SHR_KIND_R8
01589 units = 'degrees'
01590 if (shr_map_checkRad(Ysrc)) then
01591 cang=c2*pi
01592 units = 'radians'
01593 endif
01594
01595 nis = size(Xsrc,1)
01596 njs = size(Xsrc,2)
01597 nid = size(Xdst_in,1)
01598 njd = 1
01599
01600
01601 allocate(Xdst(nid))
01602 rmin = minval(Xsrc)
01603 rmax = maxval(Xsrc)
01604 do i=1,nid
01605 Xdst(i) = Xdst_in(i)
01606 do while ((Xdst(i) < rmin .and. Xdst(i)+cang <= rmax).or. &
01607 (Xdst(i) > rmax .and. Xdst(i)-cang >= rmin))
01608 if (Xdst(i) < rmin) then
01609 Xdst(i) = Xdst(i) + cang
01610 elseif (Xdst(i) > rmax) then
01611 Xdst(i) = Xdst(i) - cang
01612 else
01613 call shr_sys_abort(subName//' ERROR in Xdst wrap')
01614 endif
01615 enddo
01616 enddo
01617
01618 call shr_map_checkGrids_dest(Xsrc,Ysrc,Msrc,Xdst,Ydst,Mdst,map,lrc)
01619
01620 map%nwts = 0
01621 map%nsrc = nis*njs
01622 map%ndst = ndst
01623
01624
01625
01626
01627
01628 allocate(map%xsrc(nis*njs))
01629 allocate(map%ysrc(nis*njs))
01630 allocate(map%xdst(nid*njd))
01631 allocate(map%ydst(nid*njd))
01632 do j=1,njs
01633 do i=1,nis
01634 call shr_map_2dto1d(n1,nis,njs,i,j)
01635 map%xsrc(n1) = Xsrc(i,j)*c2*pi/cang
01636 map%ysrc(n1) = Ysrc(i,j)*c2*pi/cang
01637 enddo
01638 enddo
01639 do i=1,nid
01640 map%xdst(i) = Xdst(i)*c2*pi/cang
01641 map%ydst(i) = Ydst(i)*c2*pi/cang
01642 enddo
01643
01644 masksrc = .false.
01645 maskdstbysrc = .false.
01646 maskdst = .false.
01647 renorm = .true.
01648
01649 if (trim(map%type) /= trim(shr_map_fs_fill) .and. &
01650 trim(map%type) /= trim(shr_map_fs_cfill)) then
01651 if (trim(map%mask) == trim(shr_map_fs_bothmask) .or. &
01652 trim(map%mask) == trim(shr_map_fs_srcmask)) masksrc = .true.
01653 if (trim(map%mask) == trim(shr_map_fs_bothmask) .or. &
01654 trim(map%mask) == trim(shr_map_fs_dstmask)) maskdst = .true.
01655 endif
01656 if (trim(map%algo) == trim(shr_map_fs_spval)) then
01657 masksrc = .false.
01658 renorm = .false.
01659 endif
01660
01661 if (debug > 1) then
01662 if (s_loglev > 0) write(s_logunit,*) ' '
01663 call shr_map_print(map)
01664 endif
01665
01666 if (lrc /= 0) then
01667 if (present(rc)) rc = lrc
01668 return
01669 endif
01670
01671 if (trim(map%algo) == trim(shr_map_fs_bilinear)) then
01672 if (dopole) then
01673 pmax = nis+2
01674 ptot = 4*nid*njd
01675 else
01676 pmax = 4
01677 ptot = 4*nid*njd
01678 endif
01679 else
01680 pmax = 1
01681 ptot = 1*nid*njd
01682 endif
01683 allocate(lis(ptot))
01684 allocate(lid(ptot))
01685 allocate(lwt(ptot))
01686 allocate(pti(pmax))
01687 allocate(ptj(pmax))
01688 allocate(ptw(pmax))
01689
01690
01691 nwts = nid*njd
01692 do n=1,nwts
01693 lid(n) = Idst(n)
01694 lis(n) = Idst(n)
01695 lwt(n) = c1
01696 enddo
01697
01698
01699 if (trim(map%algo) == trim(shr_map_fs_copy)) then
01700 map%init = initcopy
01701
01702
01703
01704 elseif (trim(map%type) == trim(shr_map_fs_fill) .or. &
01705 trim(map%type) == trim(shr_map_fs_cfill)) then
01706 map%init = initcopy
01707 if (trim(map%algo) == trim(shr_map_fs_spval)) then
01708 maskdstbysrc = .true.
01709 elseif (trim(map%algo) == trim(shr_map_fs_nn)) then
01710 do n=1,nwts
01711 if (Mdst(n) == 0) then
01712 call shr_map_findnn(Xdst(n),Ydst(n),Xsrc,Ysrc,Msrc,inn,jnn)
01713 call shr_map_2dto1d(lis(n),nis,njs,inn,jnn)
01714 endif
01715 enddo
01716 elseif (trim(map%algo) == trim(shr_map_fs_nnoni)) then
01717 do n=1,nwts
01718 if (Mdst(n) == 0) then
01719 call shr_map_findnnon('i',Xdst(n),Ydst(n),Xsrc,Ysrc,Msrc,inn,jnn)
01720 call shr_map_2dto1d(lis(n),nis,njs,inn,jnn)
01721 endif
01722 enddo
01723 elseif (trim(map%algo) == trim(shr_map_fs_nnonj)) then
01724 do n=1,nwts
01725 if (Mdst(n) == 0) then
01726 call shr_map_findnnon('j',Xdst(n),Ydst(n),Xsrc,Ysrc,Msrc,inn,jnn)
01727 call shr_map_2dto1d(lis(n),nis,njs,inn,jnn)
01728 endif
01729 enddo
01730 else
01731 call shr_map_abort(subName//' ERROR: unsupported map option combo')
01732 endif
01733
01734
01735 elseif (trim(map%type) == trim(shr_map_fs_remap)) then
01736 map%init = inispval
01737 if (trim(map%algo) == trim(shr_map_fs_spval)) then
01738 nwts = 0
01739 elseif (trim(map%algo) == trim(shr_map_fs_nn)) then
01740 do n=1,nwts
01741 call shr_map_findnn(Xdst(n),Ydst(n),Xsrc,Ysrc,Msrc,inn,jnn)
01742 call shr_map_2dto1d(lis(n),nis,njs,inn,jnn)
01743 enddo
01744 elseif (trim(map%algo) == trim(shr_map_fs_nnoni)) then
01745 do n=1,nwts
01746 call shr_map_findnnon('i',Xdst(n),Ydst(n),Xsrc,Ysrc,Msrc,inn,jnn)
01747 call shr_map_2dto1d(lis(n),nis,njs,inn,jnn)
01748 enddo
01749 elseif (trim(map%algo) == trim(shr_map_fs_nnonj)) then
01750 do n=1,nwts
01751 call shr_map_findnnon('j',Xdst(n),Ydst(n),Xsrc,Ysrc,Msrc,inn,jnn)
01752 call shr_map_2dto1d(lis(n),nis,njs,inn,jnn)
01753 enddo
01754 elseif (trim(map%algo) == trim(shr_map_fs_bilinear)) then
01755 nwts = 0
01756 do n=1,nid*njd
01757 call shr_map_getWts(Xdst(n),Ydst(n),Xsrc,Ysrc,pti,ptj,ptw,pnum,units)
01758 if (nwts + pnum > size(lwt)) then
01759
01760 ptot = size(lwt)
01761 ptot2 = ptot + max(ptot/2,pnum*10)
01762 if (debug > 1 .and. s_loglev > 0) write(s_logunit,F02) 'resize wts ',ptot,ptot2
01763 allocate(ltmp(ptot))
01764 ltmp(1:nwts) = lis(1:nwts)
01765 deallocate(lis)
01766 allocate(lis(ptot2))
01767 lis(1:nwts) = ltmp(1:nwts)
01768 ltmp(1:nwts) = lid(1:nwts)
01769 deallocate(lid)
01770 allocate(lid(ptot2))
01771 lid(1:nwts) = ltmp(1:nwts)
01772 deallocate(ltmp)
01773 allocate(lwtmp(ptot))
01774 lwtmp(1:nwts) = lwt(1:nwts)
01775 deallocate(lwt)
01776 allocate(lwt(ptot2))
01777 lwt(1:nwts) = lwtmp(1:nwts)
01778 deallocate(lwtmp)
01779 endif
01780 do n1 = 1,pnum
01781 nwts = nwts + 1
01782 lid(nwts) = Idst(n)
01783 call shr_map_2dto1d(lis(nwts),nis,njs,pti(n1),ptj(n1))
01784 lwt(nwts) = ptw(n1)
01785 enddo
01786 enddo
01787 else
01788 call shr_map_abort(subName//' ERROR: unsupported map option combo')
01789 if (present(rc)) rc = 1
01790 return
01791 endif
01792 else
01793 call shr_map_abort(subName//' ERROR: unsupported map option combo')
01794 if (present(rc)) rc = 1
01795 return
01796 endif
01797
01798
01799
01800 if (debug > 1 .and. s_loglev > 0) write(s_logunit,F01) 'init: ',map%init
01801 if (map%init == initcopy .and. &
01802 trim(map%type) /= trim(shr_map_fs_cfill)) then
01803 ncnt = 0
01804 do n=1,nwts
01805 if (lid(n) == lis(n) .and. abs(lwt(n)-c1) < eps) then
01806
01807 else
01808 ncnt = ncnt+1
01809 lid(ncnt) = lid(n)
01810 lis(ncnt) = lis(n)
01811 lwt(ncnt) = lwt(n)
01812 endif
01813 enddo
01814 if (debug > 1 .and. s_loglev > 0) write(s_logunit,F02) ' rm dst grid points, nwts old/new = ',nwts,ncnt
01815 nwts = ncnt
01816 endif
01817
01818
01819 if (debug > 1 .and. s_loglev > 0) write(s_logunit,F01) 'maskdst: ',maskdst
01820 if (maskdst) then
01821 ncnt = 0
01822 do n=1,nwts
01823 if (Mdst(n) /= 0) then
01824 ncnt = ncnt+1
01825 lid(ncnt) = lid(n)
01826 lis(ncnt) = lis(n)
01827 lwt(ncnt) = lwt(n)
01828 endif
01829 enddo
01830 if (debug > 1 .and. s_loglev > 0) write(s_logunit,F02) ' rm dst grid points, nwts old/new = ',nwts,ncnt
01831 nwts = ncnt
01832 endif
01833
01834
01835 if (debug > 1 .and. s_loglev > 0) write(s_logunit,F01) 'maskdstbysrc: ',maskdstbysrc
01836 if (maskdstbysrc) then
01837 ncnt = 0
01838 do n=1,nwts
01839 call shr_map_1dto2d(lid(n),nis,njs,i,j)
01840 if (Msrc(i,j) /= 0) then
01841 ncnt = ncnt+1
01842 lid(ncnt) = lid(n)
01843 lis(ncnt) = lis(n)
01844 lwt(ncnt) = lwt(n)
01845 endif
01846 enddo
01847 if (debug > 1 .and. s_loglev > 0) write(s_logunit,F02) ' rm dst grid points by src, nwts old/new = ',nwts,ncnt
01848 nwts = ncnt
01849 endif
01850
01851
01852 if (debug > 1 .and. s_loglev > 0) write(s_logunit,F01) 'masksrc: ',masksrc
01853 if (masksrc) then
01854 ncnt = 0
01855 do n=1,nwts
01856 call shr_map_1dto2d(lis(n),nis,njs,i,j)
01857 if (Msrc(i,j) /= 0) then
01858 ncnt = ncnt+1
01859 lid(ncnt) = lid(n)
01860 lis(ncnt) = lis(n)
01861 lwt(ncnt) = lwt(n)
01862 endif
01863 enddo
01864 if (debug > 1 .and. s_loglev > 0) write(s_logunit,F02) ' rm src grid points, nwts old/new = ',nwts,ncnt
01865 nwts = ncnt
01866 endif
01867
01868
01869 allocate(sum(ndst))
01870
01871 sum(:) = c0
01872 do n=1,nwts
01873 sum(lid(n)) = sum(lid(n)) + lwt(n)
01874 enddo
01875
01876 rmin = maxval(sum)
01877 rmax = minval(sum)
01878 do n=1,ndst
01879 if (sum(n) > eps) then
01880 rmin = min(rmin,sum(n))
01881 rmax = max(rmax,sum(n))
01882 endif
01883 enddo
01884 if (debug > 1 .and. s_loglev > 0) write(s_logunit,F03) 'sum wts min/max ',rmin,rmax
01885
01886 if (debug > 1 .and. s_loglev > 0) write(s_logunit,F01) 'renorm: ',renorm
01887 if (renorm) then
01888 do n=1,nwts
01889 if (sum(lid(n)) > eps) then
01890 lwt(n) = lwt(n) / sum(lid(n))
01891 endif
01892 enddo
01893
01894 sum(:) = c0
01895 do n=1,nwts
01896 sum(lid(n)) = sum(lid(n)) + lwt(n)
01897 enddo
01898
01899 rmin = maxval(sum)
01900 rmax = minval(sum)
01901 do n=1,nid*njd
01902 if (sum(n) > eps) then
01903 rmin = min(rmin,sum(n))
01904 rmax = max(rmax,sum(n))
01905 endif
01906 enddo
01907 if (debug > 1 .and. s_loglev > 0) write(s_logunit,F03) 'sum wts min/max ',rmin,rmax
01908 endif
01909
01910 map%nwts = nwts
01911
01912
01913
01914 allocate(map%idst(nwts))
01915 allocate(map%isrc(nwts))
01916 allocate(map%wgts(nwts))
01917 do n=1,nwts
01918 map%idst(n) = lid(n)
01919 map%isrc(n) = lis(n)
01920 map%wgts(n) = lwt(n)
01921 enddo
01922
01923 deallocate(Xdst)
01924
01925 deallocate(lis)
01926 deallocate(lid)
01927 deallocate(lwt)
01928 deallocate(sum)
01929
01930 deallocate(pti)
01931 deallocate(ptj)
01932 deallocate(ptw)
01933
01934 map%fill = fillstring
01935
01936
01937 if (present(rc)) rc = lrc
01938
01939 end subroutine shr_map_mapSet_dest
01940
01941
01942
01943
01944
01945
01946
01947
01948
01949
01950
01951
01952
01953
01954
01955
01956 subroutine shr_map_mapDatam(arrsrc,arrdst,map)
01957
01958
01959 implicit none
01960
01961
01962
01963 real(SHR_KIND_R8) ,intent(in) :: arrsrc(:,:)
01964 real(SHR_KIND_R8) ,intent(out):: arrdst(:,:)
01965 type(shr_map_mapType) ,intent(in) :: map
01966
01967
01968
01969
01970 integer(SHR_KIND_IN) :: n,n2
01971 integer(SHR_KIND_IN) :: indi,indo
01972 real(SHR_KIND_R8) :: wgt
01973 integer(SHR_KIND_IN) :: nfi,nfo
01974 integer(SHR_KIND_IN) :: nsi,nso
01975 real(SHR_KIND_R8) :: theta
01976 integer(SHR_KIND_IN),save :: t0=-1,t1,t2,t3,t4,t5
01977 integer(SHR_KIND_IN),parameter :: timing=0
01978 logical,pointer :: initnew(:)
01979
01980
01981 character(*),parameter :: subName = "('shr_map_mapDatam') "
01982 character(*),parameter :: F00 = "('(shr_map_mapDatam) ',a) "
01983 character(*),parameter :: F01 = "('(shr_map_mapDatam) ',a,2i8) "
01984
01985
01986
01987 if (timing>0 .and. t0 == -1) then
01988 call shr_timer_get(t0,subName//"everything")
01989 call shr_timer_get(t1,subName//"initial checks")
01990 call shr_timer_get(t2,subName//"dst to spval")
01991 call shr_timer_get(t4,subName//"map vector")
01992 call shr_timer_get(t5,subName//"map scalar")
01993 end if
01994
01995 if (timing>0) call shr_timer_start(t0)
01996 if (timing>0) call shr_timer_start(t1)
01997
01998
01999 nfi = size(arrsrc,1)
02000 nfo = size(arrdst,1)
02001
02002
02003 if (nfi /= nfo) then
02004 write(s_logunit,F01) ' field numbers dont match ',nfi,nfo
02005 call shr_map_abort(subName//' ERROR number of fields')
02006 endif
02007
02008
02009 if (trim(map%vect) == trim(shr_map_fs_vector).and.(nfi /= 2)) then
02010 write(s_logunit,F01) ' vector mapping, must map only two fields',nfi,nfo
02011 call shr_map_abort(subName//' ERROR vector mapping fields not two')
02012 endif
02013
02014
02015 if (.not.shr_map_checkFilled(map)) then
02016 write(s_logunit,F00) ' map is not filled'
02017 call shr_map_abort(subName//' ERROR map is not filled')
02018 endif
02019
02020
02021 nsi = size(arrsrc,2)
02022 nso = size(arrdst,2)
02023
02024
02025 if (nsi /= map%nsrc) then
02026 write(s_logunit,F01) ' src grid size doesnt match ',nsi,map%nsrc
02027 call shr_map_abort(subName//' ERROR src grid size')
02028 endif
02029 if (nso /= map%ndst) then
02030 write(s_logunit,F01) ' dst grid size doesnt match ',nso,map%ndst
02031 call shr_map_abort(subName//' ERROR dst grid size')
02032 endif
02033
02034 if (timing>0) call shr_timer_stop(t1)
02035 if (timing>0) call shr_timer_start(t2)
02036
02037 allocate(initnew(1:nso))
02038 initnew = .true.
02039
02040 if (map%init == inispval) then
02041 arrdst = shr_map_spval
02042 elseif (map%init == initcopy) then
02043 if (nsi /= nso) then
02044 write(s_logunit,F01) ' initcopy has nsi ne nso ',nsi,nso
02045 call shr_map_abort(subName//' ERROR initcopy size')
02046 else
02047 do n = 1,nsi
02048 do n2 = 1,nfo
02049 arrdst(n2,n) = arrsrc(n2,n)
02050 enddo
02051 enddo
02052 endif
02053 else
02054 write(s_logunit,F00) ' map%init illegal '//trim(map%init)
02055 call shr_map_abort(subName//' ERROR map init')
02056 endif
02057
02058 if (timing>0) call shr_timer_stop(t2)
02059
02060
02061 if (trim(map%vect) == trim(shr_map_fs_vector)) then
02062 if (timing>0) call shr_timer_start(t4)
02063 do n=1,map%nwts
02064 indi = map%isrc(n)
02065 indo = map%idst(n)
02066 wgt = map%wgts(n)
02067 theta = map%xdst(indo) - map%xsrc(indi)
02068 if (initnew(indo)) then
02069 initnew(indo) = .false.
02070 arrdst(1,indo) = wgt*( arrsrc(1,indi)*cos(theta) &
02071 +arrsrc(2,indi)*sin(theta))
02072 arrdst(2,indo) = wgt*(-arrsrc(1,indi)*sin(theta) &
02073 +arrsrc(2,indi)*cos(theta))
02074 else
02075 arrdst(1,indo) = arrdst(1,indo) + wgt*( arrsrc(1,indi)*cos(theta) &
02076 +arrsrc(2,indi)*sin(theta))
02077 arrdst(2,indo) = arrdst(2,indo) + wgt*(-arrsrc(1,indi)*sin(theta) &
02078 +arrsrc(2,indi)*cos(theta))
02079 endif
02080 enddo
02081 if (timing>0) call shr_timer_stop(t4)
02082 else
02083 if (timing>0) call shr_timer_start(t5)
02084 do n=1,map%nwts
02085 indi = map%isrc(n)
02086 indo = map%idst(n)
02087 wgt = map%wgts(n)
02088 if (initnew(indo)) then
02089 initnew(indo) = .false.
02090 do n2 = 1,nfo
02091 arrdst(n2,indo) = arrsrc(n2,indi)*wgt
02092 enddo
02093 else
02094 do n2 = 1,nfo
02095 arrdst(n2,indo) = arrdst(n2,indo) + arrsrc(n2,indi)*wgt
02096 enddo
02097 endif
02098 enddo
02099 if (timing>0) call shr_timer_stop(t5)
02100 endif
02101
02102 deallocate(initnew)
02103
02104 if (timing>0) call shr_timer_stop(t0)
02105
02106 end subroutine shr_map_mapDatam
02107
02108
02109
02110
02111
02112
02113
02114
02115
02116
02117
02118
02119
02120
02121
02122
02123 subroutine shr_map_mapDatanm(arrsrc,arrdst,Xsrc,Ysrc,Msrc,Xdst,Ydst,Mdst,name,type,algo,mask,vect,rc)
02124
02125 implicit none
02126
02127
02128
02129
02130 real(SHR_KIND_R8) ,intent(in) :: arrsrc(:,:)
02131 real(SHR_KIND_R8) ,intent(out):: arrdst(:,:)
02132 real(SHR_KIND_R8) ,intent(in) :: Xsrc(:,:)
02133 real(SHR_KIND_R8) ,intent(in) :: Ysrc(:,:)
02134 integer(SHR_KIND_IN) ,intent(in) :: Msrc(:,:)
02135 real(SHR_KIND_R8) ,intent(in) :: Xdst(:,:)
02136 real(SHR_KIND_R8) ,intent(in) :: Ydst(:,:)
02137 integer(SHR_KIND_IN) ,intent(in) :: Mdst(:,:)
02138 character(*) ,intent(in) :: name
02139 character(*) ,intent(in) :: type
02140 character(*) ,intent(in) :: algo
02141 character(*) ,intent(in) :: mask
02142 character(*) ,optional,intent(in) :: vect
02143 integer(SHR_KIND_IN),optional,intent(out) :: rc
02144
02145
02146
02147
02148 type(shr_map_mapType) :: map
02149 integer(SHR_KIND_IN) :: lrc
02150
02151
02152 character(*),parameter :: subName = "('shr_map_mapDatanm') "
02153 character(*),parameter :: F00 = "('(shr_map_mapDatanm) ',a) "
02154
02155
02156
02157 lrc = 0
02158
02159 call shr_map_put(map,shr_map_fs_name,name,verify=.false.)
02160 call shr_map_put(map,shr_map_fs_type,type,verify=.true.)
02161 call shr_map_put(map,shr_map_fs_algo,algo,verify=.true.)
02162 call shr_map_put(map,shr_map_fs_mask,mask,verify=.true.)
02163 if (present(vect)) then
02164 call shr_map_put(map,shr_map_fs_vect,vect,verify=.true.)
02165 else
02166 call shr_map_put(map,shr_map_fs_vect,'scalar',verify=.true.)
02167 endif
02168 call shr_map_mapSet(map,Xsrc,Ysrc,Msrc,Xdst,Ydst,Mdst,rc=lrc)
02169 call shr_map_mapData(arrsrc,arrdst,map)
02170
02171 call shr_map_clean(map)
02172
02173 if (present(rc)) rc = lrc
02174
02175 end subroutine shr_map_mapDatanm
02176
02177
02178
02179
02180
02181
02182
02183
02184
02185
02186
02187
02188
02189
02190
02191
02192
02193 subroutine shr_map_setAbort(flag)
02194
02195 implicit none
02196
02197
02198
02199 logical,intent(in) :: flag
02200
02201
02202
02203
02204
02205
02206 character(*),parameter :: subName = "('shr_map_setAbort') "
02207 character(*),parameter :: F00 = "('(shr_map_setAbort) ',a) "
02208
02209
02210
02211 doabort = flag
02212
02213 end subroutine shr_map_setAbort
02214
02215
02216
02217
02218
02219
02220
02221
02222
02223
02224
02225
02226
02227
02228
02229
02230 subroutine shr_map_setDebug(iflag)
02231
02232 implicit none
02233
02234
02235
02236 integer,intent(in) :: iflag
02237
02238
02239
02240
02241
02242
02243 character(*),parameter :: subName = "('shr_map_setDebug') "
02244 character(*),parameter :: F00 = "('(shr_map_setDebug) ',a) "
02245
02246
02247
02248 debug = iflag
02249
02250 end subroutine shr_map_setDebug
02251
02252
02253
02254
02255
02256
02257
02258
02259
02260
02261
02262
02263
02264
02265
02266
02267 subroutine shr_map_setDopole(flag)
02268
02269 implicit none
02270
02271
02272
02273 logical, intent(in) :: flag
02274
02275
02276
02277
02278
02279
02280 character(*),parameter :: subName = "('shr_map_setDopole') "
02281 character(*),parameter :: F00 = "('(shr_map_setDopole) ',a) "
02282
02283 dopole = flag
02284
02285 end subroutine shr_map_setDopole
02286
02287
02288
02289
02290
02291
02292
02293
02294
02295
02296
02297
02298
02299
02300
02301
02302
02303 subroutine shr_map_abort(string)
02304
02305 implicit none
02306
02307
02308
02309 character(*),optional,intent(in) :: string
02310
02311
02312
02313
02314 character(shr_kind_CL) :: lstring
02315
02316
02317 character(*),parameter :: subName = "('shr_map_abort') "
02318 character(*),parameter :: F00 = "('(shr_map_abort) ',a) "
02319
02320
02321
02322 lstring = ''
02323 if (present(string)) lstring = string
02324
02325 if (doabort) then
02326 call shr_sys_abort(lstring)
02327 else
02328 write(s_logunit,F00) trim(lstring)
02329 endif
02330
02331 end subroutine shr_map_abort
02332
02333
02334
02335
02336
02337
02338
02339
02340
02341
02342
02343
02344
02345
02346
02347
02348 subroutine shr_map_checkGrids_global(Xsrc,Ysrc,Msrc,Xdst,Ydst,Mdst,map,rc)
02349
02350 implicit none
02351
02352
02353 real(SHR_KIND_R8) ,intent(in) :: Xsrc(:,:)
02354 real(SHR_KIND_R8) ,intent(in) :: Ysrc(:,:)
02355 integer(SHR_KIND_IN) ,intent(in) :: Msrc(:,:)
02356 real(SHR_KIND_R8) ,intent(in) :: Xdst(:,:)
02357 real(SHR_KIND_R8) ,intent(in) :: Ydst(:,:)
02358 integer(SHR_KIND_IN) ,intent(in) :: Mdst(:,:)
02359 type(shr_map_mapType),intent(in) :: map
02360 integer(SHR_KIND_IN),optional,intent(out) :: rc
02361
02362
02363
02364
02365 integer(SHR_KIND_IN) :: i,j,nis,njs,nid,njd,ncnt
02366 logical :: error,flag
02367
02368
02369 character(*),parameter :: subName = "('shr_map_checkGrids_global') "
02370 character(*),parameter :: F00 = "('(shr_map_checkGrids_global) ',a) "
02371 character(*),parameter :: F01 = "('(shr_map_checkGrids_global) ',a,2i8) "
02372 character(*),parameter :: F02 = "('(shr_map_checkGrids_global) ',a,4i8) "
02373 character(*),parameter :: F03 = "('(shr_map_checkGrids_global) ',a,2g20.13) "
02374 character(*),parameter :: F04 = "('(shr_map_checkGrids_global) ',a,i8,a,i8) "
02375 character(*),parameter :: F05 = "('(shr_map_checkGrids_global) ',a,i8,2g20.13) "
02376 character(*),parameter :: F06 = "('(shr_map_checkGrids_global) ',a,2i8,2g20.13) "
02377
02378
02379
02380 error = .false.
02381 if (present(rc)) rc = 0
02382
02383
02384 nis = size(Xsrc,1)
02385 njs = size(Xsrc,2)
02386 nid = size(Xdst,1)
02387 njd = size(Xdst,2)
02388
02389
02390 if (size(Ysrc,1) /= nis) then
02391 write(s_logunit,F01) 'ERROR Xsrc,Ysrc i-dim mismatch',nis,size(Ysrc,1)
02392 error = .true.
02393 endif
02394 if (size(Ysrc,2) /= njs) then
02395 write(s_logunit,F01) 'ERROR Xsrc,Ysrc j-dim mismatch',njs,size(Ysrc,2)
02396 error = .true.
02397 endif
02398 if (size(Msrc,1) /= nis) then
02399 write(s_logunit,F01) 'ERROR Xsrc,Msrc i-dim mismatch',nis,size(Msrc,1)
02400 error = .true.
02401 endif
02402 if (size(Msrc,2) /= njs) then
02403 write(s_logunit,F01) 'ERROR Xsrc,Msrc j-dim mismatch',njs,size(Msrc,2)
02404 error = .true.
02405 endif
02406 if (size(Ydst,1) /= nid) then
02407 write(s_logunit,F01) 'ERROR Xdst,Ydst i-dim mismatch',nid,size(Ydst,1)
02408 error = .true.
02409 endif
02410 if (size(Ydst,2) /= njd) then
02411 write(s_logunit,F01) 'ERROR Xdst,Ydst j-dim mismatch',njd,size(Ydst,2)
02412 error = .true.
02413 endif
02414 if (size(Mdst,1) /= nid) then
02415 write(s_logunit,F01) 'ERROR Xdst,Mdst i-dim mismatch',nid,size(Mdst,1)
02416 error = .true.
02417 endif
02418 if (size(Mdst,2) /= njd) then
02419 write(s_logunit,F01) 'ERROR Xdst,Mdst j-dim mismatch',njd,size(Mdst,2)
02420 error = .true.
02421 endif
02422
02423
02424 if (trim(map%type) == trim(shr_map_fs_fill) .or. &
02425 trim(map%type) == trim(shr_map_fs_cfill)) then
02426 if (nis*njs /= nid*njd) then
02427 write(s_logunit,F02) 'ERROR: fill type, src/dst sizes ',nis*njs,nid*njd
02428 error = .true.
02429 endif
02430 endif
02431
02432
02433 if (debug > 1 .and. s_loglev > 0) then
02434 write(s_logunit,F03) ' Xsrc min/max ',minval(Xsrc),maxval(Xsrc)
02435 write(s_logunit,F03) ' Ysrc min/max ',minval(Ysrc),maxval(Ysrc)
02436 write(s_logunit,F03) ' Xdst min/max ',minval(Xdst),maxval(Xdst)
02437 write(s_logunit,F03) ' Ydst min/max ',minval(Ydst),maxval(Ydst)
02438 endif
02439
02440 ncnt = 0
02441 do j=1,njs
02442 do i=1,nis
02443 if (Msrc(i,j) == 0) ncnt = ncnt + 1
02444 enddo
02445 enddo
02446 if (debug > 1 .and. s_loglev > 0) write(s_logunit,F04) ' Msrc mask T ',nis*njs-ncnt,' of ',nis*njs
02447
02448 ncnt = 0
02449 do j=1,njd
02450 do i=1,nid
02451 if (Mdst(i,j) == 0) ncnt = ncnt + 1
02452 enddo
02453 enddo
02454 if (debug > 1 .and. s_loglev > 0) write(s_logunit,F04) ' Mdst mask T ',nid*njd-ncnt,' of ',nid*njd
02455
02456 if (trim(map%algo) == trim(shr_map_fs_bilinear)) then
02457
02458
02459 flag = .false.
02460 i = 1
02461 do while (i < nis .and. .not.flag)
02462 if (Xsrc(i+1,1) <= Xsrc(i,1)) then
02463 write(s_logunit,F05) 'ERROR Xsrc not increasing ',i,Xsrc(i+1,1),Xsrc(i,1)
02464 flag = .true.
02465 error = .true.
02466 endif
02467 i = i+1
02468 enddo
02469
02470
02471 flag = .false.
02472 j = 1
02473 do while (j < njs .and. .not.flag)
02474 if (Ysrc(1,j+1) <= Ysrc(1,j)) then
02475 write(s_logunit,F05) 'ERROR Ysrc not increasing ',i,Ysrc(1,j+1),Ysrc(1,j)
02476 flag = .true.
02477 error = .true.
02478 endif
02479 j = j+1
02480 enddo
02481
02482
02483 flag = .false.
02484 i = 1
02485 do while (i < nis .and. .not.flag)
02486 j = 2
02487 do while (j < njs .and. .not.flag)
02488 if (abs(Xsrc(i,j)-Xsrc(i,1)) > eps) then
02489 write(s_logunit,F06) ' ERROR Xsrc not regular lat,lon ',i,j, &
02490 Xsrc(i,j),Xsrc(1,j)
02491 flag = .true.
02492 error = .true.
02493 endif
02494 j = j+1
02495 enddo
02496 i = i+1
02497 enddo
02498
02499 flag = .false.
02500 j = 1
02501 do while (j < njs .and. .not.flag)
02502 i = 2
02503 do while (i < nis .and. .not.flag)
02504 if (abs(Ysrc(i,j)-Ysrc(1,j)) > eps) then
02505 write(s_logunit,F06) ' ERROR Ysrc not regular lat,lon ',i,j, &
02506 Ysrc(i,j),Ysrc(1,j)
02507 flag = .true.
02508 error = .true.
02509 endif
02510 i = i+1
02511 enddo
02512 j = j+1
02513 enddo
02514 endif
02515
02516 if (error) then
02517 call shr_map_abort(subName//' ERROR ')
02518 if (present(rc)) rc = 1
02519 endif
02520
02521 end subroutine shr_map_checkGrids_global
02522
02523
02524
02525
02526
02527
02528
02529
02530
02531
02532
02533
02534
02535
02536
02537
02538 subroutine shr_map_checkGrids_dest(Xsrc,Ysrc,Msrc,Xdst,Ydst,Mdst,map,rc)
02539
02540 implicit none
02541
02542
02543 real(SHR_KIND_R8) ,intent(in) :: Xsrc(:,:)
02544 real(SHR_KIND_R8) ,intent(in) :: Ysrc(:,:)
02545 integer(SHR_KIND_IN) ,intent(in) :: Msrc(:,:)
02546 real(SHR_KIND_R8) ,intent(in) :: Xdst(:)
02547 real(SHR_KIND_R8) ,intent(in) :: Ydst(:)
02548 integer(SHR_KIND_IN) ,intent(in) :: Mdst(:)
02549 type(shr_map_mapType),intent(in) :: map
02550 integer(SHR_KIND_IN),optional,intent(out) :: rc
02551
02552
02553
02554
02555 integer(SHR_KIND_IN) :: i,j,nis,njs,nid,njd,ncnt
02556 logical :: error,flag
02557
02558
02559 character(*),parameter :: subName = "('shr_map_checkGrids_dest') "
02560 character(*),parameter :: F00 = "('(shr_map_checkGrids_dest) ',a) "
02561 character(*),parameter :: F01 = "('(shr_map_checkGrids_dest) ',a,2i8) "
02562 character(*),parameter :: F02 = "('(shr_map_checkGrids_dest) ',a,4i8) "
02563 character(*),parameter :: F03 = "('(shr_map_checkGrids_dest) ',a,2g20.13) "
02564 character(*),parameter :: F04 = "('(shr_map_checkGrids_dest) ',a,i8,a,i8) "
02565 character(*),parameter :: F05 = "('(shr_map_checkGrids_dest) ',a,i8,2g20.13) "
02566 character(*),parameter :: F06 = "('(shr_map_checkGrids_dest) ',a,2i8,2g20.13) "
02567
02568
02569
02570 error = .false.
02571 if (present(rc)) rc = 0
02572
02573
02574 nis = size(Xsrc,1)
02575 njs = size(Xsrc,2)
02576 nid = size(Xdst,1)
02577 njd = 1
02578
02579
02580 if (size(Ysrc,1) /= nis) then
02581 write(s_logunit,F01) 'ERROR Xsrc,Ysrc i-dim mismatch',nis,size(Ysrc,1)
02582 error = .true.
02583 endif
02584 if (size(Ysrc,2) /= njs) then
02585 write(s_logunit,F01) 'ERROR Xsrc,Ysrc j-dim mismatch',njs,size(Ysrc,2)
02586 error = .true.
02587 endif
02588 if (size(Msrc,1) /= nis) then
02589 write(s_logunit,F01) 'ERROR Xsrc,Msrc i-dim mismatch',nis,size(Msrc,1)
02590 error = .true.
02591 endif
02592 if (size(Msrc,2) /= njs) then
02593 write(s_logunit,F01) 'ERROR Xsrc,Msrc j-dim mismatch',njs,size(Msrc,2)
02594 error = .true.
02595 endif
02596 if (size(Ydst,1) /= nid) then
02597 write(s_logunit,F01) 'ERROR Xdst,Ydst i-dim mismatch',nid,size(Ydst,1)
02598 error = .true.
02599 endif
02600 if (size(Mdst,1) /= nid) then
02601 write(s_logunit,F01) 'ERROR Xdst,Mdst i-dim mismatch',nid,size(Mdst,1)
02602 error = .true.
02603 endif
02604
02605
02606
02607
02608
02609
02610
02611
02612
02613
02614
02615
02616 if (debug > 1 .and. s_loglev > 0) then
02617 write(s_logunit,F03) ' Xsrc min/max ',minval(Xsrc),maxval(Xsrc)
02618 write(s_logunit,F03) ' Ysrc min/max ',minval(Ysrc),maxval(Ysrc)
02619 write(s_logunit,F03) ' Xdst min/max ',minval(Xdst),maxval(Xdst)
02620 write(s_logunit,F03) ' Ydst min/max ',minval(Ydst),maxval(Ydst)
02621 endif
02622
02623 ncnt = 0
02624 do j=1,njs
02625 do i=1,nis
02626 if (Msrc(i,j) == 0) ncnt = ncnt + 1
02627 enddo
02628 enddo
02629 if (debug > 1 .and. s_loglev > 0) write(s_logunit,F04) ' Msrc mask T ',nis*njs-ncnt,' of ',nis*njs
02630
02631 ncnt = 0
02632 do i=1,nid
02633 if (Mdst(i) == 0) ncnt = ncnt + 1
02634 enddo
02635 if (debug > 1 .and. s_loglev > 0) write(s_logunit,F04) ' Mdst mask T ',nid*njd-ncnt,' of ',nid*njd
02636
02637 if (trim(map%algo) == trim(shr_map_fs_bilinear)) then
02638
02639
02640 flag = .false.
02641 i = 1
02642 do while (i < nis .and. .not.flag)
02643 if (Xsrc(i+1,1) <= Xsrc(i,1)) then
02644 write(s_logunit,F05) 'ERROR Xsrc not increasing ',i,Xsrc(i+1,1),Xsrc(i,1)
02645 flag = .true.
02646 error = .true.
02647 endif
02648 i = i+1
02649 enddo
02650
02651
02652 flag = .false.
02653 j = 1
02654 do while (j < njs .and. .not.flag)
02655 if (Ysrc(1,j+1) <= Ysrc(1,j)) then
02656 write(s_logunit,F05) 'ERROR Ysrc not increasing ',i,Ysrc(1,j+1),Ysrc(1,j)
02657 flag = .true.
02658 error = .true.
02659 endif
02660 j = j+1
02661 enddo
02662
02663
02664 flag = .false.
02665 i = 1
02666 do while (i < nis .and. .not.flag)
02667 j = 2
02668 do while (j < njs .and. .not.flag)
02669 if (abs(Xsrc(i,j)-Xsrc(i,1)) > eps) then
02670 write(s_logunit,F06) ' ERROR Xsrc not regular lat,lon ',i,j, &
02671 Xsrc(i,j),Xsrc(1,j)
02672 flag = .true.
02673 error = .true.
02674 endif
02675 j = j+1
02676 enddo
02677 i = i+1
02678 enddo
02679
02680 flag = .false.
02681 j = 1
02682 do while (j < njs .and. .not.flag)
02683 i = 2
02684 do while (i < nis .and. .not.flag)
02685 if (abs(Ysrc(i,j)-Ysrc(1,j)) > eps) then
02686 write(s_logunit,F06) ' ERROR Ysrc not regular lat,lon ',i,j, &
02687 Ysrc(i,j),Ysrc(1,j)
02688 flag = .true.
02689 error = .true.
02690 endif
02691 i = i+1
02692 enddo
02693 j = j+1
02694 enddo
02695 endif
02696
02697 if (error) then
02698 call shr_map_abort(subName//' ERROR ')
02699 if (present(rc)) rc = 1
02700 endif
02701
02702 end subroutine shr_map_checkGrids_dest
02703
02704
02705
02706
02707
02708
02709
02710
02711
02712
02713
02714
02715
02716
02717
02718
02719 subroutine shr_map_checkWgts_global(Msrc,Mdst,map)
02720
02721 implicit none
02722
02723
02724 integer(SHR_KIND_IN) ,intent(in) :: Msrc(:,:)
02725 integer(SHR_KIND_IN) ,intent(in) :: Mdst(:,:)
02726 type(shr_map_mapType),intent(in) :: map
02727
02728
02729
02730
02731 integer(SHR_KIND_IN) :: i,j,nis,njs,nid,njd,n
02732 integer(SHR_KIND_IN) :: ic1,ic2,ic3,ic4,ic5
02733 logical :: error
02734 real(SHR_KIND_R8),allocatable :: Csrc(:,:)
02735 real(SHR_KIND_R8),allocatable :: Cdst(:,:)
02736
02737
02738 character(*),parameter :: subName = "('shr_map_checkWgts_global') "
02739 character(*),parameter :: F00 = "('(shr_map_checkWgts_global) ',a) "
02740 character(*),parameter :: F01 = "('(shr_map_checkWgts_global) ',a,i8) "
02741 character(*),parameter :: F02 = "('(shr_map_checkWgts_global) ',a,3i8) "
02742 character(*),parameter :: F03 = "('(shr_map_checkWgts_global) ',a,i8,a) "
02743
02744
02745
02746 error = .false.
02747
02748 if (debug > 0) call shr_map_print(map)
02749
02750 if (map%nwts < 1) then
02751 if (s_loglev > 0) write(s_logunit,F00) 'WARNING map size is zero'
02752 endif
02753
02754 if (size(map%wgts) /= map%nwts .or. &
02755 size(map%isrc) /= map%nwts .or. &
02756 size(map%idst) /= map%nwts) then
02757 call shr_map_abort(subName//'ERROR sizes inconsistent')
02758 endif
02759
02760
02761 nis = size(Msrc,1)
02762 njs = size(Msrc,2)
02763 nid = size(Mdst,1)
02764 njd = size(Mdst,2)
02765
02766 allocate(Csrc(nis,njs))
02767 allocate(Cdst(nid,njd))
02768
02769 Csrc = c0
02770 Cdst = c0
02771
02772 do n = 1,map%nwts
02773 call shr_map_1dto2d(map%isrc(n),nis,njs,i,j)
02774 Csrc(i,j) = c1
02775 call shr_map_1dto2d(map%idst(n),nid,njd,i,j)
02776 Cdst(i,j) = Cdst(i,j) + map%wgts(n)
02777 enddo
02778
02779 ic1 = 0
02780 ic2 = 0
02781 ic3 = 0
02782 ic4 = 0
02783 ic5 = 0
02784 do j=1,njs
02785 do i=1,nis
02786 if (Msrc(i,j) /= 0) then
02787 if (abs(Csrc(i,j)-c1) < eps) then
02788 ic1 = ic1 + 1
02789 else
02790 ic2 = ic2 + 1
02791 endif
02792 else
02793 if (abs(Csrc(i,j)-c1) < eps) then
02794 ic3 = ic3 + 1
02795 else
02796 ic5 = ic5 + 1
02797 endif
02798 endif
02799 enddo
02800 enddo
02801
02802 if (debug > 0 .and. s_loglev > 0) then
02803 write(s_logunit,F01) ' total number of SRC points : ',nis*njs
02804 write(s_logunit,F01) ' wgts from SRC TRUE points; used : ',ic1
02805 write(s_logunit,F01) ' wgts from SRC TRUE points; not used : ',ic2
02806 write(s_logunit,F01) ' wgts from SRC FALSE points; used : ',ic3
02807 write(s_logunit,F01) ' wgts from SRC FALSE points; not used : ',ic5
02808 endif
02809
02810 ic1 = 0
02811 ic2 = 0
02812 ic3 = 0
02813 ic4 = 0
02814 ic5 = 0
02815 do j=1,njd
02816 do i=1,nid
02817 if (Mdst(i,j) /= 0) then
02818 if (abs(Cdst(i,j)-c1) < eps) then
02819 ic1 = ic1 + 1
02820 else
02821 ic2 = ic2 + 1
02822 endif
02823 else
02824 if (abs(Cdst(i,j)-c1) < eps) then
02825 ic3 = ic3 + 1
02826 elseif (abs(Cdst(i,j)) < eps) then
02827 ic4 = ic4 + 1
02828 else
02829 ic5 = ic5 + 1
02830 endif
02831 endif
02832 enddo
02833 enddo
02834
02835
02836 if (debug > 0 .and. s_loglev > 0) then
02837 write(s_logunit,F01) ' total number of DST points : ',nid*njd
02838 write(s_logunit,F01) ' sum wgts for DST TRUE points; one : ',ic1
02839 if (ic2 > 0) then
02840 write(s_logunit,F03) ' sum wgts for DST TRUE points; not : ',ic2,' **-WARNING-**'
02841 else
02842 write(s_logunit,F01) ' sum wgts for DST TRUE points; not : ',ic2
02843 endif
02844 write(s_logunit,F01) ' sum wgts for DST FALSE points; one : ',ic3
02845 write(s_logunit,F01) ' sum wgts for DST FALSE points; zero : ',ic4
02846 write(s_logunit,F01) ' sum wgts for DST FALSE points; not : ',ic5
02847 endif
02848
02849 deallocate(Csrc)
02850 deallocate(Cdst)
02851
02852 if (error) call shr_map_abort(subName//' ERROR invalid weights')
02853
02854 end subroutine shr_map_checkWgts_global
02855
02856
02857
02858
02859
02860
02861
02862
02863
02864
02865
02866
02867
02868
02869
02870
02871
02872
02873
02874
02875 subroutine shr_map_getWts(Xdst,Ydst,Xsrc,Ysrc,pti,ptj,ptw,pnum,units)
02876
02877 implicit none
02878
02879
02880
02881
02882
02883 real(SHR_KIND_R8) ,intent(in) :: Xdst,Ydst
02884 real(SHR_KIND_R8) ,intent(in) :: Xsrc(:,:),Ysrc(:,:)
02885 integer(SHR_KIND_IN),intent(out):: pti(:),ptj(:)
02886 real(SHR_KIND_R8) ,intent(out):: ptw(:)
02887 integer(SHR_KIND_IN),intent(out):: pnum
02888 character(len=*),optional,intent(in) :: units
02889
02890
02891 integer(SHR_KIND_IN) :: isize,jsize
02892 integer(SHR_KIND_IN) :: i,j
02893 integer(SHR_KIND_IN) :: n
02894 integer(SHR_KIND_IN) :: il,ir
02895 integer(SHR_KIND_IN) :: jl,ju
02896 integer(SHR_KIND_IN) :: pmax
02897 real(SHR_KIND_R8) :: xsl,xsr
02898 real(SHR_KIND_R8) :: ysl,ysu
02899 real(SHR_KIND_R8) :: xd,yd
02900 real(SHR_KIND_R8) :: dx,dy,dx1,dy1
02901 real(SHR_KIND_R8) :: csize
02902 real(SHR_KIND_R8) :: rmin,rmax
02903 real(SHR_KIND_R8) :: cpole
02904 integer(SHR_KIND_IN) :: pole
02905
02906
02907 character(*),parameter :: subName = "('shr_map_getWts') "
02908 character(*),parameter :: F00 = "('(shr_map_getWts) ',a) "
02909 character(*),parameter :: F02 = "('(shr_map_getWts) ',a,4g20.13) "
02910 character(*),parameter :: F03 = "('(shr_map_getWts) ',a,2g20.13) "
02911 character(*),parameter :: F04 = "('(shr_map_getWts) ',a,4i8) "
02912 character(*),parameter :: F05 = "('(shr_map_getWts) ',a,3g20.13) "
02913
02914
02915
02916 pmax = size(pti,1)
02917
02918
02919 if (present(units)) then
02920 if (trim(units) == 'degrees') then
02921 csize = 360._SHR_KIND_R8
02922 elseif (trim(units) == 'radians') then
02923 csize = c2*pi
02924 else
02925 call shr_sys_abort(subName//' ERROR in optional units = '//trim(units))
02926 endif
02927 else
02928 csize = 360._SHR_KIND_R8
02929 if (shr_map_checkRad(Ysrc)) csize = c2*pi
02930 endif
02931
02932 isize = size(Xsrc,1)
02933 jsize = size(Xsrc,2)
02934 pti = 0
02935 ptj = 0
02936 ptw = c0
02937
02938 cpole = csize/(c2*c2)
02939
02940 xd = Xdst
02941 yd = Ydst
02942
02943 if (yd > cpole + 1.0e-3 .or. &
02944 yd < -cpole - 1.0e-3) then
02945 write(s_logunit,*) trim(subname),' ERROR: yd outside bounds ',yd
02946 call shr_map_abort(subName//' ERROR yd outside 90 degree bounds')
02947 endif
02948 if (yd > cpole) yd = cpole
02949 if (yd < -cpole) yd = -cpole
02950
02951 call shr_map_find4corners(Xdst,yd,Xsrc,Ysrc,il,ir,jl,ju)
02952
02953
02954 pnum = 4
02955 pole = 0
02956 xsl = Xsrc(il,1)
02957 xsr = Xsrc(ir,1)
02958 ysl = Ysrc(1,jl)
02959 ysu = Ysrc(1,ju)
02960
02961 if (Xdst < Xsrc(1,1) .or. Xdst > Xsrc(isize,1)) then
02962 xsl = mod(Xsrc(il,1),csize)
02963 xsr = mod(Xsrc(ir,1),csize)
02964 xd = mod(Xdst ,csize)
02965 if (xsl > xd) xsl = xsl - csize
02966 if (xsr < xd) xsr = xsr + csize
02967 endif
02968
02969 if (yd > Ysrc(1,jsize)) then
02970 if (dopole) then
02971 pnum = isize+2
02972 pole = 1
02973 endif
02974 ysu = cpole
02975 elseif (yd < Ysrc(1,1)) then
02976 if (dopole) then
02977 pnum = isize+2
02978 pole = 2
02979 endif
02980 ysl = -cpole
02981 endif
02982
02983
02984 dx = (xsr-xsl)
02985 dy = (ysu-ysl)
02986 dx1 = ( xd-xsl)
02987 dy1 = ( yd-Ysl)
02988
02989 if (dx1 > dx .and. dx1-dx < 1.0e-7 ) dx1 = dx
02990 if (dy1 > dy .and. dy1-dy < 1.0e-7 ) dy1 = dy
02991
02992 if (dx <= c0 .or. dy <= c0 .or. dx1 > dx .or. dy1 > dy) then
02993 write(s_logunit,*) ' '
02994 write(s_logunit,F02) 'ERROR in dx,dy: ',dx1,dx,dy1,dy
02995 write(s_logunit,F03) ' dst: ',Xdst,Ydst
02996 write(s_logunit,F04) ' ind: ',il,ir,jl,ju
02997 write(s_logunit,F02) ' dis: ',dx1,dx,dy1,dy
02998 write(s_logunit,F05) ' x3 : ',xsl,xd,xsr
02999 write(s_logunit,F05) ' y3 : ',ysl,yd,ysu
03000 write(s_logunit,*) ' '
03001 call shr_map_abort(subName//' ERROR in dx,dy calc')
03002 stop
03003 return
03004 endif
03005
03006 dx1 = dx1 / dx
03007 dy1 = dy1 / dy
03008
03009 if (pnum > pmax) then
03010 call shr_sys_abort(subName//' ERROR pti not big enough')
03011 endif
03012
03013 if (pole == 0) then
03014
03015 pti(1) = il
03016 pti(2) = ir
03017 pti(3) = il
03018 pti(4) = ir
03019
03020 ptj(1) = jl
03021 ptj(2) = jl
03022 ptj(3) = ju
03023 ptj(4) = ju
03024
03025 ptw(1) = (c1-dx1)*(c1-dy1)
03026 ptw(2) = ( dx1)*(c1-dy1)
03027 ptw(3) = (c1-dx1)*( dy1)
03028 ptw(4) = ( dx1)*( dy1)
03029
03030 elseif (pole == 1) then
03031
03032 pti(1) = il
03033 pti(2) = ir
03034
03035 ptj(1) = jl
03036 ptj(2) = jl
03037
03038 ptw(1) = (c1-dx1)*(c1-dy1)
03039 ptw(2) = ( dx1)*(c1-dy1)
03040
03041 do n=1,isize
03042 pti(2+n) = n
03043 ptj(2+n) = ju
03044 ptw(2+n) = (dy1)/real(isize,SHR_KIND_R8)
03045 enddo
03046
03047 elseif (pole == 2) then
03048
03049 pti(1) = il
03050 pti(2) = ir
03051
03052 ptj(1) = ju
03053 ptj(2) = ju
03054
03055 ptw(1) = (c1-dx1)*( dy1)
03056 ptw(2) = ( dx1)*( dy1)
03057
03058 do n=1,isize
03059 pti(2+n) = n
03060 ptj(2+n) = jl
03061 ptw(2+n) = (c1-dy1)/real(isize,SHR_KIND_R8)
03062 enddo
03063
03064 else
03065
03066 write(s_logunit,F00) ' ERROR illegal pnum situation '
03067 call shr_map_abort(subName//' ERROR illegal pnum situation')
03068
03069 endif
03070
03071 end subroutine shr_map_getWts
03072
03073
03074
03075 subroutine shr_map_find4corners(Xdst,Ydst,Xsrc,Ysrc,il,ir,jl,ju)
03076
03077
03078
03079
03080 implicit none
03081
03082
03083
03084 real(SHR_KIND_R8) ,intent(in) :: Xdst,Ydst
03085 real(SHR_KIND_R8) ,intent(in) :: Xsrc(:,:),Ysrc(:,:)
03086 integer(SHR_KIND_IN),intent(out):: il,ir,jl,ju
03087
03088
03089 integer(SHR_KIND_IN) :: isize,jsize
03090 integer(SHR_KIND_IN) :: im,jm
03091
03092
03093 character(*),parameter :: subName = "('shr_map_find4corners') "
03094 character(*),parameter :: F00 = "('(shr_map_find4corners) ',a,2i8) "
03095
03096
03097
03098 isize = size(Xsrc,1)
03099 jsize = size(Xsrc,2)
03100
03101 if (Xdst < Xsrc(1,1) .or. Xdst > Xsrc(isize,1)) then
03102 il = isize
03103 ir = 1
03104 else
03105
03106 il = 1
03107 ir = isize
03108 do while (ir-il > 1)
03109 im = (ir+il)/2
03110 if (Xdst >= Xsrc(im,1)) then
03111 il = im
03112 else
03113 ir = im
03114 endif
03115 enddo
03116 endif
03117
03118 if (Ydst > Ysrc(1,jsize)) then
03119 jl = jsize
03120 ju = jsize
03121 elseif (Ydst < Ysrc(1,1)) then
03122 jl = 1
03123 ju = 1
03124 else
03125
03126 jl = 1
03127 ju = jsize
03128 do while (ju-jl > 1)
03129 jm = (ju+jl)/2
03130 if (Ydst >= Ysrc(1,jm)) then
03131 jl = jm
03132 else
03133 ju = jm
03134 endif
03135 enddo
03136 endif
03137
03138 end subroutine shr_map_find4corners
03139
03140
03141
03142 subroutine shr_map_findnn(Xdst,Ydst,Xsrc,Ysrc,Msrc,inn,jnn)
03143
03144
03145
03146
03147 implicit none
03148
03149
03150
03151 real(SHR_KIND_R8) ,intent(in) :: Xdst,Ydst
03152 real(SHR_KIND_R8) ,intent(in) :: Xsrc(:,:),Ysrc(:,:)
03153 integer(SHR_KIND_IN),intent(in) :: Msrc(:,:)
03154 integer(SHR_KIND_IN),intent(out):: inn,jnn
03155
03156
03157 integer(SHR_KIND_IN) :: isize,jsize
03158 integer(SHR_KIND_IN) :: i,j
03159 real(SHR_KIND_R8) :: dnn,dist
03160
03161
03162 character(*),parameter :: subName = "('shr_map_findnn') "
03163 character(*),parameter :: F00 = "('(shr_map_findnn) ',a,2i8) "
03164
03165
03166
03167 isize = size(Xsrc,1)
03168 jsize = size(Xsrc,2)
03169
03170 inn = -1
03171 jnn = -1
03172 dnn = -1._SHR_KIND_R8
03173 do j=1,jsize
03174 do i=1,isize
03175 if (Msrc(i,j) /= 0) then
03176 dist = shr_map_finddist(Xdst,Ydst,Xsrc(i,j),Ysrc(i,j))
03177 if (dist < dnn .or. inn < 0) then
03178 dnn = dist
03179 inn = i
03180 jnn = j
03181 endif
03182 endif
03183 enddo
03184 enddo
03185
03186 end subroutine shr_map_findnn
03187
03188
03189
03190 subroutine shr_map_findnnon(dir,Xdst,Ydst,Xsrc,Ysrc,Msrc,inn,jnn)
03191
03192
03193
03194
03195
03196 implicit none
03197
03198
03199
03200 character(*) ,intent(in) :: dir
03201 real(SHR_KIND_R8) ,intent(in) :: Xdst,Ydst
03202 real(SHR_KIND_R8) ,intent(in) :: Xsrc(:,:),Ysrc(:,:)
03203 integer(SHR_KIND_IN),intent(in) :: Msrc(:,:)
03204 integer(SHR_KIND_IN),intent(out):: inn,jnn
03205
03206
03207 integer(SHR_KIND_IN) :: isize,jsize
03208 integer(SHR_KIND_IN) :: il,ir,jl,ju
03209 integer(SHR_KIND_IN) :: n,i,j
03210 integer(SHR_KIND_IN) :: is,js
03211 integer(SHR_KIND_IN) :: i2,j2
03212 real(SHR_KIND_R8) :: dnn,dist,ds
03213
03214
03215 character(*),parameter :: subName = "('shr_map_findnnon') "
03216 character(*),parameter :: F00 = "('(shr_map_findnnon) ',a,2i8) "
03217
03218
03219
03220 isize = size(Xsrc,1)
03221 jsize = size(Xsrc,2)
03222
03223
03224 call shr_map_find4corners(Xdst,Ydst,Xsrc,Ysrc,il,ir,jl,ju)
03225
03226
03227 is = il
03228 js = jl
03229 ds = shr_map_finddist(Xdst,Ydst,Xsrc(il,jl),Ysrc(il,jl))
03230 dist = shr_map_finddist(Xdst,Ydst,Xsrc(ir,jl),Ysrc(ir,jl))
03231 if (dist < ds) then
03232 is = ir
03233 js = jl
03234 ds = dist
03235 endif
03236 dist = shr_map_finddist(Xdst,Ydst,Xsrc(il,ju),Ysrc(il,ju))
03237 if (dist < ds) then
03238 is = il
03239 js = ju
03240 ds = dist
03241 endif
03242 dist = shr_map_finddist(Xdst,Ydst,Xsrc(ir,ju),Ysrc(ir,ju))
03243 if (dist < ds) then
03244 is = ir
03245 js = ju
03246 ds = dist
03247 endif
03248
03249 inn = -1
03250 jnn = -1
03251 dnn = -1._SHR_KIND_R8
03252 i2 = 0
03253 j2 = 0
03254
03255 if (trim(dir) == 'i') then
03256
03257 do while (inn < 0 .and. j2 < jsize)
03258 do n=1,2
03259 if (n == 1) j = min(js + j2,jsize)
03260 if (n == 2) j = max(js - j2,1)
03261 do i=1,isize
03262 if (Msrc(i,j) /= 0) then
03263 dist = shr_map_finddist(Xdst,Ydst,Xsrc(i,j),Ysrc(i,j))
03264 if (dist < dnn .or. inn < 0) then
03265 dnn = dist
03266 inn = i
03267 jnn = j
03268 endif
03269 endif
03270 enddo
03271 enddo
03272 j2 = j2 + 1
03273 enddo
03274 elseif (trim(dir) == 'j') then
03275
03276 do while (inn < 0 .and. i2 < isize)
03277 do n=1,2
03278 if (n == 1) i = min(is + i2,isize)
03279 if (n == 2) i = max(is - i2,1)
03280 do j=1,jsize
03281 if (Msrc(i,j) /= 0) then
03282 dist = shr_map_finddist(Xdst,Ydst,Xsrc(i,j),Ysrc(i,j))
03283 if (dist < dnn .or. inn < 0) then
03284 dnn = dist
03285 inn = i
03286 jnn = j
03287 endif
03288 endif
03289 enddo
03290 enddo
03291 i2 = i2 + 1
03292 enddo
03293 else
03294 call shr_map_abort(subName//' ERROR illegal dir '//trim(dir))
03295 endif
03296
03297 end subroutine shr_map_findnnon
03298
03299
03300
03301 real(SHR_KIND_R8) function shr_map_finddist(Xdst,Ydst,Xsrc,Ysrc)
03302
03303
03304
03305 implicit none
03306 real(SHR_KIND_R8),intent(in) :: Xdst,Ydst,Xsrc,Ysrc
03307 character(*),parameter :: subName = "('shr_map_finddist') "
03308
03309
03310
03311 shr_map_finddist = sqrt((Ydst-Ysrc)**2 + (Xdst-Xsrc)**2)
03312
03313 end function shr_map_finddist
03314
03315
03316
03317 logical function shr_map_checkRad(Grid)
03318
03319
03320
03321 implicit none
03322 real(SHR_KIND_R8),intent(in) :: Grid(:,:)
03323 character(*),parameter :: subName = "('shr_map_checkRad') "
03324 real(SHR_KIND_R8) :: rmin,rmax
03325
03326
03327
03328 shr_map_checkRad = .false.
03329 rmin = minval(Grid)
03330 rmax = maxval(Grid)
03331 if ((rmax - rmin) < 1.01_SHR_KIND_R8*c2*pi) shr_map_checkRad = .true.
03332
03333 end function shr_map_checkRad
03334
03335
03336
03337 subroutine shr_map_1dto2d(gid,ni,nj,i,j)
03338
03339
03340
03341
03342 implicit none
03343 integer(SHR_KIND_IN),intent(in) :: gid,ni,nj
03344 integer(SHR_KIND_IN),intent(out):: i,j
03345 character(*),parameter :: subName = "('shr_map_1dto2d') "
03346 character(*),parameter :: F01 = "('(shr_map_1dto2d) ',a,3i8)"
03347
03348
03349
03350 if (gid < 1 .or. gid > ni*nj) then
03351 write(s_logunit,F01) 'ERROR: illegal gid ',gid,ni,nj
03352 call shr_map_abort(subName//' ERROR')
03353 endif
03354 j = (gid-1)/ni+1
03355 i = mod(gid-1,ni)+1
03356
03357 end subroutine shr_map_1dto2d
03358
03359
03360
03361 subroutine shr_map_2dto1d(gid,ni,nj,i,j)
03362
03363
03364
03365
03366 implicit none
03367 integer(SHR_KIND_IN),intent(in) :: ni,nj,i,j
03368 integer(SHR_KIND_IN),intent(out):: gid
03369 character(*),parameter :: subName = "('shr_map_2dto1d') "
03370 character(*),parameter :: F01 = "('(shr_map_2dto1d) ',a,4i8)"
03371
03372
03373
03374 if (i < 1 .or. i > ni .or. j < 1 .or. j > nj) then
03375 write(s_logunit,F01) 'ERROR: illegal i,j ',i,ni,j,nj
03376 call shr_map_abort(subName//' ERROR')
03377 endif
03378 gid = (j-1)*ni + i
03379
03380 end subroutine shr_map_2dto1d
03381
03382
03383
03384 end module shr_map_mod
03385