@@ -28,6 +28,7 @@ module topography
28
28
procedure :: copy = > topography_copy
29
29
generic :: assignment (= ) = > copy
30
30
procedure :: update_history = > topography_update_history
31
+ procedure :: number_seas = > topography_number_seas
31
32
procedure :: deseas = > topography_deseas
32
33
procedure :: fill_fraction = > topography_fill_fraction
33
34
procedure :: nonadvective = > topography_nonadvective
@@ -220,23 +221,34 @@ subroutine topography_update_history(this, command)
220
221
end subroutine topography_update_history
221
222
222
223
!- ------------------------------------------------------------------------
223
- subroutine topography_deseas (this )
224
- class(topography_t), intent (inout ) :: this
224
+ subroutine topography_number_seas (this , sea_number , number_of_seas , silent )
225
+ class(topography_t), intent (in ) :: this
226
+ integer (int16), intent (out ), target , optional :: sea_number(:,:)
227
+ integer (int32), intent (out ), optional :: number_of_seas
228
+ logical , intent (in ), optional :: silent
225
229
226
- integer (int32) :: i, j, counter, its, its1, its2, sea_num, iblock, jblock
230
+ integer (int32) :: i, j, counter, its, its1, its2, sea_num
227
231
integer (int32) :: im, ip, jm, jp, land
228
232
229
- integer (int32) :: ncid, sea_id, dids(2 ) ! NetCDF ids
230
-
231
233
integer (int16) :: new_sea
232
- integer (int16), allocatable :: sea(:,:)
234
+ integer (int16), pointer :: sea(:,:)
233
235
234
- logical :: choke_west, choke_east, choke_north, choke_south
236
+ logical :: silent_, choke_west, choke_east, choke_north, choke_south
235
237
236
- allocate (sea(this% nxt, this% nyt))
238
+ integer (int16), parameter :: MAX_ITER = 150
239
+
240
+ if (present (sea_number)) then
241
+ sea = > sea_number
242
+ else
243
+ allocate (sea(this% nxt, this% nyt))
244
+ end if
245
+ if (present (silent)) then
246
+ silent_ = silent
247
+ else
248
+ silent_ = .false.
249
+ end if
237
250
238
251
! Do
239
- write (output_unit,' (a)' ) " Removing seas"
240
252
land = this% nxt + this% nyt + 1
241
253
sea = land
242
254
do j = 1 , this% nyt
@@ -246,7 +258,9 @@ subroutine topography_deseas(this)
246
258
if (all (this% depth(:, j) > 0.0 )) sea(:, j) = 0 ! Southern Ocean all water across
247
259
end do
248
260
249
- do its = 1 , 150 ! Only need high number after massive editing session with fjords. Normally 10 or so sweeps works.
261
+ if (.not. silent_) write (output_unit,' (a)' ) " # Iter # Changes # Seas"
262
+
263
+ do its = 1 , MAX_ITER ! Only need high number after massive editing session with fjords. Normally 10 or so sweeps works.
250
264
counter = 0
251
265
sea_num = 0
252
266
@@ -363,24 +377,40 @@ subroutine topography_deseas(this)
363
377
counter = counter + 1
364
378
end if
365
379
end do
366
- write (output_unit,* ) counter, sea_num
380
+
381
+ if (.not. silent_) write (output_unit,* ) its, counter, sea_num + 1
367
382
368
383
! If we only have one sea or no changes are made we are finished.
369
- if (counter == 0 .or. sea_num == 1 ) exit
384
+ if (counter == 0 .or. sea_num + 1 == 1 ) exit
385
+ if (its == MAX_ITER) then
386
+ write (output_unit, ' (a)' ) " WARNING: could not number all the seas. Algorithm reached maximum number of iterations."
387
+ end if
370
388
end do
371
389
372
- write (output_unit,' (a)' ) " Done"
390
+ if (present (sea_number)) then
391
+ nullify(sea)
392
+ else
393
+ deallocate (sea)
394
+ end if
373
395
374
- ! Write out new topography
375
- do j = 1 , this% nyt
376
- do i = 1 , this% nxt
377
- if (sea(i, j) > 0 ) then
378
- this% depth(i, j) = MISSING_VALUE
379
- this% frac(i, j) = MISSING_VALUE
380
- end if
381
- end do
382
- end do
383
- this% lakes_removed = " yes"
396
+ if (present (number_of_seas)) then
397
+ number_of_seas = sea_num + 1
398
+ end if
399
+
400
+ end subroutine topography_number_seas
401
+
402
+ !- ------------------------------------------------------------------------
403
+ subroutine topography_deseas (this )
404
+ class(topography_t), intent (inout ) :: this
405
+
406
+ integer (int32) :: ncid, sea_id, dids(2 ) ! NetCDF ids
407
+ integer (int16), allocatable :: sea(:,:)
408
+
409
+ allocate (sea(this% nxt, this% nyt))
410
+
411
+ write (output_unit,' (a)' ) " Numbering seas"
412
+
413
+ call this% number_seas(sea_number= sea)
384
414
385
415
call handle_error(nf90_create(trim (' sea_num.nc' ), ior (nf90_netcdf4, nf90_clobber), ncid))
386
416
call handle_error(nf90_def_dim(ncid, ' nx' , this% nxt, dids(1 )))
@@ -391,6 +421,15 @@ subroutine topography_deseas(this)
391
421
call handle_error(nf90_put_var(ncid, sea_id, sea))
392
422
call handle_error(nf90_close(ncid))
393
423
424
+ write (output_unit,' (a)' ) " Removing seas"
425
+ where (sea > 0 )
426
+ this% depth = MISSING_VALUE
427
+ this% frac = MISSING_VALUE
428
+ end where
429
+ this% lakes_removed = " yes"
430
+
431
+ deallocate (sea)
432
+
394
433
end subroutine topography_deseas
395
434
396
435
!- ------------------------------------------------------------------------
@@ -444,6 +483,8 @@ subroutine topography_fill_fraction(this, sea_area_fraction)
444
483
class(topography_t), intent (inout ) :: this
445
484
real (real32), intent (in ) :: sea_area_fraction
446
485
486
+ integer (int32) :: nseas
487
+
447
488
write (output_unit,' (a,f7.2)' ) " Filling cells that have a sea area fraction smaller than " , sea_area_fraction
448
489
449
490
if (any (this% frac < sea_area_fraction)) then
@@ -453,13 +494,15 @@ subroutine topography_fill_fraction(this, sea_area_fraction)
453
494
end where
454
495
455
496
if (this% lakes_removed == ' yes' ) then
456
- ! We might have created new lakes, so update the corresponding attribute
457
- this% lakes_removed = ' no'
497
+ ! Check if new seas have been created
498
+ call this% number_seas(number_of_seas = nseas, silent= .true. )
499
+ if (nseas > 1 ) then
500
+ write (output_unit,' (a)' ) " WARNING: new seas have been created. To fix, rerun deseas again."
501
+ this% lakes_removed = ' no'
502
+ end if
458
503
end if
459
504
end if
460
505
461
- write (output_unit,' (a)' ) " Done"
462
-
463
506
end subroutine topography_fill_fraction
464
507
465
508
!- ------------------------------------------------------------------------
@@ -471,13 +514,14 @@ subroutine topography_nonadvective(this, vgrid, potholes, coastal, fix)
471
514
real (real32), allocatable :: depth_halo(:,:)
472
515
integer (int32), allocatable :: num_levels(:,:)
473
516
real (real32), allocatable :: zw(:), zeta(:)
474
- integer (int32) :: passes, i, j, k, ni, nj, nzeta, nz, its, counter
517
+ integer (int32) :: passes, i, j, k, ni, nj, nzeta, nz, its, coastal_counter, potholes_counter
475
518
integer (int32) :: ncid, vid
476
519
integer (int32) :: dids(2 )
477
520
logical :: se, sw, ne, nw ! .TRUE. if C-cell centre is shallower than T cell centre.
478
521
logical :: changes_made = .false.
479
522
integer (int32) :: kse, ksw, kne, knw, kmu_max
480
523
integer (int32) :: im, ip, jm, jp
524
+ integer (int32) :: nseas
481
525
482
526
call handle_error(nf90_open(trim (vgrid), nf90_nowrite, ncid))
483
527
call handle_error(nf90_inq_varid(ncid, ' zeta' , vid))
@@ -496,11 +540,15 @@ subroutine topography_nonadvective(this, vgrid, potholes, coastal, fix)
496
540
497
541
if (fix) then
498
542
passes = 20
543
+ write (output_unit,' (a)' ) " Fixing non-advective cells"
499
544
else
545
+ write (output_unit,' (a)' ) " Checking for non-advective cells"
500
546
passes = 1
501
547
end if
502
548
do its = 1 , passes
503
- counter = 0
549
+ if (fix) write (output_unit,' (a,i0)' ) " Pass # " , its
550
+ coastal_counter = 0
551
+ potholes_counter = 0
504
552
num_levels = 0
505
553
506
554
depth_halo = 0
@@ -522,6 +570,10 @@ subroutine topography_nonadvective(this, vgrid, potholes, coastal, fix)
522
570
end do
523
571
524
572
if (coastal) then
573
+ if (.not. fix) then
574
+ write (output_unit,' (a)' ) " Coastal cells"
575
+ write (output_unit,' (a)' ) " i j Depth"
576
+ end if
525
577
do j = 2 , this% nyt - 1
526
578
do i = 1 , this% nxt
527
579
if (depth_halo(i, j) > 0.5 ) then
@@ -534,18 +586,23 @@ subroutine topography_nonadvective(this, vgrid, potholes, coastal, fix)
534
586
depth_halo(i, j) = 0.0
535
587
this% frac(i, j) = 0.0
536
588
num_levels(i, j) = 0
589
+ else
590
+ write (output_unit,* ) i, j, 0.0 ,' ! nonadvective'
537
591
end if
538
- counter = counter + 1
539
- write (output_unit,* ) i, j, 0.0 ,' ! nonadvective'
592
+ coastal_counter = coastal_counter + 1
540
593
end if
541
594
end if
542
595
end do
543
596
end do
544
597
545
- write (output_unit,* ) ' 1 ' , counter
598
+ write (output_unit,' (a,i0,a) ' ) ' Found ' , coastal_counter, ' non-advective coastal cells '
546
599
end if
547
600
548
601
if (potholes) then
602
+ if (.not. fix) then
603
+ write (output_unit,' (a)' ) " Potholes"
604
+ write (output_unit,' (a)' ) " i j Level Max. halo level"
605
+ end if
549
606
do j = 2 , this% nyt
550
607
jm = j - 1
551
608
jp = j + 1
@@ -565,25 +622,29 @@ subroutine topography_nonadvective(this, vgrid, potholes, coastal, fix)
565
622
num_levels(i, j) = kmu_max
566
623
depth_halo(i, j) = zw(kmu_max)
567
624
else
568
- write (output_unit,* ) i, j, ' nonadvective, Deep ' , num_levels(i, j), kmu_max
625
+ write (output_unit,* ) i, j, num_levels(i, j), kmu_max
569
626
end if
570
- counter = counter + 1
627
+ potholes_counter = potholes_counter + 1
571
628
end if
572
629
end if
573
630
end do
574
631
end do
575
- write (output_unit,* ) counter
632
+ write (output_unit,' (a,i0,a) ' ) ' Found ' , potholes_counter, ' non-advective potholes '
576
633
end if
577
- if (counter > 0 .and. fix) changes_made = .true.
634
+ if ((coastal_counter > 0 .or. potholes_counter > 0 ) .and. fix) changes_made = .true.
578
635
this% depth = depth_halo(1 :this% nxt, 1 :this% nyt)
579
- if (counter == 0 .and. fix) exit
636
+ if (coastal_counter == 0 .and. potholes_counter == 0 .and. fix) exit
580
637
end do
581
638
582
639
if (fix .and. (coastal .or. potholes)) then
583
640
this% nonadvective_cells_removed = ' yes'
584
641
if (changes_made .and. this% lakes_removed == ' yes' ) then
585
- ! We might have created new lakes, so rerun deseas
586
- call this% deseas()
642
+ ! Check if new lakes were created new lakes
643
+ call this% number_seas(number_of_seas = nseas, silent= .true. )
644
+ if (nseas > 1 ) then
645
+ write (output_unit,' (a)' ) " WARNING: new seas have been created. To fix, rerun deseas again."
646
+ this% lakes_removed = ' no'
647
+ end if
587
648
end if
588
649
end if
589
650
0 commit comments