美文网首页
Fortran利用optional参数输出不定数量的曲线数据或云

Fortran利用optional参数输出不定数量的曲线数据或云

作者: 忆霜晨 | 来源:发表于2018-06-13 22:19 被阅读0次

前面的博客中,使用Python实现了一些工具函数,可以十分便利的输出Tecplot格式的曲线和二维云图数据,在本篇博客中,将使用Fortran实现类似的工具函数。

Python实现上述工具函数的便利之处在于其语法的宽松性,Python函数可以接收不定数量的参数,并且在函数内部可以用很简单的方式遍历传入的参数。在Fortran中要实现上述工具函数的功能,一种方式是可以使用高维数组,由于要事先将已有数组组成高维数组,而Fortran中的变量并非拿来即用、用完不管,所以过程比较繁琐。另一种方式是使用Fortran函数的可选参数功能,即关键字 optional 描述的参数。在函数内部可以使用 PRESENT 函数查询该参数是否给出。只要实现设置我们日常使用足够多的可选参数,那么就近似的实现了上述工具函数的功能。

在后文的代码中,output_tecplot_line 子程序用于输出Tecplot曲线数据文件,output_tecplot_2D 子程序用于输出Tecplot二维云图数据文件,二者都实现了8个可选参数,如果日常使用需要更多,简单修改一下即可。使用起来十分方便,示例如下:

call output_tecplot_line(                   &
    './test_output_tecplot_line.plt',       &
    'X', X, 'Y_sin', Y_sin, 'Y_cos', Y_cos, &
    'Y_sqrt', Y_sqrt, 'Y_sinh', Y_sinh,     &
    'Y_tanh', Y_tanh, 'Y_exp', Y_exp )

call output_tecplot_2D(                 &
    './test_output_tecplot_2D.plt',     &
    'X', X, 'Y', Y, 'Z_sin', Z_sin,     & 
    'Z_cos', Z_cos, 'Z_sqrt', Z_sqrt,   & 
    'Z_sinh', Z_sinh, 'Z_tanh', Z_tanh, & 
    'Z_exp', Z_exp )

output_tecplot_line 子程序输出的曲线数据文件格式如下:

 title="By SUBROUTINE output_tecplot_line"
 variables="X","Y_sin","Y_cos","Y_sqrt","Y_sinh","Y_tanh","Y_exp"
 -0.2000000E+01 -0.9092974E+00 -0.4161468E+00  0.1414214E+01 -0.3626860E+01 -0.9640276E+00  0.1353353E+00 
 -0.1990000E+01 -0.9134134E+00 -0.4070332E+00  0.1410674E+01 -0.3589419E+01 -0.9633142E+00  0.1366954E+00 
 -0.1980000E+01 -0.9174380E+00 -0.3978789E+00  0.1407125E+01 -0.3552337E+01 -0.9625870E+00  0.1380692E+00

output_tecplot_2D 子程序输出的二维云图数据文件格式如下:

 title="By SUBROUTINE output_tecplot_line"
 variables="X","Y","Z_sin","Z_cos","Z_sqrt","Z_sinh","Z_tanh","Z_exp"
 zone i = 401, j = 401
  0.0000000E+00  0.0000000E+00  0.0000000E+00  0.1000000E+01  0.0000000E+00  0.0000000E+00  0.0000000E+00  0.1000000E+01 
  0.1000000E-01  0.0000000E+00  0.9999833E-02  0.9999500E+00  0.1000000E+00  0.1000017E-01  0.9999666E-02  0.1010050E+01
module mod_Precision
implicit none
    integer, parameter :: SINGLE = 4
    integer, parameter :: DOUBLE = 8
    integer, parameter :: PRECISION = DOUBLE
