Skip to content

Commit ce76de3

Browse files
authored
Merge pull request #70 from alex-huth/basins
Added capability to track melt-by-ice-sheet-basin. Fixed consistency under different PE layouts for positioning of new footloose bergs.
2 parents 03bc432 + 30e40ff commit ce76de3

File tree

3 files changed

+198
-19
lines changed

3 files changed

+198
-19
lines changed

src/icebergs.F90

Lines changed: 53 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,7 @@ module ice_bergs
5858
use ice_bergs_io, only: ice_bergs_io_init, write_restart_bergs, write_trajectory, write_bond_trajectory
5959
use ice_bergs_io, only: read_restart_bergs, read_restart_calving
6060
use ice_bergs_io, only: read_restart_bonds
61-
use ice_bergs_io, only: read_ocean_depth
61+
use ice_bergs_io, only: read_ocean_depth, read_ice_sheet_basins
6262

6363
implicit none ; private
6464

@@ -117,8 +117,8 @@ subroutine icebergs_init(bergs, &
117117
logical, intent(in), optional :: fractional_area !< If true, ice_area contains cell area as fraction of entire spherical surface
118118
! Local variables
119119
type(icebergs_gridded), pointer :: grd => null()
120-
integer :: nbonds
121-
logical :: check_bond_quality
120+
integer :: nbonds, nbasins, id_class
121+
logical :: check_bond_quality, lerr
122122
integer :: stdlogunit, stderrunit
123123

124124
! Get the stderr and stdlog unit numbers
@@ -131,6 +131,8 @@ subroutine icebergs_init(bergs, &
131131
dt, Time, ice_lon, ice_lat, ice_wet, ice_dx, ice_dy, ice_area, &
132132
cos_rot, sin_rot, ocean_depth=ocean_depth, maskmap=maskmap, fractional_area=fractional_area)
133133

134+
grd=>bergs%grd
135+
134136
call unit_testing(bergs)
135137

136138
call mpp_clock_begin(bergs%clock_ior)
@@ -149,6 +151,18 @@ subroutine icebergs_init(bergs, &
149151

150152
!Reading ocean depth from a file
151153
if (bergs%read_ocean_depth_from_file) call read_ocean_depth(bergs%grd)
154+
! Reading the ice-sheet basins of origin for the bergs
155+
if (bergs%use_berg_origin_basins) then
156+
call read_ice_sheet_basins(bergs%grd)
157+
id_class=register_static_field('icebergs', 'ice_sheet_basins_static', axes, &
158+
'Static ice-sheet basins of origin for icebergs', 'none')
159+
if (id_class>0) lerr=send_data(id_class, grd%ice_sheet_basins(grd%isc:grd%iec,grd%jsc:grd%jec))
160+
else
161+
bergs%nbasins=1
162+
grd%ice_sheet_basins(:,:)=0.0
163+
endif
164+
allocate( grd%melt_by_ice_sheet_basin(grd%isd:grd%ied, grd%jsd:grd%jed, bergs%nbasins) )
165+
grd%melt_by_ice_sheet_basin(:,:,:)=0.
152166

153167
if (bergs%iceberg_bonds_on) then
154168
if (bergs%manually_initialize_bonds) then
@@ -2545,14 +2559,21 @@ subroutine footloose_calving(bergs, time)
25452559
l_c = pi/(2.*sqrt(2.)) !for length-scale of child iceberg
25462560
lw_c = 1./(gravity*rho_seawater) !for buoyancy length
25472561
B_c = youngs/(12.*(1.-poisson**2.)) !for bending stiffness
2548-
seed = constructSeed(mpp_pe(),mpp_pe(),time) !Seed random numbers for Poisson distribution
2549-
rns = initializeRandomNumberStream(seed)
2550-
call getRandomNumbers(rns, rn)
2562+
if (bergs%fl_init_child_xy_by_pe) then !old bug that does not reproduce on different PE layouts
2563+
seed = constructSeed(mpp_pe(),mpp_pe(),time) !Seed random numbers for Poisson distribution
2564+
rns = initializeRandomNumberStream(seed)
2565+
call getRandomNumbers(rns, rn)
2566+
endif
25512567
Visited=.true.
25522568
endif
25532569

25542570
do grdj = grd%jsc,grd%jec ; do grdi = grd%isc,grd%iec !computational domain only
25552571
this=>bergs%list(grdi,grdj)%first
2572+
if ((.not. bergs%fl_init_child_xy_by_pe) .and. associated(this)) then
2573+
! Seed random numbers based on space and "time"
2574+
rns = initializeRandomNumberStream( grdi + 10000*grdj + &
2575+
int( 16384.*abs( sin(262144.*grd%ssh(grdi,grdj)) ) ) )
2576+
endif
25562577
do while(associated(this))
25572578

25582579
!only non-static, non-footloose-child bergs are eligible for footloose calving:
@@ -3125,6 +3146,13 @@ subroutine thermodynamics(bergs)
31253146
grd%melt_by_class(i,j,k)=grd%melt_by_class(i,j,k)+melt/grd%area(i,j)*this%mass_scaling ! kg/m2/s
31263147
endif
31273148

3149+
if (bergs%use_berg_origin_basins) then
3150+
if (this%basin>0) then
3151+
grd%melt_by_ice_sheet_basin(i,j,this%basin)=grd%melt_by_ice_sheet_basin(i,j,this%basin)+&
3152+
melt/grd%area(i,j)*this%mass_scaling ! kg/m2/s
3153+
endif
3154+
endif
3155+
31283156
melt=melt*this%heat_density ! kg/s x J/kg = J/s
31293157
grd%calving_hflx(i,j)=grd%calving_hflx(i,j)+melt/grd%area(i,j)*this%mass_scaling ! W/m2
31303158
bergs%net_heat_to_ocean=bergs%net_heat_to_ocean+melt*this%mass_scaling*bergs%dt ! J
@@ -5145,6 +5173,7 @@ subroutine icebergs_run(bergs, time, calving, uo, vo, ui, vi, tauxa, tauya, ssh,
51455173
grd%mass(:,:)=0.
51465174
grd%virtual_area(:,:)=0.
51475175
grd%melt_by_class(:,:,:)=0.
5176+
grd%melt_by_ice_sheet_basin(:,:,:) = 0.
51485177
grd%melt_buoy_fl(:,:)=0.
51495178
grd%melt_eros_fl(:,:)=0.
51505179
grd%melt_conv_fl(:,:)=0.
@@ -5606,6 +5635,10 @@ subroutine icebergs_run(bergs, time, calving, uo, vo, ui, vi, tauxa, tauya, ssh,
56065635
lerr=send_data(grd%id_fay, tauya(:,:), Time)
56075636
if (grd%id_melt_by_class>0) &
56085637
lerr=send_data(grd%id_melt_by_class, grd%melt_by_class(grd%isc:grd%iec,grd%jsc:grd%jec,:), Time)
5638+
if (grd%id_melt_by_ice_sheet_basin>0) &
5639+
lerr=send_data(grd%id_melt_by_ice_sheet_basin, grd%melt_by_ice_sheet_basin(grd%isc:grd%iec,grd%jsc:grd%jec,:), Time)
5640+
if (grd%id_ice_sheet_basins>0) &
5641+
lerr=send_data(grd%id_ice_sheet_basins, grd%ice_sheet_basins(grd%isc:grd%iec,grd%jsc:grd%jec), Time)
56095642
if (grd%id_melt_buoy_fl>0) &
56105643
lerr=send_data(grd%id_melt_buoy_fl, grd%melt_buoy_fl(grd%isc:grd%iec,grd%jsc:grd%jec), Time)
56115644
if (grd%id_melt_eros_fl>0) &
@@ -6355,6 +6388,13 @@ subroutine calve_icebergs(bergs)
63556388
newberg%ang_vel=0.; newberg%ang_accel=0.; newberg%rot=0.
63566389
endif
63576390

6391+
if (bergs%use_berg_origin_basins) then
6392+
if (.not. allocations_done) then
6393+
if (.not. allocated(newberg%basin)) allocate(newberg%basin)
6394+
endif
6395+
newberg%basin=int(grd%ice_sheet_basins(i,j))
6396+
endif
6397+
63586398
if (.not. bergs%old_interp_flds_order) then
63596399
!interpolate gridded variables to new iceberg
63606400
if (grd%tidal_drift>0.) then
@@ -6565,6 +6605,11 @@ subroutine calve_fl_icebergs(bergs,pberg,k,l_b,fl_disp_x,fl_disp_y,berg_from_bit
65656605
cberg%ang_vel=0.; cberg%ang_accel=0.; cberg%rot=0.
65666606
endif
65676607

6608+
if (bergs%use_berg_origin_basins) then
6609+
allocate(cberg%basin)
6610+
cberg%basin=pberg%basin
6611+
endif
6612+
65686613
call add_new_berg_to_list(bergs%list(cberg%ine,cberg%jne)%first, cberg)
65696614
end subroutine calve_fl_icebergs
65706615

@@ -8223,6 +8268,8 @@ subroutine icebergs_end(bergs)
82238268
deallocate(bergs%grd%cn)
82248269
deallocate(bergs%grd%hi)
82258270
deallocate(bergs%grd%melt_by_class)
8271+
deallocate(bergs%grd%melt_by_ice_sheet_basin)
8272+
deallocate(bergs%grd%ice_sheet_basins)
82268273
deallocate(bergs%grd%melt_buoy_fl)
82278274
deallocate(bergs%grd%melt_eros_fl)
82288275
deallocate(bergs%grd%melt_conv_fl)

src/icebergs_fms2io.F90

Lines changed: 77 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -44,12 +44,12 @@ module ice_bergs_fms2io
4444
use ice_bergs_framework, only: force_all_pes_traj
4545
use ice_bergs_framework, only: check_for_duplicates_in_parallel
4646
use ice_bergs_framework, only: split_id, id_from_2_ints, generate_id
47-
! for MTS/DEM/fracture/footloose:
47+
! for MTS/DEM/fracture/footloose/basins:
4848
use ice_bergs_framework, only: mts,save_bond_traj
4949
use ice_bergs_framework, only: push_bond_posn, append_bond_posn
5050
use ice_bergs_framework, only: pack_bond_traj_into_buffer2,unpack_bond_traj_from_buffer2
5151
use ice_bergs_framework, only: dem, iceberg_bonds_on
52-
use ice_bergs_framework, only: footloose
52+
use ice_bergs_framework, only: footloose, use_berg_origin_basins
5353

5454

5555
implicit none ; private
@@ -59,7 +59,7 @@ module ice_bergs_fms2io
5959
public ice_bergs_io_init
6060
public read_restart_bergs, write_restart_bergs, write_trajectory, write_bond_trajectory
6161
public read_restart_calving, read_restart_bonds
62-
public read_ocean_depth
62+
public read_ocean_depth, read_ice_sheet_basins
6363

6464
!Local Vars
6565
integer, parameter :: file_format_major_version=0
@@ -187,7 +187,8 @@ subroutine write_restart_bergs(bergs, time_stamp)
187187
first_berg_ine, &
188188
other_berg_jne, &
189189
other_berg_ine, &
190-
broken
190+
broken, &
191+
basin
191192

192193

193194
integer :: grdi, grdj
@@ -258,6 +259,7 @@ subroutine write_restart_bergs(bergs, time_stamp)
258259
allocate(ang_accel(nbergs))
259260
allocate(rot(nbergs))
260261
endif
262+
if (use_berg_origin_basins) allocate(basin(nbergs))
261263

262264
i = 0
263265
do grdj = bergs%grd%jsc,bergs%grd%jec ; do grdi = bergs%grd%isc,bergs%grd%iec
@@ -296,6 +298,7 @@ subroutine write_restart_bergs(bergs, time_stamp)
296298
ang_accel(i) = this%ang_accel
297299
rot(i) = this%rot
298300
endif
301+
if (use_berg_origin_basins) basin(i) = this%basin
299302
this=>this%next
300303
enddo
301304
enddo ; enddo
@@ -393,6 +396,10 @@ subroutine write_restart_bergs(bergs, time_stamp)
393396
dim_names_1d,longname='dem accumulated rotation',units='rad')
394397
endif
395398

399+
if (use_berg_origin_basins) then
400+
call register_restart_field_wrap(fileobj,'basin',basin,&
401+
dim_names_1d,longname='ice-sheet basin of origin',units='none')
402+
endif
396403
!Checking if any icebergs are static in order to decide whether to save static_berg
397404
n_static_bergs = 0
398405
do grdj = bergs%grd%jsc,bergs%grd%jec ; do grdi = bergs%grd%isc,bergs%grd%iec
@@ -457,6 +464,8 @@ subroutine write_restart_bergs(bergs, time_stamp)
457464
rot)
458465
endif
459466

467+
if (use_berg_origin_basins) deallocate(basin)
468+
460469
deallocate( &
461470
ine, &
462471
jne, &
@@ -711,7 +720,8 @@ subroutine read_restart_bergs(bergs,Time)
711720
iceberg_num,&
712721
id_cnt, &
713722
id_ij, &
714-
start_year
723+
start_year, &
724+
basin
715725

716726
type(FmsNetcdfDomainFile_t) :: fileobj !< Fms2_io fileobj
717727
character(len=1), dimension(1) :: dim_names_1d
@@ -809,6 +819,10 @@ subroutine read_restart_bergs(bergs,Time)
809819
allocate(ang_accel(nbergs_in_file))
810820
allocate(rot(nbergs_in_file))
811821
endif
822+
if (use_berg_origin_basins) then
823+
allocate(localberg%basin)
824+
allocate(basin(nbergs_in_file))
825+
endif
812826

813827
call register_restart_field(fileobj,'lon',lon,dim_names_1d)
814828
call register_restart_field(fileobj,'lat',lat,dim_names_1d)
@@ -858,6 +872,11 @@ subroutine read_restart_bergs(bergs,Time)
858872
call register_restart_field(fileobj,'ang_accel',ang_accel,dim_names_1d,is_optional=.true.)
859873
call register_restart_field(fileobj,'rot' ,rot ,dim_names_1d,is_optional=.true.)
860874
endif
875+
876+
if (use_berg_origin_basins) then
877+
basin = 0
878+
call register_restart_field(fileobj,'basin' ,basin ,dim_names_1d,is_optional=.true.)
879+
endif
861880
call read_restart(fileobj)
862881
call close_file(fileobj)
863882
elseif (bergs%require_restart) then
@@ -943,6 +962,10 @@ subroutine read_restart_bergs(bergs,Time)
943962
localberg%rot =rot(k)
944963
endif
945964

965+
if (use_berg_origin_basins) then
966+
localberg%basin =basin(k)
967+
endif
968+
946969
if (really_debug) lres=is_point_in_cell(grd, localberg%lon, localberg%lat, localberg%ine, localberg%jne, explain=.true.)
947970
lres=pos_within_cell(grd, localberg%lon, localberg%lat, localberg%ine, localberg%jne, localberg%xi, localberg%yj)
948971
!call add_new_berg_to_list(bergs%first, localberg)
@@ -1001,6 +1024,7 @@ subroutine read_restart_bergs(bergs,Time)
10011024
ang_accel, &
10021025
rot)
10031026
endif
1027+
if (use_berg_origin_basins) deallocate(basin)
10041028

10051029
if (replace_iceberg_num) then
10061030
deallocate(iceberg_num)
@@ -1076,6 +1100,7 @@ subroutine generate_bergs(bergs,Time)
10761100
allocate(localberg%ang_accel)
10771101
allocate(localberg%rot)
10781102
endif
1103+
if (use_berg_origin_basins) allocate(localberg%basin)
10791104

10801105
do j=grd%jsc,grd%jec; do i=grd%isc,grd%iec
10811106
if (grd%msk(i,j)>0. .and. abs(grd%latc(i,j))>80.0) then
@@ -1125,6 +1150,9 @@ subroutine generate_bergs(bergs,Time)
11251150
localberg%ang_accel=0.
11261151
localberg%rot=0.
11271152
endif
1153+
if (use_berg_origin_basins) then
1154+
localberg%basin=0
1155+
endif
11281156

11291157
!Berg A
11301158
call loc_set_berg_pos(grd, 0.9, 0.5, 1., 0., localberg)
@@ -1603,7 +1631,7 @@ subroutine read_ocean_depth(grd)
16031631
! Local variables
16041632
character(len=37) :: filename
16051633
type(FmsNetcdfDomainFile_t) :: fileobj !< Fms2_io fileobj
1606-
! Read stored ice
1634+
! Read depth
16071635
filename=trim(restart_input_dir)//'topog.nc'
16081636
if (open_file(fileobj, filename, "read", grd%domain)) then
16091637
if (mpp_pe().eq.mpp_root_pe()) write(*,'(2a)') &
@@ -1627,6 +1655,34 @@ subroutine read_ocean_depth(grd)
16271655
!call grd_chksum2(bergs%grd, bergs%grd%ocean_depth, 'read_ocean_depth, ocean_depth')
16281656
end subroutine read_ocean_depth
16291657

1658+
!> Read ice-sheet basins from file
1659+
subroutine read_ice_sheet_basins(grd)
1660+
! Arguments
1661+
type(icebergs_gridded), pointer :: grd !< Container for gridded fields
1662+
! Local variables
1663+
character(len=37) :: filename, actual_filename
1664+
type(FmsNetcdfDomainFile_t) :: fileobj !< Fms2_io fileobj
1665+
! Read sub_basin
1666+
filename=trim(restart_input_dir)//'ice_sheet_basins.nc'
1667+
if (open_file(fileobj, filename, "read", grd%domain)) then
1668+
if (mpp_pe().eq.mpp_root_pe()) write(*,'(3a)') &
1669+
'KID, read_ice_sheet_basins: reading ',actual_filename, filename
1670+
call register_axis_wrapper(fileobj)
1671+
if (variable_exists(fileobj, "sub_basin")) then
1672+
if (verbose.and.mpp_pe().eq.mpp_root_pe()) write(*,'(a)') &
1673+
'KID, read_ice_sheet_basins: reading sub_basins from ice-shelf basins file.'
1674+
call read_data(fileobj, 'sub_basin', grd%ice_sheet_basins)
1675+
else
1676+
call error_mesg('KID, read_ice_sheet_basins', &
1677+
'variable sub_basin ice_sheet_basins.nc not found in ice_sheet_basins.nc!', FATAL)
1678+
endif
1679+
call close_file(fileobj)
1680+
else
1681+
call error_mesg('KID, read_ice_sheet_basins', 'ice_sheet_basins.nc not found!', FATAL)
1682+
endif
1683+
1684+
end subroutine read_ice_sheet_basins
1685+
16301686
!> Write a trajectory-based diagnostics file
16311687
subroutine write_trajectory(trajectory, save_short_traj, save_fl_traj, traj_name)
16321688
! Arguments
@@ -1642,7 +1698,7 @@ subroutine write_trajectory(trajectory, save_short_traj, save_fl_traj, traj_name
16421698
integer :: cnid, hiid, hsid
16431699
integer :: mid, smid, did, wid, lid, mbid, mflbid, mflbbid, hdid, nbid, odid, flkid
16441700
integer :: axnid,aynid,bxnid,bynid,axnfid,aynfid,bxnfid,bynfid, msid
1645-
integer :: avid, aaid, rid
1701+
integer :: avid, aaid, rid, baid
16461702
character(len=70) :: filename
16471703
character(len=7) :: pe_name
16481704
type(xyt), pointer :: this, next
@@ -1819,6 +1875,9 @@ subroutine write_trajectory(trajectory, save_short_traj, save_fl_traj, traj_name
18191875
rid = inq_varid(ncid, 'rot')
18201876
endif
18211877

1878+
if (use_berg_origin_basins) then
1879+
baid = inq_varid(ncid, 'basin')
1880+
endif
18221881
endif
18231882
else
18241883
! Dimensions
@@ -1889,6 +1948,10 @@ subroutine write_trajectory(trajectory, save_short_traj, save_fl_traj, traj_name
18891948
aaid = def_var(ncid, 'ang_accel', NF_DOUBLE, i_dim)
18901949
rid = def_var(ncid, 'rot', NF_DOUBLE, i_dim)
18911950
endif
1951+
1952+
if (use_berg_origin_basins) then
1953+
baid = def_var(ncid, 'basin', NF_INT, i_dim)
1954+
endif
18921955
endif
18931956

18941957
! Attributes
@@ -2006,6 +2069,10 @@ subroutine write_trajectory(trajectory, save_short_traj, save_fl_traj, traj_name
20062069
call put_att(ncid, rid, 'long_name', 'accumulated rotation')
20072070
call put_att(ncid, rid, 'units', 'rad')
20082071
endif
2072+
if (use_berg_origin_basins) then
2073+
call put_att(ncid, baid, 'long_name', 'ice-sheet basin of origin')
2074+
call put_att(ncid, baid, 'units', 'none')
2075+
endif
20092076
endif
20102077
endif
20112078

@@ -2087,6 +2154,9 @@ subroutine write_trajectory(trajectory, save_short_traj, save_fl_traj, traj_name
20872154
call put_double(ncid, rid, i, this%rot)
20882155
endif
20892156

2157+
if (use_berg_origin_basins) then
2158+
call put_int(ncid, baid, i, this%basin)
2159+
endif
20902160
endif
20912161
next=>this%next
20922162
deallocate(this)

0 commit comments

Comments
 (0)