OpenFOAM の Function Objects 機能を活用することで,結果処理の効率化が可能です.その1つである cellSource を使用すると,ユーザーが指定した cellZone (セルの集合) に属するセルの変数値に対して,セル体積を重みとした加重平均や体積積分などの処理を計算実行中に行って,値をモニタリングすることが可能です.例えば,porous という名前の cellZone において体積を重みとした温度の加重平均値を計算したい場合には,ケースの system/controlDict ファイルに下記のような設定を行います.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
functions { averageT { type cellSource; functionObjectLibs ("libfieldFunctionObjects.so"); enabled true; log true; valueOutput true; source cellZone; sourceName porous; operation volAverage; weightField none; fields ( T ); } } |
実行する演算処理を operation に指定します.選択可能な 11 個のオプションが,cellSource.C ファイルで確認できます.
43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 |
template<> const char* NamedEnum<fieldValues::cellSource::operationType, 11>::names[] = { "none", "sum", "sumMag", "average", "weightedAverage", "volAverage", "weightedVolAverage", "volIntegrate", "min", "max", "CoV" }; |
それぞれの演算オプションの実装は,cellSourceTemplates.C ファイルで確認できます.
70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 |
template<class Type> Type Foam::fieldValues::cellSource::processValues ( const Field<Type>& values, const scalarField& V, const scalarField& weightField ) const { Type result = Zero; switch (operation_) { case opSum: { result = sum(values); break; } case opSumMag: { result = sum(cmptMag(values)); break; } case opAverage: { result = sum(values)/values.size(); break; } case opWeightedAverage: { result = sum(weightField*values)/sum(weightField); break; } case opVolAverage: { result = sum(V*values)/sum(V); break; } case opWeightedVolAverage: { result = sum(weightField*V*values)/sum(weightField*V); break; } case opVolIntegrate: { result = sum(V*values); break; } case opMin: { result = min(values); break; } case opMax: { result = max(values); break; } case opCoV: { Type meanValue = sum(values*V)/sum(V); const label nComp = pTraits<Type>::nComponents; for (direction d=0; d<nComp; ++d) { scalarField vals(values.component(d)); scalar mean = component(meanValue, d); scalar& res = setComponent(result, d); res = sqrt(sum(V*sqr(vals - mean))/sum(V))/mean; } break; } default: { // Do nothing } } return result; } |
ここで,V はセル体積を表しているので,volIntegrate オプションは,体積積分を計算します.volAverage は,この体積積分値を cellZone の合計体積で割ることで,体積を重みとした加重平均値を計算します.これに対して,average は,単なる算術平均を計算します.また,名前に weighted が付いているオプションでは,加重平均の重みに使用する変数を weightField に指定します.sumMag オプションで使用されている cmptMag 演算子についてはこちらの記事で取り上げています.
選択したオプションが,意図した演算ではなかったなんてことが無いように,1度はしっかり確認しておきたいですね.
References |