Revision dd8daa98413988b11c594e5a3bff8f5659d7ecf7 authored by Florent Renaud on 26 June 2014, 09:41:19 UTC, committed by Florent Renaud on 26 June 2014, 09:41:19 UTC
Originally released on 18 March 2013
Based on Nbody6 downloaded on 29 January 2013
1 parent edab1b7
Raw File
chmod.f
      SUBROUTINE CHMOD(ISUB,KCASE)
*
*
*       Modification of chain member(s).
*       --------------------------------
*
      INCLUDE 'common6.h'
        REAL*8  M,MASS,MC
        PARAMETER (NMX=10,NMX3=3*NMX,NMX4=4*NMX,NMXm=NMX*(NMX-1)/2)
         COMMON/ARCHAIN/XCH(NMX3),VCH(NMX3),WTTL,M(NMX),
     &   XCDUM(NMX3),WCDUM(NMX3),MC(NMX),
     &   XI(NMX3),VI(NMX3),MASS,RINV(NMXm),RSUM,INAME(NMX),NN
      COMMON/CHAINC/  XC(3,NCMAX),UC(3,NCMAX),BODYC(NCMAX),ICH,
     &                LISTC(LMAX)
      COMMON/CPERT/  RGRAV,GPERT,IPERT,NPERT
      COMMON/CHREG/  TIMEC,TMAX,RMAXC,CM(10),NAMEC(NMX),NSTEP1,KZ27,KZ30
      COMMON/CLUMP/   BODYS(NCMAX,5),T0S(5),TS(5),STEPS(5),RMAXS(5),
     &                NAMES(NCMAX,5),ISYS(5)
      COMMON/CCOLL2/  QK(NMX4),PK(NMX4),RIK(NMX,NMX),SIZE(NMX),VSTAR1,
     &                ECOLL1,RCOLL,QPERI,ISTAR(NMX),ICOLL,ISYNC,NDISS1
      COMMON/INCOND/  X4(3,NMX),XDOT4(3,NMX)
      INTEGER  ISORT(NMX)
      REAL*8  XCM(3),VCM(3),XJ(3),VJ(3)
      SAVE IT,IWARN
      DATA IT,IWARN /0,0/
*
*
*       Copy chain variables to standard form.
      LK = 0
      DO 3 L = 1,NCH
          DO 2 K = 1,3
              LK = LK + 1
              X4(K,L) = XCH(LK)
              XDOT4(K,L) = VCH(LK)
    2     CONTINUE
    3 CONTINUE
*
*       Identify the dominant perturber (skip if none, check on NN >= 7).
      ITRY = 0
      JCLOSE = 0
      NNB = LISTC(1)
      IF (NNB.EQ.0) GO TO 10
      PMAX = 0.0
      DO 5 L = 2,NNB+1
          J = LISTC(L)
          RIJ2 = (X(1,J) - X(1,ICH))**2 + (X(2,J) - X(2,ICH))**2 +
     &                                    (X(3,J) - X(3,ICH))**2
          PIJ = BODY(J)/(RIJ2*SQRT(RIJ2))
          IF (PIJ.GT.PMAX) THEN
              PMAX = PIJ
              RJMIN2 = RIJ2
              JCLOSE = J
          END IF
    5 CONTINUE
      RIJ = SQRT(RJMIN2)
*
*       Restrict membership increase above 6 for distant perturber.
      IF (NCH.GE.6.AND.RIJ.GT.30.0*RMIN) THEN
          GO TO 10
      END IF
*
*       Check enforced escape removal to allow a closer perturber.
      IF ((GPERT.GT.0.001.AND.NN.GE.6).OR.
     &    (GPERT.GT.0.01.AND.NN.GE.5)) THEN
          RX2 = 0.0
          IT = 0
*       Determine most distant outgoing member (if any).
          DO 105 I = 1,NN
              RIJ2 = 0.0
              RD = 0.0
              DO 102 K = 1,3
                  RIJ2 = RIJ2 + X4(K,I)**2
                  RD = RD + X4(K,I)*XDOT4(K,I)
  102         CONTINUE
              IF (RIJ2.GT.RX2.AND.RD.GT.0.0) THEN
                  IT = I
                  RX2 = RIJ2
                  RDOT = RD
              END IF
  105     CONTINUE
*
*       Include safety skip on no identification.
          IF (IT.EQ.0) THEN
              GO TO 10
          END IF
*
*       Find distance to nearest member for safety check (> 2*RMIN).
          RP2 = 1.0
          DO 110 I = 1,NN
              IF (I.EQ.IT) GO TO 110
              RIJ2 = 0.0
              DO 108 K = 1,3
                  RIJ2 = RIJ2 + (X4(K,I) - X4(K,IT))**2
  108         CONTINUE
              IF (RIJ2.LT.RP2) THEN
                  RP2 = RIJ2
              END IF
  110     CONTINUE
*
*       Check central distance and closest separation.
          IF (RX2.GT.RJMIN2.AND.RP2.GT.4.0*RMIN**2) THEN
              RI = SQRT(RX2)
*       Skip if escaper would increase the perturbation.
*             GX = 2.0*BODYC(IT)/(MASS - BODYC(IT))*((RSUM-RI)/RI)**3
              CALL CPERTJ(IT,GX)
              IF (GX.GT.MAX(GPERT,1.0D-05).AND.RI.LT.30.0*RMIN.AND.
     &            RSUM.LT.50.0*RMIN) THEN
                  KCASE = 0
                  GO TO 60
              END IF
              RDOT = RDOT/RI
              HI = 0.5*RDOT**2 - BODY(ICH)/RI
*             WRITE (6,112)  NAMEC(IT), NAME(JCLOSE), GPERT, RI,
*    &                       RDOT, RIJ, SQRT(RP2)
* 112         FORMAT (' ENFORCED ESCAPE    NAMC NAMJ GP RI RD RJ RP ',
*    &                                     2I7,1P,5E10.2)
              IESC = IT
              JESC = 0
              KCASE = 1
              GO TO 40
          END IF
      END IF
      IF (NN.GE.9) GO TO 10
*
*       Form the scalar product R*V for sign of radial velocity.
      RDOT = (X(1,JCLOSE) - X(1,ICH))*(XDOT(1,JCLOSE) - XDOT(1,ICH)) +
     &       (X(2,JCLOSE) - X(2,ICH))*(XDOT(2,JCLOSE) - XDOT(2,ICH)) +
     &       (X(3,JCLOSE) - X(3,ICH))*(XDOT(3,JCLOSE) - XDOT(3,ICH))
