9 use atlas_module,
only: atlas_geometry, atlas_indexkdtree
10 use fckit_exception_module,
only: fckit_exception
11 use gsw_mod_toolbox,
only : gsw_rho, gsw_sa_from_sp, gsw_ct_from_pt, gsw_mlp
12 use kinds,
only: kind_real
33 elemental function soca_rho(sp, pt, p, lon, lat)
34 real(kind=kind_real),
intent(in) :: pt, sp, p, lon, lat
35 real(kind=kind_real) :: sa, ct, lon_rot,
soca_rho
39 if (lon<-180.0) lon_rot=lon+360.0
40 if (lon>180.0) lon_rot=lon-360.0
43 sa = gsw_sa_from_sp(sp, p, lon_rot, lat)
46 ct = gsw_ct_from_pt(sa, pt)
64 real(kind=kind_real),
intent(in) :: pt(:), sp(:), p(:), lon, lat
66 real(kind=kind_real) :: lon_rot,
soca_mld
67 real(kind=kind_real),
allocatable :: sa(:), ct(:)
71 if (lon<-180.0) lon_rot=lon+360.0
72 if (lon>180.0) lon_rot=lon-360.0
75 allocate(sa(
size(sp,1)),ct(
size(sp,1)))
78 sa = gsw_sa_from_sp(sp, p, lon_rot, lat)
81 ct = gsw_ct_from_pt(sa, pt)
97 real(kind=kind_real),
intent(in) :: v(:), h(:)
98 real(kind=kind_real),
intent(out) :: dvdz(:)
105 dvdz(ik) = (v(ik+1)-v(ik-1))/(h(ik)+0.5*h(ik+1)+h(ik-1))
117 real(kind=kind_real),
intent(in) :: vec(:)
118 character(len=*),
intent(in) :: varname
119 character(len=256),
intent(in) :: filename
120 logical,
intent(in) :: append
123 integer(kind=4) :: incid
124 integer(kind=4) :: idim_id
125 integer(kind=4) :: ivar_id
126 integer :: ndims=1, ns
130 call nc_check( nf90_open(filename, nf90_write, incid) )
131 call nc_check( nf90_inquire(incid, ndimensions = ndims) )
132 call nc_check( nf90_inq_dimid(incid,
"ns", idim_id) )
135 call nc_check(nf90_create(filename, nf90_clobber, incid))
136 call nc_check(nf90_def_dim(incid,
"ns", ns, idim_id))
140 call nc_check( nf90_def_var(incid, trim(varname), nf90_double, (/ idim_id /), ivar_id) )
146 call nc_check(nf90_put_var(incid, ivar_id , vec))
158 integer(4),
intent ( in) :: status
159 if(status /= nf90_noerr)
then
160 print *, trim(nf90_strerror(status))
169 real(kind=kind_real),
intent(in) :: std, minstd, maxstd
179 character(len=*),
intent(in) :: str
180 integer,
intent(out) :: int
188 subroutine soca_remap_idw(lon_src, lat_src, data_src, lon_dst, lat_dst, data_dst)
189 real(kind_real),
intent(in) :: lon_src(:)
190 real(kind_real),
intent(in) :: lat_src(:)
191 real(kind_real),
intent(in) :: data_src(:)
192 real(kind_real),
intent(in) :: lon_dst(:,:)
193 real(kind_real),
intent(in) :: lat_dst(:,:)
194 real(kind_real),
intent(inout) :: data_dst(:,:)
196 integer,
parameter :: nn_max = 10
197 real(kind_real),
parameter :: idw_pow = 2.0
199 integer :: idx(nn_max)
200 integer :: n_src, i, j, n, nn
201 real(kind_real) :: dmax, r, w(nn_max), dist(nn_max)
202 type(atlas_geometry) :: ageometry
203 type(atlas_indexkdtree) :: kd
206 n_src =
size(lon_src)
207 ageometry = atlas_geometry(
"UnitSphere")
208 kd = atlas_indexkdtree(ageometry)
209 call kd%reserve(n_src)
210 call kd%build(n_src, lon_src, lat_src)
213 do i = 1,
size(data_dst, dim=1)
214 do j = 1,
size(data_dst, dim=2)
217 call kd%closestPoints(lon_dst(i,j), lat_dst(i,j), nn_max, idx)
221 dist(n) = ageometry%distance(lon_dst(i,j), lat_dst(i,j), &
222 lon_src(idx(n)), lat_src(idx(n)))
232 if (dist(n) /= dist(nn_max))
exit
235 if (nn <= 0 )
call fckit_exception%abort( &
236 "No valid points found in IDW remapping, uh oh.")
239 dmax = maxval(dist(1:nn))
242 w(n) = ((dmax-dist(n)) / (dmax*dist(n))) ** idw_pow
249 r = r + data_src(idx(n))*w(n)
various utility functions
real(kind=kind_real) function, public soca_mld(sp, pt, p, lon, lat)
calculate mixed layer depth from temp/salinity profile
elemental real(kind=kind_real) function, public soca_adjust(std, minstd, maxstd)
Apply bounds.
subroutine, public nc_check(status)
wrapper for netcdf calls
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
subroutine, public soca_diff(dvdz, v, h)
subroutine, public soca_str2int(str, int)
elemental real(kind=kind_real) function, public soca_rho(sp, pt, p, lon, lat)
calculate density from temp/salinity profile