BellhopCore Subroutine

subroutine BellhopCore()

Uses

  • proc~~bellhopcore~2~~UsesGraph proc~bellhopcore~2 BellhopCore module~arrmod ArrMod proc~bellhopcore~2->module~arrmod module~attenmod AttenMod proc~bellhopcore~2->module~attenmod module~bellhopmod bellhopMod module~arrmod->module~bellhopmod module~mathconstants MathConstants module~arrmod->module~mathconstants module~fatalerror FatalError module~attenmod->module~fatalerror module~bellhopmod->module~mathconstants

Core subroutine to run Bellhop algorithm

Arguments

None

Calls

proc~~bellhopcore~2~~CallsGraph proc~bellhopcore~2 BellhopCore proc~crci CRCI proc~bellhopcore~2->proc~crci proc~errout ERROUT proc~bellhopcore~2->proc~errout proc~evaluatessp EvaluateSSP proc~bellhopcore~2->proc~evaluatessp proc~influencecervenycart InfluenceCervenyCart proc~bellhopcore~2->proc~influencecervenycart proc~influencecervenyraycen InfluenceCervenyRayCen proc~bellhopcore~2->proc~influencecervenyraycen proc~influencegeogaussiancart InfluenceGeoGaussianCart proc~bellhopcore~2->proc~influencegeogaussiancart proc~influencegeohatcart InfluenceGeoHatCart proc~bellhopcore~2->proc~influencegeohatcart proc~influencegeohatraycen InfluenceGeoHatRayCen proc~bellhopcore~2->proc~influencegeohatraycen proc~influencesgb InfluenceSGB proc~bellhopcore~2->proc~influencesgb proc~pickepsilon~2 PickEpsilon proc~bellhopcore~2->proc~pickepsilon~2 proc~scalepressure ScalePressure proc~bellhopcore~2->proc~scalepressure proc~traceray2d~2 TraceRay2D proc~bellhopcore~2->proc~traceray2d~2 proc~writearrivalsascii WriteArrivalsASCII proc~bellhopcore~2->proc~writearrivalsascii proc~writearrivalsbinary WriteArrivalsBinary proc~bellhopcore~2->proc~writearrivalsbinary proc~writeray2d WriteRay2D proc~bellhopcore~2->proc~writeray2d proc~crci->proc~errout proc~franc_garr Franc_Garr proc~crci->proc~franc_garr proc~evaluatessp->proc~errout proc~analytic Analytic proc~evaluatessp->proc~analytic proc~ccubic cCubic proc~evaluatessp->proc~ccubic proc~clinear cLinear proc~evaluatessp->proc~clinear proc~cpchip cPCHIP proc~evaluatessp->proc~cpchip proc~hexahedral Hexahedral proc~evaluatessp->proc~hexahedral proc~n2linear n2Linear proc~evaluatessp->proc~n2linear proc~quad Quad proc~evaluatessp->proc~quad proc~influencecervenycart->proc~errout proc~influencecervenycart->proc~evaluatessp proc~branchcut BranchCut proc~influencecervenycart->proc~branchcut proc~hermite Hermite proc~influencecervenycart->proc~hermite proc~rtoir RToIR proc~influencecervenycart->proc~rtoir proc~influencecervenyraycen->proc~errout proc~influencecervenyraycen->proc~branchcut proc~influencecervenyraycen->proc~hermite proc~influencecervenyraycen->proc~rtoir proc~applycontribution~2 ApplyContribution proc~influencegeogaussiancart->proc~applycontribution~2 proc~finalphase FinalPhase proc~influencegeogaussiancart->proc~finalphase proc~incphaseifcaustic IncPhaseIfCaustic proc~influencegeogaussiancart->proc~incphaseifcaustic proc~influencegeohatcart->proc~applycontribution~2 proc~influencegeohatcart->proc~finalphase proc~influencegeohatcart->proc~incphaseifcaustic proc~influencegeohatraycen->proc~applycontribution~2 proc~influencegeohatraycen->proc~finalphase proc~influencegeohatraycen->proc~incphaseifcaustic proc~influencegeohatraycen->proc~rtoir proc~influencesgb->proc~applycontribution~2 proc~influencesgb->proc~incphaseifcaustic proc~pickepsilon~2->proc~errout sngl sngl proc~scalepressure->sngl proc~traceray2d~2->proc~evaluatessp proc~distances2d Distances2D proc~traceray2d~2->proc~distances2d proc~getbotseg GetBotSeg proc~traceray2d~2->proc~getbotseg proc~gettopseg GetTopSeg proc~traceray2d~2->proc~gettopseg proc~reflect2d~2 Reflect2D proc~traceray2d~2->proc~reflect2d~2 proc~step2d Step2D proc~traceray2d~2->proc~step2d proc~writearrivalsascii->sngl proc~writearrivalsbinary->sngl proc~applycontribution~2->proc~writeray2d proc~applycontribution~2->sngl proc~addarr AddArr proc~applycontribution~2->proc~addarr proc~writeray3d WriteRay3D proc~applycontribution~2->proc~writeray3d proc~readssp ReadSSP proc~ccubic->proc~readssp proc~splineall SPLINEALL proc~ccubic->proc~splineall proc~updatedepthsegmentt UpdateDepthSegmentT proc~ccubic->proc~updatedepthsegmentt proc~clinear->proc~readssp proc~clinear->proc~updatedepthsegmentt proc~pchip PCHIP proc~cpchip->proc~pchip proc~cpchip->proc~readssp proc~cpchip->proc~updatedepthsegmentt proc~isatcaustic IsAtCaustic proc~finalphase->proc~isatcaustic proc~getbotseg->proc~errout proc~gettopseg->proc~errout proc~hexahedral->proc~errout interface~monotonic monotonic proc~hexahedral->interface~monotonic proc~hexahedral->proc~readssp proc~update3dxsegmentt Update3DXSegmentT proc~hexahedral->proc~update3dxsegmentt proc~update3dysegmentt Update3DYSegmentT proc~hexahedral->proc~update3dysegmentt proc~update3dzsegmentt Update3DZSegmentT proc~hexahedral->proc~update3dzsegmentt proc~incphaseifcaustic->proc~isatcaustic proc~n2linear->proc~readssp proc~n2linear->proc~updatedepthsegmentt proc~quad->proc~errout proc~quad->interface~monotonic proc~quad->proc~readssp proc~quad->proc~updatedepthsegmentt proc~updaterangesegmentt UpdateRangeSegmentT proc~quad->proc~updaterangesegmentt proc~reflect2d~2->proc~errout proc~reflect2d~2->proc~evaluatessp datan datan proc~reflect2d~2->datan dcos dcos proc~reflect2d~2->dcos dsin dsin proc~reflect2d~2->dsin proc~interpolatereflectioncoefficient InterpolateReflectionCoefficient proc~reflect2d~2->proc~interpolatereflectioncoefficient proc~step2d->proc~evaluatessp proc~reducestep2d ReduceStep2D proc~step2d->proc~reducestep2d proc~steptobdry2d StepToBdry2D proc~step2d->proc~steptobdry2d proc~monotonic_dble monotonic_dble interface~monotonic->proc~monotonic_dble proc~monotonic_sngl monotonic_sngl interface~monotonic->proc~monotonic_sngl proc~addarr->sngl proc~cspline CSPLINE proc~pchip->proc~cspline proc~fprime_interior_cmplx fprime_interior_Cmplx proc~pchip->proc~fprime_interior_cmplx proc~fprime_left_end_cmplx fprime_left_end_Cmplx proc~pchip->proc~fprime_left_end_cmplx proc~fprime_right_end_cmplx fprime_right_end_Cmplx proc~pchip->proc~fprime_right_end_cmplx proc~h_del h_del proc~pchip->proc~h_del proc~readssp->proc~crci proc~readssp->proc~errout proc~fprime_interior fprime_interior proc~fprime_interior_cmplx->proc~fprime_interior proc~fprime_left_end fprime_left_end proc~fprime_left_end_cmplx->proc~fprime_left_end proc~fprime_right_end fprime_right_end proc~fprime_right_end_cmplx->proc~fprime_right_end