end module
module mod_Tools
use mod_Precision
implicit none

    contains

    !* 输出Tecplot曲线
    !* 这里x是自变量,即横轴,var_i是因变量,即纵轴.
    !* 其中,var_2至var_9是可选的,即最多可以输出9条曲线.
    subroutine output_tecplot_line( file_name, &
        x_name, x,                             &
        var_1_name, var_1, var_2_name, var_2,  &
        var_3_name, var_3, var_4_name, var_4,  &
        var_5_name, var_5, var_6_name, var_6,  &
        var_7_name, var_7, var_8_name, var_8,  &
        var_9_name, var_9 )
    implicit none
        character(len=*), intent(in) :: file_name
        character(len=*), intent(in) :: x_name, var_1_name
        real(PRECISION),  dimension(:), intent(in) :: x, var_1
        character(len=*), optional, intent(in) :: &
            var_2_name, var_3_name, var_4_name, &
            var_5_name, var_6_name, var_7_name, &
            var_8_name, var_9_name
        real(PRECISION), dimension(:), optional, intent(in) :: &
            var_2, var_3, var_4, var_5,  &
            var_6, var_7, var_8, var_9

        character(len=300) :: var_name_list 
        integer :: var_count, i
        
        var_count = SIZE(x)
        
        var_name_list = 'variables="' // TRIM(ADJUSTL(x_name)) // &
            '","' // TRIM(ADJUSTL(var_1_name)) // '"'
        
        if (PRESENT(var_2_name)) then
            var_name_list = TRIM(ADJUSTL(var_name_list)) // ',"' // &
                TRIM(ADJUSTL(var_2_name)) // '"' 
        end if
        if (PRESENT(var_3_name)) then
            var_name_list = TRIM(ADJUSTL(var_name_list)) // ',"' // &
                TRIM(ADJUSTL(var_3_name)) // '"'
        end if
        if (PRESENT(var_4_name)) then
            var_name_list = TRIM(ADJUSTL(var_name_list)) // ',"' // &
                TRIM(ADJUSTL(var_4_name)) // '"'
        end if
        if (PRESENT(var_5_name)) then
            var_name_list = TRIM(ADJUSTL(var_name_list)) // ',"' // &
                TRIM(ADJUSTL(var_5_name)) // '"'
        end if
        if (PRESENT(var_6_name)) then
            var_name_list = TRIM(ADJUSTL(var_name_list)) // ',"' // &
                TRIM(ADJUSTL(var_6_name)) // '"'
        end if
        if (PRESENT(var_7_name)) then
            var_name_list = TRIM(ADJUSTL(var_name_list)) // ',"' // &
                TRIM(ADJUSTL(var_7_name)) // '"'
        end if
        if (PRESENT(var_8_name)) then
            var_name_list = TRIM(ADJUSTL(var_name_list)) // ',"' // &
                TRIM(ADJUSTL(var_8_name)) // '"'
        end if
        if (PRESENT(var_9_name)) then
            var_name_list = TRIM(ADJUSTL(var_name_list)) // ',"' // &
                TRIM(ADJUSTL(var_9_name)) // '"'
        end if
        
        open(unit=33, file=file_name, form='formatted', status='replace')
        
        write(33, *) 'title="By SUBROUTINE output_tecplot_line"'    
        write(33, *) TRIM(ADJUSTL(var_name_list))
        
        do i=1, var_count
            write(33, '(E15.7, E15.7\)') x(i), var_1(i)
        
            if (PRESENT(var_2))  write(33, '(E15.7\)') var_2(i)
            if (PRESENT(var_3))  write(33, '(E15.7\)') var_3(i)
            if (PRESENT(var_4))  write(33, '(E15.7\)') var_4(i)
            if (PRESENT(var_5))  write(33, '(E15.7\)') var_5(i)
            if (PRESENT(var_6))  write(33, '(E15.7\)') var_6(i)
            if (PRESENT(var_7))  write(33, '(E15.7\)') var_7(i)
            if (PRESENT(var_8))  write(33, '(E15.7\)') var_8(i)
            if (PRESENT(var_9))  write(33, '(E15.7\)') var_9(i)

            write(33, *)
        end do
        
        close(33)
        
        return
    end subroutine output_tecplot_line
    !====
    
    !* 输出Tecplot二维云图数据
    !* 这里 X 是 X 坐标,Y 是 Y 坐标.
    !* 其中,var_2 至 var_9 是可选的,即最多可以输出9个云图.
    subroutine output_tecplot_2D( file_name, &
        X_name, X, Y_name, Y,  &
        var_1_name, var_1, var_2_name, var_2,  &
        var_3_name, var_3, var_4_name, var_4,  &
        var_5_name, var_5, var_6_name, var_6,  &
        var_7_name, var_7, var_8_name, var_8,  &
        var_9_name, var_9 )
    implicit none
        character(len=*), intent(in) :: file_name
        character(len=*), intent(in) :: X_name, Y_name, var_1_name
        real(PRECISION),  dimension(:,:), intent(in) :: X, Y, var_1
        character(len=*), optional, intent(in) :: &
            var_2_name, var_3_name,               &
            var_4_name, var_5_name, var_6_name,   &
            var_7_name, var_8_name, var_9_name
        real(PRECISION), dimension(:,:), optional, intent(in) :: &
            var_2, var_3, var_4, var_5,  &
            var_6, var_7, var_8, var_9

        character(len=300) :: var_name_list 
        character(len=100) :: var_count_list
        character(len=20) :: i_count_to_string, j_count_to_string 
        integer :: var_shape(2), i, j
        
        var_shape = SHAPE(X)
        
        var_name_list = 'variables="' // TRIM(ADJUSTL(X_name)) // &
            '","' // TRIM(ADJUSTL(Y_name)) // '","' //            &
            TRIM(ADJUSTL(var_1_name)) // '"'
        
        if (PRESENT(var_2_name)) then
            var_name_list = TRIM(ADJUSTL(var_name_list)) // ',"' // &
                TRIM(ADJUSTL(var_2_name)) // '"'
        end if
        if (PRESENT(var_3_name)) then
            var_name_list = TRIM(ADJUSTL(var_name_list)) // ',"' // &
                TRIM(ADJUSTL(var_3_name)) // '"'
        end if
        if (PRESENT(var_4_name)) then
            var_name_list = TRIM(ADJUSTL(var_name_list)) // ',"' // &
                TRIM(ADJUSTL(var_4_name)) // '"'
        end if
        if (PRESENT(var_5_name)) then
            var_name_list = TRIM(ADJUSTL(var_name_list)) // ',"' // &
                TRIM(ADJUSTL(var_5_name)) // '"'
        end if
        if (PRESENT(var_6_name)) then
            var_name_list = TRIM(ADJUSTL(var_name_list)) // ',"' // &
                TRIM(ADJUSTL(var_6_name)) // '"'
        end if
        if (PRESENT(var_7_name)) then
            var_name_list = TRIM(ADJUSTL(var_name_list)) // ',"' // &
                TRIM(ADJUSTL(var_7_name)) // '"'
        end if
        if (PRESENT(var_8_name)) then
            var_name_list = TRIM(ADJUSTL(var_name_list)) // ',"' // &
                TRIM(ADJUSTL(var_8_name)) // '"'
        end if
        if (PRESENT(var_9_name)) then
            var_name_list = TRIM(ADJUSTL(var_name_list)) // ',"' // &
                TRIM(ADJUSTL(var_9_name)) // '"'
        end if
        
        write(i_count_to_string, *)  var_shape(1)
        write(j_count_to_string, *)  var_shape(2)
        
        var_count_list = 'zone i = ' // &
            TRIM(ADJUSTL(i_count_to_string)) // ', j = ' // &
            TRIM(ADJUSTL(j_count_to_string))
        
        open(unit=33, file=file_name, form='formatted', status='replace')
        
        write(33, *) 'title="By SUBROUTINE output_tecplot_line"'    
        write(33, *) TRIM(ADJUSTL(var_name_list))
        write(33, *) TRIM(ADJUSTL(var_count_list))
    
        do j=1, var_shape(2)
            do i=1, var_shape(1) 
                write(33, '(E15.7, E15.7, E15.7\)') &
                    X(i, j), Y(i, j), var_1(i, j)
           
                if (PRESENT(var_2))  write(33, '(E15.7\)') var_2(i, j)
                if (PRESENT(var_3))  write(33, '(E15.7\)') var_3(i, j)
                if (PRESENT(var_4))  write(33, '(E15.7\)') var_4(i, j)
                if (PRESENT(var_5))  write(33, '(E15.7\)') var_5(i, j)
                if (PRESENT(var_6))  write(33, '(E15.7\)') var_6(i, j)
                if (PRESENT(var_7))  write(33, '(E15.7\)') var_7(i, j)
                if (PRESENT(var_8))  write(33, '(E15.7\)') var_8(i, j)
                if (PRESENT(var_9))  write(33, '(E15.7\)') var_9(i, j)
            
                write(33, *)
            end do
        end do
        
        return
    end subroutine output_tecplot_2D
    !====
    
    
    subroutine test_output_tecplot_line()
    implicit none
        real(PRECISION), dimension(:), allocatable :: &
            X, Y_sin, Y_cos, Y_sqrt, Y_sinh, Y_tanh, Y_exp
            
        integer :: x_count = 401, i
        real(PRECISION) :: dx
        
        allocate( X(x_count) )
        allocate( Y_sin(x_count) )
        allocate( Y_cos(x_count) )
        allocate( Y_sqrt(x_count) )
        allocate( Y_sinh(x_count) )
        allocate( Y_tanh(x_count) )
        allocate( Y_exp(x_count) )
        
        dx = 0.01
        do i=1, x_count
            X(i) = -2 + dx * (i - 1)
            Y_sin(i) = SIN(X(i))
            Y_cos(i) = COS(X(i))
            Y_sqrt(i) = SQRT(ABS(X(i)))
            Y_sinh(i) = SINH(X(i))
            Y_tanh(i) = TANH(X(i))
            Y_exp(i) = EXP(X(i))
        end do
        
        call output_tecplot_line(                   &
            './test_output_tecplot_line.plt',       &
            'X', X, 'Y_sin', Y_sin, 'Y_cos', Y_cos, &
            'Y_sqrt', Y_sqrt, 'Y_sinh', Y_sinh,     &
            'Y_tanh', Y_tanh, 'Y_exp', Y_exp )
    
        deallocate( X )
        deallocate( Y_sin )
        deallocate( Y_cos )
        deallocate( Y_sqrt )
        deallocate( Y_sinh )
        deallocate( Y_tanh )
        deallocate( Y_exp )
        
        return
    end subroutine test_output_tecplot_line
    
    
    subroutine test_output_tecplot_2D()
    implicit none
        real(PRECISION), dimension(:, :), allocatable :: &
            X, Y, Z_sin, Z_cos, Z_sqrt, Z_sinh, Z_tanh, Z_exp
            
        integer :: x_count = 401, y_count = 401
        integer :: i, j
        real(PRECISION) :: dx, dy
        
        allocate( X(x_count, y_count) )
        allocate( Y(x_count, y_count) )
        allocate( Z_sin(x_count, y_count) )
        allocate( Z_cos(x_count, y_count) )
        allocate( Z_sqrt(x_count, y_count) )
        allocate( Z_sinh(x_count, y_count) )
        allocate( Z_tanh(x_count, y_count) )
        allocate( Z_exp(x_count, y_count) )
        
        dx = 0.01
        dy = 0.01
        do j=1, y_count
            do i=1, x_count
                X(i, j) = dx * (i - 1)
                Y(i, j) = dy * (j - 1)
                Z_sin(i, j) = SIN(X(i,j) + Y(i,j))
                Z_cos(i, j) = COS(X(i,j) + Y(i,j))
                Z_sqrt(i, j) = SQRT(ABS(X(i,j) + Y(i,j)))
                Z_sinh(i, j) = SINH(X(i,j) + Y(i,j))
                Z_tanh(i, j) = TANH(X(i,j) + Y(i,j))
                Z_exp(i, j) = EXP(X(i,j) + Y(i,j))
            end do  
        end do
        
        call output_tecplot_2D(                 &
            './test_output_tecplot_2D.plt',     &
            'X', X, 'Y', Y, 'Z_sin', Z_sin,     & 
            'Z_cos', Z_cos, 'Z_sqrt', Z_sqrt,   & 
            'Z_sinh', Z_sinh, 'Z_tanh', Z_tanh, & 
            'Z_exp', Z_exp )
    
        deallocate( X )
        deallocate( Y )
        deallocate( Z_sin )
        deallocate( Z_cos )
        deallocate( Z_sqrt )
        deallocate( Z_sinh )
        deallocate( Z_tanh )
        deallocate( Z_exp )
        
        return
    end subroutine test_output_tecplot_2D
 
