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

我不是 FORTRAN 方面的专家,但我想我会考虑为每个需要更改的参数使用命令行参数。但是,这只有在您使用 FORTRAN 2003 时才有可能。我认为 FORTRAN 95 仍然是最常用的 FORTRAN 标准之一,但我不确定这一点。如果您的 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 回答
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起始位置(seekp新块。

于 2012-07-31T02:13:50.613 回答
0

我知道您要求使用 C++,但我的代码有非常相似的情况,并且我使用 shell 脚本。

sed s/var_name/value <template >input_file用来更改模板中 var_name 的出现。我的文件格式设置为简化此操作,但 sed 是一个超级灵活的工具,我相信它可以满足您的要求。这里有一个教程。

有了这个设置,我编写了一个脚本来循环这些sed命令和应用程序调用。这就像一个魅力。此外,学习一点脚本将帮助您处理各种其他任务,例如对所有这些不同运行生成的数据进行排序。

于 2012-07-31T05:00:01.000 回答