├── Make
├── files
└── options
├── .gitignore
├── LICENSE
├── README.md
├── conditionalAverageDict
├── IOconditionalAverage.H
├── conditionalAverageGrouping.C
├── conditionalAverage.C
├── conditionalAverage.H
└── conditionalAverageTemplates.C
/Make/files:
--------------------------------------------------------------------------------
1 |
2 |
3 | conditionalAverage.C
4 | conditionalAverageGrouping.C
5 |
6 | LIB = $(FOAM_USER_LIBBIN)/libconditionalAverage
7 |
--------------------------------------------------------------------------------
/Make/options:
--------------------------------------------------------------------------------
1 | EXE_INC = \
2 | -I$(LIB_SRC)/finiteVolume/lnInclude \
3 | -I$(LIB_SRC)/fileFormats/lnInclude
4 |
5 | LIB_LIBS =
6 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | # Prerequisites
2 | *.d
3 |
4 | # Compiled Object files
5 | *.slo
6 | *.lo
7 | *.o
8 | *.obj
9 |
10 | # Precompiled Headers
11 | *.gch
12 | *.pch
13 |
14 | # Compiled Dynamic libraries
15 | *.so
16 | *.dylib
17 | *.dll
18 |
19 | # Fortran module files
20 | *.mod
21 | *.smod
22 |
23 | # Compiled Static libraries
24 | *.lai
25 | *.la
26 | *.a
27 | *.lib
28 |
29 | # Executables
30 | *.exe
31 | *.out
32 | *.app
33 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2020 Zmeng
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # conditionalAverage
2 | OpenFOAM functionObject for postProcessing, getting the conditional averaged fields with a given scalarField
3 |
4 | It has been tested in OF4, OF6, OF7, OFv1712 and OFv1806
5 | ```
6 | functions
7 | {
8 | conditionalAverageTest
9 | {
10 | type conditionalAverage;
11 | libs ("libconditionalAverage.so");
12 | regionType all;//;cellZone;
13 | //name ignitionCells;//give a specific region to postProcess
14 | writeFormat raw;//ensight,gnuplot,jplot,raw,vtk,xmgr
15 | conditionalFields (Z);// Must be volScalarField, can also be 'x','y','z','direction'.
16 | weightedAveragedField rhoMeshV;//rhoMeshV;none;meshV
17 | //directionVector (1 1 1);//If conditionalFields contains 'direction', a directionVector will be needed
18 | nBins 20;//The number of sampled data, the conditionalFields are averaged devided into nBins, [min:(max-min)/nBins:max].
19 | //maxValue 1;//The first column of output file is within [minValue, maxValue],divided into nBins number of equal parts
20 | //minValue 0;//If the maxValue and the minValue is not presented, the max and min of the conditionalFields will be used instead
21 | averagedFields ( U C7H16 OH meanChemistryHRR );
22 | }
23 | }
24 | ```
25 |
--------------------------------------------------------------------------------
/conditionalAverageDict:
--------------------------------------------------------------------------------
1 | /*--------------------------------*- C++ -*----------------------------------*\
2 | ========= |
3 | \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
4 | \\ / O peration | Website: https://openfoam.org
5 | \\ / A nd | Version: dev
6 | \\/ M anipulation |
7 | \*---------------------------------------------------------------------------*/
8 |
9 | FoamFile
10 | {
11 | version 2.0;
12 | format ascii;
13 | class dictionary;
14 | location system;
15 | object conditionalAverage;
16 | }
17 |
18 | // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
19 |
20 | enabled true;
21 |
22 | type conditionalAverage;
23 |
24 | libs ("libconditionalAverage.so");
25 |
26 | regionType all;//;cellZone;
27 | //name ignitionCells;//give a specific region to postProcess
28 | writeFormat raw;
29 | conditionalFields (Z); // Must be volScalarField, can also be 'x','y','z','direction'.
30 | weightedAveragedField meshV;//rhoMeshV;none;meshV
31 | //directionVector (1 1 1); // If conditionalFields contains 'direction', a directionVector will be needed
32 | nBins 20;
33 | //maxValue 1;//The first column of output file is within [minValue, maxValue],divided into nBins number of equal parts
34 | //minValue 0;//If the maxValue and the minValue is not presented, the max and min of the conditionalFields will be used instead
35 | // The number of sampled data, the conditionalFields are averaged devided into nBins, [min:(max-min)/nBins:max].
36 | averagedFields ( U C7H16 OH meanChemistryHRR );
37 |
--------------------------------------------------------------------------------
/IOconditionalAverage.H:
--------------------------------------------------------------------------------
1 | /*---------------------------------------------------------------------------*\
2 | ========= |
3 | \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
4 | \\ / O peration |
5 | \\ / A nd | Copyright (C) 2011 OpenFOAM Foundation
6 | \\/ M anipulation |
7 | -------------------------------------------------------------------------------
8 | License
9 | This file is part of OpenFOAM.
10 |
11 | OpenFOAM is free software: you can redistribute it and/or modify it
12 | under the terms of the GNU General Public License as published by
13 | the Free Software Foundation, either version 3 of the License, or
14 | (at your option) any later version.
15 |
16 | OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
17 | ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
18 | FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
19 | for more details.
20 |
21 | You should have received a copy of the GNU General Public License
22 | along with OpenFOAM. If not, see .
23 |
24 | Typedef
25 | Foam::IOconditionalAverage
26 |
27 | Description
28 | Instance of the generic IOOutputFilter for conditionalAverage.
29 |
30 | \*---------------------------------------------------------------------------*/
31 |
32 | #ifndef IOconditionalAverage_H
33 | #define IOconditionalAverage_H
34 |
35 | #include "conditionalAverage.H"
36 | #include "IOOutputFilter.H"
37 |
38 | // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
39 |
40 | namespace Foam
41 | {
42 | typedef IOOutputFilter IOconditionalAverage;
43 | }
44 |
45 | // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
46 |
47 | #endif
48 |
49 | // ************************************************************************* //
50 |
--------------------------------------------------------------------------------
/conditionalAverageGrouping.C:
--------------------------------------------------------------------------------
1 | /*---------------------------------------------------------------------------*\
2 | ========= |
3 | \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
4 | \\ / O peration |
5 | \\ / A nd | Copyright (C) 2011-2016 OpenFOAM Foundation
6 | \\/ M anipulation |
7 | -------------------------------------------------------------------------------
8 | License
9 | This file is part of OpenFOAM.
10 |
11 | OpenFOAM is free software: you can redistribute it and/or modify it
12 | under the terms of the GNU General Public License as published by
13 | the Free Software Foundation, either version 3 of the License, or
14 | (at your option) any later version.
15 |
16 | OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
17 | ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
18 | FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
19 | for more details.
20 |
21 | You should have received a copy of the GNU General Public License
22 | along with OpenFOAM. If not, see .
23 |
24 | \*---------------------------------------------------------------------------*/
25 |
26 | #include "conditionalAverage.H"
27 | #include "IOobjectList.H"
28 |
29 | // * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
30 |
31 | void Foam::conditionalAverage::clearFieldGroups()
32 | {
33 | scalarFields_.clear();
34 | vectorFields_.clear();
35 | sphericalTensorFields_.clear();
36 | symmTensorFields_.clear();
37 | tensorFields_.clear();
38 | }
39 |
40 |
41 | Foam::label Foam::conditionalAverage::appendFieldGroup
42 | (
43 | const word& fieldName,
44 | const word& fieldType
45 | )
46 | {
47 | if (fieldType == volScalarField::typeName)
48 | {
49 | scalarFields_.append(fieldName);
50 | return 1;
51 | }
52 | else if (fieldType == volVectorField::typeName)
53 | {
54 | vectorFields_.append(fieldName);
55 | return 1;
56 | }
57 | else if (fieldType == volSphericalTensorField::typeName)
58 | {
59 | sphericalTensorFields_.append(fieldName);
60 | return 1;
61 | }
62 | else if (fieldType == volSymmTensorField::typeName)
63 | {
64 | symmTensorFields_.append(fieldName);
65 | return 1;
66 | }
67 | else if (fieldType == volTensorField::typeName)
68 | {
69 | tensorFields_.append(fieldName);
70 | return 1;
71 | }
72 |
73 | return 0;
74 | }
75 |
76 |
77 | Foam::label Foam::conditionalAverage::classifyFields()
78 | {
79 | label nFields = 0;
80 | clearFieldGroups();
81 |
82 | if (loadFromFiles_)
83 | {
84 | // Check files for a particular time
85 | IOobjectList objects(fvMeshFunctionObject::mesh_, fvMeshFunctionObject::mesh_.time().timeName());
86 | wordList allFields = objects.sortedNames();
87 |
88 | forAll(fieldSelection_, i)
89 | {
90 | labelList indices = findStrings(fieldSelection_[i], allFields);
91 |
92 | if (indices.size())
93 | {
94 | forAll(indices, fieldi)
95 | {
96 | const word& fieldName = allFields[indices[fieldi]];
97 |
98 | nFields += appendFieldGroup
99 | (
100 | fieldName,
101 | objects.find(fieldName)()->headerClassName()
102 | );
103 | }
104 | }
105 | else
106 | {
107 | WarningInFunction
108 | << "Cannot find field file matching "
109 | << fieldSelection_[i] << endl;
110 | }
111 | }
112 | }
113 | else
114 | {
115 | // Check currently available fields
116 | wordList allFields = fvMeshFunctionObject::mesh_.sortedNames();
117 | labelList indices = findStrings(fieldSelection_, allFields);
118 |
119 | forAll(fieldSelection_, i)
120 | {
121 | labelList indices = findStrings(fieldSelection_[i], allFields);
122 |
123 | if (indices.size())
124 | {
125 | forAll(indices, fieldi)
126 | {
127 | const word& fieldName = allFields[indices[fieldi]];
128 |
129 | nFields += appendFieldGroup
130 | (
131 | fieldName,
132 | fvMeshFunctionObject::mesh_.find(fieldName)()->type()
133 | );
134 | }
135 | }
136 | else
137 | {
138 | WarningInFunction
139 | << "Cannot find registered field matching "
140 | << fieldSelection_[i] << endl;
141 | }
142 | }
143 | }
144 |
145 | return nFields;
146 | }
147 |
148 |
149 | // ************************************************************************* //
150 |
--------------------------------------------------------------------------------
/conditionalAverage.C:
--------------------------------------------------------------------------------
1 | /*---------------------------------------------------------------------------*\
2 | ========= |
3 | \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
4 | \\ / O peration |
5 | \\ / A nd | Copyright (C) 2011-2016 OpenFOAM Foundation
6 | \\/ M anipulation |
7 | -------------------------------------------------------------------------------
8 | License
9 | This file is part of OpenFOAM.
10 |
11 | OpenFOAM is free software: you can redistribute it and/or modify it
12 | under the terms of the GNU General Public License as published by
13 | the Free Software Foundation, either version 3 of the License, or
14 | (at your option) any later version.
15 |
16 | OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
17 | ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
18 | FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
19 | for more details.
20 |
21 | You should have received a copy of the GNU General Public License
22 | along with OpenFOAM. If not, see .
23 |
24 | \*---------------------------------------------------------------------------*/
25 |
26 | #include "conditionalAverage.H"
27 | #include "addToRunTimeSelectionTable.H"
28 |
29 | // * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
30 |
31 | namespace Foam
32 | {
33 | defineTypeNameAndDebug(conditionalAverage, 0);
34 |
35 | addToRunTimeSelectionTable
36 | (
37 | functionObject,
38 | conditionalAverage,
39 | dictionary
40 | );
41 | }
42 |
43 | bool Foam::conditionalAverage::verbose_ = true;
44 |
45 |
46 | // * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
47 |
48 |
49 | // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
50 |
51 | Foam::conditionalAverage::conditionalAverage
52 | (
53 | const word& name,
54 | const Time& t,
55 | const dictionary& dict
56 | )
57 | :
58 | fvMeshFunctionObject(name, t, dict),
59 | volRegion
60 | (
61 | refCast
62 | (
63 | t.lookupObject
64 | (
65 | dict.lookupOrDefault("region", polyMesh::defaultRegion)
66 | )
67 | )
68 | ,
69 | dict
70 | ),
71 | loadFromFiles_(false),
72 | outputPath_(fileName::null),
73 | dict_(dict),
74 | conditionalFieldNames_(dict.lookup("conditionalFields")),
75 | conditionalFields_(conditionalFieldNames_.size()),
76 | weightedAveragedFieldName_(dict.lookup("weightedAveragedField")),
77 | nBins_(readLabel(dict.lookup("nBins"))),
78 | maxF_(dict.lookupOrDefault("maxValue", 0.0)),
79 | minF_(dict.lookupOrDefault("minValue", 0.0)),
80 | conditionalFieldOutputs_(conditionalFieldNames_.size()),
81 | fieldSelection_(dict.lookup("averagedFields")),
82 | writeFormat_(dict.lookup("writeFormat"))
83 | {
84 | if (Pstream::parRun())
85 | {
86 | outputPath_ = fvMeshFunctionObject::mesh_.time().path()/".."/"postProcessing"/name;
87 | }
88 | else
89 | {
90 | outputPath_ = fvMeshFunctionObject::mesh_.time().path()/"postProcessing"/name;
91 | }
92 | if (fvMeshFunctionObject::mesh_.name() != fvMesh::defaultRegion)
93 | {
94 | outputPath_ = outputPath_/fvMeshFunctionObject::mesh_.name();
95 | }
96 |
97 | clearFieldGroups();
98 |
99 | if (Pstream::master() && debug)
100 | {
101 | Pout<< "conditionalFields are:" << conditionalFieldNames_ << endl;
102 | Pout<< "conditionalAverage fields:" << fieldSelection_ << endl;
103 | }
104 | }
105 |
106 |
107 | Foam::conditionalAverage::conditionalAverage
108 | (
109 | const word& name,
110 | const objectRegistry& obr,
111 | const dictionary& dict,
112 | const bool loadFromFiles
113 | )
114 | :
115 | fvMeshFunctionObject(name, obr, dict),
116 | volRegion(refCast(obr), dict ),
117 | loadFromFiles_(loadFromFiles),
118 | outputPath_(fileName::null),
119 | dict_(dict),
120 | conditionalFieldNames_(dict.lookup("conditionalFields")),
121 | conditionalFields_(conditionalFieldNames_.size()),
122 | weightedAveragedFieldName_(dict.lookup("weightedAveragedField")),
123 | nBins_(readLabel(dict.lookup("nBins"))),
124 | maxF_(dict.lookupOrDefault("maxValue", 0.0)),
125 | minF_(dict.lookupOrDefault("minValue", 0.0)),
126 | conditionalFieldOutputs_(conditionalFieldNames_.size()),
127 | fieldSelection_(dict.lookup("averagedFields")),
128 | writeFormat_(dict.lookup("writeFormat"))
129 | {
130 | if (Pstream::parRun())
131 | {
132 | outputPath_ = fvMeshFunctionObject::mesh_.time().path()/".."/"postProcessing"/name;
133 | }
134 | else
135 | {
136 | outputPath_ = fvMeshFunctionObject::mesh_.time().path()/"postProcessing"/name;
137 | }
138 | if (fvMeshFunctionObject::mesh_.name() != fvMesh::defaultRegion)
139 | {
140 | outputPath_ = outputPath_/fvMeshFunctionObject::mesh_.name();
141 | }
142 |
143 | clearFieldGroups();
144 |
145 | if (Pstream::master() && debug)
146 | {
147 | Pout<< "conditionalFields are:" << conditionalFieldNames_ << endl;
148 | Pout<< "conditionalAverage fields:" << fieldSelection_ << endl;
149 | }
150 | }
151 |
152 |
153 | // * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * //
154 |
155 | Foam::conditionalAverage::~conditionalAverage()
156 | {}
157 |
158 |
159 | // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
160 |
161 | void Foam::conditionalAverage::verbose(const bool verbosity)
162 | {
163 | verbose_ = verbosity;
164 | }
165 |
166 |
167 | bool Foam::conditionalAverage::execute()
168 | {
169 | return true;
170 | }
171 |
172 |
173 | bool Foam::conditionalAverage::write()
174 | {
175 | const label nFields = classifyFields();
176 |
177 | if (Pstream::master())
178 | {
179 | if (debug)
180 | {
181 | Pout<< "timeName = " << fvMeshFunctionObject::mesh_.time().timeName() << nl
182 | << "scalarFields " << scalarFields_ << nl
183 | << "vectorFields " << vectorFields_ << nl
184 | << "sphTensorFields " << sphericalTensorFields_ << nl
185 | << "symTensorFields " << symmTensorFields_ <.
23 |
24 | Class
25 | Foam::conditionalAverage
26 |
27 | Description
28 | Set of sets to sample.
29 | Call conditionalAverage.write() to sample&write files.
30 |
31 | SourceFiles
32 | conditionalAverage.C
33 |
34 | \*---------------------------------------------------------------------------*/
35 |
36 | #ifndef conditionalAverage_H
37 | #define conditionalAverage_H
38 |
39 | #include "functionObject.H"
40 | #include "fvMeshFunctionObject.H"
41 | #include "volRegion.H"
42 | #include "volFieldsFwd.H"
43 | #include "coordSet.H"
44 | #include "writer.H"
45 | #include "wordReList.H"
46 |
47 | // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
48 |
49 | namespace Foam
50 | {
51 |
52 | // Forward declaration of classes
53 | class objectRegistry;
54 | class fvMesh;
55 |
56 | /*---------------------------------------------------------------------------*\
57 | Class conditionalAverage Declaration
58 | \*---------------------------------------------------------------------------*/
59 |
60 | class conditionalAverage
61 | :
62 | public functionObjects::fvMeshFunctionObject,
63 | public functionObjects::volRegion
64 | {
65 |
66 | // Private classes
67 |
68 | //- Class used for grouping field types
69 | template
70 | class fieldGroup
71 | :
72 | public DynamicList
73 | {
74 | public:
75 |
76 | //- The set formatter
77 | autoPtr> formatter;
78 |
79 | //- Construct null
80 | fieldGroup()
81 | :
82 | DynamicList(0),
83 | formatter(nullptr) // change for of1806, from formatter(NULL)
84 | {}
85 |
86 | //- Construct for a particular format
87 | fieldGroup(const word& writeFormat)
88 | :
89 | DynamicList(0),
90 | formatter(writer::New(writeFormat))
91 | {}
92 |
93 | //- Reset format and field list
94 | void clear()
95 | {
96 | DynamicList::clear();
97 | formatter.clear();
98 | }
99 |
100 | //- Assign a new formatter
101 | void operator=(const word& writeFormat)
102 | {
103 | formatter = writer::New(writeFormat);
104 | }
105 |
106 | };
107 |
108 | // Static data members
109 |
110 | //- Output verbosity
111 | static bool verbose_;
112 |
113 |
114 | // Private data
115 |
116 | //- Load fields from files (not from objectRegistry)
117 | bool loadFromFiles_;
118 |
119 | //- Output path
120 | fileName outputPath_;
121 |
122 | dictionary dict_;
123 |
124 |
125 | // Private data
126 |
127 | // Read from dictonary
128 |
129 | //- conditional field List
130 | //- must give, and must be a volScalarField not vector
131 | wordReList conditionalFieldNames_;
132 |
133 | PtrList conditionalFields_;
134 |
135 | word weightedAveragedFieldName_;
136 |
137 | //volScalarField weightedAveragedField_;
138 |
139 | //- Number of Bins
140 | label nBins_;
141 | //- max
142 | scalar maxF_;
143 | //- min
144 | scalar minF_;
145 |
146 | //- The conditional field is cutted into nBins_ piece uniformly
147 | //- From min to max
148 | //- The conditionalFieldOutputs_ record the list of these pieces
149 | PtrList conditionalFieldOutputs_;
150 |
151 | //- Names of fields to sample
152 | wordReList fieldSelection_;
153 |
154 | //- Output format to use
155 | word writeFormat_;
156 |
157 |
158 | // Categorized scalar/vector/tensor fields
159 |
160 | fieldGroup scalarFields_;
161 | fieldGroup vectorFields_;
162 | fieldGroup sphericalTensorFields_;
163 | fieldGroup symmTensorFields_;
164 | fieldGroup tensorFields_;
165 |
166 |
167 | // Private Member Functions
168 |
169 | //- Clear old field groups
170 | void clearFieldGroups();
171 |
172 | //- Append fieldName to the appropriate group
173 | label appendFieldGroup(const word& fieldName, const word& fieldType);
174 |
175 | //- Classify field types, returns the number of fields
176 | label classifyFields();
177 |
178 | //- Combine values from all processors.
179 | // Valid result only on master processor.
180 | template
181 | void combineSampledValues
182 | (
183 | PtrList>& sampledFields,
184 | PtrList>>& masterFields
185 | );
186 |
187 | template
188 | void writeSampleFile
189 | (
190 | const coordSet& masterSampleSet,
191 | const PtrList>& masterFields,
192 | const wordList nameList,
193 | const fileName& timeDir,
194 | const writer& formatter
195 | );
196 |
197 | template
198 | void sampleAndWrite(fieldGroup& fields);
199 |
200 |
201 | //- Disallow default bitwise copy construct and assignment
202 | conditionalAverage(const conditionalAverage&);
203 | void operator=(const conditionalAverage&);
204 |
205 |
206 | public:
207 |
208 | //- Runtime type information
209 | TypeName("conditionalAverage");
210 |
211 |
212 | // Constructors
213 |
214 | //- Construct from Time and dictionary
215 | conditionalAverage
216 | (
217 | const word& name,
218 | const Time& time,
219 | const dictionary& dict
220 | );
221 |
222 | //- Construct for given objectRegistry and dictionary
223 | // allow the possibility to load fields from files
224 | conditionalAverage
225 | (
226 | const word& name,
227 | const objectRegistry&,
228 | const dictionary&,
229 | const bool loadFromFiles = false
230 | );
231 |
232 |
233 | //- Destructor
234 | virtual ~conditionalAverage();
235 |
236 |
237 | // Member Functions
238 |
239 | //- Set verbosity level
240 | void verbose(const bool verbosity = true);
241 |
242 | //- Filter a field according to cellIds
243 | template
244 | tmp> filterField(const Field& field) const;
245 |
246 | //- Read the conditionalAverage
247 | virtual bool read(const dictionary&);
248 |
249 | //- Execute, currently does nothing
250 | virtual bool execute();
251 |
252 | //- Sample and write
253 | virtual bool write();
254 |
255 | };
256 |
257 |
258 | // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
259 |
260 | } // End namespace Foam
261 |
262 | // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
263 |
264 | #ifdef NoRepository
265 | #include "conditionalAverageTemplates.C"
266 | #endif
267 |
268 | // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
269 |
270 | #endif
271 |
272 | // ************************************************************************* //
273 |
--------------------------------------------------------------------------------
/conditionalAverageTemplates.C:
--------------------------------------------------------------------------------
1 | /*---------------------------------------------------------------------------*\
2 | ========= |
3 | \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
4 | \\ / O peration |
5 | \\ / A nd | Copyright (C) 2011-2016 OpenFOAM Foundation
6 | \\/ M anipulation |
7 | -------------------------------------------------------------------------------
8 | License
9 | This file is part of OpenFOAM.
10 |
11 | OpenFOAM is free software: you can redistribute it and/or modify it
12 | under the terms of the GNU General Public License as published by
13 | the Free Software Foundation, either version 3 of the License, or
14 | (at your option) any later version.
15 |
16 | OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
17 | ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
18 | FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
19 | for more details.
20 |
21 | You should have received a copy of the GNU General Public License
22 | along with OpenFOAM. If not, see .
23 |
24 | \*---------------------------------------------------------------------------*/
25 |
26 | #include "conditionalAverage.H"
27 | #include "volFields.H"
28 |
29 | // * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
30 |
31 | template
32 | Foam::tmp>
33 | Foam::conditionalAverage::filterField
34 | (
35 | const Field& field
36 | ) const
37 | {
38 | if (isNull(cellIDs()))
39 | {
40 | return field;
41 | }
42 | else
43 | {
44 | return tmp>(new Field(field, cellIDs()));
45 | }
46 | }
47 |
48 | template
49 | void Foam::conditionalAverage::writeSampleFile
50 | (
51 | const coordSet& masterSampleSet,
52 | const PtrList>& masterFields,
53 | const wordList nameList,
54 | const fileName& timeDir,
55 | const writer& formatter
56 | )
57 | {
58 | wordList valueSetNames(masterFields.size());
59 | List*> valueSets(masterFields.size());
60 |
61 | forAll(masterFields, fieldi)
62 | {
63 | valueSetNames[fieldi] = nameList[fieldi];
64 | valueSets[fieldi] = &masterFields[fieldi];
65 | }
66 |
67 | fileName fName
68 | (
69 | timeDir/formatter.getFileName(masterSampleSet, valueSetNames)
70 | );
71 |
72 | OFstream ofs(fName);
73 | if (ofs.opened())
74 | {
75 | formatter.write
76 | (
77 | masterSampleSet,
78 | valueSetNames,
79 | valueSets,
80 | ofs
81 | );
82 | }
83 | else
84 | {
85 | WarningInFunction
86 | << "File " << ofs.name() << " could not be opened. "
87 | << "No data will be written" << endl;
88 | }
89 | }
90 |
91 |
92 | template
93 | void Foam::conditionalAverage::combineSampledValues
94 | (
95 | PtrList>& averagedFields,
96 | PtrList>>& masterFields
97 | )
98 | {
99 | forAll(conditionalFields_, conditionalFieldi)
100 | {
101 | word conditionalFieldName(conditionalFieldNames_[conditionalFieldi]);
102 |
103 | if
104 | (
105 | (conditionalFieldName == "x") ||
106 | (conditionalFieldName == "y") ||
107 | (conditionalFieldName == "z") ||
108 | (conditionalFieldName == "direction")
109 | )
110 | {
111 | volScalarField tempconditionalField
112 | (
113 | IOobject
114 | (
115 | conditionalFieldName,
116 | fvMeshFunctionObject::mesh_.time().timeName(),
117 | fvMeshFunctionObject::mesh_,
118 | IOobject::NO_READ,
119 | IOobject::NO_WRITE,
120 | false
121 | ),
122 | fvMeshFunctionObject::mesh_,
123 | dimensionedScalar("direction", dimLength, 0)
124 | );
125 |
126 | const volVectorField centres = fvMeshFunctionObject::mesh_.C();
127 |
128 | if(conditionalFieldName == "x") tempconditionalField = centres.component(vector::X);
129 | else if(conditionalFieldName == "y") tempconditionalField = centres.component(vector::Y);
130 | else if(conditionalFieldName == "z") tempconditionalField = centres.component(vector::Z);
131 | else
132 | {
133 | vector directionVector(dict_.lookup("directionVector"));
134 | directionVector = directionVector/(mag(directionVector)+SMALL);
135 | Info << "The normalized directionVector is:" << directionVector << endl;
136 |
137 | tempconditionalField = (directionVector & centres);
138 | }
139 |
140 | conditionalFields_.set
141 | (
142 | conditionalFieldi,
143 | filterField
144 | (
145 | tempconditionalField
146 | )
147 | );
148 | }
149 | else
150 | {
151 | if (loadFromFiles_)
152 | {
153 | volScalarField tempconditionalField
154 | (
155 | IOobject
156 | (
157 | conditionalFieldName,
158 | fvMeshFunctionObject::mesh_.time().timeName(),
159 | fvMeshFunctionObject::mesh_,
160 | IOobject::MUST_READ,
161 | IOobject::NO_WRITE,
162 | false
163 | ),
164 | fvMeshFunctionObject::mesh_
165 | );
166 | conditionalFields_.set
167 | (
168 | conditionalFieldi,
169 | filterField
170 | (
171 | tempconditionalField
172 | )
173 | );
174 | }
175 | else
176 | {
177 | if(fvMeshFunctionObject::mesh_.foundObject(conditionalFieldName))
178 | {
179 | conditionalFields_.set
180 | (
181 | conditionalFieldi,
182 | filterField
183 | (
184 | fvMeshFunctionObject::mesh_.lookupObject(conditionalFieldName)
185 | )
186 | );
187 | }
188 | else
189 | {
190 | FatalErrorInFunction
191 | << "Cannot find volScalarField "
192 | << conditionalFieldName
193 | << " for a conditionalField." << nl
194 | << "It is not in objectRegistry or not a volScalarField."
195 | << abort(FatalError);
196 | }
197 | }
198 | }
199 |
200 | const scalarField& conditionalField = conditionalFields_[conditionalFieldi];
201 |
202 | scalarField weightedAveragedField_ = fvMeshFunctionObject::mesh_.V();
203 | if(weightedAveragedFieldName_ == "meshV")
204 | {
205 | forAll(fvMeshFunctionObject::mesh_.C(),celli)
206 | {
207 | weightedAveragedField_[celli] = fvMeshFunctionObject::mesh_.V()[celli];
208 | }
209 | }
210 | else if (weightedAveragedFieldName_ == "rhoMeshV")
211 | {
212 | const volScalarField rho_ = fvMeshFunctionObject::mesh_.lookupObject("rho");
213 | forAll(fvMeshFunctionObject::mesh_.C(),celli)
214 | {
215 | weightedAveragedField_[celli] = fvMeshFunctionObject::mesh_.V()[celli]*rho_[celli];
216 | }
217 | }
218 | else if (weightedAveragedFieldName_ == "none")
219 | {
220 | forAll(fvMeshFunctionObject::mesh_.C(),celli)
221 | {
222 | weightedAveragedField_[celli] = 1.;
223 | }
224 | }
225 |
226 | //scalarList totalCounts_(nBins_,scalar(0.0));// Only for of6, need scalar(0)
227 | //scalarList localCellCounts(nBins_,scalar(0.0));// of4 and 7 can use, scalarList totalCounts_(nBins_,0);
228 | scalarList localWeightedAveragedFields_(nBins_,scalar(0.0));
229 | scalarList totalWeightedAveragedFields_(nBins_,scalar(0.0));
230 | List> localAveragedFields(averagedFields.size());
231 | List> averagedFieldsOutput_(averagedFields.size());
232 |
233 | masterFields.set
234 | (
235 | conditionalFieldi,
236 | new PtrList>(averagedFields.size())
237 | );
238 |
239 | conditionalFieldOutputs_.set
240 | (
241 | conditionalFieldi,
242 | new scalarList(0)//Init as size 0, append when there are some data in this bin
243 | );
244 |
245 | forAll(localAveragedFields, averagedFieldi)
246 | {
247 | localAveragedFields[averagedFieldi] = Field(nBins_);
248 | averagedFieldsOutput_[averagedFieldi] = Field(0);//Init as size 0, append when there are some data in this bin
249 | localAveragedFields[averagedFieldi] = 0.0*localAveragedFields[averagedFieldi];
250 | averagedFieldsOutput_[averagedFieldi] = 0.0*averagedFieldsOutput_[averagedFieldi];
251 | }
252 | scalar start = gMin(conditionalField);
253 | scalar end = gMax(conditionalField);
254 | //- This if will be skiped if minF_ and maxF_ are not given
255 | if( maxF_ > minF_ )
256 | {
257 | start = max( minF_, start);
258 | end = min( maxF_, end );
259 | }
260 | const scalar offset = (end - start)/(nBins_ - 1);
261 |
262 | forAll( conditionalField, trackCelli )
263 | {
264 | if((conditionalField[trackCelli]>=start)&&(conditionalField[trackCelli]<=end))
265 | {
266 | //get the in iBin_th localSamplingCells, assuming it is averaged distributed
267 | label iBin = 0;
268 | if(offset!=0) iBin = label((conditionalField[trackCelli] - start)/offset);
269 |
270 | //localCellCounts[iBin] ++;
271 | localWeightedAveragedFields_[iBin] += weightedAveragedField_[trackCelli];
272 | forAll( averagedFields, averagedFieldi )
273 | {
274 | // New averaged value, avoid exceed value
275 | // localAveragedFields[averagedFieldi][iBin] =
276 | // localAveragedFields[averagedFieldi][iBin]*(localCellCounts[iBin]-1)/localCellCounts[iBin]
277 | // + weightedAveragedField_[trackCelli]*averagedFields[averagedFieldi][trackCelli]/localCellCounts[iBin];
278 | localAveragedFields[averagedFieldi][iBin] += weightedAveragedField_[trackCelli]*averagedFields[averagedFieldi][trackCelli];
279 | }
280 | }
281 | }
282 |
283 | // for weightedAveragedField
284 | forAll( averagedFields, averagedFieldi )
285 | {
286 | // New averaged value, avoid exceed value
287 | forAll(localAveragedFields[averagedFieldi], iBin)
288 | {
289 | if(localWeightedAveragedFields_[iBin] != 0)
290 | {
291 | localAveragedFields[averagedFieldi][iBin] /= localWeightedAveragedFields_[iBin];
292 | }
293 | }
294 | }
295 |
296 | //- Get the value from all of the processors
297 | //forAll( conditionalFieldOutputs_[conditionalFieldi], iBin )
298 | for(label iBin = 0; iBin < nBins_; iBin++ )
299 | {
300 | //totalCounts_[iBin] = localCellCounts[iBin];
301 | totalWeightedAveragedFields_[iBin] = localWeightedAveragedFields_[iBin];
302 | reduce( totalWeightedAveragedFields_[iBin], sumOp());
303 | //- if there is no data in this region, did not append the value for conditionalFieldOutputs_ and averagedFieldsOutput_
304 | if(totalWeightedAveragedFields_[iBin] > 0)
305 | {
306 | conditionalFieldOutputs_[conditionalFieldi].append(start + iBin*offset);
307 | forAll( averagedFields, averagedFieldi )
308 | {
309 | T totalAveraged = (localWeightedAveragedFields_[iBin]/totalWeightedAveragedFields_[iBin])*localAveragedFields[averagedFieldi][iBin];
310 | reduce( totalAveraged, sumOp());
311 | averagedFieldsOutput_[averagedFieldi].append(totalAveraged);
312 | }
313 | }
314 | }
315 |
316 | forAll( averagedFields, averagedFieldi )
317 | {
318 | //- In the condition of "conditionalFieldi", the averaged field "averagedFieldi"
319 | //- masterFields[averagedFieldi].setname() = averagedFields[averagedFieldi].name();
320 | //- masterFields[conditionalFieldi] = ;
321 | masterFields[conditionalFieldi].set
322 | (
323 | averagedFieldi,
324 | new Field(averagedFieldsOutput_[averagedFieldi])
325 | );
326 | }
327 | }
328 | }
329 |
330 |
331 | template
332 | void Foam::conditionalAverage::sampleAndWrite
333 | (
334 | fieldGroup& fields
335 | )
336 | {
337 | if (fields.size())
338 | {
339 | // Create or use existing writer
340 | // fields has two properties, DynamicList and formatter
341 | // here we check the formatter
342 | if (fields.formatter.empty())
343 | {
344 | fields = writeFormat_;
345 | }
346 |
347 | // Storage for interpolated values
348 | PtrList> averagedFields(fields.size());
349 |
350 | forAll(fields, fieldi)
351 | {
352 | if (Pstream::master() && verbose_)
353 | {
354 | Pout<< "conditionalAverage::sampleAndWrite: "
355 | << fields[fieldi] << endl;
356 | }
357 |
358 | if (loadFromFiles_)
359 | {
360 | GeometricField vf
361 | (
362 | IOobject
363 | (
364 | fields[fieldi],
365 | fvMeshFunctionObject::mesh_.time().timeName(),
366 | fvMeshFunctionObject::mesh_,
367 | IOobject::MUST_READ,
368 | IOobject::NO_WRITE,
369 | false
370 | ),
371 | fvMeshFunctionObject::mesh_
372 | );
373 |
374 | averagedFields.set
375 | (
376 | fieldi,
377 | filterField(vf)// use region to filter part of the volScalarField
378 | );
379 | }
380 | else
381 | {
382 | averagedFields.set
383 | (
384 | fieldi,
385 | filterField// use region to filter part of the volScalarField
386 | (
387 | fvMeshFunctionObject::mesh_.lookupObject
388 | >
389 | (fields[fieldi])
390 | )
391 | );
392 | }
393 | }
394 |
395 | // Combine sampled fields from processors.
396 | // Note: only master results are valid
397 | PtrList>> masterFields(conditionalFieldNames_.size());
398 | combineSampledValues(averagedFields, masterFields);
399 |
400 | if (Pstream::master())
401 | {
402 | forAll(conditionalFields_, conditionalFieldi)
403 | {
404 | coordSet masterCoordSets
405 | (
406 | conditionalFieldNames_[conditionalFieldi]+"_conditionalwith",
407 | "distance",
408 | List(conditionalFieldOutputs_[conditionalFieldi].size()),
409 | conditionalFieldOutputs_[conditionalFieldi]
410 | );
411 |
412 | wordList nameList(masterFields[conditionalFieldi].size());
413 |
414 | forAll(nameList, fieldi)
415 | {
416 | nameList[fieldi] = fields[fieldi];
417 | }
418 |
419 | writeSampleFile
420 | (
421 | masterCoordSets,
422 | masterFields[conditionalFieldi],
423 | nameList,
424 | outputPath_/fvMeshFunctionObject::mesh_.time().timeName(),
425 | fields.formatter()
426 | );
427 | }
428 |
429 | }
430 | }
431 | }
432 |
433 |
434 | // ************************************************************************* //
435 |
--------------------------------------------------------------------------------