	PROGRAM SAODEMO8
C
C  Note:  This is the Unix version
C
C       This program follows 3 mass points in a planar orbit about each other.
C
C			Donald H. Gudehus, November 9, 1994
C			Version 1U, D. H. G., August 31, 1999
C			Modified code for Unix
C			Version 2, D. Gudehus, August 29, 2006
C			Incorporated changes from saofacts.for and
C			added call to GET_ENDIAN.
C
C	CHARACTER*3 DEVICES(10)
	REAL*8 xy(2,3),v_xy(2,3), !  2 positions, 3 objects; etc.
	1xy_prior(2,3),a_xy(2,3)
	REAL*8 TEMP(3),KN,km_AU,K(3),t,dt,dtmin,dt_try,dv_v,r3
C
	INCLUDE 'saofacts.for'
	INTEGER*4 ACTION,COLOR_TYPE
C
	CALL GET_ENDIAN
C
	CALL MESSAGE('This program demonstrates 3 gravitationally'//
	1' interacting bodies.  First')
	CALL MESSAGE('run it with the defaults (just press the <CR>).'//
	1'  Then vary the')
	CALL MESSAGE('(delta velocity)/velocity and the minimum'//
	1' time step and notice')
	CALL MESSAGE('how the accuracy of the final loops and slingshots'//
	1' changes.')
	CALL MESSAGE(' ')
	CALL MESSAGE('Be sure that the SAOimage desktop is at least 800'//
	1' pixels wide')
	CALL MESSAGE(' ')
C	G=6.668E-11 !  Gravitational constant in mks
C	M will be input in solar masses (1 solar mass = 1.9891E30 kg)
C	Distance will be input in AU (1 AU = 1.495979E11 m)
C	Velocity will be input in km/sec
C	The calculations will be done in AU, km/sec, and km/sec/sec 
C	to avoid overflow
C	r(km)=r(AU)*1.4959791E11*0.001
C	M(kg)=M(M_solar)*1.9891E30
C	a(km/sec/sec)=a(m/sec/sec)*0.001
C	a(m/sec/sec)=GM(kg)/r(m)**2
C	a(km/sec/sec)=GM(M_solar)/r(km)**2*(1.9891E30*0.001**2*0.001)
C	a(km/sec/sec)=K1*M(M_solar)/r(km)**2
C	K1=6.667E-11*1.9891E30*0.001**3
C	a(km/sec/sec)=KN*M(M_solar)/r(AU)**2
	KN=6.667D-11*1.9891D30*0.001**3/(1.4959791D8)**2
	km_AU=1.0D0/1.4959791D8
	TEMP(1)=1.0D0
	TEMP(2)=0.5D0
	TEMP(3)=0.25D0
	CALL MESSAGE('Enter the masses of the 3 objects in solar masses:')
	CALL USRINP(TEMP,3,'F',8,1,'MASSES=','(default = 1.0 0.5 0.25)')
	K(1)=KN*TEMP(1)
	K(2)=KN*TEMP(2)
	K(3)=KN*TEMP(3)
C
	TEMP(1)=3.0D0
	TEMP(2)=0.0D0
	CALL USRINP(TEMP,2,'F',8,1,'POSITION=',
	1'Enter the initial x and y position of mass 1 in units of AU:'//
	1' (default = 3 0)')
	xy(1,1)=TEMP(1)
	xy(2,1)=TEMP(2)
	TEMP(1)=0.0D0
	TEMP(2)=-3.0D0
	CALL USRINP(TEMP,2,'F',8,1,'POSITION=',
	1'Enter the initial position of mass 2 in units of AU:'//
	1' (default = 0 -3)')
	xy(1,2)=TEMP(1)
	xy(2,2)=TEMP(2)
	TEMP(1)=-3.0D0
	TEMP(2)=0.0D0
	CALL USRINP(TEMP,2,'F',8,1,'POSITION=',
	1'Enter the initial position of mass 3 in units of AU:'//
	1' (default = -3 0)')
	xy(1,3)=TEMP(1)
	xy(2,3)=TEMP(2)
C
	TEMP(1)=0.0D0
	TEMP(2)=9.0D0
	CALL USRINP(TEMP,2,'F',8,1,'VELOCITY=','Enter the initial velocity'//
	1' of object 1 in units of km/sec:  (default = 0 9)')
	v_xy(1,1)=TEMP(1)
	v_xy(2,1)=TEMP(2)
	TEMP(1)=10.0D0
	TEMP(2)=0.0D0
	CALL USRINP(TEMP,2,'F',8,1,'VELOCITY=','Enter the initial velocity'//
	1' of object 2 in units of km/sec:  (default = 10 0)')
	v_xy(1,2)=TEMP(1)
	v_xy(2,2)=TEMP(2)
	TEMP(1)=0.0D0
	TEMP(2)=-10.0D0
	CALL USRINP(TEMP,2,'F',8,1,'VELOCITY=','Enter the initial velocity'//
	1' of object 3 in units of km/sec:  (default = 0 -10)')
	v_xy(1,3)=TEMP(1)
	v_xy(2,3)=TEMP(2)