*
      IF (GPERT.GT.1.0.AND.IWARN.LT.10) THEN
          IWARN = IWARN + 1
          WRITE (6,115)  NN, NAME(JCLOSE), NPERT, GPERT, RGRAV, RIJ,
     &                   RDOT/RIJ
  115     FORMAT (' WARNING!   N NM NP G RG RIJ RD ',
     &                         I4,I6,I4,F7.2,1P,4E9.1)
      END IF
      IF (NN.GT.3.AND.GPERT.GT.1.0) IWARN = 0
*
*       Skip outgoing orbit with GPERT < 0.2 or large membership.
      IF (RDOT.GT.0.0.AND.(NCH.GE.5.OR.GPERT.LT.0.2)) GO TO 10
      IF (RDOT.GT.0.0.AND.GPERT.LT.1.0D-04) GO TO 10
      IF (RDOT.GT.0.0) THEN
          HI = 0.5*(RDOT/RIJ)**2 - BODY(ICH)/RIJ
          RX = -BODY(ICH)/HI
          IF (RX.GT.10.0*RMIN.OR.HI.GT.0.0) GO TO 10
          IF (GPERT.LT.0.1) GO TO 10
      END IF
*       Quit on RIJ > 5*RMIN to prevent repeated switching.
      IF (NCH.EQ.2.AND.(RIJ.GT.5.0*RMIN.OR.GPERT.LT.1.0D-04)) GO TO 10
      IF (NN.GE.7.AND.JCLOSE.GT.N) GO TO 10
*
*       Note looping for NCH = 2 which gives GAMX = 0.
      IF (NCH.LE.5.AND.GPERT.LT.0.2.AND.NNB.GT.1.AND.
     &    RIJ.GT.RSUM) THEN
          CALL CPERTX(JCLOSE,3,GAMX,GAMY)
          IF (NCH.GT.2.AND.GAMY.LT.0.1.AND.GAMX.LT.GAMY) GO TO 10
      END IF
*
*       Include extra procedure for closest perturber.
      DO 120 K = 1,3
          XJ(K) = X(K,JCLOSE) - X(K,ICH)
  120 CONTINUE
      RX2 = 1.0
      DO 130 L = 1,NCH
          RIJ2 = 0.0
          DO 125 K = 1,3
              RIJ2 = RIJ2 + (X4(K,L) - XJ(K))**2
  125     CONTINUE
          IF (RIJ2.LT.RX2) THEN
              RX2 = RIJ2
          END IF
  130 CONTINUE
*
*       Check pericentre for three-body case with massive intruder.
      IF (NCH.EQ.2.AND.KSTAR(JCLOSE).EQ.14) THEN
          RD = 0.0
          RIJ2 = 0.0
          VI2 = 0.0
          DO 135 K = 1,3
              RIJ2 = RIJ2 + XJ(K)**2
              VJ(K) =  XDOT(K,JCLOSE) - XDOT(K,ICH)
              VI2 = VI2 + VJ(K)**2
              RD = RD + XJ(K)*VJ(K)
  135     CONTINUE
          RJ = SQRT(RIJ2)
          SEMI = 2.0/RJ - VI2/(BODY(ICH) + BODY(JCLOSE))
          SEMI = 1.0/SEMI
          ECC2 = (1.0 - RJ/SEMI)**2 +
     &                  RD**2/(SEMI*(BODY(ICH) + BODY(JCLOSE)))
          ECC = SQRT(ECC2)
          PMIN = SEMI*(1.0 - ECC)
          IF (PMIN.GT.5.0*RGRAV.AND.GPERT.LT.0.001.AND.NPERT.GT.4) THEN
              IF (MOD(NSTEP1,1000).EQ.0) THEN
              WRITE (3,140)  NSTEP1, NAME(JCLOSE), ECC, SEMI,
     &                       SEMI*(1.0-ECC), 5.0*RGRAV, GPERT
  140         FORMAT (' SKIP HEAVY   # NM E A PM 5*RG GP ',
     &                               I8,I4,F8.4,1P,4E10.2)
              CALL FLUSH(3)
              END IF
              GO TO 10
          END IF
      END IF
*
*       Delay acceptance of approaching third light body.
      IF (NCH.EQ.2.AND.KSTAR(JCLOSE).LT.14.AND.RDOT.LT.0.0) THEN
          IF (RIJ.GT.5.0*RGRAV.AND.GPERT.LT.0.0001) GO TO 10
      END IF
*
*       Evaluate relative perturbation on #LL due to #JCLOSE.
*     RI2 = X4(1,LL)**2 + X4(2,LL)**2 + X4(3,LL)**2
*     FF = BODY(ICH)/RI2
*     GP = BODY(JCLOSE)/(RX2*FF)
*
*       Adopt 4*RMIN criterion or combined larger distance & perturbation.
      RX2 = MIN(RX2,RJMIN2)
*       Exclude large contrast to prevent repeated absorb/escape.
      IF (RIJ.GT.10.0*RSUM) GO TO 10
      RABS = 2.0*RMIN
      GXX = 0.1
      IF (JCLOSE.GT.N) GXX = 0.03
      GSTAR = 0.001*BODY(JCLOSE)/BODY(ICH)
      IF ((RX2.LT.RABS**2.AND.NCH.LE.6).OR.
     &   (GPERT.GT.GSTAR.AND.RX2.LT.RABS**2.AND.NCH.LE.5).OR.
     &   (GPERT.GT.GXX.AND.NCH.LE.7).OR.(KSTAR(JCLOSE).EQ.14)) THEN
*
*       Include radial velocity condition for allowing membership increase.
          RD = RDOT/RIJ
          IF (N.GE.5.AND.RD**2.LT.0.25.AND.GPERT.LT.0.001) THEN
              GO TO 10
          END IF
*
*       Perform safety check.
          DO 145 L = 1,NCH
              IF (NAMEC(L).EQ.NAME(JCLOSE)) THEN
              WRITE (6,144)  NAME(JCLOSE)
  144         FORMAT (' DANGER!   DUPLICATED   NMJ  ',I6)
              GO TO 10
              END IF
  145     CONTINUE
