1
-
!! Sound speed profile module with interpolation and derivatives
4
-
!! Sound speed profile handling with interpolation, derivatives, and environment management
6
-
! Holds SSP input by user and associated variables
8
-
! This module is very similar to the one used by the other programs in the Acoustics Toolbox
9
-
! However, it returns the SSP *and* its derivatives
11
-
! Also, a greater premium has been placed on returning this info quickly, since BELLHOP calls it at every step
12
-
! Therefore more information is pre-computed
22
-
INTEGER, PARAMETER, PRIVATE :: ENVFile = 5, PRTFile = 6
23
-
INTEGER, PARAMETER :: MaxSSP = 100001
24
-
INTEGER :: iSegr = 1, iSegx = 1, iSegy = 1, iSegz = 1
25
-
INTEGER, PRIVATE :: iz
26
-
REAL (KIND=8), PRIVATE :: Depth, W
27
-
REAL (KIND=8) :: zTemp, betaPowerLaw = 1, fT = 1D20
28
-
REAL (KIND=8) :: alphaR = 1500, betaR = 0, alphaI = 0, betaI = 0, rhoR = 1
31
-
REAL(KIND=8), ALLOCATABLE :: r(:), x(:), y(:), z(:)
32
-
END TYPE rxyz_vector
36
-
INTEGER :: NPts, Nr, Nx, Ny, Nz
37
-
REAL (KIND=8) :: z( MaxSSP ), rho( MaxSSP )
38
-
COMPLEX (KIND=8) :: c( MaxSSP ), cz( MaxSSP ), n2( MaxSSP ), n2z( MaxSSP ), cSpline( 4, MaxSSP )
39
-
COMPLEX (KIND=8) :: cCoef( 4, MaxSSP ), CSWork( 4, MaxSSP ) ! for PCHIP coefs.
40
-
REAL (KIND=8), ALLOCATABLE :: cMat( :, : ), czMat( :, : ), cMat3( :, :, : ), czMat3( :, :, : )
41
-
TYPE ( rxyz_vector ) :: Seg
42
-
CHARACTER (LEN=1) :: Type
43
-
CHARACTER (LEN=2) :: AttenUnit
44
-
END TYPE SSPStructure
46
-
TYPE( SSPStructure ) :: SSP
48
-
! *** Halfspace properties structure ***
51
-
REAL (KIND=8) :: alphaR, alphaI, betaR, betaI ! compressional and shear wave speeds/attenuations in user units
52
-
COMPLEX (KIND=8) :: cP, cS ! P-wave, S-wave speeds
53
-
REAL (KIND=8) :: rho, Depth ! density, depth
54
-
CHARACTER (LEN=1) :: BC ! Boundary condition type
55
-
CHARACTER (LEN=6) :: Opt
59
-
TYPE( HSInfo ) :: HS
63
-
TYPE( BdryPt ) :: Top, Bot
66
-
TYPE(BdryType) :: Bdry
70
42690808*
SUBROUTINE EvaluateSSP( x, t, c, cimag, gradc, crr, crz, czz, rho, freq, Task )
71
-
!! Evaluates sound speed profile at given location
73
-
! Call the particular profil routine indicated by the SSP%Type and perform Task
74
-
! Task = 'TAB' then tabulate cp, cs, rhoT
75
-
! Task = 'INI' then initialize
77
-
REAL (KIND=8), INTENT( IN ) :: freq
78
-
REAL (KIND=8), INTENT( IN ) :: x( 2 ) ! r-z coordinate where SSP is to be evaluated
79
-
REAL (KIND=8), INTENT( IN ) :: t( 2 ) ! ray tangent; for edge cases of updating segments
80
-
CHARACTER ( LEN=3), INTENT( IN ) :: Task
81
-
REAL (KIND=8), INTENT( OUT ) :: c, cimag, gradc( 2 ), crr, crz, czz, rho
82
-
REAL (KIND=8) :: gradc_3d( 3 ), cxx, cyy, cxy, cxz, cyz
83
-
REAL (KIND=8) :: x3( 3 ), t3( 3 )
85
37583
SELECT CASE ( SSP%Type )
86
-
CASE ( 'N' ) ! N2-linear profile option
87
6283761
CALL n2Linear( x, t, c, cimag, gradc, crr, crz, czz, rho, freq, Task )
88
-
CASE ( 'C' ) ! C-linear profile option
89
6246178*
CALL cLinear( x, t, c, cimag, gradc, crr, crz, czz, rho, freq, Task )
90
-
CASE ( 'P' ) ! monotone PCHIP ACS profile option
91
34117883*
CALL cPCHIP( x, t, c, cimag, gradc, crr, crz, czz, rho, freq, Task )
92
-
CASE ( 'S' ) ! Cubic spline profile option
93
36407047
CALL cCubic( x, t, c, cimag, gradc, crr, crz, czz, rho, freq, Task )
95
2289164*
CALL Quad( x, t, c, cimag, gradc, crr, crz, czz, rho, freq, Task )
97
#####
IF ( Task == 'TAB' ) THEN
98
#####
WRITE( PRTFile, * ) 'BELLHOP: EvaluateSSP: Hexahedral is not a valid SSP in 2D mode'
99
#####
CALL ERROUT( 'BELLHOP: EvaluateSSP', 'Hexahedral is not a valid SSP in 2D mode')
101
-
! this is called by BELLHOP3D only once, during READIN
102
-
! possibly the logic should be changed to call EvaluateSSP2D or 3D
103
#####
x3 = [ 0.0D0, 0.0D0, x( 2 ) ]
104
#####
t3 = [ 0.0D0, 0.0D0, t( 2 ) ]
105
#####
CALL Hexahedral( x3, t3, c, cimag, gradc_3d, cxx, cyy, czz, cxy, cxz, cyz, rho, freq, Task )
106
-
CASE ( 'A' ) ! Analytic profile option
107
#####
CALL Analytic( x, t, c, cimag, gradc, crr, crz, czz, rho )
109
#####
WRITE( PRTFile, * ) 'Profile option: ', SSP%Type
110
42690808*
CALL ERROUT( 'BELLHOP: EvaluateSSP', 'Invalid profile option' )
113
42690808
END SUBROUTINE EvaluateSSP
115
-
! **********************************************************************!
117
#####
SUBROUTINE EvaluateSSP2D( x2D, t2D, c, cimag, gradc, crr, crz, czz, rho, xs, tradial, freq )
118
-
!! Converts cartesian gradients to polar
120
-
! Called from BELLHOP3D to get a 2D slice out of the 3D SSP
122
-
REAL (KIND=8), INTENT( IN ) :: x2D( 2 ), t2D( 2 ), xs( 3 ), tradial( 2 ), freq
123
-
REAL (KIND=8), INTENT( OUT ) :: c, cimag, gradc( 2 ), czz, crz, crr, rho
124
-
REAL (KIND=8) :: x( 3 ), t( 3 ), gradc3D(3 ), cxx, cyy, cxy, cxz, cyz
126
-
! convert polar coordinate to cartesian
127
#####
x = [ xs( 1 ) + x2D( 1 ) * tradial( 1 ), xs( 2 ) + x2D( 1 ) * tradial( 2 ), x2D( 2 ) ]
128
#####
t = [ t2D( 1 ) * tradial( 1 ), t2D( 1 ) * tradial( 2 ), t2D( 2 ) ]
130
#####
CALL EvaluateSSP3D( x, t, c, cimag, gradc3D, cxx, cyy, czz, cxy, cxz, cyz, rho, freq, 'TAB' )
132
#####
gradc( 1 ) = DOT_PRODUCT( tradial, gradc3D( 1 : 2 ) ) ! r derivative
133
#####
gradc( 2 ) = gradc3D( 3 ) ! z derivative
135
#####
crz = tradial( 1 ) * cxz + tradial( 2 ) * cyz
136
#####
crr = cxx * ( tradial( 1 ) )**2 + 2.0 * cxy * tradial( 1 ) * tradial( 2 ) + cyy * ( tradial( 2 ) )**2
139
-
END SUBROUTINE EvaluateSSP2D
141
-
! **********************************************************************!
143
#####
SUBROUTINE EvaluateSSP3D( x, t, c, cimag, gradc, cxx, cyy, czz, cxy, cxz, cyz, rho, freq, Task )
145
-
! Call the particular profil routine indicated by the SSP%Type and perform Task
146
-
! Task = 'TAB' then tabulate cp, cs, rhoT
147
-
! Task = 'INI' then initialize
149
-
REAL (KIND=8), INTENT( IN ) :: freq
150
-
REAL (KIND=8), INTENT( IN ) :: x( 3 ) ! x-y-z coordinate where SSP is to be evaluated
151
-
REAL (KIND=8), INTENT( IN ) :: t( 3 ) ! ray tangent; for edge cases of updating segments
152
-
CHARACTER ( LEN=3), INTENT( IN ) :: Task
153
-
REAL (KIND=8), INTENT( OUT ) :: c, cimag, gradc( 3 ), cxx, cyy, czz, cxy, cxz, cyz, rho
154
-
REAL (KIND=8) :: x_rz( 2 ), t_rz( 2 ), gradc_rz( 2 ), crr, crz
156
#####
x_rz = [ 0.0D0, x( 3 ) ] ! convert x-y-z coordinate to cylindrical coordinate
157
#####
t_rz = [ 0.0D0, t( 3 ) ]
159
#####
SELECT CASE ( SSP%Type )
161
#####
CALL n2Linear( x_rz, t_rz, c, cimag, gradc_rz, crr, crz, czz, rho, freq, Task )
163
#####
CALL cLinear( x_rz, t_rz, c, cimag, gradc_rz, crr, crz, czz, rho, freq, Task )
165
#####
CALL cCubic( x_rz, t_rz, c, cimag, gradc_rz, crr, crz, czz, rho, freq, Task )
167
#####
CALL Hexahedral( x, t, c, cimag, gradc, cxx, cyy, czz, cxy, cxz, cyz, rho, freq, Task )
169
#####
CALL Analytic3D( x, t, c, cimag, gradc, cxx, cyy, czz, cxy, cxz, cyz, rho )
171
#####
WRITE( PRTFile, * ) 'Profile option: ', SSP%Type
172
#####
CALL ERROUT( 'BELLHOP3D: EvaluateSSP3D', 'Invalid profile option' )
175
#####
SELECT CASE ( SSP%Type )
176
-
CASE ( 'N', 'C', 'S' )
177
#####
gradc = [ 0.0D0, 0.0D0, gradc_rz( 2 ) ]
186
#####
END SUBROUTINE EvaluateSSP3D
188
-
! **********************************************************************!
190
37583*
SUBROUTINE n2Linear( x, t, c, cimag, gradc, crr, crz, czz, rho, freq, Task )
191
-
!! Linear interpolation for squared buoyancy frequency
193
-
! N2-linear interpolation of SSP data
195
-
REAL (KIND=8), INTENT( IN ) :: freq
196
-
REAL (KIND=8), INTENT( IN ) :: x( 2 ) ! r-z coordinate where sound speed is evaluated
197
-
REAL (KIND=8), INTENT( IN ) :: t( 2 ) ! ray tangent; for edge cases of updating segments
198
-
CHARACTER (LEN=3), INTENT( IN ) :: Task
199
-
REAL (KIND=8), INTENT( OUT ) :: c, cimag, gradc( 2 ), crr, crz, czz, rho ! sound speed and its derivatives
201
37583
IF ( Task == 'INI' ) THEN ! read in SSP data
203
1
CALL ReadSSP( Depth, freq )
205
3*
SSP%n2( 1 : SSP%NPts ) = 1.0 / SSP%c( 1 : SSP%NPts ) ** 2
207
-
! compute gradient, n2z
208
2*
DO iz = 2, SSP%Npts
209
3*
SSP%n2z( iz - 1 ) = ( SSP%n2( iz ) - SSP%n2( iz - 1 ) ) / &
210
5*
( SSP%z( iz ) - SSP%z( iz - 1 ) )
212
-
ELSE ! return SSP info
214
37582
CALL UpdateDepthSegmentT( x, t )
216
37582*
W = ( x( 2 ) - SSP%z( iSegz ) ) / ( SSP%z( iSegz + 1 ) - SSP%z( iSegz ) )
218
37582*
c = REAL( 1.0D0 / SQRT( ( 1.0D0 - W ) * SSP%n2( iSegz ) + W * SSP%n2( iSegz + 1 ) ) )
219
37582*
cimag = AIMAG( 1.0D0 / SQRT( ( 1.0D0 - W ) * SSP%n2( iSegz ) + W * SSP%n2( iSegz + 1 ) ) )
221
112746*
gradc = [ 0.0D0, -0.5D0 * c * c * c * REAL( SSP%n2z( iSegz ) ) ]
224
37582
czz = 3.0d0 * gradc( 2 ) * gradc( 2 ) / C
226
37582*
rho = ( 1.0D0 - W ) * SSP%rho( iSegz ) + W * SSP%rho( iSegz + 1 )
229
37583
END SUBROUTINE n2Linear
231
-
! **********************************************************************!
233
6246178*
SUBROUTINE cLinear( x, t, c, cimag, gradc, crr, crz, czz, rho, freq, Task )
234
-
!! c-linear interpolation of SSP data
236
-
REAL (KIND=8), INTENT( IN ) :: freq
237
-
REAL (KIND=8), INTENT( IN ) :: x( 2 ) ! r-z coordinate where sound speed is evaluated
238
-
REAL (KIND=8), INTENT( IN ) :: t( 2 ) ! ray tangent; for edge cases of updating segments
239
-
CHARACTER (LEN=3), INTENT( IN ) :: Task
240
-
REAL (KIND=8), INTENT( OUT ) :: c, cimag, gradc( 2 ), crr, crz, czz, rho ! sound speed and its derivatives
242
6246178
IF ( Task == 'INI' ) THEN ! read in SSP data
244
2
CALL ReadSSP( Depth, freq )
245
-
ELSE ! return SSP info
247
6246176
CALL UpdateDepthSegmentT( x, t )
249
6246176*
c = REAL( SSP%c( iSegz ) + ( x( 2 ) - SSP%z( iSegz ) ) * SSP%cz( iSegz ) )
250
6246176*
cimag = AIMAG( SSP%c( iSegz ) + ( x( 2 ) - SSP%z( iSegz ) ) * SSP%cz( iSegz ) )
251
18738528*
gradc = [ 0.0D0, REAL( SSP%cz( iSegz ) ) ]
256
6246176*
W = ( x( 2 ) - SSP%z( iSegz ) ) / ( SSP%z( iSegz + 1 ) - SSP%z( iSegz ) )
257
6246176*
rho = ( 1.0D0 - W ) * SSP%rho( iSegz ) + W * SSP%rho( iSegz + 1 )
260
6246178
END SUBROUTINE cLinear
262
-
! **********************************************************************!
264
#####
SUBROUTINE cPCHIP( x, t, c, cimag, gradc, crr, crz, czz, rho, freq, Task )
265
-
!! PCHIP for interpolation of sound speed
267
-
! This implements the new monotone piecewise cubic Hermite interpolating
268
-
! polynomial (PCHIP) algorithm for the interpolation of the sound speed c.
271
-
REAL (KIND=8), INTENT( IN ) :: freq
272
-
REAL (KIND=8), INTENT( IN ) :: x( 2 ) ! r-z coordinate where sound speed is evaluated
273
-
REAL (KIND=8), INTENT( IN ) :: t( 2 ) ! ray tangent; for edge cases of updating segments
274
-
CHARACTER (LEN=3), INTENT( IN ) :: Task
275
-
REAL (KIND=8), INTENT( OUT ) :: c, cimag, gradc( 2 ), crr, crz, czz, rho ! sound speed and its derivatives
276
-
REAL (KIND=8) :: xt
277
-
COMPLEX (KIND=8) :: c_cmplx
279
#####
IF ( Task == 'INI' ) THEN ! read in SSP data
282
#####
CALL ReadSSP( Depth, freq )
285
-
! compute coefficients of std cubic polynomial: c0 + c1*x + c2*x + c3*x
288
#####
CALL PCHIP( SSP%z, SSP%c, SSP%NPts, SSP%cCoef, SSP%CSWork )
290
-
ELSE ! return SSP info
292
#####
CALL UpdateDepthSegmentT( x, t )
294
#####
xt = x( 2 ) - SSP%z( iSegz )
295
#####
c_cmplx = SSP%cCoef( 1, iSegz ) &
296
#####
+ ( SSP%cCoef( 2, iSegz ) &
297
#####
+ ( SSP%cCoef( 3, iSegz ) &
298
#####
+ SSP%cCoef( 4, iSegz ) * xt ) * xt ) * xt
300
#####
c = REAL( c_cmplx )
301
#####
cimag = AIMAG( c_cmplx )
303
#####
gradc = [ 0.0D0, REAL( SSP%cCoef( 2, iSegz ) &
304
#####
+ ( 2.0D0 * SSP%cCoef( 3, iSegz ) &
305
#####
+ 3.0D0 * SSP%cCoef( 4, iSegz ) * xt ) * xt ) ]
309
#####
czz = REAL( 2.0D0 * SSP%cCoef( 3, iSegz ) + 6.0D0 * SSP%cCoef( 4, iSegz ) * xt )
311
#####
W = ( x( 2 ) - SSP%z( iSegz ) ) / ( SSP%z( iSegz + 1 ) - SSP%z( iSegz ) )
312
#####
rho = ( 1.0D0 - W ) * SSP%rho( iSegz ) + W * SSP%rho( iSegz + 1 ) ! linear interp of density
316
#####
END SUBROUTINE cPCHIP
318
-
! **********************************************************************!
320
34117883*
SUBROUTINE cCubic( x, t, c, cimag, gradc, crr, crz, czz, rho, freq, Task )
321
-
!! Cubic spline interpolation for sound speed
323
-
REAL (KIND=8), INTENT( IN ) :: freq
324
-
REAL (KIND=8), INTENT( IN ) :: x( 2 ) ! r-z coordinate where sound speed is evaluated
325
-
REAL (KIND=8), INTENT( IN ) :: t( 2 ) ! ray tangent; for edge cases of updating segments
326
-
CHARACTER (LEN=3), INTENT( IN ) :: Task
327
-
REAL (KIND=8), INTENT( OUT ) :: c, cimag, gradc( 2 ), crr, crz, czz, rho ! sound speed and its derivatives
328
-
INTEGER :: iBCBeg, iBCEnd
329
-
REAL (KIND=8) :: hSpline
330
-
COMPLEX (KIND=8) :: c_cmplx, cz_cmplx, czz_cmplx
332
34117883
IF ( Task == 'INI' ) THEN
334
-
! *** Task 'INIT' for initialization ***
337
10
CALL ReadSSP( Depth, freq )
339
33*
SSP%cSpline( 1, 1 : SSP%NPts ) = SSP%c( 1 : SSP%NPts )
341
-
! Compute spline coefs
344
10
CALL CSpline( SSP%z, SSP%cSpline( 1, 1 ), SSP%NPts, iBCBeg, iBCEnd, SSP%NPts )
347
-
! *** Section to return SSP info ***
349
34117873
CALL UpdateDepthSegmentT( x, t )
351
34117873*
hSpline = x( 2 ) - SSP%z( iSegz )
353
-
! c = Spline( SSP%cSpline( 1, iSegz ), hSpline )
354
-
! cz = SplineX( SSP%cSpline( 1, iSegz ), hSpline )
355
-
! czz = SplineXX( SSP%cSpline( 1, iSegz ), hSpline )
357
34117873*
CALL SplineALL( SSP%cSpline( 1, iSegz ), hSpline, c_cmplx, cz_cmplx, czz_cmplx )
359
34117873
c = DBLE( c_cmplx )
360
34117873
cimag = AIMAG( c_cmplx )
361
102353619
gradc = [ 0.0D0, DBLE( cz_cmplx ) ]
362
34117873
czz = DBLE( czz_cmplx )
366
-
! linear interpolation for density
367
34117873*
W = ( x( 2 ) - SSP%z( iSegz ) ) / ( SSP%z( iSegz + 1 ) - SSP%z( iSegz ) )
368
34117873*
rho = ( 1.0D0 - W ) * SSP%rho( iSegz ) + W * SSP%rho( iSegz + 1 )
371
34117883
END SUBROUTINE cCubic
373
-
! **********************************************************************!
375
2289164*
SUBROUTINE Quad( x, t, c, cimag, gradc, crr, crz, czz, rho, freq, Task )
376
-
!! Quadrilateral interpolation for sound speed profiles
378
-
! Bilinear quadrilateral interpolation of SSP data in 2D
380
-
INTEGER, PARAMETER :: SSPFile = 40
381
-
REAL (KIND=8), INTENT( IN ) :: freq
382
-
REAL (KIND=8), INTENT( IN ) :: x( 2 ) ! r-z coordinate where sound speed is evaluated
383
-
REAL (KIND=8), INTENT( IN ) :: t( 2 ) ! ray tangent; for edge cases of updating segments
384
-
CHARACTER (LEN=3), INTENT( IN ) :: Task
385
-
REAL (KIND=8), INTENT( OUT ) :: c, cimag, gradc( 2 ), crr, crz, czz, rho ! sound speed and its derivatives
386
-
INTEGER :: AllocateStatus, iSegT, iz2
387
-
REAL (KIND=8) :: c1, c2, cz1, cz2, cr, cz, s1, s2, delta_r, delta_z
389
2289164
IF ( Task == 'INI' ) THEN
391
-
! *** read in SSP data ***
394
1
CALL ReadSSP( Depth, freq )
396
-
! Read the 2D SSP matrix
397
1
WRITE( PRTFile, * ) '__________________________________________________________________________'
398
1
WRITE( PRTFile, * )
399
1
WRITE( PRTFile, * ) 'Using range-dependent sound speed'
401
1
READ( SSPFile, * ) SSP%Nr
402
1
WRITE( PRTFile, * ) 'Number of SSP ranges = ', SSP%Nr
404
1
IF ( SSP%Nr < 2 ) THEN
405
#####
CALL ERROUT( 'sspMod: Quad', 'You must have at least two profiles in your 2D SSP field' )
408
1*
ALLOCATE( SSP%cMat( SSP%NPts, SSP%Nr ), SSP%czMat( SSP%NPts - 1, SSP%Nr ), SSP%Seg%r( SSP%Nr ), STAT = AllocateStatus )
409
1*
IF ( AllocateStatus /= 0 ) CALL ERROUT( 'sspMod: Quad', 'Insufficient memory to store SSP' )
411
1*
READ( SSPFile, * ) SSP%Seg%r( 1 : SSP%Nr )
412
1
WRITE( PRTFile, * )
413
1
WRITE( PRTFile, * ) 'Profile ranges (km):'
414
1*
WRITE( PRTFile, FMT="( F10.2 )" ) SSP%Seg%r( 1 : SSP%Nr )
416
1*
IF ( .NOT. monotonic( SSP%Seg%r, SSP%Nr ) ) THEN
417
#####
CALL ERROUT( 'sspMod: Quad', 'The ranges in the SSP must be monotone increasing' )
420
31*
SSP%Seg%r = 1000.0 * SSP%Seg%r ! convert km to m
422
1
WRITE( PRTFile, * )
423
1
WRITE( PRTFile, * ) 'Sound speed matrix:'
424
1
WRITE( PRTFile, * ) ' Depth (m ) Soundspeed (m/s)'
425
3*
DO iz2 = 1, SSP%NPts
426
2*
READ( SSPFile, * ) SSP%cMat( iz2, : )
427
-
! WRITE( PRTFile, FMT="( 'iSegz depth = ', F10.2, ' m' )" ) SSP%z( iz2 )
428
-
! WRITE( PRTFile, FMT="( 12F10.2 )" ) SSP%cMat( iz2, : )
429
3*
WRITE( PRTFile, FMT="( 12F10.2 )" ) SSP%z( iz2 ), SSP%cMat( iz2, : )
435
31*
DO iSegt = 1, SSP%Nr
436
61*
DO iz2 = 2, SSP%NPts
437
30*
delta_z = ( SSP%z( iz2 ) - SSP%z( iz2 - 1 ) )
438
60*
SSP%czMat( iz2 - 1, iSegt ) = ( SSP%cMat( iz2, iSegt ) - SSP%cMat( iz2 - 1, iSegt ) ) / delta_z
447
-
! *** Section to return SSP info ***
449
2289163
CALL UpdateDepthSegmentT( x, t )
451
-
! Check that x is inside the box where the sound speed is defined
452
2289163*
IF ( x( 1 ) < SSP%Seg%r( 1 ) .OR. x( 1 ) > SSP%Seg%r( SSP%Nr ) ) THEN ! .OR. &
453
#####
WRITE( PRTFile, * ) 'ray is outside the box where the ocean soundspeed is defined'
454
#####
WRITE( PRTFile, * ) ' x = ( r, z ) = ', x
455
#####
CALL ERROUT( 'sspMod: Quad', 'ray is outside the box where the soundspeed is defined' )
458
2289163
CALL UpdateRangeSegmentT( x, t )
460
-
! for this depth, x( 2 ), get the sound speed at both ends of the segment
461
2289163*
cz1 = SSP%czMat( iSegz, iSegr )
462
2289163*
cz2 = SSP%czMat( iSegz, iSegr + 1 )
464
2289163*
s2 = x( 2 ) - SSP%z( iSegz )
465
2289163*
delta_z = SSP%z( iSegz + 1 ) - SSP%z( iSegz )
467
2289163*
c1 = SSP%cMat( iSegz, iSegr ) + s2 * cz1
468
2289163*
c2 = SSP%cMat( iSegz, iSegr + 1 ) + s2 * cz2
470
-
! s1 = proportional distance of x( 1 ) in range
471
2289163*
delta_r = ( SSP%Seg%r( iSegr + 1 ) - SSP%Seg%r( iSegr ) )
472
2289163*
s1 = ( x( 1 ) - SSP%Seg%r( iSegr ) ) / delta_r
473
2289163
s1 = MIN( s1, 1.0D0 ) ! force piecewise constant extrapolation for points outside the box
474
2289163
s1 = MAX( s1, 0.0D0 ) ! "
476
2289163
c = ( 1.0D0 - s1 ) * c1 + s1 * c2
478
-
! interpolate the attenuation !!!! This will use the wrong segment if the ssp in the envil is sampled at different depths
479
2289163
s2 = s2 / delta_z ! convert to a proportional depth in the layer
480
2289163*
cimag = AIMAG( ( 1.0D0 - s2 ) * SSP%c( Isegz ) + s2 * SSP%c( Isegz + 1 ) ) ! volume attenuation is taken from the single c(z) profile
482
2289163
cz = ( 1.0D0 - s1 ) * cz1 + s1 * cz2
484
2289163
cr = ( c2 - c1 ) / delta_r
485
2289163
crz = ( cz2 - cz1 ) / delta_r
487
6867489
gradc = [ cr, cz ]
491
-
! linear interpolation for density
492
2289163*
W = ( x( 2 ) - SSP%z( iSegz ) ) / ( SSP%z( iSegz + 1 ) - SSP%z( iSegz ) )
493
2289163*
rho = ( 1.0D0 - W ) * SSP%rho( iSegz ) + W * SSP%rho( iSegz + 1 )
496
-
END SUBROUTINE Quad
498
-
! **********************************************************************!
500
#####
SUBROUTINE Hexahedral( x, t, c, cimag, gradc, cxx, cyy, czz, cxy, cxz, cyz, rho, freq, Task )
501
-
!! Trilinear hexahedral interpolation of SSP data
503
-
! assumes a rectilinear case (not the most general hexahedral)
505
-
INTEGER, PARAMETER :: SSPFile = 40
506
-
REAL (KIND=8), INTENT( IN ) :: freq
507
-
REAL (KIND=8), INTENT( IN ) :: x( 3 ) ! x-y-z coordinate where sound speed is evaluated
508
-
REAL (KIND=8), INTENT( IN ) :: t( 3 ) ! ray tangent; for edge cases of updating segments
509
-
CHARACTER (LEN =3), INTENT( IN ) :: Task
510
-
REAL (KIND=8), INTENT( OUT ) :: c, cimag, gradc( 3 ), cxx, cyy, czz, cxy, cxz, cyz, rho ! sound speed and its derivatives
511
-
INTEGER :: AllocateStatus, iSegxt, iSegyt, iy2, iz2
512
-
REAL (KIND=8) :: c1, c2, c11, c12, c21, c22, cz11, cz12, cz21, cz22, cz1, cz2, &
513
-
cx, cy, cz, s1, s2, s3
515
#####
IF ( Task == 'INI' ) THEN
517
-
! *** Section to read in SSP data ***
519
-
! Read dummy SSP information from the environmental file
520
-
! This is over-ridden by the info in the SSP file
521
-
! However, cz info is used in beam selection
523
#####
CALL ReadSSP( Depth, freq )
525
-
! Read the 3D SSP matrix
527
#####
WRITE( PRTFile, * )
528
#####
WRITE( PRTFile, * ) 'Reading sound speed profile from file'
531
#####
READ( SSPFile, * ) SSP%Nx
532
#####
WRITE( PRTFile, * )
533
#####
WRITE( PRTFile, * ) 'Number of points in x = ', SSP%Nx
534
#####
ALLOCATE( SSP%Seg%x( SSP%Nx ), STAT = AllocateStatus )
535
#####
IF ( AllocateStatus /= 0 ) CALL ERROUT( 'sspMod: Hexahedral', 'Insufficient memory to store SSP' )
536
#####
READ( SSPFile, * ) SSP%Seg%x
537
-
!WRITE( PRTFile, * )
538
-
!WRITE( PRTFile, * ) 'x-coordinates of SSP (km):'
539
-
!WRITE( PRTFile, FMT="( F10.2 )" ) SSP%Seg%x( 1 : SSP%Nx )
540
#####
IF ( .NOT. monotonic( SSP%Seg%x, SSP%Nx ) ) THEN
541
#####
CALL ERROUT( 'sspMod: Hexahedral', 'The x coordinates in the SSP must be monotone increasing' )
545
#####
READ( SSPFile, * ) SSP%Ny
546
#####
WRITE( PRTFile, * )
547
#####
WRITE( PRTFile, * ) 'Number of points in y = ', SSP%Ny
548
#####
ALLOCATE( SSP%Seg%y( SSP%Ny ), STAT = AllocateStatus )
549
#####
IF ( AllocateStatus /= 0 ) CALL ERROUT( 'sspMod: Hexahedral', 'Insufficient memory to store SSP' )
550
#####
READ( SSPFile, * ) SSP%Seg%y
551
-
!WRITE( PRTFile, * )
552
-
!WRITE( PRTFile, * ) 'y-coordinates of SSP (km):'
553
-
!WRITE( PRTFile, FMT="( F10.2 )" ) SSP%Seg%y( 1 : SSP%Ny )
554
#####
IF ( .NOT. monotonic( SSP%Seg%y, SSP%Ny ) ) THEN
555
#####
CALL ERROUT( 'sspMod: Hexahedral', 'The y coordinates in the SSP must be monotone increasing' )
559
#####
READ( SSPFile, * ) SSP%Nz
560
#####
WRITE( PRTFile, * )
561
#####
WRITE( PRTFile, * ) 'Number of points in z = ', SSP%Nz
562
#####
ALLOCATE( SSP%Seg%z( SSP%Nz ), STAT = AllocateStatus )
563
#####
IF ( AllocateStatus /= 0 ) CALL ERROUT( 'sspMod: Hexahedral', 'Insufficient memory to store SSP' )
564
#####
READ( SSPFile, * ) SSP%Seg%z
565
-
!WRITE( PRTFile, * )
566
-
!WRITE( PRTFile, * ) 'z-coordinates of SSP (km):'
567
-
!WRITE( PRTFile, FMT="( F10.2 )" ) SSP%Seg%z( 1 : SSP%Nz )
568
#####
IF ( .NOT. monotonic( SSP%Seg%z, SSP%Nz ) ) THEN
569
#####
CALL ERROUT( 'sspMod: Hexahedral', 'The z coordinates in the SSP must be monotone increasing' )
572
-
! SSP matrix should be bigger than 2x2x2
573
#####
IF ( SSP%Nx < 2 .OR. SSP%Ny < 2 .OR. SSP%Nz < 2 ) THEN
574
-
CALL ERROUT( 'sspMod: Hexahedral', &
575
#####
'You must have at least two points in x, y, z directions in your 3D SSP field' )
578
#####
IF ( SSP%Nz >= MaxSSP ) THEN
579
-
! LP: SSP%Nz / SSP%Seg%z will get assigned to SSP%NPts / SSP%z.
580
-
CALL ERROUT( 'sspMod: Hexahedral', &
581
#####
'Number of SSP points in Z exceeds limit' )
584
#####
ALLOCATE( SSP%cMat3( SSP%Nx, SSP%Ny, SSP%Nz ), SSP%czMat3( SSP%Nx, SSP%Ny, SSP%Nz - 1 ), STAT = AllocateStatus )
585
#####
IF ( AllocateStatus /= 0 ) CALL ERROUT( 'sspMod: Hexahedral', 'Insufficient memory to store SSP' )
587
#####
WRITE( PRTFile, * )
588
-
! WRITE( PRTFile, * ) 'Sound speed matrix:'
589
#####
DO iz2 = 1, SSP%Nz
590
#####
DO iy2 = 1, SSP%Ny
591
#####
READ( SSPFile, * ) SSP%cMat3( :, iy2, iz2 )
592
-
! WRITE( PRTFile, FMT="( 'z-section = ', F10.2, ' m' )" ) SSP%Seg%z( iz2 )
593
-
! WRITE( PRTFile, FMT="( 'y-section = ', F10.2, ' km' )" ) SSP%Seg%y( iy2 )
594
-
! WRITE( PRTFile, FMT="( 12F10.2 )" ) SSP%cMat3( :, iy2, iz2 )
598
#####
CLOSE( SSPFile )
600
#####
SSP%Seg%x = 1000.0 * SSP%Seg%x ! convert km to m
601
#####
SSP%Seg%y = 1000.0 * SSP%Seg%y ! convert km to m
604
#####
DO iSegxt = 1, SSP%Nx
605
#####
DO iSegyt = 1, SSP%Ny
606
#####
DO iz2 = 2, SSP%Nz
607
#####
SSP%czMat3( iSegxt, iSegyt, iz2 - 1 ) = &
608
#####
( SSP%cMat3( iSegxt, iSegyt, iz2 ) - SSP%cMat3( iSegxt, iSegyt, iz2 - 1 ) ) / &
609
#####
( SSP%Seg%z( iz2 ) - SSP%Seg%z( iz2 - 1 ) )
614
-
! over-ride the SSP%z values read in from the environmental file with these new values
615
#####
SSP%NPts = SSP%Nz
616
#####
SSP%z( 1 : SSP%Nz ) = SSP%Seg%z
621
-
! *** Section to return SSP info ***
623
-
! Check that x is inside the box where the sound speed is defined
624
#####
IF ( x( 1 ) < SSP%Seg%x( 1 ) .OR. x( 1 ) > SSP%Seg%x( SSP%Nx ) .OR. &
625
#####
x( 2 ) < SSP%Seg%y( 1 ) .OR. x( 2 ) > SSP%Seg%y( SSP%Ny ) ) THEN ! .OR. &
626
-
!!$ x( 3 ) < SSP%Seg%z( 1 ) .OR. x( 3 ) > SSP%Seg%z( SSP%Nz ) ) THEN
627
#####
WRITE( PRTFile, * ) 'ray is outside the box where the ocean soundspeed is defined'
628
#####
WRITE( PRTFile, * ) ' x = ( x, y, z ) = ', x
629
#####
CALL ERROUT( 'Hexahedral', 'ray is outside the box where the soundspeed is defined' )
632
#####
CALL Update3DXSegmentT( x, t )
633
#####
CALL Update3DYSegmentT( x, t )
634
#####
CALL Update3DZSegmentT( x, t )
636
-
! cz at the corners of the current rectangle
637
#####
cz11 = SSP%czMat3( iSegx, iSegy , iSegz )
638
#####
cz12 = SSP%czMat3( iSegx + 1, iSegy , iSegz )
639
#####
cz21 = SSP%czMat3( iSegx, iSegy + 1, iSegz )
640
#####
cz22 = SSP%czMat3( iSegx + 1, iSegy + 1, iSegz )
642
-
! for this depth, x( 3 ) get the sound speed at the corners of the current rectangle
643
#####
s3 = x( 3 ) - SSP%Seg%z( iSegz )
644
#####
c11 = SSP%cMat3( iSegx, iSegy , iSegz ) + s3 * cz11
645
#####
c21 = SSP%cMat3( iSegx + 1, iSegy , iSegz ) + s3 * cz12
646
#####
c12 = SSP%cMat3( iSegx, iSegy + 1, iSegz ) + s3 * cz21
647
#####
c22 = SSP%cMat3( iSegx + 1, iSegy + 1, iSegz ) + s3 * cz22
649
-
! s1 = proportional distance of x( 1 ) in x
650
#####
s1 = ( x( 1 ) - SSP%Seg%x( iSegx ) ) / ( SSP%Seg%x( iSegx + 1 ) - SSP%Seg%x( iSegx ) )
651
#####
s1 = MIN( s1, 1.0D0 ) ! force piecewise constant extrapolation for points outside the box
652
#####
s1 = MAX( s1, 0.0D0 ) ! "
654
-
! s2 = proportional distance of x( 2 ) in y
655
#####
s2 = ( x( 2 ) - SSP%Seg%y( iSegy ) ) / ( SSP%Seg%y( iSegy + 1 ) - SSP%Seg%y( iSegy ) )
656
#####
s2 = MIN( s2, 1.0D0 ) ! force piecewise constant extrapolation for points outside the box
657
#####
s2 = MAX( s2, 0.0D0 ) ! "
659
-
! interpolate the soundspeed in the x direction, at the two endpoints in y (top and bottom sides of rectangle)
660
#####
c1 = c11 + s1 * ( c21 - c11 )
661
#####
c2 = c12 + s1 * ( c22 - c12 )
662
-
!c = ( 1.0D0 - s2 ) * c1 + s2 * c2 ! interpolation in y
663
#####
cy = ( c2 - c1 ) / ( SSP%Seg%y( iSegy + 1 ) - SSP%Seg%y( iSegy ) )
665
-
! interpolate the soundspeed in the y direction, at the two endpoints in x (left and right sides of rectangle)
666
#####
c1 = c11 + s2 * ( c12 - c11 )
667
#####
c2 = c21 + s2 * ( c22 - c21 )
669
#####
c = c1 + s1 * ( c2 - c1 ) ! interpolation in x
671
-
! interpolate the attenuation !!!! This will use the wrong segment if the ssp in the envfil is sampled at different depths
672
#####
s3 = s3 / ( SSP%z( iSegz + 1 ) - SSP%z( iSegz ) ) ! convert s3 to a proportional distance in the layer
673
#####
cimag = AIMAG( ( 1.0D0 - s3 ) * SSP%c( Isegz ) + s3 * SSP%c( Isegz + 1 ) ) ! volume attenuation is taken from the single c(z) profile
675
#####
cx = ( c2 - c1 ) / ( SSP%Seg%x( iSegx + 1 ) - SSP%Seg%x( iSegx ) )
678
#####
cz1 = cz11 + s2 * ( cz21 - cz11 )
679
#####
cz2 = cz12 + s2 * ( cz22 - cz12 )
680
#####
cz = cz1 + s1 * ( cz2 - cz1 ) ! interpolation in z
682
-
!gradc = [ cx, cy, cz ]
683
#####
gradc( 1 ) = cx
684
#####
gradc( 2 ) = cy
685
#####
gradc( 3 ) = cz
693
-
! write( *, FMT="( 'SSP', I3, 2X, 4F10.2, F10.4 )" ) layer, x, c, cz
695
-
! linear interpolation for density
696
#####
W = ( x( 3 ) - SSP%z( iSegz ) ) / ( SSP%z( iSegz + 1 ) - SSP%z( iSegz ) )
697
#####
rho = ( 1.0D0 - W ) * SSP%rho( iSegz ) + W * SSP%rho( iSegz + 1 )
700
-
END SUBROUTINE Hexahedral
702
-
! **********************************************************************!
704
#####
SUBROUTINE Analytic( x, t, c, cimag, gradc, crr, crz, czz, rho )
706
-
REAL (KIND=8), INTENT( IN ) :: x( 2 )
707
-
REAL (KIND=8), INTENT( IN ) :: t( 2 ) ! ray tangent; for edge cases of updating segments
708
-
REAL (KIND=8), INTENT( OUT ) :: c, cimag, gradc( 2 ), crr, crz, czz, rho
709
-
REAL (KIND=8) :: c0, cr, cz, DxtDz, xt
715
-
! homogeneous halfspace was removed since BELLHOP needs to get gradc just a little below the boundaries, on ray reflection
717
-
!!$ IF ( x( 2 ) < 5000.0 ) THEN
718
#####
xt = 2.0 * ( x( 2 ) - 1300.0 ) / 1300.0
719
#####
DxtDz = 2.0 / 1300.0
720
#####
c = C0 * ( 1.0 + 0.00737*( xt - 1.0 + EXP( -xt ) ) )
722
#####
cz = C0 * 0.00737 * ( 1.0 - EXP( -xt ) ) * DxtDz
723
#####
czz = C0 * 0.00737 * EXP( -xt ) * DxtDz ** 2
725
-
!!$ ! Homogeneous half-space
726
-
!!$ xt = 2.0 * ( 5000.0 - 1300.0 ) / 1300.0
727
-
!!$ c = C0 * ( 1.0 + 0.00737 * ( xt - 1.0 + EXP( -xt ) ) )
734
#####
gradc = [ cr, cz ]
739
-
END SUBROUTINE Analytic
741
-
! **********************************************************************!
743
#####
SUBROUTINE AnalyticCosh( x, t, c, cimag, gradc, crr, crz, czz, rho )
745
-
REAL (KIND=8), INTENT( IN ) :: x( 2 )
746
-
REAL (KIND=8), INTENT( IN ) :: t( 2 ) ! ray tangent; for edge cases of updating segments
747
-
REAL (KIND=8), INTENT( OUT ) :: c, cimag, gradc( 2 ), crr, crz, czz, rho
748
-
REAL (KIND=8) :: cr, cz, A, B, D, z
760
#####
c = A * COSH( B * ( Z - D ) )
761
#####
cz = B * A * SINH( B * ( Z - D ) )
762
#####
czz = B * B * A * COSH( B * ( Z - D ) )
767
#####
gradc = [ cr, cz ]
772
-
END SUBROUTINE AnalyticCosh
774
-
! **********************************************************************!
776
#####
SUBROUTINE Analytic3D( x, t, c, cimag, gradc, cxx, cyy, czz, cxy, cxz, cyz, rho )
778
-
REAL (KIND=8), INTENT( IN ) :: x( 3 )
779
-
REAL (KIND=8), INTENT( OUT ) :: c, cimag, gradc( 3 )
780
-
REAL (KIND=8), INTENT( OUT ) :: cxx, cyy, czz, cxy, cxz, cyz
781
-
REAL (KIND=8), INTENT( IN ) :: t( 3 ) ! ray tangent; for edge cases of updating segments
782
-
REAL (KIND=8), INTENT( INOUT ) :: rho
784
-
REAL (KIND=8) :: c0, W, Wz, epsilon, epsilon_y
790
-
!!$ IF ( x( 3 ) .LT. 5000.0 ) THEN
791
#####
epsilon = 0.00737 + x( 2 ) / 100000.0 * 0.003
792
#####
epsilon_y = 0.003 / 100000.0
794
#####
W = 2.0 * ( x( 3 ) - 1300.0 ) / 1300.0
795
#####
Wz = 2.0 / 1300.0
797
#####
c = c0 * ( 1.0 + epsilon * ( W - 1.0 + EXP( -W ) ) )
799
#####
gradc( 2 ) = c0 * epsilon_y * ( W - 1.0 + EXP( -W ) )
800
#####
gradc( 3 ) = c0 * epsilon * ( 1.0 - EXP( -W ) ) * Wz
801
#####
czz = c0 * epsilon * EXP( -W ) * Wz **2
802
#####
cyz = c0 * epsilon_y * ( 1.0 - EXP( -W ) ) * Wz
803
-
!!$ ELSE ! HOMOGENEOUS HALF-SPACE
804
-
!!$ W = 2.0 * ( 5000.0 - 1300.0 ) / 1300.0
805
-
!!$ c = c0*( 1.0 + 0.00737 * ( W - 1.0 + EXP( -W ) ) )
806
-
!!$ gradc( 2 ) = 0.0
807
-
!!$ gradc( 3 ) = 0.0
812
#####
gradc( 1 ) = 0.0
819
-
END SUBROUTINE Analytic3D
821
-
! **********************************************************************!
823
14
SUBROUTINE ReadSSP( Depth, freq )
824
-
!! Reads SSP data from the environmental file and convert to Nepers/m
828
-
REAL (KIND=8), INTENT(IN) :: freq, Depth
830
14
WRITE( PRTFile, * )
831
14
WRITE( PRTFile, * ) 'Sound speed profile:'
833
14
WRITE( PRTFile, "( ' z alphaR betaR rho alphaI betaI' )" )
834
14
WRITE( PRTFile, "( ' (m) (m/s) (m/s) (g/cm^3) (m/s) (m/s)', / )" )
838
55*
DO iz = 1, MaxSSP
840
55*
READ( ENVFile, * ) SSP%z( iz ), alphaR, betaR, rhoR, alphaI, betaI
841
55*
WRITE( PRTFile, FMT="( F10.2, 3X, 2F10.2, 3X, F6.2, 3X, 2F10.4 )" ) SSP%z( iz ), alphaR, betaR, rhoR, alphaI, betaI
843
55*
SSP%c( iz ) = CRCI( SSP%z( iz ), alphaR, alphaI, freq, freq, SSP%AttenUnit, betaPowerLaw, fT )
844
55*
SSP%rho( iz ) = rhoR
846
-
! verify that the depths are monotone increasing
847
55
IF ( iz > 1 ) THEN
848
41*
IF ( SSP%z( iz ) <= SSP%z( iz - 1 ) ) THEN
849
#####
WRITE( PRTFile, * ) 'Bad depth in SSP: ', SSP%z( iz )
850
#####
CALL ERROUT( 'ReadSSP', 'The depths in the SSP must be monotone increasing' )
854
-
! compute gradient, cz
855
178*
IF ( iz > 1 ) SSP%cz( iz - 1 ) = ( SSP%c( iz ) - SSP%c( iz - 1 ) ) / &
856
164*
( SSP%z( iz ) - SSP%z( iz - 1 ) )
858
-
! Did we read the last point?
859
55*
IF ( ABS( SSP%z( iz ) - Depth ) < 100. * EPSILON( 1.0e0 ) ) THEN
861
14
IF ( SSP%NPts == 1 ) THEN
862
#####
WRITE( PRTFile, * ) '#SSP points: ', SSP%NPts
863
#####
CALL ERROUT( 'ReadSSP', 'The SSP must have at least 2 points' )
869
41*
SSP%NPts = SSP%NPts + 1
872
-
! Fall through means too many points in the profile
873
#####
WRITE( PRTFile, * ) 'Max. #SSP points: ', MaxSSP
874
#####
CALL ERROUT( 'ReadSSP', 'Number of SSP points exceeds limit' )
876
-
END SUBROUTINE ReadSSP
878
42690794
SUBROUTINE UpdateDepthSegmentT( x, t )
879
-
REAL (KIND=8), INTENT(IN) :: x( 2 ), t( 2 )
881
-
! LP: Handles edge cases based on which direction the ray is going. If the
882
-
! ray takes a small step in the direction of t, it will remain in the same
883
-
! segment as it is now.
885
42690794
IF ( t( 2 ) >= 0.0 ) THEN
886
-
! SSP%z( iSegz ) <= x( 2 ) < SSP%z( iSegz + 1 )
887
21559934*
DO WHILE ( x( 2 ) < SSP%z( iSegz ) .AND. iSegz > 1 )
888
#####
iSegz = iSegz - 1
890
22046181*
DO WHILE ( x( 2 ) >= SSP%z( iSegz + 1 ) .AND. iSegz < SSP%Npts-1 )
891
486247
iSegz = iSegz + 1
894
-
! SSP%z( iSegz ) < x( 2 ) <= SSP%z( iSegz + 1 )
895
21130860*
DO WHILE ( x( 2 ) > SSP%z( iSegz + 1 ) .AND. iSegz < SSP%Npts-1 )
896
#####
iSegz = iSegz + 1
898
21513393*
DO WHILE ( x( 2 ) <= SSP%z( iSegz ) .AND. iSegz > 1 )
899
382533
iSegz = iSegz - 1
903
42690794
END SUBROUTINE UpdateDepthSegmentT
905
2289163
SUBROUTINE UpdateRangeSegmentT( x, t )
906
-
REAL (KIND=8), INTENT(IN) :: x( 2 ), t( 2 )
908
-
! LP: See UpdateDepthSegmentT
910
2289163
IF ( t( 1 ) >= 0.0 ) THEN
911
-
! SSP%Seg%r( iSegr ) <= x( 1 ) < SSP%Seg%r( iSegr + 1 )
912
2269935*
DO WHILE ( x( 1 ) < SSP%Seg%r( iSegr ) .AND. iSegr > 1 )
913
#####
iSegr = iSegr - 1
915
2281188*
DO WHILE ( x( 1 ) >= SSP%Seg%r( iSegr + 1 ) .AND. iSegr < SSP%Nr-1 )
916
11253
iSegr = iSegr + 1
919
-
! SSP%Seg%r( iSegr ) < x( 1 ) <= SSP%Seg%r( iSegr + 1 )
920
19228*
DO WHILE ( x( 1 ) > SSP%Seg%r( iSegr + 1 ) .AND. iSegr < SSP%Nr-1 )
921
#####
iSegr = iSegr + 1
923
25112*
DO WHILE ( x( 1 ) <= SSP%Seg%r( iSegr ) .AND. iSegr > 1 )
924
5884
iSegr = iSegr - 1
928
2289163
END SUBROUTINE UpdateRangeSegmentT
930
#####
SUBROUTINE Update3DXSegmentT( x, t )
931
-
REAL (KIND=8), INTENT(IN) :: x( 3 ), t( 3 )
933
-
! LP: See UpdateDepthSegmentT
935
#####
IF ( t( 1 ) >= 0.0 ) THEN
936
-
! SSP%Seg%x( iSegx ) <= x( 1 ) < SSP%Seg%x( iSegx + 1 )
937
#####
DO WHILE ( x( 1 ) < SSP%Seg%x( iSegx ) .AND. iSegx > 1 )
938
#####
iSegx = iSegx - 1
940
#####
DO WHILE ( x( 1 ) >= SSP%Seg%x( iSegx + 1 ) .AND. iSegx < SSP%Nx-1 )
941
#####
iSegx = iSegx + 1
944
-
! SSP%Seg%x( iSegx ) < x( 1 ) <= SSP%Seg%x( iSegx + 1 )
945
#####
DO WHILE ( x( 1 ) > SSP%Seg%x( iSegx + 1 ) .AND. iSegx < SSP%Nx-1 )
946
#####
iSegx = iSegx + 1
948
#####
DO WHILE ( x( 1 ) <= SSP%Seg%x( iSegx ) .AND. iSegx > 1 )
949
#####
iSegx = iSegx - 1
953
#####
END SUBROUTINE Update3DXSegmentT
955
#####
SUBROUTINE Update3DYSegmentT( x, t )
956
-
REAL (KIND=8), INTENT(IN) :: x( 3 ), t( 3 )
958
-
! LP: See UpdateDepthSegmentT
960
#####
IF ( t( 2 ) >= 0.0 ) THEN
961
-
! SSP%Seg%y( iSegy ) <= x( 2 ) < SSP%Seg%y( iSegy + 1 )
962
#####
DO WHILE ( x( 2 ) < SSP%Seg%y( iSegy ) .AND. iSegy > 1 )
963
#####
iSegy = iSegy - 1
965
#####
DO WHILE ( x( 2 ) >= SSP%Seg%y( iSegy + 1 ) .AND. iSegy < SSP%Ny-1 )
966
#####
iSegy = iSegy + 1
969
-
! SSP%Seg%y( iSegy ) < x( 2 ) <= SSP%Seg%y( iSegy + 1 )
970
#####
DO WHILE ( x( 2 ) > SSP%Seg%y( iSegy + 1 ) .AND. iSegy < SSP%Ny-1 )
971
#####
iSegy = iSegy + 1
973
#####
DO WHILE ( x( 2 ) <= SSP%Seg%y( iSegy ) .AND. iSegy > 1 )
974
#####
iSegy = iSegy - 1
978
#####
END SUBROUTINE Update3DYSegmentT
980
#####
SUBROUTINE Update3DZSegmentT( x, t )
981
-
REAL (KIND=8), INTENT(IN) :: x( 3 ), t( 3 )
983
-
! LP: See UpdateDepthSegmentT
985
#####
IF ( t( 3 ) >= 0.0 ) THEN
986
-
! SSP%Seg%z( iSegz ) <= x( 3 ) < SSP%Seg%z( iSegz + 1 )
987
#####
DO WHILE ( x( 3 ) < SSP%Seg%z( iSegz ) .AND. iSegz > 1 )
988
#####
iSegz = iSegz - 1
990
#####
DO WHILE ( x( 3 ) >= SSP%Seg%z( iSegz + 1 ) .AND. iSegz < SSP%Nz-1 )
991
#####
iSegz = iSegz + 1
994
-
! SSP%Seg%z( iSegz ) < x( 3 ) <= SSP%Seg%z( iSegz + 1 )
995
#####
DO WHILE ( x( 3 ) > SSP%Seg%z( iSegz + 1 ) .AND. iSegz < SSP%Nz-1 )
996
#####
iSegz = iSegz + 1
998
#####
DO WHILE ( x( 3 ) <= SSP%Seg%z( iSegz ) .AND. iSegz > 1 )
999
#####
iSegz = iSegz - 1
1003
#####
END SUBROUTINE Update3DZSegmentT
1005
#####
END MODULE sspmod
1005
#####
END MODULE sspmod
1005
#####
END MODULE sspmod
1005
#####
END MODULE sspmod
1005
#####
END MODULE sspmod
1005
#####
END MODULE sspmod
1005
#####
END MODULE sspmod
1005
#####
END MODULE sspmod