C
	dv_v=0.003D0
	CALL MESSAGE('Enter the maximum desired (delta velocity)/velocity')
	CALL USRINP(dv_v,1,'F',8,1,'DELTA_VELOCITY/VELOCITY=',
	1'per integration step:  (default = 0.003)')
	CALL MESSAGE('Enter the minimum allowable time interval in seconds'//
	1' for the steps:')
	dtmin=2000.0D0
	CALL USRINP(dtmin,1,'F',8,1,'MINIMUM_TIME_INTERVAL=',
	1'(default = 2,000;  this takes precedence over the previous'//
	2' constraint)')
	N_STEPS_PER_PLOT=60
	CALL USRINP(N_STEPS_PER_PLOT,1,'I',4,1,'N_STEPS_PER_PLOT=',
	1'Enter the number of calculations per plotted point:'//
	2'  (default = 60)')
	P_SCALE=0.15 !  Scaling for plot
	CALL USRINP(P_SCALE,1,'F',4,1,'PLOT_SCALE=',
	1'Enter the plotting scale in inches per AU:  (default = 0.15)')
	t_max=1.5D9
	CALL USRINP(t_max,1,'F',4,1,'MAXIMUM_TIME=',
	1'Enter the desired elapsed time in seconds:  (default = 1.5E9)')
C  Begin the calculation
C  The commented code below shows an alternate way of displaying the
C  results by means of the MIIPS plot package.
C	DEVICES(1)='S'
C	CALL PLOTDEVICES(DEVICES)
C	CALL PLOTDEVICES2(DEVICES)
C	CALL COLORMODE(8388564) !  Aquamarine
C	CALL PLOT(2.2,5.0,-3)
C	CALL SYMBOL(-0.8,0.5,0.3,%REF('Three-body Calculation'),0.0,22)
	IFB_SAO=2
	CALL SAOSTART
	CALL SAOFIRST
	NPIC_SAO=1
	NFRAME_SAO=0
	XLOC_SAO(NPIC_SAO)=2.2*95
	YLOC_SAO(NPIC_SAO)=0.8*95
	TV_FILENAME(NPIC_SAO)='3-body calculation'
	CALL SAOCAPTION
	IMSX_SAO(NFRAME_SAO,NPIC_SAO)=1
	IMSY_SAO(NFRAME_SAO,NPIC_SAO)=1
	NPTSX_SAO(NPIC_SAO)=MAXFB_COLS_SAO
	NPTSY_SAO(NPIC_SAO)=MAXFB_ROWS_SAO
	ACTION=3 !  Immediate display of vectors
C
	t=0.0D0
	DO WHILE (t.LT.t_max)
	  DO N=1,3 !  Loops over objects
	    xy_prior(1,N)=xy(1,N) !  Used for plotting only
	    xy_prior(2,N)=xy(2,N)
	  END DO
	  DO I=1,N_STEPS_PER_PLOT
	    DO N=1,3 !  Loops over objects
C  Update the physical quantities
	      a_xy(1,N)=0.0D0
	      a_xy(2,N)=0.0D0
	      NN=1
	      DO WHILE(NN.LE.3)
	        IF (NN.NE.N) THEN
	          r3=((xy(1,N)-xy(1,NN))**2+(xy(2,N)-xy(2,NN))**2)
	1         **1.5
	          a_xy(1,N)=a_xy(1,N)-K(N)/r3*(xy(1,N)-xy(1,NN))
	          a_xy(2,N)=a_xy(2,N)-K(N)/r3*(xy(2,N)-xy(2,NN))
	        END IF
	        NN=NN+1
	      END DO
	    END DO
C  Find the minimum delta t
	    dt=1.0D15
	    DO N=1,3 !  Loops over objects
	      IF (a_xy(1,N).NE.0.0D0) dt_try=ABS(dv_v*v_xy(1,N)/a_xy(1,N))
	      IF (dt_try.LT.dt) dt=dt_try
	      IF (a_xy(2,N).NE.0.0D0) dt_try=ABS(dv_v*v_xy(2,N)/a_xy(2,N))
	      IF (dt_try.LT.dt) dt=dt_try
	    END DO
	    dt=MAX(dt,dtmin)
	    DO N=1,3
	      v_xy(1,N)=v_xy(1,N)+a_xy(1,N)*dt
	      v_xy(2,N)=v_xy(2,N)+a_xy(2,N)*dt
	      xy(1,N)=xy(1,N)+v_xy(1,N)*dt*km_AU
	      xy(2,N)=xy(2,N)+v_xy(2,N)*dt*km_AU
	    END DO
	    t=t+dt
	  END DO
	  DO N=1,3
C	    CALL PLOT(P_SCALE*xy_prior(1,N),P_SCALE*xy_prior(2,N),3)
C	    IF (N.EQ.1) CALL COLORMODE(255) !  Blue
C	    IF (N.EQ.2) CALL COLORMODE(16766720) !  Gold
C	    IF (N.EQ.3) CALL COLORMODE(16729344) !  Orange-red
	    IF (N.EQ.1) COLOR_TYPE=206 !  Blue
	    IF (N.EQ.2) COLOR_TYPE=207 !  Yellow
	    IF (N.EQ.3) COLOR_TYPE=204 !  Red
	    X=P_SCALE*xy(1,N)
	    Y=P_SCALE*xy(2,N)
	    IF (ABS(X).GT.100.0.OR.ABS(Y).GT.100.0) STOP
C	    CALL PLOT(X,Y,2)
	    X_OLD=P_SCALE*xy_prior(1,N)
	    Y_OLD=P_SCALE*xy_prior(2,N)
	    CALL SAO_VECT(ACTION,COLOR_TYPE,95*X_OLD,95*Y_OLD,95*X,
	1   95*Y,NPIC_SAO)
	  END DO
	END DO
	END
