From d76ecc3ff651eaa75ca57a90bb9bb9ba876e4e5b Mon Sep 17 00:00:00 2001 From: skf0558 Date: Thu, 27 Aug 2020 08:48:04 +0800 Subject: [PATCH 1/3] update 49 functions.md. --- 49 functions.md | 550 ++++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 538 insertions(+), 12 deletions(-) diff --git a/49 functions.md b/49 functions.md index 9c679da..f1f1930 100644 --- a/49 functions.md +++ b/49 functions.md @@ -1,34 +1,560 @@ + # Part VI 后处理 -​ 在OpenFOAM中有两种主要的后处理方法。首先,有一些工具在模拟完成后执行。这些工具处理模拟结果的写入数据。sample和paraView是这类的两个工具。 +​ 在**OpenFOAM**中,有两种主要的后处理方法。首先,有一些工具在模拟完成后执行。这些工具处理模拟结果的写入数据。**sample**和**paraView**是这类的两个工具。 ​ 除此之外,还有实时后处理。实时后处理是在生成模拟结果数据时执行某种操作。因此,实时后处理允许更精细的时间问题。函数对象,例如用于计算力或阻力系数,是一个实时后处理的示例。这种方法的最大缺点是,用户开始模拟之前,必须知道预期的后处理的步骤。有关实时后处理详细信息请看http://www.openfoam.com/features/runtime-postprocessing.php。 ## 49 functions -​ 一般来说,函数对象是以与函数类似的方式使用的对象。函数对象的这一主要优点是它们可以有一个永久的状态。此状态可用于存储数据(在“调用”函数对象之间)。一个非常有说服力的例子是OpenFOAM的函数对象 fieldAverage,它用于计算场的时均值。此函数对象需要在每次计算时间步长时更新自身,并且当前的时均场需要在fieldAverage的“调用”之间保留。 +​ 一般来说,函数对象是以与函数类似的方式使用的对象。函数对象的这一主要优点是它们可以有一个永久的状态。此状态可用于存储数据(在“调用”函数对象之间)。一个非常有说服力的例子是**OpenFOAM**的函数对象 **fieldAverage**,它用于计算场的时均值。此函数对象需要在每次计算时间步长时更新自身,并且当前的时均场需要在**fieldAverage**的“调用”之间保留。 -​ 函数对象通常用于一个特定的目的,例如计算场量的时均值。因此,在OpenFOAM中可用的功能对象数量很多,而且在持续增加。下面列出一些,让人了解OpenFOAM功能对象涵盖任务之广泛: +​ 函数对象通常用于一个特定的目的,例如计算场量的时均值。因此,在**OpenFOAM**中可用的函数对象数量很多,而且在持续增加。下面列出一些,让人了解**OpenFOAM**函数对象涵盖任务之广泛: **fieldAverage** 计算场量的时均值 -fieldValue系列 计算场量(或其他操作)的空间平均值 +**fieldValue**系列 计算场量(或其他操作)的空间平均值 -forces 计算物体(表面)上的力 +**forces** 计算物体(表面)上的力 -forceCoeffs 计算力的系数,例如阻力、升力和扭矩 +**forceCoeffs** 计算力的系数,例如阻力、升力和扭矩 -sampledSet 保存某个区域的场量的值,例如沿一条直线 +**sampledSet** 保存某个区域的场量的值,例如沿一条直线 -probes 在某些点保存场量值 +**probes** 在某些点保存场量值 -streamLine 计算流线 +**streamLine** 计算流线 -scalarTransport 求解被动标量输运方程 +**scalarTransport** 求解被动标量输运方程 -codedFunctionObject 在一个不是从零头开始的框架中实现自己的函数对象 +**codedFunctionObject** 在一个不是从零头开始的框架中实现自己的函数对象 -上面的列表只是可用功能的一小部分。所有的可用功能函数资料,查看OpenFOAM的源码[141]。 +上面的列表只是可用功能的一小部分。所有的可用函数对象资料,查看OpenFOAM的源码[141]。 ## 49.1保持最新 +​ 使用函数对象进行实时后处理是OpenFOAM的一个特性,它在应用程序和日常使用非常多,这与mesh类的内部工作方式不同。因此,函数对象更受开发者关注的是添加新的函数对象,扩展已有的函数对象,或重新组织和重命名现有函数对象。 + +​ 前两点(添加和扩展)显然是对用户有利,而后一点(重组)在减少代码重复或便于维护方面,最可能对开发人员有利。函数对象的重组可能和重命名同步进行[142]。在这种情况下,你可能需要修改函数对象定义,当将你的算例迁移到新的[143]版本时。 + +​ 除了使用最新版本的OpenFOAM的所有其他好处外,尤其是在函数对象,如果OpenFOAM的版本已经包含了一个实现你所需功能的函数对象,您就可以不必自己开发一个函数对象。 + +## 49.2 定义 + +​ 函数对象在文件**controlDict**中定义。在那里创建一个包含所有必要的信息的函数字典。列表320显示了这样一个定义的基本结构。 + +​ 每个函数都有一个名称。在列表320中,这个名称在**NAME**占位符处被声明。这个名称也是**OpenFOAM**在算例目录中创建的文件夹的名称。在那里,存储所有由函数对象产生的数据。 + +​ 每个函数对象也有一个类型。需要在TYPE占位符的位置指定此类型。类型必须来自可用函数的列表。要了解哪些函数可用,则可以使用*banana-trick*[144]。列表321显示了由*banana-trick*引起的错误消息。 + +​ 占位符**LIBRARY**标记需要输入库名称的位置。函数对象不是一个单独可执行的程序。它只是一个供其他程序使用的库。在在我们的例子中,函数对象由解算器调用。因此,函数对象不会编译成可执行的。编译器在编译函数对象时创建库。此库包含机器可读形式的函数。 + + 关键字**enabled**是可选的。使用此关键字函数,对象可以从执行中排除。 + +``` +functions +{ + NAME + { + type TYPE ; + functionObjectLibs (" LIBRARY "); + enabled true; + /* + Definition + */ + } +} +``` + +列表320:文件**controlDict**中函数对象的定义 + +``` +--> FOAM FATAL ERROR : +Unknown function type banana +Valid functions are : +13 +( +cellSource +faceSource +fieldAverage +fieldCoordinateSystemTransform +fieldMinMax +nearWallFields +patchProbes +probes +readFields +sets +streamLine +surfaceInterpolateFields +surfaces +) +``` + +列表321 :*banana-trick*的输出;应用于关键字**type** + +## 49.3 控制 + +​ 所有函数对象或多或少都与基类**functionObject**直接相关,后者在文件**$FOAM_SRC/OpenFOAM/db/functionObjects/functionObject/functionObject.H**中定义,这个类定义 + +所有函数对象的最小公共行为。因此,学习这个类,正如它应用于所有函数对象一样,我们也许会有回报。 + +### 49.3.1 时间控制 + +**函数对象的阶段** + +​ 一些**OpenFOAM**函数对象可能有一些需要更新的内部状态,而另一些对象有一些内部状态需要更新时,可能不需要内部状态。简单的函数对象,后一类情况,例如,函数对象**fieldValue**族中的函数对象**surfaceRegion**,只需将指定**patches**程序中的数据写入磁盘情况,将选定的数据写入磁盘可能会失败。这只是在写入时才执行。 + +​ 另一方面,函数对象可能需要从结果数据中计算数据,因此需要一个内部状态,例如,**fieldAverage**函数对象需要为连续更新时均值,即使它不太频繁地将它们写入磁盘。 + +​ 因此,函数对象的操作阶段分为*执行*(用于更新其内部状态)和*写入*(用于写入数据,并计算要写入的数据,这不是内部状态) + +**执行和写控制** + +​ 何时写入的函数对象的属性是**writeControl**和**writeInterval**,在**OpenFOAM**旧版本中,这些属性是**outputControl**和**outpunterval**。它们控制从函数对象写入磁盘数据的时间和频率。 + +​ 存在一对相似的控件(**executeControl**和**executeInterval**)来控制函数对象的执行,即内部状态更新。 + +​ 请注意,当能够使用**writeInterval** **adjustableRunTime**设置时;对于函数对象的写入间隔,一般来说,我们需要确保对模拟进行相同的设置。如果模拟使用设置**writeInterval** **runTime**,则函数对象的设置被否决。 + +**启用** + +​ 启用标志控制是否启用函数对象。这需要一个布尔值和控制是否执行函数对象。这对测试或调试模拟算例可能很有用。此标志允许您在不从**controlDict** 中删除的情况下,定义和停止使用函数对象。从算例文件编辑的角度来看,这个标志的一个粗暴的替代方法是注释函数对象定义。但是,将标志从“开”改为“关”,或者相反,所需更少字符,相比更改为注释和取消注释[145]。 + +​ **timeStart**和**timeEnd**控制何时开始和何时停止使用函数对象。这些控件是可选的,在大多数情况下被省略。当省略时,默认行为是执行函数对象,从模拟开始直到模拟完成。事实上,默认值是一个负数,对于**timeStart**和**timeEnd**来说是个大得离谱的数字[146]。因此,在**timeStart**的默认值之前,不会启动任何可能的模拟,或者任何大于**timeEnd**的默认值。这样,一个简单的与当前时间进行比较就足够了,就不需要条件语句了。 + +### 49.3.2 区域控制 + +​ **region**关键字控制函数对象应用于哪个网格区域。只有一个网格区域时都可以省略,这种情况下说明网格区域是多余的。然而,在**OpenFOAM**中也有具有多个网格区域的,如共轭传热模拟。在这种情况下,当求解传热时有一个网格(区域)为流体区域,一个网格(区域)为的固体部分。在这种情况下,我们可以使用一个函数对象来记录流体和固体区域的平均温度。因此,我们指定两个函数对象来计算体积平均温度,但是,我们需要指定要为其执行函数对象的区域。 + +​ 负责选择要操作的网格区域的(抽象类[147])基类是**regionFunctionObject**。许多函数对象或多或少是直接从**regionFunctionObject**派生的。其中包括**fieldValues**系列的函数对象以及**fieldMinMax**和**fieldAverage**。 + +## 49.4 探针 + +​ 函数探针在空间中的指定点保存特定场量的值。列表322显示了一个探针函数对象定义的示例。 + +​ 此函数对象的类型为*probes*。函数对象的名称是probes1。此函数生成的数据存储在probes1目录中。此目录包含一个子目录。此子目录名称对应于模拟开始的时间。这样可以防止文件在某个时间点继续模拟时被覆盖。 + +​ 图112显示了模拟结束后的目录树。在那里,probes1文件夹包含一个名为0的子目录。这是模拟开始的时间。0文件夹包含文件p和U。 + +​ 关键字**outputControl**和**outputInterval**是可选的。正如他们的名字所示,他们控制着数据写入硬盘的方式。 + +​ 字段包含感兴趣场的名称。**probeLocations** 包含一系列点。计算这些点位置指定场的数据,并将其写入文件。文件名就是场名。列表322将生成两个文件。文件p包含所有位置的压力值,文件U将包含所有位置的速度值。 + +​ *probes*函数包含在文件中**libsampling.so**文件。 这些信息可以从教程获得。有关如何在教程中搜索特定信息的更多信息,请参见第66.3节。 + +``` +functions +{ + probes1 + { + type probes ; + functionObjectLibs (" libsampling .so "); + enabled true ; + outputControl timeStep ; + outputInterval 1; + fields + ( + p + U + ); + probeLocations + ( + ( 0.0254 0.0253 0 ) + ( 0.0508 0.0253 0 ) + ); + } +} +``` + +​ 列表322:**controlDict**文件中*probes*的定义 + + + + + +​ 图112: 模拟结束后目录树的一部分 + +### 49.4.1 陷阱 + +**区域外的探测位置** + +如果探针位置在域之外,OpenFOAM将发出警告消息并继续模拟。 + +``` +--> FOAM Warning : + From function findElements :: findElements ( const fvMesh &) + in file probes / probes .C at line 102 + Did not find location (0.075 0 0.48) in any cell. Skipping location. +``` + +​ 列表323:探针位于区域外 + +**未知和不存在的场** + +如果探测字典包含不存在要探测的字段,则不会警告或发布错误消息。OpenFOAM只是继续计算。如果字典中没有要探测的有效字段,则不会执行探测功能。因此,不会创建存储数据的文件夹。 + +**在动网格中使用探针** + +​ 当我们使用探针时,OpenFOAM会在网格中搜索包含指定探针位置的单元。更具体地说,它确定包含探针位置的单元的单元索引。因此,OpenFOAM可以很容易得到探测场的单元值。实际上,OpenFOAM中的一个场是一个值列表,而单元索引用于导航列表。 + +​ 然而,当我们使用移动网格时,与空间中某一点相关的单元索引,在时间上可能会发生变化,例如旋转网格区域内探测一个点时。因此,每次网格更新时,需要确保被探测的单元索引也被更新。 + +​ 在OpenFOAM中,探针有一个布尔标志(**fixedLocations**)来控制单元索引的更新,默认情况下,此标志设置为**true**,表示不需要更新。在下面列表324中,我们看到头文件**probes.C**中此标志的说明。 + +``` +// - Fixed locations , default = yes +// Note : set to false for moving mesh calations where locations +// should move with the mesh +bool fixedLocations_ ; +``` + +​ 列表324:在**probes.H**中**fixedLocations**布尔标志的描述 + +​ 使用移动网格时,将**fixedLocations**标志添加到**probesDict**中,如清单325所示下面。 + +``` +fields +( + ... +) +probeLocations +( + ... +) +// add this for cases using moving meshes +fixedLocations false ; +``` + +​ 列表325:使用带有动网格的探针时,向**probesDic**t添加**fixedLocations**标志 + +## 49.5 场平均 + +​ **fieldAverage**计算时均场。列表326显示一个函数已设置例子。 + +``` +functions +{ + fieldAverage1 + { + type fieldAverage ; + functionObjectLibs ( " libfieldFunctionObjects .so" ); + enabled true ; + outputControl outputTime ; + fields + ( + Ua + { + mean on; + prime2Mean off ; + base time ; + } + ); + } +} +``` + +​ 列表326:文件**controlDict**中*fieldAverage*函数对象的定义 + +​ **fieldAverage**函数对象可以提供一个平均窗口尺寸和名称来计算滑动平均。在这种情况下,生成的平均值场除了以场命名和加后缀**Mean**,还将窗口名作为文件名后缀。使用此功能,可以计算一个场的多个平均值。列表327显示了场**U.water**的两个平均值。 + +​ 如果没有指定窗口,**fieldAverage**从函数对象的开始时间计算平均值。这个结果场包含要平均的场的名称和后缀Mean。如果指定了一个窗口尺寸和窗口名称,则结果场的名称将窗口名称作为扩展名。 + +``` +U. water U. waterMean U. waterMean_w1 +``` + +​ 列表 327: **U. water**的多个平均值 + +## 49.6 面源faceSource + +### 49.6.1 平面上的平均 + +​ 面源从曲面(面)中提取数据。列表328显示了在一个切割平面上,场量的平均值如何设置。 + + + functions + { + fieldAverage1 + { + type fieldAverage ; + functionObjectLibs ("libfieldFunctionObjects.so" ); + enabled true ; + outputControl outputTime ; + // Output to log & file (true) or to file only + log true ; + + // Output field values as well + valueOutput false ; + + // Type of source : patch/faceZone/sampledSurface + source sampledSurface ; + + sampledSurfaceDict + { + // Sampling on triSurface + type cuttingPlane ; + planeType pointAndNormal ; + pointAndNormalDict + { + basePoint ( 0 0 0.3 ); + normalVector ( 0 0 1 ); + } + interpolate true ; + } + // Operation : areaAverage/sum/weightedAverage ... + operation areaAverage ; + fields + ( + alpha + ); + } + } + + +​ 列表328:在**controlDict**文件中定义一个*faceSource*对象 + +### 49.6.2计算边界上的体积流率 + +​ 列表329显示了一个函数对象的定义,该对象用于计算边界面上的体积流率。其中的关键点是定义权重场和使用求和运算。这个权重场是自动应用于后处理场的,不需要指定一个操作,如**weightedSum**。如果未定义权重场,则不使用权重场。 + +``` +functions +{ + faceIn + { + type faceSource ; + functionObjectLibs ("libfieldFunctionObjects.so"); + enabled true ; + outputControl timeStep ; + log true ; + valueOutput false ; + source patch ; + sourceName spargerInlet ; + surfaceFormat raw; + operation sum; + weightField alpha1; + + + fields + ( + phi1 + ); + } + +} +``` + +​ 列表239:在文件**controlDict**中定义一个*faceSource*对象 + +### 49.6.3 陷阱:valueOutput + +​ 选项**valueOutput**将采样曲面上的场量值写入磁盘。当**outputControl**设置为**timeStep**时,会使用巨大的磁盘空间。在这种情况下,每个时间步都会写入场量值。除非确实需要,否则应禁用选项**valueOutput**。 + +​ 图113显示了两个时间步写入磁盘后处理文件夹的内容。对于每个采样场,采样片上的场量值将写入磁盘的surface文件夹中的文件中。 + + + +​ 图113:**postPrecessing** 文件夹中内容 + +## 49.7 单元源 + +​ ***cellSource***函数对象作用于网格的所有单元或***cellZone***的单元。 + +​ 列表330显示了**cellSource**函数对象的定义。在本例中,在左边的单元里,包含了区域的一部分。函数对象计算空气体积组分的体积平均值。这个关键字**valueOutput**设置为**false**,并被注释标记为邪恶,原因如第49.6.3条所述。 + +``` +functions +{ + airContent_left + { + type cellSource ; + functionObjectLibs ("libfieldFunctionObjects.so"); + enabled true ; + outputControl timeStep ; + log true ; + valueOutput false ; // evil + source cellZone ; + sourceName left ; + operation volAverage ; + fields + ( + alpha.air + ); + } +} +``` + +​ 列表330:*cellSource*函数对象使用例子 + +## 49.8 读入场 + +​ 如果我们想后处理一个算例,我们使用创建自定义场的自定义求解器计算,并且后处理涉及这些自定义场,在运行后处理函数对象时,OpenFOAM很可能会抱怨这些场没有在数据库中。就在那时,读入场就可以上台了。 + +​ 头文件中的说明如下: + +​ 从时间目录中读取场,并将其添加到万个数据库中,为进一步的后处理。 + +​ 这个函数对象服务于读取指定场,并将这些场添加到数据库中。因此,添加后处理函数对象的这个函数对象,允许我们使用OpenFOAM的标准函数对象后处理任何自定义场。 + +## 49.9 写对象 + +​ 如果我们想对默认情况下不写入的场进行后期处理,那么我们可以告诉OpenFOAM写入指定的场到磁盘中。此对象的文件头函数说明: + +​ 允许指定注册到数据库的对象的不同写入频率。 + +## 49.10 执行C++代码作为函数对象 + +​ OpenFOAM让执行C++代码作为一个函数对象[148]成为可能。默认情况下此功能禁用。要激活它,必须更改一个标志。单个用户在**~/.OpenFOAM/$WM_PROJECT_VERSION/controlDic**t中设置,系统范围内的在**$WM_PROJECT_DIR/etc/controlDict**中。在其中一个文件,列表331所示的标志必须设置为1。第一个文件可能不存在,即没有用户指定设置。作者没有探讨优先权问题(用户设置优先于系统范围设置)。 + +​ 列表332显示这个特性的一个示例。读取场量*U1*、*U2*和*p*,并且一些计算值将打印到终端。 + +``` +// Allow case - supplied C++ code (# codeStream , codedFixedValue ) +allowSystemOperations 1; +``` + +​ 列表331:运行 算例提供的 C++代码 + +``` +extraInfo +{ + type coded ; + functionObjectLibs ("libutilityFunctionObjects.so"); + redirectType average ; + code + #{ + const volVectorField& U1 = mesh().lookupObject("U1"); + const volVectorField& U2 = mesh().lookupObject("U2"); + Info<<" max U1 = "< twallHeatFlux +( + volScalarField::New + ( + type () , + mesh_ , + dimensionedScalar(dimMass/pow3( dimTime), 0) + ) +); + +/* some code removed for brevity */ + +forAll(wallHeatFluxBf, patchi ) +{ + if(!wallHeatFluxBf[patchi].coupled()) + { + wallHeatFluxBf[patchi] = alphaBf[patchi]*heBf[patchi].snGrad(); + } +} +``` + +列表334:**wallHeatFlux.C**中壁面热流密度的计算 + +​ **wallHeatFlux**函数对象,不仅将壁面热流作为一个场来计算,而且还可以打印每个patch的积分和极值到终端,并将这些值写入数据文件。积分值当然是每个patch传递的能量,是以瓦特为单位。 + +## 49.12 模拟完成后执行函数 + +### 49.12.1 execFlowFunctionObjects + +​ **execFlowFunctionObjects**是OpenFOAM的后处理工具。此工具允许用户执行功模拟完成后的函数对象。通常,函数对象是在模拟过程中执行的。然而,在某些情况下,将一个函数应用于已经完成的模拟的数据集是有用的,例如用于测试函数。 + +**在单独的文件中定义函数对象** + +​ 列表335显示了一个只包含函数对象定义的文件。为了清楚起见,这个文件名为**functionDict**。在单独的文件中定义函数在某种程度上反映了分工。文件**controlDict**控制求解器,而文件**functionDict**定义函数对象。文件 + +**functionDict**可以通过**#include**语句包含在文件**controlDict**中。参见第11.3.5节例子。 + +``` +FoamFile +{ + version 2.0; + format ascii ; + class dictionary ; + location " system "; + object functionDict ; +} +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // +functions +{ + probes1 + { + type probes ; + functionObjectLibs ("libsampling.so"); + dictionary probesDict ; + } +} +``` + +​ 列表335:在单独的字典中定义函数。文件**functionDict** + +**运行execFlowFunctionObejcts** + +​ 必须告诉**execFlowFunctionObjects**,这些函数是在单独的文件中定义的。默认情况下,工具 + +读取文件controlDict。通过使用参数-dict,用户可以指定一个包含函数字典的替代文件。 + +``` +execFlowFunctionObjects -noFlow -dict functionDict +``` + +​ 列表336:调用*execFlowFunctionObjects* + -- Gitee From b9c8b64fc921dc27718f4c4b3a8915f9cb7f1e53 Mon Sep 17 00:00:00 2001 From: skf0558 Date: Thu, 27 Aug 2020 08:49:14 +0800 Subject: [PATCH 2/3] 50 sample --- 50 sample.md | 183 +++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 183 insertions(+) create mode 100644 50 sample.md diff --git a/50 sample.md b/50 sample.md new file mode 100644 index 0000000..98b5594 --- /dev/null +++ b/50 sample.md @@ -0,0 +1,183 @@ +# 50 提取数据 + +​ 采样(**sample**)是一个简单的后处理器。此工具由文件**sampleDict**控制。采样从一个特定区域的解中提取数据。采样可以从以下几何区域提取数据: + +​ •从空间中的一个或多个点 + +​ •沿一条线 + +​ •在一个面上 + +采样通常在模拟完成后执行。 + +## 50.1使用 + +​ 使用采样最简单的方法是调用**sample**命令。在本例中,示例将查找名为位于系统目录中的**sampleDict**。使用**-dict**,可以使用不同名称的替代文件明确规定。但是,此文件必须位于系统目录中。 + +​ 默认情况下,采样执行所有时间步。选项**-latestTime**可用于仅对最新的数据解决方案。选项**-time**可用于指定要操作的特定时间或时间范围。 + +​ 指定限定数量的时间步来执行采样可以显著减少这中动作。由采样生成的数据所使用的磁盘空间通常最多为几个兆字节。因此,在使用采样时,节省硬盘空间不是要考虑问题。 + +## 50.2样本 + +​ **sampleDict**文件控制要采样的数据和位置。 + +### 50.2.1输出格式 + +​ 有6种输出格式(csv、gnuplot、jplot、raw、vtk、xmgr)。列出格式的差别是在文件中组织数据的方式不同。 + +​ 采样给标量的量和矢量的量创建一个文件。数据文件的名称由采样场的名称、输出格式和几何集的名称生成。例如**lineXuniform_Ua_Ub.csv**,该文件包含沿**lineXuniform**线的速度场**Ua**和**Ub**。这个采样数据的数据格式为逗号分隔文件(csv)。 + +### 50.2.2场 + +​ 要采样的场量在列表**fields**中。 + +​ 忽略无效条目,没有任何警告消息。在列表337的示例中,场量列表包含名字*banana*。但是,没有名字为*banana*的字段,因此*sample*将直接忽略此条目,不会发出任何警告或错误消息。因此,**sampleDict**中的打字错误并不是那么容易找到的。取样报告没有警告,但未对预期场进行采样。始终要仔细检查子字典场中输入错误的条目,尤其是对具有复合名称的场量进行采样时,例如**U2Mean**或**U2Prime2Mean**。 + +``` +// Fields to sample . +fields +( + alpha + banana + Ua + Ub +); +``` + +​ 列表337:在文件**sampleDict**中要采样的字段 + +### 50.2.3几何区域 + +样本可以操作的几何区域有: + +**sets** 集合可以包含一个或多个点或一条直线。沿着一条线,点可以按等距分布。 + +**surfaces** 曲面可以用多种方式定义。可能是切割平面或等值曲面。 + +### 50.2.4陷阱 + +**缺少关键字** + +如果**sampleDict**中缺少关键字**sets**和**surfaces**,取样会运行而不会产生任何错误消息或任何数据。如果在列表338中,单词*banana*被*sets*替换,而*orange*被*surfaces*替换,取样就会像预期的那样工作。如果像列表338中那样,*sampleDict*调用*sample*,则*sample*不生成数据,并且不发出警告。 + +``` +setFormat raw; + +surfaceFormat vtk; + +formatOptions +{ + ensight + { + format ascii; + } +} + +interpolationScheme cellPoint; + +fields +( + p + U +); + +banana +( + lineX1 + { + type uniform; + axis distance ; + start (0.0015 0.5027 0.05); + end (0.0995 0.5027 0.05); + nPoints 20; + } +); + +orange +( +); +``` + +​ 列表338: **sampleDict**不工作的例子 + +**错误的线定义** + +​ 如果要对一条直线上的数据进行采样,由于此直线在外部域,因此该直线的定义是错误的,示例将发出警告消息。列表339显示了一个警告消息的示例。然而,*sample*不会报告错误,它将完成它的运行。所以,如果不检查*sample*输出,这可能会被忽视。 + +``` +--> FOAM Warning : + From function sampledSets::combineSampledSets(..) + in file sampledSet/sampledSets/sampledSets.C at line 102 + Sample set lineX0 has zero points. +``` + +​ 列表339:由于错误的线定义*sample*给出的警告信息 + +**写入精度不足** + +​ 在OpenFOAM教程中,大多数情况下使用6位数的写入精度,在大多数情况下,这应该足够了。但是,在某些情况下,可能需要更大的位数。 + +​ 当我们对压力场进行采样时,6位数的写入精度是否足够,这取决于我们使用的是不可压缩的还是可压缩的求解器。不可压缩求解器使用的压力场,它要除以流体密度。此外,对于不可压缩求解器,压力绝对大小是无关紧要的。因此,许多情况下,例如在出口处,使用0作为参考压力或环境压力。另一方面,对于可压缩求解器,我们使用压力场和相关压力的绝对值。因此,在许多情况下,压力场的环境压力为100000 Pa。这是书写精度是关键。在列表340中,我们看到了在使用6位数字的写入精度时,对可压缩情况下的压力进行采样的结果。在这种情况下,1000000Pa的参考压力几乎淹没了一切压力变化的信息,因为6位数字几乎完全用于表示环境压力。由于缺少有效数字,求解域中的小变化无法完全反应。 + +``` +x,p +0 ,100001 +0.00055 ,100001 +0.0011 ,100001 +0.00165 ,100001 +0.0022 ,100001 +0.00275 ,100001 +... +``` + +​ 列表340:写入精度为6位数时, 可压缩算例的采样压力场 + +​ 更糟糕的是只使用5位数的结果。在本例中,请参见列表341,OpenFOAM切换到科学记数法,只能表示环境压力。压力的微小变化现在完全丢失了。 + +``` +x,p +0,1e +05 +0.00055 ,1e +05 +0.0011 ,1e +05 +0.00165 ,1e +05 +0.0022 ,1e +05 +0.00275 ,1e +05 +... +``` + +​ 列表341:写入精度为5位数时, 可压缩算例的采样压力场 + +​ 使用足够大的有效数字可以确保求解域内的压力变化可以取样和进一步处理。 + +``` +x,p +0 ,100001.1161 +0.00055 ,100001.116 +0.0011 ,100001.1153 +0.00165 ,100001.1145 +0.0022 ,100001.1134 +0.00275 ,100001.1123 +... +``` + +​ 列表342:写入精度为10位数时, 可压缩算例的采样压力场 + +​ 选择足够的位数似乎是非常明显的解决方案。那么,我们什么时候会遇到采样数据位数不足的问题?当文件运行模拟以二进制写入场数据格式时。在这种情况下,压力场以最大精度用二进制格式写入磁盘。但是,采样数据将始终以ascii格式写入磁盘。这就是我们本节讨论的陷入麻烦的问题。使用二进制格式保存时,我们就不必考虑数字位数。 + +## 50.3 更新OpenFOAM-4 + +后处理实用工具*sample*和其他工具,已被集成在一起的工具**postProcess**所取代。幸运的是,并不是所有的东西都丢失了。所有被**postProcess**取代的实用工具都会给出关于它们正在过时的警告消息。而且,此消息包含有关如何继续的重要信息。在*sample*的例子中,现有的**sampleDicts**只需稍作修改可以进一步使用。 + +``` +sample has been superceded by the postProcess utility : + postProcess -func sample +To re-use existing ’sampleDict’ files simply add the following entries : + type sets ; + libs ("libsampling.so "); +and run + postProcess -func sampleDict +``` + +​ 列表343:在OpenFOAM-4中试图使用*sample*的警告信息 + -- Gitee From fbd3ebca584810b88c403c6b3e443d1569d6cc89 Mon Sep 17 00:00:00 2001 From: skf0558 Date: Thu, 27 Aug 2020 21:23:44 +0800 Subject: [PATCH 3/3] 52 postProcess.md --- 52 postProcess.md | 60 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 60 insertions(+) create mode 100644 52 postProcess.md diff --git a/52 postProcess.md b/52 postProcess.md new file mode 100644 index 0000000..85a67ab --- /dev/null +++ b/52 postProcess.md @@ -0,0 +1,60 @@ +# 52 postProcess + +随着OpenFOAM-4.0重写了功能对象框架。在这个重写过程中,引入了一个postProcess(后处理)实用工具,并在大多数求解器[154]中添加了postProcess选项。postProcess取代了某些后处理实用工具,例如sample。 + +## 52.1 用法 + +### 52.1.1 预配置函数对象 + +有许多预先配置好的函数对象,可以与后处理一起使用。这些可在**$FOAM_ETC/caseDicts/postProcessing**中找到。也可以使用**postProcess**的**-list**选项列出它们。 + +``` +user@host:∼$ postProcess -list +``` + +列表346:**postProcess**的**-list**选项命令 + +### 52.1.2 Passing 参数 + +列表347显示了如何确定速度场的最小值和最大值。 + +``` +user@host:∼$ postProcess -fields ’(U.water)’ -func "minMaxMagnitude(U.water)" +``` + +​ 列表347:确定速度场的极值 + +​ 列表348展示了如何同时处理两个速度场,我们只需逗号分隔列表。 + +``` +user@host:∼$postProcess -fields ’(U.air U.water)’ -func "minMaxMagnitude(U.air,U.water)" +``` + +​ 列表348:确定两个速度场的极值 + +​ 在列表349中,我们处理一个单独的速度场,并将附加参数传递给函数对象。在这种情况下,我们不想知道最大最小速度的位置。 + +``` +user@host:∼$postProcess -fields ’(U.air)’ -func "minMaxMagnitude(U.air,location=off) +``` + +​ 列表349:确定没有定位的速度场的极值 + +​ 运行函数对象之后,我们看到数据被写入后处理目录。我们注意到文件夹名对应于通过**-func**选项传递的参数。 + +``` +user@host :∼$ ls postProcessing +minMaxMagnitude(U.air, location =off) minMaxMagnitude(U.air,U.water) +``` + +​ 列表350:运行上面的两个函数对象**postProcessing**目录的内容 + +### 52.1.3 后处理分解案例 + +我们可以像并行运行求解器一样,并行运行postProcess。这允许我们去后期处理一个还没有重建的算例。 + +``` +mpirun -np 4 postProcess -parallel +``` + +​ 列表351:并行运行*postProcess*,即对分解后的算例进行后处理 \ No newline at end of file -- Gitee