2

我正在用 C++ 为 CFD 软件 OpenFOAM 编写一个插件。对于分析的每个时间步,我的代码将从模型中的每个单元(>100k 单元)读取信息。我有一个名为 C 的双精度列表列表,它在第一个时间步中用零初始化,并在下一个时间步中发生变化,但是大小保持不变。

我的问题是第一个时间步骤中列表的初始化需要太多时间。在接下来的时间步骤中,我可以轻松地遍历列表中的所有元素并对这些值执行一些计算并再次存储它们。然而,在第一个时间步骤中,我有一个大小为 0 的空列表,这意味着我必须附加零来初始化它。我确实知道列表的最终大小,所以我可以轻松编写

Foam::List<Foam::List<double>> C (size,0.0);

在第一步中,我的问题将得到解决(这是 OpenFOAM 特定的列表类https://www.openfoam.com/documentation/guides/latest/api/classFoam_1_1List.html

但是,如果我想定义我的列表列表一次,然后在所有时间步骤中使用它,我需要在头文件中定义它。在头文件中我不知道大小,这意味着我将它定义为

Foam::List<Foam::List<double>> C;

在头文件中,然后在 C 文件中用零填充它。这是我的问题 -如何在 C 文件中初始化已定义的列表列表,其中包含零?

如果这是 C#,我可以将它分成两行

List<List<double>> C;
C = new List<List<double>>(size);

并在头文件中写入第一行,在 C 文件中写入第二行(据我所知)。如何在 C++ 中做类似的事情?

非常感谢您对此的帮助。

谢谢,大卫

4

3 回答 3

2

假设Foam::List<Foam::List<double>> C;在您的.h-file 中定义并且size是一个包含两种大小的列表的两元素数组,您应该能够:

C=Foam::List<Foam::list<double>>(size[0],Foam::List<double>(size[1],0));

我认为您应该知道的另一件事是,new在 c++ 中不应将关键字用于此类事情。关键字new在堆而不是堆栈上分配内存。每当您使用new时,您还必须在delete以后使用以避免内存泄漏。通常这是通过new在 CTOR 类和deleteDTOR 类中使用来完成的。正如@MaxLanghof 在现代C++ 中正确指出的那样,您应该始终更喜欢使用智能指针,如std::shared_pointer,std::unique_pointerstd::weak_pointer使用newanddelete

于 2020-01-08T09:56:38.563 回答
1

由于要初始化的变量是类的成员,因此初始化它的正常方法是使用构造函数的成员初始化器列表:

头文件:

class MyPlugIn
{
public:
  MyPlugIn(int listSize); // constructor
protected:
  Foam::List<Foam::List<double>> C;
};

源文件:

MyPlugIn(int listSize) : C(listSize)
{
}

这当然需要在MyPlugIn创建时知道必要的大小。如果不是这种情况,使用 Max 答案中所示的复制/移动赋值运算符也是一种解决方案。

于 2020-01-08T10:27:12.630 回答
0

如果它是一个普通列表,您可以使用其中的任何一个,具体取决于您是否需要重新调整大小或者它是否已经具有正确的大小:

mylist.resize(size, Zero);
mylist = Zero;

如果您有一个列表列表,我们将假设它们具有正确的大小并将它们归零:

for (auto &lst : mylistlist)
{
    lst = Zero;
}

如果您将来需要,我会使用Zero常量而不是0.0其他任何东西 - 它使含义清晰并且很好地适用于向量/张量和其他向量空间量。

于 2020-01-11T15:55:16.843 回答