1

C++ アプリケーションから Fortran 入力ファイル内のさまざまな変数の値を簡単に変更する方法について、誰かがアドバイスしてくれることを期待していました。

Fortran で記述されたモデルがありますが、モデルをループで実行する C++ アプリケーションを記述していますが、各モデルの実行後にモデル パラメーターの値を変更しています。

アドバイスをいただければ幸いです。

ありがとう!

    .Pnd file Subbasin: 1 7/26/2012 12:00:00 AM ArcSWAT 2009.93.7
Pond inputs:
           0.000    | PND_FR : Fraction of subbasin area that drains into ponds. The value for PND_FR should be between 0.0 and 1.0. If PND_FR = 1.0, the pond is at the outlet of the subbasin on the main channel
           0.000    | PND_PSA: Surface area of ponds when filled to principal spillway [ha]
           0.000    | PND_PVOL: Volume of water stored in ponds when filled to the principal spillway [104 m3]
           0.000    | PND_ESA: Surface area of ponds when filled to emergency spillway [ha]
           0.000    | PND_EVOL: Volume of water stored in ponds when filled to the emergency spillway [104 m3]
           0.000    | PND_VOL: Initial volume of water in ponds [104 m3]
           0.000    | PND_SED: Initial sediment concentration in pond water [mg/l]
           0.000    | PND_NSED: Normal sediment concentration in pond water [mg/l]
           0.000    | PND_K: Hydraulic conductivity through bottom of ponds [mm/hr].
               0    | IFLOD1: Beginning month of non-flood season
               0    | IFLOD2: Ending month of non-flood season
           0.000    | NDTARG: Number of days needed to reach target storage from current pond storage
          10.000    | PSETLP1: Phosphorus settling rate in pond for months IPND1 through IPND2 [m/year]
          10.000    | PSETLP2: Phosphorus settling rate in pond for months other than IPND1-IPND2 [m/year]
           5.500    | NSETLP1: Initial dissolved oxygen concentration in the reach [mg O2/l]
           5.500    | NSETLP2: Initial dissolved oxygen concentration in the reach [mg O2/l]
           1.000    | CHLAP: Chlorophyll a production coefficient for ponds [ ] 
           1.000    | SECCIP: Water clarity coefficient for ponds [m]
           0.000    | PND_NO3: Initial concentration of NO3-N in pond [mg N/l]
           0.000    | PND_SOLP: Initial concentration of soluble P in pond [mg P/L]
           0.000    | PND_ORGN: Initial concentration of organic N in pond [mg N/l]
           0.000    | PND_ORGP: Initial concentration of organic P in pond [mg P/l]
           5.000    | PND_D50: Median particle diameter of sediment [um]
               1    | IPND1: Beginning month of mid-year nutrient settling "season"
               1    | IPND2: Ending month of mid-year nutrient settling "season"
Wetland inputs:
           0.000    | WET_FR : Fraction of subbasin area that drains into wetlands
           0.000    | WET_NSA: Surface area of wetlands at normal water level [ha]
           0.000    | WET_NVOL: Volume of water stored in wetlands when filled to normal water level [104 m3] 
           0.000    | WET_MXSA: Surface area of wetlands at maximum water level [ha]
           0.000    | WET_MXVOL: Volume of water stored in wetlands when filled to maximum water level [104 m3]
           0.000    | WET_VOL: Initial volume of water in wetlands [104 m3]
           0.000    | WET_SED: Initial sediment concentration in wetland water [mg/l]
           0.000    | WET_NSED: Normal sediment concentration in wetland water [mg/l]
           0.000    | WET_K: Hydraulic conductivity of bottom of wetlands [mm/hr]
           0.000    | PSETLW1: Phosphorus settling rate in wetland for months IPND1 through IPND2 [m/year]
           0.000    | PSETLW2: Phosphorus settling rate in wetlands for months other than IPND1-IPND2 [m/year]
           0.000    | NSETLW1: Nitrogen settling rate in wetlands for months IPND1 through IPND2 [m/year]
           0.000    | NSETLW2: Nitrogen settling rate in wetlands for months other than IPND1-IPND2 [m/year]
           0.000    | CHLAW: Chlorophyll a production coefficient for wetlands [ ]
           0.000    | SECCIW: Water clarity coefficient for wetlands [m]
           0.000    | WET_NO3: Initial concentration of NO3-N in wetland [mg N/l]
           0.000    | WET_SOLP: Initial concentration of soluble P in wetland [mg P/l]
           0.000    | WET_ORGN: Initial concentration of organic N in wetland [mg N/l]
           0.000    | WET_ORGP: Initial concentration of organic P in wetland [mg P/l]
           0.000    | PNDEVCOEFF: Actual pond evaporation is equal to the potential evaporation times the pond evaporation coefficient
           0.000    | WETEVCOEFF: Actual wetland evaporation is equal to the potential evaporation times the wetland evaporation coefficient.