*
*       Treat extreme mixed or classical binary as inert (but not BH-BH).
          IF (JCLOSE.GT.N) THEN
              KX = MIN(KSTAR(2*(JCLOSE-N)-1),KSTAR(2*(JCLOSE-N)))
              SEMI = -0.5*BODY(JCLOSE)/H(JCLOSE-N)
              RM = 1.0
              DO 150 K = 1,NCH-1
                  RM = MIN(1.0/RINV(K),RM)
  150         CONTINUE
              SMALL = 0.01*(RSUM - RIJ)
              IF (RM.LT.SMALL.AND.SEMI.LT.SMALL.AND.KX.LT.14) THEN
                  WRITE (6,155)  NAME(JCLOSE), GPERT, SEMI, RIJ,
     &                                         (1.0/RINV(K),K=1,NCH-1)
  155             FORMAT (' ABSORB INERT    NM G A RIJ R ',
     &                                      I6,F6.2,1P,6E10.2)
*       Reduce option #26 and set #27 = 1 temporarily for routine SETSYS.
                  KZ26 = KZ(26)
                  KZ(26) = 1
                  KZ(27) = 1
                  CALL ABSORB(ISUB)
                  KZ(26) = KZ26
                  KZ(27) = KZ27
                  KCASE = 1
                  GO TO 50
              END IF
          END IF
*
          IF (JCLOSE.GT.N) THEN
              WRITE (3,160)  NAME(JCLOSE), R(JCLOSE-N), GAMMA(JCLOSE-N)
  160         FORMAT (' ABSORB BINARY    NM R G ',I6,1P,2E10.2)
          END IF
          IF (KSTAR(JCLOSE).EQ.14.AND.NCH.EQ.2) THEN
              WRITE (3,165)  NSTEP1, ECC, SEMI, SEMI*(1-ECC), GPERT, RIJ
  165         FORMAT (' ABSORB!    # E A PM GP RIJ ',I8,F8.4,1P,4E10.2)
          END IF
*
          IF (KZ(30).GT.1) THEN
              HI = 0.5*RD**2 - BODY(ICH)/RIJ
              WRITE (6,170) TIME+TOFF, NCH, NAME(JCLOSE), GPERT, RIJ,
     &                      RD, HI
  170         FORMAT (' ABSORB    T NCH NM GP RIJ RD HI ',
     &                            F9.3,I4,I7,1P,4E9.1)
          END IF
*
*       Absorb the perturber (single particle or binary).
          CALL ABSORB(ISUB)
*
*       Reduce block-time since new c.m. step may be very small.
          TBLOCK = MIN(TIME,TBLOCK)
*
*       Activate indicator for new chain treatment.
          KCASE = 1
          ITRY = ITRY + 1
          GO TO 10
      END IF
*
*       Check for rejection (RIJ > 2*MIN(RSUM,RMIN); RDOT > 0 & G < 0.05).
      IF (GPERT.LT.0.02*(BODY(JCLOSE)/BODY(ICH)).OR.
     &    NAME(JCLOSE).LT.0) GO TO 10
      IF (RDOT.GT.0.0.AND.GPERT.LT.0.05*(BODY(JCLOSE)/BODY(ICH))) THEN
          GO TO 10
      END IF
      IF (RSUM.GT.10.0*RMIN.AND.
     &    GPERT.LT.0.01*(BODY(JCLOSE)/BODY(ICH))) GO TO 10
      IF (RIJ.GT.2.0*RSUM.OR.RSUM.GT.10.0*RMIN) GO TO 10
*
*       Perform impact parameter test (abandoned 19/7/07).
      VR2 = (XDOT(1,ICH) - XDOT(1,JCLOSE))**2 +
     &      (XDOT(2,ICH) - XDOT(2,JCLOSE))**2 +
     &      (XDOT(3,ICH) - XDOT(3,JCLOSE))**2
      AINV = 2.0/RIJ - VR2/(MASS + BODY(JCLOSE))
      ECC2 = (1.0 - RIJ*AINV)**2 + RDOT**2*AINV/(MASS + BODY(JCLOSE))
      ECC = SQRT(ECC2)
      IF (NN.EQ.2.AND.GPERT.LT.0.02*(BODY(JCLOSE)/BODY(ICH))) THEN
          GO TO 10
      END IF
*
*       Include additional criteria (V^2 > VC^2/2; JCL > N & RIJ < RSUM).
      RDOT = RDOT/RIJ
      VC2 = (MASS + BODY(JCLOSE))/RIJ
      IF ((RSUM + RIJ.LT.RMIN).OR.(NN.EQ.2.AND.GPERT.GT.0.005).OR.
     &    (RIJ.LT.RSUM.AND.RDOT**2.GT.0.5*VC2).OR.
     &    (JCLOSE.GT.N.AND.RIJ.LT.RSUM).OR.RDOT.LT.0.0) THEN
*
*       Do not allow multiple absorptions (NAMES(NMX,5) = 0 each new chain).
          IF (NAME(JCLOSE).NE.NAMES(NMX,5).AND.NAMES(NMX,5).EQ.0) THEN
              NAMES(NMX,5) = NAME(JCLOSE)
*       Include possible return after ejection in bound orbit.
          ELSE IF (RDOT.GT.0.0) THEN
              GO TO 10
          END IF
*
          RSUM = RSUM + RIJ
          IF (KZ(30).GT.1) THEN
              SEMI1 = 1.0/AINV
              PMIN = SEMI1*(1.0 - ECC)
              WRITE (6,6)  NSTEPI, NAME(JCLOSE), GPERT, ECC, SEMI1,
     &                     RIJ, RSUM, PMIN
    6         FORMAT (' ABSORB:    # NMJ GPERT E A RIJ RSUM PMIN ',
     &                             I11,I7,F8.4,F9.5,1P,5E9.1)
              CALL FLUSH(6)
          END IF
*
          IF (JCLOSE.GT.N) THEN
              WRITE (3,155)  NAME(JCLOSE), R(JCLOSE-N), GAMMA(JCLOSE-N)
          END IF
*
*       Absorb the perturber (single particle or binary).
          CALL ABSORB(ISUB)
*
*       Reduce block-time since new c.m. step may be very small.
          TBLOCK = MIN(TIME,TBLOCK)
*
*       Activate indicator for new chain treatment and try a second search.
          KCASE = 1
          ITRY = ITRY + 1
*         IF (ITRY.EQ.1) GO TO 1
      END IF
