11 use atlas_module,
only: atlas_functionspace_pointcloud, atlas_fieldset, &
12 atlas_field, atlas_real, atlas_integer, atlas_geometry, atlas_indexkdtree
13 use fckit_configuration_module,
only: fckit_configuration
14 use fckit_mpi_module,
only: fckit_mpi_comm
15 use kinds,
only: kind_real
18 use fms_io_mod,
only : fms_io_init, fms_io_exit, &
19 register_restart_field, restart_file_type, &
20 restore_state, free_restart_type, save_restart
21 use mom_diag_remap,
only : diag_remap_ctrl, diag_remap_init, diag_remap_configure_axes, &
22 diag_remap_end, diag_remap_update
23 use mom_domains,
only : mom_domain_type
24 use mom_eos,
only : eos_type
25 use mpp_domains_mod,
only : mpp_get_compute_domain, mpp_get_data_domain, &
26 mpp_get_global_domain, mpp_update_domains
44 type(mom_domain_type),
pointer :: domain
45 integer :: nzo, nzo_zstar
49 integer :: isc, iec, jsc, jec
54 integer :: isd, ied, jsd, jed
59 integer :: isg, ieg, jsg, jeg
64 integer :: iscl, iecl, jscl, jecl
69 integer :: isdl, iedl, jsdl, jedl
74 real(kind=kind_real),
allocatable,
dimension(:) :: lonh
75 real(kind=kind_real),
allocatable,
dimension(:) :: lath
76 real(kind=kind_real),
allocatable,
dimension(:) :: lonq
77 real(kind=kind_real),
allocatable,
dimension(:) :: latq
78 real(kind=kind_real),
allocatable,
dimension(:,:) :: lon
79 real(kind=kind_real),
allocatable,
dimension(:,:) :: lat
80 real(kind=kind_real),
allocatable,
dimension(:,:) :: lonu
81 real(kind=kind_real),
allocatable,
dimension(:,:) :: latu
82 real(kind=kind_real),
allocatable,
dimension(:,:) :: lonv
83 real(kind=kind_real),
allocatable,
dimension(:,:) :: latv
90 real(kind=kind_real),
allocatable,
dimension(:,:) :: mask2d
92 real(kind=kind_real),
allocatable,
dimension(:,:) :: mask2du
94 real(kind=kind_real),
allocatable,
dimension(:,:) :: mask2dv
99 real(kind=kind_real),
allocatable,
dimension(:,:) :: sin_rot
100 real(kind=kind_real),
allocatable,
dimension(:,:) :: cos_rot
101 real(kind=kind_real),
allocatable,
dimension(:,:) :: cell_area
102 real(kind=kind_real),
allocatable,
dimension(:,:) :: rossby_radius
103 real(kind=kind_real),
allocatable,
dimension(:,:) :: distance_from_coast
104 real(kind=kind_real),
allocatable,
dimension(:,:,:) :: h
105 real(kind=kind_real),
allocatable,
dimension(:,:,:) :: h_zstar
111 logical,
private :: save_local_domain = .false.
112 character(len=:),
allocatable :: geom_grid_file
113 type(fckit_mpi_comm) :: f_comm
114 type(atlas_functionspace_pointcloud) :: afunctionspace
121 procedure :: init => soca_geom_init
124 procedure :: end => soca_geom_end
127 procedure :: set_atlas_lonlat => soca_geom_set_atlas_lonlat
130 procedure :: fill_atlas_fieldset => soca_geom_fill_atlas_fieldset
133 procedure :: clone => soca_geom_clone
136 procedure :: gridgen => soca_geom_gridgen
139 procedure :: thickness2depth => soca_geom_thickness2depth
142 procedure :: struct2atlas => soca_geom_struct2atlas
145 procedure :: atlas2struct => soca_geom_atlas2struct
148 procedure :: write => soca_geom_write
160 subroutine soca_geom_init(self, f_conf, f_comm)
162 type(fckit_configuration),
intent(in) :: f_conf
163 type(fckit_mpi_comm),
intent(in) :: f_comm
165 character(len=:),
allocatable :: str
166 logical :: full_init = .false.
175 if ( .not. f_conf%get(
"geom_grid_file", self%geom_grid_file) ) &
176 self%geom_grid_file =
"soca_gridspec.nc"
179 call soca_geom_allocate(self)
182 if ( .not. f_conf%get(
"full_init", full_init) ) full_init = .false.
186 if ( .not. full_init)
call soca_geom_read(self)
189 call mpp_update_domains(self%lon, self%Domain%mpp_domain)
190 call mpp_update_domains(self%lat, self%Domain%mpp_domain)
191 call mpp_update_domains(self%lonu, self%Domain%mpp_domain)
192 call mpp_update_domains(self%latu, self%Domain%mpp_domain)
193 call mpp_update_domains(self%lonv, self%Domain%mpp_domain)
194 call mpp_update_domains(self%latv, self%Domain%mpp_domain)
195 call mpp_update_domains(self%sin_rot, self%Domain%mpp_domain)
196 call mpp_update_domains(self%cos_rot, self%Domain%mpp_domain)
197 call mpp_update_domains(self%mask2d, self%Domain%mpp_domain)
198 call mpp_update_domains(self%mask2du, self%Domain%mpp_domain)
199 call mpp_update_domains(self%mask2dv, self%Domain%mpp_domain)
200 call mpp_update_domains(self%cell_area, self%Domain%mpp_domain)
201 call mpp_update_domains(self%rossby_radius, self%Domain%mpp_domain)
202 call mpp_update_domains(self%distance_from_coast, self%Domain%mpp_domain)
205 if ( .not. f_conf%get(
"save_local_domain", self%save_local_domain) ) &
206 self%save_local_domain = .false.
209 call f_conf%get_or_die(
"fields metadata", str)
210 call self%fields_metadata%create(str)
212 end subroutine soca_geom_init
219 subroutine soca_geom_end(self)
222 if (
allocated(self%lonh))
deallocate(self%lonh)
223 if (
allocated(self%lath))
deallocate(self%lath)
224 if (
allocated(self%lonq))
deallocate(self%lonq)
225 if (
allocated(self%latq))
deallocate(self%latq)
226 if (
allocated(self%lon))
deallocate(self%lon)
227 if (
allocated(self%lat))
deallocate(self%lat)
228 if (
allocated(self%lonu))
deallocate(self%lonu)
229 if (
allocated(self%latu))
deallocate(self%latu)
230 if (
allocated(self%lonv))
deallocate(self%lonv)
231 if (
allocated(self%latv))
deallocate(self%latv)
232 if (
allocated(self%sin_rot))
deallocate(self%sin_rot)
233 if (
allocated(self%cos_rot))
deallocate(self%cos_rot)
234 if (
allocated(self%mask2d))
deallocate(self%mask2d)
235 if (
allocated(self%mask2du))
deallocate(self%mask2du)
236 if (
allocated(self%mask2dv))
deallocate(self%mask2dv)
237 if (
allocated(self%cell_area))
deallocate(self%cell_area)
238 if (
allocated(self%rossby_radius))
deallocate(self%rossby_radius)
239 if (
allocated(self%distance_from_coast))
deallocate(self%distance_from_coast)
240 if (
allocated(self%h))
deallocate(self%h)
241 if (
allocated(self%h_zstar))
deallocate(self%h_zstar)
243 call self%afunctionspace%final()
245 end subroutine soca_geom_end
252 subroutine soca_geom_set_atlas_lonlat(self, afieldset)
254 type(atlas_fieldset),
intent(inout) :: afieldset
256 real(kind_real),
pointer :: real_ptr(:,:)
257 type(atlas_field) :: afield
260 afield = atlas_field(name=
"lonlat", kind=atlas_real(kind_real), shape=(/2,(self%iec-self%isc+1)*(self%jec-self%jsc+1)/))
261 call afield%data(real_ptr)
262 real_ptr(1,:) = reshape(self%lon(self%isc:self%iec,self%jsc:self%jec),(/(self%iec-self%isc+1)*(self%jec-self%jsc+1)/))
263 real_ptr(2,:) = reshape(self%lat(self%isc:self%iec,self%jsc:self%jec),(/(self%iec-self%isc+1)*(self%jec-self%jsc+1)/))
264 call afieldset%add(afield)
266 end subroutine soca_geom_set_atlas_lonlat
273 subroutine soca_geom_fill_atlas_fieldset(self, afieldset)
275 type(atlas_fieldset),
intent(inout) :: afieldset
278 integer,
pointer :: int_ptr_2(:,:)
279 real(kind=kind_real),
pointer :: real_ptr_1(:), real_ptr_2(:,:)
280 type(atlas_field) :: afield
283 afield = self%afunctionspace%create_field(name=
'area', kind=atlas_real(kind_real), levels=0)
284 call afield%data(real_ptr_1)
285 real_ptr_1 = reshape(self%cell_area(self%isc:self%iec,self%jsc:self%jec),(/(self%iec-self%isc+1)*(self%jec-self%jsc+1)/))
286 call afieldset%add(afield)
290 afield = self%afunctionspace%create_field(name=
'vunit', kind=atlas_real(kind_real), levels=self%nzo)
291 call afield%data(real_ptr_2)
293 real_ptr_2(jz,:) = real(jz, kind_real)
295 call afieldset%add(afield)
299 afield = self%afunctionspace%create_field(name=
'gmask', kind=atlas_integer(kind(0)), levels=self%nzo)
300 call afield%data(int_ptr_2)
302 int_ptr_2(jz,:) = int(reshape(self%mask2d(self%isc:self%iec,self%jsc:self%jec), &
303 & (/(self%iec-self%isc+1)*(self%jec-self%jsc+1)/)))
305 call afieldset%add(afield)
308 end subroutine soca_geom_fill_atlas_fieldset
315 subroutine soca_geom_clone(self, other)
320 self%f_comm = other%f_comm
323 self%Domain => other%Domain
327 self%geom_grid_file = other%geom_grid_file
330 call soca_geom_allocate(self)
331 self%lonh = other%lonh
332 self%lath = other%lath
333 self%lonq = other%lonq
334 self%latq = other%latq
337 self%lonu = other%lonu
338 self%latu = other%latu
339 self%lonv = other%lonv
340 self%latv = other%latv
341 self%sin_rot = other%sin_rot
342 self%cos_rot = other%cos_rot
343 self%mask2d = other%mask2d
344 self%mask2du = other%mask2du
345 self%mask2dv = other%mask2dv
346 self%cell_area = other%cell_area
347 self%rossby_radius = other%rossby_radius
348 self%distance_from_coast = other%distance_from_coast
350 call self%fields_metadata%clone(other%fields_metadata)
351 end subroutine soca_geom_clone
358 subroutine soca_geom_gridgen(self)
363 type(diag_remap_ctrl) :: remap_ctrl
364 type(eos_type),
pointer :: eqn_of_state
366 real(kind=kind_real),
allocatable :: tracer(:,:,:)
367 logical :: answers_2018 = .false.
371 self%lonh = mom6_config%grid%gridlont
372 self%lath = mom6_config%grid%gridlatt
373 self%lonq = mom6_config%grid%gridlonb
374 self%latq = mom6_config%grid%gridlatb
375 self%lon = mom6_config%grid%GeoLonT
376 self%lat = mom6_config%grid%GeoLatT
377 self%lonu = mom6_config%grid%geoLonCu
378 self%latu = mom6_config%grid%geoLatCu
379 self%lonv = mom6_config%grid%geoLonCv
380 self%latv = mom6_config%grid%geoLatCv
382 self%sin_rot = mom6_config%grid%sin_rot
383 self%cos_rot = mom6_config%grid%cos_rot
385 self%mask2d = mom6_config%grid%mask2dT
386 self%mask2du = mom6_config%grid%mask2dCu
387 self%mask2dv = mom6_config%grid%mask2dCv
388 self%cell_area = mom6_config%grid%areaT
389 self%h = mom6_config%MOM_CSp%h
392 allocate(tracer(self%isd:self%ied, self%jsd:self%jed, self%nzo))
394 call diag_remap_init(remap_ctrl, coord_tuple=
'ZSTAR, ZSTAR, ZSTAR', answers_2018=answers_2018)
395 call diag_remap_configure_axes(remap_ctrl, mom6_config%GV, mom6_config%scaling, mom6_config%param_file)
396 self%nzo_zstar = remap_ctrl%nz
397 if (
allocated(self%h_zstar))
deallocate(self%h_zstar)
398 allocate(self%h_zstar(self%isd:self%ied, self%jsd:self%jed, 1:remap_ctrl%nz))
401 call diag_remap_update(remap_ctrl, &
404 mom6_config%scaling, &
405 self%h, tracer, tracer, eqn_of_state, self%h_zstar)
406 call diag_remap_end(remap_ctrl)
409 call soca_geom_rossby_radius(self)
411 call soca_geom_distance_from_coast(self)
414 call soca_geom_write(self)
416 end subroutine soca_geom_gridgen
423 subroutine soca_geom_allocate(self)
427 integer :: isd, ied, jsd, jed
430 call soca_geom_get_domain_indices(self,
"compute", self%isc, self%iec, self%jsc, self%jec)
431 call soca_geom_get_domain_indices(self,
"data", isd, ied, jsd, jed)
432 self%isd = isd ; self%ied = ied ; self%jsd = jsd; self%jed = jed
433 call soca_geom_get_domain_indices(self,
"global", self%isg, self%ieg, self%jsg, self%jeg)
434 call soca_geom_get_domain_indices(self,
"compute", self%iscl, self%iecl, self%jscl, self%jecl, local=.true.)
435 call soca_geom_get_domain_indices(self,
"data", self%isdl, self%iedl, self%jsdl, self%jedl, local=.true.)
439 allocate(self%lonh(self%isg:self%ieg)); self%lonh = 0.0_kind_real
440 allocate(self%lath(self%jsg:self%jeg)); self%lath = 0.0_kind_real
441 allocate(self%lonq(self%isg:self%ieg)); self%lonq = 0.0_kind_real
442 allocate(self%latq(self%jsg:self%jeg)); self%latq = 0.0_kind_real
443 allocate(self%lon(isd:ied,jsd:jed)); self%lon = 0.0_kind_real
444 allocate(self%lat(isd:ied,jsd:jed)); self%lat = 0.0_kind_real
445 allocate(self%lonu(isd:ied,jsd:jed)); self%lonu = 0.0_kind_real
446 allocate(self%latu(isd:ied,jsd:jed)); self%latu = 0.0_kind_real
447 allocate(self%lonv(isd:ied,jsd:jed)); self%lonv = 0.0_kind_real
448 allocate(self%latv(isd:ied,jsd:jed)); self%latv = 0.0_kind_real
450 allocate(self%sin_rot(isd:ied,jsd:jed)); self%sin_rot = 0.0_kind_real
451 allocate(self%cos_rot(isd:ied,jsd:jed)); self%cos_rot = 0.0_kind_real
453 allocate(self%mask2d(isd:ied,jsd:jed)); self%mask2d = 0.0_kind_real
454 allocate(self%mask2du(isd:ied,jsd:jed)); self%mask2du = 0.0_kind_real
455 allocate(self%mask2dv(isd:ied,jsd:jed)); self%mask2dv = 0.0_kind_real
457 allocate(self%cell_area(isd:ied,jsd:jed)); self%cell_area = 0.0_kind_real
458 allocate(self%rossby_radius(isd:ied,jsd:jed)); self%rossby_radius = 0.0_kind_real
459 allocate(self%distance_from_coast(isd:ied,jsd:jed)); self%distance_from_coast = 0.0_kind_real
460 allocate(self%h(isd:ied,jsd:jed,1:nzo)); self%h = 0.0_kind_real
462 end subroutine soca_geom_allocate
469 subroutine soca_geom_distance_from_coast(self)
472 type(atlas_indexkdtree) :: kd
473 type(atlas_geometry) :: ageometry
474 integer :: i, j, idx(1)
475 integer :: num_land_l, num_land
476 integer,
allocatable :: rcvcnt(:), displs(:)
477 real(kind=kind_real),
allocatable :: land_lon(:), land_lat(:)
478 real(kind=kind_real),
allocatable :: land_lon_l(:), land_lat_l(:)
479 real(kind=kind_real) :: closest_lon, closest_lat
485 allocate(rcvcnt(self%f_comm%size()))
486 allocate(displs(self%f_comm%size()))
488 num_land_l = count(self%mask2d(self%isc:self%iec, self%jsc:self%jec)==0.0)
489 call self%f_comm%allgather(num_land_l, rcvcnt)
490 num_land = sum(rcvcnt)
493 do j = 2, self%f_comm%size()
494 displs(j) = displs(j-1) + rcvcnt(j-1)
497 allocate(land_lon_l(num_land_l))
498 allocate(land_lat_l(num_land_l))
499 land_lon_l = pack(self%lon(self%isc:self%iec, self%jsc:self%jec), &
500 mask=self%mask2d(self%isc:self%iec,self%jsc:self%jec)==0.0)
501 land_lat_l = pack(self%lat(self%isc:self%iec, self%jsc:self%jec), &
502 mask=self%mask2d(self%isc:self%iec,self%jsc:self%jec)==0.0)
503 allocate(land_lon(num_land))
504 allocate(land_lat(num_land))
506 call self%f_comm%allgather(land_lon_l, land_lon, num_land_l, rcvcnt, displs)
507 call self%f_comm%allgather(land_lat_l, land_lat, num_land_l, rcvcnt, displs)
512 ageometry = atlas_geometry(
"Earth")
515 kd = atlas_indexkdtree(ageometry)
516 call kd%reserve(num_land)
517 call kd%build(num_land, land_lon, land_lat)
522 do i = self%isc, self%iec
523 do j = self%jsc, self%jec
524 call kd%closestPoints( self%lon(i,j), self%lat(i,j), 1, idx )
525 self%distance_from_coast(i,j) = ageometry%distance( &
526 self%lon(i,j), self%lat(i,j), land_lon(idx(1)), land_lat(idx(1)))
542 subroutine soca_geom_rossby_radius(self)
545 integer :: unit, i, n
546 real(kind=kind_real) :: dum
547 real(kind=kind_real),
allocatable :: lon(:),lat(:),rr(:)
548 integer :: isc, iec, jsc, jec
553 open(unit=unit,file=
"rossrad.dat",status=
"old",action=
"read")
556 read(unit,*,iostat=io)
561 allocate(lon(n),lat(n),rr(n))
563 read(unit,*) lat(i),lon(i),dum,rr(i)
571 isc = self%isc ; iec = self%iec ; jsc = self%jsc ; jec = self%jec
573 self%lat(isc:iec,jsc:jec), self%rossby_radius(isc:iec,jsc:jec) )
575 end subroutine soca_geom_rossby_radius
582 subroutine soca_geom_write(self)
585 character(len=256) :: geom_output_pe
587 character(len=8) :: fmt =
'(I5.5)'
588 character(len=1024) :: strpe
591 type(restart_file_type) :: geom_restart
595 idr_geom = register_restart_field(geom_restart, &
596 &self%geom_grid_file, &
599 domain=self%Domain%mpp_domain)
600 idr_geom = register_restart_field(geom_restart, &
601 &self%geom_grid_file, &
604 domain=self%Domain%mpp_domain)
605 idr_geom = register_restart_field(geom_restart, &
606 &self%geom_grid_file, &
609 domain=self%Domain%mpp_domain)
610 idr_geom = register_restart_field(geom_restart, &
611 &self%geom_grid_file, &
614 domain=self%Domain%mpp_domain)
615 idr_geom = register_restart_field(geom_restart, &
616 &self%geom_grid_file, &
619 domain=self%Domain%mpp_domain)
620 idr_geom = register_restart_field(geom_restart, &
621 &self%geom_grid_file, &
624 domain=self%Domain%mpp_domain)
625 idr_geom = register_restart_field(geom_restart, &
626 &self%geom_grid_file, &
629 domain=self%Domain%mpp_domain)
630 idr_geom = register_restart_field(geom_restart, &
631 &self%geom_grid_file, &
634 domain=self%Domain%mpp_domain)
635 idr_geom = register_restart_field(geom_restart, &
636 &self%geom_grid_file, &
639 domain=self%Domain%mpp_domain)
640 idr_geom = register_restart_field(geom_restart, &
641 &self%geom_grid_file, &
644 domain=self%Domain%mpp_domain)
645 idr_geom = register_restart_field(geom_restart, &
646 &self%geom_grid_file, &
648 &self%sin_rot(:,:), &
649 domain=self%Domain%mpp_domain)
650 idr_geom = register_restart_field(geom_restart, &
651 &self%geom_grid_file, &
653 &self%cos_rot(:,:), &
654 domain=self%Domain%mpp_domain)
655 idr_geom = register_restart_field(geom_restart, &
656 &self%geom_grid_file, &
658 &self%cell_area(:,:), &
659 domain=self%Domain%mpp_domain)
660 idr_geom = register_restart_field(geom_restart, &
661 &self%geom_grid_file, &
663 &self%rossby_radius(:,:), &
664 domain=self%Domain%mpp_domain)
665 idr_geom = register_restart_field(geom_restart, &
666 &self%geom_grid_file, &
669 domain=self%Domain%mpp_domain)
670 idr_geom = register_restart_field(geom_restart, &
671 &self%geom_grid_file, &
673 &self%mask2du(:,:), &
674 domain=self%Domain%mpp_domain)
675 idr_geom = register_restart_field(geom_restart, &
676 &self%geom_grid_file, &
678 &self%mask2dv(:,:), &
679 domain=self%Domain%mpp_domain)
680 idr_geom = register_restart_field(geom_restart, &
681 &self%geom_grid_file, &
684 domain=self%Domain%mpp_domain)
685 idr_geom = register_restart_field(geom_restart, &
686 &self%geom_grid_file, &
689 domain=self%Domain%mpp_domain)
690 idr_geom = register_restart_field(geom_restart, &
691 &self%geom_grid_file, &
693 &self%h_zstar(:,:,:), &
694 domain=self%Domain%mpp_domain)
695 idr_geom = register_restart_field(geom_restart, &
696 &self%geom_grid_file, &
697 &
'distance_from_coast', &
698 &self%distance_from_coast(:,:), &
699 domain=self%Domain%mpp_domain)
701 call save_restart(geom_restart, directory=
'')
702 call free_restart_type(geom_restart)
705 if (self%save_local_domain)
then
707 pe = self%f_comm%rank()
710 geom_output_pe=
'geom_output_'//trim(strpe)//
'.nc'
712 ns = (self%iec - self%isc + 1) * (self%jec - self%jsc + 1 )
713 call write2pe(reshape(self%mask2d(self%isc:self%iec,self%jsc:self%jec),(/ns/)),
'mask',geom_output_pe,.false.)
714 call write2pe(reshape(self%lon(self%isc:self%iec,self%jsc:self%jec),(/ns/)),
'lon',geom_output_pe,.true.)
715 call write2pe(reshape(self%lat(self%isc:self%iec,self%jsc:self%jec),(/ns/)),
'lat',geom_output_pe,.true.)
718 end subroutine soca_geom_write
725 subroutine soca_geom_read(self)
729 type(restart_file_type) :: geom_restart
732 idr_geom = register_restart_field(geom_restart, &
733 &self%geom_grid_file, &
736 domain=self%Domain%mpp_domain)
737 idr_geom = register_restart_field(geom_restart, &
738 &self%geom_grid_file, &
741 domain=self%Domain%mpp_domain)
742 idr_geom = register_restart_field(geom_restart, &
743 &self%geom_grid_file, &
746 domain=self%Domain%mpp_domain)
747 idr_geom = register_restart_field(geom_restart, &
748 &self%geom_grid_file, &
751 domain=self%Domain%mpp_domain)
752 idr_geom = register_restart_field(geom_restart, &
753 &self%geom_grid_file, &
756 domain=self%Domain%mpp_domain)
757 idr_geom = register_restart_field(geom_restart, &
758 &self%geom_grid_file, &
761 domain=self%Domain%mpp_domain)
762 idr_geom = register_restart_field(geom_restart, &
763 &self%geom_grid_file, &
766 domain=self%Domain%mpp_domain)
767 idr_geom = register_restart_field(geom_restart, &
768 &self%geom_grid_file, &
771 domain=self%Domain%mpp_domain)
772 idr_geom = register_restart_field(geom_restart, &
773 &self%geom_grid_file, &
776 domain=self%Domain%mpp_domain)
777 idr_geom = register_restart_field(geom_restart, &
778 &self%geom_grid_file, &
781 domain=self%Domain%mpp_domain)
782 idr_geom = register_restart_field(geom_restart, &
783 &self%geom_grid_file, &
785 &self%sin_rot(:,:), &
786 domain=self%Domain%mpp_domain)
787 idr_geom = register_restart_field(geom_restart, &
788 &self%geom_grid_file, &
790 &self%cos_rot(:,:), &
791 domain=self%Domain%mpp_domain)
792 idr_geom = register_restart_field(geom_restart, &
793 &self%geom_grid_file, &
795 &self%cell_area(:,:), &
796 domain=self%Domain%mpp_domain)
797 idr_geom = register_restart_field(geom_restart, &
798 &self%geom_grid_file, &
800 &self%rossby_radius(:,:), &
801 domain=self%Domain%mpp_domain)
802 idr_geom = register_restart_field(geom_restart, &
803 &self%geom_grid_file, &
806 domain=self%Domain%mpp_domain)
807 idr_geom = register_restart_field(geom_restart, &
808 &self%geom_grid_file, &
810 &self%mask2du(:,:), &
811 domain=self%Domain%mpp_domain)
812 idr_geom = register_restart_field(geom_restart, &
813 &self%geom_grid_file, &
815 &self%mask2dv(:,:), &
816 domain=self%Domain%mpp_domain)
817 idr_geom = register_restart_field(geom_restart, &
818 &self%geom_grid_file, &
821 domain=self%Domain%mpp_domain)
822 idr_geom = register_restart_field(geom_restart, &
823 &self%geom_grid_file, &
824 &
'distance_from_coast', &
825 &self%distance_from_coast(:,:), &
826 domain=self%Domain%mpp_domain)
827 call restore_state(geom_restart, directory=
'')
828 call free_restart_type(geom_restart)
831 end subroutine soca_geom_read
838 subroutine soca_geom_get_domain_indices(self, domain_type, is, ie, js, je, local)
840 character(len=*),
intent(in) :: domain_type
841 integer,
intent(out) :: is, ie, js, je
842 logical,
optional,
intent(in) :: local
844 integer :: isc, iec, jsc, jec
845 integer :: isd, ied, jsd, jed
846 integer :: isg, ieg, jsg, jeg
848 call mpp_get_compute_domain(self%Domain%mpp_domain,isc,iec,jsc,jec)
849 call mpp_get_data_domain(self%Domain%mpp_domain,isd,ied,jsd,jed)
850 call mpp_get_global_domain(self%Domain%mpp_domain, isg, ieg, jsg, jeg)
851 if (
present(local))
then
852 isc = isc - (isd-1) ; iec = iec - (isd-1) ; ied = ied - (isd-1) ; isd = 1
853 jsc = jsc - (jsd-1) ; jec = jec - (jsd-1) ; jed = jed - (jsd-1) ; jsd = 1
856 select case (trim(domain_type))
858 is = isc; ie = iec; js = jsc; je = jec;
860 is = isd; ie = ied; js = jsd; je = jed;
862 is = isg; ie = ieg; js = jsg; je = jeg;
865 end subroutine soca_geom_get_domain_indices
872 subroutine soca_geom_thickness2depth(self, h, z)
874 real(kind=kind_real),
intent(in ) :: h(:,:,:)
875 real(kind=kind_real),
intent(inout) :: z(:,:,:)
877 integer :: is, ie, js, je, i, j, k
891 z(i,j,k) = 0.5_kind_real*h(i,j,k)
893 z(i,j,k) = sum(h(i,j,1:k-1))+0.5_kind_real*h(i,j,k)
898 end subroutine soca_geom_thickness2depth
905 subroutine soca_geom_struct2atlas(self, dx_struct, dx_atlas)
907 real(kind=kind_real),
intent(in ) :: dx_struct(:,:)
908 type(atlas_fieldset),
intent(out) :: dx_atlas
910 real(kind_real),
pointer :: real_ptr(:)
911 type(atlas_field) :: afield
913 dx_atlas = atlas_fieldset()
914 afield = self%afunctionspace%create_field(
'var',kind=atlas_real(kind_real),levels=0)
915 call dx_atlas%add(afield)
916 call afield%data(real_ptr)
917 real_ptr = reshape(dx_struct(self%iscl:self%iecl, self%jscl:self%jecl),(/(self%iecl-self%iscl+1)*(self%jecl-self%jscl+1)/))
920 end subroutine soca_geom_struct2atlas
927 subroutine soca_geom_atlas2struct(self, dx_struct, dx_atlas)
929 real(kind=kind_real),
intent(inout) :: dx_struct(:,:)
930 type(atlas_fieldset),
intent(inout) :: dx_atlas
932 real(kind_real),
pointer :: real_ptr(:)
933 type(atlas_field) :: afield
935 afield = dx_atlas%field(
'var')
936 call afield%data(real_ptr)
937 dx_struct(self%iscl:self%iecl, self%jscl:self%jecl) = reshape(real_ptr,(/(self%iecl-self%iscl+1),(self%jecl-self%jscl+1)/))
940 end subroutine soca_geom_atlas2struct
subroutine, public soca_mom6_init(mom6_config, partial_init)
Setup/initialize/prepare mom6 for time integration.
subroutine, public soca_geomdomain_init(Domain, nk, f_comm)
Initialize mom6's domain.
various utility functions
subroutine, public soca_remap_idw(lon_src, lat_src, data_src, lon_dst, lat_dst, data_dst)
inverse distance weighted remaping (modified Shepard's method)
subroutine, public write2pe(vec, varname, filename, append)
per-PE file output, used by soca_geom to write per-PE grid
Data structure neccessary to initialize/run mom6.