4

5 に答える 5

1

目的に合った Fortran の名前リスト I/O を調べてください。この機能に関する IBM XL Fortran の資料は、ここにあります。独自のコンパイラのドキュメントを必ず参照してください。それぞれのコンパイラには、標準にいくつかの風変わりなバリエーションがあるようです (または、標準が十分に厳密ではない可能性があります)。

于 2012-07-30T21:37:50.183 に答える
0

あなたがC++を要求したことは知っていますが、私は自分のコードと非常によく似た状況にあり、シェルスクリプトを使用しています。

sed s/var_name/value <template >input_fileテンプレート内のvar_nameの出現箇所を変更するために使用します。私のファイル形式はこれを簡単にするように設定されていますが、sedは非常に柔軟なツールであり、あなたが求めていることを実行できると確信しています。ここにチュートリアルがあります。

その設定で、これらのsedコマンドとアプリケーション呼び出しをループするスクリプトを作成します。これは魅力のように機能します。さらに、少しのスクリプトを学ぶことは、それらすべての異なる実行から生成されたデータのソートなど、他のすべての種類のタスクを処理するのに役立ちます。

于 2012-07-31T05:00:01.000 に答える
0

20 バイトの ASCII フィールド内に数字があるようにツールします。シンボル、および「:」で終了する変数名。行は可変長です。だから、このようなもの:

// ./bin/bin/g++ -o hackpond hackpond.cpp

#include <fstream>
#include <string>
#include <cstddef>
#include <sstream>
#include <iomanip>

int
main()
{
    std::string variable_you_want = "PND_SOLP";
    std::string line;
    std::fstream pond("test.pnd");
    std::getline(pond, line);
    while (! pond.eof())
    {
    std::string value, variable;
    std::size_t loc = pond.tellg();
    std::getline(pond, line);
        if (line == "Pond inputs:")
            continue;
        else if (line == "Wetland inputs:")
            continue;
        std::ostringstream hack();
        value = line.substr(0, 20);
        std::size_t colon = line.find(':', 20);
        if (colon == std::string::npos)
            continue;
        variable = line.substr(22, colon - 22);
    if (variable == variable_you_want)
    {
            double new_value = 666.66;
            pond.seekp(loc);
            std::ostringstream thing;
            thing << std::setw(20) << new_value;
            pond.write(thing.str().c_str(), thing.str().length());
    }
        if (pond.eof())
            break;
    }
}

基本的な考え方は、1. 変更したい行の開始位置をメモし ( tellg)、2. 新しい値を含む 20 文字の文字列を作成し、3. その行の保存された開始位置に移動し ( seekp)、新しいチャンク。

于 2012-07-31T02:13:50.613 に答える
0

私は FORTRAN の専門家ではありませんが、変更が必要な各パラメーターに対してコマンド ライン引数を使用することを検討すると思います。ただし、これは、FORTRAN 2003 を使用している場合にのみ可能です。FORTRAN 95 は、現在も使用されている最も一般的な FORTRAN 標準の 1 つだと思いますが、確かなことはわかりません。FORTRAN の実装がコマンド ライン引数をサポートしている場合は、このサイトがそれらの使用方法を理解するのに役立つかどうかを確認してください: http://fortranwiki.org/fortran/show/Command-line+arguments そうでない場合は、FORTRAN プログラムこれらの値をテキスト ファイルから読み取ります。本当に厄介なことをしたい場合は、C++ プログラムに実際に FORTRAN ソース ファイルを変更させ、実行が必要になるたびに再コンパイルさせることができます。それを行う場合は、最初にバックアップしてください。幸運を。

于 2012-07-30T18:42:43.413 に答える
0

私があなたの問題を理解している限り、C++ でのテキスト編集が必要なだけです。最も簡単な方法は、C++ コードにすべてのパラメーターを含め、そのコードが実行ごとに完全なテキスト ファイルを書き込むようにすることだと思います。それをしたくない場合は、cpptemplatetengなどのテンプレート ツールボックスを使用することをお勧めしますが、C++ で使用できるテンプレート エンジンは他にもたくさんあり、ユース ケースに適している可能性があります。

于 2012-07-30T23:25:40.607 に答える