*
*       Exit if any particles have been absorbed.
   10 IF (ITRY.GT.0) GO TO 50
*
      KCASE = 0
      JESC = 0
      IF (NN.EQ.2) GO TO 60
*     IF (NN.EQ.2) THEN
*         R1 = 1.0/RINV(1)
*         IF (R1.GT.100.0*RMIN) THEN
*             KCASE = -1
*             GO TO 60
*         END IF
*     END IF
*
*       Place index of the smallest INVERSE distance in ISORT(1).
      CALL HPSORT(NN-1,RINV,ISORT)
*
*       Determine index of escaper candidate (single star or binary).
*       Distinguish two cases of each type (beginning & end of chain).
      IF (ISORT(1).EQ.1) THEN
          IESC = INAME(1)
          KCASE = 1
      ELSE IF (ISORT(1).EQ.NN-1) THEN
          IESC = INAME(NN)
          KCASE = 1
*       Check for possible binary escaper (NN = 3 implies single escaper).
      ELSE IF (ISORT(1).EQ.2) THEN
          IESC = INAME(1)
          JESC = INAME(2)
          IBIN = 1
*       Switch binary index in case last separation is smallest (NN >= 4).
*         IF (RINV(1).LT.RINV(NN-1)) IBIN = NN - 1
          IF (RINV(1).LT.RINV(NN-1)) THEN
              IF (BODYC(IESC) + BODYC(JESC).GT.0.5*MASS) THEN
                  IBIN = NN - 1
              END IF
          END IF
          KCASE = 2
      ELSE IF (ISORT(1).EQ.NN-2) THEN
          IESC = INAME(NN-1)
          JESC = INAME(NN)
          IBIN = NN - 1
          KCASE = 2
      END IF
*
*       Ensure massive binary is not removed (big single should be OK).
      IF (KCASE.EQ.2) THEN
          IF (IESC.EQ.INAME(1)) THEN
              J1 = INAME(NN-1)
              J2 = INAME(NN)
          ELSE
              J1 = INAME(1)
              J2 = INAME(2)
          END IF
          ZMB = BODYC(IESC) + BODYC(JESC)
          ZMB2 = BODYC(J1) + BODYC(J2)
*         IF (ZMB.GT.10.0*MIN(BODYC(J1),BODYC(J2))) THEN
*             IESC = J1
*             JESC = 0
*             KCASE = 1
*         END IF
*       Retain the most massive binary for AR_Chain case.
          IF (ZMB.GT.ZMB2) THEN
              IESC = J1
              JESC = J2
              IBIN = NN - IBIN
          END IF
      END IF
*
*       Include escape check if middle distance is largest.
      IF (KCASE.EQ.0.AND.NN.GE.7.AND.
     &    1.0/RINV(ISORT(1)).GT.2.0*RMIN) THEN
          R1 = 1.0/RINV(1)
          RN = 1.0/RINV(NN-1)
*       Set relevant indices for beginning or end of chain.
          IF (R1.GT.RN) THEN
              IESC = INAME(1)
              JX = INAME(2)
              IB = 1
              ISORT(1) = 1
              R2 = 1.0/RINV(2)
          ELSE
              IESC = INAME(NN)
              JX = INAME(NN-1)
              IB = NN - 1
              ISORT(1) = NN - 1
              R2 = 1.0/RINV(NN-2)
          END IF
*       Define binary indices for large second separation.
          IF (R2.GT.MAX(R1,RN)) THEN
              JESC = JX
              IBIN = IB
              KCASE = 2
          ELSE
              KCASE = 1
          END IF
      END IF
*
*       Skip on JESC > 0 not at beginning/end but check large chain.
      IF (JESC.GT.0.AND.(JESC.NE.1.AND.JESC.NE.NCH)) KCASE = 0
      IF (JESC.GT.0.AND.RSUM.GT.25.0*RMIN) KCASE = 2
*
*       Skip if no identified case (should be rare).
      IF (KCASE.EQ.0) GO TO 60
*
*       Ensure enforced escape of binary in wide four-body system.
      IF (KCASE.EQ.2.AND.NCH.EQ.4.AND.1.0/RINV(2).GT.20.0*RMIN) THEN
          WRITE (6,11)  IESC, JESC, NPERT, 1.0/RINV(IBIN), 1.0/RINV(2)
   11     FORMAT (' ENFORCED ESCAPE    IESC JESC NP RB R2 ',
     &                                 3I4,1P,2E10.2)
          KCASE = 1
          RI = 1.0/RINV(2)
          GO TO 40
      END IF
*
*       Enforce escape for distant member with positive radial velocity.
      RD = X4(1,IPHASE)*XDOT4(1,IPHASE) + X4(2,IPHASE)*XDOT4(2,IPHASE)
     &                                  + x4(3,IPHASE)*XDOT4(3,IPHASE)
      IF (NCH.EQ.4.AND.RSUM.GT.40.0*RMIN.AND.RD.GT.0.0D0) THEN
          KCASE = 1
          RI = 25.0*RMIN
      WRITE (6,41)  NSTEP1, IESC, JESC, GPERT, (1.0/RINV(K),K=1,NCH-1)
   41 FORMAT (' WIDE ESCAPE    # IESC JESC G R  ',I8,2I4,F8.4,1P,4E10.2)
          GO TO 40
      END IF
*
      IF (KZ(30).GT.2) THEN
          WRITE (3,12)  IESC, JESC, NSTEP1, ISORT(1),
     &                  (1.0/RINV(K),K=1,NN-1)
   12     FORMAT (' CHMOD:    IESC JESC # ISORT1 R ',2I3,I5,I3,1P,5E9.1)
          CALL FLUSH(3)
      END IF
*
*       Distinguish between binary and single particle.
      RB = 0.0
      IF (JESC.EQ.0) GO TO 20
*
*       Switch to possible non-dominant mass binary.
      ZMB = BODYC(IESC) + BODYC(JESC)
      IF (ZMB.GT.0.5*MASS) THEN
          IF (IESC.EQ.INAME(1)) THEN
              IESC = INAME(NN-1)
              JESC = INAME(NN)
              IBIN = NN - 1
          ELSE
              IESC = INAME(1)
              JESC = INAME(2)
              IBIN = 1
          END IF
      END IF
