2017-03-27 9 views
0

私はFortranプロジェクトに問題があり、おそらくあなたが私を助けることができると考えました。変数をFortranの別のファイルでどのように使用しますか?

私はIDEとしてコードブロックを使用しています。そこにプロジェクトを作ることができるので、2つのファイルを含むプロジェクトを作成しました:メインプログラムとfuction(私は何を使うべきか分かりません。おそらくfuctionとは異なる)。

だから私は、.txtから値を読み取り、それらを実数として保存し、すべてがうまくいきます。私がしたいのは、ファイルmainから、この関数を呼び出して、私が自分の関数で収集したデータをmainに保存して、メインがよりきれいになるようにします。

どうすればいいですか?あなたが望むなら私は全体のスクリプトを投稿することができますが、それはそれをもっと追加するとは思わない。

EDIT:あなたが尋ねたように、ここでそれは(ノーカット)です:

program main 

    ! Variables 
    real :: d1, r1, r2, a, teta, freq, Dt, mu, g0, r_t, height, r, omega, H, lx, ly, lz, m_c0, & 
     Jx, Jy, Jz, gmax, I_s, K, Jx0, Jy0, Jz0, Vmin, tsp_0, Fmax, Isp, c1, n, F, DV, tfin, cont, Tmax 
    real :: data_input 

    ! Call the funcion 
    data_input=data_module(d1, r1, r2, a, teta, freq, Dt, mu, g0, r_t, height, r, omega, H, lx, ly, lz, m_c0, & 
      Jx, Jy, Jz, gmax, I_s, K, Jx0, Jy0, Jz0, Vmin, tsp_0, Fmax, Isp, c1, n, F, DV, tfin, cont, Tmax) 

    ! Error 
    if (data_input/=1) then 
     print*, 'ERROR: data_module did not work' 
    end if 

    !Just to show it 
    print*,'After' 
    print*, d1, r1, r2, a, teta, freq, Dt, mu, g0, r_t, height, r, omega, H, lx, ly, lz, m_c0, & 
     Jx, Jy, Jz, gmax, I_s, K, Jx0, Jy0, Jz0, Vmin, tsp_0, Fmax, Isp, c1, n, F, DV, tfin, cont, Tmax 
end program main 

real function data_module() 

    ! Variables 
    implicit none 
    integer :: flag_read=0, w_int, d_int 
    real:: coefficient, d1, r1, r2, a, teta, freq, Dt, mu, g0, r_t, height, r, omega, H, lx, ly, lz, m_c0, & 
      Jx, Jy, Jz, gmax, I_s, K, Jx0, Jy0, Jz0, Vmin, tsp_0, Fmax, Isp, c1, n, F, DV, tfin, cont, Tmax 
    character (LEN=35) :: starting_string, name*15, coefficient_string*20, w_string, d_string, number_format 
    character :: w*2, d 

    ! Open file 
    open (11, file = 'Data.txt', status = 'old', access = 'sequential', form = 'formatted') 

    ! Read a new line for every iteration 
    sentence_reader: do while (flag_read==0) 
    read (11, fmt='(A)', iostat = flag_read) starting_string 

    ! Error 
    if (flag_read>0)then 
     print*, 'ERROR: could not read data' 
     stop 
    end if 

    ! Skip useless lines 
    if (starting_string(1:1)=='%' .OR. starting_string(1:1)==' ') then 
     cycle 
    end if 

    ! Exit when you're done 
    if (flag_read<0)then 
     exit sentence_reader 
    end if 

    ! Just stuff to prepare it 
    name=trim(starting_string(1:index(starting_string, '=')-1)) 
    coefficient_string=trim(adjustl(starting_string(index(starting_string, '=')+1:index(starting_string,';')-1))) 
    if (scan(coefficient_string,'E')/=0) then 
     w_string=coefficient_string 
     w_int=len_trim(w_string) 
     write(w, '(BN,I2)') w_int 
     d_string=coefficient_string(index(coefficient_string, '.')+1:index(coefficient_string, 'E')-1) 
     d_int=len_trim(d_string) 
     write(d, '(BN,I1)') d_int 

     !All togheter 
     number_format='(BN,F' // trim(w) // '.' // d // ')' 
    else 
     w_string=coefficient_string 
     w_int=len_trim(w_string) 
     write(w, '(BN,I1)') w_int 
     d_string=coefficient_string(index(coefficient_string, '.')+1:len_trim(coefficient_string)) 
     d_int=len_trim(d_string) 
     write(d, '(BN,I1)') d_int 
     number_format='(BN,F' // trim(w) // '.' // d // ')' 

    end if 

    ! Read the number 
    read(coefficient_string,number_format) coefficient 


    ! Save where it's needed (is there an easier way to do it?) 
    select case (name) 
     case ('d1') 
      d1=coefficient 
     case ('r1') 
      r1=coefficient 
     case ('r2') 
      r2=coefficient 
     case ('a') 
      exit 
     case ('teta') 
      exit 
     case ('freq') 
      freq=coefficient 
     case ('Dt') 
      exit 
     case ('mu') 
      mu=coefficient 
     case ('g0') 
      g0=coefficient 
     case ('r_t') 
      r_t=coefficient 
     case ('height') 
      height=coefficient 
     case ('lx') 
      lx=coefficient 
     case ('ly') 
      ly=coefficient 
     case ('lz') 
      lz=coefficient 
     case ('m_c0') 
      m_c0=coefficient 
     case ('Jx') 
      Jx=coefficient 
     case ('Jy') 
      Jy=coefficient 
     case ('Jz') 
      Jz=coefficient 
     case ('gmax') 
      gmax=coefficient 
     case ('I_s') 
      I_s=coefficient 
     case ('K') 
      K=coefficient 
     case ('Vmin') 
      Vmin=coefficient 
     case ('tsp_0') 
      tsp_0=coefficient 
     case ('Fmax') 
      Fmax=coefficient 
     case ('Isp') 
      Isp=coefficient 
     case ('n') 
      n=coefficient 
     case ('tfin') 
      tfin=coefficient 
     case ('cont') 
      cont=coefficient 
     case ('Tmax') 
      Tmax=coefficient 
     case default 
      print*, 'Variable ', name, ' is not recognized' 
    end select 


    end do sentence_reader 


    ! Other stuff I need 
    teta=atan((r1 - r2)/d1) 
    a=sqrt(d1**2 + (r1 - r2)**2) 
    Dt=1/freq 
    r=r_t + height 
    omega=(mu/(r**3))**0.5 
    H=(r*mu)**0.5 
    Jx0=Jx - I_s 
    Jy0=Jy - I_s 
    Jz0=Jz - I_s 
    c1=Isp*g0 
    F=n*Fmax 
    DV=(F/m_c0)*tsp_0 

    ! Shows that the function is correctly executed 
    data_module=1 
    print*,'Before' 
    print*, d1, r1, r2, a, teta, freq, Dt, mu, g0, r_t, height, r, omega, H, lx, ly, lz, m_c0, & 
     Jx, Jy, Jz, gmax, I_s, K, Jx0, Jy0, Jz0, Vmin, tsp_0, Fmax, Isp, c1, n, F, DV, tfin, cont, Tmax 

