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 MODULE shr_ncio_mod
00049
00050
00051
00052 use shr_kind_mod, only: SHR_KIND_CS, SHR_KIND_CL, SHR_KIND_IN, &
00053 SHR_KIND_R8, SHR_KIND_I8, &
00054 SHR_KIND_R8
00055 use shr_sys_mod, only: shr_sys_flush
00056 use shr_const_mod, only: shr_const_spval
00057 use shr_log_mod, only: s_loglev => shr_log_Level
00058 use shr_log_mod, only: s_logunit => shr_log_Unit
00059 use netcdf
00060
00061 implicit none
00062
00063 private
00064
00065
00066
00067 public :: shr_ncio_descripType
00068
00069
00070
00071 public :: shr_ncio_descripSetDefault
00072 public :: shr_ncio_descripInit
00073 public :: shr_ncio_descripPutData
00074 public :: shr_ncio_descripName
00075 public :: shr_ncio_descripGetString
00076 public :: shr_ncio_descripGetInteger
00077 public :: shr_ncio_descripGetLogical
00078 public :: shr_ncio_descripGetRealR8
00079 public :: shr_ncio_descripRead
00080 public :: shr_ncio_descripWrite
00081 public :: shr_ncio_open
00082 public :: shr_ncio_close
00083 public :: shr_ncio_setDebug
00084 public :: shr_ncio_setAbort
00085
00086
00087
00088
00089
00090
00091
00092
00093
00094 private :: shr_ncio_logical2Int
00095 private :: shr_ncio_int2Logical
00096 private :: shr_ncio_abort
00097
00098
00099 integer, parameter :: shr_ncio_integerFill = -99999
00100 character(len=*), parameter :: shr_ncio_stringFill = '----NOTSET----'
00101 real(SHR_KIND_R8), parameter :: shr_ncio_realR8Fill = shr_const_spval
00102 integer, parameter :: maxDims = 1
00103
00104
00105 type shr_ncio_descripType
00106 private
00107 character(SHR_KIND_CS) :: Name = shr_ncio_stringFill
00108 integer :: XType = shr_ncio_integerFill
00109 integer :: id = shr_ncio_integerFill
00110 integer :: nDims
00111 integer :: DimSizes(maxDims)
00112 character(SHR_KIND_CS) :: DimNames(maxDims)
00113 character(SHR_KIND_CS) :: Units = shr_ncio_stringFill
00114 character(SHR_KIND_CL) :: StringData = shr_ncio_stringFill
00115 character(SHR_KIND_CL) :: ListDescrips = shr_ncio_stringFill
00116 integer :: IntegerData = shr_ncio_integerFill
00117 real(SHR_KIND_R8) :: RealR8Data = shr_ncio_realR8Fill
00118 integer :: IntegerFill = shr_ncio_integerFill
00119 real(SHR_KIND_R8) :: RealR8Fill = shr_ncio_realR8Fill
00120 logical :: LogicalData
00121 integer, pointer :: ListValues(:)
00122 character(SHR_KIND_CL) :: LongName = shr_ncio_stringFill
00123 end type shr_ncio_descripType
00124
00125
00126 integer, parameter :: shr_ncio_integerDataValue = 1
00127 integer, parameter :: shr_ncio_stringDataValue = 2
00128 integer, parameter :: shr_ncio_logicalDataValue = 3
00129 integer, parameter :: shr_ncio_realR8DataValue = 4
00130 logical, save :: doAbort = .true.
00131 integer, save :: debugLevel = 1
00132 character(len=*), parameter :: shrCharacterDimName = "shr_character"
00133
00134
00135 CONTAINS
00136
00137
00138
00139
00140
00141
00142
00143
00144
00145
00146
00147
00148
00149
00150
00151
00152 SUBROUTINE shr_ncio_descripSetDefault( NVars, DescripVars )
00153
00154
00155
00156 implicit none
00157
00158
00159
00160 integer, intent(IN) :: nVars
00161 type(shr_ncio_descripType), intent(INOUT) :: DescripVars(nVars)
00162
00163
00164
00165
00166 character(len=*), parameter :: subName = '(shr_ncio_descripSetDefault) '
00167 integer :: i
00168
00169
00170
00171
00172
00173 do i = 1, NVars
00174 DescripVars(i)%Name = shr_ncio_stringFill
00175 DescripVars(i)%XType = shr_ncio_integerFill
00176 DescripVars(i)%id = shr_ncio_integerFill
00177 DescripVars(i)%Units = shr_ncio_stringFill
00178 DescripVars(i)%StringData = shr_ncio_stringFill
00179 DescripVars(i)%ListDescrips = shr_ncio_stringFill
00180 DescripVars(i)%IntegerData = shr_ncio_integerFill
00181 DescripVars(i)%RealR8Data = shr_ncio_realR8Fill
00182 DescripVars(i)%IntegerFill = shr_ncio_integerFill
00183 DescripVars(i)%RealR8Fill = shr_ncio_realR8Fill
00184 DescripVars(i)%LongName = shr_ncio_stringFill
00185 end do
00186
00187 END SUBROUTINE shr_ncio_descripSetDefault
00188
00189
00190
00191
00192
00193
00194
00195
00196
00197
00198
00199
00200
00201
00202
00203
00204
00205
00206
00207
00208
00209
00210
00211
00212 SUBROUTINE shr_ncio_descripInit( DescripVar, Name, LongName, Units, &
00213 StringData, IntegerData, LogicalData, &
00214 RealR8Data, IntegerFill, &
00215 RealR8Fill, ListDescrips, &
00216 ListIntValues, nDims, dimSizes )
00217
00218
00219
00220 use shr_string_mod, only: shr_string_listIsValid, shr_string_listGetNum
00221
00222 implicit none
00223
00224
00225
00226 type(shr_ncio_descripType), intent(INOUT) :: DescripVar
00227 character(len=*), intent(IN) :: Name
00228 character(len=*), intent(IN), optional :: LongName
00229 character(len=*), intent(IN), optional :: Units
00230 logical, intent(IN), optional, target :: StringData
00231 logical, intent(IN), optional, target :: IntegerData
00232 logical, intent(IN), optional, target :: LogicalData
00233 logical, intent(IN), optional, target :: RealR8Data
00234 real(SHR_KIND_R8), intent(IN), optional :: RealR8Fill
00235 integer, intent(IN), optional, target :: IntegerFill
00236
00237 character(len=*), intent(IN), optional :: ListDescrips
00238
00239 integer, intent(IN), optional :: ListIntValues(:)
00240 integer, intent(IN), optional :: nDims
00241 integer, intent(IN), optional :: dimSizes(:)
00242
00243
00244
00245
00246 character(len=*), parameter :: subName = '(shr_ncio_descripInit) '
00247 logical :: NotSet
00248 integer :: nList
00249
00250
00251
00252
00253
00254
00255
00256
00257
00258 if ( (PRESENT(StringData) .and. PRESENT(IntegerData)) .or. &
00259 (PRESENT(StringData) .and. PRESENT(LogicalData)) .or. &
00260 (PRESENT(StringData) .and. PRESENT(RealR8Data )) .or. &
00261 (PRESENT(IntegerData) .and. PRESENT(LogicalData)) .or. &
00262 (PRESENT(IntegerData) .and. PRESENT(RealR8Data )) .or. &
00263 (PRESENT(LogicalData) .and. PRESENT(RealR8Data )) )then
00264 call shr_ncio_abort( subName//': can not set more than one variable type' )
00265 end if
00266 if ( PRESENT(nDims) .or. PRESENT(dimSizes) )then
00267 call shr_ncio_abort( subName//': currently nDims and dimSizes are NOT implemented' )
00268 end if
00269 if ( PRESENT(nDims) .and. .not. PRESENT(dimSizes) &
00270 .or. (.not. PRESENT(nDims) .and. PRESENT(dimSizes) ) )then
00271 call shr_ncio_abort( subName//': if nDims set so must also dimSizes' )
00272 else if ( PRESENT(nDims) .and. PRESENT(dimSizes) )then
00273 if ( nDims /= size(dimSizes) )then
00274 call shr_ncio_abort( subName//': if nDims NOT set to same dimensionality as dimSizes' )
00275 end if
00276 if ( nDims > maxDims )then
00277 call shr_ncio_abort( subName//': nDims > size of max dimensions' )
00278 end if
00279 DescripVar%nDims = nDims
00280 DescripVar%dimSizes(:) = dimSizes(:nDims)
00281 end if
00282
00283
00284 if ( DescripVar%Name == shr_ncio_stringFill )then
00285 DescripVar%Name = Name
00286
00287 else if ( trim(Name) /= trim(DescripVar%Name) )then
00288 call shr_ncio_abort( subName//': bad Name: '//trim(Name)// &
00289 ' sent to variable already defined as:'// &
00290 trim(DescripVar%Name) )
00291
00292 end if
00293
00294 if ( PRESENT(LongName) ) DescripVar%LongName = LongName
00295 if ( PRESENT(Units) ) DescripVar%Units = Units
00296 NotSet = .true.
00297
00298 if ( PRESENT(StringData) )then
00299 NotSet = .false.
00300 DescripVar%XType = shr_ncio_stringDataValue
00301 if ( .not. PRESENT(nDims) )then
00302 DescripVar%nDims = 1
00303 DescripVar%dimSizes(1) = len(DescripVar%StringData)
00304 end if
00305 DescripVar%dimNames(1) = shrCharacterDimName
00306 if ( .not. PRESENT(Units) ) DescripVar%Units = "string"
00307 end if
00308
00309 if ( PRESENT(IntegerData) )then
00310 if ( .not. NotSet ) call shr_ncio_abort( subName//': trying to define '// &
00311 'to more than one data-type' )
00312 NotSet = .false.
00313 DescripVar%XType = shr_ncio_integerDataValue
00314 if ( .not. PRESENT(nDims) )then
00315 DescripVar%nDims = 0
00316 end if
00317 if ( PRESENT(IntegerFill) )then
00318 DescripVar%IntegerFill = IntegerFill
00319 DescripVar%IntegerData = IntegerFill
00320 end if
00321
00322 if ( PRESENT(ListDescrips) )then
00323 if ( .not. PRESENT(ListIntValues) )then
00324 call shr_ncio_abort( subName//': setting ListDescrips without '// &
00325 'setting ListIntValues' )
00326 end if
00327 if ( .not. shr_string_listIsValid( ListDescrips ) )then
00328 call shr_ncio_abort( subName//': ListDescrips is not a valid '// &
00329 'list of descriptions' )
00330 end if
00331 nList = shr_string_listGetNum( ListDescrips )
00332 if ( size(ListIntValues) /= nList )then
00333 call shr_ncio_abort( subName//': number of list descriptions '// &
00334 'inconsistent with number of list integer values' )
00335 end if
00336 allocate( DescripVar%ListValues(nList) )
00337 DescripVar%ListDescrips = ListDescrips
00338 DescripVar%ListValues(:) = ListIntValues(:)
00339 else
00340 if ( PRESENT(ListIntValues) )then
00341 call shr_ncio_abort( subName//': setting ListIntValues '// &
00342 'without setting ListDescrips' )
00343 end if
00344 end if
00345 else
00346 if ( PRESENT(IntegerFill) )then
00347 call shr_ncio_abort( subName//': setting integer FillValue '// &
00348 'without setting IntegerData' )
00349 end if
00350 if ( PRESENT(ListDescrips) .or. PRESENT(ListIntValues) )then
00351 call shr_ncio_abort( subName//': setting ListDescrips or '// &
00352 'ListIntValues without setting IntegerData' )
00353 end if
00354 end if
00355
00356 if ( PRESENT(LogicalData) )then
00357 if ( .not. NotSet ) call shr_ncio_abort( subName//': trying '// &
00358 'to define to more than one data-type' )
00359 NotSet = .false.
00360 DescripVar%XType = shr_ncio_logicalDataValue
00361 if ( .not. PRESENT(nDims) )then
00362 DescripVar%nDims = 0
00363 end if
00364 if ( .not. PRESENT(Units) ) DescripVar%Units = &
00365 "logical flag (0=false)"
00366 end if
00367
00368 if ( PRESENT(RealR8Data) )then
00369 if ( .not. NotSet ) call shr_ncio_abort( &
00370 subName//': trying to define to more than one data-type' )
00371 NotSet = .false.
00372 DescripVar%XType = shr_ncio_realR8DataValue
00373 if ( .not. PRESENT(nDims) )then
00374 DescripVar%nDims = 0
00375 end if
00376 if ( PRESENT(RealR8Fill) )then
00377 DescripVar%RealR8Fill = RealR8Fill
00378 DescripVar%RealR8Data = RealR8Fill
00379 end if
00380 else
00381 if ( PRESENT(RealR8Fill) )then
00382 call shr_ncio_abort( subName//': setting realr8 FillValue '// &
00383 'without setting RealR8Data' )
00384 end if
00385 end if
00386 if ( NotSet ) call shr_ncio_abort( subName//': called without giving '// &
00387 'a value to set' )
00388
00389 END SUBROUTINE shr_ncio_descripInit
00390
00391
00392
00393
00394
00395
00396
00397
00398
00399
00400
00401
00402
00403
00404 SUBROUTINE shr_ncio_descripPutData( DescripVar, Name, StringData, &
00405 IntegerData, LogicalData, RealR8Data )
00406
00407 implicit none
00408
00409
00410
00411 type(shr_ncio_descripType), intent(INOUT) :: DescripVar
00412 character(len=*), intent(IN) :: Name
00413 character(len=*), optional, intent(IN), target :: StringData
00414 integer, target, optional, intent(IN) :: IntegerData
00415 logical, target, optional, intent(IN) :: LogicalData
00416 real(SHR_KIND_R8), optional,intent(IN), target :: RealR8Data
00417
00418
00419
00420
00421 character(len=*), parameter :: subName = '(shr_ncio_descripPutData) '
00422 logical :: NotSet
00423
00424
00425
00426
00427
00428
00429 if ( (PRESENT(StringData) .and. PRESENT(IntegerData)) .or. &
00430 (PRESENT(StringData) .and. PRESENT(LogicalData)) .or. &
00431 (PRESENT(StringData) .and. PRESENT(RealR8Data )) .or. &
00432 (PRESENT(IntegerData) .and. PRESENT(LogicalData)) .or. &
00433 (PRESENT(IntegerData) .and. PRESENT(RealR8Data )) .or. &
00434 (PRESENT(LogicalData) .and. PRESENT(RealR8Data )) )then
00435 call shr_ncio_abort( subName//': can not set more than one variable type' )
00436 end if
00437
00438 if ( DescripVar%Name == shr_ncio_stringFill )then
00439 call shr_ncio_abort( subName//': descrip variable has not been defined '// &
00440 'yet with shr_ncio_descripInit' )
00441 else if ( trim(Name) /= trim(DescripVar%Name) )then
00442 call shr_ncio_abort( subName//': bad Name: '//trim(Name)// &
00443 ' sent to variable already defined as:'// &
00444 trim(DescripVar%Name) )
00445 end if
00446 NotSet = .true.
00447
00448
00449
00450
00451
00452
00453 if ( PRESENT(StringData) )then
00454 NotSet = .false.
00455 if ( DescripVar%XType /= shr_ncio_stringDataValue )then
00456 call shr_ncio_abort( subName//': Setting descrip variable to string '// &
00457 'which is wrong variable type' )
00458 end if
00459 if ( len_trim(StringData) > len(DescripVar%StringData) )then
00460 call shr_ncio_abort( subName//': Length of input string data longer '// &
00461 'than storage size of DescripVar type' )
00462 end if
00463 DescripVar%StringData(1:len(DescripVar%StringData)) = ' '
00464 DescripVar%StringData(:len_trim(StringData)) = trim(StringData)
00465 end if
00466
00467 if ( PRESENT(IntegerData) )then
00468 NotSet = .false.
00469 if ( DescripVar%XType /= shr_ncio_integerDataValue )then
00470 call shr_ncio_abort( subName//': Setting descrip variable to integer '// &
00471 'which is wrong variable type' )
00472 end if
00473 DescripVar%IntegerData = IntegerData
00474 end if
00475
00476 if ( PRESENT(LogicalData) )then
00477 NotSet = .false.
00478 if ( DescripVar%XType /= shr_ncio_logicalDataValue )then
00479 call shr_ncio_abort( subName//': Setting descrip variable to logical '// &
00480 'which is wrong variable type' )
00481 end if
00482 DescripVar%LogicalData = LogicalData
00483 end if
00484
00485 if ( PRESENT(RealR8Data) )then
00486 NotSet = .false.
00487 if ( DescripVar%XType /= shr_ncio_realR8DataValue )then
00488 call shr_ncio_abort( subName//': Setting descrip variable to realr8 '// &
00489 'which is wrong variable type' )
00490 end if
00491 DescripVar%RealR8Data = RealR8Data
00492 end if
00493
00494 if ( NotSet ) call shr_ncio_abort( subName//': called without giving a '// &
00495 'value to set' )
00496
00497 END SUBROUTINE shr_ncio_descripPutData
00498
00499
00500
00501
00502
00503
00504
00505
00506
00507
00508
00509
00510 FUNCTION shr_ncio_descripName( DescripVar )
00511
00512 implicit none
00513
00514
00515
00516 type(shr_ncio_descripType), intent(IN) :: DescripVar
00517 character(len=SHR_KIND_CS) :: shr_ncio_descripName
00518
00519
00520
00521
00522
00523
00524
00525 shr_ncio_descripName = trim(DescripVar%Name)
00526
00527 END FUNCTION shr_ncio_descripName
00528
00529
00530
00531
00532
00533
00534
00535
00536
00537
00538
00539
00540 FUNCTION shr_ncio_descripGetString( DescripVar )
00541
00542 implicit none
00543
00544
00545
00546 type(shr_ncio_descripType), intent(IN) :: DescripVar
00547 character(len=SHR_KIND_CL) :: shr_ncio_descripGetString
00548
00549
00550
00551
00552 character(len=*), parameter :: subName = '(shr_ncio_descripGetString) '
00553
00554
00555
00556
00557
00558
00559 if ( DescripVar%Name == shr_ncio_stringFill )then
00560 call shr_ncio_abort( subName//': input shr_ncio description variable '// &
00561 'has not been initializated yet: ' )
00562 end if
00563
00564 if ( DescripVar%XType /= shr_ncio_stringDataValue )then
00565 call shr_ncio_abort( subName//': trying to get a string from a '// &
00566 'different variable type' )
00567 end if
00568 shr_ncio_descripGetString(:) = ' '
00569 shr_ncio_descripGetString(1:len_trim(DescripVar%StringData)) = &
00570 trim(DescripVar%StringData)
00571
00572 if ( shr_ncio_descripGetString== shr_ncio_stringFill )then
00573 call shr_ncio_abort( subName//': Returned string has not been set yet' )
00574 end if
00575
00576 END FUNCTION shr_ncio_descripGetString
00577
00578
00579
00580
00581
00582
00583
00584
00585
00586
00587
00588
00589 integer FUNCTION shr_ncio_descripGetInteger( DescripVar )
00590
00591 implicit none
00592
00593
00594
00595 type(shr_ncio_descripType), intent(IN) :: DescripVar
00596
00597
00598
00599
00600 character(len=*), parameter :: subName = '(shr_ncio_descripGetInteger) '
00601
00602
00603
00604
00605
00606
00607 if ( DescripVar%Name == shr_ncio_stringFill )then
00608 call shr_ncio_abort( subName//': input shr_ncio description '// &
00609 'variable has not been initializated yet: ' )
00610 end if
00611
00612 if ( DescripVar%XType /= shr_ncio_integerDataValue )then
00613 call shr_ncio_abort( subName//': trying to get an integer from a '// &
00614 'different variable type' )
00615 end if
00616
00617 shr_ncio_descripGetInteger = DescripVar%IntegerData
00618 if ( shr_ncio_descripGetInteger == shr_ncio_integerFill )then
00619 call shr_ncio_abort( subName//': Returned integer has not been set yet' )
00620 end if
00621
00622 END FUNCTION shr_ncio_descripGetInteger
00623
00624
00625
00626
00627
00628
00629
00630
00631
00632
00633
00634
00635 logical FUNCTION shr_ncio_descripGetLogical( DescripVar )
00636
00637 implicit none
00638
00639
00640
00641 type(shr_ncio_descripType), intent(IN) :: DescripVar
00642
00643
00644
00645
00646 character(len=*), parameter :: subName = '(shr_ncio_descripGetLogical) '
00647
00648
00649
00650
00651
00652
00653 if ( DescripVar%Name == shr_ncio_stringFill )then
00654 call shr_ncio_abort( subName//': input shr_ncio description '// &
00655 'variable has not been initializated yet: ' )
00656 end if
00657
00658 if ( DescripVar%XType /= shr_ncio_logicalDataValue )then
00659 call shr_ncio_abort( subName//': trying to get an logical from a '// &
00660 'different variable type' )
00661 end if
00662 shr_ncio_descripGetLogical = DescripVar%LogicalData
00663
00664 END FUNCTION shr_ncio_descripGetLogical
00665
00666
00667
00668
00669
00670
00671
00672
00673
00674
00675
00676
00677 real(SHR_KIND_R8) FUNCTION shr_ncio_descripGetRealR8( DescripVar )
00678
00679 implicit none
00680
00681
00682
00683 type(shr_ncio_descripType), intent(IN) :: DescripVar
00684
00685
00686
00687
00688 character(len=*), parameter :: subName = '(shr_ncio_descripGetRealR8) '
00689
00690
00691
00692
00693
00694
00695 if ( DescripVar%Name == shr_ncio_stringFill )then
00696 call shr_ncio_abort( subName//': input shr_ncio description variable '// &
00697 'has not been initializated yet: ' )
00698 end if
00699
00700 if ( DescripVar%XType /= shr_ncio_realR8DataValue )then
00701 call shr_ncio_abort( subName//': trying to get an real from a '// &
00702 'different variable type' )
00703 end if
00704
00705 shr_ncio_descripGetRealR8 = DescripVar%RealR8Data
00706 if ( shr_ncio_descripGetRealR8 == shr_ncio_realR8Fill )then
00707 call shr_ncio_abort( subName//': Returned realr8 has not been set yet' )
00708 end if
00709
00710 END FUNCTION shr_ncio_descripGetRealR8
00711
00712
00713
00714
00715
00716
00717
00718
00719
00720
00721
00722
00723 SUBROUTINE shr_ncio_descripRead( ncId, nVars, prefix, mpicom, MasterTask, var )
00724
00725
00726
00727 use shr_string_mod, only: shr_string_lastIndex
00728
00729 use shr_mpi_mod, only: shr_mpi_bcast
00730
00731 implicit none
00732
00733
00734
00735 integer, intent(IN) :: ncId
00736 integer, intent(IN) :: nVars
00737 character(len=*), intent(IN), optional :: prefix
00738 integer, intent(IN), optional :: MPICom
00739 logical, intent(IN), optional :: MasterTask
00740 type(shr_ncio_descripType), intent(INOUT) :: var(:)
00741
00742 character(len=*), parameter :: subName = "(shr_ncio_descripRead) "
00743 logical :: MasterTask2
00744 integer :: rCode
00745 integer :: nDims
00746 integer :: VarDimIds(maxDims)
00747 integer :: dimIds(maxDims)
00748 integer :: type
00749 integer :: i, dim
00750 integer :: nChars
00751 integer :: n
00752 character(SHR_KIND_CL) :: StringData
00753 integer :: IntegerData
00754 real(SHR_KIND_R8) :: RealR8Data
00755 character(len=SHR_KIND_CS) :: prefixUse
00756
00757
00758
00759
00760
00761
00762 if ( present(MasterTask) )then
00763 MasterTask2 = MasterTask
00764 else
00765 MasterTask2 = .true.
00766 end if
00767
00768 if ( present(prefix) )then
00769 prefixUse = prefix
00770 else
00771 prefixUse = ""
00772 end if
00773 if ( MasterTask2 )then
00774
00775
00776
00777 do i = 1, nVars
00778 if ( debugLevel > 1 .and. s_loglev > 0) write(s_logunit,*) 'Read variable: ', trim(var(i)%Name)
00779
00780 if ( trim(var(i)%Name) == shr_ncio_stringFill )then
00781 write(s_logunit,'(a,i3,a,i3)') 'variable number = ', i, ' of ', nVars
00782 call shr_ncio_abort( subName//': variable name not defined -- '// &
00783 'DescripVarSet not called' )
00784 end if
00785
00786 rcode = nf90_inq_varid(ncId,trim(prefixUse)//trim(var(i)%Name),var(i)%id )
00787 call shr_ncio_abort( subName//': variable '// trim(var(i)%Name)//' not found', rcode )
00788
00789 rcode = nf90_inquire_variable(ncId, var(i)%id, nDims=nDims, &
00790 XType=type )
00791 call shr_ncio_abort( subName// ': error on inquiry of '//var(i)%Name, rcode )
00792 if (nDims /= var(i)%nDims )then
00793 write(s_logunit,'(a,a,a,i4,a,i4)') 'Number of dimensions for variable', &
00794 trim(var(i)%name), ' :', nDims, ' expected:', var(i)%nDims
00795 call shr_ncio_abort( subName//': '//var(i)%Name// &
00796 ' dimension size different than expected' )
00797 end if
00798
00799 do dim = 1, nDims
00800 rcode = nf90_inq_dimId(ncId, var(i)%dimNames(dim), dimIds(dim) )
00801 call shr_ncio_abort( subName// ': error gettting dimension', rcode )
00802 end do
00803
00804 if ( nDims > 0 )then
00805 rcode = nf90_inquire_variable(ncId, var(i)%id, dimIds=VarDimIds )
00806 if (rcode /= nf90_noerr) call shr_ncio_abort( subName// &
00807 ': error on inquiry of dimIds'//var(i)%Name )
00808 if ( any(dimIds /= VarDimIds) ) call shr_ncio_abort( subName// &
00809 ': dimIds not correct' )
00810 end if
00811
00812 if (var(i)%XType == shr_ncio_stringDataValue )then
00813 if ( type /= NF90_CHAR ) call shr_ncio_abort( subName//': '// &
00814 var(i)%Name//' not proper type' )
00815 rcode = nf90_get_att(ncId, var(i)%id, "nChars", nChars)
00816 if (rcode /= nf90_noerr) call shr_ncio_abort( subName// &
00817 ': error getting nChars from : '//var(i)%Name )
00818 rcode = nf90_get_var( ncId, varid=var(i)%id, values=StringData, &
00819 count=(/nChars/) )
00820 if (rcode /= nf90_noerr) call shr_ncio_abort( subName// &
00821 ': error on get of '//var(i)%Name )
00822 var(i)%StringData(:) = ' '
00823 var(i)%StringData(:nChars) = StringData(:nChars)
00824
00825 else if (var(i)%XType == shr_ncio_integerDataValue )then
00826 if ( type /= NF90_INT ) call shr_ncio_abort( subName//': '// &
00827 var(i)%Name//' not proper type' )
00828 rcode = nf90_get_var( ncId, var(i)%id, IntegerData)
00829 if (rcode /= nf90_noerr) call shr_ncio_abort( subName// &
00830 ': error on get of '//var(i)%Name )
00831 var(i)%IntegerData = IntegerData
00832
00833 else if (var(i)%XType == shr_ncio_realR8DataValue )then
00834 if ( type /= NF90_DOUBLE) call shr_ncio_abort( subName//': '// &
00835 var(i)%Name//' not proper type' )
00836 rcode = nf90_get_var( ncId, var(i)%id, RealR8Data )
00837 if (rcode /= nf90_noerr) call shr_ncio_abort( subName// &
00838 ': error on get of '//var(i)%Name )
00839 var(i)%RealR8Data = RealR8Data
00840
00841 else if (var(i)%XType == shr_ncio_logicalDataValue )then
00842 if ( type /= NF90_INT ) call shr_ncio_abort( subName//': '// &
00843 var(i)%Name//' not proper type' )
00844 rcode = nf90_get_var( ncId, var(i)%id, IntegerData)
00845 if (rcode /= nf90_noerr) call shr_ncio_abort( subName// &
00846 ': error on get of '//var(i)%Name )
00847 var(i)%LogicalData = shr_ncio_logical2Int( IntegerData )
00848
00849 else
00850 call shr_ncio_abort( subName//': only integer, logical, '// &
00851 'real-r8 or character can not be read for variable ' &
00852 //var(i)%Name )
00853 end if
00854
00855 end do
00856 end if
00857
00858
00859 if ( present(mpicom) )then
00860 if ( debugLevel > 1 .and. s_loglev > 0) write(s_logunit,*) 'Broadcast variables to all tasks'
00861 do i = 1, nVars
00862 if ( var(i)%XType == shr_ncio_stringDataValue )then
00863 call shr_mpi_bcast( var(i)%StringData, mpicom )
00864 else if ( var(i)%XType == shr_ncio_integerDataValue )then
00865 call shr_mpi_bcast( var(i)%IntegerData, mpicom )
00866 else if ( var(i)%XType == shr_ncio_realR8DataValue )then
00867 call shr_mpi_bcast( var(i)%RealR8Data, mpicom )
00868 else if ( var(i)%XType == shr_ncio_logicalDataValue )then
00869 call shr_mpi_bcast( var(i)%LogicalData, mpicom )
00870 else
00871 call shr_ncio_abort( subName//': invalid ncio type: ' )
00872 end if
00873 end do
00874 end if
00875
00876
00877 END SUBROUTINE shr_ncio_descripRead
00878
00879
00880
00881
00882
00883
00884
00885
00886
00887
00888
00889
00890 SUBROUTINE shr_ncio_descripWrite( ncId, nVars, prefix, mpicom, MasterTask, exists, &
00891 var )
00892
00893
00894
00895 use shr_string_mod, only: shr_string_lastindex, shr_string_listGetName, &
00896 shr_string_listGetNum
00897
00898 implicit none
00899
00900
00901
00902 integer, intent(IN) :: ncId
00903 integer, intent(IN) :: nVars
00904 character(len=*), intent(IN), optional :: prefix
00905 integer, intent(IN), optional :: MPICom
00906 logical, intent(IN), optional :: MasterTask
00907 logical, intent(IN) :: exists
00908 type(shr_ncio_descripType), intent(INOUT) :: var(:)
00909
00910
00911
00912
00913 character(len=*), parameter :: subName = "(shr_ncio_descripWrite) "
00914 logical :: MasterTask2
00915 integer :: rcode
00916 integer :: dimIds(maxDims)
00917 integer :: i
00918 integer :: dim
00919 logical :: NotSet
00920 logical :: DimSet
00921 integer :: n
00922 integer :: type
00923 integer :: list
00924 integer :: nList
00925 character(len=SHR_KIND_CL) :: name
00926 character(len=SHR_KIND_CS) :: prefixUse
00927 character(len=*), parameter :: F00=
00928 "(a,' input: nciD=',i3,' nvars=',i3, ' prefix=',a,' master=',l1,' exists=',l1)"
00929
00930
00931
00932
00933
00934 if ( present(MasterTask) )then
00935 MasterTask2 = MasterTask
00936 else
00937 MasterTask2 = .true.
00938 end if
00939
00940 if ( present(prefix) )then
00941 prefixUse = prefix
00942 else
00943 prefixUse = ""
00944 end if
00945
00946 if ( debugLevel > 2 .and. s_loglev > 0) write(s_logunit,F00) subName, ncid, nVars, trim(prefixUse), &
00947 MasterTask2, exists
00948 if ( MasterTask2 )then
00949
00950 if ( exists )then
00951 rcode = nf90_redef(ncId)
00952 call shr_ncio_abort( subName// ': error on redefine output NetCDF file', rcode )
00953 end if
00954
00955
00956
00957 do i = 1, nVars
00958 NotSet = .false.
00959 if ( debugLevel > 1 .and. s_loglev > 0) write(s_logunit,*) 'Write variable: ', trim(var(i)%Name)
00960
00961 if ( exists )then
00962 rcode = nf90_inq_varid(ncId, Name=trim(prefixUse)//trim(var(i)%Name), &
00963 varid=var(i)%id )
00964 if (rcode == nf90_enotvar )then
00965 NotSet = .true.
00966 else if (rcode /= nf90_noerr)then
00967 call shr_ncio_abort( subName//': error getting variable id' )
00968 end if
00969 end if
00970
00971 if ( .not. exists .or. NotSet )then
00972
00973
00974
00975 do dim = 1, var(i)%nDims
00976 DimSet = .false.
00977 rcode = nf90_inq_dimId(ncId, Name=var(i)%dimNames(dim), &
00978 dimId=dimIds(dim))
00979 if ( rcode == nf90_ebaddim )then
00980 DimSet = .true.
00981 else if (rcode /= nf90_noerr)then
00982 call shr_ncio_abort( subName//': error getting correct '// &
00983 'dimension id for :'//trim(var(i)%dimNames(dim)) )
00984 end if
00985 if ( DimSet )then
00986 rcode = nf90_def_dim(ncId, Name=var(i)%dimNames(dim), &
00987 len=SHR_KIND_CL, dimId=dimIds(dim) )
00988 call shr_ncio_abort( subName//': error writing dimension', &
00989 rcode )
00990 end if
00991 end do
00992 if ( var(i)%XType == shr_ncio_stringDataValue )then
00993 type = NF90_CHAR
00994 else if ( var(i)%XType == shr_ncio_integerDataValue .or. &
00995 var(i)%XType == shr_ncio_logicalDataValue )then
00996 type = NF90_INT
00997 else if ( var(i)%XType == shr_ncio_realR8DataValue )then
00998 type = NF90_DOUBLE
00999 else
01000 call shr_ncio_abort( subName// &
01001 ': error on variable definition: '// &
01002 trim(var(i)%Name) )
01003 end if
01004
01005 if ( var(i)%NDims > 0 )then
01006 rcode = nf90_def_var( ncId, trim(prefixUse)//trim(var(i)%Name), &
01007 type, dimIds=dimIds, varid=var(i)%id )
01008 else
01009 rcode = nf90_def_var( ncId, trim(prefixUse)//trim(var(i)%Name), &
01010 type, var(i)%id )
01011 end if
01012 if (rcode /= nf90_noerr) call shr_ncio_abort( subName// &
01013 ': error on variable definition: '// &
01014 trim(var(i)%Name) )
01015 end if
01016
01017
01018
01019 rcode = nf90_put_att( ncId, var(i)%id, "long_name", var(i)%LongName )
01020 if (rcode /= nf90_noerr) call shr_ncio_abort( subName// &
01021 ': error on putting LongName '// &
01022 'attribute on variable: '// &
01023 trim(var(i)%Name) )
01024 rcode = nf90_put_att( ncId, var(i)%id, "units", var(i)%Units )
01025 if (rcode /= nf90_noerr) call shr_ncio_abort( subName// &
01026 ': error on putting Units attribute '// &
01027 'on variable: '//trim(var(i)%Name) )
01028 if ( var(i)%XType == shr_ncio_stringDataValue )then
01029 rcode = nf90_put_att( ncId, var(i)%id, "nChars", &
01030 len_trim(var(i)%StringData) )
01031 if (rcode /= nf90_noerr) call shr_ncio_abort( subName// &
01032 ': error on putting nChars '// &
01033 'attribute on variable: '// &
01034 trim(var(i)%Name) )
01035 end if
01036
01037 if ( var(i)%IntegerFill /= shr_ncio_integerFill )then
01038 rcode = nf90_put_att( ncId, var(i)%id, "_FillValue", &
01039 var(i)%IntegerFill )
01040 if (rcode /= nf90_noerr) call shr_ncio_abort( subName// &
01041 ': error on putting _FillValue '// &
01042 'integer attribute on variable: '// &
01043 var(i)%Name )
01044 rcode = nf90_put_att( ncId, var(i)%id, "missing_value", &
01045 var(i)%IntegerFill )
01046 if (rcode /= nf90_noerr) call shr_ncio_abort( subName// &
01047 ': error on putting missing_value'// &
01048 'integer attribute on variable: '// &
01049 var(i)%Name )
01050 end if
01051
01052 if ( var(i)%RealR8Fill /= shr_ncio_realR8Fill )then
01053 rcode = nf90_put_att( ncId, var(i)%id, "_FillValue", &
01054 var(i)%RealR8Fill )
01055 if (rcode /= nf90_noerr) call shr_ncio_abort( subName// &
01056 ': error on putting _FillValue '// &
01057 'RealR8 attribute on variable: '// &
01058 var(i)%Name )
01059 rcode = nf90_put_att( ncId, var(i)%id, "missing_value", &
01060 var(i)%RealR8Fill )
01061 if (rcode /= nf90_noerr) call shr_ncio_abort( subName// &
01062 ': error on putting missing_value'// &
01063 'RealR8 attribute on variable: '// &
01064 var(i)%Name )
01065 end if
01066
01067 if ( var(i)%ListDescrips /= shr_ncio_stringFill )then
01068 rcode = nf90_put_att( ncId, var(i)%id, "type", "Integer list" )
01069 if (rcode /= nf90_noerr) call shr_ncio_abort( subName// &
01070 ': error on putting '// &
01071 ' type string attribute on variable: '// &
01072 var(i)%Name )
01073 nList = shr_string_listGetNum( var(i)%ListDescrips )
01074 do list = 1, nList
01075 call shr_string_listGetName( var(i)%ListDescrips, list, &
01076 name, rcode )
01077 rcode = nf90_put_att( ncId, var(i)%id, trim(name), &
01078 var(i)%ListValues(list) )
01079 if (rcode /= nf90_noerr) call shr_ncio_abort( subName// &
01080 ': error on putting ' &
01081 //name//' integer attribute on variable: '// &
01082 var(i)%Name )
01083 end do
01084 end if
01085 end do
01086
01087 rcode = nf90_enddef( ncId )
01088 if (rcode /= nf90_noerr) call shr_ncio_abort( subName// &
01089 ': error ending definition mode' )
01090
01091
01092
01093 do i = 1, nVars
01094 if ( var(i)%XType == shr_ncio_stringDataValue )then
01095 rcode = nf90_put_var( ncId, var(i)%id, trim(var(i)%StringData), &
01096 count=(/len_trim(var(i)%StringData)/) )
01097 else if ( var(i)%XType == shr_ncio_integerDataValue )then
01098 rcode = nf90_put_var( ncId, var(i)%id, var(i)%IntegerData )
01099 else if ( var(i)%XType == shr_ncio_realR8DataValue )then
01100 rcode = nf90_put_var( ncId, var(i)%id, var(i)%RealR8Data )
01101 else if ( var(i)%XType == shr_ncio_logicalDataValue )then
01102 rcode = nf90_put_var( ncId, var(i)%id, shr_ncio_int2Logical( &
01103 var(i)%LogicalData ) )
01104 else
01105 call shr_ncio_abort( subName//': invalid ncio type: ' )
01106 end if
01107 if (rcode /= nf90_noerr) call shr_ncio_abort( subName// &
01108 ': error writing variable: ' &
01109 //var(i)%Name )
01110 end do
01111 end if
01112 END SUBROUTINE shr_ncio_descripWrite
01113
01114
01115
01116
01117
01118
01119
01120
01121
01122
01123
01124
01125
01126 subroutine shr_ncio_open( NCFileName, MasterTask, FileType, ncId, exists, &
01127 writing, appending, clobber )
01128
01129 implicit none
01130
01131
01132
01133 character(len=*), intent(IN) :: NCFileName
01134 logical, intent(IN) :: MasterTask
01135 character(len=*), intent(IN) :: FileType
01136 integer, intent(OUT) :: ncId
01137 logical, intent(OUT) :: exists
01138 logical, intent(IN), optional :: writing
01139 logical, intent(IN), optional :: appending
01140 logical, intent(IN), optional :: clobber
01141
01142
01143
01144
01145 character(len=*), parameter :: subName = "(shr_ncio_open) "
01146 integer :: rCode
01147 logical :: writing2
01148 logical :: appending2
01149 logical :: clobber2
01150
01151
01152
01153
01154
01155
01156 if ( MasterTask ) then
01157 if ( present(writing) )then
01158 writing2 = writing
01159 else
01160 writing2 = .false.
01161 end if
01162 if ( present(appending) )then
01163 appending2 = appending
01164 else
01165 appending2 = .false.
01166 end if
01167 if ( appending2 .and. writing2 )then
01168 call shr_ncio_abort( subName//': can NOT set both appending and writing option!' )
01169 end if
01170 if ( present(clobber)) then
01171 clobber2 = clobber
01172 else
01173 clobber2 = .false.
01174 end if
01175
01176 if ( debugLevel > 0 .and. s_loglev > 0) write(s_logunit,*) 'Open NetCDF file FileType: '//trim(FileType)// &
01177 ' Filename: ', trim(NCFileName)
01178 inquire( file = trim(NCFileName), exist = exists )
01179
01180 if ( exists .and. (.not. writing2) .and. (.not. appending2) )then
01181 if ( debugLevel > 1 .and. s_loglev > 0) write(s_logunit,*) 'File exists open for reading not appending: '
01182 rCode = nf90_open( NCFileName, nf90_nowrite, ncId )
01183
01184 else if ( exists .and. appending2 )then
01185 if ( debugLevel > 1 .and. s_loglev > 0) write(s_logunit,*) 'File exists open for appending: '
01186 rCode = nf90_open( NCFileName, nf90_noclobber, ncId )
01187
01188 else if ( exists .and. writing2 .and. .not.clobber2)then
01189 if ( debugLevel > 1 .and. s_loglev > 0) write(s_logunit,*) 'File exists open for writing: '
01190 rCode = nf90_open( NCFileName, nf90_write, ncId )
01191
01192 else if ( exists .and. writing2 .and. clobber2)then
01193 if ( debugLevel > 1 .and. s_loglev > 0) write(s_logunit,*) 'File exists clobber for writing: '
01194 rCode = nf90_create( NCFileName, NF90_64BIT_OFFSET, ncId )
01195
01196 else if ( (.not. exists) .and. writing2 )then
01197 if ( debugLevel > 1 .and. s_loglev > 0) write(s_logunit,*) 'File does NOT exist open for writing: '
01198 rCode = nf90_create( NCFileName, NF90_64BIT_OFFSET, ncId )
01199
01200 else if ( .not. exists .and. ((.not. writing2) .or. appending2) )then
01201 call shr_ncio_abort( subName//': input file does not exist -- can '// &
01202 'NOT open for reading!' )
01203 end if
01204
01205 call shr_ncio_abort( subName//': error opening : '//NCFileName, rcode )
01206
01207 if (clobber2) exists = .false.
01208 end if
01209
01210 end subroutine shr_ncio_open
01211
01212
01213
01214
01215
01216
01217
01218
01219
01220
01221
01222
01223 subroutine shr_ncio_close( ncId, MasterTask, NCFilename, type )
01224
01225 implicit none
01226
01227
01228
01229 integer, intent(IN) :: ncId
01230 logical, intent(IN) :: MasterTask
01231 character(len=*), optional :: NCFileName
01232 character(len=*), optional :: type
01233
01234
01235
01236
01237 character(len=*), parameter :: subName = "(shr_ncio_close) "
01238 character(len=SHR_KIND_CL) :: FileName
01239 character(len=SHR_KIND_CL) :: FileType
01240 integer :: rCode
01241
01242
01243
01244
01245
01246
01247 if ( MasterTask )then
01248 if ( PRESENT(NCFileName) )then
01249 FileName = NCFileName
01250 else
01251 FileName = " "
01252 end if
01253 if ( PRESENT(type) )then
01254 FileType = type
01255 else
01256 FileType = " "
01257 end if
01258 rCode = nf90_close( ncId )
01259 if (rcode /= nf90_noerr) call shr_ncio_abort( subName// &
01260 ': error closing '//trim(FileType)//' file: '// &
01261 trim(FileName) )
01262 end if
01263 end subroutine shr_ncio_close
01264
01265
01266
01267
01268
01269
01270
01271
01272
01273
01274
01275
01276 subroutine shr_ncio_setDebug(iflag)
01277
01278 implicit none
01279
01280
01281
01282 integer, intent(in) :: iflag
01283
01284
01285
01286
01287 character(*),parameter :: subName = "(shr_ncio_setDebug)"
01288
01289
01290
01291
01292
01293 debugLevel = iflag
01294
01295 end subroutine shr_ncio_setDebug
01296
01297
01298
01299
01300
01301
01302
01303
01304
01305
01306
01307
01308 subroutine shr_ncio_setAbort(flag)
01309
01310 implicit none
01311
01312
01313
01314 logical, intent(in) :: flag
01315
01316
01317
01318
01319 character(*),parameter :: subName = "(shr_ncio_setAbort)"
01320
01321
01322
01323
01324
01325 doAbort = flag
01326
01327 end subroutine shr_ncio_setAbort
01328
01329
01330
01331
01332
01333
01334
01335
01336
01337
01338
01339
01340 logical FUNCTION shr_ncio_logical2Int( int_input )
01341
01342 implicit none
01343
01344
01345
01346 integer, intent(IN) :: int_input
01347
01348
01349
01350
01351 character(len=*), parameter :: subName = '(shr_ncio_logical2Int) '
01352
01353
01354
01355
01356
01357 if ( int_input == 0 )then
01358 shr_ncio_logical2Int = .false.
01359 else if ( int_input == 1 )then
01360 shr_ncio_logical2Int = .true.
01361 else
01362 call shr_ncio_abort( subName//': bad input to shr_ncio_logical2Int: ' )
01363 end if
01364
01365 END FUNCTION shr_ncio_logical2Int
01366
01367
01368
01369
01370
01371
01372
01373
01374
01375
01376
01377
01378 integer FUNCTION shr_ncio_int2Logical( log_input )
01379
01380 implicit none
01381
01382
01383
01384 logical, intent(IN) :: log_input
01385
01386
01387
01388
01389
01390
01391
01392 if ( .not. log_input )then
01393 shr_ncio_int2Logical = 0
01394 else
01395 shr_ncio_int2Logical = 1
01396 end if
01397
01398 END FUNCTION shr_ncio_int2Logical
01399
01400
01401
01402
01403
01404
01405
01406
01407
01408
01409
01410
01411 subroutine shr_ncio_abort( string, rcode)
01412
01413
01414
01415 use shr_sys_mod, only: shr_sys_abort
01416
01417 implicit none
01418
01419
01420
01421 character(*),optional,intent(IN) :: string
01422 integer, optional,intent(IN) :: rcode
01423
01424
01425
01426
01427 character(SHR_KIND_CL) :: lstring
01428 character(*),parameter :: subName = "(shr_ncio_abort)"
01429 character(*),parameter :: F00 = "('(shr_ncio_abort) ',a)"
01430
01431
01432
01433
01434
01435 if (present(rcode))then
01436 if ( rcode == nf90_noerr )then
01437 return
01438 else
01439 write(s_logunit,'(a,a,i3)') subname, ' : NetCDF error code = ', rcode
01440 end if
01441 end if
01442 lstring = ''
01443 if (present(string)) lstring = string
01444
01445 if (doAbort) then
01446 call shr_sys_abort(lstring)
01447 else
01448 write(s_logunit,F00) ' no abort:'//trim(lstring)
01449 endif
01450
01451 end subroutine shr_ncio_abort
01452
01453
01454
01455
01456 END MODULE shr_ncio_mod