Fortran三维向量叉积函数
左志华(在读硕士) [email protected]
哈尔滨工程大学 船舶工程学院 2020-12-27
关键词:Fortran
;叉积;三维向量
Ⅰ. 搜索mkl叉积函数
在一次编程过程中,涉及到求取单元法向的操作,使用到了叉乘,但是Fortran自带了点乘,却没有叉乘,我查询了mkl库,发现有一个VSL_SS_CP
函数(属于mkl统计函数部分),但是查找了INTEL FORTRAN的安装路径中的mkl_vsl.f90
查找到VSL_SS_CP
函数返回值是整数?我接触mkl的时间不长,蒙~
MKL帮助文档
VSL_SS_CP?!
Ⅱ. 自己动手
i. Main.f90
!+ 试求解三维向量的叉积,并验证USE Module ONLY Operator
!
PROGRAM MAIN
! 描述[Description]:
! 试求解三维向量的叉积,并验证USE Module ONLY Operator
!
! 方法[method]:
! 调用MOUDLE Math中的CrossProduct3D计算3维向量的叉积,并验证Fortran语法,USE Math ONLY:
! OPERATOR(.CP.)。
!
! 输入文件[Input files]:
! 无
! 输出文件[Output files]:
! 无
! 当前代码所有者[Current Code Owner]:
! 左志华[zoziha] [email protected]
!
! 历史[History]:
! Version Date CommentCN[CommentEN]
! --------- ---- ----------------
! V1.0 2020-12-27 原始代码[Original code] 左志华
! 代码说明[Code Description]: 语言[Language] = Fortran 90.
! 软件标准[Software Standards]: “书写和存储可复用的Fortran90代码准则”.
! https://www.jianshu.com/p/3c7f45cde3ea
USE Math, ONLY: &
! 导入的参数[Imported Parameters]:
! <导入的标量/数组变量(输入/输出)[Imported Scalar Variables/Arrays, intent (in/out)]>
CrossProduct3D, &
OPERATOR(.CP.)
IMPLICIT NONE
! ! 变量说明/用途
! ! Description/ purpose of variable
! REAL I(3) ! 叉积函数的3维输入数组
! REAL J(3) ! 叉积函数的3维输入数组
! REAL K(3) ! 叉积函数的3维输出数组
REAL :: I(3), J(3), K(3)
WRITE (*, "(A,/)") "# K = I × J, Example 1: "
I = (/1,0,0/); J = (/0,1,0/)
K = CrossProduct3D(I,J)
WRITE (*, "(3(2X,A,3F6.0,/))") "I = ", I, "J = ", J, "K = ", K
WRITE (*, "(/,A,/)") "# K = I × J, Example 2: "
I = (/2,3,4/); J = (/5,6,7/)
K = I .CP. J
WRITE (*, "(3(2X,A,3F6.0,/))") "I = ", I, "J = ", J, "K = ", K
READ (*, *)
END PROGRAM MAIN
!- 程序标头末尾[End of program header] -----------------------------------------
ii. Math.f90
!+ 数学模块
!
MODULE Math
!
! 描述[Description]:
! 数学模块
!
! 当前代码所有者[Current Code Owner]:
! 左志华[zoziha] [email protected]
!
! 历史[History]:
! Version Date CommentCN[CommentEN]
! --------- ---- ----------------
! V1.0 2020-12-27 原始代码[Original code] 左志华
! 代码说明[Code Description]: 语言[Language] = Fortran 90.
! 软件标准[Software Standards]: “书写和存储可复用的Fortran90代码准则”.
! https://www.jianshu.com/p/3c7f45cde3ea
IMPLICIT NONE
! ! 变量说明/用途
! ! Description/ purpose of variable
! INTERFACE OPERATOR(.CP.) ! 自定义操作符.CP.,绑定FUNCTION CrossProduct3D,
! 求三维向量叉积
INTERFACE OPERATOR (.CP.)
MODULE PROCEDURE :: CrossProduct3D
END INTERFACE
CONTAINS
!+ 求三维向量叉积
!
FUNCTION CrossProduct3D &
(X, &
Y) &
RESULT (Z) ! The use of result is recommended
! but is not compulsory.
! 描述[Description]:
! 求三维向量叉积
!
! 方法[Method]:
! 求三维向量叉积
! https://baike.baidu.com/item/%E5%90%91%E9%87%8F%E7%A7%AF/4601007?fromtitle=%E5%8F%89%E7%A7%AF&fromid=2812058
!
! 当前代码所有者[Current Code Owner]:
! 左志华[zoziha] [email protected]
!
! 历史[History]:
! Version Date CommentCN[CommentEN]
! --------- ---- ----------------
! V1.0 2020-12-27 原始代码[Original code] 左志华
! 代码说明[Code Description]: 语言[Language] = Fortran 90.
! 软件标准[Software Standards]: “书写和存储可复用的Fortran90代码准则”.
! https://www.jianshu.com/p/3c7f45cde3ea
IMPLICIT NONE
! ! 变量说明/用途
! ! Description/ purpose of variable
! REAL X(3) ! 叉积函数的3维输入数组
! REAL Y(3) ! 叉积函数的3维输入数组
! REAL Z(3) ! 叉积函数的3维输出数组
REAL, INTENT(IN) :: X(3), Y(3)
REAL :: Z(3)
Z(1) = X(2)*Y(3)-X(3)*Y(2)
Z(2) = X(3)*Y(1)-X(1)*Y(3)
Z(3) = X(1)*Y(2)-X(2)*Y(1)
RETURN
END FUNCTION CrossProduct3D
!- 模块标头末尾[End of fucntion header] ----------------------------------------
END MODULE Math
!- 模块标头末尾[End of module header] ------------------------------------------
iii. 插曲
这里用到了USE Math, ONLY: OPERATOR(.CP.)
,即:
USE, ONLY:
有以下几种用法
USE MATH, ONLY: &
A ! Variable
CrossProduct3D ! Routine
OPERATOR(.OP.) ! Operator
ASSIGNMENT(=) ! Assignment
iV. 运行结果
> gfortran Math.f90 Main.f90 -o main
> ./main
# K = I × J, Example 1:
I = 1. 0. 0.
J = 0. 1. 0.
K = 0. 0. 1.
# K = I × J, Example 2:
I = 2. 3. 4.
J = 5. 6. 7.
K = -3. 6. -3.
Ⅲ. 关于mkl/blas/imsl/lapack/fgsl等数学库
之前我都是尽量避免使用数学库,原因是数学库缺乏源码,但其实想起来,如果数学库足够稳定可控,使用它们将有助于快速解决问题。
所以我想在之后我将“驯服”[Reference:《小王子》]一两个数学库吧。
Ⅳ. 结语
这个叉乘几乎是没有太多分享意义,因为它太基础与简单了。但是,既然我做了这个事,便又“显摆”了出来。