-
Notifications
You must be signed in to change notification settings - Fork 9
Expand file tree
/
Copy pathcable_parameters.F90
More file actions
4000 lines (3496 loc) · 180 KB
/
Copy pathcable_parameters.F90
File metadata and controls
4000 lines (3496 loc) · 180 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
!==============================================================================
! This source code is part of the
! Australian Community Atmosphere Biosphere Land Exchange (CABLE) model.
! This work is licensed under the CSIRO Open Source Software License
! Agreement (variation of the BSD / MIT License).
!
! You may not use this file except in compliance with this License.
! A copy of the License (CSIRO_BSD_MIT_License_v2.0_CABLE.txt) is located
! in each directory containing CABLE code.
!
! ==============================================================================
! Purpose: This module file reads default parameter sets and basic
! initialisations for CABLE. Parameters values are chosen based
! on a global map of vegetation and soil types, currently based
! on a 1x1-degree grid for offline case and host-model grid for
! online case. Default initialisations are obtained from monthly
! climatology in GSWP and Mk3L runs for offline and online
! respectively.
!
! Contact: Bernard.Pak@csiro.au
!
! History: Changes since v1.4b for global offline (GSWP) cases, read in new
! input files
! Two subroutines moved to cable_common (reading veg and soil parameter
! files)
! Addition of code for CASA-CNP
!
!
! ==============================================================================
! CALLed from: cable_input.F90
!
! MODULEs used: cable_abort_module
! cable_common_module
! cable_def_types_mod
! casadimension
! casaparm
! cable_IO_vars_module
! phenvariable
! physical_constants
! netcdf
! CALLs: get_default_params
! read_gridinfo
! spatialSoil
! NSflip
! countPatch
! write_default_params
! write_cnp_params
! derived_parameters
! check_parameter_values
! report_parameters
!
MODULE cable_param_module
USE cable_def_types_mod
USE casadimension, ONLY: icycle
USE casavariable
USE phenvariable
USE cable_abort_module
USE cable_IO_vars_module
USE cable_common_module, ONLY: cable_user, gw_params
USE cable_pft_params_mod
USE cable_soil_params_mod
USE CABLE_LUC_EXPT, ONLY: LUC_EXPT, LUC_EXPT_TYPE, LUC_EXPT_SET_TILES
IMPLICIT NONE
PRIVATE
PUBLIC get_default_params, write_default_params, derived_parameters, &
check_parameter_values, report_parameters, parID_type, &
write_cnp_params, consistency_ice_veg_soil
INTEGER :: patches_in_parfile=4 ! # patches in default global parameter
! file
CHARACTER(LEN=4) :: classification
! Variables below are temporary - for file read-in:
INTEGER, DIMENSION(:, :, :), ALLOCATABLE :: inVeg
REAL, DIMENSION(:, :, :), ALLOCATABLE :: inPFrac
INTEGER, DIMENSION(:, :), ALLOCATABLE :: inSoil
REAL, DIMENSION(:, :, :, :), ALLOCATABLE :: inWB
REAL, DIMENSION(:, :, :, :), ALLOCATABLE :: inTGG
REAL, DIMENSION(:), ALLOCATABLE :: inLon
REAL, DIMENSION(:), ALLOCATABLE :: inLat
REAL, DIMENSION(:, :, :, :), ALLOCATABLE :: inALB
REAL, DIMENSION(:, :, :, :), ALLOCATABLE :: inSND
REAL, DIMENSION(:, :, :), ALLOCATABLE :: inLAI
REAL, DIMENSION(:, :), ALLOCATABLE :: inArea
INTEGER, DIMENSION(:, :), ALLOCATABLE :: inSorder
REAL, DIMENSION(:, :), ALLOCATABLE :: inNdep
REAL, DIMENSION(:, :), ALLOCATABLE :: inNfix
REAL, DIMENSION(:, :), ALLOCATABLE :: inPwea
REAL, DIMENSION(:, :), ALLOCATABLE :: inPdust
! Temporary values for reading IGBP soil map Q.Zhang @ 12/20/2010
REAL, DIMENSION(:, :), ALLOCATABLE :: inswilt
REAL, DIMENSION(:, :), ALLOCATABLE :: insfc
REAL, DIMENSION(:, :), ALLOCATABLE :: inssat
REAL, DIMENSION(:, :), ALLOCATABLE :: inbch
REAL, DIMENSION(:, :), ALLOCATABLE :: inhyds
REAL, DIMENSION(:, :), ALLOCATABLE :: insucs
REAL, DIMENSION(:, :), ALLOCATABLE :: inrhosoil
REAL, DIMENSION(:, :), ALLOCATABLE :: incss
REAL, DIMENSION(:, :), ALLOCATABLE :: incnsd
REAL, DIMENSION(:, :), ALLOCATABLE :: inclay
REAL, DIMENSION(:, :), ALLOCATABLE :: insilt
REAL, DIMENSION(:, :), ALLOCATABLE :: insand
!MD temp vars for reading in aquifer properties
LOGICAL :: found_explicit_gw_parameters
REAL, DIMENSION(:, :), ALLOCATABLE :: inGWbch
REAL, DIMENSION(:, :), ALLOCATABLE :: inGWssat
REAL, DIMENSION(:, :), ALLOCATABLE :: inGWhyds
REAL, DIMENSION(:, :), ALLOCATABLE :: inGWsucs
REAL, DIMENSION(:, :), ALLOCATABLE :: inGWrhosoil
REAL, DIMENSION(:, :), ALLOCATABLE :: inGWclay
REAL, DIMENSION(:, :), ALLOCATABLE :: inGWsilt
REAL, DIMENSION(:, :), ALLOCATABLE :: inGWsand
REAL, DIMENSION(:, :), ALLOCATABLE :: inGWWatr
REAL, DIMENSION(:, :), ALLOCATABLE :: inWatr
REAL, DIMENSION(:, :), ALLOCATABLE :: inSlope
REAL, DIMENSION(:, :), ALLOCATABLE :: inGWdz
REAL, DIMENSION(:, :), ALLOCATABLE :: inSlopeSTD
REAL, DIMENSION(:, :), ALLOCATABLE :: inORG
! vars intro for Ticket #27
INTEGER, DIMENSION(:, :), ALLOCATABLE :: inSoilColor
INTERFACE get_gw_data ! rk4417 - phase2
MODULE PROCEDURE get_gw_2d_var_constdef
MODULE PROCEDURE get_gw_3d_var_constdef
MODULE PROCEDURE get_gw_4d_var_constdef
MODULE PROCEDURE get_gw_2d_var
MODULE PROCEDURE get_gw_3d_var
MODULE PROCEDURE get_gw_4d_var
END INTERFACE
CONTAINS
SUBROUTINE get_default_params(logn, vegparmnew, LUC_EXPT)
USE cable_common_module, ONLY : filename, &
calcsoilalbedo,cable_user
! Load parameters for each veg type and each soil type. (get_type_parameters)
! Also read in initial information for each grid point. (read_gridinfo)
! Count to obtain 'landpt', 'max_vegpatches' and 'mp'. (countPatch)
!
! New input structure using netcdf and introduced 'month' to initialize
! soil profiles with the correct monthly average values (BP apr2010)
IMPLICIT NONE
INTEGER, INTENT(IN) :: logn ! log file unit number
LOGICAL, INTENT(IN) :: vegparmnew ! new format input file (BP dec2007)
TYPE (LUC_EXPT_TYPE), INTENT(INOUT) :: LUC_EXPT
! local variables
INTEGER :: npatch
INTEGER :: nlon
INTEGER :: nlat
WRITE(logn,*) ' Reading grid info from ', TRIM(filename%type)
WRITE(logn,*) ' And assigning C4 fraction according to veg classification.'
WRITE(logn,*)
IF(exists%patch) THEN
CALL read_gridinfo(nlon,nlat,nmetpatches)!, &
ELSE
CALL read_gridinfo(nlon,nlat,npatch)
END IF
! Overwrite veg type and inital patch frac with land-use info
IF (CABLE_USER%POPLUC) THEN
CALL get_land_index(nlon, nlat)
CALL LUC_EXPT_SET_TILES(inVeg, inPfrac, LUC_EXPT)
ENDIF
IF (soilparmnew) THEN
PRINT *, 'Use spatially-specific soil properties; ', nlon, nlat
WRITE(logn,*) 'Use spatially-specific soil properties; ', nlon, nlat
CALL spatialSoil(nlon, nlat, logn)
ENDIF
! Get parameter values for all default veg and soil types:
!CALL get_type_parameters(logn, vegparmnew, classification)
CALL cable_pft_params()
CALL cable_soil_params()
! include prescribed soil colour in determining albedo - Ticket #27
IF (calcsoilalbedo) THEN
CALL read_soilcolor(logn)
END IF
! count to obtain 'landpt', 'max_vegpatches' and 'mp'
CALL countPatch(nlon, nlat, npatch)
END SUBROUTINE get_default_params
!=============================================================================
SUBROUTINE read_gridinfo(nlon, nlat, npatch)
! Reads in veg type, patch fraction, soil type, soil moisture and temperature
! profiles; also grid area and nutrients
!
! Input variables:
! filename%type - via cable_IO_vars_module
! classification - via cable_param_module
! Output variables:
! nlon - # longitudes in input data set
! nlat - # latitudes in input data set
! npatch - # patches in each grid from input data set
! inVeg - via cable_param_module
! inPFrac - via cable_param_module
! inSoil - via cable_param_module
! inWB - via cable_param_module
! inTGG - via cable_param_module
! inLon - via cable_param_module
! inLat - via cable_param_module
! inALB - via cable_param_module
! inSND - via cable_param_module
! inLAI - via cable_param_module
!
! New input structure using netcdf and introduced 'month' to initialize
! soil profiles with the correct monthly average values (BP apr2010)
USE netcdf
USE cable_common_module, ONLY : filename
IMPLICIT NONE
INTEGER, INTENT(OUT) :: nlon
INTEGER, INTENT(OUT) :: nlat
INTEGER, INTENT(INOUT) :: npatch
! local variables
INTEGER :: ncid, ok
INTEGER :: xID, yID, pID, sID, tID, bID
INTEGER :: varID
INTEGER :: nslayer, ntime, nband, lon, lat
INTEGER :: ii, jj, kk,pp
INTEGER, DIMENSION(:, :), ALLOCATABLE :: idummy
REAL, DIMENSION(:, :), ALLOCATABLE :: rdummy
REAL, DIMENSION(:, :, :), ALLOCATABLE :: r3dum, r3dum2, r3dum3, r3dum4
ok = NF90_OPEN(filename%type, 0, ncid)
IF (ok /= NF90_NOERR) CALL nc_abort(ok, 'Error opening grid info file.')
ok = NF90_INQ_DIMID(ncid, 'longitude', xID)
IF (ok /= NF90_NOERR) ok = NF90_INQ_DIMID(ncid, 'x', xID)
IF (ok /= NF90_NOERR) CALL nc_abort(ok, 'Error inquiring x dimension.')
ok = NF90_INQUIRE_DIMENSION(ncid, xID, LEN=nlon)
IF (ok /= NF90_NOERR) CALL nc_abort(ok, 'Error getting x dimension.')
ok = NF90_INQ_DIMID(ncid, 'latitude', yID)
IF (ok /= NF90_NOERR) ok = NF90_INQ_DIMID(ncid, 'y', yID)
IF (ok /= NF90_NOERR) CALL nc_abort(ok, 'Error inquiring y dimension.')
ok = NF90_INQUIRE_DIMENSION(ncid, yID, LEN=nlat)
IF (ok /= NF90_NOERR) CALL nc_abort(ok, 'Error getting y dimension.')
IF(.NOT. exists%patch) THEN
ok = NF90_INQ_DIMID(ncid, 'patch', pID)
IF (ok /= NF90_NOERR) CALL nc_abort(ok, 'Error inquiring patch dimension.')
ok = NF90_INQUIRE_DIMENSION(ncid, pID, LEN=npatch)
IF (ok /= NF90_NOERR) CALL nc_abort(ok, 'Error getting patch dimension.')
ENDIF
ok = NF90_INQ_DIMID(ncid, 'soil', sID)
ok = NF90_INQUIRE_DIMENSION(ncid, sID, LEN=nslayer)
IF (ok /= NF90_NOERR) CALL nc_abort(ok, 'Error getting soil dimension.')
ok = NF90_INQ_DIMID(ncid, 'time', tID)
ok = NF90_INQUIRE_DIMENSION(ncid, tID, LEN=ntime)
IF (ok /= NF90_NOERR) CALL nc_abort(ok, 'Error getting time dimension.')
ok = NF90_INQ_DIMID(ncid, 'rad', bID)
ok = NF90_INQUIRE_DIMENSION(ncid, bID, LEN=nband)
IF (ok /= NF90_NOERR) CALL nc_abort(ok, 'Error getting rad dimension.')
! check dimensions of soil-layers and time
! vh_js !
IF ( (nslayer /= ms) .OR. (ntime /= 12)) THEN
PRINT *, 'Variable dimensions do not match:'
PRINT *, 'nslayer and ms = ', nslayer, ms
PRINT *, 'ntime not equal 12 months: ', ntime
IF (ntime /=12) THEN
CALL abort('Variable dimensions do not match (read_gridinfo)')
ELSE
PRINT*, 'warning: soil layers below nslayer will be initialsed with moisture'
PRINT*, 'and temperature of lowest layer in grid_info'
ENDIF
END IF
ALLOCATE( inLon(nlon), inLat(nlat) )
ALLOCATE( inVeg(nlon, nlat, npatch) )
ALLOCATE( inPFrac(nlon, nlat, npatch) )
ALLOCATE( inSoil(nlon, nlat) )
ALLOCATE( idummy(nlon, nlat) )
ALLOCATE( rdummy(nlon, nlat) )
ALLOCATE( inWB(nlon, nlat, nslayer,ntime) )
ALLOCATE( inTGG(nlon, nlat, nslayer,ntime) )
ALLOCATE( inALB(nlon, nlat, npatch,nband) )
ALLOCATE( inSND(nlon, nlat, npatch,ntime) )
ALLOCATE( inLAI(nlon, nlat, ntime) )
ALLOCATE( r3dum(nlon, nlat, nband) )
ALLOCATE( r3dum2(nlon, nlat, ntime) )
ok = NF90_INQ_VARID(ncid, 'longitude', varID)
IF (ok /= NF90_NOERR) CALL nc_abort(ok, &
'Error finding variable longitude.')
ok = NF90_GET_VAR(ncid, varID, inLon)
IF (ok /= NF90_NOERR) CALL nc_abort(ok, &
'Error reading variable longitude.')
!ensure this longitude is -180->180
!as for GSWP3 it is 0-360
WHERE (inLON > 180.0)
inLON = inLON - 360.0
ENDWHERE
ok = NF90_INQ_VARID(ncid, 'latitude', varID)
IF (ok /= NF90_NOERR) CALL nc_abort(ok, 'Error finding variable latitude.')
ok = NF90_GET_VAR(ncid, varID, inLat)
IF (ok /= NF90_NOERR) CALL nc_abort(ok, 'Error reading variable latitude.')
IF(.NOT. exists%patch) THEN
ok = NF90_INQ_VARID(ncid, 'iveg', varID)
IF (ok /= NF90_NOERR) CALL nc_abort(ok, 'Error finding variable iveg.')
!CLN ok = NF90_GET_VAR(ncid, varID, idummy)
ok = NF90_GET_VAR(ncid, varID, inVeg)
IF (ok /= NF90_NOERR) CALL nc_abort(ok, 'Error reading variable iveg.')
!CLN inVeg(:, :, 1) = idummy(:,:) ! npatch=1 in 1x1 degree input
ok = NF90_INQ_VARID(ncid, 'patchfrac', varID)
IF (ok /= NF90_NOERR) CALL nc_abort(ok, &
'Error finding variable patchfrac.')
ok = NF90_GET_VAR(ncid, varID, inPFrac)
IF (ok /= NF90_NOERR) CALL nc_abort(ok, &
'Error reading variable patchfrac.')
!CLN inPFrac(:, :, 1) = rdummy(:, :)
ELSE
!loop through lat and lon to fill patch and veg vars
DO lon = 1,nlon
DO lat = 1, nlat
inPFrac(lon,lat,:) = vegpatch_metfile(1,:) !Anna: passing met patchfrac here
inVeg(lon,lat,:) = vegtype_metfile(1,:)
ENDDO
ENDDO
END IF
ok = NF90_INQ_VARID(ncid, 'isoil', varID)
IF (ok /= NF90_NOERR) CALL nc_abort(ok, 'Error finding variable isoil.')
ok = NF90_GET_VAR(ncid, varID, inSoil)
IF (ok /= NF90_NOERR) CALL nc_abort(ok, 'Error reading variable isoil.')
ok = NF90_INQ_VARID(ncid, 'SoilMoist', varID)
IF (ok /= NF90_NOERR) CALL nc_abort(ok, &
'Error finding variable SoilMoist.')
ok = NF90_GET_VAR(ncid, varID, inWB)
IF (ok /= NF90_NOERR) CALL nc_abort(ok, &
'Error reading variable SoilMoist.')
ok = NF90_INQ_VARID(ncid, 'SoilTemp', varID)
IF (ok /= NF90_NOERR) CALL nc_abort(ok, 'Error finding variable SoilTemp.')
ok = NF90_GET_VAR(ncid, varID, inTGG)
IF (ok /= NF90_NOERR) CALL nc_abort(ok, 'Error reading variable SoilTemp.')
ok = NF90_INQ_VARID(ncid, 'Albedo', varID)
IF (ok /= NF90_NOERR) CALL nc_abort(ok, 'Error finding variable Albedo.')
ok = NF90_GET_VAR(ncid, varID, r3dum)
IF (ok /= NF90_NOERR) CALL nc_abort(ok, 'Error reading variable Albedo.')
! DO kk = 1, nband
! inALB(:,:,1,kk) = r3dum(:,:,kk)
! ENDDO
! vh!
DO kk = 1, nband
DO pp = 1,npatch
inALB(:,:,pp,kk) = r3dum(:,:,kk)
ENDDO
ENDDO
ok = NF90_INQ_VARID(ncid, 'SnowDepth', varID)
IF (ok /= NF90_NOERR) CALL nc_abort(ok, &
'Error finding variable SnowDepth.')
ok = NF90_GET_VAR(ncid,varID,r3dum2)
IF (ok /= NF90_NOERR) CALL nc_abort(ok, &
'Error reading variable SnowDepth.')
! DO kk = 1, ntime
! inSND(:, :, 1, kk) = r3dum2(:, :, kk)
! ENDDO
DO kk = 1, ntime
DO pp = 1,npatch
inSND(:, :, pp, kk) = r3dum2(:, :, kk)
ENDDO
ENDDO
ok = NF90_INQ_VARID(ncid, 'LAI', varID)
IF (ok /= NF90_NOERR) CALL nc_abort(ok, 'Error finding variable LAI.')
ok = NF90_GET_VAR(ncid,varID,inLAI)
IF (ok /= NF90_NOERR) CALL nc_abort(ok, 'Error reading variable LAI.')
IF (icycle > 0) THEN
! casaCNP parameters
ALLOCATE( inArea(nlon, nlat) )
ALLOCATE( inSorder(nlon, nlat) )
ALLOCATE( inNdep(nlon, nlat) )
ALLOCATE( inNfix(nlon, nlat) )
ALLOCATE( inPwea(nlon, nlat) )
ALLOCATE( inPdust(nlon, nlat) )
ok = NF90_INQ_VARID(ncid, 'area', varID)
IF (ok /= NF90_NOERR) CALL nc_abort(ok, 'Error finding area.')
ok = NF90_GET_VAR(ncid, varID, inArea)
IF (ok /= NF90_NOERR) CALL nc_abort(ok, 'Error reading area.')
ok = NF90_INQ_VARID(ncid, 'SoilOrder', varID)
IF (ok /= NF90_NOERR) CALL nc_abort(ok, 'Error finding SoilOrder.')
ok = NF90_GET_VAR(ncid, varID, inSorder)
IF (ok /= NF90_NOERR) CALL nc_abort(ok, 'Error reading SoilOrder.')
ok = NF90_INQ_VARID(ncid, 'Ndep', varID)
IF (ok /= NF90_NOERR) CALL nc_abort(ok, 'Error finding Ndep.')
ok = NF90_GET_VAR(ncid, varID, inNdep)
IF (ok /= NF90_NOERR) CALL nc_abort(ok, 'Error reading Ndep.')
ok = NF90_INQ_VARID(ncid, 'Nfix', varID)
IF (ok /= NF90_NOERR) CALL nc_abort(ok, 'Error finding Nfix.')
ok = NF90_GET_VAR(ncid, varID, inNfix)
IF (ok /= NF90_NOERR) CALL nc_abort(ok, 'Error reading Nfix.')
ok = NF90_INQ_VARID(ncid, 'Pwea', varID)
IF (ok /= NF90_NOERR) CALL nc_abort(ok, 'Error finding Pwea.')
ok = NF90_GET_VAR(ncid, varID, inPwea)
IF (ok /= NF90_NOERR) CALL nc_abort(ok, 'Error reading Pwea.')
ok = NF90_INQ_VARID(ncid, 'Pdust', varID)
IF (ok /= NF90_NOERR) CALL nc_abort(ok, 'Error finding Pdust.')
ok = NF90_GET_VAR(ncid, varID, inPdust)
IF (ok /= NF90_NOERR) CALL nc_abort(ok, 'Error reading Pdust.')
! change units from g/m2/yr to g/m2/day
inNdep = inNdep / 365.0
inNfix = inNfix / 365.0
inPwea = inPwea / 365.0
inPdust = inPdust / 365.0
ENDIF
ok = NF90_CLOSE(ncid)
IF (ok /= NF90_NOERR) CALL nc_abort(ok, 'Error closing grid info file.')
END SUBROUTINE read_gridinfo
!============================================================================
SUBROUTINE spatialSoil(nlon, nlat, logn)
! Read in spatially-specific soil properties including snow-free albedo
! plus soil texture; all these from UM ancilliary file
!
! Input variables:
! nlon,nlat - # longitudes and latitudes in the previous input file
! filename%soilIGBP - via cable_IO_vars_module
! Output variables:
! inswilt - via cable_param_module
! insfc - via cable_param_module
! inssat - via cable_param_module
! inbch - via cable_param_module
! inhyds - via cable_param_module
! insucs - via cable_param_module
! inrhosoil - via cable_param_module
! incss - via cable_param_module
! incnsd - via cable_param_module
! inclay - via cable_param_module
! insilt - via cable_param_module
! insand - via cable_param_module
! inALB - via cable_param_module
USE netcdf
USE cable_common_module, ONLY : filename
IMPLICIT NONE
INTEGER, INTENT(IN) :: nlon
INTEGER, INTENT(IN) :: nlat
INTEGER, INTENT(IN) :: logn ! log file unit number
! local variables
INTEGER :: ncid, ok, ii, jj, kk, ok2, ncid_elev
INTEGER :: xID, yID, fieldID
INTEGER :: xlon, xlat
REAL, DIMENSION(:,:,:,:), ALLOCATABLE :: indummy
REAL, DIMENSION(:,:), ALLOCATABLE :: sfact, dummy2
REAL, DIMENSION(:,:), ALLOCATABLE :: in2alb
ok = NF90_OPEN(filename%type, 0, ncid)
ALLOCATE( in2alb(nlon, nlat) ) ! local
ALLOCATE( dummy2(nlon, nlat) ) ! local
ALLOCATE( sfact(nlon, nlat) ) ! local
ALLOCATE( inswilt(nlon, nlat) )
ALLOCATE( insfc(nlon, nlat) )
ALLOCATE( inssat(nlon, nlat) )
ALLOCATE( inbch(nlon, nlat) )
ALLOCATE( inhyds(nlon, nlat) )
ALLOCATE( insucs(nlon, nlat) )
ALLOCATE( inrhosoil(nlon, nlat) )
ALLOCATE( incss(nlon, nlat) )
ALLOCATE( incnsd(nlon, nlat) )
ALLOCATE( inclay(nlon, nlat) )
ALLOCATE( insilt(nlon, nlat) )
ALLOCATE( insand(nlon, nlat) )
!MD Aquifer properties
ALLOCATE( inGWssat(nlon, nlat) )
ALLOCATE( inGWbch(nlon, nlat) )
ALLOCATE( inGWhyds(nlon, nlat) )
ALLOCATE( inGWsucs(nlon, nlat) )
ALLOCATE( inGWrhosoil(nlon, nlat) )
ALLOCATE( inGWWatr(nlon, nlat) )
ALLOCATE( inWatr(nlon, nlat) )
ALLOCATE( inORG(nlon, nlat) )
! 1
ok = NF90_INQ_VARID(ncid, 'swilt', fieldID)
IF (ok /= NF90_NOERR) CALL nc_abort(ok, 'Error finding variable swilt.')
ok = NF90_GET_VAR(ncid, fieldID, inswilt)
IF (ok /= NF90_NOERR) CALL nc_abort(ok, 'Error reading variable swilt.')
! 2
ok = NF90_INQ_VARID(ncid, 'sfc', fieldID)
IF (ok /= NF90_NOERR) CALL nc_abort(ok, 'Error finding variable sfc.')
ok = NF90_GET_VAR(ncid, fieldID, insfc)
IF (ok /= NF90_NOERR) CALL nc_abort(ok, 'Error reading variable sfc.')
! 3
ok = NF90_INQ_VARID(ncid, 'ssat', fieldID)
IF (ok /= NF90_NOERR) CALL nc_abort(ok, 'Error finding variable ssat.')
ok = NF90_GET_VAR(ncid, fieldID, inssat)
IF (ok /= NF90_NOERR) CALL nc_abort(ok, 'Error reading variable ssat.')
! 4
ok = NF90_INQ_VARID(ncid, 'bch', fieldID)
IF (ok /= NF90_NOERR) CALL nc_abort(ok, 'Error finding variable bch.')
ok = NF90_GET_VAR(ncid, fieldID, inbch)
IF (ok /= NF90_NOERR) CALL nc_abort(ok, 'Error reading variable bch.')
! 5
ok = NF90_INQ_VARID(ncid,'hyds',fieldID)
IF (ok /= NF90_NOERR) CALL nc_abort(ok,'Error finding variable hyds.')
ok = NF90_GET_VAR(ncid, fieldID, inhyds)
IF (ok /= NF90_NOERR) CALL nc_abort(ok, 'Error reading variable hyds.')
! 6
ok = NF90_INQ_VARID(ncid, 'sucs', fieldID)
IF (ok /= NF90_NOERR) CALL nc_abort(ok, 'Error finding variable sucs.')
ok = NF90_GET_VAR(ncid, fieldID, insucs)
IF (ok /= NF90_NOERR) CALL nc_abort(ok, 'Error reading variable sucs.')
! 7
ok = NF90_INQ_VARID(ncid, 'rhosoil', fieldID)
IF (ok /= NF90_NOERR) CALL nc_abort(ok, 'Error finding variable rhosoil.')
ok = NF90_GET_VAR(ncid,fieldID,inrhosoil)
IF (ok /= NF90_NOERR) CALL nc_abort(ok, 'Error reading variable rhosoil.')
! 8
ok = NF90_INQ_VARID(ncid, 'cnsd', fieldID)
IF (ok /= NF90_NOERR) CALL nc_abort(ok, 'Error finding variable cnsd.')
ok = NF90_GET_VAR(ncid, fieldID, incnsd)
IF (ok /= NF90_NOERR) CALL nc_abort(ok, 'Error reading variable cnsd.')
! 9
ok = NF90_INQ_VARID(ncid, 'css', fieldID)
IF (ok /= NF90_NOERR) CALL nc_abort(ok, 'Error finding variable css.')
ok = NF90_GET_VAR(ncid, fieldID, incss)
IF (ok /= NF90_NOERR) CALL nc_abort(ok, 'Error reading variable css.')
! 10
ok = NF90_INQ_VARID(ncid, 'clay', fieldID)
IF (ok /= NF90_NOERR) CALL nc_abort(ok, 'Error finding variable clay.')
ok = NF90_GET_VAR(ncid, fieldID, inclay)
IF (ok /= NF90_NOERR) CALL nc_abort(ok, 'Error reading variable clay.')
! 11
ok = NF90_INQ_VARID(ncid, 'silt', fieldID)
IF (ok /= NF90_NOERR) CALL nc_abort(ok, 'Error finding variable silt.')
ok = NF90_GET_VAR(ncid, fieldID, insilt)
IF (ok /= NF90_NOERR) CALL nc_abort(ok, 'Error reading variable silt.')
! 12
ok = NF90_INQ_VARID(ncid, 'sand', fieldID)
IF (ok /= NF90_NOERR) CALL nc_abort(ok, 'Error finding variable sand.')
ok = NF90_GET_VAR(ncid, fieldID, insand)
IF (ok /= NF90_NOERR) CALL nc_abort(ok, 'Error reading variable sand.')
! 13 UM albedo
ok = NF90_INQ_VARID(ncid, 'albedo2', fieldID)
IF (ok /= NF90_NOERR) CALL nc_abort(ok, 'Error finding variable UM albedo')
ok = NF90_GET_VAR(ncid, fieldID, in2alb)
IF (ok /= NF90_NOERR) CALL nc_abort(ok, 'Error reading variable UM albedo')
!MD try to read aquifer properties from the file
! if they don't exist set aquifer properties to the same as the soil
ok = NF90_INQ_VARID(ncid, 'Watr', fieldID)
WRITE(*,*) NF90_NOERR
ok2= ok
IF (ok .EQ. NF90_NOERR) THEN
ok2 = NF90_GET_VAR(ncid, fieldID, inWatr)
END IF
IF ((ok2 .NE. NF90_NOERR) .OR. (ok .NE. NF90_NOERR)) THEN
inWatr(:,:) = 0.05
END IF
found_explicit_gw_parameters = .TRUE.
ok = NF90_INQ_VARID(ncid, 'GWssat', fieldID)
WRITE(*,*) NF90_NOERR
ok2= ok
IF (ok .EQ. NF90_NOERR) THEN
ok2 = NF90_GET_VAR(ncid, fieldID, inGWssat)
END IF
IF ((ok2 .NE. NF90_NOERR) .OR. (ok .NE. NF90_NOERR)) THEN
inGWssat(:,:) = inssat(:,:)
found_explicit_gw_parameters = .FALSE.
END IF
ok = NF90_INQ_VARID(ncid, 'GWWatr', fieldID)
ok2 = ok
IF (ok .EQ. NF90_NOERR) THEN
ok2 = NF90_GET_VAR(ncid, fieldID, inGWssat)
END IF
IF ((ok2 .NE. NF90_NOERR) .OR. (ok .NE. NF90_NOERR)) THEN
inGWWatr(:,:) = 0.05
END IF
ok = NF90_INQ_VARID(ncid, 'GWsucs', fieldID)
ok2 = ok
IF (ok .EQ. NF90_NOERR) THEN
ok2 = NF90_GET_VAR(ncid, fieldID, inGWsucs)
END IF
IF ((ok2 .NE. NF90_NOERR) .OR. (ok .NE. NF90_NOERR)) THEN
inGWsucs(:,:) = ABS(insucs(:,:)) * 1000.0
found_explicit_gw_parameters = .FALSE.
END IF
ok = NF90_INQ_VARID(ncid, 'GWbch', fieldID)
ok2 = ok
IF (ok .EQ. NF90_NOERR) THEN
ok2 = NF90_GET_VAR(ncid, fieldID, inGWbch)
END IF
IF ((ok2 .NE. NF90_NOERR) .OR. (ok .NE. NF90_NOERR)) THEN
inGWbch(:,:) = inbch(:,:)
found_explicit_gw_parameters = .FALSE.
END IF
ok = NF90_INQ_VARID(ncid, 'GWhyds', fieldID)
ok2 = ok
IF (ok .EQ. NF90_NOERR) THEN
ok2 = NF90_GET_VAR(ncid, fieldID, inGWhyds)
END IF
IF ((ok2 .NE. NF90_NOERR) .OR. (ok .NE. NF90_NOERR)) THEN
inGWhyds(:,:) = inhyds(:,:)*1000.0
found_explicit_gw_parameters = .FALSE.
END IF
ok = NF90_INQ_VARID(ncid, 'GWrhosoil', fieldID)
ok2 = ok
IF (ok .EQ. NF90_NOERR) THEN
ok2 = NF90_GET_VAR(ncid, fieldID, inGWrhosoil)
END IF
IF ((ok2 .NE. NF90_NOERR) .OR. (ok .NE. NF90_NOERR)) THEN
inGWrhosoil(:,:) = inrhosoil(:,:)
END IF
ok = NF90_INQ_VARID(ncid, 'organic', fieldID)
ok2 = ok
IF (ok .EQ. NF90_NOERR) THEN
ok2 = NF90_GET_VAR(ncid, fieldID, inORG)
WRITE(logn,*) 'READ FORG FROM THE DATA FILE, yeidling '
WRITE(logn,*) 'A maximum value of ',MAXVAL(inORG),' and min val of',MINVAL(inORG)
END IF
IF ((ok2 .NE. NF90_NOERR) .OR. (ok .NE. NF90_NOERR)) THEN
inORG(:,:) = 0.0
WRITE(logn,*) 'COULD NOT READ FORG FROM THR SRF FILE setting to 0.0'
END IF
! Use this code if need to process original UM file soil fields into CABLE
! offline format
! ! 1
! ok = NF90_INQ_VARID(ncid,'field329',fieldID)
! IF (ok /= NF90_NOERR) CALL nc_abort(ok,'Error finding variable swilt.')
! ok = NF90_GET_VAR(ncid,fieldID,indummy)
! IF (ok /= NF90_NOERR) CALL nc_abort(ok,'Error reading variable swilt.')
! inswilt(:,:) = indummy(:,:,1,1)
! CALL NSflip(nlon,nlat,inswilt)
! ! 2
! ok = NF90_INQ_VARID(ncid,'field330',fieldID)
! IF (ok /= NF90_NOERR) CALL nc_abort(ok,'Error finding variable sfc.')
! ok = NF90_GET_VAR(ncid,fieldID,indummy)
! IF (ok /= NF90_NOERR) CALL nc_abort(ok,'Error reading variable sfc.')
! insfc(:,:) = indummy(:,:,1,1)
! CALL NSflip(nlon,nlat,insfc)
! ! 3
! ok = NF90_INQ_VARID(ncid,'field332',fieldID)
! IF (ok /= NF90_NOERR) CALL nc_abort(ok,'Error finding variable ssat.')
! ok = NF90_GET_VAR(ncid,fieldID,indummy)
! IF (ok /= NF90_NOERR) CALL nc_abort(ok,'Error reading variable ssat.')
! inssat(:,:) = indummy(:,:,1,1)
! CALL NSflip(nlon,nlat,inssat)
! ! 4
! ok = NF90_INQ_VARID(ncid,'field1381',fieldID)
! IF (ok /= NF90_NOERR) CALL nc_abort(ok,'Error finding variable bch.')
! ok = NF90_GET_VAR(ncid,fieldID,indummy)
! IF (ok /= NF90_NOERR) CALL nc_abort(ok,'Error reading variable bch.')
! inbch(:,:) = indummy(:,:,1,1)
! CALL NSflip(nlon,nlat,inbch)
! ! 5
! ok = NF90_INQ_VARID(ncid,'field333',fieldID)
! IF (ok /= NF90_NOERR) CALL nc_abort(ok,'Error finding variable hyds.')
! ok = NF90_GET_VAR(ncid,fieldID,indummy)
! IF (ok /= NF90_NOERR) CALL nc_abort(ok,'Error reading variable hyds.')
! inhyds(:,:) = indummy(:,:,1,1)
! CALL NSflip(nlon,nlat,inhyds)
! ! 6
! ok = NF90_INQ_VARID(ncid,'field342',fieldID)
! IF (ok /= NF90_NOERR) CALL nc_abort(ok,'Error finding variable sucs.')
! ok = NF90_GET_VAR(ncid,fieldID,indummy)
! IF (ok /= NF90_NOERR) CALL nc_abort(ok,'Error reading variable sucs.')
! insucs(:,:) = indummy(:,:,1,1)
! CALL NSflip(nlon,nlat,insucs)
! ! 7
! ok = NF90_INQ_VARID(ncid,'field2011',fieldID)
! IF (ok /= NF90_NOERR) CALL nc_abort(ok,'Error finding variable rhosoil.')
! ok = NF90_GET_VAR(ncid,fieldID,indummy)
! IF (ok /= NF90_NOERR) CALL nc_abort(ok,'Error reading variable rhosoil.')
! inrhosoil(:,:) = indummy(:,:,1,1)
! CALL NSflip(nlon,nlat,inrhosoil)
! ! 8
! ok = NF90_INQ_VARID(ncid,'field335',fieldID)
! IF (ok /= NF90_NOERR) CALL nc_abort(ok,'Error finding variable css.')
! ok = NF90_GET_VAR(ncid,fieldID,indummy)
! IF (ok /= NF90_NOERR) CALL nc_abort(ok,'Error reading variable css.')
! incss(:,:) = indummy(:,:,1,1)
! CALL NSflip(nlon,nlat,incss)
! ! 9
! ok = NF90_INQ_VARID(ncid,'field336',fieldID)
! IF (ok /= NF90_NOERR) CALL nc_abort(ok,'Error finding variable cnsd.')
! ok = NF90_GET_VAR(ncid,fieldID,indummy)
! IF (ok /= NF90_NOERR) CALL nc_abort(ok,'Error reading variable cnsd.')
! incnsd(:,:) = indummy(:,:,1,1)
! CALL NSflip(nlon,nlat,incnsd)
! ! 10 albedo
! ok = NF90_INQ_VARID(ncid,'field1395',fieldID)
! IF (ok /= NF90_NOERR) CALL nc_abort(ok,'Error finding variable albedo')
! ok = NF90_GET_VAR(ncid,fieldID,indummy)
! IF (ok /= NF90_NOERR) CALL nc_abort(ok,'Error reading variable albedo')
! in2alb(:,:) = indummy(:,:,1,1)
! CALL NSflip(nlon,nlat,in2alb)
ok = NF90_CLOSE(ncid)
IF (ok /= NF90_NOERR) CALL nc_abort(ok, 'Error closing IGBP soil map.')
! Code if using UM soil file
! unit change and glacial-point check were done in preprocessing
! ! change unit to m/s
! inhyds = inhyds * 1.0E-3
! ! Assign values to glacial points which are zeroes
! WHERE(inswilt==0.) inswilt = 0.216
! WHERE( insfc ==0.) insfc = 0.301
! WHERE(inssat ==0.) inssat = 0.479
! WHERE( inbch ==0.) inbch = 7.1
! WHERE(inhyds ==0.) inhyds = 1.E-3
! WHERE(insucs ==0.) insucs = 0.153
! WHERE(inrhosoil==0.) inrhosoil = 1455
! WHERE(incnsd ==0.) incnsd = 0.272
! WHERE(incss > 630000.0)
! incss = incss / inrhosoil ! normal points need unit conversion
! ELSEWHERE
! incss = 2100.0 ! glacial points
! ENDWHERE
! Calculate albedo for radiation bands and overwrite previous
! initialization
PRINT *, 'When choosing spatially-specific soil properties,'
PRINT *, 'snow-free albedo is also overwritten by this data set.'
WRITE(logn, *) 'When choosing spatially-specific soil properties,'
WRITE(logn, *) 'snow-free albedo is also overwritten by this data set.'
sfact = 0.68
WHERE (in2alb <= 0.14)
sfact = 0.5
ELSEWHERE (in2alb > 0.14)
sfact = 0.62
END WHERE
WHERE (in2alb > 1.0e19) ! ocean points
in2alb = -1.0
END WHERE
dummy2(:, :) = 2.0 * in2alb(:, :) / (1.0 + sfact(:, :))
inALB(:, :, 1, 2) = dummy2(:, :)
inALB(:, :, 1, 1) = sfact(:, :) * dummy2(:, :)
ALLOCATE(inSlope(nlon,nlat),stat=ok)
IF (ok .NE. 0) CALL nc_abort(ok, 'Error allocating inSlope ')
inSlope(:,:) = 0.0
ALLOCATE(inSlopeSTD(nlon,nlat),stat=ok)
IF (ok .NE. 0) CALL nc_abort(ok, 'Error allocating inSlopeSTD ')
inSlopeSTD(:,:) = 0.0
ALLOCATE(inGWdz(nlon,nlat),stat=ok)
IF (ok .NE. 0) CALL nc_abort(ok, 'Error allocating inGWdz ')
inGWdz(:,:) = 20.0
IF (cable_user%GW_MODEL) THEN
ok = NF90_OPEN(TRIM(filename%gw_elev),NF90_NOWRITE,ncid_elev)
IF (ok /= NF90_NOERR) CALL nc_abort(ok, 'Error opening GW elev param file.')
ok = NF90_INQ_VARID(ncid_elev, 'slope', fieldID)
IF (ok /= NF90_NOERR) WRITE(logn,*) 'Error finding variable slope'
ok = NF90_GET_VAR(ncid_elev, fieldID, inSlope)
IF (ok /= NF90_NOERR) THEN
inSlope = 0.0
WRITE(logn, *) 'Could not read slope data for SSGW, set to 0.0'
END IF
ok = NF90_INQ_VARID(ncid_elev, 'slope_std', fieldID) !slope_std
IF (ok /= NF90_NOERR) WRITE(logn,*) 'Error finding variable slope std'
ok = NF90_GET_VAR(ncid_elev, fieldID, inSlopeSTD)
IF (ok /= NF90_NOERR) THEN
inSlopeSTD = 0.0
WRITE(logn, *) 'Could not read slope stddev data for SSGW, set to 0.0'
END IF
ok = NF90_INQ_VARID(ncid_elev, 'dtb', fieldID)
IF (ok /= NF90_NOERR) WRITE(logn,*) 'Error finding variable dtb'
ok = NF90_GET_VAR(ncid_elev, fieldID, inGWdz)
IF (ok /= NF90_NOERR) THEN
inGWdz = 20.0
WRITE(logn, *) 'Could not read dtb data for SSGW, set to 0.0'
END IF
ok = NF90_CLOSE(ncid_elev)
ENDIF !running gw model
DEALLOCATE(in2alb, sfact, dummy2)
! DEALLOCATE(in2alb,sfact,dummy2,indummy)
END SUBROUTINE spatialSoil
!=============================================================================
!subr to read soil color for albed o calc - Ticket #27
SUBROUTINE read_soilcolor(logn)
! Read soil color
!
! Input variables:
! filename%soilcolor - via cable_IO_vars_module
! Output variables:
! soilcol - via cable_param_module
!
! New input structure using netcdf
USE netcdf
USE cable_common_module, ONLY : filename, calcsoilalbedo
! USE cable_IO_vars_module, ONLY : soilcol
IMPLICIT NONE
! INTEGER, DIMENSION(:), INTENT(INOUT) :: soilcol
! TYPE (soil_parameter_type), INTENT(OUT) :: soil
INTEGER, INTENT(IN) :: logn ! log file unit number
! local variables
! INTEGER, DIMENSION(:, :), ALLOCATABLE :: inSoilColor
INTEGER :: ncid, ok
INTEGER :: nlon
INTEGER :: nlat
INTEGER :: xID, yID
INTEGER :: varID
INTEGER :: r, e
REAL, DIMENSION(:), ALLOCATABLE :: inLonSoilCol
REAL, DIMENSION(:), ALLOCATABLE :: inLatSoilCol
ok = NF90_OPEN(filename%soilcolor, 0, ncid)
IF (ok /= NF90_NOERR) CALL nc_abort(ok, 'Error opening soil color file.')
ok = NF90_INQ_DIMID(ncid, 'longitude', xID)
IF (ok /= NF90_NOERR) ok = NF90_INQ_DIMID(ncid, 'x', xID)
IF (ok /= NF90_NOERR) CALL nc_abort(ok, 'Error inquiring x dimension.')
ok = NF90_INQUIRE_DIMENSION(ncid, xID, LEN=nlon)
IF (ok /= NF90_NOERR) CALL nc_abort(ok, 'Error getting x dimension.')
ok = NF90_INQ_DIMID(ncid, 'latitude', yID)
IF (ok /= NF90_NOERR) ok = NF90_INQ_DIMID(ncid, 'y', yID)
IF (ok /= NF90_NOERR) CALL nc_abort(ok, 'Error inquiring y dimension.')
ok = NF90_INQUIRE_DIMENSION(ncid, yID, LEN=nlat)
IF (ok /= NF90_NOERR) CALL nc_abort(ok, 'Error getting y dimension.')
ALLOCATE( inLonSoilCol(nlon), inLatSoilCol(nlat) )
ALLOCATE( inSoilColor(nlon, nlat) )
! ALLOCATE( soilcol(mp) )
ok = NF90_INQ_VARID(ncid, 'longitude', varID)
IF (ok /= NF90_NOERR) CALL nc_abort(ok, &
'Error finding variable longitude.')
ok = NF90_GET_VAR(ncid, varID, inLonSoilCol)
IF (ok /= NF90_NOERR) CALL nc_abort(ok, &
'Error reading variable longitude.')
DO r = 1, nlon
IF ( inLonSoilCol(r) /= inLon(r) ) CALL nc_abort(ok, &
'Wrong resolution in longitude.')
END DO
ok = NF90_INQ_VARID(ncid, 'latitude', varID)
IF (ok /= NF90_NOERR) CALL nc_abort(ok, 'Error finding variable latitude.')
ok = NF90_GET_VAR(ncid, varID, inLatSoilCol)
IF (ok /= NF90_NOERR) CALL nc_abort(ok, 'Error reading variable latitude.')
DO r = 1, nlat
IF ( inLatSoilCol(r) /= inLat(r) ) CALL nc_abort(ok, &
'Wrong resolution in latitude.')
END DO
ok = NF90_INQ_VARID(ncid, 'SOIL_COLOR', varID)
IF (ok /= NF90_NOERR) CALL nc_abort(ok, 'Error finding variable soil color.')
ok = NF90_GET_VAR(ncid, varID, inSoilColor)
IF (ok /= NF90_NOERR) CALL nc_abort(ok, 'Error reading variable soil color.')
ok = NF90_CLOSE(ncid)
IF (ok /= NF90_NOERR) CALL nc_abort(ok, 'Error closing soil color file.')
END SUBROUTINE read_soilcolor
!=============================================================================
SUBROUTINE NSflip(nlon, nlat, invar)
IMPLICIT NONE
INTEGER, INTENT(IN) :: nlon
INTEGER, INTENT(IN) :: nlat
REAL, INTENT(INOUT) :: invar(nlon,nlat)
! local variables
INTEGER :: ii, jj
REAL :: rdummy(nlon, nlat)
DO jj = 1, nlat
DO ii = 1, nlon
rdummy(ii, jj) = invar(ii, nlat - jj + 1)
ENDDO
ENDDO
invar(:, :) = rdummy(:, :)
END SUBROUTINE NSflip
!=============================================================================
SUBROUTINE get_land_index(nlon, nlat)
!
! fill the index variable 'landpt%ilat, landpt%ilon'
!
! Input variables:
! nlon - # longitudes in input data set
! nlat - # latitudes in input data set
! npatch - # patches in each grid from input data set
! inLon - via cable_param_module
! inLat - via cable_param_module
! longitude - via cable_IO_vars_module, dim(mland), not patches
! latitude - via cable_IO_vars_module, dim(mland), not patches
! nmetpatches - via cable_IO_vars_module
! vegtype_metfile - via cable_IO_vars_module, dim(mland,nmetpatches)
! soiltype_metfile- via cable_IO_vars_module, dim(mland,nmetpatches)
! Output variables:
! max_vegpatches - via cable_IO_vars_module
! landpt%type - via cable_IO_vars_module (%nap,cstart,cend,ilon,ilat)
IMPLICIT NONE
INTEGER, INTENT(IN) :: nlon, nlat
! local variables
REAL :: lon2, distance, newLength
INTEGER :: ii, jj, kk, tt, ncount
! range of longitudes from input file (inLon) should be -180 to 180,
! and longitude(:) has already been converted to -180 to 180 for CABLE.
landpt(:)%ilon = -999
landpt(:)%ilat = -999
ncount = 0
DO kk = 1, mland
distance = 5300.0 ! initialise, units are degrees
DO jj = 1, nlat
DO ii = 1, nlon
IF (inVeg(ii,jj, 1) > 0) THEN
newLength = SQRT((inLon(ii) - longitude(kk))**2 &
+ (inLat(jj) - latitude(kk))**2)
IF (newLength < distance) THEN
distance = newLength
landpt(kk)%ilon = ii
landpt(kk)%ilat = jj
END IF
END IF
END DO
END DO
IF (landpt(kk)%ilon < -900 .OR. landpt(kk)%ilat < -900) THEN
PRINT *, 'Land point ', kk, ' cannot find the nearest grid!'
PRINT *, 'lon, lat = ', longitude(kk), latitude(kk)
PRINT *, 'inLon range:', MINVAL(inLon), MAXVAL(inLon)
PRINT *, 'inLat range:', MINVAL(inLat), MAXVAL(inLat)
STOP
END IF
END DO
END SUBROUTINE get_land_index
!=============================================================================
SUBROUTINE countPatch(nlon, nlat, npatch)
! count the total number of active patches and
! fill the index variable 'landpt'
!
! Input variables:
! nlon - # longitudes in input data set
! nlat - # latitudes in input data set
! npatch - # patches in each grid from input data set
! inLon - via cable_param_module