ºòÆü¡¢£³ÂÎÌäÂê¤ÇRunge-Kutta-FehlbergË¡¤ò»È¤Ã¤¿¤¬¤¦¤Þ¤¯¤¤¤Ê¤«¤Ê¤Ã¤¿¤³¤È¤ò½ñ¤¤¤¿¤¬¡¢¤ä¤Ï¤ê¡¢¸íº¹È½Äê¤ÎÉôʬ¤¬´Ö°ã¤Ã¤Æ¤¤¤¿¤è¤¦¤À¡£½¤Àµ¤·¤¿¤È¤³¤í¡¢¤¦¤Þ¤¯¤¤¤Ã¤¿¡£
¤·¤«¤·¡¢·×»»¤Ë¤«¤Ê¤ê»þ´Ö¤¬¤«¤«¤ë¡£»ä¤Î»ý¤Ã¤Æ¤¤¤ëÈóÎϤʥѥ½¥³¥ó¤Ç¤Ï¡¢°ìÈÕÊüÃÖ¤·¤Æ¤ä¤Ã¤È½ª¤ï¤ë¤«¤É¤¦¤«¤°¤é¤¤¤À¡£¥á¥â¥ê¤â¤À¤¤¤Ö¾ÃÈñ¤¹¤ë¡£
»²¹Í¤Ë¤·¤¿¤Î¤Ï
http://homepage1.nifty.com/gfk/Runge-Kutta-Fehlberg.htm
°ìÈ̤ˡ¢¿ôÃÍ·×»»¤Ç¤Ï¡¢°Ì¿ô¤Î°Û¤Ê¤ë¶á»÷Ë¡¤òÍѤ¤¤ë¤³¤È¤Ë¤è¤ê¡¤¶É½êÂǤÁÀÚ¤ê¸íº¹¤òͽ¬¤·¡¤¤³¤Îͽ¬¤ò¤â¤È¤ËÂç°è¸íº¹¤ò¸íº¹¸ÂÅÙÆâ¤Ë¼ý¤Þ¤ë¤è¤¦¤Ë¡¤¹ï¤ßÉý¤ò·è¤á¤ë¼êË¡¤¬¤è¤¯»È¤ï¤ì¤ë¡£Runge-Kutta-FehlbergË¡¤Ï¡¢¤³¤ì¤ò¥ë¥ó¥²¥¯¥Ã¥¿Ë¡¤Ë»È¤Ã¤¿¼êË¡¤Î°ì¤Ä¤Ç¤¢¤ë¡£
Íפϡ¢Ëè²ó¡¢¸íº¹¤ò¥Á¥§¥Ã¥¯¤·¡¢»þ´Ö¹ï¤ßÉý¤òÊѹ¹¤·¤Ê¤¬¤é·×»»¤¹¤ë¤Î¤Ç¡¢ÀºÅÙ¤¬³ÊÃʤˤ褯¤Ê¤ë¡£
º£²ó»È¤Ã¤¿¤Î¤Ï¡¢£¶ÃÊ£µ¼¡¤ÎRunge-Kutta-FehlbergË¡
¥½¡¼¥¹¤Ï°Ê²¼¤Î¤È¤ª¤ê
# physical constants
G = 1.00 # Gravity constant
# experimental settings
speed=1024*2
dT = 1/speed # temporal step
N = 3 # number of stars
T_MAX=60
Rlimit=0.00000001
elimit=0.00001
Tlimit=0.00000001
# calculates gravity force amoung two stars
g_func<-function( x1,x2,M1,M2){
f<-c(0,0,0)
r=sqrt((x1[[1]]-x2[[1]])**2+(x1[[2]]-x2[[2]])**2+(x1[[3]]-x2[[3]])**2)
if (r<Rlimit) r=Rlimit
f=-G*M2/(r*r*r) * (x1-x2)
return(f)
}
# calculates gravity field
forcefunc<-function(x){
f<-matrix(0,nrow=N,ncol=3) # force of star i
for(i in 1:N){
for( j in 1:N){
if(i!=j){
r=sqrt((x[i,][1]-x[j,][1])**2+(x[i,][2]-x[j,][2])**2+(x[i,][3]-x[j,][3])**2)
fij<- g_func( x[i,],x[j,],M[i,],M[j,])
f[i,]=f[i,]+fij
}
}
}
return(f)
}
# calculates total energy
CalcEnergy<-function(){
# sums up energy
E=0
for( i in 1:N){
E= E+M[i,]/2*(v[i,][1]**2+v[i,][2]**2+v[i,][3]**2) # Kinetic Energy
for( j in i:N){
if(i!=j) {
r=sqrt((x[i,][1]-x[j,][1])**2+(x[i,][2]-x[j,][2])**2+(x[i,][3]-x[j,][3])**2)
if (r!=0){
E= E-G*M[i,]*M[j,]/r #Potential Energy
}
}
}
}
return( E )
}
#initial star setting
# velocity of stars
v<-matrix(0,nrow=N,ncol=3)
v[1,]<-c(0,0,0)
v[2,]<-c(0,0,0)
v[3,]<-c(0,0,0)
# position of a stars
x<-matrix(0,nrow=N,ncol=3)
x[1,]<-c(1,3,0)
x[2,]<-c(-2,-1,0)
x[3,]<-c(1,-1,0)
# mass of a stars
M<-matrix(0,nrow=N,ncol=1)
M[1,] = 3.0
M[2,] = 4.0
M[3,] = 5.0
#plot initial points
par(xpd=T,pch=20)
split.screen(c(2,1))
screen(1)
plot(c(0,0), axes=FALSE,xlim=c(-10,10), ylim=c(-5,5),type="n",ann = F)
screen(1)
pre_points<-matrix(0,nrow=N,ncol=3)
for( i in 1:N){
pre_points[i,]<-x[i,]
points(pre_points[i,][1],pre_points[i,][2],col=i+1)
segments(pre_points[i,][1],pre_points[i,][2],x[i,][1],x[i,][2],col=i+1)
}
Pre_E<-CalcEnergy()
#Runge-Kutta-Fehlberg method (dT control)
T=0
Pre_T=T
while( T<T_MAX){
min_r=1000
repeat {
k1_x<-dT*v
k1_v<-dT*forcefunc(x)
k2_x<-(dT+dT/4)*(v+k1_v/4)
k2_v<-(dT+dT/4)*forcefunc(x+k1_x/4)
k3_x<-(dT+3*dT/8)*(v+k1_v*3/32+k2_v*9/32)
k3_v<-(dT+3*dT/8)*forcefunc(x+k1_x*3/32+k2_x*9/32)
k4_x<-(dT+12*dT/13)*(v+k1_v*1932/2197-k2_v*7200/2197+k3_v*7296/2197)
k4_v<-(dT+12*dT/13)*forcefunc(x+k1_x*1932/2197-k2_x*7200/2197+k3_x*7296/2197)
k5_x<-(dT+dT)*(v+k1_v*439/216-k2_v*8+k3_v*3680/513-k4_v*845/4104)
k5_v<-(dT+dT)*forcefunc(x+k1_x*439/216-k2_x*8+k3_x*3680/513-k4_x*845/4104)
k6_x<-(dT+dT/2)*(v-k1_v*8/27+k2_v*2-k3_v*3544/2565+k4_v*1859/4104-k5_v*11/40)
k6_v<-(dT+dT/2)*forcefunc(x-k1_x*8/27+k2_x*2-k3_x*3544/2565+k4_x*1859/4104-k5_x*11/40)
xa<-x+k1_x*25/216+k3_x*1408/2565+k4_x*2197/4104-k5_x/5
xb<-(x+k1_x*16/135+k3_x*6656/12825+k4_x*28561/56430-k5_x*9/50+k6_x*2/55)
va<-v+k1_v*25/216+k3_v*1408/2565+k4_v*2197/4104-k5_v/5
vb<-(v+k1_x*16/135+k3_v*6656/12825+k4_v*28561/56430-k5_v*9/50+k6_v*2/55)
xab<-abs(k1_x/360 - 128*k3_x/4275 - 2197*k4_x/75240 + k5_x/50 + 2*k6_x/55)
vab<-abs(k1_v/360 - 128*k3_v/4275 - 2197*k4_v/75240 + k5_v/50 + 2*k6_v/55)
sv=(elimit*dT/vab/2)^.25
sx=(elimit*dT/xab/2)^.25
s_min=1000
for(i in 1:3){
if(s_min>sv[[i]]) s_min<-sv[[i]]
if(s_min>sx[[i]]) s_min<-sx[[i]]
}
if(s_min>=0.8 || dT<=Tlimit){
break
}
else {
if ( s_min < 0.1) s_min =0.1
dT<-s_min*dT
if ( dT < Tlimit ) dT =Tlimit
}
}
v=va
x=xa
for(i in 1:N){
for( j in i:N){
if(i!=j){
r=sqrt((x[i,][1]-x[j,][1])**2+(x[i,][2]-x[j,][2])**2+(x[i,][3]-x[j,][3])**2)
if(r<min_r) min_r=r
}
}
}
T=T+dT
dT=min_r/speed
if ( min_r < 0.1) dT =min_r/speed/2
if ( min_r < 0.01) dT=min_r/speed/8
if ( dT < Tlimit ) dT =Tlimit
if(T-Pre_T>0.001){
screen(1)
for( i in 1:N){
segments(pre_points[i,][1],pre_points[i,][2],x[i,][1],x[i,][2],col=i+1)
pre_points[i,]<-x[i,]
}
E<-CalcEnergy()
screen(2)
plot(c(0,-15), xlim=c(0,T_MAX), ylim=c(-20,-10),type="n",ann = F)
par(new=T)
if (E<=-20) E=-20
if (E>=0) E=0
segments(Pre_T,Pre_E,T,E)
Pre_E=E
Pre_T=T
}
}