50 real (r8),
intent(in) :: sa(:), ct(:), p(:), p_ref
54 integer,
allocatable :: iidata(:)
56 real (r8),
allocatable :: b(:), b_av(:), dp(:), dp_i(:)
57 real (r8),
allocatable :: sa_i(:), ct_i(:), p_i(:)
58 real (r8),
allocatable :: geo_strf_dyn_height0(:)
60 integer :: p_cnt, top_pad, i, nz, ibottle, ipref, np_max, np, ibpr
62 real (r8) :: dp_min, dp_max, p_min, p_max
68 real (r8),
parameter :: max_dp_i = 1.0_r8
73 real (r8),
parameter :: p_max_limit = 20000.0_r8
75 integer,
parameter :: np_max_limit = nint(p_max_limit/max_dp_i)
77 character (*),
parameter :: func_name =
"gsw_geo_strf_dyn_height" 83 dp = p(2:nz) - p(1:nz-1)
87 if (.not. (dp_min .gt. 0.0_r8))
then 95 if (.not. (p_ref .le. p_max))
then 105 if (p(ibottle) .eq. p_ref)
then 111 if ((dp_max .le. max_dp_i) .and. (p(1) .eq. 0.0_r8) .and. (ipref .gt. 0))
then 117 allocate (b(nz), b_av(nz-1))
121 b_av = 0.5_r8*(b(1:nz-1) + b(2:nz))
126 allocate (geo_strf_dyn_height0(nz))
128 geo_strf_dyn_height0 = (/ 0.0_r8, b_av*dp*
db2pa /)
130 geo_strf_dyn_height0(i) = geo_strf_dyn_height0(i-1) &
131 - geo_strf_dyn_height0(i)
141 allocate (iidata(nz))
144 if ((dp_max .le. max_dp_i) .and. (ipref .gt. 0))
then 149 if (p_min .gt. 0.0_r8)
then 152 allocate (sa_i(nz+1), ct_i(nz+1), p_i(nz+1))
153 sa_i = (/ sa(1), sa /)
154 ct_i = (/ ct(1), ct /)
155 p_i = (/ 0.0_r8, p /)
157 iidata = (/ (i, i=2,nz+1) /)
161 allocate (sa_i(nz), ct_i(nz), p_i(nz))
166 iidata = (/ (i, i=1,nz) /)
173 np_max = 2*nint(maxval(p/max_dp_i)+0.5_r8)
174 if (np_max.gt.np_max_limit)
then 178 allocate (p_i(np_max))
180 if (p_min .gt. 0.0_r8)
then 182 if (p_ref .lt. p_min)
then 193 p_i(1:2) = (/ 0.0_r8, p_min /)
206 iidata(ibottle) = p_cnt
207 if (p(ibottle) .eq. p_ref) ibpr = p_cnt
209 if (p(ibottle) .lt. p_ref .and. p(ibottle+1) .gt. p_ref)
then 212 call p_sequence(p(ibottle),p_ref,p_i(p_cnt+1:),np)
215 call p_sequence(p_ref,p(ibottle+1),p_i(p_cnt+1:),np)
219 call p_sequence(p(ibottle),p(ibottle+1),p_i(p_cnt+1:),np)
226 if (p(nz) .eq. p_ref) ibpr = p_cnt
228 allocate (sa_i(p_cnt), ct_i(p_cnt))
230 if (top_pad .gt. 1) &
233 sa_i(top_pad:),ct_i(top_pad:))
236 allocate (b(p_cnt), b_av(p_cnt-1), dp_i(p_cnt-1))
237 allocate (geo_strf_dyn_height0(p_cnt))
240 b_av = 0.5_r8*(b(1:p_cnt-1) + b(2:p_cnt))
241 dp_i = p_i(2:p_cnt) - p_i(1:p_cnt-1)
243 geo_strf_dyn_height0 = (/ 0.0_r8, b_av*dp_i /)
245 geo_strf_dyn_height0(i) = geo_strf_dyn_height0(i-1) &
246 - geo_strf_dyn_height0(i)
249 - geo_strf_dyn_height0(ibpr))*
db2pa 256 pure subroutine p_sequence (p1, p2, pseq, nps)
260 real (r8),
intent(in) :: p1, p2
261 real (r8),
intent(inout) :: pseq(:)
262 integer,
intent(out),
optional :: nps
264 real (r8) :: dp, pstep
269 n = ceiling(dp/max_dp_i)
272 if (
present(nps)) nps = n
277 pseq(1:n) = (/ (p2-pstep*i, i=n-1,0,-1) /)
pure real(r8) function, dimension(size(sa)) gsw_geo_strf_dyn_height(sa, ct, p, p_ref)
pure subroutine p_sequence(p1, p2, pseq, nps)
real(r8), parameter db2pa
************************************************************************GNU Lesser General Public License **This file is part of the GFDL Flexible Modeling System(FMS). ! *! *FMS is free software without even the implied warranty of MERCHANTABILITY or *FITNESS FOR A PARTICULAR PURPOSE See the GNU General Public License *for more details **You should have received a copy of the GNU Lesser General Public *License along with FMS If see< http:! ***********************************************************************subroutine READ_RECORD_CORE_(unit, field, nwords, data, start, axsiz) integer, intent(in) ::unit type(fieldtype), intent(in) ::field integer, intent(in) ::nwords MPP_TYPE_, intent(inout) ::data(nwords) integer, intent(in) ::start(:), axsiz(:) integer(SHORT_KIND) ::i2vals(nwords)!rab used in conjunction with transfer intrinsic to determine size of a variable integer(KIND=1) ::one_byte(8) integer ::word_sz!#ifdef __sgi integer(INT_KIND) ::ivals(nwords) real(FLOAT_KIND) ::rvals(nwords)!#else! integer ::ivals(nwords)! real ::rvals(nwords)!#endif real(DOUBLE_KIND) ::r8vals(nwords) pointer(ptr1, i2vals) pointer(ptr2, ivals) pointer(ptr3, rvals) pointer(ptr4, r8vals) if(mpp_io_stack_size< nwords) call mpp_io_set_stack_size(nwords) call mpp_error(FATAL, 'MPP_READ currently requires use_netCDF option') end subroutine READ_RECORD_CORE_ subroutine READ_RECORD_(unit, field, nwords, data, time_level, domain, position, tile_count, start_in, axsiz_in)!routine that is finally called by all mpp_read routines to perform the read!a non-netCDF record contains:! field ID! a set of 4 coordinates(is:ie, js:je) giving the data subdomain! a timelevel and a timestamp(=NULLTIME if field is static)! 3D real data(stored as 1D)!if you are using direct access I/O, the RECL argument to OPEN must be large enough for the above!in a global direct access file, record position on PE is given by %record.!Treatment of timestamp:! We assume that static fields have been passed without a timestamp.! Here that is converted into a timestamp of NULLTIME.! For non-netCDF fields, field is treated no differently, but is written! with a timestamp of NULLTIME. There is no check in the code to prevent! the user from repeatedly writing a static field. integer, intent(in) ::unit, nwords type(fieldtype), intent(in) ::field MPP_TYPE_, intent(inout) ::data(nwords) integer, intent(in), optional ::time_level type(domain2D), intent(in), optional ::domain integer, intent(in), optional ::position, tile_count integer, intent(in), optional ::start_in(:), axsiz_in(:) integer, dimension(size(field%axes(:))) ::start, axsiz integer ::tlevel !, subdomain(4) integer ::i, error, is, ie, js, je, isg, ieg, jsg, jeg type(domain2d), pointer ::io_domain=> tlevel if(PRESENT(start_in) .AND. PRESENT(axsiz_in)) then if(size(start(! the data domain and compute domain must refer to the subdomain being passed ! In this ! since that attempts to gather all data on PE size(field%axes(:)) axsiz(i)
elemental real(r8) function, public gsw_error_code(err_num, func_name, error_code)