Called by

proc~~bellhopcore~2~~CalledByGraph proc~bellhopcore~2 BellhopCore program~bellhop BELLHOP program~bellhop->proc~bellhopcore~2

Source Code

SUBROUTINE BellhopCore
  !! Core subroutine to run Bellhop algorithm

  USE ArrMod
  USE AttenMod

  INTEGER, PARAMETER   :: ArrivalsStorage = 200000000, MinNArr = 10
  INTEGER              :: IBPvec( 1 ), ibp, is, iBeamWindow2, Irz1, Irec, NalphaOpt, iSeg
  REAL                 :: Tstart, Tstop
  REAL        (KIND=8) :: Amp0, DalphaOpt, xs( 2 ), tdummy( 2 ), RadMax, s, &
                          c, cimag, gradc( 2 ), crr, crz, czz, rho
  COMPLEX, ALLOCATABLE :: U( :, : )
  COMPLEX     (KIND=8) :: epsilon

  CALL CPU_TIME( Tstart )

  omega = 2.0 * pi * freq

  IF ( Beam%deltas == 0.0 ) THEN
     Beam%deltas = ( Bdry%Bot%HS%Depth - Bdry%Top%HS%Depth ) / 10.0   ! Automatic step size selection
     WRITE( PRTFile, * )
     WRITE( PRTFile, fmt = '(  '' Step length,       deltas = '', G11.4, '' m (automatically selected)'' )' ) Beam%deltas
  END IF

  Angles%alpha  = DegRad * Angles%alpha   ! convert to radians
  Angles%Dalpha = 0.0
  IF ( Angles%Nalpha /= 1 ) &
       Angles%Dalpha = ( Angles%alpha( Angles%Nalpha ) - Angles%alpha( 1 ) ) / ( Angles%Nalpha - 1 )  ! angular spacing between beams

  ! convert range-dependent geoacoustic parameters from user to program units
  IF ( atiType( 2 : 2 ) == 'L' ) THEN
     DO iSeg = 1, NatiPts
        Top( iSeg )%HS%cp = CRCI( 1D20, Top( iSeg )%HS%alphaR, Top( iSeg )%HS%alphaI, freq, freq, 'W ', &
             betaPowerLaw, ft )   ! compressional wave speed
        Top( iSeg )%HS%cs = CRCI( 1D20, Top( iSeg )%HS%betaR,  Top( iSeg )%HS%betaI,  freq, freq, 'W ', &
             betaPowerLaw, ft )   ! shear         wave speed
     END DO
  END IF

  IF ( btyType( 2 : 2 ) == 'L' ) THEN
     DO iSeg = 1, NbtyPts
        Bot( iSeg )%HS%cp = CRCI( 1D20, Bot( iSeg )%HS%alphaR, Bot( iSeg )%HS%alphaI, freq, freq, 'W ', &
             betaPowerLaw, ft )   ! compressional wave speed
        Bot( iSeg )%HS%cs = CRCI( 1D20, Bot( iSeg )%HS%betaR,  Bot( iSeg )%HS%betaI,  freq, freq, 'W ', &
             betaPowerLaw, ft )   ! shear         wave speed
     END DO
  END IF

  SELECT CASE ( Beam%RunType( 5 : 5 ) )
  CASE ( 'I' )
     NRz_per_range = 1         ! irregular grid
  CASE DEFAULT
     NRz_per_range = Pos%NRz   ! rectilinear grid
  END SELECT

  ! for a TL calculation, allocate space for the pressure matrix
  SELECT CASE ( Beam%RunType( 1 : 1 ) )
  CASE ( 'C', 'S', 'I' )        ! TL calculation
     ALLOCATE ( U( NRz_per_range, Pos%NRr ), Stat = IAllocStat )
     IF ( IAllocStat /= 0 ) &
          CALL ERROUT( 'BELLHOP', 'Insufficient memory for TL matrix: reduce Nr * NRz'  )
  CASE ( 'A', 'a', 'R', 'E' )   ! Arrivals calculation
     ALLOCATE ( U( 1, 1 ), Stat = IAllocStat )   ! open a dummy variable
  END SELECT

  ! for an arrivals run, allocate space for arrivals matrices
  SELECT CASE ( Beam%RunType( 1 : 1 ) )
  CASE ( 'A', 'a' )
     MaxNArr = MAX( ArrivalsStorage / ( NRz_per_range * Pos%NRr ), MinNArr )   ! allow space for at least 10 arrivals
     WRITE( PRTFile, * )
     WRITE( PRTFile, * ) '( Maximum # of arrivals = ', MaxNArr, ')'

     ALLOCATE ( Arr( NRz_per_range, Pos%NRr, MaxNArr ), NArr( NRz_per_range, Pos%NRr ), Stat = IAllocStat )
     IF ( IAllocStat /= 0 ) CALL ERROUT( 'BELLHOP', &
          'Insufficient memory to allocate arrivals matrix; reduce parameter ArrivalsStorage' )
  CASE DEFAULT
     MaxNArr = 1
     ALLOCATE ( Arr( NRz_per_range, Pos%NRr, 1 ), NArr( NRz_per_range, Pos%NRr ), Stat = IAllocStat )
  END SELECT

  WRITE( PRTFile, * )

  SourceDepth: DO is = 1, Pos%NSz
     xs = [ 0.0, Pos%sz( is ) ]   ! source coordinate

     SELECT CASE ( Beam%RunType( 1 : 1 ) )
     CASE ( 'C', 'S', 'I' ) ! TL calculation, zero out pressure matrix
        U = 0.0
     CASE ( 'A', 'a' )      ! Arrivals calculation, zero out arrival matrix
        NArr = 0
     END SELECT

     ! LP: This initialization was missing (only done once globally). In some
     ! cases (a source on a boundary), in conjunction with other subtle issues,
     ! the missing initialization caused the initial state of one ray to be
     ! dependent on the final state of the previous ray, which is obviously
     ! non-physical.
     ! This initialization is here in addition to TraceRay2D because of EvaluateSSP.
     iSegz = 1
     iSegr = 1

     tdummy = [ 1.0, 0.0 ]
     CALL EvaluateSSP( xs, tdummy, c, cimag, gradc, crr, crz, czz, rho, freq, 'TAB' )
     RadMax = 5 * c / freq  ! 5 wavelength max radius

     ! Are there enough beams?
     DalphaOpt = SQRT( c / ( 6.0 * freq * Pos%Rr( Pos%NRr ) ) )
     NalphaOpt = 2 + INT( ( Angles%alpha( Angles%Nalpha ) - Angles%alpha( 1 ) ) / DalphaOpt )

     IF ( Beam%RunType( 1 : 1 ) == 'C' .AND. Angles%Nalpha < NalphaOpt ) THEN
        WRITE( PRTFile, * ) 'Warning in BELLHOP : Too few beams'
        WRITE( PRTFile, * ) 'Nalpha should be at least = ', NalphaOpt
     ENDIF

     ! Trace successive beams

     DeclinationAngle: DO ialpha = 1, Angles%Nalpha
        SrcDeclAngle = RadDeg * Angles%alpha( ialpha )          ! take-off declination angle in degrees

        IF ( Angles%iSingle_alpha == 0 .OR. ialpha == Angles%iSingle_alpha ) THEN    ! Single beam run?

           IBPvec = maxloc( SrcBmPat( :, 1 ), mask = SrcBmPat( :, 1 ) < SrcDeclAngle )  ! index of ray angle in beam pattern
           IBP    = IBPvec( 1 )
           IBP    = MAX( IBP, 1 )               ! don't go before beginning of table
           IBP    = MIN( IBP, NSBPPts - 1 )     ! don't go past end of table

           ! linear interpolation to get amplitude
           s    = ( SrcDeclAngle  - SrcBmPat( IBP, 1 ) ) / ( SrcBmPat( IBP + 1, 1 ) - SrcBmPat( IBP, 1 ) )
           Amp0 = ( 1 - s ) * SrcBmPat( IBP, 2 ) + s * SrcBmPat( IBP + 1, 2 )

           ! Lloyd mirror pattern for semi-coherent option
           IF ( Beam%RunType( 1 : 1 ) == 'S' ) &
              Amp0 = Amp0 * SQRT( 2.0 ) * ABS( SIN( omega / c * xs( 2 ) * SIN( Angles%alpha( ialpha ) ) ) )

           ! show progress ...
           IF ( MOD( ialpha - 1, max( Angles%Nalpha / 50, 1 ) ) == 0 ) THEN
              WRITE( PRTFile, FMT = "( 'Tracing beam ', I7, F10.2 )" ) ialpha, SrcDeclAngle
              FLUSH( PRTFile )
           END IF

           CALL TraceRay2D( xs, Angles%alpha( ialpha ), Amp0 )   ! Trace a ray

           IF ( Beam%RunType( 1 : 1 ) == 'R' ) THEN   ! Write the ray trajectory to RAYFile
              CALL WriteRay2D( SrcDeclAngle, Beam%Nsteps )
           ELSE                                       ! Compute the contribution to the field

              epsilon = PickEpsilon( Beam%Type( 1 : 2 ), omega, c, gradc, Angles%alpha( ialpha ), &
                   Angles%Dalpha, Beam%rLoop, Beam%epsMultiplier ) ! 'optimal' beam constant

              SELECT CASE ( Beam%Type( 1 : 1 ) )
              CASE ( 'R' )
                 iBeamWindow2 = Beam%iBeamWindow **2
                 RadMax       = 50 * c / freq  ! 50 wavelength max radius
                 CALL InfluenceCervenyRayCen(   U, epsilon, Angles%alpha( ialpha ), iBeamWindow2, RadMax )
              CASE ( 'C' )
                 iBeamWindow2 = Beam%iBeamWindow **2
                 RadMax       = 50 * c / freq  ! 50 wavelength max radius
                 CALL InfluenceCervenyCart(     U, epsilon, Angles%alpha( ialpha ), iBeamWindow2, RadMax )
              CASE ( 'g' )
                 CALL InfluenceGeoHatRayCen(    U, Angles%alpha( ialpha ), Angles%Dalpha )
              CASE ( 'S' )
                 RadMax       = 50 * c / freq  ! 50 wavelength max radius
                 CALL InfluenceSGB(             U, Angles%alpha( ialpha ), Angles%Dalpha, RadMax )
              CASE ( 'B' )
                 CALL InfluenceGeoGaussianCart( U, Angles%alpha( ialpha ), Angles%Dalpha )
             CASE DEFAULT
                 CALL InfluenceGeoHatCart(      U, Angles%alpha( ialpha ), Angles%Dalpha )
              END SELECT

           END IF
        END IF
     END DO DeclinationAngle

     ! write results to disk

     SELECT CASE ( Beam%RunType( 1 : 1 ) )
     CASE ( 'C', 'S', 'I' )   ! TL calculation
        CALL ScalePressure( Angles%Dalpha, ray2D( 1 )%c, Pos%Rr, U, NRz_per_range, Pos%NRr, Beam%RunType, freq )
        IRec = 10 + NRz_per_range * ( is - 1 )
        RcvrDepth: DO Irz1 = 1, NRz_per_range
           IRec = IRec + 1
           WRITE( SHDFile, REC = IRec ) U( Irz1, 1 : Pos%NRr )
        END DO RcvrDepth
     CASE ( 'A' )             ! arrivals calculation, ascii
        CALL WriteArrivalsASCII(  Pos%Rr, NRz_per_range, Pos%NRr, Beam%RunType( 4 : 4 ) )
     CASE ( 'a' )             ! arrivals calculation, binary
        CALL WriteArrivalsBinary( Pos%Rr, NRz_per_range, Pos%NRr, Beam%RunType( 4 : 4 ) )
     END SELECT

  END DO SourceDepth

  ! Display run time
  CALL CPU_TIME( Tstop )
  WRITE( PRTFile, "( /, ' CPU Time = ', G15.3, 's' )" ) Tstop - Tstart

  ! close all files
  SELECT CASE ( Beam%RunType( 1 : 1 ) )
  CASE ( 'C', 'S', 'I' )      ! TL calculation
     CLOSE( SHDFile )
  CASE ( 'A', 'a' )           ! arrivals calculation
     CLOSE( ARRFile )
  CASE ( 'R', 'E' )                ! ray trace
     CLOSE( RAYFile )
  END SELECT

  CLOSE( PRTFile )

END SUBROUTINE BellhopCore