*
*       First check case of escaping binary (JESC > 0 & RB < RJB/4).
      IF (JESC.GT.0) THEN
          RB = 1.0/RINV(IBIN)
          JBIN = IBIN + 1
          IF (IBIN.EQ.NN - 1) JBIN = IBIN - 1
          RJB = 1.0/RINV(JBIN)
*       Ensure removal of widest binary (maybe not as KS) at RSUM > 30*RMIN.
          IF (RSUM.GT.30.0*RMIN.AND.RB.GT.0.25*RJB) THEN
              JBIN = NN - 1
              IF (JBIN.EQ.IBIN) IBIN = 1
              RB = 1.0/RINV(IBIN)
              RJB = 4.01*RB
              WRITE (6,13) IESC, JESC, IBIN, RB, RJB, ZMB*SMU
   13         FORMAT (' IMPOSED ESCAPE    IESC JESC IB RB RJB MB ',
     &                                    3I4,1P,3E10.2)
          END IF
*       Consider removal of outermost particle instead if binary is wide.
          IF (RB.GT.0.25*RJB) THEN
*       Change pointer to end of chain and redefine IESC.
              IF (ISORT(1).EQ.2) THEN
                  ISORT(1) = 1
              ELSE
                  ISORT(1) = NN - 1
              END IF
              IESC = JESC
              GO TO 20
          END IF
      ELSE
          GO TO 20
      END IF
*
*       Form coordinates & velocities of distant binary (local c.m. frame).
      RB = 1.0/RINV(IBIN)
      BCM = BODYC(IESC) + BODYC(JESC)
      RI2 = 0.0
      RDOT = 0.0
      VREL2 = 0.0
      DO 15 K = 1,3
          XCM(K) = (BODYC(IESC)*X4(K,IESC) + BODYC(JESC)*X4(K,JESC))/BCM
          VCM(K) = (BODYC(IESC)*XDOT4(K,IESC) +
     &              BODYC(JESC)*XDOT4(K,JESC))/BCM
          RI2 = RI2 + XCM(K)**2
          RDOT = RDOT + XCM(K)*VCM(K)
          VREL2 = VREL2 + (XDOT4(K,IESC) - XDOT4(K,JESC))**2
   15 CONTINUE
*
*       Convert to relative distance & radial velocity w.r.t. inner part.
      FAC = BODY(ICH)/(BODY(ICH) - BCM)
      RI = SQRT(RI2)
      RDOT = FAC*RDOT/RI
      RI = FAC*RI
      RJB = 0.0
*       Adopt harmonic mean of RSUM and RMAXS for delaying escape.
*     DESC = 0.5*SQRT(RSUM*RMAXS(ISUB))
      DESC = SQRT(RMIN*RMAXS(ISUB))
*       Reduce delay test for large length contrasts.
      IM = ISORT(1)
      RM = 1.0/RINV(IM)
      CX = RSUM/(RSUM - RM)
      IF (CX.GT.25.0) DESC = 25.0*RGRAV
      RESC = MAX(3.0*RGRAV,DESC)
      AINV = 2.0/RB - VREL2/BCM
      EB = -0.5*BODYC(IESC)*BODYC(JESC)*AINV
      HI = 0.5*RDOT**2 - BODY(ICH)/RI
      IF (HI.GT.0.0) THEN
          VINF = SQRT(2.0*HI)*VSTAR
      ELSE
          VINF = 0.0
      END IF
*
*       Employ parabolic escape criterion (terminate if RI > RMIN & NCH < 5).
      IF ((RI.GT.RESC.AND.RDOT.GT.0.0.AND.RB*AINV.GT.0.99).OR.
     &    (HI.GT.0.0.AND.RI.GT.3.0*RMIN)) THEN
          IF (RDOT**2.LT.2.0*BODY(ICH)/RI) THEN
*       Define effective perturbation using remaining size.
              GB = 2.0*BCM/(BODY(ICH) - BCM)*((RSUM - RJB - RB)/RI)**3
*       Split into two KS solutions if binaries are well separated.
              IF (NCH.EQ.4.AND.GB.LT.0.001) THEN
*                 KCASE = -1
                  KCASE = 1
                  GO TO 40
              END IF
*       Enforce termination if RI > MAX(RMAXS/2,RMIN) and NCH <= 4.
              IF (RI.GT.MAX(0.5*RMAXS(ISUB),RMIN).AND.NCH.LE.4) THEN
*                 KCASE = -1
                  KCASE = 1
                  GO TO 40
*       Accept binary escape for small perturbation & V**2 > M/R (NCH > 4).
              ELSE IF (GB.LT.0.01.AND.NCH.GT.4.AND.
     &                 (RDOT**2.GT.BODY(ICH)/RI.OR.RI.GT.RMIN)) THEN
                  WRITE (3,18)  IESC, JESC, NAMEC(IESC), NAMEC(JESC),
     &                          RI, RDOT**2, 2.0*BODY(ICH)/RI, RB
                  CM(9) = CM(9) - EB
                  GO TO 40
              ELSE
*       Check splitting into two KS solutions (R1 + R3 < R2/5 & RDOT > VC).
                  IF (NCH.EQ.4) THEN
                      R13 = 1.0/RINV(1) + 1.0/RINV(3)
                      VC2 = RDOT**2*RI/BODY(ICH)
*       Ensure RSUM > 0.1*RMIN for reducing differential force corrections.
                      IF (R13.LT.0.2/RINV(2).AND.VC2.GT.1.0.AND.
     &                    RSUM.GT.0.1*RMIN) THEN
*                         KCASE = -1
                          KCASE = 1
                          GO TO 40
                      END IF
                  END IF
                  KCASE = 0
*       Try single escape for wide binary.
                  IF (1.0/RINV(IBIN).GT.4.0*RMIN) THEN
                      JESC = 0
                      GO TO 20
                  END IF
                  GO TO 60
              END IF
          ELSE
              IF (HI.GT.0.0) THEN
                  VINF = SQRT(2.0*HI)*VSTAR
              ELSE
                  VINF = 0.0
              END IF
              IF (KZ(30).GT.1.OR.VINF.GT.1.0) THEN
                  WRITE (3,18)  IESC, JESC, NAMEC(IESC), NAMEC(JESC),
     &                          RI, RDOT**2, 2.0*BODY(ICH)/RI, RB, VINF
   18             FORMAT (' CHAIN ESCAPE:    IESC JESC NM RI RDOT2 ',
     &                                      '2*M/R RB VINF ',
     &                                       2I3,2I6,1P,4E9.1,0P,F6.1)
              END IF
