├── 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 | --------------------------------------------------------------------------------