end module mod_Tools
PROGRAM MAIN
use mod_Tools
implicit none

    call test_output_tecplot_line()
    call test_output_tecplot_2D()
    
END PROGRAM

相关文章

  • Fortran利用optional参数输出不定数量的曲线数据或云

    在前面的博客中,使用Python实现了一些工具函数,可以十分便利的输出Tecplot格式的曲线和二维云图数据,在本...

  • OpenSSL命令生成椭圆曲线密钥

    使用OpenSSL生成椭圆曲线密钥 生成secp256k1椭圆曲线参数 输出类似 生成椭圆曲线密钥 输出类似 解析...

  • C语言可变参数实现

    一.如果我自己来实现printf printf是可变参数的典型列子,他接受一个格式化字符串和不定数量的输出参数,函...

  • Java学习 Day7

    1.动态参数(不定长参数): 只能作为方法的参数。参数的个数不定。 语法:数据类型...变量名; (1)不定长参数...

  • 二维数组

    1.动态参数(不定长参数): 只能作为方法的参数。参数的个数不定。 语法:数据类型...变量名; (1)不定长参数...

  • golang不定长参数问题

    golang不定长参数问题 一般函数的参数都是定长的,但是有一些参数可以传入不定数量的参数,golang 语言也有...

  • php中的输出

    | 使用 | 所属 | 返回值 | 参数类型 | 参数数量 | 输出结果 | 结果可捕获| 备注 || -----...

  • 函数

    参数 必备参数 关键字参数 默认参数 不定长参数 必备参数 必备参数须以正确的顺序传入函数。调用时的数量必须和声明...

  • 如何阐述产品卖点和好处

    如何阐述产品卖点 利用精准的数据,制造数量多的效果 从产品规格参数入手 从生产流程入手 从使用场景入手 利用案例证...

  • Python函数中的*、*args、**kwargs

    ==用法1:不定长参数== 当函数需要的参数数量不确定的时候,可以使用args 和 kwargs ,所有的位置参数...

网友评论

      本文标题:Fortran利用optional参数输出不定数量的曲线数据或云

      本文链接:https://www.haomeiwen.com/subject/agrseftx.html