*       Enforce termination (KCASE < 0) if NCH <= 4 (final membership <= 2).
              IF (NCH.LE.4) THEN
*                 KCASE = -1
                  KCASE = 1
                  GO TO 40
              END IF
              CM(9) = CM(9) - EB
              GO TO 40
          END IF
      ELSE
          KCASE = 0
          IF (1.0/RINV(IBIN).GT.4.0*RMIN) THEN
              JESC = 0
              GO TO 20
          END IF
          GO TO 60
      END IF
*
*       Include a basic escape criterion for distant single members.
   20 RX = 0.0
      DO 25 I = 1,NN
          RIJ2 = 0.0
          DO 22 K = 1,3
              RIJ2 = RIJ2 + X4(K,I)**2
   22     CONTINUE
          IF (RIJ2.GT.RX) THEN
              IT = I
              RX = RIJ2
          END IF
   25 CONTINUE
*
*       Employ safety check for heavy single closer to c.m. (NCH = 3).
      IF (NN.EQ.3) THEN
          IF (ISORT(1).EQ.1) THEN
              IT = INAME(1)
          ELSE IF (ISORT(1).EQ.NN-1) THEN
              IT = INAME(NN)
          END IF
      END IF
*
*       Bypass complications for distant member at end of chain.
      IF ((IESC.EQ.1.OR.IESC.EQ.NN).AND.
     &               1.0/RINV(IESC).GT.50.0*RMIN) GO TO 210
      RI = SQRT(RX)
      RDOT = X4(1,IT)*XDOT4(1,IT) + X4(2,IT)*XDOT4(2,IT) +
     &                              X4(3,IT)*XDOT4(3,IT)
      IF (RI.GT.20.0*RMIN.AND.RDOT.GT.0.0) THEN
*       Delay for BH and small perturbation (orbit may turn around).
          IF (ISTAR(IT).EQ.14.AND.GPERT.LT.1.0D-04.AND.
     &        RI.LT.50.0*RMIN) THEN
              KCASE = 0
              GO TO 60
          ELSE IF (IT.EQ.1.OR.IT.EQ.NN) THEN
              RDOT = RDOT/RI
              HI = 0.5*RDOT**2 - BODY(ICH)/RI
              RX = 1.0
              IF (HI.LT.0.0) RX = -BODY(ICH)/HI
              RY = MAX(RI,RX)
              DR = ABS(RI - RX)/RX
              IF ((RY.LT.20.0*RMIN.AND.GPERT.LT.1.0D-03).OR.
     &            (RY.LT.30.0*RMIN.AND.GPERT.LT.1.0D-04).OR.
     &            (DR.LT.0.2.AND.GPERT.LT.1.0D-04)) THEN
                  KCASE = 0
                  GO TO 60
              END IF
              CALL CPERTJ(IT,GX)
              IF (GX.GT.2.0*MAX(GPERT,1.D-05).AND.RI.LT.30.0*RMIN) THEN
                  KCASE = 0
                  GO TO 60
              END IF
*             WRITE (3,27)  IT, NAMEC(IT), GPERT, RI, RDOT, RX
*  27         FORMAT (' BASIC ESCAPE:    IESC NM GP RI RDOT RX ',
*    &                                   I3,I7,1P,4E10.2)
              IESC = IT
              JESC = 0
              KCASE = 1
              GO TO 40
          END IF
      END IF
*
          RP2 = 1.0
          DO 200 L = 2,NNB+1
              J = LISTC(L)
              RIJ2 = 0.0
              DO 195 K = 1,3
*       Include extra procedure for closest perturber.
                  XJ(K) = X4(K,IESC) + X(K,ICH)
                  RIJ2 = RIJ2 + (XJ(K) - X(K,J))**2
  195         CONTINUE
              IF (RIJ2.LT.RP2) RP2 = RIJ2
  200     CONTINUE
          IF (RP2.LT.4.0*RMIN**2) THEN
              KCASE = 0
              GO TO 60
          END IF
*
  210 CONTINUE
      RI = SQRT(X4(1,IESC)**2 + X4(2,IESC)**2 + X4(3,IESC)**2)
      IF (ISTAR(IESC).EQ.14.AND.NCH.LE.6) THEN
*         GX = 2.0*BODYC(IESC)/(MASS - BODYC(IESC))*((RSUM-RI)/RI)**3
          CALL CPERTJ(IESC,GX)
          IF (GX.GT.2.0*MAX(GPERT,1.D-05).AND.RI.LT.30.0*RMIN) THEN
              KCASE = 0
              GO TO 60
          END IF
      END IF
*
*       Form relative distance and radial velocity for single particle.
*       Skip massive body test because of large factor FAC.
      IF (RI.LT.RGRAV) THEN
          KCASE = 0
          GO TO 60
      END IF
      RDOT = X4(1,IESC)*XDOT4(1,IESC) + X4(2,IESC)*XDOT4(2,IESC) +
     &                                  X4(3,IESC)*XDOT4(3,IESC)
      FAC = BODY(ICH)/(BODY(ICH) - BODYC(IESC))
      RDOT = FAC*RDOT/RI
      RI = FAC*RI
      IM = ISORT(1)
*       Ensure that escaper is not close to another body.
      RM = MIN(1.0/RINV(IM),RI)
*
*       Check distance to closest chain member.
      RX2 = 1.0
      DO 30 I = 1,NN
          IF (I.EQ.IESC) GO TO 30
          RIJ2 = 0.0
          DO 28 K = 1,3
              RIJ2 = RIJ2 + (X4(K,I) - X4(K,IESC))**2
   28     CONTINUE
          IF (RIJ2.LT.RX2) THEN
              RX2 = RIJ2
          END IF
   30 CONTINUE
      RABS = MIN(RGRAV,2.0*RMIN)
      IF (RX2.LT.RABS**2.AND.RI.LT.10.0*RMIN) THEN
          KCASE = 0
          GO TO 60
      END IF