end function data_module 

PS。私はモジュールを知っていますが、オープンなものとそれ以外のものはすべて私がそれらを動かすことができませんでした。喜んで。

私がしたいのは、data_moduleで収集したデータd1、r1、eccをmainに渡してメインに保存することですが、このようにすると保存されません(実行するとあなたが「前」にそれらを印刷し、あなたがそれらを印刷するとき、すべてがあなたがすべてゼロになった「後」、結構です。

+0

はあなたのコードを表示します。あなたが何を記述しているかは、私にはあまり明確ではありません。あなたの関数は何を返すのですか?それは関数かサブルーチンか?あなたはモジュールを知っていますか?(http://stackoverflow.com/documentation/fortran/1139/usage-of-modules#t=20170327191803339714) –

+0

変数を関数defの引数として与える必要があります。 'real function data_module (d1、r1、r2、...) '(実際に'モジュール 'を使用した場合、この種の間違いはかなり明確なエラーメッセージを与えるでしょう) – agentp

+0

agentp、私は5回試みました。今私は再びそれを試して、それは魔法のように働いた。それは奇妙ですが、ありがとうございます。私はちょっと馬鹿だと思っていますが、インターネットで探している人を助けることができれば幸いです。私はしばらくの間探して、それについて何も見つけませんでした。 – TheJasonKilljoy

答えて

1

さて、私が気づくいくつかのものがある。

  1. あなたfunction

    はタイプrealであり、あなたがコメントに "関数が正しく実行されたことを表示する"と書いたように、1(整数)に設定するだけです。 それはuncではありませんommonは、プロシージャを正しく実行するかどうかを示す値を返すようにしますが、通常はエラーコードで、エラーが発生せずすべてがうまくいったことを意味します。 また、realの代わりにintegerという関数を宣言することもできます。そのような場合には整数が適しています。

  2. 実際の質問について:呼び出し元のルーチンに複数の値を渡したい場合は、intent(out)のダミー変数を宣言することをお勧めします。次の例を参照してください。

    integer function test_output(outdata) 
        integer, intent(out) :: outdata(10) 
        integer :: i 
        outdata = (/(i, i=1, 10)/) 
        ! All worked well 
        test_output = 0 
        return 
    end function test_output 
    
  3. モジュールは移動方法です。ここではモジュールに上記の機能を組み込む方法については非常に限られた例であり、プログラムにそのモジュールを使用して:

    module mod_test 
        implicit none 
        ! Here you can place variables that should be available 
        ! to any procedure using this module 
    contains 
        ! Here you can place all the procedures (functions and 
        ! subroutines) 
        integer function test_output(outdata) 
         integer, intent(out) :: outdata(10) 
         integer :: i 
         outdata = (/(i, i=1, 10)/) 
         ! All worked well 
         test_output = 0 
         return 
        end function test_output 
    end module mod_test 
    
    program test 
        ! The 'USE' statement is the only thing that needs to be 
        ! *ahead* of the 'implicit none' 
        use mod_test 
        implicit none 
        integer :: mydata(10) ! The variable that will contain the data 
              ! from the function 
        integer :: status  ! The variable that will contain the error 
              ! code. 
        status = test_output(mydata) 
    
        if (status == 0) then 
         print*, mydata 
        end if 
    
    end program test 
    

    モジュールが別のソースファイル内にある場合、あなたは彼らにこの方法をコンパイルする必要があります( )あなたがgfortranを使用することを想定:

    $ gfortran -c -o mod_test.o mod_test.f90 
    $ gfortran -c -o test.o test.f90 
    $ gfortran -o test test.o mod_test.o 
    
+0

マイナーな追加ポイント - エラーに設定されない場合はエラーコードを返すことに意味がありません値。 – SteveES

+0

真実ですが、自分の例でエラーコード(またはそれに似たもの)を使用していたので、そのコードがどのように含まれるかを示したかったのです。また、ある時点で近い将来、何らかのエラーチェックを追加することが合理的に確かであれば、あとで多くのコードを変更する必要がないため、役立ちます。 – chw21

関連する問題