将三个功能合并为一个
Merging three functions into one
我正在构建一个将轨道元素转换为笛卡尔坐标的程序。
我想创建一个函数来执行此操作,将轨道元素转换为笛卡尔坐标,但我无法让它工作。这是我第一次使用 fortran,所以我还在适应它。
program conversion
implicit none
real*8 :: EC, A, IC, OM, W, TA, X, Y, Z
real*8, external :: XCARTISIAN, YCARTISIAN, ZCARTISIAN, r
print *, "Insert Oribtal Elements (EC, A, IC, OM, W, TA): "
read *, EC, A, IC, OM, W, TA, X, Y, Z
X = XCARTISIAN(EC, A, IC, OM, W, TA)
Y = YCARTISIAN(EC, A, IC, OM, W, TA)
Z = ZCARTISIAN(EC, A, IC, OM, W, TA)
print *, "X : ", X, "Y : ", Y, "Z : ", Z
end program conversion
real*8 function XCARTISIAN(EC, A, IC, OM, W, TA)
implicit none
real*8, intent(in) :: EC, A, IC, OM, W, TA
real*8 :: XCARTISIAN, r
r = A(1-EC**2)/(1+EC*COS(TA))
XCARTISIAN = r(COS(OM)*COS(W+TA)-SIN(OM)*SIN(W+TA)*COS(IC))
return
end function XCARTISIAN
real*8 function YCARTISIAN(EC, A, IC, OM, W, TA)
implicit none
real*8, intent(in) :: EC, A, IC, OM, W, TA
real*8 :: YCARTISIAN
r = A(1-EC**2)/(1+EC*COS(TA))
YCARTISIAN = r(SIN(OM)*COS(W+TA)+COS(OM)*SIN(W+TA)*COS(IC))
return
end function YCARTISIAN
real*8 function ZCARTISIAN(EC, A, IC, OM, W, TA)
implicit none
real*8, intent(in) :: EC, A, IC, OM, W, TA
real*8 :: ZCARTISIAN
r = A(1-EC**2)/(1+EC*COS(TA))
ZCARTISIAN = r(SIN(W+F)*SIN(IC)
return
end function ZCARTISIAN
我怎样才能使它工作并创建一个函数来执行此操作而不是分别为 X、Y 和 Z 创建三个单独的函数?
转换公式如下:
X = r(COS(OM)*COS(W+TA)-SIN(OM)*SIN(W+TA)*COS(IC))
Y = r(SIN(OM)*COS(W+TA)+COS(OM)*SIN(W+TA)*COS(IC))
Z = r(SIN(W+F)*SIN(IC)
其中,
r = A(1-EC**2)/(1+EC*COS(TA))
也许把你的函数放到一个模块中?
MODULE ORBITCANDY
IMPLICIT NONE
PRIVATE
TYPE(Cart_typ)
REAL*8 X
REAL*8 Y
REAL*8 Z
END TYPE Cart_typ
PUBLIC :: Cart_Typ
TYPE(OE_typ)
REAL*8 EC
REAL*8 A
REAL*8 IC
REAL*8 OM
REAL*8 W
REAL*8 TA
END TYPE OE_typ
PUBLIC :: OE_Typ
PUBLIC :: OE2CART
CONTAINS
function OE2Cart(OE)
implicit none
TYPE(OE_Typ) , INTENT(IN ) :: OE
TYPE(Cart_Typ) :: OE2Cart
real*8 :: EC, A, IC, OM, W, TA
real*8 :: XCARTISIAN, r
EC = OE%EC
A = OE%A
IC = OE%IC
OM = OE%OM
W = OE%W
TA = OE%TA
OE2Cart%X = XCARTISIAN(EC, A, IC, OM, W, TA)
OE2Cart%Y = YCARTESIAN(EC, A, IC, OM, W, TA)
OE2Cart%Z = ZCARTESIAN(EC, A, IC, OM, W, TA)
RETURN
END FUNCTION OE2CART
!%%%%%%%%%%%%%%
real*8 function YCARTISIAN(EC, A, IC, OM, W, TA)
implicit none
TYPE(OE_Typ) , INTENT(IN ) :: OE
real*8, intent(in) :: EC, A, IC, OM, W, TA
real*8 :: XCARTISIAN, r
r = A(1-EC**2)/(1+EC*COS(TA))
XCARTISIAN = r(COS(OM)*COS(W+TA)-SIN(OM)*SIN(W+TA)*COS(IC))
return
end function XCARTISIAN
!%%%%%%%%%%%%%%
real*8 function YCARTISIAN(EC, A, IC, OM, W, TA)
implicit none
real*8, intent(in) :: EC, A, IC, OM, W, TA
real*8 :: YCARTISIAN
r = A(1-EC**2)/(1+EC*COS(TA))
YCARTISIAN = r(SIN(OM)*COS(W+TA)+COS(OM)*SIN(W+TA)*COS(IC))
return
end function YCARTISIAN
!%%%%%%%%%%%%%%
real*8 function ZCARTISIAN(EC, A, IC, OM, W, TA)
implicit none
real*8, intent(in) :: EC, A, IC, OM, W, TA
real*8 :: ZCARTISIAN
r = A(1-EC**2)/(1+EC*COS(TA))
ZCARTISIAN = r(SIN(W+F)*SIN(IC)
return
end function ZCARTISIAN
END MODULE ORBITCANDY
还有一个用于 R,然后是 CART2GEODETIC,等等...
program conversion
USE ORBITCANDY
implicit none
TYPE(OE_Typ) :: OE
TYPE(Cart_Typ) :: Cart
real*8, external :: r ! Add this one above
print *, "Insert Oribtal Elements (EC, A, IC, OM, W, TA): "
read *, OE%EC, OE%A, OE%IC, OE%OM, OE%W, OE%TA
print *, "Insert Oribtal Elements (EC, A, IC, OM, W, TA): "
read *, OE%EC, OE%A, OE%IC, OE%OM, OE%W, OE%TA
XYZ = OE2CART(OE)
print *, "X : ", XYZ%X, "Y : ", XYZ%Y, "Z : ", XYZ%Z
end program conversion
iPad里面没有编译器,肯定是打错了...
最直接的做法是制作一个子程序。最好放在一个模块中,但这是可选的(但恕我直言,所有函数和子例程都应该在某个模块中)。
subroutine XYZCARTISIAN(XCARTISIAN, YCARTISIAN, ZCARTISIAN, EC, A, IC, OM, W, TA)
implicit none
real*8 :: XCARTISIAN, YCARTISIAN, ZCARTISIAN
real*8, intent(in) :: EC, A, IC, OM, W, TA
, r
r = A(1-EC**2)/(1+EC*COS(TA))
XCARTISIAN = r*(COS(OM)*COS(W+TA)-SIN(OM)*SIN(W+TA)*COS(IC))
YCARTISIAN = r*(SIN(OM)*COS(W+TA)+COS(OM)*SIN(W+TA)*COS(IC))
ZCARTISIAN = r*(SIN(W+F)*SIN(IC)
end subroutine
这也会更快,因为您只计算 r
一次并且只调用一个子程序。
请注意:
real*8
完全不标准,不是Fortran。
- 使用缩进使您的代码更具可读性。
- 那里不需要
return
,我们只是过早地return。
我正在构建一个将轨道元素转换为笛卡尔坐标的程序。
我想创建一个函数来执行此操作,将轨道元素转换为笛卡尔坐标,但我无法让它工作。这是我第一次使用 fortran,所以我还在适应它。
program conversion
implicit none
real*8 :: EC, A, IC, OM, W, TA, X, Y, Z
real*8, external :: XCARTISIAN, YCARTISIAN, ZCARTISIAN, r
print *, "Insert Oribtal Elements (EC, A, IC, OM, W, TA): "
read *, EC, A, IC, OM, W, TA, X, Y, Z
X = XCARTISIAN(EC, A, IC, OM, W, TA)
Y = YCARTISIAN(EC, A, IC, OM, W, TA)
Z = ZCARTISIAN(EC, A, IC, OM, W, TA)
print *, "X : ", X, "Y : ", Y, "Z : ", Z
end program conversion
real*8 function XCARTISIAN(EC, A, IC, OM, W, TA)
implicit none
real*8, intent(in) :: EC, A, IC, OM, W, TA
real*8 :: XCARTISIAN, r
r = A(1-EC**2)/(1+EC*COS(TA))
XCARTISIAN = r(COS(OM)*COS(W+TA)-SIN(OM)*SIN(W+TA)*COS(IC))
return
end function XCARTISIAN
real*8 function YCARTISIAN(EC, A, IC, OM, W, TA)
implicit none
real*8, intent(in) :: EC, A, IC, OM, W, TA
real*8 :: YCARTISIAN
r = A(1-EC**2)/(1+EC*COS(TA))
YCARTISIAN = r(SIN(OM)*COS(W+TA)+COS(OM)*SIN(W+TA)*COS(IC))
return
end function YCARTISIAN
real*8 function ZCARTISIAN(EC, A, IC, OM, W, TA)
implicit none
real*8, intent(in) :: EC, A, IC, OM, W, TA
real*8 :: ZCARTISIAN
r = A(1-EC**2)/(1+EC*COS(TA))
ZCARTISIAN = r(SIN(W+F)*SIN(IC)
return
end function ZCARTISIAN
我怎样才能使它工作并创建一个函数来执行此操作而不是分别为 X、Y 和 Z 创建三个单独的函数?
转换公式如下:
X = r(COS(OM)*COS(W+TA)-SIN(OM)*SIN(W+TA)*COS(IC))
Y = r(SIN(OM)*COS(W+TA)+COS(OM)*SIN(W+TA)*COS(IC))
Z = r(SIN(W+F)*SIN(IC)
其中,
r = A(1-EC**2)/(1+EC*COS(TA))
也许把你的函数放到一个模块中?
MODULE ORBITCANDY
IMPLICIT NONE
PRIVATE
TYPE(Cart_typ)
REAL*8 X
REAL*8 Y
REAL*8 Z
END TYPE Cart_typ
PUBLIC :: Cart_Typ
TYPE(OE_typ)
REAL*8 EC
REAL*8 A
REAL*8 IC
REAL*8 OM
REAL*8 W
REAL*8 TA
END TYPE OE_typ
PUBLIC :: OE_Typ
PUBLIC :: OE2CART
CONTAINS
function OE2Cart(OE)
implicit none
TYPE(OE_Typ) , INTENT(IN ) :: OE
TYPE(Cart_Typ) :: OE2Cart
real*8 :: EC, A, IC, OM, W, TA
real*8 :: XCARTISIAN, r
EC = OE%EC
A = OE%A
IC = OE%IC
OM = OE%OM
W = OE%W
TA = OE%TA
OE2Cart%X = XCARTISIAN(EC, A, IC, OM, W, TA)
OE2Cart%Y = YCARTESIAN(EC, A, IC, OM, W, TA)
OE2Cart%Z = ZCARTESIAN(EC, A, IC, OM, W, TA)
RETURN
END FUNCTION OE2CART
!%%%%%%%%%%%%%%
real*8 function YCARTISIAN(EC, A, IC, OM, W, TA)
implicit none
TYPE(OE_Typ) , INTENT(IN ) :: OE
real*8, intent(in) :: EC, A, IC, OM, W, TA
real*8 :: XCARTISIAN, r
r = A(1-EC**2)/(1+EC*COS(TA))
XCARTISIAN = r(COS(OM)*COS(W+TA)-SIN(OM)*SIN(W+TA)*COS(IC))
return
end function XCARTISIAN
!%%%%%%%%%%%%%%
real*8 function YCARTISIAN(EC, A, IC, OM, W, TA)
implicit none
real*8, intent(in) :: EC, A, IC, OM, W, TA
real*8 :: YCARTISIAN
r = A(1-EC**2)/(1+EC*COS(TA))
YCARTISIAN = r(SIN(OM)*COS(W+TA)+COS(OM)*SIN(W+TA)*COS(IC))
return
end function YCARTISIAN
!%%%%%%%%%%%%%%
real*8 function ZCARTISIAN(EC, A, IC, OM, W, TA)
implicit none
real*8, intent(in) :: EC, A, IC, OM, W, TA
real*8 :: ZCARTISIAN
r = A(1-EC**2)/(1+EC*COS(TA))
ZCARTISIAN = r(SIN(W+F)*SIN(IC)
return
end function ZCARTISIAN
END MODULE ORBITCANDY
还有一个用于 R,然后是 CART2GEODETIC,等等...
program conversion
USE ORBITCANDY
implicit none
TYPE(OE_Typ) :: OE
TYPE(Cart_Typ) :: Cart
real*8, external :: r ! Add this one above
print *, "Insert Oribtal Elements (EC, A, IC, OM, W, TA): "
read *, OE%EC, OE%A, OE%IC, OE%OM, OE%W, OE%TA
print *, "Insert Oribtal Elements (EC, A, IC, OM, W, TA): "
read *, OE%EC, OE%A, OE%IC, OE%OM, OE%W, OE%TA
XYZ = OE2CART(OE)
print *, "X : ", XYZ%X, "Y : ", XYZ%Y, "Z : ", XYZ%Z
end program conversion
iPad里面没有编译器,肯定是打错了...
最直接的做法是制作一个子程序。最好放在一个模块中,但这是可选的(但恕我直言,所有函数和子例程都应该在某个模块中)。
subroutine XYZCARTISIAN(XCARTISIAN, YCARTISIAN, ZCARTISIAN, EC, A, IC, OM, W, TA)
implicit none
real*8 :: XCARTISIAN, YCARTISIAN, ZCARTISIAN
real*8, intent(in) :: EC, A, IC, OM, W, TA
, r
r = A(1-EC**2)/(1+EC*COS(TA))
XCARTISIAN = r*(COS(OM)*COS(W+TA)-SIN(OM)*SIN(W+TA)*COS(IC))
YCARTISIAN = r*(SIN(OM)*COS(W+TA)+COS(OM)*SIN(W+TA)*COS(IC))
ZCARTISIAN = r*(SIN(W+F)*SIN(IC)
end subroutine
这也会更快,因为您只计算 r
一次并且只调用一个子程序。
请注意:
real*8
完全不标准,不是Fortran。- 使用缩进使您的代码更具可读性。
- 那里不需要
return
,我们只是过早地return。