*
*       Impose termination of wide BH binary after collision (not ARchain).
*     IF (NN.EQ.2.AND.RI.GT.50.0*RMIN) THEN
*         KCASE = -1
*         GO TO 60
*     END IF
*
*       Skip escape removal if closest body is near pericentre.
*     IX = ISORT(NN-1)
*     IF (1.0/RINV(IX).LT.0.05*RGRAV) THEN
*         KCASE = 0
*         GO TO 60
*     END IF
*
*       Include additional tests for removal (RDOT > 0).
      HI = 0.5*RDOT**2 - BODY(ICH)/RI
      RX = 10.0
      IF (HI.LT.0.0) RX = -BODY(ICH)/HI
      DR = ABS(RI - RX)/RX
      IF ((HI.GT.0.0.AND.RI.GT.10.0*RGRAV.AND.RDOT.GT.0.0).OR.
     &    (RI.GT.20.0*RMIN.AND.RDOT.GT.0.0).OR.
     &    (DR.LT.0.2.AND.GPERT.LT.5.0D-03)) THEN
          IF (ISTAR(IESC).EQ.14.AND.GPERT.GT.0.001) THEN
              VINF = 0.0
              IF (HI.GT.0.0) VINF = SQRT(2.0*HI)*VSTAR
*             WRITE (3,32)  NAMEC(IESC), VINF, GPERT, RI, RX
*  32         FORMAT (' HEAVY ESCAPER   NAM VINF G R RX ',
*    &                                  I4,F6.1,1P,3E10.2)
              KCASE = 1
              GO TO 40
          ELSE
              RX = 10.0
              IF (HI.LT.0.0) RX = -BODY(ICH)/RI
              RY = MAX(RI,RX)
              IF (RY.LT.30.0*RMIN.AND.GPERT.LT.1.0D-04) THEN
                  KCASE = 0
                  GO TO 60
              ELSE
                  KCASE = 1
                  GO TO 40
              END IF
          END IF
      END IF
*
*       Check approximate escape criterion outside 3*RGRAV and DESC.
      DESC = 0.5*SQRT(RSUM*RMAXS(ISUB))
*       Note that harmonic mean tends to delay escape.
      RESC = MAX(5.0*RGRAV,DESC)
      RESC = MIN(RESC,3.0*RMIN)
      IF (NN.EQ.3.AND.RESC.LT.0.001*RMIN) RESC = 5.0*RESC
      IF (RM.GT.RESC.AND.RDOT.GT.0.0) THEN
          IF (RDOT**2.LT.2.0*BODY(ICH)/RI) THEN
              FAC2 = 2.0*BODYC(IESC)/(BODY(ICH) - BODYC(IESC))
              GI = FAC2*((RSUM - 1.0/RINV(IM))/RI)**3
*       Do not permit large length contrast even for bound orbit.
              IF (NN.GE.4.AND.RI.GT.5.0*RMIN.AND.GPERT.GT.0.001) THEN
                  KCASE = 1
                  GO TO 35
              END IF
              ER = 0.5*RDOT**2 - BODY(ICH)/RI
              RX = -BODY(ICH)/ER
              IF (ER.LT.0.0.AND.RX.LT.MIN(2.0*RSUM,2.0*RMIN)) THEN
                  KCASE = 0
                  GO TO 60
              END IF
              IF (RI.GT.MAX(0.5*RMAXS(ISUB),3.0*RMIN)) THEN
*       Decide between termination or removal for sub-parabolic motion.
                  IF (NN.LT.4) THEN
*       Delay termination for eccentric binary inside R = -m1*m2/2*E < a.
                      IB = 3 - IM
                      J1 = INAME(IB)
                      J2 = INAME(IB+1)
*       Obtain semi-major axis from ENERGY = -(m1*m2 + (m1+m2)*m3)/RGRAV.
                      ZMU = BODYC(J1)*BODYC(J2)/(BODYC(J1) + BODYC(J2))
                      ZF = BODYC(IESC)/ZMU
*       Write E = E_b + E_1 with E_b = -m1*m2/2*a and E_1 = MU3*ER.
                      SEMI = 0.5*RGRAV/(1.0 + ZF*(1.0 + RGRAV*ER/MASS))
                      RY = 1.0/RINV(IB)
                      IF (RY.LT.0.9*SEMI.AND.RI.LT.2.0*RMIN) THEN
                          WRITE (3,33)  NSTEP1, RY/SEMI, RI, RDOT**2,
     &                                  2.0*BODY(ICH)/RI, SEMI
                          KCASE = 0
                          GO TO 60
                      END IF
                      IF (RI.GT.20.0*SEMI) THEN
*       Delay single BH for small perturbation (orbit may turn around).
                          IF (ISTAR(IESC).EQ.14.AND.
     &                        GPERT.LT.1.0D-03) THEN
                              KCASE = 0
                              GO TO 60
                          ELSE
                              KCASE = 1
                              GO TO 35
                          END IF
                      ELSE
                          KCASE = 0
                          GO TO 60
                      END IF
                  ELSE
                      IF (ISTAR(IESC).EQ.14.AND.
     &                    GPERT.LT.1.0D-03) THEN
                          KCASE = 0
                          GO TO 60
                      ELSE
                          KCASE = 1
                          GO TO 35
                      END IF
                  END IF
              ELSE
                  KCASE = 0
                  GO TO 60
              END IF
          ELSE IF (NN.GE.4) THEN
*       Accept escape of hyperbolic body if separation > RMIN.
              RBIG = 1.0/RINV(IM)
              IF (RBIG.GT.RMIN) THEN
                  KCASE = 1
                  GO TO 35
              END IF
*       Include three-body stability test for distant fourth body.
*             IF (RBIG.GT.0.75*RSUM.AND.NN.EQ.4.AND.
*    &            RSUM.GT.0.5*RMIN) THEN
*                 CALL CHSTAB(ITERM)
*                 IF (ITERM.LT.0) THEN
*                     KCASE = -1
*                     GO TO 60
*                 END IF
*             END IF
*       Skip if largest separation is not dominant.
              IF (RBIG.LT.0.66*RSUM) THEN
                  KCASE = 0
                  GO TO 60
              END IF
          ELSE
*       Note possibility a << RGRAV/6 after strong interaction with NN = 3.
              IB = 3 - IM
              J1 = INAME(IB)
              J2 = INAME(IB+1)
*       Obtain semi-major axis from ENERGY = -(m1*m2 + (m1+m2)*m3)/RGRAV.
              ZMU = BODYC(J1)*BODYC(J2)/(BODYC(J1) + BODYC(J2))
              ZF = BODYC(IESC)/ZMU
              ER = 0.5*RDOT**2 - BODY(ICH)/RI
