@@ -88,7 +88,7 @@ subroutine init_atm_static(mesh, dims, configs)
88
88
integer ,dimension (:,:),allocatable:: ncat
89
89
90
90
real (kind= RKIND), pointer :: scalefactor_ptr
91
- real (kind= c_float) :: scalefactor
91
+ real (kind= RKIND) :: scalefactor
92
92
real (kind= c_float),dimension (:,:,:),pointer,contiguous :: rarray
93
93
type(c_ptr) :: rarray_ptr
94
94
@@ -129,10 +129,12 @@ subroutine init_atm_static(mesh, dims, configs)
129
129
integer (kind= I8KIND), dimension (:), pointer :: ter_integer
130
130
real (kind= RKIND), dimension (:), pointer :: soiltemp
131
131
real (kind= RKIND), dimension (:), pointer :: snoalb
132
+ integer (kind= I8KIND), dimension (:), pointer :: snoalb_integer
132
133
real (kind= RKIND), dimension (:), pointer :: shdmin, shdmax
133
134
real (kind= RKIND), dimension (:,:), pointer :: greenfrac
134
135
real (kind= RKIND), dimension (:,:), pointer :: albedo12m
135
136
real (kind= RKIND) :: msgval, fillval
137
+ real (kind= RKIND), pointer :: missing_value
136
138
integer , pointer :: category_min, category_max
137
139
integer , dimension (:), pointer :: lu_index
138
140
integer , dimension (:), pointer :: soilcat_top
@@ -150,6 +152,7 @@ subroutine init_atm_static(mesh, dims, configs)
150
152
type (mpas_geotile_type), pointer :: tile
151
153
152
154
real (kind= RKIND) :: tval
155
+ integer (kind= I8KIND) :: i8val
153
156
integer , pointer :: tile_bdr
154
157
integer , pointer :: tile_nx, tile_ny
155
158
@@ -829,107 +832,152 @@ subroutine init_atm_static(mesh, dims, configs)
829
832
!
830
833
if (trim(config_maxsnowalbedo_data) == ' MODIS' ) then
831
834
835
+ geog_sub_path = ' maxsnowalb_modis/ '
836
+
832
837
call mpas_log_write(' Using MODIS 0.05 - deg data for maximum snow albedo' )
833
838
if (supersample_fac > 1) then
834
839
call mpas_log_write(' Dataset will be supersampled by a factor of $i' , intArgs=(/supersample_fac/))
835
840
end if
836
841
837
- nx = 1206
838
- ny = 1206
839
- nz = 1
840
- isigned = 1
841
- endian = 0
842
- wordsize = 2
843
- scalefactor = 0.01
844
- msgval = real(-999.0,kind=R4KIND)*real(0.01,kind=R4KIND)
845
- fillval = 0.0
846
- allocate(rarray(nx,ny,nz))
847
- allocate(nhs(nCells))
848
- nhs(:) = 0
849
- snoalb(:) = 0.0
842
+ ierr = mgr % init(trim(config_geog_data_path)//trim(geog_sub_path))
843
+ if (ierr /= 0) then
844
+ call mpas_log_write(' Error occurred when initializing the interpolation of snow albedo (snoalb)' , &
845
+ messageType=MPAS_LOG_CRIT)
846
+ endif
850
847
851
- rarray_ptr = c_loc(rarray)
852
-
853
- start_lat = 90.0 - 0.05 * 0.5 / supersample_fac
854
- start_lon = -180.0 + 0.05 * 0.5 / supersample_fac
855
- geog_sub_path = ' maxsnowalb_modis/ '
848
+ call mpas_pool_get_config(mgr % pool, ' tile_bdr' , tile_bdr)
849
+ call mpas_pool_get_config(mgr % pool, ' tile_x' , tile_nx)
850
+ call mpas_pool_get_config(mgr % pool, ' tile_y' , tile_ny)
851
+ call mpas_pool_get_config(mgr % pool, ' missing_value' , missing_value)
852
+ call mpas_pool_get_config(mgr % pool, ' scale_factor' , scalefactor_ptr)
853
+ scalefactor = scalefactor_ptr
856
854
857
- do jTileStart = 1,02401,ny-6
858
- jTileEnd = jTileStart + ny - 1 - 6
855
+ allocate(nhs(nCells))
856
+ allocate(snoalb_integer(nCells))
857
+ snoalb_integer(:) = 0
858
+ snoalb(:) = 0.0
859
+ nhs(:) = 0
860
+ fillval = 0.0
859
861
860
- do iTileStart=1,06001,nx-6
861
- iTileEnd = iTileStart + nx - 1 - 6
862
- write(fname,' (a,i5.5 ,a1,i5.5 ,a1,i5.5 ,a1,i5.5 )' ) trim(geog_data_path)//trim(geog_sub_path), &
863
- iTileStart,' - ' ,iTileEnd,' .' ,jTileStart,' - ' ,jTileEnd
864
- call mpas_log_write(trim(fname))
865
- call mpas_f_to_c_string(fname, c_fname)
862
+ do iCell = 1, nCells
863
+ if (nhs(iCell) == 0) then
864
+ tile => null()
865
+ ierr = mgr % get_tile(latCell(iCell), lonCell(iCell), tile)
866
+ if (ierr /= 0 .or. .not. associated(tile)) then
867
+ call mpas_log_write(' Could not get tile that contained cell $i' , intArgs=(/iCell/), messageType=MPAS_LOG_CRIT)
868
+ end if
866
869
867
- call read_geogrid(c_fname,rarray_ptr,nx,ny,nz,isigned,endian, &
868
- wordsize,istatus)
869
- call init_atm_check_read_error(istatus, fname)
870
- rarray(:,:,:) = rarray(:,:,:) * scalefactor
870
+ ierr = mgr % push_tile(tile)
871
+ if (ierr /= 0) then
872
+ call mpas_log_write("Error pushing this tile onto the stack: "//trim(tile%fname), messageType=MPAS_LOG_CRIT)
873
+ end if
874
+ end if
871
875
872
- iPoint = 1
873
- do j=supersample_fac * 3 + 1, supersample_fac * (ny-3)
874
- do i=supersample_fac * 3 + 1, supersample_fac * (nx-3)
875
- ii = (i - 1) / supersample_fac + 1
876
- jj = (j - 1) / supersample_fac + 1
876
+ do while (.not. mgr % is_stack_empty())
877
+ tile => mgr % pop_tile()
877
878
878
- lat_pt = start_lat - (supersample_fac*(jTileStart-1) + j - (supersample_fac*3+1)) * 0.05 / supersample_fac
879
- lon_pt = start_lon + (supersample_fac*(iTileStart-1) + i - (supersample_fac*3+1)) * 0.05 / supersample_fac
880
- lat_pt = lat_pt * PI / 180.0
881
- lon_pt = lon_pt * PI / 180.0
879
+ if (tile % is_processed) then
880
+ cycle
881
+ end if
882
882
883
- iPoint = nearest_cell(lat_pt,lon_pt,iPoint,nCells,maxEdges, &
884
- nEdgesOnCell,cellsOnCell, &
885
- latCell,lonCell)
886
- if (rarray(ii,jj,1) /= msgval) then
883
+ call mpas_log_write(' Processing tile: ' //trim(tile % fname))
884
+
885
+ all_pixels_mapped_to_halo_cells = .true.
886
+
887
+ do j = supersample_fac * tile_bdr + 1, supersample_fac * (tile_ny + tile_bdr), 1
888
+ do i = supersample_fac * tile_bdr + 1, supersample_fac * (tile_nx + tile_bdr), 1
889
+
890
+ ii = (i - 1) / supersample_fac + 1
891
+ jj = (j - 1) / supersample_fac + 1
892
+
893
+ i8val = int(tile % tile(ii, jj, 1), kind=I8KIND)
894
+
895
+ call mgr % tile_to_latlon(tile, j, i, lat_pt, lon_pt, supersample_fac)
896
+ call mpas_latlon_to_xyz(xPixel, yPixel, zPixel, sphere_radius, lat_pt, lon_pt)
897
+ call mpas_kd_search(tree, (/xPixel, yPixel, zPixel/), res)
898
+
899
+ if (bdyMaskCell(res % id) < nBdyLayers) then
900
+ !
901
+ ! This field only matters for land cells, and for all but the outermost boundary cells,
902
+ ! we can safely assume that the nearest model grid cell contains the pixel (else, a different
903
+ ! cell would be nearest).
904
+ !
905
+ ! Since values in i8val are not yet scaled, we can compare them to missing_value, which
906
+ ! also is not scaled, without scaling either value
907
+ if (landmask(res % id) == 1 .and. i8val /= int(missing_value, kind=I8KIND)) then
908
+ snoalb_integer(res % id) = snoalb_integer(res % id) + i8val
909
+ nhs(res % id) = nhs(res % id) + 1
910
+ end if
911
+
912
+ !
913
+ ! When a pixel maps to a non-land cell or is a missing value, the values are not accumulated
914
+ ! above; however, these pixels may still reside in an owned cell, in which case we will still need
915
+ ! to push the tile' s neighbors onto the stack for processing.
916
+ !
917
+ if (res % id <= nCellsSolve) then
918
+ all_pixels_mapped_to_halo_cells = .false.
919
+ end if
920
+ ! For outermost cells, additional work is needed to verify that the pixel
921
+ ! actually lies within the nearest cell
922
+ else
923
+ if (mpas_in_cell(xPixel, yPixel, zPixel, xCell(res % id), yCell(res % id), zCell(res % id), &
924
+ nEdgesOnCell(res % id), verticesOnCell(:,res % id), xVertex, yVertex, zVertex)) then
925
+
926
+ ! Since values in i8val are not yet scaled, we can compare them to missing_value, which
927
+ ! also is not scaled, without scaling either value
928
+ if (landmask(res % id) == 1 .and. i8val /= int (missing_value, kind= I8KIND)) then
929
+ snoalb_integer(res % id) = snoalb_integer(res % id) + i8val
930
+ nhs(res % id) = nhs(res % id) + 1
931
+ end if
932
+
933
+ !
934
+ ! When a pixel maps to a non- land cell or is a missing value, the values are not accumulated
935
+ ! above; however, these pixels may still reside in an owned cell, in which case we will still need
936
+ ! to push the tile' s neighbors onto the stack for processing.
937
+ !
938
+ if (res % id <= nCellsSolve) then
939
+ all_pixels_mapped_to_halo_cells = .false.
940
+ end if
941
+ end if
942
+ end if
943
+ end do
944
+ end do
887
945
888
- !
889
- ! This field only matters for land cells, and for all but the outermost boundary cells,
890
- ! we can safely assume that the nearest model grid cell contains the pixel (else, a different
891
- ! cell would be nearest)
892
- !
893
- if (landmask(iPoint) == 1 .and. bdyMaskCell(iPoint) < nBdyLayers) then
894
- snoalb(iPoint) = snoalb(iPoint) + rarray(ii,jj,1)
895
- nhs(iPoint) = nhs(iPoint) + 1
946
+ tile % is_processed = .true.
896
947
897
- ! For outermost land cells, additional work is needed to verify that the pixel
898
- ! actually lies within the nearest cell
899
- else if (landmask(iPoint) == 1) then
900
- zPixel = sphere_radius * sin(lat_pt) ! Model cell coordinates assume a "full" sphere radius
901
- xPixel = sphere_radius * cos(lon_pt) * cos(lat_pt) ! at this point, so we need to ues the same radius
902
- yPixel = sphere_radius * sin(lon_pt) * cos(lat_pt) ! for source pixel coordinates
903
-
904
- if (mpas_in_cell(xPixel, yPixel, zPixel, xCell(iPoint), yCell(iPoint), zCell(iPoint), &
905
- nEdgesOnCell(iPoint), verticesOnCell(:,iPoint), xVertex, yVertex, zVertex)) then
906
- snoalb(iPoint) = snoalb(iPoint) + rarray(ii,jj,1)
907
- nhs(iPoint) = nhs(iPoint) + 1
908
- end if
948
+ if (.not. all_pixels_mapped_to_halo_cells) then
949
+ ierr = mgr % push_neighbors(tile)
950
+ if (ierr /= 0) then
951
+ call mpas_log_write("Error pushing the tile neighbors of: "//trim(tile%fname), messageType=MPAS_LOG_CRIT)
909
952
end if
910
- end if
911
- end do
912
- end do
913
-
914
- end do
953
+ end if
954
+ end do
915
955
end do
916
956
917
- do iCell = 1,nCells
918
- !
919
- ! Mismatches in land mask can lead to MPAS land points with no maximum snow albedo.
920
- ! Ideally, we would perform a search for nearby valid albedos, but for now using
921
- ! the fill value will at least allow the model to run. In general, the number of cells
922
- ! to be treated in this way tends to be a very small fraction of the total number of cells.
923
- !
924
- if (nhs(iCell) == 0) then
925
- snoalb(iCell) = fillval
926
- else
927
- snoalb(iCell) = snoalb(iCell) / real(nhs(iCell))
928
- end if
929
- snoalb(iCell) = 0.01_RKIND * snoalb(iCell) ! Convert from percent to fraction
957
+ do iCell = 1, nCells
958
+ !
959
+ ! Mismatches in land mask can lead to MPAS land points with no maximum snow albedo.
960
+ ! Ideally, we would perform a search for nearby valid albedos, but for now using
961
+ ! the fill value will at least allow the model to run. In general, the number of cells
962
+ ! to be treated in this way tends to be a very small fraction of the total number of cells.
963
+ !
964
+ if (nhs(iCell) == 0) then
965
+ snoalb(iCell) = fillval
966
+ else
967
+ snoalb(iCell) = real(snoalb_integer(iCell), kind=R8KIND) / real(nhs(iCell), kind=R8KIND)
968
+ snoalb(iCell) = snoalb(iCell) * scalefactor
969
+ snoalb(iCell) = 0.01_RKIND * snoalb(iCell) ! Convert from percent to fraction
970
+ endif
930
971
end do
931
- deallocate(rarray)
972
+
932
973
deallocate(nhs)
974
+ deallocate(snoalb_integer)
975
+
976
+ ierr = mgr % finalize()
977
+ if (ierr /= 0) then
978
+ call mpas_log_write(' Error occurred when finalizing the interpolation of snow albedo (snoalb)' , &
979
+ messageType=MPAS_LOG_CRIT)
980
+ endif
933
981
934
982
else if (trim(config_maxsnowalbedo_data) == ' NCEP' ) then
935
983
0 commit comments