*       Write E = E_b + E_1 with E_b = -m1*m2/2*a and E_1 = MU3*ER.
              SEMI = 0.5*RGRAV/(1.0 + ZF*(1.0 + RGRAV*ER/MASS))
              RY = 1.0/RINV(IB)
*       Note RGRAV = MIN(0.5*RSUM,RGRAV) is OK and RGRAV adjusted on QPMOD.
              IF (RY.LT.0.8*SEMI.AND.RI.LT.2.0*RMIN) THEN
                  WRITE (3,33)  NSTEP1, RY/SEMI, RI, RDOT**2,
     &                          2.0*BODY(ICH)/RI, SEMI
   33             FORMAT (' CHAIN DELAY    # R/A RI RD2 VP2 A ',
     &                                     I8,F6.2,1P,4E9.1)
                  KCASE = 0
                  GO TO 60
              END IF
          END IF
*
*       Check that escaper is well separated (ratio > 2).
          RR = RSUM - 1.0/RINV(IM)
          RATIO = 1.0/(RINV(IM)*RR)
          IF (RATIO.LT.2.0.AND.RSUM.LT.RMIN) THEN
              KCASE = 0
              GO TO 60
          END IF
*
   35     HI = 0.5*RDOT**2 - BODY(ICH)/RI
          IF (HI.LT.0.0) THEN
*       Skip small radial velocity (0.01 circular value).
              RATIO = RI*RDOT**2/BODY(ICH)
              IF (RATIO.LT.0.0001) THEN
                  KCASE = 0
                  GO TO 60
              END IF
              VINF = 0.0
              RX = -BODY(ICH)/HI
          ELSE
              VINF = SQRT(2.0*HI)*VSTAR
              RX = 10.0
          END IF
          IF ((RX.LT.5.0*RMIN.AND.GPERT.LT.1.0D-04).OR.
     &        (HI.GT.0.0.AND.RI.LT.5.0*RMIN)) THEN
              KCASE = 0
              GO TO 60
          END IF
          IF (KZ(30).GT.1.OR.VINF.GT.2.0) THEN
              WRITE (3,36)  IESC, NAMEC(IESC), RI, RDOT**2,
     &                      2.0*BODY(ICH)/RI, VINF, GPERT
   36         FORMAT (' CHAIN ESCAPE:    IESC NM RI RDOT2 2*M/R VF GP ',
     &                                   I3,I6,1P,3E9.1,0P,F6.1,1P,E9.1)
              CALL FLUSH(3)
          END IF
*       Ensure single body is removed in case of wide binary.
          JESC = 0
      ELSE
          KCASE = 0
          GO TO 60
      END IF
*
*       Reduce chain membership (NCH > 3) or specify termination.
   40 IF (NCH.GE.3) THEN
          IF (RI.GT.20.0*RMIN) GO TO 99
          IF (VINF.GT.5.0.AND.RI.GT.3.0*RMIN) GO TO 99
          IF (VINF.GT.0.0.AND.RI.GT.5.0*RMIN.AND.RDOT.GT.0.0) GO TO 99
*       Subtract largest chain distance from system size (also binary).
*         IM = ISORT(1)
*         RSUM = RSUM - 1.0/RINV(IM) - RB
          IF (JESC.EQ.0) THEN
              HI = 0.5*RDOT**2 - BODY(ICH)/RI
              RX = 10.0
              IF (HI.LT.0.0) RX = -BODY(ICH)/HI
              IF ((RX.LT.25.0*RMIN.AND.GPERT.LT.0.001).OR.
     &            (RDOT.LT.0.0.AND.NCH.LE.5.AND.GPERT.LT.0.01)) THEN
                  KCASE = 0
                  GO TO 60
              END IF
*       Skip if escaper would increase the perturbation by factor 1.5.
*             GX = 2.0*BODYC(IESC)/(MASS-BODYC(IESC))*((RSUM-RI)/RI)**3
              CALL CPERTJ(IESC,GX)
              IF ((GPERT.LT.1.5*GX.AND.RI.LT.20.0*RMIN).OR.
     &            (ISTAR(IESC).EQ.14.AND.GPERT.LT.0.01).OR.
     &            (RI.LT.10.0*RMIN.AND.GPERT.LT.0.01)) THEN
                  KCASE = 0
                  GO TO 60
              END IF
*        Check distance to nearest member.
              RP2 = 1.0
              DO 45 I = 1,NN
                  IF (I.EQ.IESC) GO TO 45
                  RIJ2 = 0.0
                  DO 44 K = 1,3
                      RIJ2 = RIJ2 + (X4(K,I) - X4(K,IESC))**2
   44             CONTINUE
                  IF (RIJ2.LT.RP2) THEN
                      RP2 = RIJ2
                  END IF
   45         CONTINUE
              IF (RP2.LT.4.0*RMIN**2.AND.RI.LT.10.0*RMIN) THEN
                  KCASE = 0
                  GO TO 60
              END IF
              RP = SQRT(RP2)
              WRITE (3,46) NSTEP1, NCH, NAMEC(IESC), RI, RX,GPERT,GX,
     &                     RP, RDOT
   46         FORMAT (' REDUCE!   # NCH NMC RI RX GP GX RP RD ',
     &                            I8,I4,I6,1P,2E10.2,4E9.1)
          END IF
*
          IF (JESC.GT.0) THEN
              WRITE (6,48)  NAMEC(IESC),NAMEC(JESC), 1.0/RINV(IBIN)
   48         FORMAT (' BINARY!!!   NAM RB  ',2I6,1P,E10.2)
              WRITE (6,49)  NSTEP1, IESC, JESC, (1.0/RINV(KK),KK=1,NN-1)
   49         FORMAT (' # R  ',I8,2I4,1P,7E10.2)
          END IF
          IF (KZ(30).GT.1) THEN
              WRITE (6,55)  TIME+TOFF, NN, NAMEC(IESC), RI, RDOT
   55         FORMAT (' REDUCE    T NCH NAM RI RD ',
     &                            F10.3,I4,I7,1P,2E10.2)
          END IF
*
   99     CALL REDUCE(IESC,JESC,ISUB)
*     ELSE
*         KCASE = -1
      END IF
*
*       Set phase indicator < 0 to ensure new NLIST in routine INTGRT.
   50 IPHASE = -1
*
      CALL FLUSH(6)
   60 RETURN
*
      END
back to top