diff --git a/src/OpenFOAM/Make/files b/src/OpenFOAM/Make/files index 6b271cfc1d0e5493b23288cc125d2a431d1b3653..47c8dee78897a440b9f0bd9b9de5386199bd1da8 100644 --- a/src/OpenFOAM/Make/files +++ b/src/OpenFOAM/Make/files @@ -209,6 +209,7 @@ $(dll)/codedBase/codedBase.C db/functionObjects/functionObject/functionObject.C db/functionObjects/functionObjectList/functionObjectList.C db/functionObjects/functionObjectFile/functionObjectFile.C +db/functionObjects/functionObjectState/functionObjectState.C db/functionObjects/outputFilterOutputControl/outputFilterOutputControl.C diff --git a/src/OpenFOAM/db/functionObjects/functionObjectFile/functionObjectFile.C b/src/OpenFOAM/db/functionObjects/functionObjectFile/functionObjectFile.C index 847747964d68bcf391c28db78c1c02d9abd76adf..e44f41f6ac27f94a01e8bc5e88cbad659461029c 100644 --- a/src/OpenFOAM/db/functionObjects/functionObjectFile/functionObjectFile.C +++ b/src/OpenFOAM/db/functionObjects/functionObjectFile/functionObjectFile.C @@ -3,7 +3,7 @@ \\ / F ield | OpenFOAM: The Open Source CFD Toolbox \\ / O peration | \\ / A nd | Copyright (C) 2012-2015 OpenFOAM Foundation - \\/ M anipulation | + \\/ M anipulation | Copyright (C) 2015 OpenCFD Ltd ------------------------------------------------------------------------------- License This file is part of OpenFOAM. @@ -39,6 +39,7 @@ Foam::label Foam::functionObjectFile::addChars = 7; void Foam::functionObjectFile::initStream(Ostream& os) const { os.setf(ios_base::scientific, ios_base::floatfield); + os.precision(writePrecision_); os.width(charWidth()); } @@ -78,78 +79,44 @@ Foam::fileName Foam::functionObjectFile::baseTimeDir() const } -void Foam::functionObjectFile::createFiles() +Foam::autoPtr<Foam::OFstream> Foam::functionObjectFile::createFile +( + const word& name +) const { - if (Pstream::master()) + autoPtr<OFstream> osPtr; + + if (Pstream::master() && writeToFile_) { const word startTimeName = obr_.time().timeName(obr_.time().startTime().value()); - forAll(names_, i) - { - if (!filePtrs_.set(i)) - { - fileName outputDir(baseFileDir()/prefix_/startTimeName); - mkDir(outputDir); + fileName outputDir(baseFileDir()/prefix_/startTimeName); - word fName(names_[i]); + mkDir(outputDir); - // Check if file already exists - IFstream is(outputDir/(fName + ".dat")); - if (is.good()) - { - fName = fName + "_" + obr_.time().timeName(); - } + word fName(name); - filePtrs_.set(i, new OFstream(outputDir/(fName + ".dat"))); - - initStream(filePtrs_[i]); - - writeFileHeader(i); - - } + // Check if file already exists + IFstream is(outputDir/(fName + ".dat")); + if (is.good()) + { + fName = fName + "_" + obr_.time().timeName(); } - } -} - - -void Foam::functionObjectFile::writeFileHeader(const label i) -{} - -void Foam::functionObjectFile::write() -{ - createFiles(); -} + osPtr.set(new OFstream(outputDir/(fName + ".dat"))); - -void Foam::functionObjectFile::resetNames(const wordList& names) -{ - names_.clear(); - names_.append(names); - - if (Pstream::master()) - { - filePtrs_.clear(); - filePtrs_.setSize(names_.size()); - - createFiles(); + initStream(osPtr()); } + + return osPtr; } -void Foam::functionObjectFile::resetName(const word& name) +void Foam::functionObjectFile::resetFile(const word& fileName) { - names_.clear(); - names_.append(name); - - if (Pstream::master()) - { - filePtrs_.clear(); - filePtrs_.setSize(1); - - createFiles(); - } + fileName_ = fileName; + filePtr_ = createFile(fileName_); } @@ -169,8 +136,10 @@ Foam::functionObjectFile::functionObjectFile : obr_(obr), prefix_(prefix), - names_(), - filePtrs_() + fileName_("undefined"), + filePtr_(), + writePrecision_(IOstream::defaultPrecision()), + writeToFile_(true) {} @@ -178,46 +147,22 @@ Foam::functionObjectFile::functionObjectFile ( const objectRegistry& obr, const word& prefix, - const word& name + const word& fileName, + const dictionary& dict ) : obr_(obr), prefix_(prefix), - names_(), - filePtrs_() + fileName_(fileName), + filePtr_(), + writePrecision_(IOstream::defaultPrecision()), + writeToFile_(true) { - names_.clear(); - names_.append(name); - if (Pstream::master()) - { - filePtrs_.clear(); - filePtrs_.setSize(1); - - // Cannot create files - need to access virtual function - } -} - + read(dict); -Foam::functionObjectFile::functionObjectFile -( - const objectRegistry& obr, - const word& prefix, - const wordList& names -) -: - obr_(obr), - prefix_(prefix), - names_(names), - filePtrs_() -{ - names_.clear(); - names_.append(names); - if (Pstream::master()) + if (writeToFile_) { - filePtrs_.clear(); - filePtrs_.setSize(names_.size()); - - // Cannot create files - need to access virtual function + filePtr_ = createFile(fileName_); } } @@ -230,72 +175,38 @@ Foam::functionObjectFile::~functionObjectFile() // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * // -const Foam::wordList& Foam::functionObjectFile::names() const +void Foam::functionObjectFile::read(const dictionary& dict) { - return names_; + writePrecision_ = + dict.lookupOrDefault("writePrecision", IOstream::defaultPrecision()); + + // Only write on master process + writeToFile_ = dict.lookupOrDefault("writeToFile", true); + writeToFile_ = writeToFile_ && Pstream::master(); } Foam::OFstream& Foam::functionObjectFile::file() { - if (!Pstream::master()) - { - FatalErrorIn("Foam::OFstream& Foam::functionObjectFile::file()") - << "Request for file() can only be done by the master process" - << abort(FatalError); - } - - if (filePtrs_.size() != 1) + if (!writeToFile_) { - WarningIn("Foam::Ostream& Foam::functionObjectFile::file()") - << "Requested single file, but multiple files are present" - << endl; + return Snull; } - if (!filePtrs_.set(0)) + if (!filePtr_.valid()) { FatalErrorIn("Foam::OFstream& Foam::functionObjectFile::file()") - << "File pointer at index " << 0 << " not allocated" + << "File pointer not allocated" << abort(FatalError); } - return filePtrs_[0]; + return filePtr_(); } -Foam::PtrList<Foam::OFstream>& Foam::functionObjectFile::files() +bool Foam::functionObjectFile::writeToFile() const { - if (!Pstream::master()) - { - FatalErrorIn("Foam::OFstream& Foam::functionObjectFile::files()") - << "Request for files() can only be done by the master process" - << abort(FatalError); - } - - return filePtrs_; -} - - -Foam::OFstream& Foam::functionObjectFile::file(const label i) -{ - if (!Pstream::master()) - { - FatalErrorIn - ( - "Foam::OFstream& Foam::functionObjectFile::file(const label)" - ) - << "Request for file(i) can only be done by the master process" - << abort(FatalError); - } - - if (!filePtrs_.set(i)) - { - FatalErrorIn("Foam::OFstream& Foam::functionObjectFile::file()") - << "File pointer at index " << i << " not allocated" - << abort(FatalError); - } - - return filePtrs_[i]; + return writeToFile_; } diff --git a/src/OpenFOAM/db/functionObjects/functionObjectFile/functionObjectFile.H b/src/OpenFOAM/db/functionObjects/functionObjectFile/functionObjectFile.H index 5b5e3597a14a737ff0d0588f64826c7b869f947b..2dfd5c7c1115346f76bff485ee5682f4f1de7ea9 100644 --- a/src/OpenFOAM/db/functionObjects/functionObjectFile/functionObjectFile.H +++ b/src/OpenFOAM/db/functionObjects/functionObjectFile/functionObjectFile.H @@ -3,7 +3,7 @@ \\ / F ield | OpenFOAM: The Open Source CFD Toolbox \\ / O peration | \\ / A nd | Copyright (C) 2012-2015 OpenFOAM Foundation - \\/ M anipulation | + \\/ M anipulation | Copyright (C) 2015 OpenCFD Ltd ------------------------------------------------------------------------------- License This file is part of OpenFOAM. @@ -57,6 +57,8 @@ namespace Foam class functionObjectFile { +private: + // Private data //- Reference to the database @@ -65,15 +67,24 @@ class functionObjectFile //- Prefix const word prefix_; - //- File names - wordList names_; + //- Name of file + word fileName_; //- File pointer - PtrList<OFstream> filePtrs_; + autoPtr<OFstream> filePtr_; + + //- Write precision + label writePrecision_; protected: + // Protected Data + + //- Flag to enable/disable writing to file + bool writeToFile_; + + // Protected Member Functions //- Initialise the output stream for writing @@ -85,20 +96,11 @@ protected: //- Return the base directory for the current time value virtual fileName baseTimeDir() const; - //- Create the output file - virtual void createFiles(); - - //- File header information - virtual void writeFileHeader(const label i = 0); - - //- Write function - virtual void write(); - - //- Reset the list of names from a wordList - virtual void resetNames(const wordList& names); + //- Return an autoPtr to a new file + virtual autoPtr<OFstream> createFile(const word& name) const; - //- Reset the list of names to a single name entry - virtual void resetName(const word& name); + //- Reset internal file pointer to new file with new name + virtual void resetFile(const word& name); //- Return the value width when writing to stream with optional offset virtual Omanip<int> valueWidth(const label offset = 0) const; @@ -118,26 +120,18 @@ public: //- Additional characters for writing static label addChars; - // Constructors //- Construct null functionObjectFile(const objectRegistry& obr, const word& prefix); - //- Construct from components - functionObjectFile - ( - const objectRegistry& obr, - const word& prefix, - const word& name - ); - - //- Construct from components + //- Construct from components and read options from dictionary functionObjectFile ( const objectRegistry& obr, const word& prefix, - const wordList& names + const word& fileName, + const dictionary& dict ); @@ -147,17 +141,14 @@ public: // Member Functions - //- Return const access to the names - const wordList& names() const; + //- Read + void read(const dictionary& dict); //- Return access to the file (if only 1) OFstream& file(); - //- Return access to the files - PtrList<OFstream>& files(); - - //- Return file 'i' - OFstream& file(const label i); + //- Return true if can write to file + bool writeToFile() const; //- Write a commented string to stream void writeCommented diff --git a/src/OpenFOAM/db/functionObjects/functionObjectList/functionObjectList.C b/src/OpenFOAM/db/functionObjects/functionObjectList/functionObjectList.C index 0c44dbbfbd47d478179b523bee447411e4bf67ab..0c93b738d245020baabe54fcd4c2092e68e37ca8 100644 --- a/src/OpenFOAM/db/functionObjects/functionObjectList/functionObjectList.C +++ b/src/OpenFOAM/db/functionObjects/functionObjectList/functionObjectList.C @@ -2,8 +2,8 @@ ========= | \\ / F ield | OpenFOAM: The Open Source CFD Toolbox \\ / O peration | - \\ / A nd | Copyright (C) 2011-2013 OpenFOAM Foundation - \\/ M anipulation | + \\ / A nd | Copyright (C) 2011-2014 OpenFOAM Foundation + \\/ M anipulation | Copyright (C) 2015 OpenCFD Ltd ------------------------------------------------------------------------------- License This file is part of OpenFOAM. @@ -29,6 +29,28 @@ License // * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * * // +void Foam::functionObjectList::createStateDict() const +{ + // Cannot set the state dictionary on construction since Time has not + // been fully initialised + stateDictPtr_.reset + ( + new IOdictionary + ( + IOobject + ( + "functionObjectProperties", + time_.timeName(), + "uniform"/word("functionObjects"), + time_, + IOobject::READ_IF_PRESENT, + IOobject::NO_WRITE + ) + ) + ); +} + + Foam::functionObject* Foam::functionObjectList::remove ( const word& key, @@ -70,6 +92,7 @@ Foam::functionObjectList::functionObjectList indices_(), time_(t), parentDict_(t.controlDict()), + stateDictPtr_(), execution_(execution), updated_(false) {} @@ -87,6 +110,7 @@ Foam::functionObjectList::functionObjectList indices_(), time_(t), parentDict_(parentDict), + stateDictPtr_(), execution_(execution), updated_(false) {} @@ -100,6 +124,28 @@ Foam::functionObjectList::~functionObjectList() // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * // +Foam::IOdictionary& Foam::functionObjectList::stateDict() +{ + if (!stateDictPtr_.valid()) + { + createStateDict(); + } + + return stateDictPtr_(); +} + + +const Foam::IOdictionary& Foam::functionObjectList::stateDict() const +{ + if (!stateDictPtr_.valid()) + { + createStateDict(); + } + + return stateDictPtr_(); +} + + void Foam::functionObjectList::clear() { PtrList<functionObject>::clear(); @@ -165,6 +211,22 @@ bool Foam::functionObjectList::execute(const bool forceWrite) } } + // Force writing of state dictionary after function object execution + if (time_.outputTime()) + { + label oldPrecision = IOstream::precision_; + IOstream::precision_ = 16; + + stateDictPtr_->writeObject + ( + IOstream::ASCII, + IOstream::currentVersion, + time_.writeCompression() + ); + + IOstream::precision_ = oldPrecision; + } + return ok; } @@ -234,6 +296,11 @@ bool Foam::functionObjectList::adjustTimeStep() bool Foam::functionObjectList::read() { + if (!stateDictPtr_.valid()) + { + createStateDict(); + } + bool ok = true; updated_ = execution_; diff --git a/src/OpenFOAM/db/functionObjects/functionObjectList/functionObjectList.H b/src/OpenFOAM/db/functionObjects/functionObjectList/functionObjectList.H index 126a1f18bbda131ebe08631197a1e959046fee61..681e135d0f888146cecf92165cdb37c17e0f36b9 100644 --- a/src/OpenFOAM/db/functionObjects/functionObjectList/functionObjectList.H +++ b/src/OpenFOAM/db/functionObjects/functionObjectList/functionObjectList.H @@ -2,8 +2,8 @@ ========= | \\ / F ield | OpenFOAM: The Open Source CFD Toolbox \\ / O peration | - \\ / A nd | Copyright (C) 2011-2013 OpenFOAM Foundation - \\/ M anipulation | + \\ / A nd | Copyright (C) 2011-2014 OpenFOAM Foundation + \\/ M anipulation | Copyright (C) 2015 OpenCFD Ltd ------------------------------------------------------------------------------- License This file is part of OpenFOAM. @@ -43,6 +43,7 @@ SourceFiles #include "functionObject.H" #include "SHA1Digest.H" #include "HashTable.H" +#include "IOdictionary.H" // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // @@ -74,6 +75,9 @@ class functionObjectList // functionObject specifications. const dictionary& parentDict_; + //- Function object properties - stores state information + mutable autoPtr<IOdictionary> stateDictPtr_; + //- Switch for the execution of the functionObjects bool execution_; @@ -83,6 +87,9 @@ class functionObjectList // Private Member Functions + //- Create state dictionary + void createStateDict() const; + //- Remove and return the function object pointer by name, // and returns the old index via the parameter. // Returns a NULL pointer (and index -1) if it didn't exist. @@ -136,6 +143,12 @@ public: //- Access to the functionObjects using PtrList<functionObject>::operator[]; + //- Return the state dictionary + IOdictionary& stateDict(); + + //- Return const access to the state dictionary + const IOdictionary& stateDict() const; + //- Clear the list of function objects virtual void clear(); diff --git a/src/OpenFOAM/db/functionObjects/functionObjectState/functionObjectState.C b/src/OpenFOAM/db/functionObjects/functionObjectState/functionObjectState.C new file mode 100644 index 0000000000000000000000000000000000000000..37d57d06f10cafda562a9e1b83bc29837d518507 --- /dev/null +++ b/src/OpenFOAM/db/functionObjects/functionObjectState/functionObjectState.C @@ -0,0 +1,173 @@ +/*---------------------------------------------------------------------------*\ + ========= | + \\ / F ield | OpenFOAM: The Open Source CFD Toolbox + \\ / O peration | + \\ / A nd | Copyright (C) 2015 OpenFOAM Foundation + \\/ M anipulation | Copyright (C) 2015 OpenCFD Ltd +------------------------------------------------------------------------------- +License + This file is part of OpenFOAM. + + OpenFOAM is free software: you can redistribute it and/or modify it + under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + OpenFOAM is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + for more details. + + You should have received a copy of the GNU General Public License + along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>. + +\*---------------------------------------------------------------------------*/ + +#include "functionObjectState.H" +#include "Time.H" + +const Foam::word Foam::functionObjectState::resultsName_ = "results"; + + +// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * // + +Foam::functionObjectState::functionObjectState +( + const objectRegistry& obr, + const word& name +) +: + obr_(obr), + name_(name), + active_(true), + stateDict_ + ( + const_cast<IOdictionary&>(obr.time().functionObjects().stateDict()) + ) +{} + + +// * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * // + +Foam::functionObjectState::~functionObjectState() +{} + + +// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * // + +const Foam::word& Foam::functionObjectState::name() const +{ + return name_; +} + + +bool Foam::functionObjectState::active() const +{ + return active_; +} + + +const Foam::IOdictionary& Foam::functionObjectState::stateDict() const +{ + return stateDict_; +} + + +Foam::dictionary& Foam::functionObjectState::propertyDict() +{ + if (!stateDict_.found(name_)) + { + stateDict_.add(name_, dictionary()); + } + + return stateDict_.subDict(name_); +} + + +bool Foam::functionObjectState::foundProperty(const word& entryName) const +{ + if (stateDict_.found(name_)) + { + const dictionary& baseDict = stateDict_.subDict(name_); + return baseDict.found(entryName); + } + + return false; +} + + +Foam::word Foam::functionObjectState::resultType(const word& entryName) const +{ + return objectResultType(name_, entryName); +} + + +Foam::word Foam::functionObjectState::objectResultType +( + const word& objectName, + const word& entryName +) const +{ + word result = word::null; + + if (stateDict_.found(resultsName_)) + { + const dictionary& resultsDict = stateDict_.subDict(resultsName_); + + if (resultsDict.found(objectName)) + { + const dictionary& objectDict = resultsDict.subDict(objectName); + + forAllConstIter(dictionary, objectDict, iter) + { + const dictionary& dict = iter().dict(); + + if (dict.found(entryName)) + { + return dict.dictName(); + } + } + } + } + + return result; +} + + +Foam::List<Foam::word> Foam::functionObjectState::objectResultEntries() const +{ + return objectResultEntries(name_); +} + + +Foam::List<Foam::word> Foam::functionObjectState::objectResultEntries +( + const word& objectName +) const +{ + DynamicList<word> result(2); + + if (stateDict_.found(resultsName_)) + { + const dictionary& resultsDict = stateDict_.subDict(resultsName_); + + if (resultsDict.found(objectName)) + { + const dictionary& objectDict = resultsDict.subDict(objectName); + + forAllConstIter(dictionary, objectDict, iter) + { + const dictionary& dict = iter().dict(); + result.append(dict.toc()); + } + } + } + + wordList entries; + entries.transfer(result); + + return entries; +} + + +// ************************************************************************* // diff --git a/src/OpenFOAM/db/functionObjects/functionObjectState/functionObjectState.H b/src/OpenFOAM/db/functionObjects/functionObjectState/functionObjectState.H new file mode 100644 index 0000000000000000000000000000000000000000..c3c8b94c7ab561750d7c2c7a3b8164c6b8a19f5b --- /dev/null +++ b/src/OpenFOAM/db/functionObjects/functionObjectState/functionObjectState.H @@ -0,0 +1,255 @@ +/*---------------------------------------------------------------------------*\ + ========= | + \\ / F ield | OpenFOAM: The Open Source CFD Toolbox + \\ / O peration | + \\ / A nd | Copyright (C) 2015 OpenFOAM Foundation + \\/ M anipulation | Copyright (C) 2015 OpenCFD Ltd +------------------------------------------------------------------------------- +License + This file is part of OpenFOAM. + + OpenFOAM is free software: you can redistribute it and/or modify it + under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + OpenFOAM is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + for more details. + + You should have received a copy of the GNU General Public License + along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>. + +Class + Foam::functionObjectState + +Description + Base class for function objects, adding functionality to read/write state + information (data required for smooth restart behaviour) and results + to/from the state dictionary + +See Also + Foam::functionObject + +SourceFiles + functionObjectState.C + +\*---------------------------------------------------------------------------*/ + +#ifndef functionObjectState_H +#define functionObjectState_H + +#include "objectRegistry.H" +#include "IOdictionary.H" + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +namespace Foam +{ + +/*---------------------------------------------------------------------------*\ + Class functionObjectState Declaration +\*---------------------------------------------------------------------------*/ + +class functionObjectState +{ +private: + + // Private data + + //- Name of the results dictionary + static const word resultsName_; + + //- Reference to the database + const objectRegistry& obr_; + + +protected: + + // Protected data + + //- Name of model + const word name_; + + //- Flag to indicate whether the object is active + bool active_; + + //- Reference to the state dictionary + IOdictionary& stateDict_; + + +protected: + + // Protected Member Functions + + //- Disallow default bitwise copy construct + functionObjectState(const functionObjectState&); + + //- Disallow default bitwise assignment + void operator=(const functionObjectState&); + + +public: + + // Constructors + + //- Construct from components + functionObjectState + ( + const objectRegistry& obr, + const word& name + ); + + + //- Destructor + virtual ~functionObjectState(); + + + // Member Functions + + //- Return the name + const word& name() const; + + //- Return the active flag + bool active() const; + + //- Return access to the state dictionary + const IOdictionary& stateDict() const; + + //- Return access to the property dictionary + dictionary& propertyDict(); + + //- Set the active status by querying objectRegistry type + // returns new active status + template<class Type> + bool setActive(); + + + // Properties + + //- Return true if the property exists + bool foundProperty(const word& entryName) const; + + //- Retrieve generic property + template<class Type> + Type getProperty + ( + const word& entryName, + const Type& defaultValue = pTraits<Type>::zero + ) const; + + //- Retrieve generic property + template<class Type> + void getProperty(const word& entryName, Type& value) const; + + //- Add generic property + template<class Type> + void setProperty(const word& entryName, const Type& value); + + //- Retrieve generic property from named object + template<class Type> + Type getObjectProperty + ( + const word& objectName, + const word& entryName, + const Type& defaultValue = pTraits<Type>::zero + ) const; + + //- Retrieve generic property from named object + template<class Type> + void getObjectProperty + ( + const word& objectName, + const word& entryName, + Type& value + ) const; + + //- Add generic property from named object + template<class Type> + void setObjectProperty + ( + const word& objectName, + const word& entryName, + const Type& value + ); + + + // Results + + //- Add result + template<class Type> + void setResult + ( + const word& entryName, + const Type& value + ); + + //- Add result from named object + template<class Type> + void setObjectResult + ( + const word& objectName, + const word& entryName, + const Type& value + ); + + //- Retrieve result + template<class Type> + Type getResult + ( + const word& entryName, + const Type& defaultValue = pTraits<Type>::zero + ) const; + + //- Retrieve result from named object + template<class Type> + Type getObjectResult + ( + const word& objectName, + const word& entryName, + const Type& defaultValue = pTraits<Type>::zero + ) const; + + //- Retrieve result from named object + template<class Type> + void getObjectResult + ( + const word& objectName, + const word& entryName, + Type& value + ) const; + + //- Retrieve the result type + word resultType(const word& entryName) const; + + //- Return the type of result + word objectResultType + ( + const word& objectName, + const word& entryName + ) const; + + //- Retrieve the result entries + List<word> objectResultEntries() const; + + //- Return result entries for named object + List<word> objectResultEntries(const word& objectName) const; +}; + + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +} // End namespace Foam + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +#ifdef NoRepository + #include "functionObjectStateTemplates.C" +#endif + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +#endif + +// ************************************************************************* // diff --git a/src/OpenFOAM/db/functionObjects/functionObjectState/functionObjectStateTemplates.C b/src/OpenFOAM/db/functionObjects/functionObjectState/functionObjectStateTemplates.C new file mode 100644 index 0000000000000000000000000000000000000000..fb27b2668c021457a718ed23526675b4effac6d8 --- /dev/null +++ b/src/OpenFOAM/db/functionObjects/functionObjectState/functionObjectStateTemplates.C @@ -0,0 +1,242 @@ +/*---------------------------------------------------------------------------*\ + ========= | + \\ / F ield | OpenFOAM: The Open Source CFD Toolbox + \\ / O peration | + \\ / A nd | Copyright (C) 2015 OpenFOAM Foundation + \\/ M anipulation | Copyright (C) 2015 OpenCFD Ltd +------------------------------------------------------------------------------- +License + This file is part of OpenFOAM. + + OpenFOAM is free software: you can redistribute it and/or modify it + under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + OpenFOAM is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + for more details. + + You should have received a copy of the GNU General Public License + along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>. + +\*---------------------------------------------------------------------------*/ + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +template<class Type> +bool Foam::functionObjectState::setActive() +{ + active_ = true; + + if (!isA<Type>(obr_)) + { + WarningIn + ( + "void Foam::functionObjectState::setActive()" + ) << "No " << Type::typeName << " available, deactivating " << name_ + << endl; + + active_ = false; + } + + return active_; +} + + +template<class Type> +Type Foam::functionObjectState::getProperty +( + const word& entryName, + const Type& defaultValue +) const +{ + Type result = defaultValue; + getProperty(entryName, result); + return result; +} + + +template<class Type> +void Foam::functionObjectState::getProperty +( + const word& entryName, + Type& value +) const +{ + getObjectProperty(name_, entryName, value); +} + + +template<class Type> +void Foam::functionObjectState::setProperty +( + const word& entryName, + const Type& value +) +{ + setObjectProperty(name_, entryName, value); +} + + +template<class Type> +Type Foam::functionObjectState::getObjectProperty +( + const word& objectName, + const word& entryName, + const Type& defaultValue +) const +{ + Type result = defaultValue; + getObjectProperty(objectName, entryName, result); + return result; +} + + +template<class Type> +void Foam::functionObjectState::getObjectProperty +( + const word& objectName, + const word& entryName, + Type& value +) const +{ + if (stateDict_.found(objectName)) + { + const dictionary& baseDict = stateDict_.subDict(objectName); + if (baseDict.found(entryName)) + { + if (baseDict.isDict(entryName)) + { + value = baseDict.subDict(entryName); + } + else + { + baseDict.lookup(entryName) >> value; + } + } + } +} + + +template<class Type> +void Foam::functionObjectState::setObjectProperty +( + const word& objectName, + const word& entryName, + const Type& value +) +{ + if (!stateDict_.found(objectName)) + { + stateDict_.add(objectName, dictionary()); + } + + dictionary& baseDict = stateDict_.subDict(objectName); + baseDict.add(entryName, value, true); +} + + +template<class Type> +void Foam::functionObjectState::setResult +( + const word& entryName, + const Type& value +) +{ + setObjectResult(name_, entryName, value); +} + + +template<class Type> +void Foam::functionObjectState::setObjectResult +( + const word& objectName, + const word& entryName, + const Type& value +) +{ + if (!stateDict_.found(resultsName_)) + { + stateDict_.add(resultsName_, dictionary()); + } + + dictionary& resultsDict = stateDict_.subDict(resultsName_); + + if (!resultsDict.found(objectName)) + { + resultsDict.add(name_, dictionary()); + } + + dictionary& objectDict = resultsDict.subDict(objectName); + + const word& dictTypeName = pTraits<Type>::typeName; + + if (!objectDict.found(dictTypeName)) + { + objectDict.add(dictTypeName, dictionary()); + } + + dictionary& resultTypeDict = objectDict.subDict(dictTypeName); + + resultTypeDict.add(entryName, value, true); +} + + +template<class Type> +Type Foam::functionObjectState::getResult +( + const word& entryName, + const Type& defaultValue +) const +{ + return getObjectResult(name_, entryName, defaultValue); +} + + +template<class Type> +Type Foam::functionObjectState::getObjectResult +( + const word& objectName, + const word& entryName, + const Type& defaultValue +) const +{ + Type result = defaultValue; + getObjectResult(objectName, entryName, result); + return result; +} + + +template<class Type> +void Foam::functionObjectState::getObjectResult +( + const word& objectName, + const word& entryName, + Type& value +) const +{ + if (stateDict_.found(resultsName_)) + { + const dictionary& resultsDict = stateDict_.subDict(resultsName_); + + if (resultsDict.found(objectName)) + { + const dictionary& objectDict = resultsDict.subDict(objectName); + + const word& dictTypeName = pTraits<Type>::typeName; + + if (objectDict.found(dictTypeName)) + { + const dictionary& resultTypeDict = + objectDict.subDict(dictTypeName); + + resultTypeDict.readIfPresent<Type>(entryName, value); + } + } + } +} + + +// ************************************************************************* // diff --git a/src/OpenFOAM/primitives/functions/DataEntry/Constant/Constant.C b/src/OpenFOAM/primitives/functions/DataEntry/Constant/Constant.C index e4f60195a840533e725cccc8d3e4d431f5c1f9d1..87a78b64cb781b05b2e7f8e72d3fa4797c6f9501 100644 --- a/src/OpenFOAM/primitives/functions/DataEntry/Constant/Constant.C +++ b/src/OpenFOAM/primitives/functions/DataEntry/Constant/Constant.C @@ -3,7 +3,7 @@ \\ / F ield | OpenFOAM: The Open Source CFD Toolbox \\ / O peration | \\ / A nd | Copyright (C) 2011-2015 OpenFOAM Foundation - \\/ M anipulation | + \\/ M anipulation | Copyright (C) 2015 OpenCFD Ltd ------------------------------------------------------------------------------- License This file is part of OpenFOAM. @@ -55,6 +55,20 @@ Foam::Constant<Type>::Constant(const word& entryName, const dictionary& dict) } +template<class Type> +Foam::Constant<Type>::Constant +( + const word& entryName, + const Type& value, + const dimensionSet& dimensions +) +: + DataEntry<Type>(entryName), + value_(value), + dimensions_(dimensions) +{} + + template<class Type> Foam::Constant<Type>::Constant(const Constant<Type>& cnst) : diff --git a/src/OpenFOAM/primitives/functions/DataEntry/Constant/Constant.H b/src/OpenFOAM/primitives/functions/DataEntry/Constant/Constant.H index 0c251fec033c4775487bf91c3f7d04ab2e3085a3..024eca67259c990570e8f4d6886594c66811e3f6 100644 --- a/src/OpenFOAM/primitives/functions/DataEntry/Constant/Constant.H +++ b/src/OpenFOAM/primitives/functions/DataEntry/Constant/Constant.H @@ -3,7 +3,7 @@ \\ / F ield | OpenFOAM: The Open Source CFD Toolbox \\ / O peration | \\ / A nd | Copyright (C) 2011 OpenFOAM Foundation - \\/ M anipulation | + \\/ M anipulation | Copyright (C) 2015 OpenCFD Ltd ------------------------------------------------------------------------------- License This file is part of OpenFOAM. @@ -86,7 +86,15 @@ public: // Constructors - //- Construct from entry name and Istream + //- Construct from components + Constant + ( + const word& entryName, + const Type& value, + const dimensionSet& dimensions = dimless + ); + + //- Construct from entry name and dictionary Constant(const word& entryName, const dictionary& dict); //- Copy constructor diff --git a/src/postProcessing/functionObjects/IO/IOFunctionObjectsDoc.H b/src/postProcessing/functionObjects/IO/doc/IOFunctionObjectsDoc.H similarity index 100% rename from src/postProcessing/functionObjects/IO/IOFunctionObjectsDoc.H rename to src/postProcessing/functionObjects/IO/doc/IOFunctionObjectsDoc.H diff --git a/src/postProcessing/functionObjects/cloud/cloudInfo/cloudInfo.C b/src/postProcessing/functionObjects/cloud/cloudInfo/cloudInfo.C index 480d5fa8be0de617ad564bbb122c6b59dd30ab5a..fd58741bd7419a3aa5d40cd19aacde1361b35c22 100644 --- a/src/postProcessing/functionObjects/cloud/cloudInfo/cloudInfo.C +++ b/src/postProcessing/functionObjects/cloud/cloudInfo/cloudInfo.C @@ -3,7 +3,7 @@ \\ / F ield | OpenFOAM: The Open Source CFD Toolbox \\ / O peration | \\ / A nd | Copyright (C) 2012-2015 OpenFOAM Foundation - \\/ M anipulation | + \\/ M anipulation | Copyright (C) 2015 OpenCFD Ltd ------------------------------------------------------------------------------- License This file is part of OpenFOAM. @@ -37,13 +37,16 @@ namespace Foam // * * * * * * * * * * * * Protected Member Functions * * * * * * * * * * * // -void Foam::cloudInfo::writeFileHeader(const label i) +void Foam::cloudInfo::writeFileHeader(Ostream& os) const { - writeHeader(file(), "Cloud information"); - writeCommented(file(), "Time"); - writeTabbed(file(), "nParcels"); - writeTabbed(file(), "mass"); - file() << endl; + writeHeader(os, "Cloud information"); + writeCommented(os, "Time"); + writeTabbed(os, "nParcels"); + writeTabbed(os, "mass"); + writeTabbed(os, "Dmax"); + writeTabbed(os, "D10"); + writeTabbed(os, "D32"); + os << endl; } @@ -60,7 +63,10 @@ Foam::cloudInfo::cloudInfo functionObjectFile(obr, name), name_(name), obr_(obr), - active_(true) + active_(true), + log_(true), + cloudNames_(), + filePtrs_() { read(dict); } @@ -78,47 +84,70 @@ void Foam::cloudInfo::read(const dictionary& dict) { if (active_) { - functionObjectFile::resetNames(dict.lookup("clouds")); + functionObjectFile::read(dict); - Info<< type() << " " << name_ << ": "; - if (names().size()) + log_ = dict.lookupOrDefault<Switch>("log", true); + dict.lookup("clouds") >> cloudNames_; + + if (log_) { - Info<< "applying to clouds:" << nl; - forAll(names(), i) + Info<< type() << " " << name_ << ": "; + + if (cloudNames_.size()) + { + Info<< "applying to clouds:" << nl; + forAll(cloudNames_, i) + { + Info<< " " << cloudNames_[i] << nl; + } + Info<< endl; + } + else { - Info<< " " << names()[i] << nl; + Info<< "no clouds to be processed" << nl << endl; } - Info<< endl; } - else + + if (writeToFile()) { - Info<< "no clouds to be processed" << nl << endl; + filePtrs_.setSize(cloudNames_.size()); + filePtrs_.clear(); + forAll(filePtrs_, fileI) + { + const word& cloudName = cloudNames_[fileI]; + filePtrs_.set(fileI, createFile(cloudName)); + writeFileHeader(filePtrs_[fileI]); + } } } } void Foam::cloudInfo::execute() -{} +{ + // Do nothing +} void Foam::cloudInfo::end() -{} +{ + // Do nothing +} void Foam::cloudInfo::timeSet() -{} +{ + // Do nothing +} void Foam::cloudInfo::write() { if (active_) { - functionObjectFile::write(); - - forAll(names(), i) + forAll(cloudNames_, cloudI) { - const word& cloudName = names()[i]; + const word& cloudName = cloudNames_[cloudI]; const kinematicCloud& cloud = obr_.lookupObject<kinematicCloud>(cloudName); @@ -127,12 +156,31 @@ void Foam::cloudInfo::write() scalar massInSystem = returnReduce(cloud.massInSystem(), sumOp<scalar>()); + scalar Dmax = cloud.Dmax(); + scalar D10 = cloud.Dij(1, 0); + scalar D32 = cloud.Dij(3, 2); + if (Pstream::master()) { - file(i) + filePtrs_[cloudI] << obr_.time().value() << token::TAB << nParcels << token::TAB - << massInSystem << endl; + << massInSystem << token::TAB + << Dmax << token::TAB + << D10 << token::TAB + << D32 << token::TAB + << endl; + } + + if (log_) + { + Info<< type() << " " << name_ << " output:" << nl + << " number of parcels : " << nParcels << nl + << " mass in system : " << massInSystem << nl + << " maximum diameter : " << Dmax << nl + << " D10 diameter : " << D10 << nl + << " D32 diameter : " << D32 << nl + << endl; } } } diff --git a/src/postProcessing/functionObjects/cloud/cloudInfo/cloudInfo.H b/src/postProcessing/functionObjects/cloud/cloudInfo/cloudInfo.H index 9bd17610612ed8ffe80bada458f2e1c8a45aacc4..9e160bbab46d338836ea3c201c81e07b66bdc88c 100644 --- a/src/postProcessing/functionObjects/cloud/cloudInfo/cloudInfo.H +++ b/src/postProcessing/functionObjects/cloud/cloudInfo/cloudInfo.H @@ -2,8 +2,8 @@ ========= | \\ / F ield | OpenFOAM: The Open Source CFD Toolbox \\ / O peration | - \\ / A nd | Copyright (C) 2012-2013 OpenFOAM Foundation - \\/ M anipulation | + \\ / A nd | Copyright (C) 2012-2015 OpenFOAM Foundation + \\/ M anipulation | Copyright (C) 2015 OpenCFD Ltd ------------------------------------------------------------------------------- License This file is part of OpenFOAM. @@ -109,11 +109,20 @@ protected: //- on/off switch bool active_; + //- Switch to send output to Info as well + Switch log_; + + //- List of cloud names + wordList cloudNames_; + + //- Output file per cloud + PtrList<OFstream> filePtrs_; + // Protected Member Functions //- File header information - virtual void writeFileHeader(const label i); + virtual void writeFileHeader(Ostream& os) const; //- Disallow default bitwise copy construct cloudInfo(const cloudInfo&); diff --git a/src/postProcessing/functionObjects/cloud/cloudFunctionObjectsDoc.H b/src/postProcessing/functionObjects/cloud/doc/cloudFunctionObjectsDoc.H similarity index 100% rename from src/postProcessing/functionObjects/cloud/cloudFunctionObjectsDoc.H rename to src/postProcessing/functionObjects/cloud/doc/cloudFunctionObjectsDoc.H diff --git a/src/postProcessing/functionObjects/doc/functionObjects.dox b/src/postProcessing/functionObjects/doc/functionObjects.dox index 4fa79c730c1a63978b976666c180684901af3a43..dc0b395fe8c3efb6b17360e24de7b5c47f8205ec 100644 --- a/src/postProcessing/functionObjects/doc/functionObjects.dox +++ b/src/postProcessing/functionObjects/doc/functionObjects.dox @@ -3,7 +3,7 @@ \\ / F ield | OpenFOAM: The Open Source CFD Toolbox \\ / O peration | \\ / A nd | Copyright (C) 2012-2014 OpenFOAM Foundation - \\/ M anipulation | + \\/ M anipulation | Copyright (C) 2015 OpenCFD Ltd ------------------------------------------------------------------------------- License This file is part of OpenFOAM. @@ -63,6 +63,8 @@ functions enabled yes; timeStart 0; timeEnd 10; + evaluateControl timeStep; + evaluateInterval 1; outputControl outputTime; outputInterval 1; ... @@ -78,7 +80,9 @@ Where: region | name of region for multi-region cases | no | enabled | on/off switch | no | yes timeStart| start time | no | - timeEnd | end time | no | + timeEnd | end time | no | + evaluateControl | when to evaluate: either 'outputTime' or 'timeStep'| no | timeStep + evaluateInterval| steps between evaluation when evaluateControl=timeStep | no | 1 outputControl | when to output: either 'outputTime' or 'timeStep'| no | timeStep outputInterval| steps between output when outputControl=timeStep | no | 1 \endtable @@ -88,7 +92,7 @@ typically used as the name of the output directory for any derived data. The \c type entry defines the type of function object properties that follow. Since the function objects are packaged into separate libraries, the user must tell the code where to find the function object implementation, identified -using the \c libs entry. +using the \c functionObjectLibs entry. \*---------------------------------------------------------------------------*/ diff --git a/src/postProcessing/functionObjects/field/fieldFunctionObjectsDoc.H b/src/postProcessing/functionObjects/field/doc/fieldFunctionObjectsDoc.H similarity index 100% rename from src/postProcessing/functionObjects/field/fieldFunctionObjectsDoc.H rename to src/postProcessing/functionObjects/field/doc/fieldFunctionObjectsDoc.H diff --git a/src/postProcessing/functionObjects/field/fieldAverage/fieldAverage/fieldAverage.C b/src/postProcessing/functionObjects/field/fieldAverage/fieldAverage/fieldAverage.C index 62407d83162db71c162c23dbeffae4e0e55468ea..5652904ffa30b7df27e6d0971ef16709c2400aea 100644 --- a/src/postProcessing/functionObjects/field/fieldAverage/fieldAverage/fieldAverage.C +++ b/src/postProcessing/functionObjects/field/fieldAverage/fieldAverage/fieldAverage.C @@ -3,7 +3,7 @@ \\ / F ield | OpenFOAM: The Open Source CFD Toolbox \\ / O peration | \\ / A nd | Copyright (C) 2011-2015 OpenFOAM Foundation - \\/ M anipulation | + \\/ M anipulation | Copyright (C) 2015 OpenCFD Ltd ------------------------------------------------------------------------------- License This file is part of OpenFOAM. @@ -66,7 +66,8 @@ void Foam::fieldAverage::initialize() { resetFields(); - Info<< type() << " " << name_ << ":" << nl; + if (log_) Info << type() << " " << name_ << ":" << nl; + // Add mean fields to the field lists forAll(faItems_, fieldI) @@ -98,7 +99,7 @@ void Foam::fieldAverage::initialize() // ensure first averaging works unconditionally prevTimeIndex_ = -1; - Info<< endl; + if (log_) Info << endl; initialised_ = true; } @@ -123,9 +124,11 @@ void Foam::fieldAverage::calcAverages() prevTimeIndex_ = currentTimeIndex; } - Info<< type() << " " << name_ << " output:" << nl; - - Info<< " Calculating averages" << nl; + if (log_) + { + Info<< type() << " " << name_ << " output:" << nl + << " Calculating averages" << nl; + } addMeanSqrToPrime2Mean<scalar, scalar>(); addMeanSqrToPrime2Mean<vector, symmTensor>(); @@ -149,7 +152,7 @@ void Foam::fieldAverage::calcAverages() void Foam::fieldAverage::writeAverages() const { - Info<< " Writing average fields" << endl; + if (log_) Info << " Writing average fields" << endl; writeFields<scalar>(); writeFields<vector>(); @@ -159,31 +162,17 @@ void Foam::fieldAverage::writeAverages() const } -void Foam::fieldAverage::writeAveragingProperties() const +void Foam::fieldAverage::writeAveragingProperties() { - IOdictionary propsDict - ( - IOobject - ( - "fieldAveragingProperties", - obr_.time().timeName(), - "uniform", - obr_, - IOobject::NO_READ, - IOobject::NO_WRITE, - false - ) - ); - forAll(faItems_, fieldI) { const word& fieldName = faItems_[fieldI].fieldName(); - propsDict.add(fieldName, dictionary()); - propsDict.subDict(fieldName).add("totalIter", totalIter_[fieldI]); - propsDict.subDict(fieldName).add("totalTime", totalTime_[fieldI]); - } - propsDict.regIOobject::write(); + dictionary propsDict; + propsDict.add("totalIter", totalIter_[fieldI]); + propsDict.add("totalTime", totalTime_[fieldI]); + setProperty(fieldName, propsDict); + } } @@ -195,46 +184,41 @@ void Foam::fieldAverage::readAveragingProperties() totalTime_.clear(); totalTime_.setSize(faItems_.size(), obr_.time().deltaTValue()); - if (resetOnRestart_ || resetOnOutput_) + if (log_ && (resetOnRestart_ || resetOnOutput_)) { Info<< " Starting averaging at time " << obr_.time().timeName() << nl; } else { - IOobject propsDictHeader - ( - "fieldAveragingProperties", - obr_.time().timeName(obr_.time().startTime().value()), - "uniform", - obr_, - IOobject::MUST_READ_IF_MODIFIED, - IOobject::NO_WRITE, - false - ); - - if (!propsDictHeader.headerOk()) - { - Info<< " Starting averaging at time " << obr_.time().timeName() - << nl; - return; - } - - IOdictionary propsDict(propsDictHeader); + if (log_) Info << " Restarting averaging for fields:" << nl; - Info<< " Restarting averaging for fields:" << nl; forAll(faItems_, fieldI) { const word& fieldName = faItems_[fieldI].fieldName(); - if (propsDict.found(fieldName)) + if (foundProperty(fieldName)) { - dictionary fieldDict(propsDict.subDict(fieldName)); + dictionary fieldDict; + getProperty(fieldName, fieldDict); totalIter_[fieldI] = readLabel(fieldDict.lookup("totalIter")); totalTime_[fieldI] = readScalar(fieldDict.lookup("totalTime")); - Info<< " " << fieldName - << " iters = " << totalIter_[fieldI] - << " time = " << totalTime_[fieldI] << nl; + + if (log_) + { + Info<< " " << fieldName + << " iters = " << totalIter_[fieldI] + << " time = " << totalTime_[fieldI] << nl; + } + } + else + { + if (log_) + { + Info<< " " << fieldName + << ": starting averaging at time " + << obr_.time().timeName() << endl; + } } } } @@ -251,37 +235,22 @@ Foam::fieldAverage::fieldAverage const bool loadFromFiles ) : - name_(name), + functionObjectState(obr, name), obr_(obr), - active_(true), prevTimeIndex_(-1), resetOnRestart_(false), resetOnOutput_(false), + log_(true), initialised_(false), faItems_(), totalIter_(), totalTime_() { // Only active if a fvMesh is available - if (isA<fvMesh>(obr_)) + if (setActive<fvMesh>()) { read(dict); } - else - { - active_ = false; - WarningIn - ( - "fieldAverage::fieldAverage" - "(" - "const word&, " - "const objectRegistry&, " - "const dictionary&, " - "const bool " - ")" - ) << "No fvMesh available, deactivating " << name_ << nl - << endl; - } } @@ -299,7 +268,9 @@ void Foam::fieldAverage::read(const dictionary& dict) { initialised_ = false; - Info<< type() << " " << name_ << ":" << nl; + log_.readIfPresent("log", dict); + + if (log_) Info << type() << " " << name_ << ":" << nl; dict.readIfPresent("resetOnRestart", resetOnRestart_); dict.readIfPresent("resetOnOutput", resetOnOutput_); @@ -307,7 +278,7 @@ void Foam::fieldAverage::read(const dictionary& dict) readAveragingProperties(); - Info<< endl; + if (log_) Info << endl; } } @@ -317,7 +288,7 @@ void Foam::fieldAverage::execute() if (active_) { calcAverages(); - Info<< endl; + if (log_) Info << endl; } } @@ -326,8 +297,7 @@ void Foam::fieldAverage::end() { if (active_) { - calcAverages(); - Info<< endl; + execute(); } } @@ -345,8 +315,11 @@ void Foam::fieldAverage::write() if (resetOnOutput_) { - Info<< " Restarting averaging at time " << obr_.time().timeName() - << nl << endl; + if (log_) + { + Info<< " Restarting averaging at time " << obr_.time().timeName() + << nl << endl; + } totalIter_.clear(); totalIter_.setSize(faItems_.size(), 1); @@ -357,7 +330,7 @@ void Foam::fieldAverage::write() initialize(); } - Info<< endl; + if (log_) Info << endl; } } diff --git a/src/postProcessing/functionObjects/field/fieldAverage/fieldAverage/fieldAverage.H b/src/postProcessing/functionObjects/field/fieldAverage/fieldAverage/fieldAverage.H index 01b25580104f04839231dc18657f67d68e9b9e0c..748b4ee168411c051702ed69a72ae17b7a329753 100644 --- a/src/postProcessing/functionObjects/field/fieldAverage/fieldAverage/fieldAverage.H +++ b/src/postProcessing/functionObjects/field/fieldAverage/fieldAverage/fieldAverage.H @@ -3,7 +3,7 @@ \\ / F ield | OpenFOAM: The Open Source CFD Toolbox \\ / O peration | \\ / A nd | Copyright (C) 2011-2013 OpenFOAM Foundation - \\/ M anipulation | + \\/ M anipulation | Copyright (C) 2015 OpenCFD Ltd ------------------------------------------------------------------------------- License This file is part of OpenFOAM. @@ -94,9 +94,10 @@ Description \table Property | Description | Required | Default value type | type name: fieldAverage | yes | - resetOnRestart | flag to reset the averaging on restart | yes | + resetOnRestart | flag to reset the averaging on restart | yes | resetOnOutput| flag to reset the averaging on output | yes | fields | list of fields and averaging options | yes | + log | Log to standard output | no | yes \endtable @@ -117,6 +118,7 @@ SourceFiles #ifndef fieldAverage_H #define fieldAverage_H +#include "functionObjectState.H" #include "volFieldsFwd.H" #include "Switch.H" @@ -139,20 +141,16 @@ class mapPolyMesh; \*---------------------------------------------------------------------------*/ class fieldAverage +: + public functionObjectState { protected: // Protected data - //- Name of this set of field averages. - word name_; - - //- Database this class is registered to + //- Reference to the database const objectRegistry& obr_; - //- On/off switch - bool active_; - //- Time at last call, prevents repeated averaging label prevTimeIndex_; @@ -162,6 +160,9 @@ protected: //- Reset the averaging process on output flag Switch resetOnOutput_; + //- Switch to send output to Info as well as to file + Switch log_; + //- Initialised flag bool initialised_; @@ -251,7 +252,7 @@ protected: void writeFields() const; //- Write averaging properties - steps and time - void writeAveragingProperties() const; + void writeAveragingProperties(); //- Read averaging properties - steps and time void readAveragingProperties(); diff --git a/src/postProcessing/functionObjects/field/fieldAverage/fieldAverage/fieldAverageTemplates.C b/src/postProcessing/functionObjects/field/fieldAverage/fieldAverage/fieldAverageTemplates.C index 62e733481d5334f6ffb6fbe2e2d238e85396b42c..4f3a2d7cab670b971b0bac60ffb5d30f5ce69f10 100644 --- a/src/postProcessing/functionObjects/field/fieldAverage/fieldAverage/fieldAverageTemplates.C +++ b/src/postProcessing/functionObjects/field/fieldAverage/fieldAverage/fieldAverageTemplates.C @@ -3,7 +3,7 @@ \\ / F ield | OpenFOAM: The Open Source CFD Toolbox \\ / O peration | \\ / A nd | Copyright (C) 2011-2015 OpenFOAM Foundation - \\/ M anipulation | + \\/ M anipulation | Copyright (C) 2015 OpenCFD Ltd ------------------------------------------------------------------------------- License This file is part of OpenFOAM. @@ -38,7 +38,7 @@ void Foam::fieldAverage::addMeanFieldType(const label fieldI) const word& fieldName = faItems_[fieldI].fieldName(); const word& meanFieldName = faItems_[fieldI].meanFieldName(); - Info<< " Reading/initialising field " << meanFieldName << endl; + if (log_) Info << " Reading/initialising field " << meanFieldName << endl; if (obr_.foundObject<Type>(meanFieldName)) { @@ -46,9 +46,12 @@ void Foam::fieldAverage::addMeanFieldType(const label fieldI) } else if (obr_.found(meanFieldName)) { - Info<< " Cannot allocate average field " << meanFieldName - << " since an object with that name already exists." - << " Disabling averaging for field." << endl; + if (log_) + { + Info<< " Cannot allocate average field " << meanFieldName + << " since an object with that name already exists." + << " Disabling averaging for field." << endl; + } faItems_[fieldI].mean() = false; } @@ -107,7 +110,10 @@ void Foam::fieldAverage::addPrime2MeanFieldType(const label fieldI) const word& meanFieldName = faItems_[fieldI].meanFieldName(); const word& prime2MeanFieldName = faItems_[fieldI].prime2MeanFieldName(); - Info<< " Reading/initialising field " << prime2MeanFieldName << nl; + if (log_) + { + Info << " Reading/initialising field " << prime2MeanFieldName << nl; + } if (obr_.foundObject<Type2>(prime2MeanFieldName)) { @@ -115,9 +121,12 @@ void Foam::fieldAverage::addPrime2MeanFieldType(const label fieldI) } else if (obr_.found(prime2MeanFieldName)) { - Info<< " Cannot allocate average field " << prime2MeanFieldName - << " since an object with that name already exists." - << " Disabling averaging for field." << nl; + if (log_) + { + Info<< " Cannot allocate average field " << prime2MeanFieldName + << " since an object with that name already exists." + << " Disabling averaging for field." << nl; + } faItems_[fieldI].prime2Mean() = false; } diff --git a/src/postProcessing/functionObjects/field/fieldMinMax/fieldMinMax.C b/src/postProcessing/functionObjects/field/fieldMinMax/fieldMinMax.C index dac7d8a71e0cd95512e719615a78de7ff860451e..56ce3cde087d4df018c4ad38fe6619b5cc6f4302 100644 --- a/src/postProcessing/functionObjects/field/fieldMinMax/fieldMinMax.C +++ b/src/postProcessing/functionObjects/field/fieldMinMax/fieldMinMax.C @@ -3,7 +3,7 @@ \\ / F ield | OpenFOAM: The Open Source CFD Toolbox \\ / O peration | \\ / A nd | Copyright (C) 2011-2015 OpenFOAM Foundation - \\/ M anipulation | + \\/ M anipulation | Copyright (C) 2015 OpenCFD Ltd ------------------------------------------------------------------------------- License This file is part of OpenFOAM. @@ -49,6 +49,45 @@ const Foam::NamedEnum<Foam::fieldMinMax::modeType, 2> Foam::fieldMinMax::modeTypeNames_; +// * * * * * * * * * * * * * Protected Member Functions * * * * * * * * * * // + +void Foam::fieldMinMax::writeFileHeader(Ostream& os) const +{ + writeHeader(os, "Field minima and maxima"); + writeCommented(os, "Time"); + + if (writeLocation_) + { + writeTabbed(os, "field"); + writeTabbed(os, "min"); + writeTabbed(os, "position(min)"); + + if (Pstream::parRun()) + { + writeTabbed(os, "processor"); + } + + writeTabbed(os, "max"); + writeTabbed(os, "position(max)"); + + if (Pstream::parRun()) + { + writeTabbed(os, "processor"); + } + } + else + { + forAll(fieldSet_, fieldI) + { + writeTabbed(os, "min(" + fieldSet_[fieldI] + ')'); + writeTabbed(os, "max(" + fieldSet_[fieldI] + ')'); + } + } + + os << endl; +} + + // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * // Foam::fieldMinMax::fieldMinMax @@ -59,33 +98,20 @@ Foam::fieldMinMax::fieldMinMax const bool loadFromFiles ) : - functionObjectFile(obr, name, typeName), - name_(name), + functionObjectState(obr, name), + functionObjectFile(obr, name, typeName, dict), obr_(obr), - active_(true), log_(true), - location_(true), + writeLocation_(true), mode_(mdMag), fieldSet_() { // Check if the available mesh is an fvMesh otherise deactivate - if (!isA<fvMesh>(obr_)) + if (setActive<fvMesh>()) { - active_ = false; - WarningIn - ( - "fieldMinMax::fieldMinMax" - "(" - "const word&, " - "const objectRegistry&, " - "const dictionary&, " - "const bool" - ")" - ) << "No fvMesh available, deactivating " << name_ - << endl; + read(dict); + writeFileHeader(file()); } - - read(dict); } @@ -101,8 +127,10 @@ void Foam::fieldMinMax::read(const dictionary& dict) { if (active_) { + functionObjectFile::read(dict); + log_ = dict.lookupOrDefault<Switch>("log", true); - location_ = dict.lookupOrDefault<Switch>("location", true); + writeLocation_ = dict.lookupOrDefault<Switch>("writeLocation", true); mode_ = modeTypeNames_[dict.lookupOrDefault<word>("mode", "magnitude")]; dict.lookup("fields") >> fieldSet_; @@ -110,46 +138,6 @@ void Foam::fieldMinMax::read(const dictionary& dict) } -void Foam::fieldMinMax::writeFileHeader(const label i) -{ - OFstream& file = this->file(); - - writeHeader(file, "Field minima and maxima"); - writeCommented(file, "Time"); - - if (location_) - { - writeTabbed(file, "field"); - - writeTabbed(file, "min"); - writeTabbed(file, "location(min)"); - - if (Pstream::parRun()) - { - writeTabbed(file, "processor"); - } - - writeTabbed(file, "max"); - writeTabbed(file, "location(max)"); - - if (Pstream::parRun()) - { - writeTabbed(file, "processor"); - } - } - else - { - forAll(fieldSet_, fieldI) - { - writeTabbed(file, "min(" + fieldSet_[fieldI] + ')'); - writeTabbed(file, "max(" + fieldSet_[fieldI] + ')'); - } - } - - file<< endl; -} - - void Foam::fieldMinMax::execute() { // Do nothing - only valid on write @@ -172,9 +160,7 @@ void Foam::fieldMinMax::write() { if (active_) { - functionObjectFile::write(); - - if (!location_) file()<< obr_.time().value(); + if (!writeLocation_) file()<< obr_.time().value(); if (log_) Info<< type() << " " << name_ << " output:" << nl; forAll(fieldSet_, fieldI) @@ -186,7 +172,7 @@ void Foam::fieldMinMax::write() calcMinMaxFields<tensor>(fieldSet_[fieldI], mode_); } - if (!location_) file()<< endl; + if (!writeLocation_) file()<< endl; if (log_) Info<< endl; } } diff --git a/src/postProcessing/functionObjects/field/fieldMinMax/fieldMinMax.H b/src/postProcessing/functionObjects/field/fieldMinMax/fieldMinMax.H index b2246eb9b1d07626154c9f8316fe28e8ce136ef6..2c6f45e923d412aa3f51b2e74fb515317e084bba 100644 --- a/src/postProcessing/functionObjects/field/fieldMinMax/fieldMinMax.H +++ b/src/postProcessing/functionObjects/field/fieldMinMax/fieldMinMax.H @@ -3,7 +3,7 @@ \\ / F ield | OpenFOAM: The Open Source CFD Toolbox \\ / O peration | \\ / A nd | Copyright (C) 2011-2015 OpenFOAM Foundation - \\/ M anipulation | + \\/ M anipulation | Copyright (C) 2015 OpenCFD Ltd ------------------------------------------------------------------------------- License This file is part of OpenFOAM. @@ -28,7 +28,7 @@ Group grpFieldFunctionObjects Description - This function object calculates the value and location of scalar minimim + This function object calculates the value and position of scalar minimim and maximum for a list of user-specified fields. For variables with a rank greater than zero, either the min/max of a component value or the magnitude is reported. When operating in parallel, the processor owning the value @@ -41,15 +41,11 @@ Description type fieldMinMax; functionObjectLibs ("libfieldFunctionObjects.so"); ... - write yes; + writeToFile yes; log yes; - location yes; + writeLocation yes; mode magnitude; - fields - ( - U - p - ); + fields (U p); } \endverbatim @@ -57,20 +53,24 @@ Description \table Property | Description | Required | Default value type | type name: fieldMinMax | yes | - write | write min/max data to file | no | yes - log | write min/max data to standard output | no | no - location | write location of the min/max value | no | yes + writeToFile | write min/max data to file | no | yes + log | write min/max data to standard output | no | yes + writeLocation | write location of the min/max value | no | yes mode | calculation mode: magnitude or component | no | magnitude + fields | list of fields to process | yes | \endtable Output data is written to the file \<timeDir\>/fieldMinMax.dat SeeAlso Foam::functionObject + Foam::functionObjectFile + Foam::functionObjectState Foam::OutputFilterFunctionObject SourceFiles fieldMinMax.C + fieldMinMaxTemplates.C IOfieldMinMax.H \*---------------------------------------------------------------------------*/ @@ -78,8 +78,10 @@ SourceFiles #ifndef fieldMinMax_H #define fieldMinMax_H +#include "functionObjectState.H" #include "functionObjectFile.H" #include "Switch.H" +#include "NamedEnum.H" #include "vector.H" // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // @@ -94,20 +96,24 @@ class polyMesh; class mapPolyMesh; /*---------------------------------------------------------------------------*\ - Class fieldMinMax Declaration + Class fieldMinMax Declaration \*---------------------------------------------------------------------------*/ class fieldMinMax : + public functionObjectState, public functionObjectFile { public: - enum modeType - { - mdMag, - mdCmpt - }; + // Public enumerations + + enum modeType + { + mdMag, // magnitude + mdCmpt // component + }; + protected: @@ -116,20 +122,14 @@ protected: //- Mode type names static const NamedEnum<modeType, 2> modeTypeNames_; - //- Name of this set of field min/max - // Also used as the name of the output directory - word name_; - + //- Reference to the database const objectRegistry& obr_; - //- on/off switch - bool active_; - //- Switch to send output to Info as well Switch log_; //- Switch to write location of min/max values - Switch location_; + Switch writeLocation_; //- Mode for min/max - only applicable for ranks > 0 modeType mode_; @@ -154,15 +154,16 @@ protected: const Type& maxValue ); + + //- Output file header information + virtual void writeFileHeader(Ostream& os) const; + //- Disallow default bitwise copy construct fieldMinMax(const fieldMinMax&); //- Disallow default bitwise assignment void operator=(const fieldMinMax&); - //- Output file header information - virtual void writeFileHeader(const label i); - public: @@ -189,12 +190,6 @@ public: // Member Functions - //- Return name of the set of field min/max - virtual const word& name() const - { - return name_; - } - //- Read the field min/max data virtual void read(const dictionary&); diff --git a/src/postProcessing/functionObjects/field/fieldMinMax/fieldMinMaxTemplates.C b/src/postProcessing/functionObjects/field/fieldMinMax/fieldMinMaxTemplates.C index 729500caefeae6beef0db2af575e65abf192184d..3680134b8903291b344019624a5086d573e219b7 100644 --- a/src/postProcessing/functionObjects/field/fieldMinMax/fieldMinMaxTemplates.C +++ b/src/postProcessing/functionObjects/field/fieldMinMax/fieldMinMaxTemplates.C @@ -3,7 +3,7 @@ \\ / F ield | OpenFOAM: The Open Source CFD Toolbox \\ / O peration | \\ / A nd | Copyright (C) 2011-2015 OpenFOAM Foundation - \\/ M anipulation | + \\/ M anipulation | Copyright (C) 2015 OpenCFD Ltd ------------------------------------------------------------------------------- License This file is part of OpenFOAM. @@ -43,7 +43,7 @@ void Foam::fieldMinMax::output { OFstream& file = this->file(); - if (location_) + if (writeLocation_) { file<< obr_.time().value(); @@ -95,6 +95,15 @@ void Foam::fieldMinMax::output } if (log_) Info<< endl; + + // Write state/results information + word nameStr('(' + outputName + ')'); + this->setResult("min" + nameStr, minValue); + this->setResult("min" + nameStr + "_position", minC); + this->setResult("min" + nameStr + "_processor", minProcI); + this->setResult("max" + nameStr, maxValue); + this->setResult("max" + nameStr + "_position", maxC); + this->setResult("max" + nameStr + "_processor", maxProcI); } @@ -163,33 +172,34 @@ void Foam::fieldMinMax::calcMinMaxFields } Pstream::gatherList(minVs); + Pstream::scatterList(minVs); Pstream::gatherList(minCs); + Pstream::scatterList(minCs); Pstream::gatherList(maxVs); + Pstream::scatterList(maxVs); Pstream::gatherList(maxCs); + Pstream::scatterList(maxCs); - if (Pstream::master()) - { - label minI = findMin(minVs); - scalar minValue = minVs[minI]; - const vector& minC = minCs[minI]; - - label maxI = findMax(maxVs); - scalar maxValue = maxVs[maxI]; - const vector& maxC = maxCs[maxI]; - - output - ( - fieldName, - word("mag(" + fieldName + ")"), - minC, - maxC, - minI, - maxI, - minValue, - maxValue - ); - } + label minI = findMin(minVs); + scalar minValue = minVs[minI]; + const vector& minC = minCs[minI]; + + label maxI = findMax(maxVs); + scalar maxValue = maxVs[maxI]; + const vector& maxC = maxCs[maxI]; + + output + ( + fieldName, + word("mag(" + fieldName + ")"), + minC, + maxC, + minI, + maxI, + minValue, + maxValue + ); break; } case mdCmpt: @@ -236,33 +246,34 @@ void Foam::fieldMinMax::calcMinMaxFields } Pstream::gatherList(minVs); + Pstream::scatterList(minVs); Pstream::gatherList(minCs); + Pstream::scatterList(minCs); Pstream::gatherList(maxVs); + Pstream::scatterList(maxVs); Pstream::gatherList(maxCs); + Pstream::scatterList(maxCs); - if (Pstream::master()) - { - label minI = findMin(minVs); - Type minValue = minVs[minI]; - const vector& minC = minCs[minI]; - - label maxI = findMax(maxVs); - Type maxValue = maxVs[maxI]; - const vector& maxC = maxCs[maxI]; - - output - ( - fieldName, - fieldName, - minC, - maxC, - minI, - maxI, - minValue, - maxValue - ); - } + label minI = findMin(minVs); + Type minValue = minVs[minI]; + const vector& minC = minCs[minI]; + + label maxI = findMax(maxVs); + Type maxValue = maxVs[maxI]; + const vector& maxC = maxCs[maxI]; + + output + ( + fieldName, + fieldName, + minC, + maxC, + minI, + maxI, + minValue, + maxValue + ); break; } default: @@ -274,7 +285,8 @@ void Foam::fieldMinMax::calcMinMaxFields "const word&, " "const modeType&" ")" - ) << "Unknown min/max mode: " << modeTypeNames_[mode_] + ) + << "Unknown min/max mode: " << modeTypeNames_[mode_] << exit(FatalError); } } diff --git a/src/postProcessing/functionObjects/field/fieldValues/cellSource/cellSource.C b/src/postProcessing/functionObjects/field/fieldValues/cellSource/cellSource.C index 9d4b8400c80a32c181fbe566eaf7d5e0e6e8a629..40d3ff5bf67862e8c4bc30aaf648c68f21aedcd5 100644 --- a/src/postProcessing/functionObjects/field/fieldValues/cellSource/cellSource.C +++ b/src/postProcessing/functionObjects/field/fieldValues/cellSource/cellSource.C @@ -79,8 +79,6 @@ void Foam::fieldValues::cellSource::setCellZoneCells() { case stCellZone: { - dict().lookup("sourceName") >> sourceName_; - label zoneId = mesh().cellZones().findZoneID(sourceName_); if (zoneId < 0) @@ -135,7 +133,8 @@ void Foam::fieldValues::cellSource::initialise(const dictionary& dict) WarningIn ( "Foam::fieldValues::cellSource::initialise(const dictionary&)" - ) << type() << " " << name_ << ": " + ) + << type() << " " << name_ << ": " << sourceTypeNames_[source_] << "(" << sourceName_ << "):" << nl << " Source has no cells - deactivating" << endl; @@ -145,44 +144,46 @@ void Foam::fieldValues::cellSource::initialise(const dictionary& dict) volume_ = volume(); - Info<< type() << " " << name_ << ":" - << sourceTypeNames_[source_] << "(" << sourceName_ << "):" << nl - << " total cells = " << nCells_ << nl - << " total volume = " << volume_ - << nl << endl; + if (log_) + { + Info<< type() << " " << name_ << ":" + << sourceTypeNames_[source_] << "(" << sourceName_ << "):" << nl + << " total cells = " << nCells_ << nl + << " total volume = " << volume_ + << nl << endl; + } if (dict.readIfPresent("weightField", weightFieldName_)) { - Info<< " weight field = " << weightFieldName_; + if (log_) Info << " weight field = " << weightFieldName_; } - Info<< nl << endl; + if (log_) Info << nl << endl; } -void Foam::fieldValues::cellSource::writeFileHeader(const label i) +void Foam::fieldValues::cellSource::writeFileHeader(Ostream& os) const { - writeCommented(file(), "Source : "); - file() << sourceTypeNames_[source_] << " " << sourceName_ << endl; - writeCommented(file(), "Cells : "); - file() << nCells_ << endl; - writeCommented(file(), "Volume : "); - file() << volume_ << endl; - - writeCommented(file(), "Time"); + writeHeaderValue(os, "Source", sourceTypeNames_[source_]); + writeHeaderValue(os, "Name", sourceName_); + writeHeaderValue(os, "Cells", nCells_); + writeHeaderValue(os, "Volume", volume_); + writeHeaderValue(os, "Scale factor", scaleFactor_); + + + writeCommented(os, "Time"); if (writeVolume_) { - file() << tab << "Volume"; + os << tab << "Volume"; } forAll(fields_, i) { - file() - << tab << operationTypeNames_[operation_] + os << tab << operationTypeNames_[operation_] << "(" << fields_[i] << ")"; } - file() << endl; + os << endl; } @@ -204,7 +205,11 @@ Foam::fieldValues::cellSource::cellSource weightFieldName_("none"), writeVolume_(dict.lookupOrDefault("writeVolume", false)) { - read(dict); + if (active_) + { + read(dict); + writeFileHeader(file()); + } } @@ -218,11 +223,11 @@ Foam::fieldValues::cellSource::~cellSource() void Foam::fieldValues::cellSource::read(const dictionary& dict) { - fieldValue::read(dict); - if (active_) { - // no additional info to read + fieldValue::read(dict); + + // No additional info to read initialise(dict); } } @@ -234,33 +239,34 @@ void Foam::fieldValues::cellSource::write() if (active_) { - if (Pstream::master()) + file() << obr_.time().value(); + + // Construct weight field. Note: zero size indicates unweighted + scalarField weightField; + if (weightFieldName_ != "none") { - file() << obr_.time().value(); + weightField = setFieldValues<scalar>(weightFieldName_, true); } - + if (writeVolume_) { volume_ = volume(); - if (Pstream::master()) - { - file() << tab << volume_; - } + file() << tab << volume_; if (log_) Info<< " total volume = " << volume_ << endl; } forAll(fields_, i) { const word& fieldName = fields_[i]; - bool processed = false; + bool ok = false; - processed = processed || writeValues<scalar>(fieldName); - processed = processed || writeValues<vector>(fieldName); - processed = processed || writeValues<sphericalTensor>(fieldName); - processed = processed || writeValues<symmTensor>(fieldName); - processed = processed || writeValues<tensor>(fieldName); + ok = ok || writeValues<scalar>(fieldName, weightField); + ok = ok || writeValues<vector>(fieldName, weightField); + ok = ok || writeValues<sphericalTensor>(fieldName, weightField); + ok = ok || writeValues<symmTensor>(fieldName, weightField); + ok = ok || writeValues<tensor>(fieldName, weightField); - if (!processed) + if (!ok) { WarningIn("void Foam::fieldValues::cellSource::write()") << "Requested field " << fieldName @@ -269,10 +275,7 @@ void Foam::fieldValues::cellSource::write() } } - if (Pstream::master()) - { - file()<< endl; - } + file()<< endl; if (log_) Info<< endl; } diff --git a/src/postProcessing/functionObjects/field/fieldValues/cellSource/cellSource.H b/src/postProcessing/functionObjects/field/fieldValues/cellSource/cellSource.H index 42f788d88443fc7f8d9d24a323377fc60d9dcfb1..8c59c8450d6fe274925d97a2651c71e4de81350b 100644 --- a/src/postProcessing/functionObjects/field/fieldValues/cellSource/cellSource.H +++ b/src/postProcessing/functionObjects/field/fieldValues/cellSource/cellSource.H @@ -3,7 +3,7 @@ \\ / F ield | OpenFOAM: The Open Source CFD Toolbox \\ / O peration | \\ / A nd | Copyright (C) 2011-2015 OpenFOAM Foundation - \\/ M anipulation | + \\/ M anipulation | Copyright (C) 2015 OpenCFD Ltd ------------------------------------------------------------------------------- License This file is part of OpenFOAM. @@ -62,11 +62,11 @@ Description log | Write data to standard output | no | no valueOutput | Write the raw output values | yes | writeVolume | Write the volume of the cellSource | no | - source | cell source: see below | yes | - sourceName | name of cell source if required | no | - operation | operation to perform | yes | - weightField | name of field to apply weighting | no | - fields | list of fields to operate on | yes | + source | Cell source: see below | yes | + sourceName | Name of cell source if required | no | + operation | Operation to perform | yes | + weightField | Name of field to apply weighting | no | + fields | List of fields to operate on | yes | \endtable \linebreak @@ -228,7 +228,7 @@ protected: ) const; //- Output file header information - virtual void writeFileHeader(const label i); + virtual void writeFileHeader(Ostream& os) const; public: @@ -272,7 +272,11 @@ public: //- Templated helper function to output field values template<class Type> - bool writeValues(const word& fieldName); + bool writeValues + ( + const word& fieldName, + const scalarField& weightField + ); //- Filter a field according to cellIds template<class Type> diff --git a/src/postProcessing/functionObjects/field/fieldValues/cellSource/cellSourceTemplates.C b/src/postProcessing/functionObjects/field/fieldValues/cellSource/cellSourceTemplates.C index 15030ea689cc451f206e1b1f34df8e27ec2dc103..f6f67d55e620a50efc74afb2680fed7c3879183b 100644 --- a/src/postProcessing/functionObjects/field/fieldValues/cellSource/cellSourceTemplates.C +++ b/src/postProcessing/functionObjects/field/fieldValues/cellSource/cellSourceTemplates.C @@ -3,7 +3,7 @@ \\ / F ield | OpenFOAM: The Open Source CFD Toolbox \\ / O peration | \\ / A nd | Copyright (C) 2011-2015 OpenFOAM Foundation - \\/ M anipulation | + \\/ M anipulation | Copyright (C) 2015 OpenCFD Ltd. ------------------------------------------------------------------------------- License This file is part of OpenFOAM. @@ -87,52 +87,66 @@ Type Foam::fieldValues::cellSource::processValues { case opSum: { - result = sum(values); + result = gSum(values); break; } case opSumMag: { - result = sum(cmptMag(values)); + result = gSum(cmptMag(values)); break; } case opAverage: { - result = sum(values)/values.size(); + label n = returnReduce(values.size(), sumOp<label>()); + result = gSum(values)/(scalar(n) + ROOTVSMALL); break; } case opWeightedAverage: { - result = sum(weightField*values)/sum(weightField); + label wSize = returnReduce(weightField.size(), sumOp<label>()); + + if (wSize > 0) + { + result = + gSum(weightField*values)/(gSum(weightField) + ROOTVSMALL); + } + else + { + label n = returnReduce(values.size(), sumOp<label>()); + result = gSum(values)/(scalar(n) + ROOTVSMALL); + } break; } case opVolAverage: { - result = sum(V*values)/sum(V); + result = gSum(values*V)/(gSum(V) + ROOTVSMALL); break; } case opWeightedVolAverage: { - result = sum(weightField*V*values)/sum(weightField*V); + result = gSum(weightField*V*values)/gSum(weightField*V); break; } case opVolIntegrate: { - result = sum(V*values); + result = gSum(V*values); break; } case opMin: { - result = min(values); + result = gMin(values); break; } case opMax: { - result = max(values); + result = gMax(values); break; } case opCoV: { - Type meanValue = sum(values*V)/sum(V); + const scalar sumV = gSum(V); + + Type meanValue = gSum(V*values)/sumV; const label nComp = pTraits<Type>::nComponents; @@ -142,7 +156,7 @@ Type Foam::fieldValues::cellSource::processValues scalar mean = component(meanValue, d); scalar& res = setComponent(result, d); - res = sqrt(sum(V*sqr(vals - mean))/sum(V))/mean; + res = sqrt(gSum(V*sqr(vals - mean))/sumV)/(mean + ROOTVSMALL); } break; @@ -160,7 +174,11 @@ Type Foam::fieldValues::cellSource::processValues // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * // template<class Type> -bool Foam::fieldValues::cellSource::writeValues(const word& fieldName) +bool Foam::fieldValues::cellSource::writeValues +( + const word& fieldName, + const scalarField& weightField +) { const bool ok = validField<Type>(fieldName); @@ -168,26 +186,13 @@ bool Foam::fieldValues::cellSource::writeValues(const word& fieldName) { Field<Type> values(setFieldValues<Type>(fieldName)); scalarField V(filterField(mesh().V())); - scalarField weightField(values.size(), 1.0); - if (weightFieldName_ != "none") + if (valueOutput_) { - weightField = setFieldValues<scalar>(weightFieldName_, true); - } - - // Combine onto master - combineFields(values); - combineFields(V); - combineFields(weightField); - - if (Pstream::master()) - { - Type result = processValues(values, V, weightField); - - // Add to result dictionary, over-writing any previous entry - resultDict_.add(fieldName, result, true); + Field<Type> allValues(values); + combineFields(allValues); - if (valueOutput_) + if (Pstream::master()) { IOField<Type> ( @@ -200,17 +205,29 @@ bool Foam::fieldValues::cellSource::writeValues(const word& fieldName) IOobject::NO_READ, IOobject::NO_WRITE ), - weightField*values + allValues ).write(); } + } + + // Apply scale factor + values *= scaleFactor_; + Type result = processValues(values, V, weightField); - file()<< tab << result; + file()<< tab << result; - if (log_) Info<< " " << operationTypeNames_[operation_] + if (log_) + { + Info<< " " << operationTypeNames_[operation_] << "(" << sourceName_ << ") of " << fieldName << " = " << result << endl; } + + // write state/results information + const word& opName = operationTypeNames_[operation_]; + word resultName = opName + '(' + sourceName_ + ',' + fieldName + ')'; + this->setResult(resultName, result); } return ok; diff --git a/src/postProcessing/functionObjects/field/fieldValues/controlDict b/src/postProcessing/functionObjects/field/fieldValues/controlDict index 5b0e8b7a3e1508de6c680093e31fb7c4de07e82e..6c5462e8b68fe1971f05042e373bcfa9f0a4f524 100644 --- a/src/postProcessing/functionObjects/field/fieldValues/controlDict +++ b/src/postProcessing/functionObjects/field/fieldValues/controlDict @@ -60,10 +60,13 @@ functions // Output field values as well valueOutput true; + // Output format for field values + surfaceFormat vtk; + // Type of source: patch/faceZone/sampledSurface source patch; - // if patch or faceZone: name of patch or faceZone + // If patch or faceZone: name of patch or faceZone sourceName movingWall; //// if sampledSurface: dictionary with a sampledSurface @@ -96,6 +99,7 @@ functions outputControl outputTime; log true; valueOutput true; + surfaceFormat vtk; source faceZone; sourceName f0; operation sum; diff --git a/src/postProcessing/functionObjects/field/fieldValues/faceSource/faceSource.C b/src/postProcessing/functionObjects/field/fieldValues/faceSource/faceSource.C index 4e1f79807de01b7554a5314ea987a351f5faa206..89f2037c36bcdc320b45e54860b7e914576000ad 100644 --- a/src/postProcessing/functionObjects/field/fieldValues/faceSource/faceSource.C +++ b/src/postProcessing/functionObjects/field/fieldValues/faceSource/faceSource.C @@ -352,7 +352,7 @@ void Foam::fieldValues::faceSource::combineSurfaceGeometry if (Pstream::parRun()) { - // dimension as fraction of mesh bounding box + // Dimension as fraction of mesh bounding box scalar mergeDim = 1e-10*mesh().bounds().mag(); labelList pointsMap; @@ -400,8 +400,6 @@ Foam::scalar Foam::fieldValues::faceSource::totalArea() const void Foam::fieldValues::faceSource::initialise(const dictionary& dict) { - dict.lookup("sourceName") >> sourceName_; - switch (source_) { case stFaceZone: @@ -450,15 +448,14 @@ void Foam::fieldValues::faceSource::initialise(const dictionary& dict) totalArea_ = totalArea(); - Info<< type() << " " << name_ << ":" << nl - << " total faces = " << nFaces_ - << nl - << " total area = " << totalArea_ - << nl; + if (log_) Info + << type() << " " << name_ << ":" << nl + << " total faces = " << nFaces_ << nl + << " total area = " << totalArea_ << nl; if (dict.readIfPresent("weightField", weightFieldName_)) { - Info<< " weight field = " << weightFieldName_ << nl; + if (log_) Info << " weight field = " << weightFieldName_ << nl; if (source_ == stSampledSurface) { @@ -480,7 +477,7 @@ void Foam::fieldValues::faceSource::initialise(const dictionary& dict) if (weightFieldName_ == "none") { dict.lookup("orientedWeightField") >> weightFieldName_; - Info<< " weight field = " << weightFieldName_ << nl; + if (log_) Info << " weight field = " << weightFieldName_ << nl; orientWeightField_ = true; } else @@ -506,12 +503,7 @@ void Foam::fieldValues::faceSource::initialise(const dictionary& dict) fields_.append(orientedFields); } - if (dict.readIfPresent("scaleFactor", scaleFactor_)) - { - Info<< " scale factor = " << scaleFactor_ << nl; - } - - Info<< nl << endl; + if (log_) Info << nl << endl; if (valueOutput_) { @@ -530,29 +522,27 @@ void Foam::fieldValues::faceSource::initialise(const dictionary& dict) } -void Foam::fieldValues::faceSource::writeFileHeader(const label i) +void Foam::fieldValues::faceSource::writeFileHeader(Ostream& os) const { - writeCommented(file(), "Source : "); - file() << sourceTypeNames_[source_] << " " << sourceName_ << endl; - writeCommented(file(), "Faces : "); - file() << nFaces_ << endl; - writeCommented(file(), "Area : "); - file() << totalArea_ << endl; - - writeCommented(file(), "Time"); + writeHeaderValue(os, "Source", sourceTypeNames_[source_]); + writeHeaderValue(os, "Name", sourceName_); + writeHeaderValue(os, "Faces", nFaces_); + writeHeaderValue(os, "Total area", totalArea_); + writeHeaderValue(os, "Scale factor", scaleFactor_); + + writeCommented(os, "Time"); if (writeArea_) { - file() << tab << "Area"; + os << tab << "Area"; } forAll(fields_, i) { - file() - << tab << operationTypeNames_[operation_] + os << tab << operationTypeNames_[operation_] << "(" << fields_[i] << ")"; } - file() << endl; + os << endl; } @@ -569,14 +559,14 @@ Foam::scalar Foam::fieldValues::faceSource::processValues case opSumDirection: { vector n(dict_.lookup("direction")); - return sum(pos(values*(Sf & n))*mag(values)); + return gSum(pos(values*(Sf & n))*mag(values)); } case opSumDirectionBalance: { vector n(dict_.lookup("direction")); const scalarField nv(values*(Sf & n)); - return sum(pos(nv)*mag(values) - neg(nv)*mag(values)); + return gSum(pos(nv)*mag(values) - neg(nv)*mag(values)); } default: { @@ -603,7 +593,7 @@ Foam::vector Foam::fieldValues::faceSource::processValues n /= mag(n) + ROOTVSMALL; const scalarField nv(n & values); - return sum(pos(nv)*n*(nv)); + return gSum(pos(nv)*n*(nv)); } case opSumDirectionBalance: { @@ -611,16 +601,16 @@ Foam::vector Foam::fieldValues::faceSource::processValues n /= mag(n) + ROOTVSMALL; const scalarField nv(n & values); - return sum(pos(nv)*n*(nv)); + return gSum(pos(nv)*n*(nv)); } case opAreaNormalAverage: { - scalar result = sum(values & Sf)/sum(mag(Sf)); + scalar result = gSum(values & Sf)/gSum(mag(Sf)); return vector(result, 0.0, 0.0); } case opAreaNormalIntegrate: { - scalar result = sum(values & Sf); + scalar result = gSum(values & Sf); return vector(result, 0.0, 0.0); } default: @@ -649,14 +639,17 @@ Foam::fieldValues::faceSource::faceSource weightFieldName_("none"), orientWeightField_(false), orientedFieldsStart_(labelMax), - scaleFactor_(1.0), writeArea_(dict.lookupOrDefault("writeArea", false)), nFaces_(0), faceId_(), facePatchId_(), faceSign_() { - read(dict); + if (active_) + { + read(dict); + writeFileHeader(file()); + } } @@ -670,10 +663,11 @@ Foam::fieldValues::faceSource::~faceSource() void Foam::fieldValues::faceSource::read(const dictionary& dict) { - fieldValue::read(dict); - if (active_) { + fieldValue::read(dict); + + // No additional info to read initialise(dict); } } @@ -690,27 +684,21 @@ void Foam::fieldValues::faceSource::write() surfacePtr_().update(); } - if (Pstream::master()) - { - file() << obr_.time().value(); - } + file() << obr_.time().value(); if (writeArea_) { totalArea_ = totalArea(); - if (Pstream::master()) - { - file() << tab << totalArea_; - } + file() << tab << totalArea_; if (log_) Info<< " total area = " << totalArea_ << endl; } - // construct weight field. Note: zero size means weight = 1 + // Construct weight field. Note: zero size indicates unweighted scalarField weightField; if (weightFieldName_ != "none") { weightField = - getFieldValues<scalar> + setFieldValues<scalar> ( weightFieldName_, true, @@ -718,10 +706,7 @@ void Foam::fieldValues::faceSource::write() ); } - // Combine onto master - combineFields(weightField); - - // process the fields + // Process the fields forAll(fields_, i) { const word& fieldName = fields_[i]; @@ -730,8 +715,8 @@ void Foam::fieldValues::faceSource::write() bool orient = i >= orientedFieldsStart_; ok = ok || writeValues<scalar>(fieldName, weightField, orient); ok = ok || writeValues<vector>(fieldName, weightField, orient); - ok = ok - || writeValues<sphericalTensor>(fieldName, weightField, orient); + ok = ok || + writeValues<sphericalTensor>(fieldName, weightField, orient); ok = ok || writeValues<symmTensor>(fieldName, weightField, orient); ok = ok || writeValues<tensor>(fieldName, weightField, orient); @@ -744,10 +729,7 @@ void Foam::fieldValues::faceSource::write() } } - if (Pstream::master()) - { - file()<< endl; - } + file()<< endl; if (log_) Info<< endl; } diff --git a/src/postProcessing/functionObjects/field/fieldValues/faceSource/faceSource.H b/src/postProcessing/functionObjects/field/fieldValues/faceSource/faceSource.H index e74b840f18a73bf56bb85c85f04ac74d59b0668f..77fde515c4dcb62a385f4a0b06453d8111269b6e 100644 --- a/src/postProcessing/functionObjects/field/fieldValues/faceSource/faceSource.H +++ b/src/postProcessing/functionObjects/field/fieldValues/faceSource/faceSource.H @@ -3,7 +3,7 @@ \\ / F ield | OpenFOAM: The Open Source CFD Toolbox \\ / O peration | \\ / A nd | Copyright (C) 2011-2015 OpenFOAM Foundation - \\/ M anipulation | + \\/ M anipulation | Copyright (C) 2015 OpenCFD Ltd ------------------------------------------------------------------------------- License This file is part of OpenFOAM. @@ -257,9 +257,6 @@ protected: //- Start index of fields that require application of flipMap label orientedFieldsStart_; - //- Scale factor - optional - scalar scaleFactor_; - //- Total area of the faceSource scalar totalArea_; @@ -300,7 +297,7 @@ protected: //- Return field values by looking up field name template<class Type> - tmp<Field<Type> > getFieldValues + tmp<Field<Type> > setFieldValues ( const word& fieldName, const bool mustGet = false, @@ -328,7 +325,7 @@ protected: ) const; //- Output file header information - virtual void writeFileHeader(const label i); + virtual void writeFileHeader(Ostream& os) const; public: diff --git a/src/postProcessing/functionObjects/field/fieldValues/faceSource/faceSourceTemplates.C b/src/postProcessing/functionObjects/field/fieldValues/faceSource/faceSourceTemplates.C index 53bca6f1fab3ae2fbc1fdf8fa814d484dbb99991..1598eb881fac32047c25c10567bdf8711e075722 100644 --- a/src/postProcessing/functionObjects/field/fieldValues/faceSource/faceSourceTemplates.C +++ b/src/postProcessing/functionObjects/field/fieldValues/faceSource/faceSourceTemplates.C @@ -3,7 +3,7 @@ \\ / F ield | OpenFOAM: The Open Source CFD Toolbox \\ / O peration | \\ / A nd | Copyright (C) 2011-2015 OpenFOAM Foundation - \\/ M anipulation | + \\/ M anipulation | Copyright (C) 2015 OpenCFD Ltd ------------------------------------------------------------------------------- License This file is part of OpenFOAM. @@ -51,7 +51,7 @@ bool Foam::fieldValues::faceSource::validField(const word& fieldName) const template<class Type> -Foam::tmp<Foam::Field<Type> > Foam::fieldValues::faceSource::getFieldValues +Foam::tmp<Foam::Field<Type> > Foam::fieldValues::faceSource::setFieldValues ( const word& fieldName, const bool mustGet, @@ -113,7 +113,7 @@ Foam::tmp<Foam::Field<Type> > Foam::fieldValues::faceSource::getFieldValues FatalErrorIn ( "Foam::tmp<Foam::Field<Type> > " - "Foam::fieldValues::faceSource::getFieldValues" + "Foam::fieldValues::faceSource::setFieldValues" "(" "const word&, " "const bool, " @@ -140,12 +140,12 @@ Type Foam::fieldValues::faceSource::processSameTypeValues { case opSum: { - result = sum(values); + result = gSum(values); break; } case opSumMag: { - result = sum(cmptMag(values)); + result = gSum(cmptMag(values)); break; } case opSumDirection: @@ -190,18 +190,23 @@ Type Foam::fieldValues::faceSource::processSameTypeValues } case opAverage: { - result = sum(values)/values.size(); + label n = returnReduce(values.size(), sumOp<label>()); + result = gSum(values)/(scalar(n) + ROOTVSMALL); break; } case opWeightedAverage: { - if (weightField.size()) + label wSize = returnReduce(weightField.size(), sumOp<label>()); + + if (wSize > 0) { - result = sum(weightField*values)/sum(weightField); + result = + gSum(weightField*values)/(gSum(weightField) + ROOTVSMALL); } else { - result = sum(values)/values.size(); + label n = returnReduce(values.size(), sumOp<label>()); + result = gSum(values)/(scalar(n) + ROOTVSMALL); } break; } @@ -209,20 +214,21 @@ Type Foam::fieldValues::faceSource::processSameTypeValues { const scalarField magSf(mag(Sf)); - result = sum(magSf*values)/sum(magSf); + result = gSum(magSf*values)/gSum(magSf); break; } case opWeightedAreaAverage: { const scalarField magSf(mag(Sf)); + label wSize = returnReduce(weightField.size(), sumOp<label>()); - if (weightField.size()) + if (wSize > 0) { - result = sum(weightField*magSf*values)/sum(magSf*weightField); + result = gSum(weightField*magSf*values)/gSum(magSf*weightField); } else { - result = sum(magSf*values)/sum(magSf); + result = gSum(magSf*values)/gSum(magSf); } break; } @@ -230,24 +236,26 @@ Type Foam::fieldValues::faceSource::processSameTypeValues { const scalarField magSf(mag(Sf)); - result = sum(magSf*values); + result = gSum(magSf*values); break; } case opMin: { - result = min(values); + result = gMin(values); break; } case opMax: { - result = max(values); + result = gMax(values); break; } case opCoV: { const scalarField magSf(mag(Sf)); - Type meanValue = sum(values*magSf)/sum(magSf); + const scalar gSumMagSf = gSum(magSf); + + Type meanValue = gSum(values*magSf)/gSumMagSf; const label nComp = pTraits<Type>::nComponents; @@ -257,7 +265,9 @@ Type Foam::fieldValues::faceSource::processSameTypeValues scalar mean = component(meanValue, d); scalar& res = setComponent(result, d); - res = sqrt(sum(magSf*sqr(vals - mean))/sum(magSf))/mean; + res = + sqrt(gSum(magSf*sqr(vals - mean))/gSumMagSf) + /(mean + ROOTVSMALL); } break; @@ -299,7 +309,7 @@ bool Foam::fieldValues::faceSource::writeValues if (ok) { - Field<Type> values(getFieldValues<Type>(fieldName, true, orient)); + Field<Type> values(setFieldValues<Type>(fieldName, true, orient)); vectorField Sf; if (surfacePtr_.valid()) @@ -313,13 +323,12 @@ bool Foam::fieldValues::faceSource::writeValues Sf = filterField(mesh().Sf(), true); } - // Combine onto master - combineFields(values); - combineFields(Sf); - // Write raw values on surface if specified if (surfaceWriterPtr_.valid()) { + Field<Type> allValues(values); + combineFields(allValues); + faceList faces; pointField points; @@ -344,29 +353,30 @@ bool Foam::fieldValues::faceSource::writeValues points, faces, fieldName, - values, + allValues, false ); } } - // Apply scale factor values *= scaleFactor_; - if (Pstream::master()) - { - Type result = processValues(values, Sf, weightField); - - // Add to result dictionary, over-writing any previous entry - resultDict_.add(fieldName, result, true); + Type result = processValues(values, Sf, weightField); - file()<< tab << result; + file()<< tab << result; - if (log_) Info<< " " << operationTypeNames_[operation_] - << "(" << sourceName_ << ") of " << fieldName + if (log_) + { + Info<< " " << operationTypeNames_[operation_] + << "(" << sourceName_ << ") for " << fieldName << " = " << result << endl; } + + // Write state/results information + const word& opName = operationTypeNames_[operation_]; + word resultName = opName + '(' + sourceName_ + ',' + fieldName + ')'; + this->setResult(resultName, result); } return ok; diff --git a/src/postProcessing/functionObjects/field/fieldValues/fieldValue/fieldValue.C b/src/postProcessing/functionObjects/field/fieldValues/fieldValue/fieldValue.C index e54187c5f488e0736314a64f13bf36cc1219822e..b744457cf7167e0d2bbf6f40d4e00f9a2f321dd9 100644 --- a/src/postProcessing/functionObjects/field/fieldValues/fieldValue/fieldValue.C +++ b/src/postProcessing/functionObjects/field/fieldValues/fieldValue/fieldValue.C @@ -3,7 +3,7 @@ \\ / F ield | OpenFOAM: The Open Source CFD Toolbox \\ / O peration | \\ / A nd | Copyright (C) 2011-2015 OpenFOAM Foundation - \\/ M anipulation | + \\/ M anipulation | Copyright (C) 2015 OpenCFD Ltd ------------------------------------------------------------------------------- License This file is part of OpenFOAM. @@ -43,11 +43,14 @@ void Foam::fieldValue::read(const dictionary& dict) { if (active_) { + functionObjectFile::read(dict); + dict_ = dict; log_ = dict.lookupOrDefault<Switch>("log", true); dict.lookup("fields") >> fields_; dict.lookup("valueOutput") >> valueOutput_; + dict.readIfPresent("scaleFactor", scaleFactor_); } } @@ -56,9 +59,7 @@ void Foam::fieldValue::write() { if (active_) { - functionObjectFile::write(); - - if (log_) Info<< type() << " " << name_ << " output:" << nl; + if (log_) Info << type() << " " << name_ << " output:" << nl; } } @@ -74,37 +75,21 @@ Foam::fieldValue::fieldValue const bool loadFromFiles ) : - functionObjectFile(obr, name, valueType), - name_(name), + functionObjectState(obr, name), + functionObjectFile(obr, name, valueType, dict), obr_(obr), dict_(dict), - active_(true), log_(true), - sourceName_(word::null), - fields_(dict.lookup("fields")), - valueOutput_(dict.lookup("valueOutput")), - resultDict_(fileName("name"), dictionary::null) + sourceName_(dict.lookupOrDefault<word>("sourceName", "sampledSurface")), + fields_(), + valueOutput_(false), + scaleFactor_(1.0) { // Only active if obr is an fvMesh - if (isA<fvMesh>(obr_)) + if (setActive<fvMesh>()) { read(dict); } - else - { - WarningIn - ( - "fieldValue::fieldValue" - "(" - "const word&, " - "const objectRegistry&, " - "const dictionary&, " - "const bool" - ")" - ) << "No fvMesh available, deactivating " << name << nl - << endl; - active_ = false; - } } diff --git a/src/postProcessing/functionObjects/field/fieldValues/fieldValue/fieldValue.H b/src/postProcessing/functionObjects/field/fieldValues/fieldValue/fieldValue.H index 9d852cdfb798173aadcec34a3f1a7a13c60b8382..5e3d4e3223ab20c697ffffa66d27fa5f9d3c4bef 100644 --- a/src/postProcessing/functionObjects/field/fieldValues/fieldValue/fieldValue.H +++ b/src/postProcessing/functionObjects/field/fieldValues/fieldValue/fieldValue.H @@ -2,8 +2,8 @@ ========= | \\ / F ield | OpenFOAM: The Open Source CFD Toolbox \\ / O peration | - \\ / A nd | Copyright (C) 2011-2013 OpenFOAM Foundation - \\/ M anipulation | + \\ / A nd | Copyright (C) 2011-2014 OpenFOAM Foundation + \\/ M anipulation | Copyright (C) 2015 OpenCFD Ltd ------------------------------------------------------------------------------- License This file is part of OpenFOAM. @@ -28,7 +28,7 @@ Group grpFieldFunctionObjects Description - Base class for field value -based function objects. + Base class for field value-based function objects. SourceFiles fieldValue.C @@ -38,6 +38,7 @@ SourceFiles #ifndef fieldValue_H #define fieldValue_H +#include "functionObjectState.H" #include "functionObjectFile.H" #include "Switch.H" #include "OFstream.H" @@ -62,6 +63,7 @@ class mapPolyMesh; class fieldValue : + public functionObjectState, public functionObjectFile { @@ -69,18 +71,12 @@ protected: // Protected data - //- Name of this fieldValue object - word name_; - //- Database this class is registered to const objectRegistry& obr_; //- Construction dictionary dictionary dict_; - //- Active flag - bool active_; - //- Switch to send output to Info as well as to file Switch log_; @@ -93,8 +89,8 @@ protected: //- Output field values flag Switch valueOutput_; - //- Results dictionary for external access of results - dictionary resultDict_; + //- Scale factor - optional + scalar scaleFactor_; public: @@ -173,9 +169,6 @@ public: //- Helper function to return the reference to the mesh inline const fvMesh& mesh() const; - //- Return access to the latest set of results - inline const dictionary& resultDict() const; - // Function object functions diff --git a/src/postProcessing/functionObjects/field/fieldValues/fieldValue/fieldValueI.H b/src/postProcessing/functionObjects/field/fieldValues/fieldValue/fieldValueI.H index 55651a3539ed50705d18fe6a75cf10f4425e9d59..f1a88185f81025777eaef3392f55bf71cb60a206 100644 --- a/src/postProcessing/functionObjects/field/fieldValues/fieldValue/fieldValueI.H +++ b/src/postProcessing/functionObjects/field/fieldValues/fieldValue/fieldValueI.H @@ -3,7 +3,7 @@ \\ / F ield | OpenFOAM: The Open Source CFD Toolbox \\ / O peration | \\ / A nd | Copyright (C) 2011-2013 OpenFOAM Foundation - \\/ M anipulation | + \\/ M anipulation | Copyright (C) 2015 OpenCFD Ltd ------------------------------------------------------------------------------- License This file is part of OpenFOAM. @@ -82,10 +82,4 @@ inline const Foam::fvMesh& Foam::fieldValue::mesh() const } -inline const Foam::dictionary& Foam::fieldValue::resultDict() const -{ - return resultDict_; -} - - // ************************************************************************* // diff --git a/src/postProcessing/functionObjects/field/fieldValues/fieldValue/fieldValueTemplates.C b/src/postProcessing/functionObjects/field/fieldValues/fieldValue/fieldValueTemplates.C index 43d1a18d99ce117d57117d35a9b8b8bf86b64d5f..d9945b9570344e0ad73839cf309400342bc9c653 100644 --- a/src/postProcessing/functionObjects/field/fieldValues/fieldValue/fieldValueTemplates.C +++ b/src/postProcessing/functionObjects/field/fieldValues/fieldValue/fieldValueTemplates.C @@ -3,7 +3,7 @@ \\ / F ield | OpenFOAM: The Open Source CFD Toolbox \\ / O peration | \\ / A nd | Copyright (C) 2011 OpenFOAM Foundation - \\/ M anipulation | + \\/ M anipulation | Copyright (C) 2015 OpenCFD Ltd ------------------------------------------------------------------------------- License This file is part of OpenFOAM. @@ -37,16 +37,14 @@ void Foam::fieldValue::combineFields(Field<Type>& field) allValues[Pstream::myProcNo()] = field; Pstream::gatherList(allValues); - - if (Pstream::master()) - { - field = - ListListOps::combine<Field<Type> > - ( - allValues, - accessOp<Field<Type> >() - ); - } + Pstream::scatterList(allValues); + + field = + ListListOps::combine<Field<Type> > + ( + allValues, + accessOp<Field<Type> >() + ); } diff --git a/src/postProcessing/functionObjects/field/fieldValues/fieldValueDelta/fieldValueDelta.C b/src/postProcessing/functionObjects/field/fieldValues/fieldValueDelta/fieldValueDelta.C index 28e5866b013246046e0411dff990f875acecb504..091ae05ec7a2240d441a40787ac8bcf23b4963f7 100644 --- a/src/postProcessing/functionObjects/field/fieldValues/fieldValueDelta/fieldValueDelta.C +++ b/src/postProcessing/functionObjects/field/fieldValues/fieldValueDelta/fieldValueDelta.C @@ -3,7 +3,7 @@ \\ / F ield | OpenFOAM: The Open Source CFD Toolbox \\ / O peration | \\ / A nd | Copyright (C) 2012-2015 OpenFOAM Foundation - \\/ M anipulation | + \\/ M anipulation | Copyright (C) 2015 OpenCFD Ltd ------------------------------------------------------------------------------- License This file is part of OpenFOAM. @@ -54,30 +54,9 @@ namespace Foam } -// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * // +// * * * * * * * * * * * * * Protected Member Functions * * * * * * * * * * // -Foam::fieldValues::fieldValueDelta::fieldValueDelta -( - const word& name, - const objectRegistry& obr, - const dictionary& dict, - const bool loadFromFiles -) -: - functionObjectFile(obr, name, typeName), - name_(name), - obr_(obr), - loadFromFiles_(loadFromFiles), - log_(true), - operation_(opSubtract), - source1Ptr_(NULL), - source2Ptr_(NULL) -{ - read(dict); -} - - -void Foam::fieldValues::fieldValueDelta::writeFileHeader(const label i) +void Foam::fieldValues::fieldValueDelta::writeFileHeader(Ostream& os) const { const wordList& fields1 = source1Ptr_->fields(); const wordList& fields2 = source2Ptr_->fields(); @@ -92,8 +71,6 @@ void Foam::fieldValues::fieldValueDelta::writeFileHeader(const label i) } } - Ostream& os = file(); - writeHeaderValue(os, "Source1", source1Ptr_->name()); writeHeaderValue(os, "Source2", source2Ptr_->name()); writeHeaderValue(os, "Operation", operationTypeNames_[operation_]); @@ -108,6 +85,33 @@ void Foam::fieldValues::fieldValueDelta::writeFileHeader(const label i) } +// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * // + +Foam::fieldValues::fieldValueDelta::fieldValueDelta +( + const word& name, + const objectRegistry& obr, + const dictionary& dict, + const bool loadFromFiles +) +: + functionObjectState(obr, name), + functionObjectFile(obr, name, typeName, dict), + obr_(obr), + loadFromFiles_(loadFromFiles), + log_(true), + operation_(opSubtract), + source1Ptr_(NULL), + source2Ptr_(NULL) +{ + if (setActive<fvMesh>()) + { + read(dict); + writeFileHeader(file()); + } +} + + // * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * // Foam::fieldValues::fieldValueDelta::~fieldValueDelta() @@ -118,83 +122,131 @@ Foam::fieldValues::fieldValueDelta::~fieldValueDelta() void Foam::fieldValues::fieldValueDelta::read(const dictionary& dict) { - log_ = dict.lookupOrDefault<Switch>("log", true); - source1Ptr_.reset - ( - fieldValue::New + if (active_) + { + functionObjectFile::read(dict); + + log_ = dict.lookupOrDefault<Switch>("log", true); + source1Ptr_.reset ( - name_ + ".source1", - obr_, - dict.subDict("source1"), - loadFromFiles_, - false - ).ptr() - ); - source2Ptr_.reset - ( - fieldValue::New + fieldValue::New + ( + name_ + ".source1", + obr_, + dict.subDict("source1"), + loadFromFiles_, + false + ).ptr() + ); + source2Ptr_.reset ( - name_ + ".source2", - obr_, - dict.subDict("source2"), - loadFromFiles_, - false - ).ptr() - ); - - operation_ = operationTypeNames_.read(dict.lookup("operation")); + fieldValue::New + ( + name_ + ".source2", + obr_, + dict.subDict("source2"), + loadFromFiles_, + false + ).ptr() + ); + + operation_ = operationTypeNames_.read(dict.lookup("operation")); + } } void Foam::fieldValues::fieldValueDelta::write() { - functionObjectFile::write(); + // Do nothing +} - source1Ptr_->write(); - source2Ptr_->write(); - if (Pstream::master()) +void Foam::fieldValues::fieldValueDelta::execute() +{ + if (active_) { + source1Ptr_->write(); + source2Ptr_->write(); + file()<< obr_.time().value(); - } - if (log_) Info<< type() << " " << name_ << " output:" << endl; + if (log_) Info << type() << " " << name_ << " output:" << endl; - bool found = false; - processFields<scalar>(found); - processFields<vector>(found); - processFields<sphericalTensor>(found); - processFields<symmTensor>(found); - processFields<tensor>(found); + const word& name1 = source1Ptr_->name(); + const word& name2 = source2Ptr_->name(); - if (Pstream::master()) - { - file()<< endl; - } + const wordList entries1 = objectResultEntries(name1); + const wordList entries2 = objectResultEntries(name2); - if (log_) - { - if (!found) + if (entries1.size() != entries2.size()) { - Info<< " none" << endl; + FatalErrorIn("void Foam::fieldValues::fieldValueDelta::execute()") + << name_ << ": objects must generate the same number of results" + << nl + << " " << name1 << " objects: " << entries1 << nl + << " " << name2 << " objects: " << entries2 << nl + << exit(FatalError); } - else + + forAll(entries1, i) { - Info<< endl; + const word& entry1(entries1[i]); + const word& entry2(entries2[i]); + const word type1 = objectResultType(name1, entry1); + const word type2 = objectResultType(name2, entry2); + + if (type1 != type2) + { + FatalErrorIn + ( + "void Foam::fieldValues::fieldValueDelta::execute()" + ) + << name_ + << ": input values for operation must be of the same type" + << nl + << " " << entry1 << ": " << type1 << nl + << " " << entry2 << ": " << type2 << nl + << exit(FatalError); + } + + bool found = false; + + apply<scalar>(type1, name1, name2, entry1, entry2, found); + apply<vector>(type1, name1, name2, entry1, entry2, found); + apply<sphericalTensor>(type1, name1, name2, entry1, entry2, found); + apply<symmTensor>(type1, name1, name2, entry1, entry2, found); + apply<tensor>(type1, name1, name2, entry1, entry2, found); + + if (log_ && !found) + { + Info<< "Operation between " + << name1 << " with result " << entry1 << " and " + << name2 << " with result " << entry2 << " not applied" + << endl; + } } - } -} + if (log_) + { + if (entries1.empty()) + { + Info<< " none"; + } + + Info<< endl; + } -void Foam::fieldValues::fieldValueDelta::execute() -{ - // Do nothing + file()<< endl; + } } void Foam::fieldValues::fieldValueDelta::end() { - // Do nothing + if (active_) + { + execute(); + } } diff --git a/src/postProcessing/functionObjects/field/fieldValues/fieldValueDelta/fieldValueDelta.H b/src/postProcessing/functionObjects/field/fieldValues/fieldValueDelta/fieldValueDelta.H index d408227bbce516b4d45735a39316375c8dca9fcb..f4133d6a666b652cbe40b2e7e42e9221aa183fa2 100644 --- a/src/postProcessing/functionObjects/field/fieldValues/fieldValueDelta/fieldValueDelta.H +++ b/src/postProcessing/functionObjects/field/fieldValues/fieldValueDelta/fieldValueDelta.H @@ -3,7 +3,7 @@ \\ / F ield | OpenFOAM: The Open Source CFD Toolbox \\ / O peration | \\ / A nd | Copyright (C) 2012-2013 OpenFOAM Foundation - \\/ M anipulation | + \\/ M anipulation | Copyright (C) 2015 OpenCFD Ltd ------------------------------------------------------------------------------- License This file is part of OpenFOAM. @@ -28,8 +28,11 @@ Group grpFieldFunctionObjects Description - This function object provides a differencing option between two 'field - value' function objects. + This function object provides applies an operation to the output of two + fieldValue function objects. + + The operation is applied to all results of each fieldValue object. + Accordingly, each object must generate the same number and type of results. Example of function object specification: \verbatim @@ -39,11 +42,11 @@ Description functionObjectLibs ("libfieldFunctionObjects.so"); operation subtract; - fieldValue1 + source1 { ... } - fieldValue2 + source2 { ... } @@ -65,6 +68,7 @@ Description max | maximum average | average \endplaintable + SeeAlso Foam::fieldValue @@ -76,6 +80,7 @@ SourceFiles #ifndef fieldValueDelta_H #define fieldValueDelta_H +#include "functionObjectState.H" #include "functionObjectFile.H" #include "fieldValue.H" #include "autoPtr.H" @@ -94,6 +99,7 @@ namespace fieldValues class fieldValueDelta : + public functionObjectState, public functionObjectFile { public: @@ -115,9 +121,6 @@ private: // Private data - //- Name of this fieldValue object - word name_; - //- Database this class is registered to const objectRegistry& obr_; @@ -139,13 +142,17 @@ private: // Private Member Functions - //- Templated function to process common fields - template<class Type> - void processFields(bool& found); - //- Templated function to apply the operation template<class Type> - Type applyOperation(const Type& value1, const Type& value2) const; + void apply + ( + const word& resultType, + const word& name1, + const word& name2, + const word& entryName1, + const word& entryName2, + bool& found + ); protected: @@ -153,7 +160,7 @@ protected: // Functions to be over-ridden from IOoutputFilter class //- Output file header information - virtual void writeFileHeader(const label i); + virtual void writeFileHeader(Ostream& os) const; public: diff --git a/src/postProcessing/functionObjects/field/fieldValues/fieldValueDelta/fieldValueDeltaTemplates.C b/src/postProcessing/functionObjects/field/fieldValues/fieldValueDelta/fieldValueDeltaTemplates.C index 70c64effabdc00a0b147f8b6b27a4a75308d2384..65c521ef00cd62544f93230530bb07f14765d086 100644 --- a/src/postProcessing/functionObjects/field/fieldValues/fieldValueDelta/fieldValueDeltaTemplates.C +++ b/src/postProcessing/functionObjects/field/fieldValues/fieldValueDelta/fieldValueDeltaTemplates.C @@ -3,7 +3,7 @@ \\ / F ield | OpenFOAM: The Open Source CFD Toolbox \\ / O peration | \\ / A nd | Copyright (C) 2012-2015 OpenFOAM Foundation - \\/ M anipulation | + \\/ M anipulation | Copyright (C) 2015 OpenCFD Ltd ------------------------------------------------------------------------------- License This file is part of OpenFOAM. @@ -23,21 +23,31 @@ License \*---------------------------------------------------------------------------*/ -#include "GeometricField.H" -#include "volMesh.H" -#include "surfaceMesh.H" - // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * // template<class Type> -Type Foam::fieldValues::fieldValueDelta::applyOperation +void Foam::fieldValues::fieldValueDelta::apply ( - const Type& value1, - const Type& value2 -) const + const word& resultType, + const word& name1, + const word& name2, + const word& entryName1, + const word& entryName2, + bool& found +) { + if (pTraits<Type>::typeName != resultType) + { + return; + } + Type result = pTraits<Type>::zero; + Type value1 = this->getObjectResult<Type>(name1, entryName1); + Type value2 = this->getObjectResult<Type>(name2, entryName2); + + const word& opName = operationTypeNames_[operation_]; + switch (operation_) { case opAdd: @@ -69,63 +79,33 @@ Type Foam::fieldValues::fieldValueDelta::applyOperation { FatalErrorIn ( - "Type Foam::fieldValues::fieldValueDelta::applyOperation" + "void Foam::fieldValues::fieldValueDelta::applyOperation" "(" - "const Type&, " - "const Type&" + "const word&, " + "const word&, " + "const word&, " + "const word&, " + "const word&" + "bool&" ") const" ) - << "Unable to process operation " - << operationTypeNames_[operation_] + << "Operation not supported: " + << opName << abort(FatalError); } } - return result; -} - - -template<class Type> -void Foam::fieldValues::fieldValueDelta::processFields(bool& found) -{ - typedef GeometricField<Type, fvPatchField, volMesh> vf; - typedef GeometricField<Type, fvsPatchField, surfaceMesh> sf; - - const wordList& fields1 = source1Ptr_->fields(); - - const dictionary& results1 = source1Ptr_->resultDict(); - const dictionary& results2 = source2Ptr_->resultDict(); - - Type r1(pTraits<Type>::zero); - Type r2(pTraits<Type>::zero); - - forAll(fields1, i) - { - const word& fieldName = fields1[i]; - - if - ( - (obr_.foundObject<vf>(fieldName) || obr_.foundObject<sf>(fieldName)) - && results2.found(fieldName) - ) - { - results1.lookup(fieldName) >> r1; - results2.lookup(fieldName) >> r2; + const word + resultName(opName + '(' + entryName1 + ',' + entryName2 + ')'); - Type result = applyOperation(r1, r2); + if (log_) Info << " " << resultName << " = " << result << endl; - if (log_) Info<< " " << operationTypeNames_[operation_] - << "(" << fieldName << ") = " << result - << endl; + this->file()<< tab << result; - if (Pstream::master()) - { - file()<< tab << result; - } + // Write state/results information + this->setResult(resultName, result); - found = true; - } - } + found = true; } diff --git a/src/postProcessing/functionObjects/field/regionSizeDistribution/regionSizeDistribution.C b/src/postProcessing/functionObjects/field/regionSizeDistribution/regionSizeDistribution.C index 6a081fd49f436a54d4d07e0cfa78d96502344dbf..da17d2be684e00dca8165c9666e01ee424579a80 100644 --- a/src/postProcessing/functionObjects/field/regionSizeDistribution/regionSizeDistribution.C +++ b/src/postProcessing/functionObjects/field/regionSizeDistribution/regionSizeDistribution.C @@ -3,7 +3,7 @@ \\ / F ield | OpenFOAM: The Open Source CFD Toolbox \\ / O peration | \\ / A nd | Copyright (C) 2013-2015 OpenFOAM Foundation - \\/ M anipulation | + \\/ M anipulation | Copyright (C) 2015 OpenCFD Ltd ------------------------------------------------------------------------------- License This file is part of OpenFOAM. @@ -72,8 +72,11 @@ void Foam::regionSizeDistribution::writeGraph OFstream str(outputPath/formatterPtr_().getFileName(coords, valNames)); - Info<< "Writing distribution of " << valueName << " to " << str.name() - << endl; + if (log_) + { + Info<< "Writing distribution of " << valueName << " to " << str.name() + << endl; + } List<const scalarField*> valPtrs(1); valPtrs[0] = &values; @@ -149,16 +152,26 @@ void Foam::regionSizeDistribution::writeAlphaFields liquidCore.correctBoundaryConditions(); backgroundAlpha.correctBoundaryConditions(); - Info<< " Volume of liquid-core = " - << fvc::domainIntegrate(liquidCore).value() - << endl; - Info<< " Volume of background = " - << fvc::domainIntegrate(backgroundAlpha).value() - << endl; + if (log_) + { + Info<< " Volume of liquid-core = " + << fvc::domainIntegrate(liquidCore).value() + << endl; + Info<< " Volume of background = " + << fvc::domainIntegrate(backgroundAlpha).value() + << endl; + } - Info<< "Writing liquid-core field to " << liquidCore.name() << endl; + if (log_) + { + Info<< "Writing liquid-core field to " << liquidCore.name() << endl; + } liquidCore.write(); - Info<< "Writing background field to " << backgroundAlpha.name() << endl; + + if (log_) + { + Info<< "Writing background field to " << backgroundAlpha.name() << endl; + } backgroundAlpha.write(); } @@ -322,12 +335,13 @@ Foam::regionSizeDistribution::regionSizeDistribution const bool loadFromFiles ) : - functionObjectFile(obr, name, typeName), + functionObjectFile(obr, name), name_(name), obr_(obr), active_(true), alphaName_(dict.lookup("field")), - patchNames_(dict.lookup("patches")) + patchNames_(dict.lookup("patches")), + log_(true) { // Check if the available mesh is an fvMesh, otherwise deactivate if (isA<fvMesh>(obr_)) @@ -364,6 +378,10 @@ void Foam::regionSizeDistribution::read(const dictionary& dict) { if (active_) { + functionObjectFile::read(dict); + + log_.readIfPresent("log", dict); + dict.lookup("field") >> alphaName_; dict.lookup("patches") >> patchNames_; dict.lookup("threshold") >> threshold_; @@ -380,8 +398,11 @@ void Foam::regionSizeDistribution::read(const dictionary& dict) { coordSysPtr_.reset(new coordinateSystem(obr_, dict)); - Info<< "Transforming all vectorFields with coordinate system " - << coordSysPtr_().name() << endl; + if (log_) + { + Info<< "Transforming all vectorFields with coordinate system " + << coordSysPtr_().name() << endl; + } } } } @@ -409,18 +430,18 @@ void Foam::regionSizeDistribution::write() { if (active_) { - Info<< type() << " " << name_ << " output:" << nl; + if (log_) Info << type() << " " << name_ << " output:" << nl; const fvMesh& mesh = refCast<const fvMesh>(obr_); autoPtr<volScalarField> alphaPtr; if (obr_.foundObject<volScalarField>(alphaName_)) { - Info<< " Looking up field " << alphaName_ << endl; + if (log_) Info << " Looking up field " << alphaName_ << endl; } else { - Info<< " Reading field " << alphaName_ << endl; + if (log_) Info << " Reading field " << alphaName_ << endl; alphaPtr.reset ( new volScalarField @@ -446,17 +467,24 @@ void Foam::regionSizeDistribution::write() : obr_.lookupObject<volScalarField>(alphaName_) ); - Info<< " Volume of alpha = " - << fvc::domainIntegrate(alpha).value() - << endl; + if (log_) + { + Info<< " Volume of alpha = " + << fvc::domainIntegrate(alpha).value() + << endl; + } const scalar meshVol = gSum(mesh.V()); const scalar maxDropletVol = 1.0/6.0*pow(maxDiam_, 3); const scalar delta = (maxDiam_-minDiam_)/nBins_; - Info<< " Mesh volume = " << meshVol << endl; - Info<< " Maximum droplet diameter = " << maxDiam_ << endl; - Info<< " Maximum droplet volume = " << maxDropletVol << endl; + if (log_) + { + Info<< " Mesh volume = " << meshVol << nl + << " Maximum droplet diameter = " << maxDiam_ << nl + << " Maximum droplet volume = " << maxDropletVol + << endl; + } // Determine blocked faces @@ -515,8 +543,11 @@ void Foam::regionSizeDistribution::write() regionSplit regions(mesh, blockedFace); - Info<< " Determined " << regions.nRegions() - << " disconnected regions" << endl; + if (log_) + { + Info<< " Determined " << regions.nRegions() + << " disconnected regions" << endl; + } if (debug) @@ -534,8 +565,13 @@ void Foam::regionSizeDistribution::write() mesh, dimensionedScalar("zero", dimless, 0) ); - Info<< " Dumping region as volScalarField to " << region.name() - << endl; + + if (log_) + { + Info<< " Dumping region as " << volScalarField::typeName + << " to " << region.name() + << endl; + } forAll(regions, cellI) { @@ -566,11 +602,15 @@ void Foam::regionSizeDistribution::write() if (debug) { - Info<< " " << token::TAB << "Region" - << token::TAB << "Volume(mesh)" - << token::TAB << "Volume(" << alpha.name() << "):" - << token::TAB << "nCells" - << endl; + if (log_) + { + Info<< " " << token::TAB << "Region" + << token::TAB << "Volume(mesh)" + << token::TAB << "Volume(" << alpha.name() << "):" + << token::TAB << "nCells" + << endl; + } + scalar meshSumVol = 0.0; scalar alphaSumVol = 0.0; label nCells = 0; @@ -586,50 +626,61 @@ void Foam::regionSizeDistribution::write() ++vIter, ++aIter, ++numIter ) { - Info<< " " << token::TAB << vIter.key() - << token::TAB << vIter() - << token::TAB << aIter() - << token::TAB << numIter() - << endl; + if (log_) + { + Info<< " " << token::TAB << vIter.key() + << token::TAB << vIter() + << token::TAB << aIter() + << token::TAB << numIter() + << endl; + } meshSumVol += vIter(); alphaSumVol += aIter(); nCells += numIter(); } - Info<< " " << token::TAB << "Total:" - << token::TAB << meshSumVol - << token::TAB << alphaSumVol - << token::TAB << nCells - << endl; - Info<< endl; - } + if (log_) + { + Info<< " " << token::TAB << "Total:" + << token::TAB << meshSumVol + << token::TAB << alphaSumVol + << token::TAB << nCells + << nl << endl; + } + } + if (log_) { - Info<< " Patch connected regions (liquid core):" << endl; - Info<< token::TAB << " Region" + Info<< " Patch connected regions (liquid core):" << nl + << token::TAB << " Region" << token::TAB << "Volume(mesh)" << token::TAB << "Volume(" << alpha.name() << "):" << endl; + forAllConstIter(Map<label>, patchRegions, iter) { label regionI = iter.key(); + Info<< " " << token::TAB << iter.key() << token::TAB << allRegionVolume[regionI] << token::TAB << allRegionAlphaVolume[regionI] << endl; } + Info<< endl; } + if (log_) { - Info<< " Background regions:" << endl; - Info<< " " << token::TAB << "Region" + Info<< " Background regions:" << nl + << " " << token::TAB << "Region" << token::TAB << "Volume(mesh)" << token::TAB << "Volume(" << alpha.name() << "):" << endl; + Map<scalar>::const_iterator vIter = allRegionVolume.begin(); Map<scalar>::const_iterator aIter = allRegionAlphaVolume.begin(); @@ -652,6 +703,7 @@ void Foam::regionSizeDistribution::write() << token::TAB << aIter() << endl; } } + Info<< endl; } @@ -746,9 +798,10 @@ void Foam::regionSizeDistribution::write() } // Write to screen + if (log_) { - Info<< " Bins:" << endl; - Info<< " " << token::TAB << "Bin" + Info<< " Bins:" << nl + << " " << token::TAB << "Bin" << token::TAB << "Min diameter" << token::TAB << "Count:" << endl; @@ -759,8 +812,10 @@ void Foam::regionSizeDistribution::write() Info<< " " << token::TAB << binI << token::TAB << diam << token::TAB << binCount[binI] << endl; + diam += delta; } + Info<< endl; } @@ -783,7 +838,7 @@ void Foam::regionSizeDistribution::write() forAll(selected, i) { const word& fldName = scalarNames[selected[i]]; - Info<< " Scalar field " << fldName << endl; + if (log_) Info << " Scalar field " << fldName << endl; const scalarField& fld = obr_.lookupObject < @@ -812,7 +867,7 @@ void Foam::regionSizeDistribution::write() forAll(selected, i) { const word& fldName = vectorNames[selected[i]]; - Info<< " Vector field " << fldName << endl; + if (log_) Info << " Vector field " << fldName << endl; vectorField fld = obr_.lookupObject < @@ -821,10 +876,13 @@ void Foam::regionSizeDistribution::write() if (coordSysPtr_.valid()) { - Info<< "Transforming vector field " << fldName - << " with coordinate system " - << coordSysPtr_().name() - << endl; + if (log_) + { + Info<< "Transforming vector field " << fldName + << " with coordinate system " + << coordSysPtr_().name() + << endl; + } fld = coordSysPtr_().localVector(fld); } diff --git a/src/postProcessing/functionObjects/field/regionSizeDistribution/regionSizeDistribution.H b/src/postProcessing/functionObjects/field/regionSizeDistribution/regionSizeDistribution.H index b639d8e251c9c9e3fe0b42fcabe6eaa64d49a9eb..680c34fe2c86977b710e50bedd733523d55a3a8c 100644 --- a/src/postProcessing/functionObjects/field/regionSizeDistribution/regionSizeDistribution.H +++ b/src/postProcessing/functionObjects/field/regionSizeDistribution/regionSizeDistribution.H @@ -3,7 +3,7 @@ \\ / F ield | OpenFOAM: The Open Source CFD Toolbox \\ / O peration | \\ / A nd | Copyright (C) 2013 OpenFOAM Foundation - \\/ M anipulation | + \\/ M anipulation | Copyright (C) 2015 OpenCFD Ltd ------------------------------------------------------------------------------- License This file is part of OpenFOAM. @@ -92,6 +92,7 @@ Description minDiameter | minimum region equivalent diameter | no | 0 setFormat | writing format | yes | coordinateSystem | transformation for vector fields | no | + log | Log to standard output | no | yes \endtable SeeAlso @@ -113,6 +114,7 @@ SourceFiles #include "volFieldsFwd.H" #include "wordReList.H" #include "coordinateSystem.H" +#include "Switch.H" // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // @@ -150,6 +152,9 @@ class regionSizeDistribution //- Patches to walk from wordReList patchNames_; + //- Switch to send output to Info as well as to file + Switch log_; + //- Clip value scalar threshold_; diff --git a/src/postProcessing/functionObjects/forces/forcesFunctionObjectsDoc.H b/src/postProcessing/functionObjects/forces/doc/forcesFunctionObjectsDoc.H similarity index 100% rename from src/postProcessing/functionObjects/forces/forcesFunctionObjectsDoc.H rename to src/postProcessing/functionObjects/forces/doc/forcesFunctionObjectsDoc.H diff --git a/src/postProcessing/functionObjects/forces/forceCoeffs/forceCoeffs.C b/src/postProcessing/functionObjects/forces/forceCoeffs/forceCoeffs.C index fe09f4fd9495b1a7f6ec5254ea5cfc23989a2baf..da2f58847274c4dbb3ea877dc935a756fadf1359 100644 --- a/src/postProcessing/functionObjects/forces/forceCoeffs/forceCoeffs.C +++ b/src/postProcessing/functionObjects/forces/forceCoeffs/forceCoeffs.C @@ -3,7 +3,7 @@ \\ / F ield | OpenFOAM: The Open Source CFD Toolbox \\ / O peration | \\ / A nd | Copyright (C) 2011-2015 OpenFOAM Foundation - \\/ M anipulation | + \\/ M anipulation | Copyright (C) 2015 OpenCFD Ltd ------------------------------------------------------------------------------- License This file is part of OpenFOAM. @@ -28,6 +28,9 @@ License #include "Time.H" #include "Pstream.H" #include "IOmanip.H" +#include "fvMesh.H" +#include "dimensionedTypes.H" +#include "volFields.H" // * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * // @@ -39,81 +42,157 @@ namespace Foam // * * * * * * * * * * * * Protected Member Functions * * * * * * * * * * * // -void Foam::forceCoeffs::writeFileHeader(const label i) +void Foam::forceCoeffs::createFiles() { - if (i == 0) + // Note: Only possible to create bin files after bins have been initialised + + if (writeToFile() && !coeffFilePtr_.valid()) { - // force coeff data - - writeHeader(file(i), "Force coefficients"); - writeHeaderValue(file(i), "liftDir", liftDir_); - writeHeaderValue(file(i), "dragDir", dragDir_); - writeHeaderValue(file(i), "pitchAxis", pitchAxis_); - writeHeaderValue(file(i), "magUInf", magUInf_); - writeHeaderValue(file(i), "lRef", lRef_); - writeHeaderValue(file(i), "Aref", Aref_); - writeHeaderValue(file(i), "CofR", coordSys_.origin()); - writeCommented(file(i), "Time"); - writeTabbed(file(i), "Cm"); - writeTabbed(file(i), "Cd"); - writeTabbed(file(i), "Cl"); - writeTabbed(file(i), "Cl(f)"); - writeTabbed(file(i), "Cl(r)"); - file(i) - << tab << "Cm" << tab << "Cd" << tab << "Cl" << tab << "Cl(f)" - << tab << "Cl(r)"; + coeffFilePtr_ = createFile("coefficient"); + writeIntegratedHeader("Coefficients", coeffFilePtr_()); + + if (nBin_ > 1) + { + CmBinFilePtr_ = createFile("CmBin"); + writeBinHeader("Moment coefficient bins", CmBinFilePtr_()); + CdBinFilePtr_ = createFile("CdBin"); + writeBinHeader("Drag coefficient bins", CdBinFilePtr_()); + ClBinFilePtr_ = createFile("ClBin"); + writeBinHeader("Lift coefficient bins", ClBinFilePtr_()); + } } - else if (i == 1) +} + + +void Foam::forceCoeffs::writeIntegratedHeader +( + const word& header, + Ostream& os +) const +{ + writeHeader(os, "Force coefficients"); + writeHeaderValue(os, "liftDir", liftDir_); + writeHeaderValue(os, "dragDir", dragDir_); + writeHeaderValue(os, "pitchAxis", pitchAxis_); + writeHeaderValue(os, "magUInf", magUInf_); + writeHeaderValue(os, "lRef", lRef_); + writeHeaderValue(os, "Aref", Aref_); + writeHeaderValue(os, "CofR", coordSys_.origin()); + writeHeader(os, ""); + writeCommented(os, "Time"); + writeTabbed(os, "Cm"); + writeTabbed(os, "Cd"); + writeTabbed(os, "Cl"); + writeTabbed(os, "Cl(f)"); + writeTabbed(os, "Cl(r)"); + os << endl; +} + + +void Foam::forceCoeffs::writeBinHeader +( + const word& header, + Ostream& os +) const +{ + writeHeader(os, header); + writeHeaderValue(os, "bins", nBin_); + writeHeaderValue(os, "start", binMin_); + writeHeaderValue(os, "delta", binDx_); + writeHeaderValue(os, "direction", binDir_); + + vectorField binPoints(nBin_); + writeCommented(os, "x co-ords :"); + forAll(binPoints, pointI) { - // bin coeff data + binPoints[pointI] = (binMin_ + (pointI + 1)*binDx_)*binDir_; + os << tab << binPoints[pointI].x(); + } + os << nl; - writeHeader(file(i), "Force coefficient bins"); - writeHeaderValue(file(i), "bins", nBin_); - writeHeaderValue(file(i), "start", binMin_); - writeHeaderValue(file(i), "delta", binDx_); - writeHeaderValue(file(i), "direction", binDir_); + writeCommented(os, "y co-ords :"); + forAll(binPoints, pointI) + { + os << tab << binPoints[pointI].y(); + } + os << nl; - vectorField binPoints(nBin_); - writeCommented(file(i), "x co-ords :"); - forAll(binPoints, pointI) - { - binPoints[pointI] = (binMin_ + (pointI + 1)*binDx_)*binDir_; - file(i) << tab << binPoints[pointI].x(); - } - file(i) << nl; + writeCommented(os, "z co-ords :"); + forAll(binPoints, pointI) + { + os << tab << binPoints[pointI].z(); + } + os << nl; - writeCommented(file(i), "y co-ords :"); - forAll(binPoints, pointI) - { - file(i) << tab << binPoints[pointI].y(); - } - file(i) << nl; + writeHeader(os, ""); + writeCommented(os, "Time"); - writeCommented(file(i), "z co-ords :"); - forAll(binPoints, pointI) + for (label j = 0; j < nBin_; j++) + { + word jn(Foam::name(j) + ':'); + writeTabbed(os, jn + "total"); + writeTabbed(os, jn + "pressure"); + writeTabbed(os, jn + "viscous"); + + if (porosity_) { - file(i) << tab << binPoints[pointI].z(); + writeTabbed(os, jn + "porous"); } - file(i) << nl; + } - writeCommented(file(i), "Time"); + os << endl; +} - for (label j = 0; j < nBin_; j++) + +void Foam::forceCoeffs::writeIntegratedData +( + const word& title, + const List<Field<scalar> >& coeff +) const +{ + scalar pressure = sum(coeff[0]); + scalar viscous = sum(coeff[1]); + scalar porous = sum(coeff[2]); + scalar total = pressure + viscous + porous; + + if (log_) + { + Info<< " " << title << " : " << total << token::TAB + << "(" + << "pressure: " << pressure << token::TAB + << "viscous: " << viscous; + + if (porosity_) { - const word jn('(' + Foam::name(j) + ')'); - writeTabbed(file(i), "Cm" + jn); - writeTabbed(file(i), "Cd" + jn); - writeTabbed(file(i), "Cl" + jn); + Info<< token::TAB << "porous: " << porous; } + + Info<< ")" << endl; } - else +} + + +void Foam::forceCoeffs::writeBinData +( + const List<Field<scalar> > coeffs, + Ostream& os +) const +{ + os << obr_.time().value(); + + for (label binI = 0; binI < nBin_; binI++) { - FatalErrorIn("void Foam::forces::writeFileHeader(const label)") - << "Unhandled file index: " << i - << abort(FatalError); + scalar total = coeffs[0][binI] + coeffs[1][binI] + coeffs[2][binI]; + + os << tab << total << tab << coeffs[0][binI] << tab << coeffs[1][binI]; + + if (porosity_) + { + os << tab << coeffs[2][binI]; + } } - file(i)<< endl; + os << endl; } @@ -124,7 +203,8 @@ Foam::forceCoeffs::forceCoeffs const word& name, const objectRegistry& obr, const dictionary& dict, - const bool loadFromFiles + const bool loadFromFiles, + const bool readFields ) : forces(name, obr, dict, loadFromFiles, false), @@ -133,11 +213,17 @@ Foam::forceCoeffs::forceCoeffs pitchAxis_(vector::zero), magUInf_(0.0), lRef_(0.0), - Aref_(0.0) + Aref_(0.0), + coeffFilePtr_(), + CmBinFilePtr_(), + CdBinFilePtr_(), + ClBinFilePtr_() { - read(dict); - - Info<< endl; + if (readFields) + { + read(dict); + if (log_) Info << endl; + } } @@ -151,115 +237,225 @@ Foam::forceCoeffs::~forceCoeffs() void Foam::forceCoeffs::read(const dictionary& dict) { - if (active_) + if (!active_) { - forces::read(dict); - - // Directions for lift and drag forces, and pitch moment - dict.lookup("liftDir") >> liftDir_; - dict.lookup("dragDir") >> dragDir_; - dict.lookup("pitchAxis") >> pitchAxis_; - - // Free stream velocity magnitude - dict.lookup("magUInf") >> magUInf_; - - // Reference length and area scales - dict.lookup("lRef") >> lRef_; - dict.lookup("Aref") >> Aref_; + return; } -} + forces::read(dict); -void Foam::forceCoeffs::execute() -{ - // Do nothing - only valid on write -} + // Directions for lift and drag forces, and pitch moment + dict.lookup("liftDir") >> liftDir_; + dict.lookup("dragDir") >> dragDir_; + dict.lookup("pitchAxis") >> pitchAxis_; + // Free stream velocity magnitude + dict.lookup("magUInf") >> magUInf_; -void Foam::forceCoeffs::end() -{ - // Do nothing - only valid on write -} + // Reference length and area scales + dict.lookup("lRef") >> lRef_; + dict.lookup("Aref") >> Aref_; - -void Foam::forceCoeffs::timeSet() -{ - // Do nothing - only valid on write + if (writeFields_) + { + const fvMesh& mesh = refCast<const fvMesh>(obr_); + + tmp<volVectorField> tforceCoeff + ( + new volVectorField + ( + IOobject + ( + fieldName("forceCoeff"), + mesh.time().timeName(), + mesh, + IOobject::NO_READ, + IOobject::NO_WRITE + ), + mesh, + dimensionedVector("0", dimless, vector::zero) + ) + ); + + obr_.store(tforceCoeff.ptr()); + + tmp<volVectorField> tmomentCoeff + ( + new volVectorField + ( + IOobject + ( + fieldName("momentCoeff"), + mesh.time().timeName(), + mesh, + IOobject::NO_READ, + IOobject::NO_WRITE + ), + mesh, + dimensionedVector("0", dimless, vector::zero) + ) + ); + + obr_.store(tmomentCoeff.ptr()); + } } -void Foam::forceCoeffs::write() +void Foam::forceCoeffs::execute() { - forces::calcForcesMoment(); - if (!active_) { return; } - if (Pstream::master()) - { - functionObjectFile::write(); + forces::calcForcesMoment(); - scalar pDyn = 0.5*rhoRef_*magUInf_*magUInf_; + createFiles(); - Field<vector> totForce(force_[0] + force_[1] + force_[2]); - Field<vector> totMoment(moment_[0] + moment_[1] + moment_[2]); + scalar pDyn = 0.5*rhoRef_*magUInf_*magUInf_; - List<Field<scalar> > coeffs(3); - coeffs[0].setSize(nBin_); - coeffs[1].setSize(nBin_); - coeffs[2].setSize(nBin_); + // Storage for pressure, viscous and porous contributions to coeffs + List<Field<scalar> > momentCoeffs(3); + List<Field<scalar> > dragCoeffs(3); + List<Field<scalar> > liftCoeffs(3); + forAll(liftCoeffs, i) + { + momentCoeffs[i].setSize(nBin_); + dragCoeffs[i].setSize(nBin_); + liftCoeffs[i].setSize(nBin_); + } + + // Calculate coefficients + scalar CmTot = 0; + scalar CdTot = 0; + scalar ClTot = 0; + forAll(liftCoeffs, i) + { + momentCoeffs[i] = (moment_[i] & pitchAxis_)/(Aref_*pDyn*lRef_); + dragCoeffs[i] = (force_[i] & dragDir_)/(Aref_*pDyn); + liftCoeffs[i] = (force_[i] & liftDir_)/(Aref_*pDyn); - // lift, drag and moment - coeffs[0] = (totForce & liftDir_)/(Aref_*pDyn); - coeffs[1] = (totForce & dragDir_)/(Aref_*pDyn); - coeffs[2] = (totMoment & pitchAxis_)/(Aref_*lRef_*pDyn); + CmTot += sum(momentCoeffs[i]); + CdTot += sum(dragCoeffs[i]); + ClTot += sum(liftCoeffs[i]); + } - scalar Cl = sum(coeffs[0]); - scalar Cd = sum(coeffs[1]); - scalar Cm = sum(coeffs[2]); + scalar ClfTot = ClTot/2.0 + CmTot; + scalar ClrTot = ClTot/2.0 - CmTot; - scalar Clf = Cl/2.0 + Cm; - scalar Clr = Cl/2.0 - Cm; + if (log_) + { + Info<< type() << " " << name_ << " output:" << nl + << " Coefficients" << nl; + } + writeIntegratedData("Cm", momentCoeffs); + writeIntegratedData("Cd", dragCoeffs); + writeIntegratedData("Cl", liftCoeffs); + if (log_) + { + Info<< " Cl(f) : " << ClfTot << nl + << " Cl(r) : " << ClrTot << nl + << endl; + } - file(0) - << obr_.time().value() << tab << Cm << tab << Cd - << tab << Cl << tab << Clf << tab << Clr << endl; + if (writeToFile()) + { + coeffFilePtr_() + << obr_.time().value() << tab << CmTot << tab << CdTot + << tab << ClTot << tab << ClfTot << tab << ClrTot << endl; - if (log_) Info<< type() << " " << name_ << " output:" << nl - << " Cm = " << Cm << nl - << " Cd = " << Cd << nl - << " Cl = " << Cl << nl - << " Cl(f) = " << Clf << nl - << " Cl(r) = " << Clr << endl; if (nBin_ > 1) { if (binCumulative_) { - for (label i = 1; i < coeffs[0].size(); i++) + forAll(liftCoeffs, i) { - coeffs[0][i] += coeffs[0][i-1]; - coeffs[1][i] += coeffs[1][i-1]; - coeffs[2][i] += coeffs[2][i-1]; + for (label binI = 1; binI < nBin_; binI++) + { + liftCoeffs[i][binI] += liftCoeffs[i][binI-1]; + dragCoeffs[i][binI] += dragCoeffs[i][binI-1]; + momentCoeffs[i][binI] += momentCoeffs[i][binI-1]; + } } } - file(1)<< obr_.time().value(); + writeBinData(dragCoeffs, CdBinFilePtr_()); + writeBinData(liftCoeffs, ClBinFilePtr_()); + writeBinData(momentCoeffs, CmBinFilePtr_()); + } + } - forAll(coeffs[0], i) - { - file(1) - << tab << coeffs[2][i] - << tab << coeffs[1][i] - << tab << coeffs[0][i]; - } + // Write state/results information + { + setResult("Cm", CmTot); + setResult("Cd", CdTot); + setResult("Cl", ClTot); + setResult("Cl(f)", ClfTot); + setResult("Cl(r)", ClrTot); + } - file(1) << endl; - } + if (writeFields_) + { + const volVectorField& force = + obr_.lookupObject<volVectorField>(fieldName("force")); + + const volVectorField& moment = + obr_.lookupObject<volVectorField>(fieldName("moment")); + + volVectorField& forceCoeff = + const_cast<volVectorField&> + ( + obr_.lookupObject<volVectorField>(fieldName("forceCoeff")) + ); + + volVectorField& momentCoeff = + const_cast<volVectorField&> + ( + obr_.lookupObject<volVectorField>(fieldName("momentCoeff")) + ); + + dimensionedScalar f0("f0", dimForce, Aref_*pDyn); + dimensionedScalar m0("m0", dimForce*dimLength, Aref_*lRef_*pDyn); + + forceCoeff == force/f0; + momentCoeff == moment/m0; + } +} + + +void Foam::forceCoeffs::end() +{ + if (active_) + { + execute(); + } +} + + +void Foam::forceCoeffs::timeSet() +{ + // Do nothing +} + + +void Foam::forceCoeffs::write() +{ + if (!active_) + { + return; + } + + if (writeFields_) + { + const volVectorField& forceCoeff = + obr_.lookupObject<volVectorField>(fieldName("forceCoeff")); + + const volVectorField& momentCoeff = + obr_.lookupObject<volVectorField>(fieldName("momentCoeff")); - if (log_) Info<< endl; + forceCoeff.write(); + momentCoeff.write(); } } diff --git a/src/postProcessing/functionObjects/forces/forceCoeffs/forceCoeffs.H b/src/postProcessing/functionObjects/forces/forceCoeffs/forceCoeffs.H index e291065f33e309e8349445f5d880e34b9666a3be..a7002663f4912faa1758ce3a70dded7ef1523d15 100644 --- a/src/postProcessing/functionObjects/forces/forceCoeffs/forceCoeffs.H +++ b/src/postProcessing/functionObjects/forces/forceCoeffs/forceCoeffs.H @@ -2,8 +2,8 @@ ========= | \\ / F ield | OpenFOAM: The Open Source CFD Toolbox \\ / O peration | - \\ / A nd | Copyright (C) 2011-2013 OpenFOAM Foundation - \\/ M anipulation | + \\ / A nd | Copyright (C) 2011-2015 OpenFOAM Foundation + \\/ M anipulation | Copyright (C) 2015 OpenCFD Ltd ------------------------------------------------------------------------------- License This file is part of OpenFOAM. @@ -32,6 +32,19 @@ Description lift, drag and moment coefficients. The data can optionally be output into bins, defined in a given direction. + The binned data provides the total and consitituentcomponents per bin: + - total coefficient + - pressure coefficient contribution + - viscous coefficient contribution + - porous coefficient contribution + + Data is written into multiple files in the + postProcessing/\<functionObjectName\> directory: + - coefficient.dat : integrated coefficients over all geometries + - CmBin.dat : moment coefficient bins + - CdBin.dat : drag coefficient bins + - ClBin.dat : lift coefficient bins + Example of function object specification: \verbatim forceCoeffs1 @@ -40,6 +53,7 @@ Description functionObjectLibs ("libforces.so"); ... log yes; + writeFields yes; patches (walls); liftDir (0 1 0); dragDir (-1 0 0); @@ -62,6 +76,7 @@ Description Property | Description | Required | Default value type | type name: forces | yes | log | write force data to standard output | no | no + writeFields | write the force and moment coefficient fields | no | no patches | patches included in the forces calculation | yes | liftDir | lift direction | yes | dragDir | drag direction | yes | @@ -137,6 +152,21 @@ class forceCoeffs scalar Aref_; + // File streams + + //- Integrated coefficients + autoPtr<OFstream> coeffFilePtr_; + + //- Moment coefficient + autoPtr<OFstream> CmBinFilePtr_; + + //- Drag coefficient + autoPtr<OFstream> CdBinFilePtr_; + + //- Lift coefficient + autoPtr<OFstream> ClBinFilePtr_; + + // Private Member Functions //- Disallow default bitwise copy construct @@ -148,8 +178,26 @@ class forceCoeffs protected: - //- Output file header information - virtual void writeFileHeader(const label i); + // Protected Member Functions + + //- Create the output files + void createFiles(); + + //- Write header for integrated data + void writeIntegratedHeader(const word& header, Ostream& os) const; + + //- Write header for binned data + void writeBinHeader(const word& header, Ostream& os) const; + + //- Write integrated data + void writeIntegratedData + ( + const word& title, + const List<Field<scalar> >& coeff + ) const; + + //- Write binned data + void writeBinData(const List<Field<scalar> > coeffs, Ostream& os) const; public: @@ -167,7 +215,8 @@ public: const word& name, const objectRegistry&, const dictionary&, - const bool loadFromFiles = false + const bool loadFromFiles = false, + const bool readFields = true ); diff --git a/src/postProcessing/functionObjects/forces/forces/forces.C b/src/postProcessing/functionObjects/forces/forces/forces.C index dfb4a1cb42e0c84a4776e22e517c85f54c8fb0db..9f3758caf1896af8d9dc4dfb04fb579e77a4d566 100644 --- a/src/postProcessing/functionObjects/forces/forces/forces.C +++ b/src/postProcessing/functionObjects/forces/forces/forces.C @@ -3,7 +3,7 @@ \\ / F ield | OpenFOAM: The Open Source CFD Toolbox \\ / O peration | \\ / A nd | Copyright (C) 2011-2015 OpenFOAM Foundation - \\/ M anipulation | + \\/ M anipulation | Copyright (C) 2015 OpenCFD Ltd ------------------------------------------------------------------------------- License This file is part of OpenFOAM. @@ -43,113 +43,121 @@ namespace Foam // * * * * * * * * * * * * Protected Member Functions * * * * * * * * * * * // -Foam::wordList Foam::forces::createFileNames(const dictionary& dict) const +Foam::word Foam::forces::fieldName(const word& name) const { - DynamicList<word> names(1); + return name_ + ":" + name; +} - const word forceType(dict.lookup("type")); - if (dict.found("binData")) +void Foam::forces::createFiles() +{ + // Note: Only possible to create bin files after bins have been initialised + + if (writeToFile() && !forceFilePtr_.valid()) { - const dictionary& binDict(dict.subDict("binData")); - label nb = readLabel(binDict.lookup("nBin")); - if (nb > 0) + forceFilePtr_ = createFile("force"); + writeIntegratedHeader("Force", forceFilePtr_()); + momentFilePtr_ = createFile("moment"); + writeIntegratedHeader("Moment", momentFilePtr_()); + + if (nBin_ > 1) { - names.append(forceType + "_bins"); + forceBinFilePtr_ = createFile("forceBin"); + writeBinHeader("Force", forceBinFilePtr_()); + momentBinFilePtr_ = createFile("momentBin"); + writeBinHeader("Moment", momentBinFilePtr_()); } - } - names.append(forceType); + if (localSystem_) + { + localForceFilePtr_ = createFile("localForce"); + writeIntegratedHeader("Force", localForceFilePtr_()); + localMomentFilePtr_ = createFile("localMoment"); + writeIntegratedHeader("Moment", localMomentFilePtr_()); - return names; + if (nBin_ > 1) + { + localForceBinFilePtr_ = createFile("localForceBin"); + writeBinHeader("Force", localForceBinFilePtr_()); + localMomentBinFilePtr_ = createFile("localMomentBin"); + writeBinHeader("Moment", localMomentBinFilePtr_()); + } + } + } } -void Foam::forces::writeFileHeader(const label i) +void Foam::forces::writeIntegratedHeader +( + const word& header, + Ostream& os +) const { - if (i == 0) + writeHeader(os, header); + writeHeaderValue(os, "CofR", coordSys_.origin()); + writeHeader(os, ""); + writeCommented(os, "Time"); + writeTabbed(os, "(total_x total_y total_z)"); + writeTabbed(os, "(pressure_x pressure_y pressure_z)"); + writeTabbed(os, "(viscous_x viscous_y viscous_z)"); + + if (porosity_) { - // force data + writeTabbed(os, "(porous_x porous_y porous_z)"); + } - writeHeader(file(i), "Forces"); - writeHeaderValue(file(i), "CofR", coordSys_.origin()); - writeCommented(file(i), "Time"); + os << endl; +} - file(i) - << "forces(pressure viscous porous) " - << "moment(pressure viscous porous)"; - if (localSystem_) - { - file(i) - << tab - << "localForces(pressure,viscous,porous) " - << "localMoments(pressure,viscous,porous)"; - } - } - else if (i == 1) +void Foam::forces::writeBinHeader(const word& header, Ostream& os) const +{ + writeHeader(os, header + " bins"); + writeHeaderValue(os, "bins", nBin_); + writeHeaderValue(os, "start", binMin_); + writeHeaderValue(os, "delta", binDx_); + writeHeaderValue(os, "direction", binDir_); + + vectorField binPoints(nBin_); + writeCommented(os, "x co-ords :"); + forAll(binPoints, pointI) { - // bin data - - writeHeader(file(i), "Force bins"); - writeHeaderValue(file(i), "bins", nBin_); - writeHeaderValue(file(i), "start", binMin_); - writeHeaderValue(file(i), "delta", binDx_); - writeHeaderValue(file(i), "direction", binDir_); - - vectorField binPoints(nBin_); - writeCommented(file(i), "x co-ords :"); - forAll(binPoints, pointI) - { - binPoints[pointI] = (binMin_ + (pointI + 1)*binDx_)*binDir_; - file(i) << tab << binPoints[pointI].x(); - } - file(i) << nl; + binPoints[pointI] = (binMin_ + (pointI + 1)*binDx_)*binDir_; + os << tab << binPoints[pointI].x(); + } + os << nl; - writeCommented(file(i), "y co-ords :"); - forAll(binPoints, pointI) - { - file(i) << tab << binPoints[pointI].y(); - } - file(i) << nl; + writeCommented(os, "y co-ords :"); + forAll(binPoints, pointI) + { + os << tab << binPoints[pointI].y(); + } + os << nl; - writeCommented(file(i), "z co-ords :"); - forAll(binPoints, pointI) - { - file(i) << tab << binPoints[pointI].z(); - } - file(i) << nl; + writeCommented(os, "z co-ords :"); + forAll(binPoints, pointI) + { + os << tab << binPoints[pointI].z(); + } + os << nl; - writeCommented(file(i), "Time"); + writeHeader(os, ""); + writeCommented(os, "Time"); - for (label j = 0; j < nBin_; j++) - { - const word jn('(' + Foam::name(j) + ')'); - const word f("forces" + jn + "[pressure,viscous,porous]"); - const word m("moments" + jn + "[pressure,viscous,porous]"); + for (label j = 0; j < nBin_; j++) + { + const word jn(Foam::name(j) + ':'); + os << tab << jn << "(total_x total_y total_z)" + << tab << jn << "(pressure_x pressure_y pressure_z)" + << tab << jn << "(viscous_x viscous_y viscous_z)"; - file(i)<< tab << f << tab << m; - } - if (localSystem_) + if (porosity_) { - for (label j = 0; j < nBin_; j++) - { - const word jn('(' + Foam::name(j) + ')'); - const word f("localForces" + jn + "[pressure,viscous,porous]"); - const word m("localMoments" + jn + "[pressure,viscous,porous]"); - - file(i)<< tab << f << tab << m; - } + os << tab << jn << "(porous_x porous_y porous_z)"; } } - else - { - FatalErrorIn("void Foam::forces::writeFileHeader(const label)") - << "Unhandled file index: " << i - << abort(FatalError); - } - file(i)<< endl; + os << endl; } @@ -198,10 +206,117 @@ void Foam::forces::initialise() } } + initialiseBins(); + initialised_ = true; } +void Foam::forces::initialiseBins() +{ + if (!active_) + { + return; + } + + if (nBin_ > 1) + { + const fvMesh& mesh = refCast<const fvMesh>(obr_); + const polyBoundaryMesh& pbm = mesh.boundaryMesh(); + + // Determine extents of patches + binMin_ = GREAT; + scalar binMax = -GREAT; + forAllConstIter(labelHashSet, patchSet_, iter) + { + label patchI = iter.key(); + const polyPatch& pp = pbm[patchI]; + scalarField d(pp.faceCentres() & binDir_); + binMin_ = min(min(d), binMin_); + binMax = max(max(d), binMax); + } + + // Include porosity + if (porosity_) + { + const HashTable<const porosityModel*> models = + obr_.lookupClass<porosityModel>(); + + const scalarField dd(mesh.C() & binDir_); + + forAllConstIter(HashTable<const porosityModel*>, models, iter) + { + const porosityModel& pm = *iter(); + const labelList& cellZoneIDs = pm.cellZoneIDs(); + + forAll(cellZoneIDs, i) + { + label zoneI = cellZoneIDs[i]; + const cellZone& cZone = mesh.cellZones()[zoneI]; + const scalarField d(dd, cZone); + binMin_ = min(min(d), binMin_); + binMax = max(max(d), binMax); + } + } + } + + reduce(binMin_, minOp<scalar>()); + reduce(binMax, maxOp<scalar>()); + + // Slightly boost binMax so that region of interest is fully + // within bounds + binMax = 1.0001*(binMax - binMin_) + binMin_; + + binDx_ = (binMax - binMin_)/scalar(nBin_); + + // Create the bin points used for writing + binPoints_.setSize(nBin_); + forAll(binPoints_, i) + { + binPoints_[i] = (i + 0.5)*binDir_*binDx_; + } + + // Allocate storage for forces and moments + forAll(force_, i) + { + force_[i].setSize(nBin_); + moment_[i].setSize(nBin_); + } + } +} + + +void Foam::forces::resetFields() +{ + force_[0] = vector::zero; + force_[1] = vector::zero; + force_[2] = vector::zero; + + moment_[0] = vector::zero; + moment_[1] = vector::zero; + moment_[2] = vector::zero; + + if (writeFields_) + { + volVectorField& force = + const_cast<volVectorField&> + ( + obr_.lookupObject<volVectorField>(fieldName("force")) + ); + + force == dimensionedVector("0", force.dimensions(), vector::zero); + + volVectorField& moment = + const_cast<volVectorField&> + ( + obr_.lookupObject<volVectorField>(fieldName("moment")) + ); + + moment == dimensionedVector("0", moment.dimensions(), vector::zero); + } +} + + Foam::tmp<Foam::volSymmTensorField> Foam::forces::devRhoReff() const { typedef compressible::turbulenceModel cmpTurbModel; @@ -388,59 +503,180 @@ void Foam::forces::applyBins } +void Foam::forces::addToFields +( + const label patchI, + const vectorField& Md, + const vectorField& fN, + const vectorField& fT, + const vectorField& fP +) +{ + if (!writeFields_) + { + return; + } + + volVectorField& force = + const_cast<volVectorField&> + ( + obr_.lookupObject<volVectorField>(fieldName("force")) + ); + + vectorField& pf = force.boundaryField()[patchI]; + pf += fN + fT + fP; + + volVectorField& moment = + const_cast<volVectorField&> + ( + obr_.lookupObject<volVectorField>(fieldName("moment")) + ); + + vectorField& pm = moment.boundaryField()[patchI]; + pm += Md; +} + + +void Foam::forces::addToFields +( + const labelList& cellIDs, + const vectorField& Md, + const vectorField& fN, + const vectorField& fT, + const vectorField& fP +) +{ + if (!writeFields_) + { + return; + } + + volVectorField& force = + const_cast<volVectorField&> + ( + obr_.lookupObject<volVectorField>(fieldName("force")) + ); + + volVectorField& moment = + const_cast<volVectorField&> + ( + obr_.lookupObject<volVectorField>(fieldName("moment")) + ); + + forAll(cellIDs, i) + { + label cellI = cellIDs[i]; + force[cellI] += fN[i] + fT[i] + fP[i]; + moment[cellI] += Md[i]; + } +} + + +void Foam::forces::writeIntegratedForceMoment +( + const string& descriptor, + const vectorField& fm0, + const vectorField& fm1, + const vectorField& fm2, + autoPtr<OFstream>& osPtr +) const +{ + vector pressure = sum(fm0); + vector viscous = sum(fm1); + vector porous = sum(fm2); + vector total = pressure + viscous + porous; + + if (log_) + { + Info<< " Sum of " << descriptor.c_str() << nl + << " Total : " << total << nl + << " Pressure : " << pressure << nl + << " Viscous : " << viscous << nl; + + if (porosity_) + { + Info<< " Porous : " << porous << nl; + } + } + + if (writeToFile()) + { + Ostream& os = osPtr(); + + os << obr_.time().value() + << tab << total + << tab << pressure + << tab << viscous; + + if (porosity_) + { + os << tab << porous; + } + + os << endl; + } +} + + void Foam::forces::writeForces() { - if (log_) Info - << type() << " " << name_ << " output:" << nl - << " sum of forces:" << nl - << " pressure : " << sum(force_[0]) << nl - << " viscous : " << sum(force_[1]) << nl - << " porous : " << sum(force_[2]) << nl - << " sum of moments:" << nl - << " pressure : " << sum(moment_[0]) << nl - << " viscous : " << sum(moment_[1]) << nl - << " porous : " << sum(moment_[2]) - << endl; - - file(0) << obr_.time().value() << tab << setw(1) << '(' - << sum(force_[0]) << setw(1) << ' ' - << sum(force_[1]) << setw(1) << ' ' - << sum(force_[2]) << setw(3) << ") (" - << sum(moment_[0]) << setw(1) << ' ' - << sum(moment_[1]) << setw(1) << ' ' - << sum(moment_[2]) << setw(1) << ')' - << endl; + if (log_) Info << type() << " " << name_ << " output:" << nl; + + writeIntegratedForceMoment + ( + "forces", + force_[0], + force_[1], + force_[2], + forceFilePtr_ + ); + + writeIntegratedForceMoment + ( + "moments", + moment_[0], + moment_[1], + moment_[2], + momentFilePtr_ + ); if (localSystem_) { - vectorField localForceN(coordSys_.localVector(force_[0])); - vectorField localForceT(coordSys_.localVector(force_[1])); - vectorField localForceP(coordSys_.localVector(force_[2])); - vectorField localMomentN(coordSys_.localVector(moment_[0])); - vectorField localMomentT(coordSys_.localVector(moment_[1])); - vectorField localMomentP(coordSys_.localVector(moment_[2])); - - file(0) << obr_.time().value() << tab << setw(1) << '(' - << sum(localForceN) << setw(1) << ' ' - << sum(localForceT) << setw(1) << ' ' - << sum(localForceP) << setw(3) << ") (" - << sum(localMomentN) << setw(1) << ' ' - << sum(localMomentT) << setw(1) << ' ' - << sum(localMomentP) << setw(1) << ')' - << endl; + writeIntegratedForceMoment + ( + "local forces", + coordSys_.localVector(force_[0]), + coordSys_.localVector(force_[1]), + coordSys_.localVector(force_[2]), + localForceFilePtr_ + ); + + writeIntegratedForceMoment + ( + "local moments", + coordSys_.localVector(moment_[0]), + coordSys_.localVector(moment_[1]), + coordSys_.localVector(moment_[2]), + localMomentFilePtr_ + ); } + + if (log_) Info << endl; } -void Foam::forces::writeBins() +void Foam::forces::writeBinnedForceMoment +( + const List<Field<vector> >& fm, + autoPtr<OFstream>& osPtr +) const { - if (nBin_ == 1) + if ((nBin_ == 1) || !writeToFile()) { return; } - List<Field<vector> > f(force_); - List<Field<vector> > m(moment_); + List<Field<vector> > f(fm); if (binCumulative_) { @@ -449,27 +685,36 @@ void Foam::forces::writeBins() f[0][i] += f[0][i-1]; f[1][i] += f[1][i-1]; f[2][i] += f[2][i-1]; - - m[0][i] += m[0][i-1]; - m[1][i] += m[1][i-1]; - m[2][i] += m[2][i-1]; } } - file(1) << obr_.time().value(); + Ostream& os = osPtr(); + + os << obr_.time().value(); forAll(f[0], i) { - file(1) - << tab << setw(1) << '(' - << f[0][i] << setw(1) << ' ' - << f[1][i] << setw(1) << ' ' - << f[2][i] << setw(3) << ") (" - << m[0][i] << setw(1) << ' ' - << m[1][i] << setw(1) << ' ' - << m[2][i] << setw(1) << ')'; + vector total = f[0][i] + f[1][i] + f[2][i]; + + os << tab << total + << tab << f[0][i] + << tab << f[1][i]; + + if (porosity_) + { + os << tab << f[2][i]; + } } + os << nl; +} + + +void Foam::forces::writeBins() +{ + writeBinnedForceMoment(force_, forceBinFilePtr_); + writeBinnedForceMoment(moment_, momentBinFilePtr_); + if (localSystem_) { List<Field<vector> > lf(3); @@ -481,33 +726,9 @@ void Foam::forces::writeBins() lm[1] = coordSys_.localVector(moment_[1]); lm[2] = coordSys_.localVector(moment_[2]); - if (binCumulative_) - { - for (label i = 1; i < lf[0].size(); i++) - { - lf[0][i] += lf[0][i-1]; - lf[1][i] += lf[1][i-1]; - lf[2][i] += lf[2][i-1]; - lm[0][i] += lm[0][i-1]; - lm[1][i] += lm[1][i-1]; - lm[2][i] += lm[2][i-1]; - } - } - - forAll(lf[0], i) - { - file(1) - << tab << setw(1) << '(' - << lf[0][i] << setw(1) << ' ' - << lf[1][i] << setw(1) << ' ' - << lf[2][i] << setw(3) << ") (" - << lm[0][i] << setw(1) << ' ' - << lm[1][i] << setw(1) << ' ' - << lm[2][i] << setw(1) << ')'; - } + writeBinnedForceMoment(lf, localForceBinFilePtr_); + writeBinnedForceMoment(lm, localMomentBinFilePtr_); } - - file(1) << endl; } @@ -522,13 +743,20 @@ Foam::forces::forces const bool readFields ) : - functionObjectFile(obr, name, createFileNames(dict)), - name_(name), + functionObjectState(obr, name), + functionObjectFile(obr, name), obr_(obr), - active_(true), log_(true), force_(3), moment_(3), + forceFilePtr_(), + momentFilePtr_(), + forceBinFilePtr_(), + momentBinFilePtr_(), + localForceFilePtr_(), + localMomentFilePtr_(), + localForceBinFilePtr_(), + localMomentBinFilePtr_(), patchSet_(), pName_(word::null), UName_(word::null), @@ -546,33 +774,18 @@ Foam::forces::forces binMin_(GREAT), binPoints_(), binCumulative_(true), + writeFields_(false), initialised_(false) { // Check if the available mesh is an fvMesh otherise deactivate - if (isA<fvMesh>(obr_)) + if (setActive<fvMesh>()) { if (readFields) { read(dict); - Info<< endl; + if (log_) Info << endl; } } - else - { - active_ = false; - WarningIn - ( - "Foam::forces::forces" - "(" - "const word&, " - "const objectRegistry&, " - "const dictionary&, " - "const bool" - ")" - ) << "No fvMesh available, deactivating " << name_ - << endl; - } - } @@ -589,13 +802,20 @@ Foam::forces::forces const coordinateSystem& coordSys ) : - functionObjectFile(obr, name, typeName), - name_(name), + functionObjectState(obr, name), + functionObjectFile(obr, name), obr_(obr), - active_(true), log_(true), force_(3), moment_(3), + forceFilePtr_(), + momentFilePtr_(), + forceBinFilePtr_(), + momentBinFilePtr_(), + localForceFilePtr_(), + localMomentFilePtr_(), + localForceBinFilePtr_(), + localMomentBinFilePtr_(), patchSet_(patchSet), pName_(pName), UName_(UName), @@ -613,8 +833,12 @@ Foam::forces::forces binMin_(GREAT), binPoints_(), binCumulative_(true), + writeFields_(false), initialised_(false) { + // Turn off writing to file + writeToFile_ = false; + forAll(force_, i) { force_[i].setSize(nBin_); @@ -633,195 +857,230 @@ Foam::forces::~forces() void Foam::forces::read(const dictionary& dict) { - if (active_) + if (!active_) { - initialised_ = false; + return; + } - log_ = dict.lookupOrDefault<Switch>("log", false); + functionObjectFile::read(dict); - if (log_) Info<< type() << " " << name_ << ":" << nl; + initialised_ = false; - directForceDensity_ = dict.lookupOrDefault("directForceDensity", false); + log_ = dict.lookupOrDefault<Switch>("log", false); - const fvMesh& mesh = refCast<const fvMesh>(obr_); - const polyBoundaryMesh& pbm = mesh.boundaryMesh(); + if (log_) Info << type() << " " << name_ << ":" << nl; - patchSet_ = pbm.patchSet(wordReList(dict.lookup("patches"))); + directForceDensity_ = dict.lookupOrDefault("directForceDensity", false); - if (directForceDensity_) - { - // Optional entry for fDName - fDName_ = dict.lookupOrDefault<word>("fDName", "fD"); - } - else - { - // Optional entries U and p - pName_ = dict.lookupOrDefault<word>("pName", "p"); - UName_ = dict.lookupOrDefault<word>("UName", "U"); - rhoName_ = dict.lookupOrDefault<word>("rhoName", "rho"); + const fvMesh& mesh = refCast<const fvMesh>(obr_); + const polyBoundaryMesh& pbm = mesh.boundaryMesh(); - // Reference density needed for incompressible calculations - rhoRef_ = readScalar(dict.lookup("rhoInf")); + patchSet_ = pbm.patchSet(wordReList(dict.lookup("patches"))); - // Reference pressure, 0 by default - pRef_ = dict.lookupOrDefault<scalar>("pRef", 0.0); - } + if (directForceDensity_) + { + // Optional entry for fDName + fDName_ = dict.lookupOrDefault<word>("fDName", "fD"); + } + else + { + // Optional entries U and p + pName_ = dict.lookupOrDefault<word>("pName", "p"); + UName_ = dict.lookupOrDefault<word>("UName", "U"); + rhoName_ = dict.lookupOrDefault<word>("rhoName", "rho"); + + // Reference density needed for incompressible calculations + rhoRef_ = readScalar(dict.lookup("rhoInf")); + + // Reference pressure, 0 by default + pRef_ = dict.lookupOrDefault<scalar>("pRef", 0.0); + } + + coordSys_.clear(); + + // Centre of rotation for moment calculations + // specified directly, from coordinate system, or implicitly (0 0 0) + if (!dict.readIfPresent<point>("CofR", coordSys_.origin())) + { + coordSys_ = coordinateSystem(obr_, dict); + localSystem_ = true; + } + + dict.readIfPresent("porosity", porosity_); + if (porosity_) + { + if (log_) Info << " Including porosity effects" << endl; + } + else + { + if (log_) Info << " Not including porosity effects" << endl; + } - coordSys_.clear(); + if (dict.found("binData")) + { + const dictionary& binDict(dict.subDict("binData")); + binDict.lookup("nBin") >> nBin_; - // Centre of rotation for moment calculations - // specified directly, from coordinate system, or implicitly (0 0 0) - if (!dict.readIfPresent<point>("CofR", coordSys_.origin())) + if (nBin_ < 0) { - coordSys_ = coordinateSystem(obr_, dict); - localSystem_ = true; + FatalIOErrorIn + ( + "void Foam::forces::read(const dictionary&)", dict + ) << "Number of bins (nBin) must be zero or greater" + << exit(FatalIOError); } - - dict.readIfPresent("porosity", porosity_); - if (porosity_) + else if (nBin_ == 0) { - if (log_) Info<< " Including porosity effects" << endl; + nBin_ = 1; } else { - if (log_) Info<< " Not including porosity effects" << endl; + binDict.lookup("cumulative") >> binCumulative_; + binDict.lookup("direction") >> binDir_; + binDir_ /= mag(binDir_); } + } - if (dict.found("binData")) + if (nBin_ == 1) + { + // Allocate storage for forces and moments + forAll(force_, i) { - const dictionary& binDict(dict.subDict("binData")); - binDict.lookup("nBin") >> nBin_; + force_[i].setSize(1); + moment_[i].setSize(1); + } + } - if (nBin_ < 0) - { - FatalIOErrorIn + writeFields_ = dict.lookupOrDefault("writeFields", false); + + if (writeFields_) + { + if (log_) Info << " Fields will be written" << endl; + + tmp<volVectorField> tforce + ( + new volVectorField + ( + IOobject ( - "void Foam::forces::read(const dictionary&)", dict - ) << "Number of bins (nBin) must be zero or greater" - << exit(FatalIOError); - } - else if ((nBin_ == 0) || (nBin_ == 1)) - { - nBin_ = 1; - forAll(force_, i) - { - force_[i].setSize(1); - moment_[i].setSize(1); - } - } + fieldName("force"), + mesh.time().timeName(), + mesh, + IOobject::NO_READ, + IOobject::NO_WRITE + ), + mesh, + dimensionedVector("0", dimForce, vector::zero) + ) + ); - if (nBin_ > 1) - { - binDict.lookup("direction") >> binDir_; - binDir_ /= mag(binDir_); + obr_.store(tforce.ptr()); - binMin_ = GREAT; - scalar binMax = -GREAT; - forAllConstIter(labelHashSet, patchSet_, iter) - { - label patchI = iter.key(); - const polyPatch& pp = pbm[patchI]; - scalarField d(pp.faceCentres() & binDir_); - binMin_ = min(min(d), binMin_); - binMax = max(max(d), binMax); - } - reduce(binMin_, minOp<scalar>()); - reduce(binMax, maxOp<scalar>()); + tmp<volVectorField> tmoment + ( + new volVectorField + ( + IOobject + ( + fieldName("moment"), + mesh.time().timeName(), + mesh, + IOobject::NO_READ, + IOobject::NO_WRITE + ), + mesh, + dimensionedVector("0", dimForce*dimLength, vector::zero) + ) + ); - // slightly boost binMax so that region of interest is fully - // within bounds - binMax = 1.0001*(binMax - binMin_) + binMin_; + obr_.store(tmoment.ptr()); + } +} - binDx_ = (binMax - binMin_)/scalar(nBin_); - // create the bin points used for writing - binPoints_.setSize(nBin_); - forAll(binPoints_, i) - { - binPoints_[i] = (i + 0.5)*binDir_*binDx_; - } +void Foam::forces::execute() +{ + if (!active_) + { + return; + } - binDict.lookup("cumulative") >> binCumulative_; + // calcForcesMoment may have reset the active flag - need to re-check + calcForcesMoment(); - // allocate storage for forces and moments - forAll(force_, i) - { - force_[i].setSize(nBin_); - moment_[i].setSize(nBin_); - } - } - } + if (!active_) + { + return; + } - if (nBin_ == 1) - { - // allocate storage for forces and moments - force_[0].setSize(1); - force_[1].setSize(1); - force_[2].setSize(1); - moment_[0].setSize(1); - moment_[1].setSize(1); - moment_[2].setSize(1); - } + if (Pstream::master()) + { + createFiles(); + + writeForces(); + + writeBins(); + + if (log_) Info << endl; } -} + // write state/results information + setResult("normalForce", sum(force_[0])); + setResult("tangentialForce", sum(force_[1])); + setResult("porousForce", sum(force_[2])); -void Foam::forces::execute() -{ - // Do nothing - only valid on write + setResult("normalMoment", sum(moment_[0])); + setResult("tangentialMoment", sum(moment_[1])); + setResult("porousMoment", sum(moment_[2])); } void Foam::forces::end() { - // Do nothing - only valid on write + if (active_) + { + execute(); + } } void Foam::forces::timeSet() { - // Do nothing - only valid on write + // Do nothing } void Foam::forces::write() { - calcForcesMoment(); - if (!active_) { return; } - if (Pstream::master()) + if (writeFields_) { - functionObjectFile::write(); - - writeForces(); - - writeBins(); - - if (log_) Info<< endl; + obr_.lookupObject<volVectorField>(fieldName("force")).write(); + obr_.lookupObject<volVectorField>(fieldName("moment")).write(); } } void Foam::forces::calcForcesMoment() { + if (!active_) + { + return; + } + initialise(); + // Initialise may have reset the active flag - need to re-check if (!active_) { return; } - force_[0] = vector::zero; - force_[1] = vector::zero; - force_[2] = vector::zero; - - moment_[0] = vector::zero; - moment_[1] = vector::zero; - moment_[2] = vector::zero; + resetFields(); if (directForceDensity_) { @@ -858,6 +1117,8 @@ void Foam::forces::calcForcesMoment() //- Porous force vectorField fP(Md.size(), vector::zero); + addToFields(patchI, Md, fN, fT, fP); + applyBins(Md, fN, fT, fP, mesh.C().boundaryField()[patchI]); } } @@ -896,6 +1157,8 @@ void Foam::forces::calcForcesMoment() vectorField fP(Md.size(), vector::zero); + addToFields(patchI, Md, fN, fT, fP); + applyBins(Md, fN, fT, fP, mesh.C().boundaryField()[patchI]); } } @@ -939,6 +1202,8 @@ void Foam::forces::calcForcesMoment() const vectorField fDummy(Md.size(), vector::zero); + addToFields(cZone, Md, fDummy, fDummy, fP); + applyBins(Md, fDummy, fDummy, fP, d); } } diff --git a/src/postProcessing/functionObjects/forces/forces/forces.H b/src/postProcessing/functionObjects/forces/forces/forces.H index f0131f0c32ef4127c211b212f27615150b644cf0..32839b5a0a784a197311fafbdd4898503a6b1954 100644 --- a/src/postProcessing/functionObjects/forces/forces/forces.H +++ b/src/postProcessing/functionObjects/forces/forces/forces.H @@ -2,8 +2,8 @@ ========= | \\ / F ield | OpenFOAM: The Open Source CFD Toolbox \\ / O peration | - \\ / A nd | Copyright (C) 2011-2013 OpenFOAM Foundation - \\/ M anipulation | + \\ / A nd | Copyright (C) 2011-2015 OpenFOAM Foundation + \\/ M anipulation | Copyright (C) 2015 OpenCFD Ltd ------------------------------------------------------------------------------- License This file is part of OpenFOAM. @@ -29,11 +29,24 @@ Group Description This function object calculates the forces and moments by integrating the - pressure and skin-friction forces over a given list of patches. - - Member function forces::write() calculates the forces/moments and - writes the forces/moments into the file \<timeDir\>/forces.dat and bin - data (if selected) to the file \<timeDir\>/forces_bin.dat + pressure and skin-friction forces over a given list of patches, and + the resistance from porous zones. + + Forces and moments are calculated, with optional co-ordinate system and + writing of binned data, where force and moment contributions are collected + into a user-defined number of bins that span the input geometries for a + user-defined direction vector. + + Data is written into multiple files in the + postProcessing/\<functionObjectName\> directory: + - force.dat : forces in global Cartesian co-ordinate system + - moment.dat : moments in global Cartesian co-ordinate system + - forceBin.dat : force bins in global Cartesian co-ordinate system + - momentBin.dat : moment bins in global Cartesian co-ordinate system + - localForce.dat : forces in local co-ordinate system + - localMoment.dat : moments in local co-ordinate system + - localForceBin.dat : force bins in local co-ordinate system + - localMomentBin.dat : moment bins in local co-ordinate system Example of function object specification: \verbatim @@ -43,6 +56,7 @@ Description functionObjectLibs ("libforces.so"); ... log yes; + writeFields yes; patches (walls); binData @@ -59,6 +73,7 @@ Description Property | Description | Required | Default value type | type name: forces | yes | log | write force data to standard output | no | no + writeFields | write the force and moment fields | no | no patches | patches included in the forces calculation | yes | pName | pressure field name | no | p UName | velocity field name | no | U @@ -101,6 +116,8 @@ Note SeeAlso Foam::functionObject + Foam::functionObjectFile + Foam::functionObjectState Foam::OutputFilterFunctionObject Foam::forceCoeffs @@ -113,6 +130,7 @@ SourceFiles #ifndef forces_H #define forces_H +#include "functionObjectState.H" #include "functionObjectFile.H" #include "coordinateSystem.H" #include "coordinateSystems.H" @@ -122,7 +140,6 @@ SourceFiles #include "Tuple2.H" #include "OFstream.H" #include "Switch.H" -#include "writer.H" // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // @@ -141,21 +158,16 @@ class mapPolyMesh; class forces : + public functionObjectState, public functionObjectFile { protected: // Protected data - //- Name of this set of forces, - // Also used as the name of the probes directory. - word name_; - + //- Reference to the database const objectRegistry& obr_; - //- On/off switch - bool active_; - //- Switch to send output to Info as well as to file Switch log_; @@ -165,6 +177,32 @@ protected: //- Pressure, viscous and porous moment per bin List<Field<vector> > moment_; + // File streams + + //- Forces + autoPtr<OFstream> forceFilePtr_; + + //- Moments + autoPtr<OFstream> momentFilePtr_; + + //- Force bins + autoPtr<OFstream> forceBinFilePtr_; + + //- Moment bins + autoPtr<OFstream> momentBinFilePtr_; + + //- Local force + autoPtr<OFstream> localForceFilePtr_; + + //- Local moment + autoPtr<OFstream> localMomentFilePtr_; + + //- Local force bins + autoPtr<OFstream> localForceBinFilePtr_; + + //- Local moment bins + autoPtr<OFstream> localMomentBinFilePtr_; + // Read from dictionary @@ -223,21 +261,36 @@ protected: bool binCumulative_; + //- Write fields flag + bool writeFields_; + //- Initialised flag bool initialised_; // Protected Member Functions - //- Create file names for forces and bins - wordList createFileNames(const dictionary& dict) const; + //- Create a field name + word fieldName(const word& name) const; + + //- Create the output files + void createFiles(); - //- Output file header information - virtual void writeFileHeader(const label i); + //- Write header for integrated data + void writeIntegratedHeader(const word& header, Ostream& os) const; + + //- Write header for binned data + void writeBinHeader(const word& header, Ostream& os) const; //- Initialise the fields void initialise(); + //- Initialise the collection bins + void initialiseBins(); + + //- Reset the fields prior to accumulation of force/moments + void resetFields(); + //- Return the effective viscous stress (laminar + turbulent). tmp<volSymmTensorField> devRhoReff() const; @@ -261,10 +314,47 @@ protected: const vectorField& d ); - //- Helper function to write force data + //- Add patch contributions to force and moment fields + void addToFields + ( + const label patchI, + const vectorField& Md, + const vectorField& fN, + const vectorField& fT, + const vectorField& fP + ); + + //- Add cell contributions to force and moment fields + void addToFields + ( + const labelList& cellIDs, + const vectorField& Md, + const vectorField& fN, + const vectorField& fT, + const vectorField& fP + ); + + //- Helper function to write integrated forces and moments + void writeIntegratedForceMoment + ( + const string& descriptor, + const vectorField& fm0, + const vectorField& fm1, + const vectorField& fm2, + autoPtr<OFstream>& osPtr + ) const; + + //- Write force data void writeForces(); - //- Helper function to write bin data + //- Helper function to write binned forces and moments + void writeBinnedForceMoment + ( + const List<Field<vector> >& fm, + autoPtr<OFstream>& osPtr + ) const; + + //- Write binned data void writeBins(); //- Disallow default bitwise copy construct diff --git a/src/postProcessing/functionObjects/graphics/Allwmake b/src/postProcessing/functionObjects/graphics/Allwmake new file mode 100755 index 0000000000000000000000000000000000000000..fc5ea8144bd5d6957a142f890c71b26b4428dcff --- /dev/null +++ b/src/postProcessing/functionObjects/graphics/Allwmake @@ -0,0 +1,4 @@ +#!/bin/sh +cd ${0%/*} || exit 1 # Run from this directory + +./runTimePostProcessing/Allwmake diff --git a/src/postProcessing/functionObjects/graphics/runTimePostProcessing/Allwclean b/src/postProcessing/functionObjects/graphics/runTimePostProcessing/Allwclean new file mode 100755 index 0000000000000000000000000000000000000000..b570283bce32175fee1a3aaa778128a115bf1cd3 --- /dev/null +++ b/src/postProcessing/functionObjects/graphics/runTimePostProcessing/Allwclean @@ -0,0 +1,12 @@ +#!/bin/sh +cd ${0%/*} || exit 1 # Run from this directory + +# Source the wmake functions +. $WM_DIR/scripts/wmakeFunctions + +( + # Where are the generated files stored? + findObjectDir dummy.C + depDir="$objectsDir" + rm -rf "$depDir" > /dev/null 2>&1 +) diff --git a/src/postProcessing/functionObjects/graphics/runTimePostProcessing/Allwmake b/src/postProcessing/functionObjects/graphics/runTimePostProcessing/Allwmake new file mode 100755 index 0000000000000000000000000000000000000000..aa7ed7cc7e98bbed6f7f9c8a58be44e65f5a215f --- /dev/null +++ b/src/postProcessing/functionObjects/graphics/runTimePostProcessing/Allwmake @@ -0,0 +1,28 @@ +#!/bin/sh +cd ${0%/*} || exit 1 # Run from this directory + +# Source the wmake functions +. $WM_DIR/scripts/wmakeFunctions + +# Store current directory +sourceDir=$PWD + +# Where are any generated files stored? +findObjectDir dummy.C +depDir="$objectsDir" + +if [ -d "$VTK_DIR" -o -d "$ParaView_DIR" ] +then + # ensure CMake gets the correct C++ compiler + [ -n "$WM_CXX" ] && export CXX="$WM_CXX" + [ -n "$WM_CC" ] && export CC="$WM_CC" + + (mkdir -p $depDir && cd $depDir && cmake $sourceDir && make) +else + echo "ERROR: Build of $PWD requires a valid VTK installation which" + echo " can be supplied either by ParaView by VTK. In case of" + echo " - ParaView : export the ParaView_DIR environment variable" + echo " - VTK : export the VTK_DIR variable" +fi + +# ----------------------------------------------------------------- end-of-file diff --git a/src/postProcessing/functionObjects/graphics/runTimePostProcessing/CMakeLists-Common.txt b/src/postProcessing/functionObjects/graphics/runTimePostProcessing/CMakeLists-Common.txt new file mode 100644 index 0000000000000000000000000000000000000000..d309a24fd56bb75d769e18f14b4d6e02410594fb --- /dev/null +++ b/src/postProcessing/functionObjects/graphics/runTimePostProcessing/CMakeLists-Common.txt @@ -0,0 +1,84 @@ +include(${VTK_USE_FILE}) + +if(VTK_LIBRARIES) + message("Found VTK LIBRARIES: " ${VTK_USE_FILE}) +endif() + +if(${VTK_VERSION} VERSION_GREATER "6") + message("VTK version: " ${VTK_VERSION}) +else() + message(FATAL_ERROR " VTK6 required") +endif() + +include_directories( + $ENV{WM_PROJECT_DIR}/src/OpenFOAM/lnInclude + $ENV{WM_PROJECT_DIR}/src/OSspecific/$ENV{WM_OSTYPE}/lnInclude + $ENV{WM_PROJECT_DIR}/src/triSurface/lnInclude + $ENV{WM_PROJECT_DIR}/src/finiteVolume/lnInclude + ${CMAKE_CURRENT_SOURCE_DIR} + ${CMAKE_CURRENT_BINARY_DIR} +) + +link_directories( + $ENV{FOAM_LIBBIN} + $ENV{FOAM_EXT_LIBBIN} +) + +add_definitions( + -DWM_$ENV{WM_PRECISION_OPTION} -DNoRepository + -DWM_LABEL_SIZE=$ENV{WM_LABEL_SIZE} +) + +set(CMAKE_BUILD_TYPE Release) + +set(CMAKE_CXX_FLAGS_DEBUG + "-g -O0 -Wall -Wextra -Wno-unused-parameter -Wnon-virtual-dtor -Wno-overloaded-virtual" +) +set(CMAKE_C_FLAGS_DEBUG "-g -O0") + +set(CMAKE_CXX_FLAGS_RELEASE + "-O3 -Wall -Wextra -Wno-unused-parameter -Wnon-virtual-dtor -Wno-overloaded-virtual") +set(CMAKE_C_FLAGS_RELEASE "-O3") + +# Set output library destination to plugin directory +set(LIBRARY_OUTPUT_PATH $ENV{FOAM_LIBBIN} + CACHE INTERNAL + "" +) + +file(GLOB SOURCE_FILES + fieldVisualisationBase.C + functionObjectCloud.C + functionObjectLine.C + functionObjectSurface.C + geometryBase.C + geometrySurface.C + pathline.C + pointData.C + runTimePostProcessing.C + runTimePostProcessingFunctionObject.C + scene.C + surface.C + text.C +) + +set(OPENFOAM_LIBRARIES + OpenFOAM + triSurface + finiteVolume +) + +add_library( + runTimePostProcessing + SHARED + ${SOURCE_FILES} +) + +target_link_libraries( + runTimePostProcessing + ${VTK_LIBRARIES} + ${OPENFOAM_LIBRARIES} +) + + +#----------------------------------------------------------------------------- diff --git a/src/postProcessing/functionObjects/graphics/runTimePostProcessing/CMakeLists.txt b/src/postProcessing/functionObjects/graphics/runTimePostProcessing/CMakeLists.txt new file mode 100644 index 0000000000000000000000000000000000000000..b2afd1e03d986cb76a4fec9cfb3e9f5715505dd6 --- /dev/null +++ b/src/postProcessing/functionObjects/graphics/runTimePostProcessing/CMakeLists.txt @@ -0,0 +1,23 @@ +cmake_minimum_required(VERSION 2.8) + +project(runTimePostProcessing) + +if (EXISTS $ENV{VTK_DIR}) + message("Building with VTK from $ENV{VTK_DIR}") + find_package(VTK REQUIRED HINTS $ENV{VTK_DIR}) + include(${VTK_USE_FILE}) + +else (EXISTS $ENV{ParaView_DIR}) + message("Building with Paraview from $ENV{ParaView_DIR}") + find_package(ParaView REQUIRED) + include(${VTK_USE_FILE}) + + set( + VTK_VERSION + "${VTK_MAJOR_VERSION}.${VTK_MINOR_VERSION}.${VTK_BUILD_VERSION}" + ) +endif (EXISTS $ENV{VTK_DIR}) + +include(CMakeLists-Common.txt) + +#----------------------------------------------------------------------------- diff --git a/src/postProcessing/functionObjects/graphics/runTimePostProcessing/IOrunTimePostProcessing.H b/src/postProcessing/functionObjects/graphics/runTimePostProcessing/IOrunTimePostProcessing.H new file mode 100644 index 0000000000000000000000000000000000000000..dd39c24c3384bff7d1fec07c20656dd34a129104 --- /dev/null +++ b/src/postProcessing/functionObjects/graphics/runTimePostProcessing/IOrunTimePostProcessing.H @@ -0,0 +1,49 @@ +/*---------------------------------------------------------------------------*\ + ========= | + \\ / F ield | OpenFOAM: The Open Source CFD Toolbox + \\ / O peration | + \\ / A nd | Copyright (C) 2015 OpenFOAM Foundation + \\/ M anipulation | +------------------------------------------------------------------------------- +License + This file is part of OpenFOAM. + + OpenFOAM is free software: you can redistribute it and/or modify it + under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + OpenFOAM is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + for more details. + + You should have received a copy of the GNU General Public License + along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>. + +Typedef + Foam::IOrunTimePostProcessing + +Description + Instance of the generic IOOutputFilter for runTimePostProcessing. + +\*---------------------------------------------------------------------------*/ + +#ifndef IOrunTimePostProcessing_H +#define IOrunTimePostProcessing_H + +#include "runTimePostProcessing.H" +#include "IOOutputFilter.H" + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +namespace Foam +{ + typedef IOOutputFilter<runTimePostProcessing> IOrunTimePostProcessing; +} + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +#endif + +// ************************************************************************* // diff --git a/src/postProcessing/functionObjects/graphics/runTimePostProcessing/fieldVisualisationBase.C b/src/postProcessing/functionObjects/graphics/runTimePostProcessing/fieldVisualisationBase.C new file mode 100644 index 0000000000000000000000000000000000000000..e7de2eb2d9abb1a23ea2738708359e47f9445026 --- /dev/null +++ b/src/postProcessing/functionObjects/graphics/runTimePostProcessing/fieldVisualisationBase.C @@ -0,0 +1,517 @@ +/*---------------------------------------------------------------------------*\ + ========= | + \\ / F ield | OpenFOAM: The Open Source CFD Toolbox + \\ / O peration | + \\ / A nd | Copyright (C) 2015 OpenFOAM Foundation + \\/ M anipulation | +------------------------------------------------------------------------------- +License + This file is part of OpenFOAM. + + OpenFOAM is free software: you can redistribute it and/or modify it + under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + OpenFOAM is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + for more details. + + You should have received a copy of the GNU General Public License + along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>. + +\*---------------------------------------------------------------------------*/ + +// OpenFOAM includes +#include "fieldVisualisationBase.H" +#include "runTimePostProcessing.H" + +// VTK includes +#include "vtkArrowSource.h" +#include "vtkColorTransferFunction.h" +#include "vtkFloatArray.h" +#include "vtkGlyph3D.h" +#include "vtkLookupTable.h" +#include "vtkPointData.h" +#include "vtkPolyData.h" +#include "vtkPolyDataMapper.h" +#include "vtkRenderer.h" +#include "vtkScalarBarActor.h" +#include "vtkSmartPointer.h" +#include "vtkSphereSource.h" +#include "vtkTextActor.h" +#include "vtkTextProperty.h" + +// * * * * * * * * * * * * * Static Member Functions * * * * * * * * * * * * // + +namespace Foam +{ + template<> + const char* NamedEnum<fieldVisualisationBase::colourByType, 2>::names[] = + { + "colour", + "field" + }; + + template<> + const char* NamedEnum<fieldVisualisationBase::colourMapType, 4>::names[] = + { + "rainbow", + "blueWhiteRed", + "fire", + "greyscale" + }; +} + +const Foam::NamedEnum<Foam::fieldVisualisationBase::colourByType, 2> + Foam::fieldVisualisationBase::colourByTypeNames; + +const Foam::NamedEnum<Foam::fieldVisualisationBase::colourMapType, 4> + Foam::fieldVisualisationBase::colourMapTypeNames; + + +// * * * * * * * * * * * * Protected Member Functions * * * * * * * * * * * // + +void Foam::fieldVisualisationBase::setColourMap(vtkLookupTable* lut) const +{ + label nColours = 256; + + lut->SetNumberOfColors(nColours); + + vtkSmartPointer<vtkColorTransferFunction> ctf = + vtkSmartPointer<vtkColorTransferFunction>::New(); + + switch (colourMap_) + { + case cmRainbow: + { + ctf->SetColorSpaceToHSV(); + ctf->AddRGBPoint(0, 0, 0, 1); + ctf->AddRGBPoint(0.5, 0, 1, 0); + ctf->AddRGBPoint(1, 1, 0, 0); + break; + } + case cmBlueWhiteRed: + { + // Values taken from ParaView settings + ctf->SetColorSpaceToDiverging(); + ctf->AddRGBPoint(0.0, 0.231373, 0.298039, 0.752941); + ctf->AddRGBPoint(0.5, 0.865003, 0.865003, 0.865003); + ctf->AddRGBPoint(1.0, 0.705882, 0.0156863, 0.14902); + break; + } + case cmFire: + { + // Values taken from ParaView settings + ctf->SetColorSpaceToRGB(); + ctf->AddRGBPoint(0, 0, 0, 0); + ctf->AddRGBPoint(0.4, 0.901961, 0, 0); + ctf->AddRGBPoint(0.8, 0.901961, 0.901961, 0); + ctf->AddRGBPoint(1, 1, 1, 1); + break; + } + case cmGreyscale: + { + ctf->SetColorSpaceToRGB(); + ctf->AddRGBPoint(0, 0, 0, 0); + ctf->AddRGBPoint(1, 1, 1, 1); + break; + } + } + + + for (label i = 0; i < nColours; i++) + { + double* c = ctf->GetColor(scalar(i)/scalar(nColours)); + lut->SetTableValue(i, c[0], c[1], c[2], 1.0); + } +} + + +void Foam::fieldVisualisationBase::addScalarBar +( + const scalar position, + vtkRenderer* renderer, + vtkLookupTable* lut +) const +{ + // add scalar bar legend + if (!scalarBar_.visible_) + { + return; + } + + vtkSmartPointer<vtkScalarBarActor> sbar = + vtkSmartPointer<vtkScalarBarActor>::New(); + sbar->SetLookupTable(lut); + sbar->SetNumberOfLabels(scalarBar_.numberOfLabels_); + + const vector textColour = colours_["text"]->value(position); + + // workaround to supply our own scalarbar title + vtkSmartPointer<vtkTextActor> titleActor = + vtkSmartPointer<vtkTextActor>::New(); + sbar->SetTitle(" "); + titleActor->SetInput(scalarBar_.title_.c_str()); + titleActor->GetTextProperty()->SetFontFamilyToArial(); + titleActor->GetTextProperty()->SetFontSize(3*scalarBar_.fontSize_); + titleActor->GetTextProperty()->SetJustificationToCentered(); + titleActor->GetTextProperty()->SetVerticalJustificationToBottom(); + titleActor->GetTextProperty()->BoldOn(); + titleActor->GetTextProperty()->ItalicOff(); + titleActor->GetTextProperty()->SetColor + ( + textColour[0], + textColour[1], + textColour[2] + ); + titleActor->GetPositionCoordinate()-> + SetCoordinateSystemToNormalizedViewport(); + +/* + sbar->SetTitle(scalarBar_.title_.c_str()); + sbar->GetTitleTextProperty()->SetColor + ( + textColour[0], + textColour[1], + textColour[2] + ); + sbar->GetTitleTextProperty()->SetFontSize(scalarBar_.fontSize_); + sbar->GetTitleTextProperty()->ShadowOff(); + sbar->GetTitleTextProperty()->BoldOn(); + sbar->GetTitleTextProperty()->ItalicOff(); +*/ + + sbar->GetLabelTextProperty()->SetColor + ( + textColour[0], + textColour[1], + textColour[2] + ); + sbar->GetLabelTextProperty()->SetFontSize(scalarBar_.fontSize_); + sbar->GetLabelTextProperty()->ShadowOff(); + sbar->GetLabelTextProperty()->BoldOff(); + sbar->GetLabelTextProperty()->ItalicOff(); + sbar->SetLabelFormat(scalarBar_.labelFormat_.c_str()); + + sbar->GetPositionCoordinate()->SetCoordinateSystemToNormalizedViewport(); + sbar->GetPositionCoordinate()->SetValue + ( + scalarBar_.position_.first(), + scalarBar_.position_.second() + ); + if (scalarBar_.vertical_) + { + sbar->SetOrientationToVertical(); + sbar->SetWidth(0.1); + sbar->SetHeight(0.75); + sbar->SetTextPositionToSucceedScalarBar(); + } + else + { + sbar->SetOrientationToHorizontal(); + + // adjustments since not using scalarbar title property + sbar->SetWidth(0.75); + sbar->SetHeight(0.07); + sbar->SetBarRatio(0.5); +// sbar->SetHeight(0.1); +// sbar->SetTitleRatio(0.01); + sbar->SetTextPositionToPrecedeScalarBar(); + } + + titleActor->GetPositionCoordinate()->SetValue + ( + scalarBar_.position_.first() + 0.5*sbar->GetWidth(), + scalarBar_.position_.second() + sbar->GetHeight() + ); + +// sbar->DrawFrameOn(); +// sbar->DrawBackgroundOn(); +// sbar->UseOpacityOff(); +// sbar->VisibilityOff(); + sbar->VisibilityOn(); + + renderer->AddActor(sbar); + renderer->AddActor2D(titleActor); +} + + +void Foam::fieldVisualisationBase::setField +( + const scalar position, + const word& colourFieldName, + vtkPolyDataMapper* mapper, + vtkRenderer* renderer +) const +{ + mapper->InterpolateScalarsBeforeMappingOn(); + + switch (colourBy_) + { + case cbColour: + { + mapper->ScalarVisibilityOff(); + break; + } + case cbField: + { + // create look-up table for colours + vtkSmartPointer<vtkLookupTable> lut = + vtkSmartPointer<vtkLookupTable>::New(); + setColourMap(lut); + lut->SetVectorMode(vtkScalarsToColors::MAGNITUDE); + + // configure the mapper + mapper->SelectColorArray(colourFieldName.c_str()); + mapper->SetScalarRange(range_.first(), range_.second()); + mapper->SetScalarModeToUsePointFieldData(); + + mapper->SetColorModeToMapScalars(); + mapper->SetLookupTable(lut); + mapper->ScalarVisibilityOn(); + + // add the bar + addScalarBar(position, renderer, lut); + break; + } + } + + mapper->Modified(); +} + + + +void Foam::fieldVisualisationBase::addGlyphs +( + const scalar position, + const word& scaleFieldName, + const word& colourFieldName, + const scalar maxGlyphLength, + vtkPolyData* data, + vtkActor* actor, + vtkRenderer* renderer +) const +{ + vtkSmartPointer<vtkGlyph3D> glyph = vtkSmartPointer<vtkGlyph3D>::New(); + vtkSmartPointer<vtkPolyDataMapper> glyphMapper = + vtkSmartPointer<vtkPolyDataMapper>::New(); + glyphMapper->SetInputConnection(glyph->GetOutputPort()); + + glyph->SetInputData(data); + glyph->ScalingOn(); + bool ok = true; + + label nComponents = + data->GetPointData()->GetArray(scaleFieldName.c_str()) + ->GetNumberOfComponents(); + + if (nComponents == 1) + { + vtkSmartPointer<vtkSphereSource> sphere = + vtkSmartPointer<vtkSphereSource>::New(); + sphere->SetCenter(0, 0, 0); + sphere->SetRadius(0.5); +// setting higher resolution slows the rendering significantly +// sphere->SetPhiResolution(20); +// sphere->SetThetaResolution(20); + + glyph->SetSourceConnection(sphere->GetOutputPort()); + + if (maxGlyphLength > 0) + { + double range[2]; + +// can use values to find range +// vtkDataArray* values = +// data->GetPointData()->GetScalars(scaleFieldName.c_str()); +// values->GetRange(range); + + // set range accoding to user-supplied limits + range[0] = range_.first(); + range[1] = range_.second(); + glyph->ClampingOn(); + glyph->SetRange(range); + + // if range[0] != min(value), maxGlyphLength behaviour will not + // be correct... + glyph->SetScaleFactor(maxGlyphLength); + } + else + { + glyph->SetScaleFactor(1); + } + glyph->SetScaleModeToScaleByScalar(); + glyph->OrientOff(); + glyph->SetColorModeToColorByScalar(); + glyph->SetInputArrayToProcess + ( + 0, // scalars + 0, + 0, + vtkDataObject::FIELD_ASSOCIATION_POINTS, + scaleFieldName.c_str() + ); + } + else if (nComponents == 3) + { + vtkSmartPointer<vtkArrowSource> arrow = + vtkSmartPointer<vtkArrowSource>::New(); + arrow->SetTipResolution(10); + arrow->SetTipRadius(0.1); + arrow->SetTipLength(0.35); + arrow->SetShaftResolution(10); + arrow->SetShaftRadius(0.03); + + glyph->SetSourceConnection(arrow->GetOutputPort()); + + if (maxGlyphLength > 0) + { + vtkDataArray* values = + data->GetPointData()->GetVectors(scaleFieldName.c_str()); + double range[6]; + values->GetRange(range); + +/* + // attempt to set range for vectors... + scalar x0 = sqrt(sqr(range_.first())/3.0); + scalar x1 = sqrt(sqr(range_.second())/3.0); + range[0] = x0; + range[1] = x0; + range[2] = x0; + range[3] = x1; + range[4] = x1; + range[5] = x1; +*/ + glyph->ClampingOn(); + glyph->SetRange(range); + glyph->SetScaleFactor(maxGlyphLength); + } + else + { + glyph->SetScaleFactor(1); + } + glyph->SetScaleModeToScaleByVector(); + glyph->OrientOn(); + glyph->SetVectorModeToUseVector(); + glyph->SetColorModeToColorByVector(); + glyph->SetInputArrayToProcess + ( + 1, // vectors + 0, + 0, + vtkDataObject::FIELD_ASSOCIATION_POINTS, + scaleFieldName.c_str() + ); + } + else + { + WarningIn + ( + "void Foam::fieldVisualisationBase::addGlyphs" + "(" + "const scalar, " + "const word&, " + "const word&, " + "const scalar, " + "vtkPolyData*, " + "vtkActor*, " + "vtkRenderer*" + ") const" + ) + << "Glyphs can only be added to " << pTraits<scalar>::typeName + << " and " << pTraits<vector>::typeName << " fields. " + << " Field " << scaleFieldName << " has " << nComponents + << " components" << endl; + + ok = false; + } + + if (ok) + { + glyph->Update(); + + setField(position, colourFieldName, glyphMapper, renderer); + + glyphMapper->Update(); + + actor->SetMapper(glyphMapper); + + renderer->AddActor(actor); + } +} + + +// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * // + +Foam::fieldVisualisationBase::fieldVisualisationBase +( + const runTimePostProcessing& parent, + const dictionary& dict, + const HashPtrTable<DataEntry<vector>, word>& colours +) +: + parent_(parent), + colours_(colours), + fieldName_(dict.lookup("fieldName")), + colourBy_(cbColour), + colourMap_(cmRainbow), + range_() +{ + colourBy_ = colourByTypeNames.read(dict.lookup("colourBy")); + + switch (colourBy_) + { + case cbColour: + { + break; + } + case cbField: + { + dict.lookup("range") >> range_; + break; + } + } + + if (dict.found("colourMap")) + { + colourMap_ = colourMapTypeNames.read(dict.lookup("colourMap")); + } + + const dictionary& sbarDict = dict.subDict("scalarBar"); + sbarDict.lookup("visible") >> scalarBar_.visible_; + if (scalarBar_.visible_) + { + sbarDict.lookup("vertical") >> scalarBar_.vertical_; + sbarDict.lookup("position") >> scalarBar_.position_; + sbarDict.lookup("title") >> scalarBar_.title_; + sbarDict.lookup("fontSize") >> scalarBar_.fontSize_; + sbarDict.lookup("labelFormat") >> scalarBar_.labelFormat_; + sbarDict.lookup("numberOfLabels") >> scalarBar_.numberOfLabels_; + } +} + + +// * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * // + +Foam::fieldVisualisationBase::~fieldVisualisationBase() +{} + + +// * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * * // + +const Foam::HashPtrTable<Foam::DataEntry<Foam::vector>, Foam::word>& +Foam::fieldVisualisationBase::colours() const +{ + return colours_; +} + + +const Foam::word& Foam::fieldVisualisationBase::fieldName() const +{ + return fieldName_; +} + + +// ************************************************************************* // diff --git a/src/postProcessing/functionObjects/graphics/runTimePostProcessing/fieldVisualisationBase.H b/src/postProcessing/functionObjects/graphics/runTimePostProcessing/fieldVisualisationBase.H new file mode 100644 index 0000000000000000000000000000000000000000..e365ddf59792c0fd4fb66ea5ac29715dcc1f5145 --- /dev/null +++ b/src/postProcessing/functionObjects/graphics/runTimePostProcessing/fieldVisualisationBase.H @@ -0,0 +1,216 @@ +/*---------------------------------------------------------------------------*\ + ========= | + \\ / F ield | OpenFOAM: The Open Source CFD Toolbox + \\ / O peration | + \\ / A nd | Copyright (C) 2015 OpenFOAM Foundation + \\/ M anipulation | +------------------------------------------------------------------------------- +License + This file is part of OpenFOAM. + + OpenFOAM is free software: you can redistribute it and/or modify it + under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + OpenFOAM is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + for more details. + + You should have received a copy of the GNU General Public License + along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>. + +Class + Foam::fieldVisualisationBase + +Description + +SourceFiles + fieldVisualisationBase.C + +\*---------------------------------------------------------------------------*/ + +#ifndef fieldVisualisationBase_H +#define fieldVisualisationBase_H + +#include "dictionary.H" +#include "Tuple2.H" +#include "NamedEnum.H" +#include "vector.H" +#include "HashPtrTable.H" +#include "DataEntry.H" + +#include "vtkSmartPointer.h" + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +class vtkActor; +class vtkLookupTable; +class vtkPolyData; +class vtkPolyDataMapper; +class vtkRenderer; + + +class vtkMapper; + +namespace Foam +{ + +class runTimePostProcessing; + +/*---------------------------------------------------------------------------*\ + Class fieldVisualisationBase Declaration +\*---------------------------------------------------------------------------*/ + +class fieldVisualisationBase +{ +public: + + // Public enumerations + + enum colourByType + { + cbColour, + cbField + }; + + static const NamedEnum<colourByType, 2> colourByTypeNames; + + enum colourMapType + { + cmRainbow, + cmBlueWhiteRed, + cmFire, + cmGreyscale + }; + + static const NamedEnum<colourMapType, 4> colourMapTypeNames; + + +private: + + // Private data + + //- Reference to the parent function object + const runTimePostProcessing& parent_; + + + // Private Member Functions + + //- Disallow default bitwise copy construct + fieldVisualisationBase(const fieldVisualisationBase&); + + //- Disallow default bitwise assignment + void operator=(const fieldVisualisationBase&); + + +protected: + + // Protected data + + struct scalarBar + { + bool visible_; + bool vertical_; + Tuple2<scalar, scalar> position_; + string title_; + label fontSize_; + string labelFormat_; + label numberOfLabels_; + }; + + //- Colours + const HashPtrTable<DataEntry<vector>, word>& colours_; + + //- Field name + word fieldName_; + + //- Colour by type + colourByType colourBy_; + + //- Colour map type + colourMapType colourMap_; + + //- Range of values + Tuple2<scalar, scalar> range_; + + //- Scalar bar + scalarBar scalarBar_; + + + // Protected Member Functions + + //- Set the colour map + void setColourMap(vtkLookupTable* lut) const; + + //- Add scalar bar to renderer + void addScalarBar + ( + const scalar position, + vtkRenderer* renderer, + vtkLookupTable* lut + ) const; + + //- Set field/configure mapper, add scalar bar + void setField + ( + const scalar position, + const word& colourFieldName, + vtkPolyDataMapper* mapper, + vtkRenderer* renderer + ) const; + + //- Add glyphs + void addGlyphs + ( + const scalar position, + const word& scaleFieldName, + const word& colourFieldName, + const scalar maxGlyphLength, + vtkPolyData* data, + vtkActor* actor, + vtkRenderer* renderer + ) const; + + +public: + + // Constructors + + //- Construct from dictionary + fieldVisualisationBase + ( + const runTimePostProcessing& parent, + const dictionary& dict, + const HashPtrTable<DataEntry<vector>, word>& colours + ); + + + //- Destructor + virtual ~fieldVisualisationBase(); + + + // Member Functions + + // Access + + //- Return the colours + const HashPtrTable<DataEntry<vector>, word>& colours() const; + + //- Return the field name + const word& fieldName() const; +}; + + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +} // End namespace Foam + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +#endif + +// ************************************************************************* // diff --git a/src/postProcessing/functionObjects/graphics/runTimePostProcessing/functionObjectCloud.C b/src/postProcessing/functionObjects/graphics/runTimePostProcessing/functionObjectCloud.C new file mode 100644 index 0000000000000000000000000000000000000000..fe863c2cf2e27e0740b91cac00651731bc24dab5 --- /dev/null +++ b/src/postProcessing/functionObjects/graphics/runTimePostProcessing/functionObjectCloud.C @@ -0,0 +1,157 @@ +/*---------------------------------------------------------------------------*\ + ========= | + \\ / F ield | OpenFOAM: The Open Source CFD Toolbox + \\ / O peration | + \\ / A nd | Copyright (C) 2015 OpenFOAM Foundation + \\/ M anipulation | +------------------------------------------------------------------------------- +License + This file is part of OpenFOAM. + + OpenFOAM is free software: you can redistribute it and/or modify it + under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + OpenFOAM is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + for more details. + + You should have received a copy of the GNU General Public License + along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>. + +\*---------------------------------------------------------------------------*/ + +// OpenFOAM includes +#include "functionObjectCloud.H" +#include "runTimePostProcessing.H" +#include "addToRunTimeSelectionTable.H" + +// VTK includes +#include "vtkActor.h" +#include "vtkRenderer.h" +#include "vtkSmartPointer.h" +#include "vtkPolyDataMapper.h" +#include "vtkPolyDataReader.h" +#include "vtkProperty.h" + +// * * * * * * * * * * * * * Static Member Functions * * * * * * * * * * * * // + +namespace Foam +{ + defineTypeNameAndDebug(functionObjectCloud, 0); + addToRunTimeSelectionTable(pointData, functionObjectCloud, dictionary); +} + + +// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * // + +Foam::functionObjectCloud::functionObjectCloud +( + const runTimePostProcessing& parent, + const dictionary& dict, + const HashPtrTable<DataEntry<vector>, word>& colours +) +: + pointData(parent, dict, colours), + fieldVisualisationBase(parent, dict, colours), + cloudName_(dict.lookup("cloudName")), + functionObject_(dict.lookup("functionObject")), + colourFieldName_(dict.lookup("colourFieldName")), + actor_() +{ + actor_ = vtkSmartPointer<vtkActor>::New(); +} + + +// * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * // + +Foam::functionObjectCloud::~functionObjectCloud() +{} + + +// * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * * // + +void Foam::functionObjectCloud::addGeometryToScene +( + const scalar position, + vtkRenderer* renderer +) +{ + if (!visible_) + { + return; + } + + const dictionary& cloudDict = + geometryBase::parent_.obr().lookupObject<IOdictionary> + ( + cloudName_ + "OutputProperties" + ); + + fileName fName; + if (cloudDict.found("cloudFunctionObject")) + { + const dictionary& foDict = cloudDict.subDict("cloudFunctionObject"); + if (foDict.found(functionObject_)) + { + foDict.subDict(functionObject_).readIfPresent("file", fName); + } + } + + if (fName.empty()) + { + WarningIn + ( + "void Foam::functionObjectCloud::addToScene" + "(" + "const scalar, " + "vtkRenderer*" + ")" + ) + << "Unable to find function object " << functionObject_ + << " output for field " << fieldName_ + << ". Line will not be processed" + << endl; + return; + } + + if (fName.ext() == "vtk") + { + vtkSmartPointer<vtkPolyDataReader> points = + vtkSmartPointer<vtkPolyDataReader>::New(); + points->SetFileName(fName.c_str()); + points->Update(); + + vtkSmartPointer<vtkPolyDataMapper> mapper = + vtkSmartPointer<vtkPolyDataMapper>::New(); + + actor_->SetMapper(mapper); + + addGlyphs + ( + position, + fieldName_, + colourFieldName_, + maxGlyphLength_, + points->GetOutput(), + actor_, + renderer + ); + + renderer->AddActor(actor_); + } +} + + +void Foam::functionObjectCloud::updateActors(const scalar position) +{ + actor_->GetProperty()->SetOpacity(opacity(position)); + + vector pc = pointColour_->value(position); + actor_->GetProperty()->SetColor(pc[0], pc[1], pc[2]); +} + + +// ************************************************************************* // diff --git a/src/postProcessing/functionObjects/graphics/runTimePostProcessing/functionObjectCloud.H b/src/postProcessing/functionObjects/graphics/runTimePostProcessing/functionObjectCloud.H new file mode 100644 index 0000000000000000000000000000000000000000..553bf96f3af287d5406118343b245cf14530a685 --- /dev/null +++ b/src/postProcessing/functionObjects/graphics/runTimePostProcessing/functionObjectCloud.H @@ -0,0 +1,125 @@ +/*---------------------------------------------------------------------------*\ + ========= | + \\ / F ield | OpenFOAM: The Open Source CFD Toolbox + \\ / O peration | + \\ / A nd | Copyright (C) 2015 OpenFOAM Foundation + \\/ M anipulation | +------------------------------------------------------------------------------- +License + This file is part of OpenFOAM. + + OpenFOAM is free software: you can redistribute it and/or modify it + under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + OpenFOAM is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + for more details. + + You should have received a copy of the GNU General Public License + along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>. + +Class + Foam::functionObjectCloud + +Description + +SourceFiles + functionObjectCloud.C + +\*---------------------------------------------------------------------------*/ + +#ifndef functionObjectCloud_H +#define functionObjectCloud_H + +#include "pointData.H" +#include "fieldVisualisationBase.H" + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +namespace Foam +{ + +/*---------------------------------------------------------------------------*\ + Class functionObjectCloud Declaration +\*---------------------------------------------------------------------------*/ + +class functionObjectCloud +: + public pointData, + public fieldVisualisationBase +{ +private: + + // Private Member Functions + + //- Disallow default bitwise copy construct + functionObjectCloud(const functionObjectCloud&); + + //- Disallow default bitwise assignment + void operator=(const functionObjectCloud&); + + +protected: + + // Protected data + + //- Name of cloud + word cloudName_; + + //- Name of cloud function object result to render + word functionObject_; + + //- Name of field to colour by + word colourFieldName_; + + //- Actor + vtkSmartPointer<vtkActor> actor_; + + +public: + + //- Run-time type information + TypeName("functionObjectCloud"); + + + // Constructors + + //- Construct from dictionary + functionObjectCloud + ( + const runTimePostProcessing& parent, + const dictionary& dict, + const HashPtrTable<DataEntry<vector>, word>& colours + ); + + + //- Destructor + virtual ~functionObjectCloud(); + + + // Member Functions + + //- Add tube(s) to scene + virtual void addGeometryToScene + ( + const scalar position, + vtkRenderer* renderer + ); + + //- Update actors + virtual void updateActors(const scalar position); +}; + + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +} // End namespace Foam + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +#endif + +// ************************************************************************* // diff --git a/src/postProcessing/functionObjects/graphics/runTimePostProcessing/functionObjectLine.C b/src/postProcessing/functionObjects/graphics/runTimePostProcessing/functionObjectLine.C new file mode 100644 index 0000000000000000000000000000000000000000..0298da6fdca5b9abcf032a064f0c32d2478d2510 --- /dev/null +++ b/src/postProcessing/functionObjects/graphics/runTimePostProcessing/functionObjectLine.C @@ -0,0 +1,138 @@ +/*---------------------------------------------------------------------------*\ + ========= | + \\ / F ield | OpenFOAM: The Open Source CFD Toolbox + \\ / O peration | + \\ / A nd | Copyright (C) 2015 OpenFOAM Foundation + \\/ M anipulation | +------------------------------------------------------------------------------- +License + This file is part of OpenFOAM. + + OpenFOAM is free software: you can redistribute it and/or modify it + under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + OpenFOAM is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + for more details. + + You should have received a copy of the GNU General Public License + along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>. + +\*---------------------------------------------------------------------------*/ + +// OpenFOAM includes +#include "functionObjectLine.H" +#include "runTimePostProcessing.H" +#include "addToRunTimeSelectionTable.H" + +// VTK includes +#include "vtkActor.h" +#include "vtkRenderer.h" +#include "vtkSmartPointer.h" +#include "vtkPolyDataMapper.h" +#include "vtkPolyDataReader.h" +#include "vtkProperty.h" + +// * * * * * * * * * * * * * Static Member Functions * * * * * * * * * * * * // + +namespace Foam +{ + defineTypeNameAndDebug(functionObjectLine, 0); + addToRunTimeSelectionTable(pathline, functionObjectLine, dictionary); +} + + +// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * // + +Foam::functionObjectLine::functionObjectLine +( + const runTimePostProcessing& parent, + const dictionary& dict, + const HashPtrTable<DataEntry<vector>, word>& colours +) +: + pathline(parent, dict, colours), + fieldVisualisationBase(parent, dict, colours), + functionObject_(dict.lookup("functionObject")), + actor_() +{ + actor_ = vtkSmartPointer<vtkActor>::New(); +} + + +// * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * // + +Foam::functionObjectLine::~functionObjectLine() +{} + + +// * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * * // + +void Foam::functionObjectLine::addGeometryToScene +( + const scalar position, + vtkRenderer* renderer +) +{ + if (!visible_) + { + return; + } + + const dictionary dict = + geometryBase::parent_.getObjectProperty + ( + functionObject_, + fieldName_, + dictionary::null + ); + + fileName fName; + if (!dict.readIfPresent("file", fName)) + { + WarningIn + ( + "void Foam::functionObjectLine::addToScene" + "(" + "const scalar, " + "vtkRenderer*" + ")" + ) + << "Unable to find function object " << functionObject_ + << " output for field " << fieldName_ + << ". Line will not be processed" + << endl; + return; + } + + if (fName.ext() == "vtk") + { + vtkSmartPointer<vtkPolyDataReader> lines = + vtkSmartPointer<vtkPolyDataReader>::New(); + lines->SetFileName(fName.c_str()); + lines->Update(); + + vtkSmartPointer<vtkPolyDataMapper> mapper = + vtkSmartPointer<vtkPolyDataMapper>::New(); + setField(position, fieldName_, mapper, renderer); + + actor_->SetMapper(mapper); + + addLines(position, actor_, lines->GetOutput()); + + renderer->AddActor(actor_); + } +} + + +void Foam::functionObjectLine::updateActors(const scalar position) +{ + actor_->GetProperty()->SetLineWidth(2); + actor_->GetProperty()->SetOpacity(opacity(position)); +} + + +// ************************************************************************* // diff --git a/src/postProcessing/functionObjects/graphics/runTimePostProcessing/functionObjectLine.H b/src/postProcessing/functionObjects/graphics/runTimePostProcessing/functionObjectLine.H new file mode 100644 index 0000000000000000000000000000000000000000..9224d7246ade59a9ca07a9f78a156de2eca0dfa7 --- /dev/null +++ b/src/postProcessing/functionObjects/graphics/runTimePostProcessing/functionObjectLine.H @@ -0,0 +1,119 @@ +/*---------------------------------------------------------------------------*\ + ========= | + \\ / F ield | OpenFOAM: The Open Source CFD Toolbox + \\ / O peration | + \\ / A nd | Copyright (C) 2015 OpenFOAM Foundation + \\/ M anipulation | +------------------------------------------------------------------------------- +License + This file is part of OpenFOAM. + + OpenFOAM is free software: you can redistribute it and/or modify it + under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + OpenFOAM is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + for more details. + + You should have received a copy of the GNU General Public License + along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>. + +Class + Foam::functionObjectLine + +Description + +SourceFiles + functionObjectLine.C + +\*---------------------------------------------------------------------------*/ + +#ifndef functionObjectLine_H +#define functionObjectLine_H + +#include "pathline.H" +#include "fieldVisualisationBase.H" + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +namespace Foam +{ + +/*---------------------------------------------------------------------------*\ + Class functionObjectLine Declaration +\*---------------------------------------------------------------------------*/ + +class functionObjectLine +: + public pathline, + public fieldVisualisationBase +{ +private: + + // Private Member Functions + + //- Disallow default bitwise copy construct + functionObjectLine(const functionObjectLine&); + + //- Disallow default bitwise assignment + void operator=(const functionObjectLine&); + + +protected: + + // Protected data + + //- Name of function object result to render + word functionObject_; + + //- Actor + vtkSmartPointer<vtkActor> actor_; + + +public: + + //- Run-time type information + TypeName("line"); + + + // Constructors + + //- Construct from dictionary + functionObjectLine + ( + const runTimePostProcessing& parent, + const dictionary& dict, + const HashPtrTable<DataEntry<vector>, word>& colours + ); + + + //- Destructor + virtual ~functionObjectLine(); + + + // Member Functions + + //- Add tube(s) to scene + virtual void addGeometryToScene + ( + const scalar position, + vtkRenderer* renderer + ); + + //- Update actors + virtual void updateActors(const scalar position); +}; + + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +} // End namespace Foam + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +#endif + +// ************************************************************************* // diff --git a/src/postProcessing/functionObjects/graphics/runTimePostProcessing/functionObjectSurface.C b/src/postProcessing/functionObjects/graphics/runTimePostProcessing/functionObjectSurface.C new file mode 100644 index 0000000000000000000000000000000000000000..9139dcf90567e33daaff87ad2ceb4e11587a596f --- /dev/null +++ b/src/postProcessing/functionObjects/graphics/runTimePostProcessing/functionObjectSurface.C @@ -0,0 +1,163 @@ +/*---------------------------------------------------------------------------*\ + ========= | + \\ / F ield | OpenFOAM: The Open Source CFD Toolbox + \\ / O peration | + \\ / A nd | Copyright (C) 2015 OpenFOAM Foundation + \\/ M anipulation | +------------------------------------------------------------------------------- +License + This file is part of OpenFOAM. + + OpenFOAM is free software: you can redistribute it and/or modify it + under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + OpenFOAM is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + for more details. + + You should have received a copy of the GNU General Public License + along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>. + +\*---------------------------------------------------------------------------*/ + +// OpenFOAM includes +#include "functionObjectSurface.H" +#include "runTimePostProcessing.H" +#include "addToRunTimeSelectionTable.H" + +// VTK includes +#include "vtkActor.h" +#include "vtkPolyDataMapper.h" +#include "vtkPolyDataReader.h" +#include "vtkProperty.h" +#include "vtkRenderer.h" +#include "vtkSmartPointer.h" + +// * * * * * * * * * * * * * Static Member Functions * * * * * * * * * * * * // + +namespace Foam +{ + defineTypeNameAndDebug(functionObjectSurface, 0); + addToRunTimeSelectionTable(surface, functionObjectSurface, dictionary); +} + + +// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * // + +Foam::functionObjectSurface::functionObjectSurface +( + const runTimePostProcessing& parent, + const dictionary& dict, + const HashPtrTable<DataEntry<vector>, word>& colours +) +: + geometrySurface(parent, dict, colours, List<fileName>()), + fieldVisualisationBase(parent, dict, colours), + functionObject_("") +{ + if (visible_) + { + dict.lookup("functionObject") >> functionObject_; + } +} + + +// * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * // + +Foam::functionObjectSurface::~functionObjectSurface() +{} + + +// * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * * // + +void Foam::functionObjectSurface::addGeometryToScene +( + const scalar position, + vtkRenderer* renderer +) +{ + if (!visible_) + { + return; + } + + const dictionary dict = + geometryBase::parent_.getObjectProperty + ( + functionObject_, + fieldName_, + dictionary::null + ); + + fileName fName; + if (!dict.readIfPresent("file", fName)) + { + WarningIn + ( + "void Foam::functionObjectSurface::addToScene" + "(" + "const scalar, " + "vtkRenderer*" + ")" + ) + << "Unable to find function object " << functionObject_ + << " output for field " << fieldName_ + << ". Surface will not be processed" + << endl; + return; + } + + + if (representation_ == rtGlyph) + { + vtkSmartPointer<vtkPolyDataReader> surf = + vtkSmartPointer<vtkPolyDataReader>::New(); + surf->SetFileName(fName.c_str()); + surf->Update(); + + addGlyphs + ( + position, + fieldName_, + fieldName_, + maxGlyphLength_, + surf->GetOutput(), + surfaceActor_, + renderer + ); + } + else + { + if ((colourBy_ == cbField) && (fName.ext() == "vtk")) + { + vtkSmartPointer<vtkPolyDataReader> surf = + vtkSmartPointer<vtkPolyDataReader>::New(); + surf->SetFileName(fName.c_str()); + surf->Update(); + + addFeatureEdges(renderer, surf->GetOutput()); + + vtkSmartPointer<vtkPolyDataMapper> mapper = + vtkSmartPointer<vtkPolyDataMapper>::New(); + mapper->SetInputConnection(surf->GetOutputPort()); + + setField(position, fieldName_, mapper, renderer); + + surfaceActor_->SetMapper(mapper); + + setRepresentation(surfaceActor_); + + renderer->AddActor(surfaceActor_); + } + else + { + geometrySurface::addGeometryToScene(position, renderer); + } + } +} + + +// ************************************************************************* // diff --git a/src/postProcessing/functionObjects/graphics/runTimePostProcessing/functionObjectSurface.H b/src/postProcessing/functionObjects/graphics/runTimePostProcessing/functionObjectSurface.H new file mode 100644 index 0000000000000000000000000000000000000000..32f4a7572c63c666b60c782a4ae32cfe520f9439 --- /dev/null +++ b/src/postProcessing/functionObjects/graphics/runTimePostProcessing/functionObjectSurface.H @@ -0,0 +1,115 @@ +/*---------------------------------------------------------------------------*\ + ========= | + \\ / F ield | OpenFOAM: The Open Source CFD Toolbox + \\ / O peration | + \\ / A nd | Copyright (C) 2015 OpenFOAM Foundation + \\/ M anipulation | +------------------------------------------------------------------------------- +License + This file is part of OpenFOAM. + + OpenFOAM is free software: you can redistribute it and/or modify it + under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + OpenFOAM is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + for more details. + + You should have received a copy of the GNU General Public License + along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>. + +Class + Foam::functionObjectSurface + +Description + +SourceFiles + functionObjectSurface.C + +\*---------------------------------------------------------------------------*/ + +#ifndef functionObjectSurface_H +#define functionObjectSurface_H + +#include "geometrySurface.H" +#include "fieldVisualisationBase.H" + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +namespace Foam +{ + +/*---------------------------------------------------------------------------*\ + Class functionObjectSurface Declaration +\*---------------------------------------------------------------------------*/ + +class functionObjectSurface +: + public geometrySurface, + public fieldVisualisationBase +{ + + +private: + + // Private Member Functions + + //- Disallow default bitwise copy construct + functionObjectSurface(const functionObjectSurface&); + + //- Disallow default bitwise assignment + void operator=(const functionObjectSurface&); + + +protected: + + // Protected data + + //- Name of function object result to render + word functionObject_; + + +public: + + //- Run-time type information + TypeName("functionObject"); + + + // Constructors + + //- Construct from dictionary + functionObjectSurface + ( + const runTimePostProcessing& parent, + const dictionary& dict, + const HashPtrTable<DataEntry<vector>, word>& colours + ); + + + //- Destructor + virtual ~functionObjectSurface(); + + + // Member Functions + + //- Add surface(s) to scene + virtual void addGeometryToScene + ( + const scalar position, + vtkRenderer* renderer + ); +}; + + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +} // End namespace Foam + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +#endif + +// ************************************************************************* // diff --git a/src/postProcessing/functionObjects/graphics/runTimePostProcessing/geometryBase.C b/src/postProcessing/functionObjects/graphics/runTimePostProcessing/geometryBase.C new file mode 100644 index 0000000000000000000000000000000000000000..a40bd6b9fe365d825b110ffece4f67379bac13a6 --- /dev/null +++ b/src/postProcessing/functionObjects/graphics/runTimePostProcessing/geometryBase.C @@ -0,0 +1,149 @@ +/*---------------------------------------------------------------------------*\ + ========= | + \\ / F ield | OpenFOAM: The Open Source CFD Toolbox + \\ / O peration | + \\ / A nd | Copyright (C) 2015 OpenFOAM Foundation + \\/ M anipulation | +------------------------------------------------------------------------------- +License + This file is part of OpenFOAM. + + OpenFOAM is free software: you can redistribute it and/or modify it + under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + OpenFOAM is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + for more details. + + You should have received a copy of the GNU General Public License + along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>. + +\*---------------------------------------------------------------------------*/ + +#include "geometryBase.H" +#include "runTimePostProcessing.H" +#include "Constant.H" + +#include "vtkActor.h" +#include "vtkProperty.h" + +// * * * * * * * * * * * * * Static Member Functions * * * * * * * * * * * * // + +namespace Foam +{ + template<> + const char* NamedEnum<geometryBase::renderModeType, 3>::names[] = + { + "flat", + "gouraud", + "phong" + }; +} + +const Foam::NamedEnum<Foam::geometryBase::renderModeType, 3> + Foam::geometryBase::renderModeTypeNames; + + +// * * * * * * * * * * * * Protected Member Functions * * * * * * * * * * * // + +void Foam::geometryBase::initialiseActor(vtkActor* actor) const +{ + actor->GetProperty()->SetSpecular(0); + actor->GetProperty()->SetSpecularPower(20); + + switch (renderMode_) + { + case rmFlat: + { + actor->GetProperty()->SetInterpolationToFlat(); + break; + } + case rmGouraud: + { + actor->GetProperty()->SetInterpolationToGouraud(); + break; + } + case rmPhong: + { + actor->GetProperty()->SetInterpolationToPhong(); + break; + } + } +} + + +// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * // + +Foam::geometryBase::geometryBase +( + const runTimePostProcessing& parent, + const dictionary& dict, + const HashPtrTable<DataEntry<vector>, word>& colours +) +: + parent_(parent), + name_(dict.dictName()), + visible_(readBool(dict.lookup("visible"))), + renderMode_(rmGouraud), + opacity_(NULL), + colours_(colours) +{ + if (dict.found("renderMode")) + { + renderMode_ = renderModeTypeNames.read(dict.lookup("renderMode")); + } + + if (dict.found("opacity")) + { + opacity_.reset(DataEntry<scalar>::New("opacity", dict).ptr()); + } + else + { + opacity_.reset(new Constant<scalar>("opacity", 1.0)); + } +} + + +// * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * // + +Foam::geometryBase::~geometryBase() +{} + + +// * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * * // + +const Foam::runTimePostProcessing& Foam::geometryBase::parent() const +{ + return parent_; +} + + +const Foam::word& Foam::geometryBase::name() const +{ + return name_; +} + + +bool Foam::geometryBase::visible() const +{ + return visible_; +} + + +Foam::scalar Foam::geometryBase::opacity(const scalar position) const +{ + return opacity_->value(position); +} + + +const Foam::HashPtrTable<Foam::DataEntry<Foam::vector>, Foam::word>& +Foam::geometryBase::colours() const +{ + return colours_; +} + + +// ************************************************************************* // diff --git a/src/postProcessing/functionObjects/graphics/runTimePostProcessing/geometryBase.H b/src/postProcessing/functionObjects/graphics/runTimePostProcessing/geometryBase.H new file mode 100644 index 0000000000000000000000000000000000000000..ee6afe332a4eb284a9eabf805f6c99c77c60c293 --- /dev/null +++ b/src/postProcessing/functionObjects/graphics/runTimePostProcessing/geometryBase.H @@ -0,0 +1,171 @@ +/*---------------------------------------------------------------------------*\ + ========= | + \\ / F ield | OpenFOAM: The Open Source CFD Toolbox + \\ / O peration | + \\ / A nd | Copyright (C) 2015 OpenFOAM Foundation + \\/ M anipulation | +------------------------------------------------------------------------------- +License + This file is part of OpenFOAM. + + OpenFOAM is free software: you can redistribute it and/or modify it + under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + OpenFOAM is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + for more details. + + You should have received a copy of the GNU General Public License + along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>. + +Class + Foam::geometryBase + +Description + +SourceFiles + geometryBase.C + +\*---------------------------------------------------------------------------*/ + +#ifndef geometryBase_H +#define geometryBase_H + +#include "dictionary.H" +#include "vector.H" +#include "DataEntry.H" +#include "HashPtrTable.H" +#include "NamedEnum.H" + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +class vtkRenderer; +class vtkActor; + +namespace Foam +{ + +class runTimePostProcessing; + +/*---------------------------------------------------------------------------*\ + Class geometryBase Declaration +\*---------------------------------------------------------------------------*/ + +class geometryBase +{ + +public: + + // Public enumerations + + enum renderModeType + { + rmFlat, + rmGouraud, + rmPhong + }; + + static const NamedEnum<renderModeType, 3> renderModeTypeNames; + + +private: + + // Private Member Functions + + //- Disallow default bitwise copy construct + geometryBase(const geometryBase&); + + //- Disallow default bitwise assignment + void operator=(const geometryBase&); + + +protected: + + // Protected data + + //- Reference to the parent function object + const runTimePostProcessing& parent_; + + //- Name + word name_; + + //- Visible flag + bool visible_; + + //- Render mode + renderModeType renderMode_; + + //- Opacity + autoPtr<DataEntry<scalar> > opacity_; + + //- Reference to the colours + const HashPtrTable<DataEntry<vector>, word>& colours_; + + + // Protected functions + + //- Initialse actor + void initialiseActor(vtkActor* actor) const; + + +public: + + // Constructors + + //- Construct from dictionary + geometryBase + ( + const runTimePostProcessing& parent_, + const dictionary& dict, + const HashPtrTable<DataEntry<vector>, word>& colours + ); + + + //- Destructor + virtual ~geometryBase(); + + + // Member Functions + + // Access + + //- Return the reference to the parent function object + const runTimePostProcessing& parent() const; + + //- Return the name + const word& name() const; + + //- Return the visible flag + bool visible() const; + + //- Return the opacity + scalar opacity(const scalar position) const; + + //- Return reference to the colours + const HashPtrTable<DataEntry<vector>, word>& colours() const; + + + //- Add geometry to scene + virtual void addGeometryToScene + ( + const scalar position, + vtkRenderer* renderer + ) = 0; + + //- Update the actors + virtual void updateActors(const scalar position) = 0; +}; + + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +} // End namespace Foam + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +#endif + +// ************************************************************************* // diff --git a/src/postProcessing/functionObjects/graphics/runTimePostProcessing/geometrySurface.C b/src/postProcessing/functionObjects/graphics/runTimePostProcessing/geometrySurface.C new file mode 100644 index 0000000000000000000000000000000000000000..49a3964c68ce0256560e74881fe23ee403feecaa --- /dev/null +++ b/src/postProcessing/functionObjects/graphics/runTimePostProcessing/geometrySurface.C @@ -0,0 +1,214 @@ +/*---------------------------------------------------------------------------*\ + ========= | + \\ / F ield | OpenFOAM: The Open Source CFD Toolbox + \\ / O peration | + \\ / A nd | Copyright (C) 2015 OpenFOAM Foundation + \\/ M anipulation | +------------------------------------------------------------------------------- +License + This file is part of OpenFOAM. + + OpenFOAM is free software: you can redistribute it and/or modify it + under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + OpenFOAM is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + for more details. + + You should have received a copy of the GNU General Public License + along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>. + +\*---------------------------------------------------------------------------*/ + +// OpenFOAM includes +#include "geometrySurface.H" +#include "stringOps.H" +#include "triSurface.H" +#include "runTimePostProcessing.H" +#include "addToRunTimeSelectionTable.H" + +// VTK includes +#include "vtkActor.h" +#include "vtkCellArray.h" +#include "vtkCellData.h" +#include "vtkDoubleArray.h" +#include "vtkPointData.h" +#include "vtkPoints.h" +#include "vtkPolyData.h" +#include "vtkPolyDataMapper.h" +#include "vtkProperty.h" +#include "vtkRenderer.h" +#include "vtkSmartPointer.h" +#include "vtkTriangle.h" + +// * * * * * * * * * * * * * Static Member Functions * * * * * * * * * * * * // + +namespace Foam +{ + defineTypeNameAndDebug(geometrySurface, 0); + addToRunTimeSelectionTable(surface, geometrySurface, dictionary); +} + + +// * * * * * * * * * * * * Protected Member Functions * * * * * * * * * * * // + +void Foam::geometrySurface::addGeometryToScene +( + const scalar position, + vtkRenderer* renderer, + const fileName& fName +) const +{ + if (representation_ == rtGlyph) + { + FatalErrorIn + ( + "void Foam::geometrySurface::addGeometryToScene" + "(" + "const label, " + "vtkRenderer*, " + "const fileName&" + ") const" + ) + << "Glyph representation not available for " << typeName + << "object" << exit(FatalError); + } + + triSurface surf(fName); + + const Field<point>& surfPoints = surf.points(); + const Field<vector>& surfFaceNormals = surf.faceNormals(); + + vtkSmartPointer<vtkPoints> points = vtkSmartPointer<vtkPoints>::New(); + vtkSmartPointer<vtkCellArray> triangles = + vtkSmartPointer<vtkCellArray>::New(); + vtkSmartPointer<vtkDoubleArray> faceNormals = + vtkSmartPointer<vtkDoubleArray>::New(); + + faceNormals->SetNumberOfComponents(3); + + forAll(surfPoints, i) + { + const point& pt = surfPoints[i]; + points->InsertNextPoint(pt.x(), pt.y(), pt.z()); + } + + forAll(surf, i) + { + const Foam::face& f = surf[i]; + + vtkSmartPointer<vtkTriangle> triangle = + vtkSmartPointer<vtkTriangle>::New(); + triangle->GetPointIds()->SetId(0, f[0]); + triangle->GetPointIds()->SetId(1, f[1]); + triangle->GetPointIds()->SetId(2, f[2]); + triangles->InsertNextCell(triangle); + + double n[3]; + n[0] = surfFaceNormals[i].x(); + n[1] = surfFaceNormals[i].y(); + n[2] = surfFaceNormals[i].z(); + + faceNormals->InsertNextTuple(n); + } + + surf.clearOut(); + + vtkSmartPointer<vtkPolyData> polyData = + vtkSmartPointer<vtkPolyData>::New(); + polyData->SetPoints(points); + polyData->SetPolys(triangles); + polyData->GetCellData()->SetNormals(faceNormals); + + vtkSmartPointer<vtkPolyDataMapper> mapper = + vtkSmartPointer<vtkPolyDataMapper>::New(); + mapper->ScalarVisibilityOff(); + mapper->SetInputData(polyData); + + addFeatureEdges(renderer, polyData); + + surfaceActor_->SetMapper(mapper); + + setRepresentation(surfaceActor_); + + renderer->AddActor(surfaceActor_); +} + + +// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * // + +Foam::geometrySurface::geometrySurface +( + const runTimePostProcessing& parent, + const dictionary& dict, + const HashPtrTable<DataEntry<vector>, word>& colours +) +: + surface(parent, dict, colours), + fileNames_(dict.lookup("files")) +{} + + +Foam::geometrySurface::geometrySurface +( + const runTimePostProcessing& parent, + const dictionary& dict, + const HashPtrTable<DataEntry<vector>, word>& colours, + const List<fileName>& fileNames +) +: + surface(parent, dict, colours), + fileNames_(fileNames) +{} + + +// * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * // + +Foam::geometrySurface::~geometrySurface() +{} + + +// * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * * // + +void Foam::geometrySurface::addGeometryToScene +( + const scalar position, + vtkRenderer* renderer +) +{ + if (!visible_) + { + return; + } + + forAll(fileNames_, i) + { + fileName fName = fileNames_[i].expand(); + addGeometryToScene(position, renderer, fName); + } +} + + +void Foam::geometrySurface::updateActors(const scalar position) +{ + if (!visible_) + { + return; + } + + surface::updateActors(position); + + surfaceActor_->GetProperty()->SetOpacity(opacity(position)); + + vector sc = surfaceColour_->value(position); + surfaceActor_->GetProperty()->SetColor(sc[0], sc[1], sc[2]); + + vector ec = edgeColour_->value(position); + surfaceActor_->GetProperty()->SetEdgeColor(ec[0], ec[1], ec[2]); +} + + +// ************************************************************************* // diff --git a/src/postProcessing/functionObjects/graphics/runTimePostProcessing/geometrySurface.H b/src/postProcessing/functionObjects/graphics/runTimePostProcessing/geometrySurface.H new file mode 100644 index 0000000000000000000000000000000000000000..5eec3ee8d67d79183053dee1b8e4b22f070edee1 --- /dev/null +++ b/src/postProcessing/functionObjects/graphics/runTimePostProcessing/geometrySurface.H @@ -0,0 +1,136 @@ +/*---------------------------------------------------------------------------*\ + ========= | + \\ / F ield | OpenFOAM: The Open Source CFD Toolbox + \\ / O peration | + \\ / A nd | Copyright (C) 2015 OpenFOAM Foundation + \\/ M anipulation | +------------------------------------------------------------------------------- +License + This file is part of OpenFOAM. + + OpenFOAM is free software: you can redistribute it and/or modify it + under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + OpenFOAM is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + for more details. + + You should have received a copy of the GNU General Public License + along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>. + +Class + Foam::geometrySurface + +Description + +SourceFiles + geometrySurface.C + +\*---------------------------------------------------------------------------*/ + +#ifndef geometrySurface_H +#define geometrySurface_H + +#include "surface.H" + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +class vtkPolyData; + +namespace Foam +{ + +/*---------------------------------------------------------------------------*\ + Class geometrySurface Declaration +\*---------------------------------------------------------------------------*/ + +class geometrySurface +: + public surface +{ +private: + + // Private Member Functions + + //- Disallow default bitwise copy construct + geometrySurface(const geometrySurface&); + + //- Disallow default bitwise assignment + void operator=(const geometrySurface&); + + +protected: + + // Protected data + + //- File names + List<fileName> fileNames_; + + + // Protected Member Functions + + //- Add surface (file) to scene + void addGeometryToScene + ( + const scalar position, + vtkRenderer* renderer, + const fileName& fName + ) const; + + +public: + + //- Run-time type information + TypeName("geometry"); + + + // Constructors + + //- Construct from dictionary + geometrySurface + ( + const runTimePostProcessing& parent, + const dictionary& dict, + const HashPtrTable<DataEntry<vector>, word>& colours + ); + + //- Construct from components + geometrySurface + ( + const runTimePostProcessing& parent, + const dictionary& dict, + const HashPtrTable<DataEntry<vector>, word>& colours, + const List<fileName>& fileNames + ); + + + //- Destructor + virtual ~geometrySurface(); + + + // Member Functions + + //- Add surface(s) to scene + virtual void addGeometryToScene + ( + const scalar position, + vtkRenderer* renderer + ); + + //- Update actors + virtual void updateActors(const scalar position); +}; + + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +} // End namespace Foam + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +#endif + +// ************************************************************************* // diff --git a/src/postProcessing/functionObjects/graphics/runTimePostProcessing/pathline.C b/src/postProcessing/functionObjects/graphics/runTimePostProcessing/pathline.C new file mode 100644 index 0000000000000000000000000000000000000000..925baae2cdd4210240df5cc4234c731f8c986843 --- /dev/null +++ b/src/postProcessing/functionObjects/graphics/runTimePostProcessing/pathline.C @@ -0,0 +1,211 @@ +/*---------------------------------------------------------------------------*\ + ========= | + \\ / F ield | OpenFOAM: The Open Source CFD Toolbox + \\ / O peration | + \\ / A nd | Copyright (C) 2015 OpenFOAM Foundation + \\/ M anipulation | +------------------------------------------------------------------------------- +License + This file is part of OpenFOAM. + + OpenFOAM is free software: you can redistribute it and/or modify it + under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + OpenFOAM is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + for more details. + + You should have received a copy of the GNU General Public License + along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>. + +\*---------------------------------------------------------------------------*/ + +// OpenFOAM includes +#include "pathline.H" +#include "runTimePostProcessing.H" + +// VTK includes +#include "vtkActor.h" +#include "vtkPolyDataMapper.h" +#include "vtkProperty.h" +#include "vtkRenderer.h" +#include "vtkSmartPointer.h" +#include "vtkTubeFilter.h" +#include "vtkLookupTable.h" + +// * * * * * * * * * * * * * Static Member Functions * * * * * * * * * * * * // + +namespace Foam +{ + template<> + const char* NamedEnum<pathline::representationType, 4>::names[] = + { + "none", + "line", + "tube", + "vector" + }; + + defineTypeNameAndDebug(pathline, 0); + defineRunTimeSelectionTable(pathline, dictionary); +} + +const Foam::NamedEnum<Foam::pathline::representationType, 4> + Foam::pathline::representationTypeNames; + + +// * * * * * * * * * * * * Protected Member Functions * * * * * * * * * * * // + +void Foam::pathline::addLines +( + const label frameI, + vtkActor* actor, + vtkPolyData* data +) const +{ + geometryBase::initialiseActor(actor); + + vector colour = lineColour_->value(frameI); + actor->GetProperty()->SetColor(colour[0], colour[1], colour[2]); + + vtkPolyDataMapper* mapper = + vtkPolyDataMapper::SafeDownCast(actor->GetMapper()); + + switch (representation_) + { + case rtNone: + { + actor->VisibilityOff(); + break; + } + case rtLine: + { + mapper->SetInputData(data); + mapper->Update(); + break; + + } + case rtTube: + { + vtkSmartPointer<vtkTubeFilter> tubes = + vtkSmartPointer<vtkTubeFilter>::New(); + tubes->SetInputData(data); + tubes->SetRadius(tubeRadius_); + tubes->SetNumberOfSides(20); + tubes->CappingOn(); + tubes->Update(); + + mapper->SetInputConnection(tubes->GetOutputPort()); + mapper->Update(); + + break; + + } + case rtVector: + { + break; + } + } +} + + +// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * // + +Foam::pathline::pathline +( + const runTimePostProcessing& parent, + const dictionary& dict, + const HashPtrTable<DataEntry<vector>, word>& colours +) +: + geometryBase(parent, dict, colours), + representation_ + ( + representationTypeNames.read(dict.lookup("representation")) + ), + tubeRadius_(0.0), + lineColour_(NULL) +{ + if (dict.found("lineColour")) + { + lineColour_.reset(DataEntry<vector>::New("lineColour", dict).ptr()); + } + else + { + lineColour_.reset(colours["line"]->clone().ptr()); + } + + switch (representation_) + { + case rtNone: + { + break; + } + case rtLine: + { + break; + } + case rtTube: + { + dict.lookup("tubeRadius") >> tubeRadius_; + break; + } + case rtVector: + { + break; + } + } + +} + + +// * * * * * * * * * * * * * * * * Selectors * * * * * * * * * * * * * * * * // + +Foam::autoPtr<Foam::pathline> Foam::pathline::New +( + const runTimePostProcessing& parent, + const dictionary& dict, + const HashPtrTable<DataEntry<vector>, word>& colours, + const word& pathlineType +) +{ + if (debug) + { + Info<< "Selecting pathline " << pathlineType << endl; + } + + dictionaryConstructorTable::iterator cstrIter = + dictionaryConstructorTablePtr_->find(pathlineType); + + if (cstrIter == dictionaryConstructorTablePtr_->end()) + { + FatalErrorIn + ( + "Foam::autoPtr<Foam::pathline> Foam::pathline::New" + "(" + "const runTimePostProcessing&, " + "const dictionary&, " + "const HashPtrTable<DataEntry<vector>, word>&, " + "const word&" + ")" + ) << "Unknown pathline type " + << pathlineType << nl << nl + << "Valid pathline types are:" << endl + << dictionaryConstructorTablePtr_->sortedToc() + << exit(FatalError); + } + + return autoPtr<pathline>(cstrIter()(parent, dict, colours)); +} + + +// * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * // + +Foam::pathline::~pathline() +{} + + +// ************************************************************************* // diff --git a/src/postProcessing/functionObjects/graphics/runTimePostProcessing/pathline.H b/src/postProcessing/functionObjects/graphics/runTimePostProcessing/pathline.H new file mode 100644 index 0000000000000000000000000000000000000000..0813210117a5cf8ded72ff4891c52bb1d28e99b7 --- /dev/null +++ b/src/postProcessing/functionObjects/graphics/runTimePostProcessing/pathline.H @@ -0,0 +1,167 @@ +/*---------------------------------------------------------------------------*\ + ========= | + \\ / F ield | OpenFOAM: The Open Source CFD Toolbox + \\ / O peration | + \\ / A nd | Copyright (C) 2015 OpenFOAM Foundation + \\/ M anipulation | +------------------------------------------------------------------------------- +License + This file is part of OpenFOAM. + + OpenFOAM is free software: you can redistribute it and/or modify it + under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + OpenFOAM is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + for more details. + + You should have received a copy of the GNU General Public License + along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>. + +Class + Foam::pathline + +Description + +SourceFiles + pathline.C + +\*---------------------------------------------------------------------------*/ + +#ifndef pathline_H +#define pathline_H + +#include "geometryBase.H" +#include "NamedEnum.H" +#include "runTimeSelectionTables.H" + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +class vtkActor; +class vtkPolyData; +class vtkPolyDataMapper; + +namespace Foam +{ + +/*---------------------------------------------------------------------------*\ + Class pathline Declaration +\*---------------------------------------------------------------------------*/ + +class pathline +: + public geometryBase +{ +public: + + // Public enumerations + + enum representationType + { + rtNone, + rtLine, + rtTube, + rtVector + }; + + static const NamedEnum<representationType, 4> representationTypeNames; + + +private: + + // Private Member Functions + + //- Disallow default bitwise copy construct + pathline(const pathline&); + + //- Disallow default bitwise assignment + void operator=(const pathline&); + + +protected: + + // Protected data + + //- Representation type + representationType representation_; + + //- Radius for the tube filter + scalar tubeRadius_; + + //- Line colour + autoPtr<DataEntry<vector> > lineColour_; + + + // Protected Member Functions + + //- Add the pathlines to the renderer + void addLines + ( + const label frameI, + vtkActor* actor, + vtkPolyData* data + ) const; + + +public: + + //- Run-time type information + TypeName("pathline"); + + + // Declare run-time constructor selection table + + declareRunTimeSelectionTable + ( + autoPtr, + pathline, + dictionary, + ( + const runTimePostProcessing& parent, + const dictionary& dict, + const HashPtrTable<DataEntry<vector>, word>& colours + ), + (parent, dict, colours) + ); + + + // Constructors + + //- Construct from dictionary + pathline + ( + const runTimePostProcessing& parent, + const dictionary& dict, + const HashPtrTable<DataEntry<vector>, word>& colours + ); + + + // Selectors + + //- Return a reference to the selected RAS model + static autoPtr<pathline> New + ( + const runTimePostProcessing& parent, + const dictionary& dict, + const HashPtrTable<DataEntry<vector>, word>& colours, + const word& pathlineName + ); + + + //- Destructor + virtual ~pathline(); +}; + + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +} // End namespace Foam + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +#endif + +// ************************************************************************* // diff --git a/src/postProcessing/functionObjects/graphics/runTimePostProcessing/pointData.C b/src/postProcessing/functionObjects/graphics/runTimePostProcessing/pointData.C new file mode 100644 index 0000000000000000000000000000000000000000..f85686325c064819c728babd14999cba3582145b --- /dev/null +++ b/src/postProcessing/functionObjects/graphics/runTimePostProcessing/pointData.C @@ -0,0 +1,171 @@ +/*---------------------------------------------------------------------------*\ + ========= | + \\ / F ield | OpenFOAM: The Open Source CFD Toolbox + \\ / O peration | + \\ / A nd | Copyright (C) 2015 OpenFOAM Foundation + \\/ M anipulation | +------------------------------------------------------------------------------- +License + This file is part of OpenFOAM. + + OpenFOAM is free software: you can redistribute it and/or modify it + under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + OpenFOAM is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + for more details. + + You should have received a copy of the GNU General Public License + along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>. + +\*---------------------------------------------------------------------------*/ + +// OpenFOAM includes +#include "pointData.H" +#include "runTimePostProcessing.H" + +// VTK includes +#include "vtkActor.h" +#include "vtkPolyDataMapper.h" +#include "vtkProperty.h" +#include "vtkRenderer.h" +#include "vtkSmartPointer.h" +#include "vtkTubeFilter.h" +#include "vtkLookupTable.h" + +// * * * * * * * * * * * * * Static Member Functions * * * * * * * * * * * * // + +namespace Foam +{ + template<> + const char* NamedEnum<pointData::representationType, 2>::names[] = + { + "sphere", + "vector" + }; + + defineTypeNameAndDebug(pointData, 0); + defineRunTimeSelectionTable(pointData, dictionary); +} + +const Foam::NamedEnum<Foam::pointData::representationType, 2> + Foam::pointData::representationTypeNames; + + +// * * * * * * * * * * * * Protected Member Functions * * * * * * * * * * * // + +void Foam::pointData::addPoints +( + const label frameI, + vtkActor* actor, + vtkPolyDataMapper* mapper, + vtkPolyData* data +) const +{ + geometryBase::initialiseActor(actor); + + vector colour = pointColour_->value(frameI); + actor->GetProperty()->SetColor(colour[0], colour[1], colour[2]); + + switch (representation_) + { + case rtSphere: + case rtVector: + { + break; + } + } +} + + +// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * // + +Foam::pointData::pointData +( + const runTimePostProcessing& parent, + const dictionary& dict, + const HashPtrTable<DataEntry<vector>, word>& colours +) +: + geometryBase(parent, dict, colours), + representation_ + ( + representationTypeNames.read(dict.lookup("representation")) + ), + maxGlyphLength_(readScalar(dict.lookup("maxGlyphLength"))), + pointColour_(NULL) +{ + if (dict.found("pointColour")) + { + pointColour_.reset(DataEntry<vector>::New("pointColour", dict).ptr()); + } + else + { + pointColour_.reset(colours["point"]->clone().ptr()); + } + + switch (representation_) + { + case rtSphere: + { + break; + } + case rtVector: + { + break; + } + } + +} + + +// * * * * * * * * * * * * * * * * Selectors * * * * * * * * * * * * * * * * // + +Foam::autoPtr<Foam::pointData> Foam::pointData::New +( + const runTimePostProcessing& parent, + const dictionary& dict, + const HashPtrTable<DataEntry<vector>, word>& colours, + const word& pointDataType +) +{ + if (debug) + { + Info<< "Selecting pointData " << pointDataType << endl; + } + + dictionaryConstructorTable::iterator cstrIter = + dictionaryConstructorTablePtr_->find(pointDataType); + + if (cstrIter == dictionaryConstructorTablePtr_->end()) + { + FatalErrorIn + ( + "Foam::autoPtr<Foam::pointData> Foam::pointData::New" + "(" + "const runTimePostProcessing&, " + "const dictionary&, " + "const HashPtrTable<DataEntry<vector>, word>&, " + "const word&" + ")" + ) << "Unknown pointData type " + << pointDataType << nl << nl + << "Valid pointData types are:" << endl + << dictionaryConstructorTablePtr_->sortedToc() + << exit(FatalError); + } + + return autoPtr<pointData>(cstrIter()(parent, dict, colours)); +} + + +// * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * // + +Foam::pointData::~pointData() +{} + + +// ************************************************************************* // diff --git a/src/postProcessing/functionObjects/graphics/runTimePostProcessing/pointData.H b/src/postProcessing/functionObjects/graphics/runTimePostProcessing/pointData.H new file mode 100644 index 0000000000000000000000000000000000000000..068ee78fc0cb89e39c492ce89da28ba92a880de4 --- /dev/null +++ b/src/postProcessing/functionObjects/graphics/runTimePostProcessing/pointData.H @@ -0,0 +1,166 @@ +/*---------------------------------------------------------------------------*\ + ========= | + \\ / F ield | OpenFOAM: The Open Source CFD Toolbox + \\ / O peration | + \\ / A nd | Copyright (C) 2015 OpenFOAM Foundation + \\/ M anipulation | +------------------------------------------------------------------------------- +License + This file is part of OpenFOAM. + + OpenFOAM is free software: you can redistribute it and/or modify it + under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + OpenFOAM is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + for more details. + + You should have received a copy of the GNU General Public License + along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>. + +Class + Foam::pointData + +Description + +SourceFiles + pointData.C + +\*---------------------------------------------------------------------------*/ + +#ifndef pointData_H +#define pointData_H + +#include "geometryBase.H" +#include "NamedEnum.H" +#include "runTimeSelectionTables.H" + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +class vtkActor; +class vtkPolyData; +class vtkPolyDataMapper; + +namespace Foam +{ + +/*---------------------------------------------------------------------------*\ + Class pointData Declaration +\*---------------------------------------------------------------------------*/ + +class pointData +: + public geometryBase +{ +public: + + // Public enumerations + + enum representationType + { + rtSphere, + rtVector + }; + + static const NamedEnum<representationType, 2> representationTypeNames; + + +private: + + // Private Member Functions + + //- Disallow default bitwise copy construct + pointData(const pointData&); + + //- Disallow default bitwise assignment + void operator=(const pointData&); + + +protected: + + // Protected data + + //- Representation type + representationType representation_; + + //- Max glyph length + scalar maxGlyphLength_; + + //- Point colour + autoPtr<DataEntry<vector> > pointColour_; + + + // Protected Member Functions + + //- Add the point data to the renderer + void addPoints + ( + const label frameI, + vtkActor* actor, + vtkPolyDataMapper* mapper, + vtkPolyData* data + ) const; + + +public: + + //- Run-time type information + TypeName("pointData"); + + + // Declare run-time constructor selection table + + declareRunTimeSelectionTable + ( + autoPtr, + pointData, + dictionary, + ( + const runTimePostProcessing& parent, + const dictionary& dict, + const HashPtrTable<DataEntry<vector>, word>& colours + ), + (parent, dict, colours) + ); + + + // Constructors + + //- Construct from dictionary + pointData + ( + const runTimePostProcessing& parent, + const dictionary& dict, + const HashPtrTable<DataEntry<vector>, word>& colours + ); + + + // Selectors + + //- Return a reference to the selected RAS model + static autoPtr<pointData> New + ( + const runTimePostProcessing& parent, + const dictionary& dict, + const HashPtrTable<DataEntry<vector>, word>& colours, + const word& pointDataName + ); + + + //- Destructor + virtual ~pointData(); +}; + + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +} // End namespace Foam + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +#endif + +// ************************************************************************* // diff --git a/src/postProcessing/functionObjects/graphics/runTimePostProcessing/runTimePostProcessing.C b/src/postProcessing/functionObjects/graphics/runTimePostProcessing/runTimePostProcessing.C new file mode 100644 index 0000000000000000000000000000000000000000..dea4fca5fe8dc6cfaafb8255ebdd054223b33369 --- /dev/null +++ b/src/postProcessing/functionObjects/graphics/runTimePostProcessing/runTimePostProcessing.C @@ -0,0 +1,210 @@ +/*---------------------------------------------------------------------------*\ + ========= | + \\ / F ield | OpenFOAM: The Open Source CFD Toolbox + \\ / O peration | + \\ / A nd | Copyright (C) 2015 OpenFOAM Foundation + \\/ M anipulation | +------------------------------------------------------------------------------- +License + This file is part of OpenFOAM. + + OpenFOAM is free software: you can redistribute it and/or modify it + under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + OpenFOAM is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + for more details. + + You should have received a copy of the GNU General Public License + along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>. + +\*---------------------------------------------------------------------------*/ + +// OpenFOAM includes +#include "runTimePostProcessing.H" +#include "dictionary.H" +#include "pointData.H" +#include "pathline.H" +#include "surface.H" +#include "text.H" +#include "Time.H" + +// VTK includes +#include "vtkPolyDataMapper.h" +#include "vtkRenderer.h" +#include "vtkRenderWindow.h" +#include "vtkSmartPointer.h" + +#include "vtkLight.h" + +// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * // + +namespace Foam +{ + defineTypeNameAndDebug(runTimePostProcessing, 0); +} + + +// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * // + +Foam::runTimePostProcessing::runTimePostProcessing +( + const word& name, + const objectRegistry& obr, + const dictionary& dict, + const bool loadFromFiles +) +: + functionObjectState(obr, name), + scene_(obr, name), + points_(), + lines_(), + surfaces_(), + text_(), + obr_(obr), + active_(true) +{ + read(dict); +} + + +// * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * // + +Foam::runTimePostProcessing::~runTimePostProcessing() +{} + + +// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * // + +void Foam::runTimePostProcessing::read(const dictionary& dict) +{ + Info<< type() << " " << name_ << ": reading post-processing data" << endl; + + scene_.read(dict); + + const dictionary& outputDict = dict.subDict("output"); + outputDict.lookup("name") >> output_.name_; + outputDict.lookup("width") >> output_.width_; + outputDict.lookup("height") >> output_.height_; + + + readObjects(dict.subOrEmptyDict("points"), points_); + readObjects(dict.subOrEmptyDict("lines"), lines_); + readObjects(dict.subOrEmptyDict("surfaces"), surfaces_); + + + const dictionary& textDict = dict.subDict("text"); + forAllConstIter(dictionary, textDict, iter) + { + if (!iter().isDict()) + { + FatalIOErrorIn + ( + "void Foam::runTimePostProcessing::read(const dictionary&)", + textDict + ) + << "text must be specified in dictionary format" + << exit(FatalIOError); + } + + text_.append(new text(*this, iter().dict(), scene_.colours())); + } +} + + +void Foam::runTimePostProcessing::execute() +{ + // Do nothing +} + + +void Foam::runTimePostProcessing::end() +{ + // Do nothing +} + + +void Foam::runTimePostProcessing::timeSet() +{ + // Do nothing +} + + +void Foam::runTimePostProcessing::write() +{ + if (!Pstream::master()) + { + return; + } + + Info<< type() << " " << name_ << " output:" << nl + << " Constructing scene" << endl; + + // Initialise render window + vtkSmartPointer<vtkRenderWindow> renderWindow = + vtkSmartPointer<vtkRenderWindow>::New(); + renderWindow->OffScreenRenderingOn(); + renderWindow->SetSize(output_.width_, output_.height_); + renderWindow->SetAAFrames(10); + renderWindow->SetAlphaBitPlanes(true); + renderWindow->SetMultiSamples(0); +// renderWindow->PolygonSmoothingOn(); + + vtkSmartPointer<vtkRenderer> renderer = vtkSmartPointer<vtkRenderer>::New(); + scene_.initialise(renderer, output_.name_); + + renderWindow->AddRenderer(renderer); + + // Add the points + forAll(points_, i) + { + points_[i].addGeometryToScene(0, renderer); + } + + // Add the lines + forAll(lines_, i) + { + lines_[i].addGeometryToScene(0, renderer); + } + + // Add the surfaces + forAll(surfaces_, i) + { + surfaces_[i].addGeometryToScene(0, renderer); + } + + while (scene_.loop(renderer)) + { + scalar position = scene_.position(); + + // Add the text + forAll(text_, i) + { + text_[i].addGeometryToScene(position, renderer); + } + + // Update the points + forAll(points_, i) + { + points_[i].updateActors(position); + } + + // Update the lines + forAll(lines_, i) + { + lines_[i].updateActors(position); + } + + // Update the surfaces + forAll(surfaces_, i) + { + surfaces_[i].updateActors(position); + } + } +} + + +// ************************************************************************* // diff --git a/src/postProcessing/functionObjects/graphics/runTimePostProcessing/runTimePostProcessing.H b/src/postProcessing/functionObjects/graphics/runTimePostProcessing/runTimePostProcessing.H new file mode 100644 index 0000000000000000000000000000000000000000..087942b92d5627cbc3aea430a7fd715f2c9eb564 --- /dev/null +++ b/src/postProcessing/functionObjects/graphics/runTimePostProcessing/runTimePostProcessing.H @@ -0,0 +1,205 @@ +/*---------------------------------------------------------------------------*\ + ========= | + \\ / F ield | OpenFOAM: The Open Source CFD Toolbox + \\ / O peration | + \\ / A nd | Copyright (C) 2015 OpenFOAM Foundation + \\/ M anipulation | +------------------------------------------------------------------------------- +License + This file is part of OpenFOAM. + + OpenFOAM is free software: you can redistribute it and/or modify it + under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + OpenFOAM is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + for more details. + + You should have received a copy of the GNU General Public License + along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>. + +Class + Foam::runTimePostProcessing + +Description + Function object to generate images during run-time. + + The functionality makes use of the VTK libraries (see http://www.vtk.org) + which provide a broad set of functionality for scene composition and + manipulation. + + Images are generated using a combination of function object output, and + additional data e.gg triangulated surfaces and text. Current capabilities + include support for: + - Camera + - Objects + - Points + - Lines + - Surfaces + - Scalar bars + - Annotations + - Selection of colour maps + Scene configuration is performed using standard OpenFOAM dictionaries, using + the main headings of: output=, camera, colours, points, lines, + surfaces and text. + +SourceFiles + runTimePostProcessing.C + +\*---------------------------------------------------------------------------*/ + +#ifndef runTimePostProcessing_H +#define runTimePostProcessing_H + +#include "functionObjectState.H" +#include "objectRegistry.H" +#include "mapPolyMesh.H" +#include "PtrList.H" +#include "scene.H" + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +class vtkRenderer; +class vtkRenderWindow; + +namespace Foam +{ + +class dictionary; +class pointData; +class pathline; +class surface; +class text; + +/*---------------------------------------------------------------------------*\ + Class runTimePostProcessing Declaration +\*---------------------------------------------------------------------------*/ + +class runTimePostProcessing +: + public functionObjectState +{ +private: + + // Private data + + // Output + struct outputType + { + word name_; + label width_; + label height_; + }; + + //- Output instance + outputType output_; + + //- Scene manager + scene scene_; + + //- List of points + PtrList<pointData> points_; + + //- List of lines + PtrList<pathline> lines_; + + //- List of surfaces + PtrList<surface> surfaces_; + + //- List of text + PtrList<text> text_; + + + // Private Member Functions + + //- Helper function to read scene objects + template<class Type> + void readObjects + ( + const dictionary& dict, + PtrList<Type>& objects + ) const; + + +protected: + + // Protected data + + //- Reference to the database + const objectRegistry& obr_; + + //- on/off switch + bool active_; + + +public: + + //- Runtime type information + TypeName("runTimePostProcessing"); + + + // Constructors + + //- Construct from dictionary + runTimePostProcessing + ( + const word& name, + const objectRegistry&, + const dictionary&, + const bool loadFromFiles = false + ); + + //- Desructor + virtual ~runTimePostProcessing(); + + + // Member Functions + + virtual const objectRegistry& obr() const + { + return obr_; + } + + //- Read the field min/max data + virtual void read(const dictionary&); + + //- Execute, currently does nothing + virtual void execute(); + + //- Execute at the final time-loop, currently does nothing + virtual void end(); + + //- Called when time was set at the end of the Time::operator++ + virtual void timeSet(); + + //- Write + virtual void write(); + + //- Update for changes of mesh + virtual void updateMesh(const mapPolyMesh&) + {} + + //- Update for changes of mesh + virtual void movePoints(const polyMesh&) + {} +}; + + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +} // End namespace Foam + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +#ifdef NoRepository + #include "runTimePostProcessingTemplates.C" +#endif + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +#endif + +// ************************************************************************* // diff --git a/src/postProcessing/functionObjects/graphics/runTimePostProcessing/runTimePostProcessingFunctionObject.C b/src/postProcessing/functionObjects/graphics/runTimePostProcessing/runTimePostProcessingFunctionObject.C new file mode 100644 index 0000000000000000000000000000000000000000..abe87dfffddae9f4177f4c2a273c9587480f48f6 --- /dev/null +++ b/src/postProcessing/functionObjects/graphics/runTimePostProcessing/runTimePostProcessingFunctionObject.C @@ -0,0 +1,42 @@ +/*---------------------------------------------------------------------------*\ + ========= | + \\ / F ield | OpenFOAM: The Open Source CFD Toolbox + \\ / O peration | + \\ / A nd | Copyright (C) 2015 OpenFOAM Foundation + \\/ M anipulation | +------------------------------------------------------------------------------- +License + This file is part of OpenFOAM. + + OpenFOAM is free software: you can redistribute it and/or modify it + under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + OpenFOAM is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + for more details. + + You should have received a copy of the GNU General Public License + along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>. + +\*---------------------------------------------------------------------------*/ + +#include "runTimePostProcessingFunctionObject.H" + +// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * // + +namespace Foam +{ + defineNamedTemplateTypeNameAndDebug(runTimePostProcessingFunctionObject, 0); + + addToRunTimeSelectionTable + ( + functionObject, + runTimePostProcessingFunctionObject, + dictionary + ); +} + +// ************************************************************************* // diff --git a/src/postProcessing/functionObjects/graphics/runTimePostProcessing/runTimePostProcessingFunctionObject.H b/src/postProcessing/functionObjects/graphics/runTimePostProcessing/runTimePostProcessingFunctionObject.H new file mode 100644 index 0000000000000000000000000000000000000000..389447e8b59765840aec1d44245bee22ce2bf32d --- /dev/null +++ b/src/postProcessing/functionObjects/graphics/runTimePostProcessing/runTimePostProcessingFunctionObject.H @@ -0,0 +1,54 @@ +/*---------------------------------------------------------------------------*\ + ========= | + \\ / F ield | OpenFOAM: The Open Source CFD Toolbox + \\ / O peration | + \\ / A nd | Copyright (C) 2015 OpenFOAM Foundation + \\/ M anipulation | +------------------------------------------------------------------------------- +License + This file is part of OpenFOAM. + + OpenFOAM is free software: you can redistribute it and/or modify it + under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + OpenFOAM is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + for more details. + + You should have received a copy of the GNU General Public License + along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>. + +Typedef + Foam::runTimePostProcessingFunctionObject + +Description + FunctionObject wrapper around runTimePostProcessing to allow them to be + created via the functions entry within controlDict. + +SourceFiles + runTimePostProcessingFunctionObject.C + +\*---------------------------------------------------------------------------*/ + +#ifndef runTimePostProcessingFunctionObject_H +#define runTimePostProcessingFunctionObject_H + +#include "runTimePostProcessing.H" +#include "OutputFilterFunctionObject.H" + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +namespace Foam +{ + typedef OutputFilterFunctionObject<runTimePostProcessing> + runTimePostProcessingFunctionObject; +} + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +#endif + +// ************************************************************************* // diff --git a/src/postProcessing/functionObjects/graphics/runTimePostProcessing/runTimePostProcessingTemplates.C b/src/postProcessing/functionObjects/graphics/runTimePostProcessing/runTimePostProcessingTemplates.C new file mode 100644 index 0000000000000000000000000000000000000000..713506e488dd183ddb6f882669baa42a2342770c --- /dev/null +++ b/src/postProcessing/functionObjects/graphics/runTimePostProcessing/runTimePostProcessingTemplates.C @@ -0,0 +1,65 @@ +/*---------------------------------------------------------------------------*\ + ========= | + \\ / F ield | OpenFOAM: The Open Source CFD Toolbox + \\ / O peration | + \\ / A nd | Copyright (C) 2015 OpenFOAM Foundation + \\/ M anipulation | +------------------------------------------------------------------------------- +License + This file is part of OpenFOAM. + + OpenFOAM is free software: you can redistribute it and/or modify it + under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + OpenFOAM is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + for more details. + + You should have received a copy of the GNU General Public License + along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>. + +\*---------------------------------------------------------------------------*/ + +// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * // + +template<class Type> +void Foam::runTimePostProcessing::readObjects +( + const dictionary& dict, + PtrList<Type>& objects +) const +{ + objects.clear(); + forAllConstIter(dictionary, dict, iter) + { + if (!iter().isDict()) + { + FatalIOErrorIn + ( + "void Foam::runTimePostProcessing::readObjects" + "(" + "const dictionary&, " + "PtrList<Type>&" + ")", + dict + ) + << dict.dictName() + << " objects must be specified in dictionary format" + << exit(FatalIOError); + } + + const dictionary& objectDict(iter().dict()); + word objectType = objectDict.lookup("type"); + + objects.append + ( + Type::New(*this, iter().dict(), scene_.colours(), objectType) + ); + } +} + + +// ************************************************************************* // diff --git a/src/postProcessing/functionObjects/graphics/runTimePostProcessing/scene.C b/src/postProcessing/functionObjects/graphics/runTimePostProcessing/scene.C new file mode 100644 index 0000000000000000000000000000000000000000..9a1d8da59324477e4c65d40dcb03cd59f64a409b --- /dev/null +++ b/src/postProcessing/functionObjects/graphics/runTimePostProcessing/scene.C @@ -0,0 +1,410 @@ +/*---------------------------------------------------------------------------*\ + ========= | + \\ / F ield | OpenFOAM: The Open Source CFD Toolbox + \\ / O peration | + \\ / A nd | Copyright (C) 2015 OpenFOAM Foundation + \\/ M anipulation | +------------------------------------------------------------------------------- +License + This file is part of OpenFOAM. + + OpenFOAM is free software: you can redistribute it and/or modify it + under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + OpenFOAM is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + for more details. + + You should have received a copy of the GNU General Public License + along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>. + +\*---------------------------------------------------------------------------*/ + +// OpenFOAM includes +#include "scene.H" +#include "Constant.H" + +// VTK includes +#include "vtkCamera.h" +#include "vtkCubeSource.h" +#include "vtkLightKit.h" +#include "vtkPolyDataMapper.h" +#include "vtkPNGWriter.h" +#include "vtkRenderer.h" +#include "vtkRendererCollection.h" +#include "vtkRenderWindow.h" +#include "vtkWindowToImageFilter.h" + +// * * * * * * * * * * * * Static Member Functions * * * * * * * * * * * * * // + +namespace Foam +{ + template<> + const char* NamedEnum<scene::modeType, 2>::names[] = + { + "static", + "flightPath" + }; +} + +const Foam::NamedEnum<Foam::scene::modeType, 2> modeTypeNames_; + + +// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * // + +void Foam::scene::readCamera(const dictionary& dict) +{ + if (dict.readIfPresent("nFrameTotal", nFrameTotal_)) + { + if (nFrameTotal_ < 1) + { + FatalIOErrorIn + ( + "void Foam::scene::readCamera(const dictionary&)", + dict + ) << "nFrameTotal must be 1 or greater" + << exit(FatalIOError); + } + } + + if (dict.readIfPresent("startPosition", position_)) + { + if ((position_ < 0) || (position_ > 1)) + { + FatalIOErrorIn + ( + "void Foam::scene::readCamera(const dictionary&)", + dict + ) << "startPosition must be in the range 0-1" + << exit(FatalIOError); + } + } + + + dict.lookup("parallelProjection") >> parallelProjection_; + + if (nFrameTotal_ > 1) + { + scalar endPosition = dict.lookupOrDefault<scalar>("endPosition", 1); + if ((endPosition < 0) || (endPosition > 1)) + { + FatalIOErrorIn + ( + "void Foam::scene::readCamera(const dictionary&)", + dict + ) << "endPosition must be in the range 0-1" + << exit(FatalIOError); + } + dPosition_ = (endPosition - position_)/scalar(nFrameTotal_ - 1); + } + + mode_ = modeTypeNames_.read(dict.lookup("mode")); + + word coeffsName = modeTypeNames_[mode_] + word("Coeffs"); + const dictionary& coeffs = dict.subDict(coeffsName); + + switch (mode_) + { + case mtStatic: + { + clipBox_ = boundBox(coeffs.lookup("clipBox")); + const vector lookDir(vector(coeffs.lookup("lookDir"))); + cameraPosition_.reset(new Constant<point>("position", -lookDir)); + const vector focalPoint(coeffs.lookup("focalPoint")); + cameraFocalPoint_.reset + ( + new Constant<point>("focalPoint", focalPoint) + ); + const vector up(coeffs.lookup("up")); + cameraUp_.reset(new Constant<point>("up", up)); + break; + } + case mtFlightPath: + { + cameraPosition_.reset + ( + DataEntry<vector>::New("position", coeffs).ptr() + ); + cameraFocalPoint_.reset + ( + DataEntry<point>::New("focalPoint", coeffs).ptr() + ); + cameraUp_.reset(DataEntry<vector>::New("up", coeffs).ptr()); + break; + } + default: + { + FatalErrorIn("void Foam::scene::read(const dictionary&)") + << "Unhandled enumeration " << modeTypeNames_[mode_] + << abort(FatalError); + } + } + + if (dict.found("zoom")) + { + cameraZoom_.reset(DataEntry<scalar>::New("zoom", dict).ptr()); + } + else + { + cameraZoom_.reset(new Constant<scalar>("zoom", 1.0)); + } + + if (dict.found("viewAngle")) + { + cameraViewAngle_.reset(DataEntry<scalar>::New("viewAngle", dict).ptr()); + } + else + { + cameraViewAngle_.reset(new Constant<scalar>("viewAngle", 35.0)); + } +} + + +void Foam::scene::readColours(const dictionary& dict) +{ + const wordList colours = dict.toc(); + forAll(colours, i) + { + const word& c = colours[i]; + colours_.insert(c, DataEntry<vector>::New(c, dict).ptr()); + } +} + + +void Foam::scene::initialise(vtkRenderer* renderer, const word& outputName) +{ + currentFrameI_ = 0; + + outputName_ = outputName; + + // Set the background + const vector backgroundColour = colours_["background"]->value(position()); + renderer->SetBackground + ( + backgroundColour.x(), + backgroundColour.y(), + backgroundColour.z() + ); + + // Apply gradient background if "background2" defined + if (colours_.found("background2")) + { + renderer->GradientBackgroundOn(); + vector backgroundColour2 = colours_["background2"]->value(position()); + + renderer->SetBackground2 + ( + backgroundColour2.x(), + backgroundColour2.y(), + backgroundColour2.z() + ); + } + + // Depth peeling + renderer->SetUseDepthPeeling(true); + renderer->SetMaximumNumberOfPeels(4); + renderer->SetOcclusionRatio(0); + + // Set the camera + vtkSmartPointer<vtkCamera> camera = vtkSmartPointer<vtkCamera>::New(); + camera->SetParallelProjection(parallelProjection_); + renderer->SetActiveCamera(camera); + + setCamera(renderer, true); + + // Initialise the extents + if (mode_ == mtStatic) + { + const point& min = clipBox_.min(); + const point& max = clipBox_.max(); + vtkSmartPointer<vtkCubeSource> clipBox = + vtkSmartPointer<vtkCubeSource>::New(); + clipBox->SetXLength(max.x() - min.x()); + clipBox->SetYLength(max.y() - min.y()); + clipBox->SetZLength(max.z() - min.z()); + clipBox->SetCenter + ( + min.x() + 0.5*(max.x() - min.x()), + min.y() + 0.5*(max.y() - min.y()), + min.z() + 0.5*(max.z() - min.z()) + ); + vtkSmartPointer<vtkPolyDataMapper> clipMapper = + vtkSmartPointer<vtkPolyDataMapper>::New(); + clipMapper->SetInputConnection(clipBox->GetOutputPort()); + + vtkSmartPointer<vtkActor> clipActor = vtkSmartPointer<vtkActor>::New(); + clipActor->SetMapper(clipMapper); + clipActor->VisibilityOn(); + renderer->AddActor(clipActor); + + renderer->ResetCamera(); + + clipActor->VisibilityOff(); + } +} + + +void Foam::scene::setCamera(vtkRenderer* renderer, const bool override) const +{ + if (mode_ == mtFlightPath || override) + { + vtkCamera* camera = renderer->GetActiveCamera(); + + if (!parallelProjection_) + { + camera->SetViewAngle(cameraViewAngle_->value(position())); + } + + const vector up = cameraUp_->value(position()); + const vector pos = cameraPosition_->value(position()); + const point focalPoint = cameraFocalPoint_->value(position()); + + camera->SetViewUp(up.x(), up.y(), up.z()); + camera->SetPosition(pos.x(), pos.y(), pos.z()); + camera->SetFocalPoint(focalPoint.x(), focalPoint.y(), focalPoint.z()); + camera->Modified(); + + vtkSmartPointer<vtkLightKit> lightKit = + vtkSmartPointer<vtkLightKit>::New(); + lightKit->AddLightsToRenderer(renderer); + } +} + + +Foam::string Foam::scene::frameIndexStr() const +{ + string str = Foam::name(currentFrameI_); + str.insert(0, 4 - str.length(), '0'); + + return str; +} + + +// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * // + +Foam::scene::scene(const objectRegistry& obr, const word& name) +: + obr_(obr), + name_(name), + colours_(), + mode_(mtStatic), + cameraPosition_(NULL), + cameraFocalPoint_(NULL), + cameraUp_(NULL), + cameraZoom_(NULL), + cameraViewAngle_(NULL), + clipBox_(), + parallelProjection_(true), + nFrameTotal_(1), + position_(0), + dPosition_(0), + currentFrameI_(0), + outputName_("unknown") +{} + + +// * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * // + +Foam::scene::~scene() +{} + + +// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * // + +const Foam::HashPtrTable<Foam::DataEntry<Foam::vector>, Foam::word>& +Foam::scene::colours() const +{ + return colours_; +} + + +Foam::label Foam::scene::frameIndex() const +{ + return currentFrameI_; +} + + +Foam::scalar Foam::scene::position() const +{ + return position_; +} + + +void Foam::scene::read(const dictionary& dict) +{ + readCamera(dict.subDict("camera")); + readColours(dict.subDict("colours")); +} + + +bool Foam::scene::loop(vtkRenderer* renderer) +{ + static bool initialised = false; + + setCamera(renderer, false); + + if (!initialised) + { + initialised = true; + return true; + } + + // Save image from last iteration + saveImage(renderer->GetRenderWindow()); + + currentFrameI_++; + + position_ += currentFrameI_*dPosition_; + + if (currentFrameI_ < nFrameTotal_) + { + return true; + } + else + { + return false; + } +} + + +void Foam::scene::saveImage(vtkRenderWindow* renderWindow) const +{ + if (!renderWindow) + { + return; + } + + fileName prefix("postProcessing"/name_/obr_.time().timeName()); + mkDir(prefix); + + renderWindow->Render(); + + // Set up off-screen rendering + vtkSmartPointer<vtkWindowToImageFilter> windowToImageFilter = + vtkSmartPointer<vtkWindowToImageFilter>::New(); + + windowToImageFilter->SetInput(renderWindow); + + //// Add alpha channel for transparency + // windowToImageFilter->SetInputBufferTypeToRGBA(); + windowToImageFilter->SetInputBufferTypeToRGB(); + +// windowToImageFilter->ReadFrontBufferOff(); + windowToImageFilter->Update(); + + // Save the image + vtkSmartPointer<vtkPNGWriter> writer = vtkSmartPointer<vtkPNGWriter>::New(); + fileName fName(prefix/outputName_ + '.' + frameIndexStr() + ".png"); + writer->SetFileName(fName.c_str()); + writer->SetInputConnection(windowToImageFilter->GetOutputPort()); + + Info<< " Generating image: " << fName << endl; + + writer->Write(); +} + + +// ************************************************************************* // diff --git a/src/postProcessing/functionObjects/graphics/runTimePostProcessing/scene.H b/src/postProcessing/functionObjects/graphics/runTimePostProcessing/scene.H new file mode 100644 index 0000000000000000000000000000000000000000..d3bd156e39d56a04419ec7c316d5f9c70d88dadb --- /dev/null +++ b/src/postProcessing/functionObjects/graphics/runTimePostProcessing/scene.H @@ -0,0 +1,202 @@ +/*---------------------------------------------------------------------------*\ + ========= | + \\ / F ield | OpenFOAM: The Open Source CFD Toolbox + \\ / O peration | + \\ / A nd | Copyright (C) 2015 OpenFOAM Foundation + \\/ M anipulation | +------------------------------------------------------------------------------- +License + This file is part of OpenFOAM. + + OpenFOAM is free software: you can redistribute it and/or modify it + under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + OpenFOAM is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + for more details. + + You should have received a copy of the GNU General Public License + along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>. + +Class + Foam::camera + +Description + +SourceFiles + scene.C + +\*---------------------------------------------------------------------------*/ + +#ifndef scene_H +#define scene_H + +// OpenFOAM includes +#include "dictionary.H" +#include "DataEntry.H" +#include "vector.H" +#include "point.H" +#include "boundBox.H" +#include "NamedEnum.H" +#include "HashPtrTable.H" +#include "vector.H" + +// VTK includes +#include "vtkSmartPointer.h" + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +class vtkRenderer; +class vtkRenderWindow; + +namespace Foam +{ + +/*---------------------------------------------------------------------------*\ + Class scene Declaration +\*---------------------------------------------------------------------------*/ + +class scene +{ +public: + + enum modeType{mtStatic, mtFlightPath}; + + NamedEnum<modeType, 2> modeTypeNames_; + + +private: + + // Private data + + //- Reference to the object registry + const objectRegistry& obr_; + + //- Object name + const word name_; + + + // Private Member Functions + + //- Read camera properties + void readCamera(const dictionary& dict); + + //- Read solour properties + void readColours(const dictionary& dict); + + //- Disallow default bitwise copy construct + scene(const scene&); + + //- Disallow default bitwise assignment + void operator=(const scene&); + + +protected: + + // Protected data + + //- Colours + HashPtrTable<DataEntry<vector>, word> colours_; + + + // Camera settings + + //- Mode + modeType mode_; + + //- Position + autoPtr<DataEntry<point> > cameraPosition_; + + //- Focal point + autoPtr<DataEntry<point> > cameraFocalPoint_; + + //- Up direction + autoPtr<DataEntry<vector> > cameraUp_; + + //- Zoom level + autoPtr<DataEntry<scalar> > cameraZoom_; + + //- View angle + autoPtr<DataEntry<scalar> > cameraViewAngle_; + + + // Scene management + + //- Clipping box + boundBox clipBox_; + + //- Parallel projection flag + bool parallelProjection_; + + //- Number of frames + label nFrameTotal_; + + //- Position [0-1] + scalar position_; + + //- Change in position per frame + scalar dPosition_; + + //- Index of current frame + label currentFrameI_; + + //- Name prefix of output + word outputName_; + + + // Protected Member Functions + + void setCamera(vtkRenderer* renderer, const bool override) const; + + string frameIndexStr() const; + + +public: + + // Constructors + + //- Construct from components + scene(const objectRegistry& obr, const word& name); + + + //- Destructor + virtual ~scene(); + + + // Member Functions + + // Access + + //- Return the colours + const HashPtrTable<DataEntry<vector>, word>& colours() const; + + //- Return the current frame index + label frameIndex() const; + + //- Return the current position (in range 0-1) + scalar position() const; + + void read(const dictionary& dict); + + void initialise(vtkRenderer* renderer, const word& outputName); + + //- Main control loop + bool loop(vtkRenderer* renderer); + + //- Save image to file + void saveImage(vtkRenderWindow* renderWindow) const; +}; + + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +} // End namespace Foam + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +#endif + +// ************************************************************************* // diff --git a/src/postProcessing/functionObjects/graphics/runTimePostProcessing/surface.C b/src/postProcessing/functionObjects/graphics/runTimePostProcessing/surface.C new file mode 100644 index 0000000000000000000000000000000000000000..cd9b241c96db8fd3e2238bbff20fa6148b17d955 --- /dev/null +++ b/src/postProcessing/functionObjects/graphics/runTimePostProcessing/surface.C @@ -0,0 +1,262 @@ +/*---------------------------------------------------------------------------*\ + ========= | + \\ / F ield | OpenFOAM: The Open Source CFD Toolbox + \\ / O peration | + \\ / A nd | Copyright (C) 2015 OpenFOAM Foundation + \\/ M anipulation | +------------------------------------------------------------------------------- +License + This file is part of OpenFOAM. + + OpenFOAM is free software: you can redistribute it and/or modify it + under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + OpenFOAM is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + for more details. + + You should have received a copy of the GNU General Public License + along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>. + +\*---------------------------------------------------------------------------*/ + +// OpenFOAM includes +#include "surface.H" +#include "runTimePostProcessing.H" + +// VTK includes +#include "vtkActor.h" +#include "vtkFeatureEdges.h" +#include "vtkPolyData.h" +#include "vtkPolyDataMapper.h" +#include "vtkProperty.h" +#include "vtkRenderer.h" +#include "vtkSmartPointer.h" + +// * * * * * * * * * * * * * Static Member Functions * * * * * * * * * * * * // + +namespace Foam +{ + template<> + const char* NamedEnum<surface::representationType, 5>::names[] = + { + "none", + "wireframe", + "surface", + "surfaceWithEdges", + "glyph" + }; + + defineTypeNameAndDebug(surface, 0); + defineRunTimeSelectionTable(surface, dictionary); +} + +const Foam::NamedEnum<Foam::surface::representationType, 5> + Foam::surface::representationTypeNames; + + +// * * * * * * * * * * * * Protected Member Functions * * * * * * * * * * * // + +void Foam::surface::setRepresentation(vtkActor* actor) const +{ + geometryBase::initialiseActor(actor); + + switch (representation_) + { + case rtNone: + { + actor->VisibilityOff(); + break; + } + case rtWireframe: + { + // note: colour is set using general SetColour, not setEdgeColor + actor->GetProperty()->SetRepresentationToWireframe(); + break; + } + case rtGlyph: + case rtSurface: + { + actor->GetProperty()->SetRepresentationToSurface(); + break; + } + case rtSurfaceWithEdges: + { + actor->GetProperty()->SetRepresentationToSurface(); + actor->GetProperty()->EdgeVisibilityOn(); + break; + } + } +} + + +void Foam::surface::addFeatureEdges +( + vtkRenderer* renderer, + vtkPolyData* data +) const +{ + if (!featureEdges_) + { + return; + } + + vtkSmartPointer<vtkFeatureEdges> featureEdges = + vtkSmartPointer<vtkFeatureEdges>::New(); + featureEdges->SetInputData(data); + featureEdges->BoundaryEdgesOn(); + featureEdges->FeatureEdgesOn(); + featureEdges->ManifoldEdgesOff(); + featureEdges->NonManifoldEdgesOff(); +// featureEdges->SetFeatureAngle(60); + featureEdges->ColoringOff(); + featureEdges->Update(); + + vtkSmartPointer<vtkPolyDataMapper> mapper = + vtkSmartPointer<vtkPolyDataMapper>::New(); + mapper->SetInputConnection(featureEdges->GetOutputPort()); + mapper->ScalarVisibilityOff(); + + edgeActor_->GetProperty()->SetSpecular(0); + edgeActor_->GetProperty()->SetSpecularPower(20); + edgeActor_->GetProperty()->SetRepresentationToWireframe(); + edgeActor_->SetMapper(mapper); + + renderer->AddActor(edgeActor_); +} + + +// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * // + +Foam::surface::surface +( + const runTimePostProcessing& parent, + const dictionary& dict, + const HashPtrTable<DataEntry<vector>, word>& colours +) +: + geometryBase(parent, dict, colours), + representation_ + ( + representationTypeNames.read(dict.lookup("representation")) + ), + featureEdges_(false), + surfaceColour_(NULL), + edgeColour_(NULL), + surfaceActor_(), + edgeActor_(), + maxGlyphLength_(0.0) +{ + surfaceActor_ = vtkSmartPointer<vtkActor>::New(); + edgeActor_ = vtkSmartPointer<vtkActor>::New(); + + if (dict.found("surfaceColour")) + { + surfaceColour_.reset + ( + DataEntry<vector>::New("surfaceColour", dict).ptr() + ); + } + else + { + surfaceColour_.reset(colours["surface"]->clone().ptr()); + } + + if (dict.found("edgeColour")) + { + edgeColour_.reset(DataEntry<vector>::New("edgeColour", dict).ptr()); + } + else + { + edgeColour_.reset(colours["edge"]->clone().ptr()); + } + + if (representation_ == rtGlyph) + { + dict.lookup("maxGlyphLength") >> maxGlyphLength_; + } + else + { + dict.lookup("featureEdges") >> featureEdges_; + } +} + + +// * * * * * * * * * * * * * * * * Selectors * * * * * * * * * * * * * * * * // + +Foam::autoPtr<Foam::surface> Foam::surface::New +( + const runTimePostProcessing& parent, + const dictionary& dict, + const HashPtrTable<DataEntry<vector>, word>& colours, + const word& surfaceType +) +{ + if (debug) + { + Info<< "Selecting surface " << surfaceType << endl; + } + + dictionaryConstructorTable::iterator cstrIter = + dictionaryConstructorTablePtr_->find(surfaceType); + + if (cstrIter == dictionaryConstructorTablePtr_->end()) + { + FatalErrorIn + ( + "Foam::autoPtr<Foam::surface> Foam::surface::New" + "(" + "const runTimePostProcessing&, " + "const dictionary&, " + "const HashPtrTable<DataEntry<vector>, word>&, " + "const word&" + ")" + ) << "Unknown surface type " + << surfaceType << nl << nl + << "Valid surface types are:" << endl + << dictionaryConstructorTablePtr_->sortedToc() + << exit(FatalError); + } + + return autoPtr<surface>(cstrIter()(parent, dict, colours)); +} + + +// * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * // + +Foam::surface::~surface() +{} + + +// * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * * // + +void Foam::surface::updateActors(const scalar position) +{ + if (!featureEdges_) + { + return; + } + + edgeActor_->GetProperty()->SetLineWidth(2); + edgeActor_->GetProperty()->SetOpacity(opacity(position)); + + const vector colour = edgeColour_->value(position); + edgeActor_->GetProperty()->SetColor + ( + colour[0], + colour[1], + colour[2] + ); + edgeActor_->GetProperty()->SetEdgeColor + ( + colour[0], + colour[1], + colour[2] + ); +} + + +// ************************************************************************* // diff --git a/src/postProcessing/functionObjects/graphics/runTimePostProcessing/surface.H b/src/postProcessing/functionObjects/graphics/runTimePostProcessing/surface.H new file mode 100644 index 0000000000000000000000000000000000000000..d03ff34fb7bb0cd7d2be35fb769b97b3ea7c6967 --- /dev/null +++ b/src/postProcessing/functionObjects/graphics/runTimePostProcessing/surface.H @@ -0,0 +1,190 @@ +/*---------------------------------------------------------------------------*\ + ========= | + \\ / F ield | OpenFOAM: The Open Source CFD Toolbox + \\ / O peration | + \\ / A nd | Copyright (C) 2015 OpenFOAM Foundation + \\/ M anipulation | +------------------------------------------------------------------------------- +License + This file is part of OpenFOAM. + + OpenFOAM is free software: you can redistribute it and/or modify it + under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + OpenFOAM is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + for more details. + + You should have received a copy of the GNU General Public License + along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>. + +Class + Foam::surface + +Description + +SourceFiles + surface.C + +\*---------------------------------------------------------------------------*/ + +#ifndef surface_H +#define surface_H + +#include "geometryBase.H" +#include "NamedEnum.H" +#include "runTimeSelectionTables.H" + +#include "vtkSmartPointer.h" + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +class vtkActor; +class vtkRenderer; +class vtkPolyData; + +namespace Foam +{ + +/*---------------------------------------------------------------------------*\ + Class surface Declaration +\*---------------------------------------------------------------------------*/ + +class surface +: + public geometryBase +{ +public: + + // Public enumerations + + enum representationType + { + rtNone, + rtWireframe, + rtSurface, + rtSurfaceWithEdges, + rtGlyph + }; + + static const NamedEnum<representationType, 5> representationTypeNames; + + +private: + + // Private Member Functions + + //- Disallow default bitwise copy construct + surface(const surface&); + + //- Disallow default bitwise assignment + void operator=(const surface&); + + +protected: + + // Protected data + + //- Representation type + representationType representation_; + + //- Activate feature edges + bool featureEdges_; + + //- Surface colour + autoPtr<DataEntry<vector> > surfaceColour_; + + //- Edge colour + autoPtr<DataEntry<vector> > edgeColour_; + + //- Surface actor + vtkSmartPointer<vtkActor> surfaceActor_; + + //- Edge actor + vtkSmartPointer<vtkActor> edgeActor_; + + //- Max glyph length for representation type rtGlyph + scalar maxGlyphLength_; + + + // Protected Member Functions + + //- Set the representation + void setRepresentation(vtkActor* actor) const; + + //- Add feature edges to scene + void addFeatureEdges + ( + vtkRenderer* renderer, + vtkPolyData* data + ) const; + + +public: + + //- Run-time type information + TypeName("surface"); + + + // Declare run-time constructor selection table + + declareRunTimeSelectionTable + ( + autoPtr, + surface, + dictionary, + ( + const runTimePostProcessing& parent, + const dictionary& dict, + const HashPtrTable<DataEntry<vector>, word>& colours + ), + (parent, dict, colours) + ); + + + // Constructors + + //- Construct from dictionary + surface + ( + const runTimePostProcessing& parent, + const dictionary& dict, + const HashPtrTable<DataEntry<vector>, word>& colours + ); + + + // Selectors + + //- Return a reference to the selected RAS model + static autoPtr<surface> New + ( + const runTimePostProcessing& parent, + const dictionary& dict, + const HashPtrTable<DataEntry<vector>, word>& colours, + const word& surfaceName + ); + + + //- Destructor + virtual ~surface(); + + + // Member Functions + + //- Update the actors + virtual void updateActors(const scalar position); +}; + + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +} // End namespace Foam + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +#endif + +// ************************************************************************* // diff --git a/src/postProcessing/functionObjects/graphics/runTimePostProcessing/text.C b/src/postProcessing/functionObjects/graphics/runTimePostProcessing/text.C new file mode 100644 index 0000000000000000000000000000000000000000..b4c1ff3f86c9d099704922e1c57fd6e41f3a89ed --- /dev/null +++ b/src/postProcessing/functionObjects/graphics/runTimePostProcessing/text.C @@ -0,0 +1,110 @@ +/*---------------------------------------------------------------------------*\ + ========= | + \\ / F ield | OpenFOAM: The Open Source CFD Toolbox + \\ / O peration | + \\ / A nd | Copyright (C) 2015 OpenFOAM Foundation + \\/ M anipulation | +------------------------------------------------------------------------------- +License + This file is part of OpenFOAM. + + OpenFOAM is free software: you can redistribute it and/or modify it + under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + OpenFOAM is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + for more details. + + You should have received a copy of the GNU General Public License + along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>. + +\*---------------------------------------------------------------------------*/ + +// OpenFOAM includes +#include "text.H" +#include "runTimePostProcessing.H" + +// VTK includes +#include "vtkRenderer.h" +#include "vtkSmartPointer.h" +#include "vtkTextActor.h" +#include "vtkTextProperty.h" + +// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * // + +Foam::text::text +( + const runTimePostProcessing& parent, + const dictionary& dict, + const HashPtrTable<DataEntry<vector>, word>& colours +) +: + geometryBase(parent, dict, colours), + string_(dict.lookup("string")), + position_(dict.lookup("position")), + size_(readScalar(dict.lookup("size"))), + colour_(NULL), + bold_(readBool(dict.lookup("bold"))) +{ + if (dict.found("colour")) + { + colour_.reset(DataEntry<vector>::New("colour", dict).ptr()); + } + else + { + colour_.reset(colours["text"]->clone().ptr()); + } +} + + +// * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * // + +Foam::text::~text() +{} + + +// * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * * // + +void Foam::text::addGeometryToScene +( + const scalar position, + vtkRenderer* renderer +) +{ + if (!visible_) + { + return; + } + + vtkSmartPointer<vtkTextActor> actor = vtkSmartPointer<vtkTextActor>::New(); + + actor->SetInput(string_.c_str()); + actor->GetTextProperty()->SetFontFamilyToArial(); + actor->GetTextProperty()->SetFontSize(size_); + actor->GetTextProperty()->SetJustificationToLeft(); + actor->GetTextProperty()->SetVerticalJustificationToBottom(); + actor->GetTextProperty()->SetBold(bold_); + + const vector colour = colour_->value(position); + actor->GetTextProperty()->SetColor(colour[0], colour[1], colour[2]); + actor->GetPositionCoordinate()->SetCoordinateSystemToNormalizedViewport(); + actor->GetPositionCoordinate()->SetValue + ( + position_.first(), + position_.second() + ); + + renderer->AddActor2D(actor); +} + + +void Foam::text::updateActors(const scalar position) +{ + // do nothing - all handled by addGeometryToScene +} + + +// ************************************************************************* // diff --git a/src/postProcessing/functionObjects/graphics/runTimePostProcessing/text.H b/src/postProcessing/functionObjects/graphics/runTimePostProcessing/text.H new file mode 100644 index 0000000000000000000000000000000000000000..bee0020ef55cbebd33943905a1521ff437988ed6 --- /dev/null +++ b/src/postProcessing/functionObjects/graphics/runTimePostProcessing/text.H @@ -0,0 +1,125 @@ +/*---------------------------------------------------------------------------*\ + ========= | + \\ / F ield | OpenFOAM: The Open Source CFD Toolbox + \\ / O peration | + \\ / A nd | Copyright (C) 2015 OpenFOAM Foundation + \\/ M anipulation | +------------------------------------------------------------------------------- +License + This file is part of OpenFOAM. + + OpenFOAM is free software: you can redistribute it and/or modify it + under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + OpenFOAM is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + for more details. + + You should have received a copy of the GNU General Public License + along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>. + +Class + Foam::text + +Description + +SourceFiles + text.C + +\*---------------------------------------------------------------------------*/ + +#ifndef text_H +#define text_H + +#include "geometryBase.H" +#include "Tuple2.H" + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +class vtkRenderer; + +namespace Foam +{ + +/*---------------------------------------------------------------------------*\ + Class text Declaration +\*---------------------------------------------------------------------------*/ + +class text +: + public geometryBase +{ +private: + + // Private Member Functions + + //- Disallow default bitwise copy construct + text(const text&); + + //- Disallow default bitwise assignment + void operator=(const text&); + + +protected: + + // Protected data + + //- Text + string string_; + + //- Position + Tuple2<scalar, scalar> position_; + + //- Size + scalar size_; + + //- Colour + autoPtr<DataEntry<vector> > colour_; + + //- Bold flag + bool bold_; + + +public: + + // Constructors + + //- Construct from dictionary + text + ( + const runTimePostProcessing& parent, + const dictionary& dict, + const HashPtrTable<DataEntry<vector>, word>& colours + ); + + + //- Destructor + virtual ~text(); + + + // Member Functions + + //- Add surface(s) to scene + virtual void addGeometryToScene + ( + const scalar position, + vtkRenderer* renderer + ); + + //- Update actors + virtual void updateActors(const scalar position); +}; + + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +} // End namespace Foam + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +#endif + +// ************************************************************************* // diff --git a/src/postProcessing/functionObjects/utilities/pressureTools/pressureTools.H b/src/postProcessing/functionObjects/utilities/pressureTools/pressureTools.H index 6d80b388d107eb205d8de7cb08f8b438a993a8b0..6f7607e6e0f76afdc3d518f288c3a95c4532180d 100644 --- a/src/postProcessing/functionObjects/utilities/pressureTools/pressureTools.H +++ b/src/postProcessing/functionObjects/utilities/pressureTools/pressureTools.H @@ -3,7 +3,7 @@ \\ / F ield | OpenFOAM: The Open Source CFD Toolbox \\ / O peration | \\ / A nd | Copyright (C) 2012-2013 OpenFOAM Foundation - \\/ M anipulation | + \\/ M anipulation | Copyright (C) 2015 OpenCFD Ltd ------------------------------------------------------------------------------- License This file is part of OpenFOAM. @@ -93,6 +93,9 @@ Description Property | Description | Required | Default value type | type name: pressureTools| yes | calcTotal | Calculate total coefficient | yes | + pName | Name of pressure field | no | p + UName | Name of velocity field | no | U + rhoName | Name of density field | no | rho pRef | Reference pressure for total pressure | no | 0.0 calcCoeff | Calculate pressure coefficient | yes | pInf | Freestream pressure for coefficient calculation | no | diff --git a/src/postProcessing/functionObjects/utilities/residuals/residuals.C b/src/postProcessing/functionObjects/utilities/residuals/residuals.C index 64ac3690b691b50127993e5b11beff0e4be242f8..00e652b47dbeac60369902f70e11c98a8e7530a1 100644 --- a/src/postProcessing/functionObjects/utilities/residuals/residuals.C +++ b/src/postProcessing/functionObjects/utilities/residuals/residuals.C @@ -3,7 +3,7 @@ \\ / F ield | OpenFOAM: The Open Source CFD Toolbox \\ / O peration | \\ / A nd | Copyright (C) 2015 OpenFOAM Foundation - \\/ M anipulation | + \\/ M anipulation | Copyright (C) 2015 OpenCFD Ltd ------------------------------------------------------------------------------- License This file is part of OpenFOAM. @@ -35,6 +35,23 @@ namespace Foam defineTypeNameAndDebug(residuals, 0); } + +// * * * * * * * * * * * * * Protected Member Functions * * * * * * * * * * // + +void Foam::residuals::writeFileHeader(Ostream& os) const +{ + writeHeader(os, "Residuals"); + writeCommented(os, "Time"); + + forAll(fieldSet_, fieldI) + { + writeTabbed(os, fieldSet_[fieldI]); + } + + os << endl; +} + + // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * // Foam::residuals::residuals @@ -45,7 +62,7 @@ Foam::residuals::residuals const bool loadFromFiles ) : - functionObjectFile(obr, name, typeName), + functionObjectFile(obr, name, typeName, dict), name_(name), obr_(obr), active_(true), @@ -68,7 +85,11 @@ Foam::residuals::residuals << endl; } - read(dict); + if (active_) + { + read(dict); + writeFileHeader(file()); + } } @@ -84,24 +105,11 @@ void Foam::residuals::read(const dictionary& dict) { if (active_) { - dict.lookup("fields") >> fieldSet_; - } -} + functionObjectFile::read(dict); - -void Foam::residuals::writeFileHeader(const label i) -{ - if (Pstream::master()) - { - writeHeader(file(), "Residuals"); - writeCommented(file(), "Time"); - - forAll(fieldSet_, fieldI) - { - writeTabbed(file(), fieldSet_[fieldI]); - } - - file() << endl; + wordList allFields(dict.lookup("fields")); + wordHashSet uniqueFields(allFields); + fieldSet_ = uniqueFields.toc(); } } @@ -128,8 +136,6 @@ void Foam::residuals::write() { if (active_) { - functionObjectFile::write(); - if (Pstream::master()) { file()<< obr_.time().value(); diff --git a/src/postProcessing/functionObjects/utilities/residuals/residuals.H b/src/postProcessing/functionObjects/utilities/residuals/residuals.H index cb3d69cabdf9752cc18ce469369b1349b150402c..01b24bbcee6f19665faf0cec7c28974f242e002c 100644 --- a/src/postProcessing/functionObjects/utilities/residuals/residuals.H +++ b/src/postProcessing/functionObjects/utilities/residuals/residuals.H @@ -3,7 +3,7 @@ \\ / F ield | OpenFOAM: The Open Source CFD Toolbox \\ / O peration | \\ / A nd | Copyright (C) 2015 OpenFOAM Foundation - \\/ M anipulation | + \\/ M anipulation | Copyright (C) 2015 OpenCFD Ltd ------------------------------------------------------------------------------- License This file is part of OpenFOAM. @@ -83,7 +83,7 @@ class polyMesh; class mapPolyMesh; /*---------------------------------------------------------------------------*\ - Class residuals Declaration + Class residuals Declaration \*---------------------------------------------------------------------------*/ class residuals @@ -116,7 +116,7 @@ protected: void operator=(const residuals&); //- Output file header information - virtual void writeFileHeader(const label i); + virtual void writeFileHeader(Ostream& os) const; public: @@ -150,7 +150,7 @@ public: return name_; } - //- Read the field min/max data + //- Read the field residuals data virtual void read(const dictionary&); //- Execute, currently does nothing @@ -162,7 +162,7 @@ public: //- Called when time was set at the end of the Time::operator++ virtual void timeSet(); - //- Calculate the field min/max + //- Calculate the field residuals template<class Type> void writeResidual(const word& fieldName); diff --git a/src/postProcessing/functionObjects/utilities/residuals/residualsTemplates.C b/src/postProcessing/functionObjects/utilities/residuals/residualsTemplates.C index 4d7c0c032edcff9833494fcba70d501c8ed300e2..2bd3ea0190c438f9b34a7dc6dc1ca1fff57dfc01 100644 --- a/src/postProcessing/functionObjects/utilities/residuals/residualsTemplates.C +++ b/src/postProcessing/functionObjects/utilities/residuals/residualsTemplates.C @@ -3,7 +3,7 @@ \\ / F ield | OpenFOAM: The Open Source CFD Toolbox \\ / O peration | \\ / A nd | Copyright (C) 2015 OpenFOAM Foundation - \\/ M anipulation | + \\/ M anipulation | Copyright (C) 2015 OpenCFD Ltd ------------------------------------------------------------------------------- License This file is part of OpenFOAM. @@ -26,16 +26,11 @@ License #include "residuals.H" #include "volFields.H" #include "dictionary.H" -#include "Time.H" -#include "ListOps.H" // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // template<class Type> -void Foam::residuals::writeResidual -( - const word& fieldName -) +void Foam::residuals::writeResidual(const word& fieldName) { typedef GeometricField<Type, fvPatchField, volMesh> fieldType; diff --git a/src/postProcessing/functionObjects/utilities/wallShearStress/wallShearStress.C b/src/postProcessing/functionObjects/utilities/wallShearStress/wallShearStress.C index 4271fa5394ee61a742e98505487434bb742077f8..0f5be2bbb04ead5b8941a1f3045b95fbca2be0e4 100644 --- a/src/postProcessing/functionObjects/utilities/wallShearStress/wallShearStress.C +++ b/src/postProcessing/functionObjects/utilities/wallShearStress/wallShearStress.C @@ -3,7 +3,7 @@ \\ / F ield | OpenFOAM: The Open Source CFD Toolbox \\ / O peration | \\ / A nd | Copyright (C) 2013-2015 OpenFOAM Foundation - \\/ M anipulation | + \\/ M anipulation | Copyright (C) 2015 OpenCFD Ltd ------------------------------------------------------------------------------- License This file is part of OpenFOAM. @@ -40,15 +40,15 @@ namespace Foam // * * * * * * * * * * * * * Protected Member Functions * * * * * * * * * * // -void Foam::wallShearStress::writeFileHeader(const label i) +void Foam::wallShearStress::writeFileHeader(Ostream& os) const { // Add headers to output data - writeHeader(file(), "Wall shear stress"); - writeCommented(file(), "Time"); - writeTabbed(file(), "patch"); - writeTabbed(file(), "min"); - writeTabbed(file(), "max"); - file() << endl; + writeHeader(os, "Wall shear stress"); + writeCommented(os, "Time"); + writeTabbed(os, "patch"); + writeTabbed(os, "min"); + writeTabbed(os, "max"); + os << endl; } @@ -74,17 +74,17 @@ void Foam::wallShearStress::calcShearStress vector minSsp = gMin(ssp); vector maxSsp = gMax(ssp); - if (Pstream::master()) + file() << mesh.time().value() + << token::TAB << pp.name() + << token::TAB << minSsp + << token::TAB << maxSsp + << endl; + + if (log_) { - file() << mesh.time().value() - << token::TAB << pp.name() - << token::TAB << minSsp - << token::TAB << maxSsp - << endl; + Info<< " min/max(" << pp.name() << ") = " + << minSsp << ", " << maxSsp << endl; } - - if (log_) Info<< " min/max(" << pp.name() << ") = " - << minSsp << ", " << maxSsp << endl; } } @@ -99,10 +99,11 @@ Foam::wallShearStress::wallShearStress const bool loadFromFiles ) : - functionObjectFile(obr, name, typeName), + functionObjectFile(obr, name, typeName, dict), name_(name), obr_(obr), active_(true), + resultName_(name), log_(true), patchSet_() { @@ -123,6 +124,8 @@ Foam::wallShearStress::wallShearStress << endl; } + read(dict); + if (active_) { const fvMesh& mesh = refCast<const fvMesh>(obr_); @@ -133,7 +136,7 @@ Foam::wallShearStress::wallShearStress ( IOobject ( - type(), + resultName_, mesh.time().timeName(), mesh, IOobject::NO_READ, @@ -150,9 +153,9 @@ Foam::wallShearStress::wallShearStress ); mesh.objectRegistry::store(wallShearStressPtr); - } - read(dict); + writeFileHeader(file()); + } } @@ -168,7 +171,10 @@ void Foam::wallShearStress::read(const dictionary& dict) { if (active_) { - log_ = dict.lookupOrDefault<Switch>("log", true); + functionObjectFile::read(dict); + + log_.readIfPresent("log", dict); + dict.readIfPresent("resultName", resultName_); const fvMesh& mesh = refCast<const fvMesh>(obr_); const polyBoundaryMesh& pbm = mesh.boundaryMesh(); @@ -179,7 +185,7 @@ void Foam::wallShearStress::read(const dictionary& dict) wordReList(dict.lookupOrDefault("patches", wordReList())) ); - Info<< type() << " " << name_ << ":" << nl; + if (log_) Info << type() << " " << name_ << " output:" << nl; if (patchSet_.empty()) { @@ -191,11 +197,11 @@ void Foam::wallShearStress::read(const dictionary& dict) } } - Info<< " processing all wall patches" << nl << endl; + if (log_) Info << " processing all wall patches" << nl << endl; } else { - Info<< " processing wall patches: " << nl; + if (log_) Info << " processing wall patches: " << nl; labelHashSet filteredPatchSet; forAllConstIter(labelHashSet, patchSet_, iter) { @@ -203,7 +209,7 @@ void Foam::wallShearStress::read(const dictionary& dict) if (isA<wallPolyPatch>(pbm[patchI])) { filteredPatchSet.insert(patchI); - Info<< " " << pbm[patchI].name() << endl; + if (log_) Info << " " << pbm[patchI].name() << endl; } else { @@ -213,7 +219,7 @@ void Foam::wallShearStress::read(const dictionary& dict) } } - Info<< endl; + if (log_) Info << endl; patchSet_ = filteredPatchSet; } @@ -228,17 +234,15 @@ void Foam::wallShearStress::execute() if (active_) { - functionObjectFile::write(); - const fvMesh& mesh = refCast<const fvMesh>(obr_); volVectorField& wallShearStress = const_cast<volVectorField&> ( - mesh.lookupObject<volVectorField>(type()) + mesh.lookupObject<volVectorField>(resultName_) ); - if (log_) Info<< type() << " " << name_ << " output:" << nl; + if (log_) Info << type() << " " << name_ << " output:" << nl; tmp<volSymmTensorField> Reff; @@ -258,12 +262,14 @@ void Foam::wallShearStress::execute() } else { - FatalErrorIn("void Foam::wallShearStress::execute()") + FatalErrorIn("void Foam::wallShearStress::write()") << "Unable to find turbulence model in the " << "database" << exit(FatalError); } calcShearStress(mesh, Reff(), wallShearStress); + + if (log_) Info << endl; } } @@ -287,14 +293,15 @@ void Foam::wallShearStress::write() { if (active_) { - functionObjectFile::write(); - const volVectorField& wallShearStress = - obr_.lookupObject<volVectorField>(type()); + obr_.lookupObject<volVectorField>(resultName_); - if (log_) Info<< type() << " " << name_ << " output:" << nl - << " writing field " << wallShearStress.name() << nl - << endl; + if (log_) + { + Info<< type() << " " << name_ << " output:" << nl + << " writing field " << wallShearStress.name() << nl + << endl; + } wallShearStress.write(); } diff --git a/src/postProcessing/functionObjects/utilities/wallShearStress/wallShearStress.H b/src/postProcessing/functionObjects/utilities/wallShearStress/wallShearStress.H index b2171a1d67cb42fbd475a18e2d255e2da337a537..7d51167335bbae37cf86370e6b7e6460d48aa513 100644 --- a/src/postProcessing/functionObjects/utilities/wallShearStress/wallShearStress.H +++ b/src/postProcessing/functionObjects/utilities/wallShearStress/wallShearStress.H @@ -2,8 +2,8 @@ ========= | \\ / F ield | OpenFOAM: The Open Source CFD Toolbox \\ / O peration | - \\ / A nd | Copyright (C) 2013-2014 OpenFOAM Foundation - \\/ M anipulation | + \\ / A nd | Copyright (C) 2013-2015 OpenFOAM Foundation + \\/ M anipulation | Copyright (C) 2015 OpenCFD Ltd ------------------------------------------------------------------------------- License This file is part of OpenFOAM. @@ -59,9 +59,11 @@ Description \heading Function object usage \table - Property | Description | Required | Default value + Property | Description | Required | Default value type | type name: wallShearStress | yes | + resultName | Name of wall shear stress field | no | <function name> patches | list of patches to process | no | all wall patches + log | Log to standard output | no | yes \endtable SourceFiles @@ -105,11 +107,15 @@ protected: //- Name of this set of wallShearStress object word name_; + //- Refefence to the database const objectRegistry& obr_; //- on/off switch bool active_; + //- Result name + word resultName_; + //- Switch to send output to Info as well as to file Switch log_; @@ -120,7 +126,7 @@ protected: // Protected Member Functions //- File header information - virtual void writeFileHeader(const label i); + virtual void writeFileHeader(Ostream& os) const; //- Calculate the shear stress void calcShearStress diff --git a/src/postProcessing/functionObjects/utilities/yPlus/yPlus.C b/src/postProcessing/functionObjects/utilities/yPlus/yPlus.C index 119a0f895dca358e3eaaf37e0052314fe1606329..01630313c846a1ef83dd5c988dee74a7c9dc3a95 100644 --- a/src/postProcessing/functionObjects/utilities/yPlus/yPlus.C +++ b/src/postProcessing/functionObjects/utilities/yPlus/yPlus.C @@ -3,7 +3,7 @@ \\ / F ield | OpenFOAM: The Open Source CFD Toolbox \\ / O peration | \\ / A nd | Copyright (C) 2013-2015 OpenFOAM Foundation - \\/ M anipulation | + \\/ M anipulation | Copyright (C) 2015 OpenCFD Ltd ------------------------------------------------------------------------------- License This file is part of OpenFOAM. @@ -38,16 +38,15 @@ namespace Foam // * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * // -void Foam::yPlus::writeFileHeader(const label i) +void Foam::yPlus::writeFileHeader(Ostream& os) const { - writeHeader(file(), "y+ ()"); - - writeCommented(file(), "Time"); - writeTabbed(file(), "patch"); - writeTabbed(file(), "min"); - writeTabbed(file(), "max"); - writeTabbed(file(), "average"); - file() << endl; + writeHeader(os, "y+"); + writeCommented(os, "Time"); + writeTabbed(os, "patch"); + writeTabbed(os, "min"); + writeTabbed(os, "max"); + writeTabbed(os, "average"); + os << endl; } @@ -61,12 +60,13 @@ Foam::yPlus::yPlus const bool loadFromFiles ) : - functionObjectFile(obr, name, typeName), + functionObjectFile(obr, name, typeName, dict), name_(name), obr_(obr), active_(true), - log_(true), - phiName_("phi") + phiName_("phi"), + resultName_(name), + log_(true) { // Check if the available mesh is an fvMesh, otherwise deactivate if (!isA<fvMesh>(obr_)) @@ -87,6 +87,8 @@ Foam::yPlus::yPlus if (active_) { + read(dict); + const fvMesh& mesh = refCast<const fvMesh>(obr_); volScalarField* yPlusPtr @@ -95,7 +97,7 @@ Foam::yPlus::yPlus ( IOobject ( - type(), + resultName_, mesh.time().timeName(), mesh, IOobject::NO_READ, @@ -107,6 +109,8 @@ Foam::yPlus::yPlus ); mesh.objectRegistry::store(yPlusPtr); + + writeFileHeader(file()); } } @@ -123,51 +127,81 @@ void Foam::yPlus::read(const dictionary& dict) { if (active_) { - log_ = dict.lookupOrDefault<Switch>("log", true); - phiName_ = dict.lookupOrDefault<word>("phiName", "phi"); + functionObjectFile::read(dict); + + log_.readIfPresent("log", dict); + dict.readIfPresent("resultName", resultName_); + dict.readIfPresent("phiName", phiName_); } } void Foam::yPlus::execute() { - typedef compressible::turbulenceModel cmpModel; - typedef incompressible::turbulenceModel icoModel; + typedef compressible::turbulenceModel cmpTurbModel; + typedef incompressible::turbulenceModel icoTurbModel; if (active_) { - functionObjectFile::write(); + const surfaceScalarField& phi = + obr_.lookupObject<surfaceScalarField>(phiName_); const fvMesh& mesh = refCast<const fvMesh>(obr_); volScalarField& yPlus = const_cast<volScalarField&> ( - mesh.lookupObject<volScalarField>(type()) + mesh.lookupObject<volScalarField>(resultName_) ); - if (log_) Info<< type() << " " << name_ << " output:" << nl; + if (log_) Info << type() << " " << name_ << " output:" << nl; - tmp<volSymmTensorField> Reff; - if (mesh.foundObject<cmpModel>(turbulenceModel::propertiesName)) + if (phi.dimensions() == dimMass/dimTime) { - const cmpModel& model = - mesh.lookupObject<cmpModel>(turbulenceModel::propertiesName); - - calcYPlus(model, mesh, yPlus); + if (mesh.foundObject<cmpTurbModel>(turbulenceModel::propertiesName)) + { + const cmpTurbModel& model = + mesh.lookupObject<cmpTurbModel> + ( + turbulenceModel::propertiesName + ); + + calcYPlus(model, mesh, yPlus); + } + else + { + WarningIn("void Foam::yPlus::execute()") + << "Unable to find compressible turbulence model in the " + << "database: yPlus will not be calculated" << endl; + } } - else if (mesh.foundObject<icoModel>(turbulenceModel::propertiesName)) + else if (phi.dimensions() == dimVolume/dimTime) { - const icoModel& model = - mesh.lookupObject<icoModel>(turbulenceModel::propertiesName); - - calcYPlus(model, mesh, yPlus); + if (mesh.foundObject<icoTurbModel>(turbulenceModel::propertiesName)) + { + const icoTurbModel& model = + mesh.lookupObject<icoTurbModel> + ( + turbulenceModel::propertiesName + ); + + calcYPlus(model, mesh, yPlus); + } + else + { + WarningIn("void Foam::yPlus::execute()") + << "Unable to find incompressible turbulence model in the " + << "database: yPlus will not be calculated" << endl; + } } else { - FatalErrorIn("void Foam::yPlus::write()") - << "Unable to find turbulence model in the " - << "database" << exit(FatalError); + WarningIn("void Foam::yPlus::execute()") + << "Unknown " << phiName_ << " dimensions: " + << phi.dimensions() << nl + << "Expected either " << dimMass/dimTime << " or " + << dimVolume/dimTime << nl + << "yPlus will not be calculated" << endl; } } } @@ -192,12 +226,16 @@ void Foam::yPlus::write() { if (active_) { - functionObjectFile::write(); - const volScalarField& yPlus = - obr_.lookupObject<volScalarField>(type()); + obr_.lookupObject<volScalarField>(resultName_); - if (log_) Info<< " writing field " << yPlus.name() << nl << endl; + if (log_) + { + Info + << type() << " " << name_ << " output:" << nl + << " writing field " << yPlus.name() << nl + << endl; + } yPlus.write(); } diff --git a/src/postProcessing/functionObjects/utilities/yPlus/yPlus.H b/src/postProcessing/functionObjects/utilities/yPlus/yPlus.H index a2a27bf0222438d10a3432d38661da65eb3445eb..80ce1abb8d82d13b638124cececcc32451a3b7d3 100644 --- a/src/postProcessing/functionObjects/utilities/yPlus/yPlus.H +++ b/src/postProcessing/functionObjects/utilities/yPlus/yPlus.H @@ -3,7 +3,7 @@ \\ / F ield | OpenFOAM: The Open Source CFD Toolbox \\ / O peration | \\ / A nd | Copyright (C) 2013-2015 OpenFOAM Foundation - \\/ M anipulation | + \\/ M anipulation | Copyright (C) 2015 OpenCFD Ltd ------------------------------------------------------------------------------- License This file is part of OpenFOAM. @@ -28,8 +28,29 @@ Group grpUtilitiesFunctionObjects Description - Evaluates and outputs turbulence y+ for models. Values written to - time directories as field 'yPlus' + This function object evaluates and outputs turbulence y+ for turbulence + models. The field is stored on the mesh database so that it can be + retrieved and used for other applications. + + Example of function object specification to calculate the y+ (LES): + \verbatim + yPlus1 + { + type yPlus; + functionObjectLibs ("libutilityFunctionObjects.so"); + ... + } + \endverbatim + + \heading Function object usage + \table + Property | Description | Required | Default value + type | Type name: yPlus | yes | + phiName | Name of flux field | no | phi + resultName | Name of y+ field | no | <function name> + log | Log to standard output | no | yes + \endtable + SourceFiles yPlus.C @@ -44,6 +65,7 @@ SourceFiles #include "volFieldsFwd.H" #include "Switch.H" #include "OFstream.H" +#include "Switch.H" // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // @@ -58,7 +80,7 @@ class mapPolyMesh; class fvMesh; /*---------------------------------------------------------------------------*\ - Class yPlus Declaration + Class yPlus Declaration \*---------------------------------------------------------------------------*/ class yPlus @@ -75,17 +97,20 @@ class yPlus //- on/off switch bool active_; - //- Switch to send output to Info as well as to file - Switch log_; - //- Name of mass/volume flux field (optional, default = phi) word phiName_; + //- Result name + word resultName_; + + //- Switch to send output to Info as well as to file + Switch log_; + // Private Member Functions //- File header information - virtual void writeFileHeader(const label i); + virtual void writeFileHeader(Ostream& os) const; //- Calculate y+ template<class TurbulenceModel> diff --git a/src/postProcessing/functionObjects/utilities/yPlus/yPlusTemplates.C b/src/postProcessing/functionObjects/utilities/yPlus/yPlusTemplates.C index 818610cfe5f3b67a02a86ed6b147d8034f69d3d3..0e7a625879d55ec79979543847a02cb154c35033 100644 --- a/src/postProcessing/functionObjects/utilities/yPlus/yPlusTemplates.C +++ b/src/postProcessing/functionObjects/utilities/yPlus/yPlusTemplates.C @@ -2,8 +2,8 @@ ========= | \\ / F ield | OpenFOAM: The Open Source CFD Toolbox \\ / O peration | - \\ / A nd | Copyright (C) 2015 OpenFOAM Foundation - \\/ M anipulation | + \\ / A nd | Copyright (C) 2013-2015 OpenFOAM Foundation + \\/ M anipulation | Copyright (C) 2015 OpenCFD Ltd ------------------------------------------------------------------------------- License This file is part of OpenFOAM. @@ -23,10 +23,9 @@ License \*---------------------------------------------------------------------------*/ -#include "yPlus.H" +#include "wallFvPatch.H" #include "nutWallFunctionFvPatchScalarField.H" #include "nearWallDist.H" -#include "wallFvPatch.H" // * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * // @@ -70,20 +69,19 @@ void Foam::yPlus::calcYPlus const scalar maxYplus = gMax(yPlusp); const scalar avgYplus = gAverage(yPlusp); - if (Pstream::master()) + if (log_) { - if (log_) Info - << " patch " << patch.name() + Info<< " patch " << patch.name() << " y+ : min = " << minYplus << ", max = " << maxYplus << ", average = " << avgYplus << nl; - - file() << obr_.time().value() - << token::TAB << patch.name() - << token::TAB << minYplus - << token::TAB << maxYplus - << token::TAB << avgYplus - << endl; } + + file() << obr_.time().value() + << token::TAB << patch.name() + << token::TAB << minYplus + << token::TAB << maxYplus + << token::TAB << avgYplus + << endl; } else if (isA<wallFvPatch>(patch)) { diff --git a/src/sampling/Make/files b/src/sampling/Make/files index 8bbc898ddae90ca8fc7496ea36f99e87981e890c..d5e75fd2ce30a662f7fb3e2c71bf100c26ff8b27 100644 --- a/src/sampling/Make/files +++ b/src/sampling/Make/files @@ -50,6 +50,7 @@ $(surfWriters)/proxy/proxySurfaceWriter.C $(surfWriters)/raw/rawSurfaceWriter.C $(surfWriters)/starcd/starcdSurfaceWriter.C $(surfWriters)/vtk/vtkSurfaceWriter.C +$(surfWriters)/boundaryData/boundaryDataSurfaceWriter.C graphField/writePatchGraph.C graphField/writeCellGraph.C diff --git a/src/sampling/sampledSet/sampledSets/sampledSets.C b/src/sampling/sampledSet/sampledSets/sampledSets.C index 0286e5487737cabeee186975fa7a08f580d1f4d0..38fb6a40c81dc7231cacd3b4a6cf63192a2c620e 100644 --- a/src/sampling/sampledSet/sampledSets/sampledSets.C +++ b/src/sampling/sampledSet/sampledSets/sampledSets.C @@ -3,7 +3,7 @@ \\ / F ield | OpenFOAM: The Open Source CFD Toolbox \\ / O peration | \\ / A nd | Copyright (C) 2011-2013 OpenFOAM Foundation - \\/ M anipulation | + \\/ M anipulation | Copyright (C) 2015 OpenCFD Ltd ------------------------------------------------------------------------------- License This file is part of OpenFOAM. @@ -136,8 +136,8 @@ Foam::sampledSets::sampledSets const bool loadFromFiles ) : + functionObjectState(obr, name), PtrList<sampledSet>(), - name_(name), mesh_(refCast<const fvMesh>(obr)), loadFromFiles_(loadFromFiles), outputPath_(fileName::null), diff --git a/src/sampling/sampledSet/sampledSets/sampledSets.H b/src/sampling/sampledSet/sampledSets/sampledSets.H index 430039a2cea485fff5457d294c5fd447a8ecee7c..a9cac56d0b40cd091d476faea8d7b40859fed34e 100644 --- a/src/sampling/sampledSet/sampledSets/sampledSets.H +++ b/src/sampling/sampledSet/sampledSets/sampledSets.H @@ -3,7 +3,7 @@ \\ / F ield | OpenFOAM: The Open Source CFD Toolbox \\ / O peration | \\ / A nd | Copyright (C) 2011-2015 OpenFOAM Foundation - \\/ M anipulation | + \\/ M anipulation | Copyright (C) 2015 OpenCFD Ltd ------------------------------------------------------------------------------- License This file is part of OpenFOAM. @@ -36,6 +36,7 @@ SourceFiles #ifndef sampledSets_H #define sampledSets_H +#include "functionObjectState.H" #include "sampledSet.H" #include "volFieldsFwd.H" #include "meshSearch.H" @@ -59,6 +60,7 @@ class fvMesh; class sampledSets : + public functionObjectState, public PtrList<sampledSet> { // Private classes @@ -153,10 +155,6 @@ class sampledSets // Private data - //- Name of this set of sets, - // Also used as the name of the sampledSets directory. - word name_; - //- Const reference to fvMesh const fvMesh& mesh_; @@ -273,12 +271,6 @@ public: // Member Functions - //- Return name of the set of probes - virtual const word& name() const - { - return name_; - } - //- Set verbosity level void verbose(const bool verbosity = true); diff --git a/src/sampling/sampledSet/sampledSets/sampledSetsTemplates.C b/src/sampling/sampledSet/sampledSets/sampledSetsTemplates.C index a646a8c7c3013d522b4b949441f9e67f21b21a46..78ded3125dbd3b3e00e3ce0b03cfefed8170fd97 100644 --- a/src/sampling/sampledSet/sampledSets/sampledSetsTemplates.C +++ b/src/sampling/sampledSet/sampledSets/sampledSetsTemplates.C @@ -3,7 +3,7 @@ \\ / F ield | OpenFOAM: The Open Source CFD Toolbox \\ / O peration | \\ / A nd | Copyright (C) 2011-2013 OpenFOAM Foundation - \\/ M anipulation | + \\/ M anipulation | Copyright (C) 2015 OpenCFD Ltd ------------------------------------------------------------------------------- License This file is part of OpenFOAM. @@ -155,6 +155,14 @@ void Foam::sampledSets::writeSampleFile valueSets, ofs ); + + forAll(masterFields, fieldi) + { + dictionary propsDict; + propsDict.add("file", fName); + const word& fieldName = masterFields[fieldi].name(); + setProperty(fieldName, propsDict); + } } else { @@ -226,10 +234,7 @@ void Foam::sampledSets::combineSampledValues template<class Type> -void Foam::sampledSets::sampleAndWrite -( - fieldGroup<Type>& fields -) +void Foam::sampledSets::sampleAndWrite(fieldGroup<Type>& fields) { if (fields.size()) { diff --git a/src/sampling/sampledSurface/sampledSurfaces/sampledSurfaces.C b/src/sampling/sampledSurface/sampledSurfaces/sampledSurfaces.C index 220a61baee674efb9babf13b088fe7719637d49e..47a9f9ebbc4d0e0e67bfb7b63e98c683c6eb56de 100644 --- a/src/sampling/sampledSurface/sampledSurfaces/sampledSurfaces.C +++ b/src/sampling/sampledSurface/sampledSurfaces/sampledSurfaces.C @@ -3,7 +3,7 @@ \\ / F ield | OpenFOAM: The Open Source CFD Toolbox \\ / O peration | \\ / A nd | Copyright (C) 2011-2015 OpenFOAM Foundation - \\/ M anipulation | + \\/ M anipulation | Copyright (C) 2015 OpenCFD Ltd ------------------------------------------------------------------------------- License This file is part of OpenFOAM. @@ -49,7 +49,7 @@ void Foam::sampledSurfaces::writeGeometry() const // Write to time directory under outputPath_ // Skip surface without faces (eg, a failed cut-plane) - const fileName outputDir = outputPath_/mesh_.time().timeName(); + const fileName outputDir = outputPath_/obr_.time().timeName(); forAll(*this, surfI) { @@ -92,9 +92,9 @@ Foam::sampledSurfaces::sampledSurfaces const bool loadFromFiles ) : + functionObjectState(obr, name), PtrList<sampledSurface>(), - name_(name), - mesh_(refCast<const fvMesh>(obr)), + obr_(obr), loadFromFiles_(loadFromFiles), outputPath_(fileName::null), fieldSelection_(), @@ -102,13 +102,19 @@ Foam::sampledSurfaces::sampledSurfaces mergeList_(), formatter_(NULL) { + // Only active if a fvMesh is available + if (setActive<fvMesh>()) + { + read(dict); + } + if (Pstream::parRun()) { - outputPath_ = mesh_.time().path()/".."/"postProcessing"/name_; + outputPath_ = obr_.time().path()/".."/"postProcessing"/name_; } else { - outputPath_ = mesh_.time().path()/"postProcessing"/name_; + outputPath_ = obr_.time().path()/"postProcessing"/name_; } read(dict); @@ -161,11 +167,11 @@ void Foam::sampledSurfaces::write() if (debug) { Pout<< "Creating directory " - << outputPath_/mesh_.time().timeName() << nl << endl; + << outputPath_/obr_.time().timeName() << nl << endl; } - mkDir(outputPath_/mesh_.time().timeName()); + mkDir(outputPath_/obr_.time().timeName()); } // Write geometry first if required, @@ -175,7 +181,7 @@ void Foam::sampledSurfaces::write() writeGeometry(); } - const IOobjectList objects(mesh_, mesh_.time().timeName()); + const IOobjectList objects(obr_, obr_.time().timeName()); sampleAndWrite<volScalarField>(objects); sampleAndWrite<volVectorField>(objects); @@ -211,10 +217,12 @@ void Foam::sampledSurfaces::read(const dictionary& dict) dict.subOrEmptyDict("formatOptions").subOrEmptyDict(writeType) ); + const fvMesh& mesh = refCast<const fvMesh>(obr_); + PtrList<sampledSurface> newList ( dict.lookup("surfaces"), - sampledSurface::iNew(mesh_) + sampledSurface::iNew(mesh) ); transfer(newList); @@ -334,8 +342,10 @@ bool Foam::sampledSurfaces::update() return updated; } + const fvMesh& mesh = refCast<const fvMesh>(obr_); + // Dimension as fraction of mesh bounding box - scalar mergeDim = mergeTol_ * mesh_.bounds().mag(); + scalar mergeDim = mergeTol_*mesh.bounds().mag(); if (Pstream::master() && debug) { @@ -374,4 +384,18 @@ bool Foam::sampledSurfaces::update() } +Foam::scalar Foam::sampledSurfaces::mergeTol() +{ + return mergeTol_; +} + + +Foam::scalar Foam::sampledSurfaces::mergeTol(const scalar tol) +{ + scalar oldTol = mergeTol_; + mergeTol_ = tol; + return oldTol; +} + + // ************************************************************************* // diff --git a/src/sampling/sampledSurface/sampledSurfaces/sampledSurfaces.H b/src/sampling/sampledSurface/sampledSurfaces/sampledSurfaces.H index 5957d1398d784289c6fcc1eb35c43aaeabaea353..3958c7f538304740072d702d72008ba4da188ac7 100644 --- a/src/sampling/sampledSurface/sampledSurfaces/sampledSurfaces.H +++ b/src/sampling/sampledSurface/sampledSurfaces/sampledSurfaces.H @@ -3,7 +3,7 @@ \\ / F ield | OpenFOAM: The Open Source CFD Toolbox \\ / O peration | \\ / A nd | Copyright (C) 2011-2015 OpenFOAM Foundation - \\/ M anipulation | + \\/ M anipulation | Copyright (C) 2015 OpenCFD Ltd ------------------------------------------------------------------------------- License This file is part of OpenFOAM. @@ -37,6 +37,7 @@ SourceFiles #ifndef sampledSurfaces_H #define sampledSurfaces_H +#include "functionObjectState.H" #include "sampledSurface.H" #include "surfaceWriter.H" #include "volFieldsFwd.H" @@ -58,6 +59,7 @@ class dictionary; class sampledSurfaces : + public functionObjectState, public PtrList<sampledSurface> { // Private classes @@ -92,12 +94,8 @@ class sampledSurfaces // Private data - //- Name of this set of surfaces, - // Also used as the name of the sampledSurfaces directory. - const word name_; - - //- Const reference to fvMesh - const fvMesh& mesh_; + //- Const reference to database + const objectRegistry& obr_; //- Load fields from files (not from objectRegistry) const bool loadFromFiles_; @@ -238,6 +236,12 @@ public: //- Update for changes of mesh due to readUpdate - expires the surfaces virtual void readUpdate(const polyMesh::readUpdateState state); + + //- Get merge tolerance + static scalar mergeTol(); + + //- Set tolerance (and return old tolerance) + static scalar mergeTol(const scalar); }; diff --git a/src/sampling/sampledSurface/sampledSurfaces/sampledSurfacesGrouping.C b/src/sampling/sampledSurface/sampledSurfaces/sampledSurfacesGrouping.C index 27b4d63d6036c8dfce1b6768cc36c39e45274b63..ff2aaf3c9912e1ef34f50aaa0eabbaf1dcb9d9c8 100644 --- a/src/sampling/sampledSurface/sampledSurfaces/sampledSurfacesGrouping.C +++ b/src/sampling/sampledSurface/sampledSurfaces/sampledSurfacesGrouping.C @@ -37,7 +37,7 @@ Foam::label Foam::sampledSurfaces::classifyFields() if (loadFromFiles_) { // Check files for a particular time - IOobjectList objects(mesh_, mesh_.time().timeName()); + IOobjectList objects(obr_, obr_.time().timeName()); wordList allFields = objects.sortedNames(); forAll(fieldSelection_, i) @@ -59,7 +59,7 @@ Foam::label Foam::sampledSurfaces::classifyFields() else { // Check currently available fields - wordList allFields = mesh_.sortedNames(); + wordList allFields = obr_.sortedNames(); labelList indices = findStrings(fieldSelection_, allFields); forAll(fieldSelection_, i) diff --git a/src/sampling/sampledSurface/sampledSurfaces/sampledSurfacesTemplates.C b/src/sampling/sampledSurface/sampledSurfaces/sampledSurfacesTemplates.C index 8683e320dc6581f9caa8b4f0a9f2f4906ca26d1f..88718cf62d7f025b485a0982346f7c387a025b1d 100644 --- a/src/sampling/sampledSurface/sampledSurfaces/sampledSurfacesTemplates.C +++ b/src/sampling/sampledSurface/sampledSurfaces/sampledSurfacesTemplates.C @@ -3,7 +3,7 @@ \\ / F ield | OpenFOAM: The Open Source CFD Toolbox \\ / O peration | \\ / A nd | Copyright (C) 2011-2013 OpenFOAM Foundation - \\/ M anipulation | + \\/ M anipulation | Copyright (C) 2015 OpenCFD Ltd ------------------------------------------------------------------------------- License This file is part of OpenFOAM. @@ -72,7 +72,7 @@ void Foam::sampledSurfaces::writeSurface // skip surface without faces (eg, a failed cut-plane) if (mergeList_[surfI].faces.size()) { - formatter_->write + fileName fName = formatter_->write ( outputDir, s.name(), @@ -82,6 +82,10 @@ void Foam::sampledSurfaces::writeSurface allValues, s.interpolate() ); + + dictionary propsDict; + propsDict.add("file", fName); + setProperty(fieldName, propsDict); } } } @@ -91,7 +95,7 @@ void Foam::sampledSurfaces::writeSurface // skip surface without faces (eg, a failed cut-plane) if (s.faces().size()) { - formatter_->write + fileName fName = formatter_->write ( outputDir, s.name(), @@ -101,6 +105,10 @@ void Foam::sampledSurfaces::writeSurface values, s.interpolate() ); + + dictionary propsDict; + propsDict.add("file", fName); + setProperty(fieldName, propsDict); } } } @@ -153,7 +161,7 @@ void Foam::sampledSurfaces::sampleAndWrite const GeometricField<Type, fvsPatchField, surfaceMesh>& sField ) { - const word& fieldName = sField.name(); + const word& fieldName = sField.name(); const fileName outputDir = outputPath_/sField.time().timeName(); forAll(*this, surfI) @@ -169,6 +177,8 @@ template<class GeoField> void Foam::sampledSurfaces::sampleAndWrite(const IOobjectList& objects) { wordList names; + const fvMesh& mesh = refCast<const fvMesh>(obr_); + if (loadFromFiles_) { IOobjectList fieldObjects(objects.lookupClass(GeoField::typeName)); @@ -176,7 +186,7 @@ void Foam::sampledSurfaces::sampleAndWrite(const IOobjectList& objects) } else { - names = mesh_.thisDb().names<GeoField>(); + names = mesh.thisDb().names<GeoField>(); } labelList nameIDs(findStrings(fieldSelection_, names)); @@ -199,11 +209,11 @@ void Foam::sampledSurfaces::sampleAndWrite(const IOobjectList& objects) IOobject ( fieldName, - mesh_.time().timeName(), - mesh_, + mesh.time().timeName(), + mesh, IOobject::MUST_READ ), - mesh_ + mesh ); sampleAndWrite(fld); @@ -212,7 +222,7 @@ void Foam::sampledSurfaces::sampleAndWrite(const IOobjectList& objects) { sampleAndWrite ( - mesh_.thisDb().lookupObject<GeoField>(fieldName) + mesh.thisDb().lookupObject<GeoField>(fieldName) ); } } diff --git a/src/sampling/sampledSurface/writers/boundaryData/boundaryDataSurfaceWriter.C b/src/sampling/sampledSurface/writers/boundaryData/boundaryDataSurfaceWriter.C new file mode 100644 index 0000000000000000000000000000000000000000..076a9a42260dc1ecf0c4894d903fd4dcfc2c2574 --- /dev/null +++ b/src/sampling/sampledSurface/writers/boundaryData/boundaryDataSurfaceWriter.C @@ -0,0 +1,117 @@ +/*---------------------------------------------------------------------------*\ + ========= | + \\ / F ield | OpenFOAM: The Open Source CFD Toolbox + \\ / O peration | + \\ / A nd | Copyright (C) 2015 OpenFOAM Foundation + \\/ M anipulation | +------------------------------------------------------------------------------- +License + This file is part of OpenFOAM. + + OpenFOAM is free software: you can redistribute it and/or modify it + under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + OpenFOAM is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + for more details. + + You should have received a copy of the GNU General Public License + along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>. + +\*---------------------------------------------------------------------------*/ + +#include "boundaryDataSurfaceWriter.H" +#include "makeSurfaceWriterMethods.H" + +// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * // + +namespace Foam +{ + makeSurfaceWriterType(boundaryDataSurfaceWriter); +} + +// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * // + +Foam::boundaryDataSurfaceWriter::boundaryDataSurfaceWriter() +: + surfaceWriter() +{} + + +// * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * // + +Foam::boundaryDataSurfaceWriter::~boundaryDataSurfaceWriter() +{} + + +// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * // + +Foam::fileName Foam::boundaryDataSurfaceWriter::write +( + const fileName& outputDir, + const fileName& surfaceName, + const pointField& points, + const faceList& faces, + const bool verbose +) const +{ + const fileName baseDir(outputDir.path()/surfaceName); + const fileName timeName(outputDir.name()); + + + // Construct dummy time to use as an objectRegistry + const fileName caseDir(getEnv("FOAM_CASE")); + Time dummyTime + ( + caseDir.path(), //rootPath, + caseDir.name(), //caseName, + "system", //systemName, + "constant", //constantName, + false //enableFunctionObjects + ); + + + // Write points + if (verbose) + { + Info<< "Writing points to " << baseDir/"points" << endl; + } + + pointIOField pts + ( + IOobject + ( + baseDir/"points", + dummyTime, + IOobject::NO_READ, + IOobject::NO_WRITE, + false + ), + points + ); + + { + // Do like regIOobject::writeObject but don't do instance() adaptation + // since this would write to e.g. 0/ instead of postProcessing/ + + // Try opening an OFstream for object + mkDir(pts.path()); + OFstream os(pts.objectPath()); + + pts.writeHeader(os); + pts.writeData(os); + pts.writeEndDivider(os); + } + + return baseDir; +} + + +// create write methods +defineSurfaceWriterWriteFields(Foam::boundaryDataSurfaceWriter); + + +// ************************************************************************* // diff --git a/src/sampling/sampledSurface/writers/boundaryData/boundaryDataSurfaceWriter.H b/src/sampling/sampledSurface/writers/boundaryData/boundaryDataSurfaceWriter.H new file mode 100644 index 0000000000000000000000000000000000000000..c58e073f36cdeb5695aa83ee79bef2b53c6cfa50 --- /dev/null +++ b/src/sampling/sampledSurface/writers/boundaryData/boundaryDataSurfaceWriter.H @@ -0,0 +1,222 @@ +/*---------------------------------------------------------------------------*\ + ========= | + \\ / F ield | OpenFOAM: The Open Source CFD Toolbox + \\ / O peration | + \\ / A nd | Copyright (C) 2015 OpenFOAM Foundation + \\/ M anipulation | +------------------------------------------------------------------------------- +License + This file is part of OpenFOAM. + + OpenFOAM is free software: you can redistribute it and/or modify it + under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + OpenFOAM is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + for more details. + + You should have received a copy of the GNU General Public License + along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>. + +Class + Foam::boundaryDataSurfaceWriter + +Description + A surfaceWriter for outputting to a form useable for the + timeVaryingMapped boundary condition. This reads the data from + constant/boundaryData/<patch> + + Typical way of working: + - use a sampledSurface of type 'patch' (to sample a patch): + surfaces + { + type surfaces; + surfaceFormat boundaryData; + fields ( p ); + surfaces + ( + outlet + { + type patch; + patches (outlet); + interpolate false; + } + ); + + - write using this writer. + - move postProcessing/surfaces/outlet to constant/boundaryData/outlet + in your destination case. + - use a timeVaryingMappedFixedValue bc to read&interpolate + the profile: + type timeVaryingMappedFixedValue; + setAverage false; // do not use read average + offset 0; // do not apply offset to values + + Note: + - with 'interpolate false' the data is on the face centres of the + patch. Take care that a 2D geometry will only have a single row + of face centres so might not provide a valid triangulation + (this is what timeVaryingMappedFixedValue uses to do interpolation) + (Alternatively use timeVaryingMappedFixedValue with mapMethod 'nearest') + + +SourceFiles + boundaryDataSurfaceWriter.C + +\*---------------------------------------------------------------------------*/ + +#ifndef boundaryDataSurfaceWriter_H +#define boundaryDataSurfaceWriter_H + +#include "surfaceWriter.H" + + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +namespace Foam +{ + +/*---------------------------------------------------------------------------*\ + Class boundaryDataSurfaceWriter Declaration +\*---------------------------------------------------------------------------*/ + +class boundaryDataSurfaceWriter +: + public surfaceWriter +{ + // Private Member Functions + + //- Templated write operation + template<class Type> + fileName writeTemplate + ( + const fileName& outputDir, + const fileName& surfaceName, + const pointField& points, + const faceList& faces, + const word& fieldName, + const Field<Type>& values, + const bool isNodeValues, + const bool verbose + ) const; + + +public: + + //- Runtime type information + TypeName("boundaryData"); + + + // Constructors + + //- Construct null + boundaryDataSurfaceWriter(); + + + //- Destructor + virtual ~boundaryDataSurfaceWriter(); + + + // Member Functions + + //- Write single surface geometry to file. + virtual fileName write + ( + const fileName& outputDir, + const fileName& surfaceName, + const pointField& points, + const faceList& faces, + const bool verbose = false + ) const; + + + //- Write scalarField for a single surface to file. + // One value per face or vertex (isNodeValues = true) + virtual fileName write + ( + const fileName& outputDir, // <case>/surface/TIME + const fileName& surfaceName, // name of surface + const pointField& points, + const faceList& faces, + const word& fieldName, // name of field + const Field<scalar>& values, + const bool isNodeValues, + const bool verbose = false + ) const; + + //- Write vectorField for a single surface to file. + // One value per face or vertex (isNodeValues = true) + virtual fileName write + ( + const fileName& outputDir, // <case>/surface/TIME + const fileName& surfaceName, // name of surface + const pointField& points, + const faceList& faces, + const word& fieldName, // name of field + const Field<vector>& values, + const bool isNodeValues, + const bool verbose = false + ) const; + + //- Write sphericalTensorField for a single surface to file. + // One value per face or vertex (isNodeValues = true) + virtual fileName write + ( + const fileName& outputDir, // <case>/surface/TIME + const fileName& surfaceName, // name of surface + const pointField& points, + const faceList& faces, + const word& fieldName, // name of field + const Field<sphericalTensor>& values, + const bool isNodeValues, + const bool verbose = false + ) const; + + //- Write symmTensorField for a single surface to file. + // One value per face or vertex (isNodeValues = true) + virtual fileName write + ( + const fileName& outputDir, // <case>/surface/TIME + const fileName& surfaceName, // name of surface + const pointField& points, + const faceList& faces, + const word& fieldName, // name of field + const Field<symmTensor>& values, + const bool isNodeValues, + const bool verbose = false + ) const; + + //- Write tensorField for a single surface to file. + // One value per face or vertex (isNodeValues = true) + virtual fileName write + ( + const fileName& outputDir, // <case>/surface/TIME + const fileName& surfaceName, // name of surface + const pointField& points, + const faceList& faces, + const word& fieldName, // name of field + const Field<tensor>& values, + const bool isNodeValues, + const bool verbose = false + ) const; +}; + + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +} // End namespace Foam + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +#ifdef NoRepository + #include "boundaryDataSurfaceWriterTemplates.C" +#endif + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +#endif + +// ************************************************************************* // diff --git a/src/sampling/sampledSurface/writers/boundaryData/boundaryDataSurfaceWriterTemplates.C b/src/sampling/sampledSurface/writers/boundaryData/boundaryDataSurfaceWriterTemplates.C new file mode 100644 index 0000000000000000000000000000000000000000..dd2edd5d93c521026541ec27307a48ede9383740 --- /dev/null +++ b/src/sampling/sampledSurface/writers/boundaryData/boundaryDataSurfaceWriterTemplates.C @@ -0,0 +1,146 @@ +/*---------------------------------------------------------------------------*\ + ========= | + \\ / F ield | OpenFOAM: The Open Source CFD Toolbox + \\ / O peration | + \\ / A nd | Copyright (C) 2015 OpenFOAM Foundation + \\/ M anipulation | +------------------------------------------------------------------------------- +License + This file is part of OpenFOAM. + + OpenFOAM is free software: you can redistribute it and/or modify i + under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + OpenFOAM is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + for more details. + + You should have received a copy of the GNU General Public License + along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>. + +\*---------------------------------------------------------------------------*/ + +#include "OFstream.H" +#include "OSspecific.H" +#include "IOmanip.H" +#include "Time.H" +#include "pointIOField.H" +#include "AverageIOField.H" +#include "primitivePatch.H" + +// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * // + +template<class Type> +Foam::fileName Foam::boundaryDataSurfaceWriter::writeTemplate +( + const fileName& outputDir, + const fileName& surfaceName, + const pointField& points, + const faceList& faces, + const word& fieldName, + const Field<Type>& values, + const bool isNodeValues, + const bool verbose +) const +{ + const fileName baseDir(outputDir.path()/surfaceName); + const fileName timeName(outputDir.name()); + + + // Construct dummy time to use as an objectRegistry + const fileName caseDir(getEnv("FOAM_CASE")); + Time dummyTime + ( + caseDir.path(), //rootPath, + caseDir.name(), //caseName, + "system", //systemName, + "constant", //constantName, + false //enableFunctionObjects + ); + + + // Write points + + pointIOField pts + ( + IOobject + ( + baseDir/"points", + dummyTime, + IOobject::NO_READ, + IOobject::NO_WRITE, + false + ), + 0 + ); + + if (isNodeValues) + { + if (verbose) + { + Info<< "Writing points to " << baseDir/"points" << endl; + } + pts = points; + } + else + { + if (verbose) + { + Info<< "Writing face centres to " << baseDir/"points" << endl; + } + + primitivePatch pp(SubList<face>(faces, faces.size()), points); + + pts = pp.faceCentres(); + } + + { + // Do like regIOobject::writeObject but don't do instance() adaptation + // since this would write to e.g. 0/ instead of postProcessing/ + + // Try opening an OFstream for object + mkDir(pts.path()); + OFstream os(pts.objectPath()); + + pts.writeHeader(os); + pts.writeData(os); + pts.writeEndDivider(os); + } + + + // Write field + { + AverageIOField<Type> vals + ( + IOobject + ( + baseDir/timeName/fieldName, + dummyTime, + IOobject::NO_READ, + IOobject::NO_WRITE, + false + ), + pTraits<Type>::zero, + values + ); + + // Do like regIOobject::writeObject but don't do instance() adaptation + // since this would write to e.g. 0/ instead of postProcessing/ + + // Try opening an OFstream for object + mkDir(vals.path()); + OFstream os(vals.objectPath()); + + vals.writeHeader(os); + vals.writeData(os); + vals.writeEndDivider(os); + } + + return baseDir; +} + + +// ************************************************************************* // diff --git a/src/sampling/sampledSurface/writers/dx/dxSurfaceWriter.C b/src/sampling/sampledSurface/writers/dx/dxSurfaceWriter.C index c95a7aed65c5fd60d577c60c2d0cbaa5f42bc415..05029018d4ad335c51b91ac51bbe07dd080bd572 100644 --- a/src/sampling/sampledSurface/writers/dx/dxSurfaceWriter.C +++ b/src/sampling/sampledSurface/writers/dx/dxSurfaceWriter.C @@ -3,7 +3,7 @@ \\ / F ield | OpenFOAM: The Open Source CFD Toolbox \\ / O peration | \\ / A nd | Copyright (C) 2011 OpenFOAM Foundation - \\/ M anipulation | + \\/ M anipulation | Copyright (C) 2015 OpenCFD Ltd ------------------------------------------------------------------------------- License This file is part of OpenFOAM. @@ -24,10 +24,6 @@ License \*---------------------------------------------------------------------------*/ #include "dxSurfaceWriter.H" - -#include "OFstream.H" -#include "OSspecific.H" - #include "makeSurfaceWriterMethods.H" // * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * // @@ -215,58 +211,6 @@ namespace Foam } -// arbitrary field -template<class Type> -inline void Foam::dxSurfaceWriter::writeData -( - Ostream& os, - const Field<Type>& values -) -{ - os << "object 3 class array type float rank 0 items " - << values.size() << " data follows" << nl; - - forAll(values, elemI) - { - os << float(0.0) << nl; - } -} - - -template<class Type> -void Foam::dxSurfaceWriter::writeTemplate -( - const fileName& outputDir, - const fileName& surfaceName, - const pointField& points, - const faceList& faces, - const word& fieldName, - const Field<Type>& values, - const bool isNodeValues, - const bool verbose -) const -{ - if (!isDir(outputDir)) - { - mkDir(outputDir); - } - - OFstream os - ( - outputDir/fieldName + '_' + surfaceName + ".dx" - ); - - if (verbose) - { - Info<< "Writing field " << fieldName << " to " << os.name() << endl; - } - - writeGeometry(os, points, faces); - writeData(os, values); - writeTrailer(os, isNodeValues); -} - - // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * // Foam::dxSurfaceWriter::dxSurfaceWriter() diff --git a/src/sampling/sampledSurface/writers/dx/dxSurfaceWriter.H b/src/sampling/sampledSurface/writers/dx/dxSurfaceWriter.H index 3b4f2fd6d1ba2551afe7add4cf09c3bf4fd9a34d..047c3d65175d95acb914c961b9527cb8e5b499dc 100644 --- a/src/sampling/sampledSurface/writers/dx/dxSurfaceWriter.H +++ b/src/sampling/sampledSurface/writers/dx/dxSurfaceWriter.H @@ -3,7 +3,7 @@ \\ / F ield | OpenFOAM: The Open Source CFD Toolbox \\ / O peration | \\ / A nd | Copyright (C) 2011 OpenFOAM Foundation - \\/ M anipulation | + \\/ M anipulation | Copyright (C) 2015 OpenCFD Ltd ------------------------------------------------------------------------------- License This file is part of OpenFOAM. @@ -61,7 +61,7 @@ class dxSurfaceWriter //- Templated write operation template<class Type> - void writeTemplate + fileName writeTemplate ( const fileName& outputDir, const fileName& surfaceName, @@ -94,7 +94,7 @@ public: //- Write scalarField for a single surface to file. // One value per face or vertex (isNodeValues = true) - virtual void write + virtual fileName write ( const fileName& outputDir, // <case>/surface/TIME const fileName& surfaceName, // name of surface @@ -108,7 +108,7 @@ public: //- Write vectorField for a single surface to file. // One value per face or vertex (isNodeValues = true) - virtual void write + virtual fileName write ( const fileName& outputDir, // <case>/surface/TIME const fileName& surfaceName, // name of surface @@ -122,7 +122,7 @@ public: //- Write sphericalTensorField for a single surface to file. // One value per face or vertex (isNodeValues = true) - virtual void write + virtual fileName write ( const fileName& outputDir, // <case>/surface/TIME const fileName& surfaceName, // name of surface @@ -136,7 +136,7 @@ public: //- Write symmTensorField for a single surface to file. // One value per face or vertex (isNodeValues = true) - virtual void write + virtual fileName write ( const fileName& outputDir, // <case>/surface/TIME const fileName& surfaceName, // name of surface @@ -150,7 +150,7 @@ public: //- Write tensorField for a single surface to file. // One value per face or vertex (isNodeValues = true) - virtual void write + virtual fileName write ( const fileName& outputDir, // <case>/surface/TIME const fileName& surfaceName, // name of surface @@ -161,7 +161,6 @@ public: const bool isNodeValues, const bool verbose = false ) const; - }; @@ -171,6 +170,12 @@ public: // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // +#ifdef NoRepository + #include "dxSurfaceWriterTemplates.C" +#endif + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + #endif // ************************************************************************* // diff --git a/src/sampling/sampledSurface/writers/dx/dxSurfaceWriterTemplates.C b/src/sampling/sampledSurface/writers/dx/dxSurfaceWriterTemplates.C new file mode 100644 index 0000000000000000000000000000000000000000..cd3c11a04c9868ccc04409ba43c3f65a95306068 --- /dev/null +++ b/src/sampling/sampledSurface/writers/dx/dxSurfaceWriterTemplates.C @@ -0,0 +1,81 @@ +/*---------------------------------------------------------------------------*\ + ========= | + \\ / F ield | OpenFOAM: The Open Source CFD Toolbox + \\ / O peration | + \\ / A nd | Copyright (C) 2011-2014 OpenFOAM Foundation + \\/ M anipulation | Copyright (C) 2015 OpenCFD Ltd +------------------------------------------------------------------------------- +License + This file is part of OpenFOAM. + + OpenFOAM is free software: you can redistribute it and/or modify it + under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + OpenFOAM is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + for more details. + + You should have received a copy of the GNU General Public License + along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>. + +\*---------------------------------------------------------------------------*/ + +#include "OFstream.H" +#include "OSspecific.H" + +// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * // + +template<class Type> +inline void Foam::dxSurfaceWriter::writeData +( + Ostream& os, + const Field<Type>& values +) +{ + os << "object 3 class array type float rank 0 items " + << values.size() << " data follows" << nl; + + forAll(values, elemI) + { + os << float(0.0) << nl; + } +} + + +template<class Type> +Foam::fileName Foam::dxSurfaceWriter::writeTemplate +( + const fileName& outputDir, + const fileName& surfaceName, + const pointField& points, + const faceList& faces, + const word& fieldName, + const Field<Type>& values, + const bool isNodeValues, + const bool verbose +) const +{ + if (!isDir(outputDir)) + { + mkDir(outputDir); + } + + OFstream os(outputDir/fieldName + '_' + surfaceName + ".dx"); + + if (verbose) + { + Info<< "Writing field " << fieldName << " to " << os.name() << endl; + } + + writeGeometry(os, points, faces); + writeData(os, values); + writeTrailer(os, isNodeValues); + + return os.name(); +} + + +// ************************************************************************* // diff --git a/src/sampling/sampledSurface/writers/ensight/ensightSurfaceWriter.C b/src/sampling/sampledSurface/writers/ensight/ensightSurfaceWriter.C index 5e2ab171145186f084469424d9cedcb29151d22e..0df2913efce0ba0f0a7fefc7133270b16e93c4c2 100644 --- a/src/sampling/sampledSurface/writers/ensight/ensightSurfaceWriter.C +++ b/src/sampling/sampledSurface/writers/ensight/ensightSurfaceWriter.C @@ -3,7 +3,7 @@ \\ / F ield | OpenFOAM: The Open Source CFD Toolbox \\ / O peration | \\ / A nd | Copyright (C) 2011-2013 OpenFOAM Foundation - \\/ M anipulation | + \\/ M anipulation | Copyright (C) 2015 OpenCFD Ltd ------------------------------------------------------------------------------- License This file is part of OpenFOAM. @@ -24,13 +24,7 @@ License \*---------------------------------------------------------------------------*/ #include "ensightSurfaceWriter.H" - -#include "OFstream.H" -#include "OSspecific.H" -#include "IOmanip.H" #include "ensightPartFaces.H" -#include "ensightPTraits.H" - #include "makeSurfaceWriterMethods.H" // * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * // @@ -42,83 +36,13 @@ namespace Foam } -// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * // - -template<class Type> -void Foam::ensightSurfaceWriter::writeTemplate -( - const fileName& outputDir, - const fileName& surfaceName, - const pointField& points, - const faceList& faces, - const word& fieldName, - const Field<Type>& values, - const bool isNodeValues, - const bool verbose -) const -{ - if (!isDir(outputDir/fieldName)) - { - mkDir(outputDir/fieldName); - } - - // const scalar timeValue = Foam::name(this->mesh().time().timeValue()); - const scalar timeValue = 0.0; - - OFstream osCase(outputDir/fieldName/surfaceName + ".case"); - ensightGeoFile osGeom - ( - outputDir/fieldName/surfaceName + ".000.mesh", - writeFormat_ - ); - ensightFile osField - ( - outputDir/fieldName/surfaceName + ".000." + fieldName, - writeFormat_ - ); - - if (verbose) - { - Info<< "Writing case file to " << osCase.name() << endl; - } - - osCase - << "FORMAT" << nl - << "type: ensight gold" << nl - << nl - << "GEOMETRY" << nl - << "model: 1 " << osGeom.name().name() << nl - << nl - << "VARIABLE" << nl - << ensightPTraits<Type>::typeName << " per " - << word(isNodeValues ? "node:" : "element:") << setw(10) << 1 - << " " << fieldName - << " " << surfaceName.c_str() << ".***." << fieldName << nl - << nl - << "TIME" << nl - << "time set: 1" << nl - << "number of steps: 1" << nl - << "filename start number: 0" << nl - << "filename increment: 1" << nl - << "time values:" << nl - << timeValue << nl - << nl; - - ensightPartFaces ensPart(0, osGeom.name().name(), points, faces, true); - osGeom << ensPart; - - // Write field - osField.writeKeyword(ensightPTraits<Type>::typeName); - ensPart.writeField(osField, values, isNodeValues); -} - - // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * // Foam::ensightSurfaceWriter::ensightSurfaceWriter() : surfaceWriter(), - writeFormat_(IOstream::ASCII) + writeFormat_(IOstream::ASCII), + collateTimes_(false) {} @@ -132,6 +56,7 @@ Foam::ensightSurfaceWriter::ensightSurfaceWriter(const dictionary& options) { writeFormat_ = IOstream::formatEnum(options.lookup("format")); } + options.readIfPresent("collateTimes", collateTimes_); } @@ -143,7 +68,7 @@ Foam::ensightSurfaceWriter::~ensightSurfaceWriter() // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * // -void Foam::ensightSurfaceWriter::write +Foam::fileName Foam::ensightSurfaceWriter::write ( const fileName& outputDir, const fileName& surfaceName, @@ -163,7 +88,7 @@ void Foam::ensightSurfaceWriter::write OFstream osCase(outputDir/surfaceName + ".case"); ensightGeoFile osGeom ( - outputDir/surfaceName + ".000.mesh", + outputDir/surfaceName + ".0000.mesh", writeFormat_ ); @@ -190,6 +115,8 @@ void Foam::ensightSurfaceWriter::write ensightPartFaces ensPart(0, osGeom.name().name(), points, faces, true); osGeom << ensPart; + + return osCase.name(); } diff --git a/src/sampling/sampledSurface/writers/ensight/ensightSurfaceWriter.H b/src/sampling/sampledSurface/writers/ensight/ensightSurfaceWriter.H index b1cd9d019f3e0de27f400d256afe7feda0033f8f..773a86ee5577f4d949a02be61ed54d9488b205a0 100644 --- a/src/sampling/sampledSurface/writers/ensight/ensightSurfaceWriter.H +++ b/src/sampling/sampledSurface/writers/ensight/ensightSurfaceWriter.H @@ -3,7 +3,7 @@ \\ / F ield | OpenFOAM: The Open Source CFD Toolbox \\ / O peration | \\ / A nd | Copyright (C) 2011 OpenFOAM Foundation - \\/ M anipulation | + \\/ M anipulation | Copyright (C) 2015 OpenCFD Ltd ------------------------------------------------------------------------------- License This file is part of OpenFOAM. @@ -55,12 +55,42 @@ class ensightSurfaceWriter //- Write option (default is IOstream::ASCII IOstream::streamFormat writeFormat_; + bool collateTimes_; + // Private Member Functions + //- Templated write operation - one file per timestep + template<class Type> + fileName writeCollated + ( + const fileName& outputDir, + const fileName& surfaceName, + const pointField& points, + const faceList& faces, + const word& fieldName, + const Field<Type>& values, + const bool isNodeValues, + const bool verbose + ) const; + + //- Templated write operation - all time steps in single file + template<class Type> + fileName writeUncollated + ( + const fileName& outputDir, + const fileName& surfaceName, + const pointField& points, + const faceList& faces, + const word& fieldName, + const Field<Type>& values, + const bool isNodeValues, + const bool verbose + ) const; + //- Templated write operation template<class Type> - void writeTemplate + fileName writeTemplate ( const fileName& outputDir, const fileName& surfaceName, @@ -96,14 +126,14 @@ public: //- True if the surface format supports geometry in a separate file. // False if geometry and field must be in a single file - virtual bool separateGeometry() + virtual bool separateGeometry() const { - return true; + return !collateTimes_; } //- Write single surface geometry to file. - virtual void write + virtual fileName write ( const fileName& outputDir, const fileName& surfaceName, @@ -115,7 +145,7 @@ public: //- Write scalarField for a single surface to file. // One value per face or vertex (isNodeValues = true) - virtual void write + virtual fileName write ( const fileName& outputDir, // <case>/surface/TIME const fileName& surfaceName, // name of surface @@ -129,7 +159,7 @@ public: //- Write vectorField for a single surface to file. // One value per face or vertex (isNodeValues = true) - virtual void write + virtual fileName write ( const fileName& outputDir, // <case>/surface/TIME const fileName& surfaceName, // name of surface @@ -143,7 +173,7 @@ public: //- Write sphericalTensorField for a single surface to file. // One value per face or vertex (isNodeValues = true) - virtual void write + virtual fileName write ( const fileName& outputDir, // <case>/surface/TIME const fileName& surfaceName, // name of surface @@ -157,7 +187,7 @@ public: //- Write symmTensorField for a single surface to file. // One value per face or vertex (isNodeValues = true) - virtual void write + virtual fileName write ( const fileName& outputDir, // <case>/surface/TIME const fileName& surfaceName, // name of surface @@ -171,7 +201,7 @@ public: //- Write tensorField for a single surface to file. // One value per face or vertex (isNodeValues = true) - virtual void write + virtual fileName write ( const fileName& outputDir, // <case>/surface/TIME const fileName& surfaceName, // name of surface @@ -182,7 +212,6 @@ public: const bool isNodeValues, const bool verbose = false ) const; - }; @@ -192,6 +221,12 @@ public: // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // +#ifdef NoRepository + #include "ensightSurfaceWriterTemplates.C" +#endif + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + #endif // ************************************************************************* // diff --git a/src/sampling/sampledSurface/writers/ensight/ensightSurfaceWriterTemplates.C b/src/sampling/sampledSurface/writers/ensight/ensightSurfaceWriterTemplates.C new file mode 100644 index 0000000000000000000000000000000000000000..2a1fea54133ae89fbfd65796a3126d1d3b100cc4 --- /dev/null +++ b/src/sampling/sampledSurface/writers/ensight/ensightSurfaceWriterTemplates.C @@ -0,0 +1,339 @@ +/*---------------------------------------------------------------------------*\ + ========= | + \\ / F ield | OpenFOAM: The Open Source CFD Toolbox + \\ / O peration | + \\ / A nd | Copyright (C) 2011-2014 OpenFOAM Foundation + \\/ M anipulation | Copyright (C) 2015 OpenCFD Ltd +------------------------------------------------------------------------------- +License + This file is part of OpenFOAM. + + OpenFOAM is free software: you can redistribute it and/or modify it + under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + OpenFOAM is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + for more details. + + You should have received a copy of the GNU General Public License + along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>. + +\*---------------------------------------------------------------------------*/ + +#include "IOmanip.H" +#include "IFstream.H" +#include "OFstream.H" +#include "OSspecific.H" +#include "ensightPartFaces.H" +#include "ensightPTraits.H" +#include "OStringStream.H" +#include "regExp.H" + +// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * // + +template<class Type> +Foam::fileName Foam::ensightSurfaceWriter::writeUncollated +( + const fileName& outputDir, + const fileName& surfaceName, + const pointField& points, + const faceList& faces, + const word& fieldName, + const Field<Type>& values, + const bool isNodeValues, + const bool verbose +) const +{ + if (!isDir(outputDir/fieldName)) + { + mkDir(outputDir/fieldName); + } + + // const scalar timeValue = Foam::name(this->mesh().time().timeValue()); + const scalar timeValue = 0.0; + + OFstream osCase(outputDir/fieldName/surfaceName + ".case"); + ensightGeoFile osGeom + ( + outputDir/fieldName/surfaceName + ".0000.mesh", + writeFormat_ + ); + ensightFile osField + ( + outputDir/fieldName/surfaceName + ".0000." + fieldName, + writeFormat_ + ); + + if (verbose) + { + Info<< "Writing case file to " << osCase.name() << endl; + } + + osCase + << "FORMAT" << nl + << "type: ensight gold" << nl + << nl + << "GEOMETRY" << nl + << "model: 1 " << osGeom.name().name() << nl + << nl + << "VARIABLE" << nl + << ensightPTraits<Type>::typeName << " per " + << word(isNodeValues ? "node:" : "element:") << setw(10) << 1 + << " " << fieldName + << " " << surfaceName.c_str() << ".****." << fieldName << nl + << nl + << "TIME" << nl + << "time set: 1" << nl + << "number of steps: 1" << nl + << "filename start number: 0" << nl + << "filename increment: 1" << nl + << "time values:" << nl + << timeValue << nl + << nl; + + ensightPartFaces ensPart(0, osGeom.name().name(), points, faces, true); + osGeom << ensPart; + + // Write field + osField.writeKeyword(ensightPTraits<Type>::typeName); + ensPart.writeField(osField, values, isNodeValues); + + return osCase.name(); +} + + +template<class Type> +Foam::fileName Foam::ensightSurfaceWriter::writeCollated +( + const fileName& outputDir, + const fileName& surfaceName, + const pointField& points, + const faceList& faces, + const word& fieldName, + const Field<Type>& values, + const bool isNodeValues, + const bool verbose +) const +{ + + const fileName baseDir = outputDir.path()/surfaceName; + const fileName timeDir = outputDir.name(); + + if (!isDir(baseDir)) + { + mkDir(baseDir); + } + + const fileName meshFile(baseDir/surfaceName + ".0000.mesh"); + const scalar timeValue = readScalar(IStringStream(timeDir)()); + label timeIndex = 0; + + + // Do case file + { + dictionary dict; + scalarList times; + bool stateChanged = false; + + if (isFile(baseDir/"fieldsDict")) + { + IFstream is(baseDir/"fieldsDict"); + if (is.good() && dict.read(is)) + { + dict.lookup("times") >> times; + const scalar timeValue = readScalar(IStringStream(timeDir)()); + label index = findLower(times, timeValue); + timeIndex = index+1; + } + } + + + // Update stored times list + times.setSize(timeIndex+1, -1); + + if (times[timeIndex] != timeValue) + { + stateChanged = true; + } + times[timeIndex] = timeValue; + + + // Add my information to dictionary + { + dict.set("times", times); + if (dict.found("fields")) + { + dictionary& fieldsDict = dict.subDict("fields"); + if (!fieldsDict.found(fieldName)) + { + dictionary fieldDict; + fieldDict.set("type", ensightPTraits<Type>::typeName); + fieldsDict.set(fieldName, fieldDict); + + stateChanged = true; + } + } + else + { + dictionary fieldDict; + fieldDict.set("type", ensightPTraits<Type>::typeName); + + dictionary fieldsDict; + fieldsDict.set(fieldName, fieldDict); + + dict.set("fields", fieldsDict); + + stateChanged = true; + } + } + + + if (stateChanged) + { + if (verbose) + { + Info<< "Writing state file to fieldsDict" << endl; + } + OFstream os(baseDir/"fieldsDict"); + os << dict; + + + OFstream osCase(baseDir/surfaceName + ".case"); + + if (verbose) + { + Info<< "Writing case file to " << osCase.name() << endl; + } + + osCase + << "FORMAT" << nl + << "type: ensight gold" << nl + << nl + << "GEOMETRY" << nl + << "model: 1 " << meshFile.name() << nl + << nl + << "VARIABLE" << nl; + const dictionary& fieldsDict = dict.subDict("fields"); + forAllConstIter(dictionary, fieldsDict, iter) + { + const word& fieldName = iter().keyword(); + const word fieldType(iter().dict().lookup("type")); + + osCase + << fieldType << " per " + << word(isNodeValues ? "node:" : "element:") + << setw(10) << 1 + << setw(15) << fieldName + << " " << surfaceName.c_str() << ".****." << fieldName + << nl; + } + osCase << nl; + + osCase + << "TIME" << nl + << "time set: 1" << nl + << "number of steps: " << timeIndex+1 << nl + << "filename start number: 0" << nl + << "filename increment: 1" << nl + << "time values:" << nl; + forAll(times, timeI) + { + osCase << setw(12) << times[timeI] << " "; + + if (timeI != 0 && (timeI % 6) == 0) + { + osCase << nl; + } + } + osCase << nl; + } + } + + + // Write geometry + ensightPartFaces ensPart(0, meshFile.name(), points, faces, true); + if (!exists(meshFile)) + { + if (verbose) + { + Info<< "Writing mesh file to " << meshFile.name() << endl; + } + ensightGeoFile osGeom(meshFile, writeFormat_); + osGeom << ensPart; + } + + + // Get string representation + string timeString; + { + OStringStream os; + os.stdStream().fill('0'); + os << setw(4) << timeIndex; + timeString = os.str(); + } + + // Write field + ensightFile osField + ( + baseDir/surfaceName + "." + timeString + "." + fieldName, + writeFormat_ + ); + if (verbose) + { + Info<< "Writing field file to " << osField.name() << endl; + } + osField.writeKeyword(ensightPTraits<Type>::typeName); + ensPart.writeField(osField, values, isNodeValues); + + return baseDir/surfaceName + ".case"; +} + + +template<class Type> +Foam::fileName Foam::ensightSurfaceWriter::writeTemplate +( + const fileName& outputDir, + const fileName& surfaceName, + const pointField& points, + const faceList& faces, + const word& fieldName, + const Field<Type>& values, + const bool isNodeValues, + const bool verbose +) const +{ + if (collateTimes_) + { + return writeCollated + ( + outputDir, + surfaceName, + points, + faces, + fieldName, + values, + isNodeValues, + verbose + ); + } + else + { + return writeUncollated + ( + outputDir, + surfaceName, + points, + faces, + fieldName, + values, + isNodeValues, + verbose + ); + } +} + + +// ************************************************************************* // diff --git a/src/sampling/sampledSurface/writers/foamFile/foamFileSurfaceWriter.C b/src/sampling/sampledSurface/writers/foamFile/foamFileSurfaceWriter.C index e85450dce5184b2680daf92298a4e8e0ccbbee2a..fbff527c526f042400600b3b561dc54aaeef8ac0 100644 --- a/src/sampling/sampledSurface/writers/foamFile/foamFileSurfaceWriter.C +++ b/src/sampling/sampledSurface/writers/foamFile/foamFileSurfaceWriter.C @@ -3,7 +3,7 @@ \\ / F ield | OpenFOAM: The Open Source CFD Toolbox \\ / O peration | \\ / A nd | Copyright (C) 2011 OpenFOAM Foundation - \\/ M anipulation | + \\/ M anipulation | Copyright (C) 2015 OpenCFD Ltd ------------------------------------------------------------------------------- License This file is part of OpenFOAM. @@ -24,10 +24,6 @@ License \*---------------------------------------------------------------------------*/ #include "foamFileSurfaceWriter.H" - -#include "OFstream.H" -#include "OSspecific.H" - #include "makeSurfaceWriterMethods.H" // * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * // @@ -38,49 +34,6 @@ namespace Foam } -// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * // - -template<class Type> -void Foam::foamFileSurfaceWriter::writeTemplate -( - const fileName& outputDir, - const fileName& surfaceName, - const pointField& points, - const faceList& faces, - const word& fieldName, - const Field<Type>& values, - const bool isNodeValues, - const bool verbose -) const -{ - fileName surfaceDir(outputDir/surfaceName); - - if (!isDir(surfaceDir)) - { - mkDir(surfaceDir); - } - - if (verbose) - { - Info<< "Writing field " << fieldName << " to " << surfaceDir << endl; - } - - // geometry should already have been written - // Values to separate directory (e.g. "scalarField/p") - - fileName foamName(pTraits<Type>::typeName); - fileName valuesDir(surfaceDir / (foamName + Field<Type>::typeName)); - - if (!isDir(valuesDir)) - { - mkDir(valuesDir); - } - - // values - OFstream(valuesDir/fieldName)() << values; -} - - // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * // Foam::foamFileSurfaceWriter::foamFileSurfaceWriter() @@ -97,7 +50,7 @@ Foam::foamFileSurfaceWriter::~foamFileSurfaceWriter() // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * // -void Foam::foamFileSurfaceWriter::write +Foam::fileName Foam::foamFileSurfaceWriter::write ( const fileName& outputDir, const fileName& surfaceName, @@ -135,6 +88,8 @@ void Foam::foamFileSurfaceWriter::write } OFstream(surfaceDir/"faceCentres")() << faceCentres; + + return surfaceDir; } diff --git a/src/sampling/sampledSurface/writers/foamFile/foamFileSurfaceWriter.H b/src/sampling/sampledSurface/writers/foamFile/foamFileSurfaceWriter.H index 254dadcb4493de3a98070411de39e4bcd246c895..1149091771d92da4376bb242a4e3d6b66b2e2acb 100644 --- a/src/sampling/sampledSurface/writers/foamFile/foamFileSurfaceWriter.H +++ b/src/sampling/sampledSurface/writers/foamFile/foamFileSurfaceWriter.H @@ -3,7 +3,7 @@ \\ / F ield | OpenFOAM: The Open Source CFD Toolbox \\ / O peration | \\ / A nd | Copyright (C) 2011 OpenFOAM Foundation - \\/ M anipulation | + \\/ M anipulation | Copyright (C) 2015 OpenCFD Ltd ------------------------------------------------------------------------------- License This file is part of OpenFOAM. @@ -54,7 +54,7 @@ class foamFileSurfaceWriter //- Templated write operation template<class Type> - void writeTemplate + fileName writeTemplate ( const fileName& outputDir, const fileName& surfaceName, @@ -87,13 +87,13 @@ public: //- True if the surface format supports geometry in a separate file. // False if geometry and field must be in a single file - virtual bool separateGeometry() + virtual bool separateGeometry() const { return true; } //- Write single surface geometry to file. - virtual void write + virtual fileName write ( const fileName& outputDir, const fileName& surfaceName, @@ -105,7 +105,7 @@ public: //- Write scalarField for a single surface to file. // One value per face or vertex (isNodeValues = true) - virtual void write + virtual fileName write ( const fileName& outputDir, // <case>/surface/TIME const fileName& surfaceName, // name of surface @@ -119,7 +119,7 @@ public: //- Write vectorField for a single surface to file. // One value per face or vertex (isNodeValues = true) - virtual void write + virtual fileName write ( const fileName& outputDir, // <case>/surface/TIME const fileName& surfaceName, // name of surface @@ -133,7 +133,7 @@ public: //- Write sphericalTensorField for a single surface to file. // One value per face or vertex (isNodeValues = true) - virtual void write + virtual fileName write ( const fileName& outputDir, // <case>/surface/TIME const fileName& surfaceName, // name of surface @@ -147,7 +147,7 @@ public: //- Write symmTensorField for a single surface to file. // One value per face or vertex (isNodeValues = true) - virtual void write + virtual fileName write ( const fileName& outputDir, // <case>/surface/TIME const fileName& surfaceName, // name of surface @@ -161,7 +161,7 @@ public: //- Write tensorField for a single surface to file. // One value per face or vertex (isNodeValues = true) - virtual void write + virtual fileName write ( const fileName& outputDir, // <case>/surface/TIME const fileName& surfaceName, // name of surface @@ -172,7 +172,6 @@ public: const bool isNodeValues, const bool verbose = false ) const; - }; @@ -182,6 +181,12 @@ public: // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // +#ifdef NoRepository + #include "foamFileSurfaceWriterTemplates.C" +#endif + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + #endif // ************************************************************************* // diff --git a/src/sampling/sampledSurface/writers/foamFile/foamFileSurfaceWriterTemplates.C b/src/sampling/sampledSurface/writers/foamFile/foamFileSurfaceWriterTemplates.C new file mode 100644 index 0000000000000000000000000000000000000000..f87b2591d99a77274a5d7a83149d6f019ef6a1c2 --- /dev/null +++ b/src/sampling/sampledSurface/writers/foamFile/foamFileSurfaceWriterTemplates.C @@ -0,0 +1,74 @@ +/*---------------------------------------------------------------------------*\ + ========= | + \\ / F ield | OpenFOAM: The Open Source CFD Toolbox + \\ / O peration | + \\ / A nd | Copyright (C) 2011-2014 OpenFOAM Foundation + \\/ M anipulation | Copyright (C) 2015 OpenCFD Ltd +------------------------------------------------------------------------------- +License + This file is part of OpenFOAM. + + OpenFOAM is free software: you can redistribute it and/or modify it + under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + OpenFOAM is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + for more details. + + You should have received a copy of the GNU General Public License + along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>. + +\*---------------------------------------------------------------------------*/ + +#include "OFstream.H" +#include "OSspecific.H" + +// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * // + +template<class Type> +Foam::fileName Foam::foamFileSurfaceWriter::writeTemplate +( + const fileName& outputDir, + const fileName& surfaceName, + const pointField& points, + const faceList& faces, + const word& fieldName, + const Field<Type>& values, + const bool isNodeValues, + const bool verbose +) const +{ + fileName surfaceDir(outputDir/surfaceName); + + if (!isDir(surfaceDir)) + { + mkDir(surfaceDir); + } + + if (verbose) + { + Info<< "Writing field " << fieldName << " to " << surfaceDir << endl; + } + + // geometry should already have been written + // Values to separate directory (e.g. "scalarField/p") + + fileName foamName(pTraits<Type>::typeName); + fileName valuesDir(surfaceDir/(foamName + Field<Type>::typeName)); + + if (!isDir(valuesDir)) + { + mkDir(valuesDir); + } + + // values + OFstream(valuesDir/fieldName)() << values; + + return valuesDir/fieldName; +} + + +// ************************************************************************* // diff --git a/src/sampling/sampledSurface/writers/makeSurfaceWriterMethods.H b/src/sampling/sampledSurface/writers/makeSurfaceWriterMethods.H index 2f640fc2e0f9815be62b12b6eac195d0385f2c7b..16236bb8bf8f6d73dde78e7ecbf637078c4f80a4 100644 --- a/src/sampling/sampledSurface/writers/makeSurfaceWriterMethods.H +++ b/src/sampling/sampledSurface/writers/makeSurfaceWriterMethods.H @@ -3,7 +3,7 @@ \\ / F ield | OpenFOAM: The Open Source CFD Toolbox \\ / O peration | \\ / A nd | Copyright (C) 2011 OpenFOAM Foundation - \\/ M anipulation | + \\/ M anipulation | Copyright (C) 2015 OpenCFD Ltd ------------------------------------------------------------------------------- License This file is part of OpenFOAM. @@ -47,7 +47,7 @@ namespace Foam #define defineSurfaceWriterWriteField(ThisClass, FieldType) \ - void ThisClass::write \ + Foam::fileName ThisClass::write \ ( \ const fileName& outputDir, \ const fileName& surfaceName, \ @@ -59,7 +59,7 @@ namespace Foam const bool verbose \ ) const \ { \ - writeTemplate \ + return writeTemplate \ ( \ outputDir, \ surfaceName, \ diff --git a/src/sampling/sampledSurface/writers/nastran/nastranSurfaceWriter.C b/src/sampling/sampledSurface/writers/nastran/nastranSurfaceWriter.C index eaa16feb6b6f9fc520413d762049523e4af222af..8f5e0c8a79d3b92f82ff97af2b7d518f1f181fdb 100644 --- a/src/sampling/sampledSurface/writers/nastran/nastranSurfaceWriter.C +++ b/src/sampling/sampledSurface/writers/nastran/nastranSurfaceWriter.C @@ -3,7 +3,7 @@ \\ / F ield | OpenFOAM: The Open Source CFD Toolbox \\ / O peration | \\ / A nd | Copyright (C) 2012-2013 OpenFOAM Foundation - \\/ M anipulation | + \\/ M anipulation | Copyright (C) 2015 OpenCFD Ltd ------------------------------------------------------------------------------- License This file is part of OpenFOAM. @@ -35,7 +35,7 @@ namespace Foam makeSurfaceWriterType(nastranSurfaceWriter); addToRunTimeSelectionTable(surfaceWriter, nastranSurfaceWriter, wordDict); - // create write methods + // Create write methods defineSurfaceWriterWriteFields(nastranSurfaceWriter); template<> @@ -46,8 +46,19 @@ namespace Foam "free" }; + const NamedEnum<nastranSurfaceWriter::writeFormat, 3> nastranSurfaceWriter::writeFormatNames_; + + template<> + const char* NamedEnum<nastranSurfaceWriter::dataFormat, 2>::names[] = + { + "PLOAD2", + "PLOAD4" + }; + + const NamedEnum<nastranSurfaceWriter::dataFormat, 2> + nastranSurfaceWriter::dataFormatNames_; } @@ -57,7 +68,7 @@ void Foam::nastranSurfaceWriter::formatOS(OFstream& os) const { os.setf(ios_base::scientific); - // capitalise the E marker + // Capitalise the E marker os.setf(ios_base::uppercase); label prec = 0; @@ -65,11 +76,11 @@ void Foam::nastranSurfaceWriter::formatOS(OFstream& os) const switch (writeFormat_) { case (wfShort): - case (wfFree): { prec = 8 - offset; break; } + case (wfFree): case (wfLong): { prec = 16 - offset; @@ -84,6 +95,37 @@ void Foam::nastranSurfaceWriter::formatOS(OFstream& os) const } +void Foam::nastranSurfaceWriter::writeKeyword +( + const word& keyword, + Ostream& os +) const +{ + os.setf(ios_base::left); + + switch (writeFormat_) + { + case wfShort: + { + os << setw(8) << keyword; + break; + } + case wfLong: + { + os << setw(8) << word(keyword + '*'); + break; + } + case wfFree: + { + os << keyword; + break; + } + } + + os.unsetf(ios_base::left); +} + + void Foam::nastranSurfaceWriter::writeCoord ( const point& p, @@ -102,19 +144,27 @@ void Foam::nastranSurfaceWriter::writeCoord // 8 PS : single point constraints (blank) // 9 SEID : super-element ID + + writeKeyword("GRID", os); + + os << separator_; + + os.setf(ios_base::right); + + writeValue(pointI + 1, os); + os << separator_; + writeValue("", os); + os << separator_; + writeValue(p.x(), os); + os << separator_; + writeValue(p.y(), os); + os << separator_; + switch (writeFormat_) { case wfShort: { - os.setf(ios_base::left); - os << setw(8) << "GRID"; - os.unsetf(ios_base::left); - os.setf(ios_base::right); - os << setw(8) << pointI + 1 - << " " - << setw(8) << p.x() - << setw(8) << p.y() - << setw(8) << p.z() + os << setw(8) << p.z() << nl; os.unsetf(ios_base::right); @@ -122,35 +172,19 @@ void Foam::nastranSurfaceWriter::writeCoord } case wfLong: { - os.setf(ios_base::left); - os << setw(8) << "GRID*"; - os.unsetf(ios_base::left); - os.setf(ios_base::right); - os << setw(16) << pointI + 1 - << " " - << setw(16) << p.x() - << setw(16) << p.y() - << nl; + os << nl; os.unsetf(ios_base::right); - os.setf(ios_base::left); - os << setw(8) << "*"; - os.unsetf(ios_base::left); + writeKeyword("", os); os.setf(ios_base::right); - os << setw(16) << p.z() - << nl; - os.unsetf(ios_base::right); + writeValue(p.z(), os); + os << nl; break; } case wfFree: { - os << "GRID" - << ',' << pointI + 1 - << ',' - << ',' << p.x() - << ',' << p.y() - << ',' << p.z() - << nl; + writeValue(p.z(), os); + os << nl; break; } @@ -166,8 +200,11 @@ void Foam::nastranSurfaceWriter::writeCoord ) << "Unknown writeFormat enumeration" << abort(FatalError); } } + + os.unsetf(ios_base::right); } + void Foam::nastranSurfaceWriter::writeFace ( const word& faceType, @@ -190,67 +227,55 @@ void Foam::nastranSurfaceWriter::writeFace // For CTRIA3 elements, cols 7 onwards are not used + label PID = 1; + + writeKeyword(faceType, os); + + os << separator_; + + os.setf(ios_base::right); + + writeValue(nFace++, os); + + os << separator_; + + writeValue(PID, os); + switch (writeFormat_) { case wfShort: { - os.setf(ios_base::left); - os << setw(8) << faceType; - os.unsetf(ios_base::left); - os.setf(ios_base::right); - os << setw(8) << nFace++ - << " "; - forAll(facePts, i) { - os << setw(8) << facePts[i] + 1; + writeValue(facePts[i] + 1, os); } - os << nl; - os.unsetf(ios_base::right); - break; } case wfLong: { - os.setf(ios_base::left); - os << setw(8) << word(faceType + "*"); - os.unsetf(ios_base::left); - os.setf(ios_base::right); - os << setw(16) << nFace++ - << " "; - forAll(facePts, i) { - os << setw(16) << facePts[i] + 1; + writeValue(facePts[i] + 1, os); if (i == 1) { os << nl; os.unsetf(ios_base::right); - os.setf(ios_base::left); - os << setw(8) << "*"; - os.unsetf(ios_base::left); + writeKeyword("", os); os.setf(ios_base::right); } } - os << nl; - os.unsetf(ios_base::right); - break; } case wfFree: { - os << faceType << ',' - << ++nFace << ','; - forAll(facePts, i) { - os << ',' << facePts[i] + 1; + os << separator_; + writeValue(facePts[i] + 1, os); } - os << nl; - break; } default: @@ -268,6 +293,8 @@ void Foam::nastranSurfaceWriter::writeFace } } + os << nl; + os.unsetf(ios_base::right); } @@ -279,7 +306,7 @@ void Foam::nastranSurfaceWriter::writeGeometry OFstream& os ) const { - // write points + // Write points os << "$" << nl << "$ Points" << nl @@ -291,7 +318,7 @@ void Foam::nastranSurfaceWriter::writeGeometry } - // write faces + // Write faces os << "$" << nl << "$ Faces" << nl @@ -315,7 +342,7 @@ void Foam::nastranSurfaceWriter::writeGeometry } else { - // decompose poly face into tris + // Decompose poly face into tris label nTri = 0; faceList triFaces; f.triangles(points, nTri, triFaces); @@ -330,6 +357,42 @@ void Foam::nastranSurfaceWriter::writeGeometry } +void Foam::nastranSurfaceWriter::writeFooter(Ostream& os) const +{ + label PID = 1; + + writeKeyword("PSHELL", os); + + os << separator_; + + writeValue(PID, os); + + for (label i = 0; i < 7; i++) + { + // Dummy values + os << separator_; + writeValue(1, os); + } + + os << nl; + writeKeyword("MAT1", os); + os << separator_; + + label MID = 1; + + writeValue(MID, os); + + for (label i = 0; i < 7; i++) + { + // Dummy values + os << separator_; + writeValue("", os); + } + + os << nl; +} + + // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * // Foam::nastranSurfaceWriter::nastranSurfaceWriter() @@ -346,18 +409,26 @@ Foam::nastranSurfaceWriter::nastranSurfaceWriter(const dictionary& options) surfaceWriter(), writeFormat_(wfLong), fieldMap_(), - scale_(options.lookupOrDefault("scale", 1.0)) + scale_(options.lookupOrDefault("scale", 1.0)), + separator_("") { if (options.found("format")) { writeFormat_ = writeFormatNames_.read(options.lookup("format")); } + if (writeFormat_ == wfFree) + { + separator_ = ","; + } + List<Tuple2<word, word> > fieldSet(options.lookup("fields")); forAll(fieldSet, i) { - fieldMap_.insert(fieldSet[i].first(), fieldSet[i].second()); + dataFormat format = dataFormatNames_[fieldSet[i].second()]; + + fieldMap_.insert(fieldSet[i].first(), format); } } @@ -370,7 +441,7 @@ Foam::nastranSurfaceWriter::~nastranSurfaceWriter() // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * // -void Foam::nastranSurfaceWriter::write +Foam::fileName Foam::nastranSurfaceWriter::write ( const fileName& outputDir, const fileName& surfaceName, @@ -384,7 +455,7 @@ void Foam::nastranSurfaceWriter::write mkDir(outputDir); } - OFstream os(outputDir/surfaceName + ".dat"); + OFstream os(outputDir/surfaceName + ".nas"); formatOS(os); if (verbose) @@ -405,7 +476,11 @@ void Foam::nastranSurfaceWriter::write mkDir(outputDir); } + writeFooter(os); + os << "ENDDATA" << endl; + + return os.name(); } diff --git a/src/sampling/sampledSurface/writers/nastran/nastranSurfaceWriter.H b/src/sampling/sampledSurface/writers/nastran/nastranSurfaceWriter.H index e80383a3037765cebc6dee6cbe7d0dfa12c7ec5a..0d8f23fae885b170aba86d7adfc7758f63fd789c 100644 --- a/src/sampling/sampledSurface/writers/nastran/nastranSurfaceWriter.H +++ b/src/sampling/sampledSurface/writers/nastran/nastranSurfaceWriter.H @@ -3,7 +3,7 @@ \\ / F ield | OpenFOAM: The Open Source CFD Toolbox \\ / O peration | \\ / A nd | Copyright (C) 2012-2013 OpenFOAM Foundation - \\/ M anipulation | + \\/ M anipulation | Copyright (C) 2015 OpenCFD Ltd ------------------------------------------------------------------------------- License This file is part of OpenFOAM. @@ -32,7 +32,11 @@ Description nastran { // From OpenFOAM field name to Nastran field name - fields ((pMean PLOAD2)); + fields + ( + (pMean PLOAD2) + (p PLOAD4) + ); // Optional scale scale 2.0; // Optional format @@ -52,6 +56,7 @@ SourceFiles #include "surfaceWriter.H" #include "NamedEnum.H" #include "OFstream.H" +#include "HashTable.H" // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // @@ -77,6 +82,14 @@ public: static const NamedEnum<writeFormat, 3> writeFormatNames_; + enum dataFormat + { + dfPLOAD2, + dfPLOAD4 + }; + + static const NamedEnum<dataFormat, 2> dataFormatNames_; + private: @@ -85,12 +98,15 @@ private: //- Write option writeFormat writeFormat_; - //- Map of OpenFOAM field name vs nastran field name - HashTable<word> fieldMap_; + //- Mapping from field name to data format enumeration + HashTable<dataFormat, word> fieldMap_; //- Scale to apply to values (default = 1.0) scalar scale_; + //- Separator used for free format + word separator_; + // Private Member Functions @@ -123,19 +139,37 @@ private: OFstream& os ) const; + //- Write the formatted keyword to the output stream + void writeKeyword + ( + const word& keyword, + Ostream& os + ) const; + + //- Write the footer information + void writeFooter(Ostream& os) const; + + //- Write a formatted value to the output stream + template<class Type> + void writeValue + ( + const Type& value, + Ostream& os + ) const; + //- Write a face-based value template<class Type> void writeFaceValue ( - const word& nasFieldName, + const dataFormat& format, const Type& value, const label EID, - OFstream& os + Ostream& os ) const; //- Templated write operation template<class Type> - void writeTemplate + fileName writeTemplate ( const fileName& outputDir, const fileName& surfaceName, @@ -171,13 +205,13 @@ public: //- True if the surface format supports geometry in a separate file. // False if geometry and field must be in a single file - virtual bool separateGeometry() + virtual bool separateGeometry() const { return false; } //- Write single surface geometry to file. - virtual void write + virtual fileName write ( const fileName& outputDir, const fileName& surfaceName, @@ -188,7 +222,7 @@ public: //- Write scalarField for a single surface to file. // One value per face or vertex (isNodeValues = true) - virtual void write + virtual fileName write ( const fileName& outputDir, const fileName& surfaceName, @@ -202,7 +236,7 @@ public: //- Write vectorField for a single surface to file. // One value per face or vertex (isNodeValues = true) - virtual void write + virtual fileName write ( const fileName& outputDir, const fileName& surfaceName, @@ -216,7 +250,7 @@ public: //- Write sphericalTensorField for a single surface to file. // One value per face or vertex (isNodeValues = true) - virtual void write + virtual fileName write ( const fileName& outputDir, const fileName& surfaceName, @@ -230,7 +264,7 @@ public: //- Write symmTensorField for a single surface to file. // One value per face or vertex (isNodeValues = true) - virtual void write + virtual fileName write ( const fileName& outputDir, const fileName& surfaceName, @@ -244,7 +278,7 @@ public: //- Write tensorField for a single surface to file. // One value per face or vertex (isNodeValues = true) - virtual void write + virtual fileName write ( const fileName& outputDir, const fileName& surfaceName, diff --git a/src/sampling/sampledSurface/writers/nastran/nastranSurfaceWriterTemplates.C b/src/sampling/sampledSurface/writers/nastran/nastranSurfaceWriterTemplates.C index fe1e6a998aea64831e68d502dfebace5ad05c4d4..b4cc3d464d19f867ef344e777d7637b99aa3ef38 100644 --- a/src/sampling/sampledSurface/writers/nastran/nastranSurfaceWriterTemplates.C +++ b/src/sampling/sampledSurface/writers/nastran/nastranSurfaceWriterTemplates.C @@ -2,8 +2,8 @@ ========= | \\ / F ield | OpenFOAM: The Open Source CFD Toolbox \\ / O peration | - \\ / A nd | Copyright (C) 2012-2013 OpenFOAM Foundation - \\/ M anipulation | + \\ / A nd | Copyright (C) 2012-2015 OpenFOAM Foundation + \\/ M anipulation | Copyright (C) 2015 OpenCFD Ltd ------------------------------------------------------------------------------- License This file is part of OpenFOAM. @@ -29,93 +29,142 @@ License // * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * // +template<class Type> +void Foam::nastranSurfaceWriter::writeValue +( + const Type& value, + Ostream& os +) const +{ + switch (writeFormat_) + { + case wfShort: + { + os << setw(8) << value; + break; + } + case wfLong: + { + os << setw(16) << value; + break; + } + case wfFree: + { + os << value; + break; + } + } +} + + template<class Type> void Foam::nastranSurfaceWriter::writeFaceValue ( - const word& nasFieldName, + const dataFormat& format, const Type& value, const label EID, - OFstream& os + Ostream& os ) const { - // Fixed short/long formats: - // 1 Nastran distributed load type, e.g. PLOAD4 - // 2 SID : load set ID - // 3 EID : element ID - // 4 onwards: load values + // Fixed short/long formats supporting PLOAD2 and PLOAD4: + + // PLOAD2: + // 1 descriptor : PLOAD2 + // 2 SID : load set ID + // 3 data value : load value - MUST be singular + // 4 EID : element ID + + // PLOAD4: + // 1 descriptor : PLOAD4 + // 2 SID : load set ID + // 3 EID : element ID + // 4 onwards : load values label SID = 1; Type scaledValue = scale_*value; - switch (writeFormat_) - { - case wfShort: - { - os.setf(ios_base::left); - os << setw(8) << nasFieldName; - os.unsetf(ios_base::left); - os.setf(ios_base::right); - os << setw(8) << SID - << setw(8) << EID; + // Write Keyword + writeKeyword(dataFormatNames_[format], os); - for (direction dirI = 0; dirI < pTraits<Type>::nComponents; dirI++) - { - os << setw(8) << component(scaledValue, dirI); - } + os << separator_; - os.unsetf(ios_base::right); + // Write load set ID + os.setf(ios_base::right); + writeValue(SID, os); - break; - } - case wfLong: - { - os.setf(ios_base::left); - os << setw(8) << word(nasFieldName + "*"); - os.unsetf(ios_base::left); - os.setf(ios_base::right); - os << setw(16) << SID - << setw(16) << EID; + os << separator_; - for (direction dirI = 0; dirI < pTraits<Type>::nComponents; dirI++) + switch (format) + { + case dfPLOAD2: + { + if (pTraits<Type>::nComponents == 1) { - os << setw(16) << component(scaledValue, dirI); + writeValue(scaledValue, os); + } + else + { + WarningIn + ( + "template<class Type>" + "void Foam::nastranSurfaceWriter::writeNodeValue" + "(" + "const dataFormat&, " + "const Type&, " + "const label, " + "OFstream&" + ") const" + ) + << dataFormatNames_[format] << " requires scalar values " + << "and cannot be used for higher rank values" + << endl; + + writeValue(scalar(0), os); } - os.unsetf(ios_base::right); - - os << nl; - - os.setf(ios_base::left); - os << '*'; - os.unsetf(ios_base::left); + os << separator_; + writeValue(EID, os); break; } - case wfFree: + case dfPLOAD4: { - os << nasFieldName << ',' - << SID << ',' - << EID; + writeValue(EID, os); for (direction dirI = 0; dirI < pTraits<Type>::nComponents; dirI++) { - os << ',' << component(scaledValue, dirI); + os << separator_; + writeValue(component(scaledValue, dirI), os); } - break; } default: { + WarningIn + ( + "template<class Type>" + "void Foam::nastranSurfaceWriter::writeNodeValue" + "(" + "const dataFormat&, " + "const Type&, " + "const label, " + "OFstream&" + ") const" + ) + << "Unhandled enumeration " << dataFormatNames_[format] + << endl; } } + os.unsetf(ios_base::right); + os << nl; } template<class Type> -void Foam::nastranSurfaceWriter::writeTemplate +Foam::fileName Foam::nastranSurfaceWriter::writeTemplate ( const fileName& outputDir, const fileName& surfaceName, @@ -127,6 +176,7 @@ void Foam::nastranSurfaceWriter::writeTemplate const bool verbose ) const { + if (!fieldMap_.found(fieldName)) { WarningIn @@ -148,10 +198,10 @@ void Foam::nastranSurfaceWriter::writeTemplate << fieldMap_ << exit(FatalError); - return; + return fileName::null; } - const word& nasFieldName(fieldMap_[fieldName]); + const dataFormat& format(fieldMap_[fieldName]); if (!isDir(outputDir/fieldName)) { @@ -161,7 +211,7 @@ void Foam::nastranSurfaceWriter::writeTemplate // const scalar timeValue = Foam::name(this->mesh().time().timeValue()); const scalar timeValue = 0.0; - OFstream os(outputDir/fieldName/surfaceName + ".dat"); + OFstream os(outputDir/fieldName/surfaceName + ".nas"); formatOS(os); if (verbose) @@ -203,7 +253,7 @@ void Foam::nastranSurfaceWriter::writeTemplate } v /= f.size(); - writeFaceValue(nasFieldName, v, ++n, os); + writeFaceValue(format, v, ++n, os); } } } @@ -217,12 +267,16 @@ void Foam::nastranSurfaceWriter::writeTemplate forAll(dFaces, faceI) { - writeFaceValue(nasFieldName, values[faceI], ++n, os); + writeFaceValue(format, values[faceI], ++n, os); } } } + writeFooter(os); + os << "ENDDATA" << endl; + + return os.name(); } diff --git a/src/sampling/sampledSurface/writers/proxy/proxySurfaceWriter.C b/src/sampling/sampledSurface/writers/proxy/proxySurfaceWriter.C index 780e25b568a8bdb844e1747187ec13722201c20e..33dc3263d45c7ee82040d9e9b2937c89f7ac52ce 100644 --- a/src/sampling/sampledSurface/writers/proxy/proxySurfaceWriter.C +++ b/src/sampling/sampledSurface/writers/proxy/proxySurfaceWriter.C @@ -3,7 +3,7 @@ \\ / F ield | OpenFOAM: The Open Source CFD Toolbox \\ / O peration | \\ / A nd | Copyright (C) 2011 OpenFOAM Foundation - \\/ M anipulation | + \\/ M anipulation | Copyright (C) 2015 OpenCFD Ltd ------------------------------------------------------------------------------- License This file is part of OpenFOAM. @@ -56,7 +56,7 @@ Foam::proxySurfaceWriter::~proxySurfaceWriter() // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * // -void Foam::proxySurfaceWriter::write +Foam::fileName Foam::proxySurfaceWriter::write ( const fileName& outputDir, const fileName& surfaceName, @@ -68,7 +68,7 @@ void Foam::proxySurfaceWriter::write // avoid bad values if (ext_.empty()) { - return; + return fileName::null; } if (!isDir(outputDir)) @@ -84,6 +84,8 @@ void Foam::proxySurfaceWriter::write } MeshedSurfaceProxy<face>(points, faces).write(outName); + + return outName; } diff --git a/src/sampling/sampledSurface/writers/proxy/proxySurfaceWriter.H b/src/sampling/sampledSurface/writers/proxy/proxySurfaceWriter.H index 89ec6429f42b865321fc654c0f525f61b65a007a..7dc6e52a7d1ae9004c04ae47c022c08c4ab29a8c 100644 --- a/src/sampling/sampledSurface/writers/proxy/proxySurfaceWriter.H +++ b/src/sampling/sampledSurface/writers/proxy/proxySurfaceWriter.H @@ -3,7 +3,7 @@ \\ / F ield | OpenFOAM: The Open Source CFD Toolbox \\ / O peration | \\ / A nd | Copyright (C) 2011 OpenFOAM Foundation - \\/ M anipulation | + \\/ M anipulation | Copyright (C) 2015 OpenCFD Ltd ------------------------------------------------------------------------------- License This file is part of OpenFOAM. @@ -78,14 +78,14 @@ public: //- True if the surface format supports geometry in a separate file. // False if geometry and field must be in a single file - virtual bool separateGeometry() + virtual bool separateGeometry() const { return true; } //- Write single surface geometry to file. - virtual void write + virtual fileName write ( const fileName& outputDir, const fileName& surfaceName, @@ -93,7 +93,6 @@ public: const faceList& faces, const bool verbose = false ) const; - }; diff --git a/src/sampling/sampledSurface/writers/raw/rawSurfaceWriter.C b/src/sampling/sampledSurface/writers/raw/rawSurfaceWriter.C index 1899b1212a37c0d05343092d098ec17b2f06d92e..4447a16b938a414d79f4eecfbe7681180c54d141 100644 --- a/src/sampling/sampledSurface/writers/raw/rawSurfaceWriter.C +++ b/src/sampling/sampledSurface/writers/raw/rawSurfaceWriter.C @@ -3,7 +3,7 @@ \\ / F ield | OpenFOAM: The Open Source CFD Toolbox \\ / O peration | \\ / A nd | Copyright (C) 2011 OpenFOAM Foundation - \\/ M anipulation | + \\/ M anipulation | Copyright (C) 2015 OpenCFD Ltd ------------------------------------------------------------------------------- License This file is part of OpenFOAM. @@ -24,11 +24,6 @@ License \*---------------------------------------------------------------------------*/ #include "rawSurfaceWriter.H" - -#include "OFstream.H" -#include "OSspecific.H" -#include "IOmanip.H" - #include "makeSurfaceWriterMethods.H" // * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * // @@ -208,66 +203,6 @@ namespace Foam } -template<class Type> -void Foam::rawSurfaceWriter::writeTemplate -( - const fileName& outputDir, - const fileName& surfaceName, - const pointField& points, - const faceList& faces, - const word& fieldName, - const Field<Type>& values, - const bool isNodeValues, - const bool verbose -) const -{ - if (!isDir(outputDir)) - { - mkDir(outputDir); - } - - OFstream os(outputDir/fieldName + '_' + surfaceName + ".raw"); - - if (verbose) - { - Info<< "Writing field " << fieldName << " to " << os.name() << endl; - } - - // header - os << "# " << fieldName; - if (isNodeValues) - { - os << " POINT_DATA "; - } - else - { - os << " FACE_DATA "; - } - - // header - writeHeader(os, fieldName, values); - - // values - if (isNodeValues) - { - forAll(values, elemI) - { - writeLocation(os, points, elemI); - writeData(os, values[elemI]); - } - } - else - { - forAll(values, elemI) - { - writeLocation(os, points, faces, elemI); - writeData(os, values[elemI]); - } - } -} - - - // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * // Foam::rawSurfaceWriter::rawSurfaceWriter() @@ -284,7 +219,7 @@ Foam::rawSurfaceWriter::~rawSurfaceWriter() // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * // -void Foam::rawSurfaceWriter::write +Foam::fileName Foam::rawSurfaceWriter::write ( const fileName& outputDir, const fileName& surfaceName, @@ -318,6 +253,8 @@ void Foam::rawSurfaceWriter::write } os << nl; + + return os.name(); } diff --git a/src/sampling/sampledSurface/writers/raw/rawSurfaceWriter.H b/src/sampling/sampledSurface/writers/raw/rawSurfaceWriter.H index 6a3b3c2ee244d5f4a3853e15ca6e4a3532fd58f2..8cb999dac617b3c55797c179c413d7f569bd7920 100644 --- a/src/sampling/sampledSurface/writers/raw/rawSurfaceWriter.H +++ b/src/sampling/sampledSurface/writers/raw/rawSurfaceWriter.H @@ -3,7 +3,7 @@ \\ / F ield | OpenFOAM: The Open Source CFD Toolbox \\ / O peration | \\ / A nd | Copyright (C) 2011 OpenFOAM Foundation - \\/ M anipulation | + \\/ M anipulation | Copyright (C) 2015 OpenCFD Ltd ------------------------------------------------------------------------------- License This file is part of OpenFOAM. @@ -82,7 +82,7 @@ class rawSurfaceWriter //- Templated write operation template<class Type> - void writeTemplate + fileName writeTemplate ( const fileName& outputDir, const fileName& surfaceName, @@ -114,7 +114,7 @@ public: // Member Functions //- Write single surface geometry to file. - virtual void write + virtual fileName write ( const fileName& outputDir, const fileName& surfaceName, @@ -126,7 +126,7 @@ public: //- Write scalarField for a single surface to file. // One value per face or vertex (isNodeValues = true) - virtual void write + virtual fileName write ( const fileName& outputDir, // <case>/surface/TIME const fileName& surfaceName, // name of surface @@ -140,7 +140,7 @@ public: //- Write vectorField for a single surface to file. // One value per face or vertex (isNodeValues = true) - virtual void write + virtual fileName write ( const fileName& outputDir, // <case>/surface/TIME const fileName& surfaceName, // name of surface @@ -154,7 +154,7 @@ public: //- Write sphericalTensorField for a single surface to file. // One value per face or vertex (isNodeValues = true) - virtual void write + virtual fileName write ( const fileName& outputDir, // <case>/surface/TIME const fileName& surfaceName, // name of surface @@ -168,7 +168,7 @@ public: //- Write symmTensorField for a single surface to file. // One value per face or vertex (isNodeValues = true) - virtual void write + virtual fileName write ( const fileName& outputDir, // <case>/surface/TIME const fileName& surfaceName, // name of surface @@ -182,7 +182,7 @@ public: //- Write tensorField for a single surface to file. // One value per face or vertex (isNodeValues = true) - virtual void write + virtual fileName write ( const fileName& outputDir, // <case>/surface/TIME const fileName& surfaceName, // name of surface @@ -193,7 +193,6 @@ public: const bool isNodeValues, const bool verbose = false ) const; - }; @@ -203,6 +202,12 @@ public: // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // +#ifdef NoRepository + #include "rawSurfaceWriterTemplates.C" +#endif + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + #endif // ************************************************************************* // diff --git a/src/sampling/sampledSurface/writers/raw/rawSurfaceWriterTemplates.C b/src/sampling/sampledSurface/writers/raw/rawSurfaceWriterTemplates.C new file mode 100644 index 0000000000000000000000000000000000000000..59b15c59b9cafbd6c00793f3b53dc0409ff36b75 --- /dev/null +++ b/src/sampling/sampledSurface/writers/raw/rawSurfaceWriterTemplates.C @@ -0,0 +1,93 @@ +/*---------------------------------------------------------------------------*\ + ========= | + \\ / F ield | OpenFOAM: The Open Source CFD Toolbox + \\ / O peration | + \\ / A nd | Copyright (C) 2011-2014 OpenFOAM Foundation + \\/ M anipulation | Copyright (C) 2015 OpenCFD Ltd +------------------------------------------------------------------------------- +License + This file is part of OpenFOAM. + + OpenFOAM is free software: you can redistribute it and/or modify it + under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + OpenFOAM is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + for more details. + + You should have received a copy of the GNU General Public License + along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>. + +\*---------------------------------------------------------------------------*/ + +#include "OFstream.H" +#include "OSspecific.H" +#include "IOmanip.H" + +// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * // + +template<class Type> +Foam::fileName Foam::rawSurfaceWriter::writeTemplate +( + const fileName& outputDir, + const fileName& surfaceName, + const pointField& points, + const faceList& faces, + const word& fieldName, + const Field<Type>& values, + const bool isNodeValues, + const bool verbose +) const +{ + if (!isDir(outputDir)) + { + mkDir(outputDir); + } + + OFstream os(outputDir/fieldName + '_' + surfaceName + ".raw"); + + if (verbose) + { + Info<< "Writing field " << fieldName << " to " << os.name() << endl; + } + + // header + os << "# " << fieldName; + if (isNodeValues) + { + os << " POINT_DATA "; + } + else + { + os << " FACE_DATA "; + } + + // header + writeHeader(os, fieldName, values); + + // values + if (isNodeValues) + { + forAll(values, elemI) + { + writeLocation(os, points, elemI); + writeData(os, values[elemI]); + } + } + else + { + forAll(values, elemI) + { + writeLocation(os, points, faces, elemI); + writeData(os, values[elemI]); + } + } + + return os.name(); +} + + +// ************************************************************************* // diff --git a/src/sampling/sampledSurface/writers/starcd/starcdSurfaceWriter.C b/src/sampling/sampledSurface/writers/starcd/starcdSurfaceWriter.C index 86fb4b1c17db8e6994d65e8c7497751532bc5b99..a22f5a49eaa1092ad5dd918b32d87b7bbf4e8ab3 100644 --- a/src/sampling/sampledSurface/writers/starcd/starcdSurfaceWriter.C +++ b/src/sampling/sampledSurface/writers/starcd/starcdSurfaceWriter.C @@ -3,7 +3,7 @@ \\ / F ield | OpenFOAM: The Open Source CFD Toolbox \\ / O peration | \\ / A nd | Copyright (C) 2011 OpenFOAM Foundation - \\/ M anipulation | + \\/ M anipulation | Copyright (C) 2015 OpenCFD Ltd ------------------------------------------------------------------------------- License This file is part of OpenFOAM. @@ -24,11 +24,7 @@ License \*---------------------------------------------------------------------------*/ #include "starcdSurfaceWriter.H" - #include "MeshedSurfaceProxy.H" -#include "OFstream.H" -#include "OSspecific.H" - #include "makeSurfaceWriterMethods.H" // * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * // @@ -78,50 +74,6 @@ namespace Foam } -template<class Type> -inline void Foam::starcdSurfaceWriter::writeData -( - Ostream& os, - const Type& v -) -{} - - -template<class Type> -void Foam::starcdSurfaceWriter::writeTemplate -( - const fileName& outputDir, - const fileName& surfaceName, - const pointField& points, - const faceList& faces, - const word& fieldName, - const Field<Type>& values, - const bool isNodeValues, - const bool verbose -) const -{ - if (!isDir(outputDir)) - { - mkDir(outputDir); - } - - OFstream os(outputDir/fieldName + '_' + surfaceName + ".usr"); - - if (verbose) - { - Info<< "Writing field " << fieldName << " to " << os.name() << endl; - } - - // no header, just write values - forAll(values, elemI) - { - os << elemI+1 << ' '; - writeData(os, values[elemI]); - } -} - - - // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * // Foam::starcdSurfaceWriter::starcdSurfaceWriter() @@ -138,7 +90,7 @@ Foam::starcdSurfaceWriter::~starcdSurfaceWriter() // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * // -void Foam::starcdSurfaceWriter::write +Foam::fileName Foam::starcdSurfaceWriter::write ( const fileName& outputDir, const fileName& surfaceName, @@ -160,6 +112,8 @@ void Foam::starcdSurfaceWriter::write } MeshedSurfaceProxy<face>(points, faces).write(outName); + + return outName; } diff --git a/src/sampling/sampledSurface/writers/starcd/starcdSurfaceWriter.H b/src/sampling/sampledSurface/writers/starcd/starcdSurfaceWriter.H index 13444367fc9b1f94560edf229c2d3893cbb72c5a..9341f9816b2deb94957fcb56e79eb616ecdc00dc 100644 --- a/src/sampling/sampledSurface/writers/starcd/starcdSurfaceWriter.H +++ b/src/sampling/sampledSurface/writers/starcd/starcdSurfaceWriter.H @@ -3,7 +3,7 @@ \\ / F ield | OpenFOAM: The Open Source CFD Toolbox \\ / O peration | \\ / A nd | Copyright (C) 2011 OpenFOAM Foundation - \\/ M anipulation | + \\/ M anipulation | Copyright (C) 2015 OpenCFD Ltd ------------------------------------------------------------------------------- License This file is part of OpenFOAM. @@ -77,7 +77,7 @@ class starcdSurfaceWriter //- Templated write operation template<class Type> - void writeTemplate + fileName writeTemplate ( const fileName& outputDir, const fileName& surfaceName, @@ -110,13 +110,13 @@ public: //- True if the surface format supports geometry in a separate file. // False if geometry and field must be in a single file - virtual bool separateGeometry() + virtual bool separateGeometry() const { return true; } //- Write single surface geometry to file. - virtual void write + virtual fileName write ( const fileName& outputDir, const fileName& surfaceName, @@ -127,7 +127,7 @@ public: //- Write scalarField for a single surface to file. // One value per face or vertex (isNodeValues = true) - virtual void write + virtual fileName write ( const fileName& outputDir, // <case>/surface/TIME const fileName& surfaceName, // name of surface @@ -141,7 +141,7 @@ public: //- Write vectorField for a single surface to file. // One value per face or vertex (isNodeValues = true) - virtual void write + virtual fileName write ( const fileName& outputDir, // <case>/surface/TIME const fileName& surfaceName, // name of surface @@ -155,7 +155,7 @@ public: //- Write sphericalTensorField for a single surface to file. // One value per face or vertex (isNodeValues = true) - virtual void write + virtual fileName write ( const fileName& outputDir, // <case>/surface/TIME const fileName& surfaceName, // name of surface @@ -166,7 +166,6 @@ public: const bool isNodeValues, const bool verbose = false ) const; - }; @@ -176,6 +175,12 @@ public: // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // +#ifdef NoRepository + #include "starcdSurfaceWriterTemplates.C" +#endif + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + #endif // ************************************************************************* // diff --git a/src/sampling/sampledSurface/writers/starcd/starcdSurfaceWriterTemplates.C b/src/sampling/sampledSurface/writers/starcd/starcdSurfaceWriterTemplates.C new file mode 100644 index 0000000000000000000000000000000000000000..08733bb5a2907de3e7ba734dfc0d11e8fc29c39c --- /dev/null +++ b/src/sampling/sampledSurface/writers/starcd/starcdSurfaceWriterTemplates.C @@ -0,0 +1,76 @@ +/*---------------------------------------------------------------------------*\ + ========= | + \\ / F ield | OpenFOAM: The Open Source CFD Toolbox + \\ / O peration | + \\ / A nd | Copyright (C) 2011-2014 OpenFOAM Foundation + \\/ M anipulation | Copyright (C) 2015 OpenCFD Ltd +------------------------------------------------------------------------------- +License + This file is part of OpenFOAM. + + OpenFOAM is free software: you can redistribute it and/or modify it + under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + OpenFOAM is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + for more details. + + You should have received a copy of the GNU General Public License + along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>. + +\*---------------------------------------------------------------------------*/ + +#include "OFstream.H" +#include "OSspecific.H" + +// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * // + +template<class Type> +inline void Foam::starcdSurfaceWriter::writeData +( + Ostream& os, + const Type& v +) +{} + + +template<class Type> +Foam::fileName Foam::starcdSurfaceWriter::writeTemplate +( + const fileName& outputDir, + const fileName& surfaceName, + const pointField& points, + const faceList& faces, + const word& fieldName, + const Field<Type>& values, + const bool isNodeValues, + const bool verbose +) const +{ + if (!isDir(outputDir)) + { + mkDir(outputDir); + } + + OFstream os(outputDir/fieldName + '_' + surfaceName + ".usr"); + + if (verbose) + { + Info<< "Writing field " << fieldName << " to " << os.name() << endl; + } + + // no header, just write values + forAll(values, elemI) + { + os << elemI+1 << ' '; + writeData(os, values[elemI]); + } + + return os.name(); +} + + +// ************************************************************************* // diff --git a/src/sampling/sampledSurface/writers/surfaceWriter.H b/src/sampling/sampledSurface/writers/surfaceWriter.H index 84ca3cdf5d57ba6e38c2326eed2bef5aad6f1ec4..7fd2af4a09b6c884451d03e90e2f490eac134ad0 100644 --- a/src/sampling/sampledSurface/writers/surfaceWriter.H +++ b/src/sampling/sampledSurface/writers/surfaceWriter.H @@ -3,7 +3,7 @@ \\ / F ield | OpenFOAM: The Open Source CFD Toolbox \\ / O peration | \\ / A nd | Copyright (C) 2011-2012 OpenFOAM Foundation - \\/ M anipulation | + \\/ M anipulation | Copyright (C) 2015 OpenCFD Ltd ------------------------------------------------------------------------------- License This file is part of OpenFOAM. @@ -110,13 +110,13 @@ public: //- True if the surface format supports geometry in a separate file. // False if geometry and field must be in a single file - virtual bool separateGeometry() + virtual bool separateGeometry() const { return false; } //- Write single surface geometry to file. - virtual void write + virtual fileName write ( const fileName& outputDir, // <case>/surface/TIME const fileName& surfaceName, // name of surface @@ -124,11 +124,13 @@ public: const faceList& faces, const bool verbose = false ) const - {} + { + return fileName::null; + } //- Write scalarField for a single surface to file. // One value per face or vertex (isNodeValues = true) - virtual void write + virtual fileName write ( const fileName& outputDir, // <case>/surface/TIME const fileName& surfaceName, // name of surface @@ -139,11 +141,13 @@ public: const bool isNodeValues, const bool verbose = false ) const - {} + { + return fileName::null; + } //- Write vectorField for a single surface to file. // One value per face or vertex (isNodeValues = true) - virtual void write + virtual fileName write ( const fileName& outputDir, // <case>/surface/TIME const fileName& surfaceName, // name of surface @@ -154,11 +158,13 @@ public: const bool isNodeValues, const bool verbose = false ) const - {} + { + return fileName::null; + } //- Write sphericalTensorField for a single surface to file. // One value per face or vertex (isNodeValues = true) - virtual void write + virtual fileName write ( const fileName& outputDir, // <case>/surface/TIME const fileName& surfaceName, // name of surface @@ -169,11 +175,13 @@ public: const bool isNodeValues, const bool verbose = false ) const - {} + { + return fileName::null; + } //- Write symmTensorField for a single surface to file. // One value per face or vertex (isNodeValues = true) - virtual void write + virtual fileName write ( const fileName& outputDir, // <case>/surface/TIME const fileName& surfaceName, // name of surface @@ -184,11 +192,13 @@ public: const bool isNodeValues, const bool verbose = false ) const - {} + { + return fileName::null; + } //- Write tensorField for a single surface to file. // One value per face or vertex (isNodeValues = true) - virtual void write + virtual fileName write ( const fileName& outputDir, // <case>/surface/TIME const fileName& surfaceName, // name of surface @@ -199,7 +209,9 @@ public: const bool isNodeValues, const bool verbose = false ) const - {} + { + return fileName::null; + } }; diff --git a/src/sampling/sampledSurface/writers/vtk/vtkSurfaceWriter.C b/src/sampling/sampledSurface/writers/vtk/vtkSurfaceWriter.C index 5e6c38045b6cce60b0fe4b068ab688feb6156c9a..41cf0f5617c97279b66e49ff35a89f72ba41e133 100644 --- a/src/sampling/sampledSurface/writers/vtk/vtkSurfaceWriter.C +++ b/src/sampling/sampledSurface/writers/vtk/vtkSurfaceWriter.C @@ -3,7 +3,7 @@ \\ / F ield | OpenFOAM: The Open Source CFD Toolbox \\ / O peration | \\ / A nd | Copyright (C) 2011-2012 OpenFOAM Foundation - \\/ M anipulation | + \\/ M anipulation | Copyright (C) 2015 OpenCFD Ltd ------------------------------------------------------------------------------- License This file is part of OpenFOAM. @@ -24,10 +24,6 @@ License \*---------------------------------------------------------------------------*/ #include "vtkSurfaceWriter.H" - -#include "OFstream.H" -#include "OSspecific.H" - #include "makeSurfaceWriterMethods.H" // * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * // @@ -202,69 +198,6 @@ namespace Foam } -// Write generic field in vtk format -template<class Type> -void Foam::vtkSurfaceWriter::writeData -( - Ostream& os, - const Field<Type>& values -) -{ - os << "1 " << values.size() << " float" << nl; - - forAll(values, elemI) - { - os << float(0) << nl; - } -} - - -template<class Type> -void Foam::vtkSurfaceWriter::writeTemplate -( - const fileName& outputDir, - const fileName& surfaceName, - const pointField& points, - const faceList& faces, - const word& fieldName, - const Field<Type>& values, - const bool isNodeValues, - const bool verbose -) const -{ - if (!isDir(outputDir)) - { - mkDir(outputDir); - } - - OFstream os(outputDir/fieldName + '_' + surfaceName + ".vtk"); - - if (verbose) - { - Info<< "Writing field " << fieldName << " to " << os.name() << endl; - } - - writeGeometry(os, points, faces); - - // start writing data - if (isNodeValues) - { - os << "POINT_DATA "; - } - else - { - os << "CELL_DATA "; - } - - os << values.size() << nl - << "FIELD attributes 1" << nl - << fieldName << " "; - - // Write data - writeData(os, values); -} - - // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * // Foam::vtkSurfaceWriter::vtkSurfaceWriter() @@ -281,7 +214,7 @@ Foam::vtkSurfaceWriter::~vtkSurfaceWriter() // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * // -void Foam::vtkSurfaceWriter::write +Foam::fileName Foam::vtkSurfaceWriter::write ( const fileName& outputDir, const fileName& surfaceName, @@ -303,6 +236,8 @@ void Foam::vtkSurfaceWriter::write } writeGeometry(os, points, faces); + + return os.name(); } diff --git a/src/sampling/sampledSurface/writers/vtk/vtkSurfaceWriter.H b/src/sampling/sampledSurface/writers/vtk/vtkSurfaceWriter.H index e6a6a91c01668f1cba4e419cb8cc57861ebf3dab..6e648086e1a8be0e636b122c6fe425380e5ebe5e 100644 --- a/src/sampling/sampledSurface/writers/vtk/vtkSurfaceWriter.H +++ b/src/sampling/sampledSurface/writers/vtk/vtkSurfaceWriter.H @@ -3,7 +3,7 @@ \\ / F ield | OpenFOAM: The Open Source CFD Toolbox \\ / O peration | \\ / A nd | Copyright (C) 2011 OpenFOAM Foundation - \\/ M anipulation | + \\/ M anipulation | Copyright (C) 2015 OpenCFD Ltd ------------------------------------------------------------------------------- License This file is part of OpenFOAM. @@ -60,7 +60,7 @@ class vtkSurfaceWriter //- Templated write operation template<class Type> - void writeTemplate + fileName writeTemplate ( const fileName& outputDir, const fileName& surfaceName, @@ -72,6 +72,7 @@ class vtkSurfaceWriter const bool verbose ) const; + public: //- Runtime type information @@ -91,7 +92,7 @@ public: // Member Functions //- Write single surface geometry to file. - virtual void write + virtual fileName write ( const fileName& outputDir, const fileName& surfaceName, @@ -103,7 +104,7 @@ public: //- Write scalarField for a single surface to file. // One value per face or vertex (isNodeValues = true) - virtual void write + virtual fileName write ( const fileName& outputDir, // <case>/surface/TIME const fileName& surfaceName, // name of surface @@ -117,7 +118,7 @@ public: //- Write vectorField for a single surface to file. // One value per face or vertex (isNodeValues = true) - virtual void write + virtual fileName write ( const fileName& outputDir, // <case>/surface/TIME const fileName& surfaceName, // name of surface @@ -131,7 +132,7 @@ public: //- Write sphericalTensorField for a single surface to file. // One value per face or vertex (isNodeValues = true) - virtual void write + virtual fileName write ( const fileName& outputDir, // <case>/surface/TIME const fileName& surfaceName, // name of surface @@ -145,7 +146,7 @@ public: //- Write symmTensorField for a single surface to file. // One value per face or vertex (isNodeValues = true) - virtual void write + virtual fileName write ( const fileName& outputDir, // <case>/surface/TIME const fileName& surfaceName, // name of surface @@ -159,7 +160,7 @@ public: //- Write tensorField for a single surface to file. // One value per face or vertex (isNodeValues = true) - virtual void write + virtual fileName write ( const fileName& outputDir, // <case>/surface/TIME const fileName& surfaceName, // name of surface @@ -180,6 +181,12 @@ public: // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // +#ifdef NoRepository + #include "vtkSurfaceWriterTemplates.C" +#endif + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + #endif // ************************************************************************* // diff --git a/src/sampling/sampledSurface/writers/vtk/vtkSurfaceWriterTemplates.C b/src/sampling/sampledSurface/writers/vtk/vtkSurfaceWriterTemplates.C new file mode 100644 index 0000000000000000000000000000000000000000..819dd567f825227c98076d4f2154a344cd14a3a0 --- /dev/null +++ b/src/sampling/sampledSurface/writers/vtk/vtkSurfaceWriterTemplates.C @@ -0,0 +1,95 @@ +/*---------------------------------------------------------------------------*\ + ========= | + \\ / F ield | OpenFOAM: The Open Source CFD Toolbox + \\ / O peration | + \\ / A nd | Copyright (C) 2011-2014 OpenFOAM Foundation + \\/ M anipulation | Copyright (C) 2015 OpenCFD Ltd +------------------------------------------------------------------------------- +License + This file is part of OpenFOAM. + + OpenFOAM is free software: you can redistribute it and/or modify it + under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + OpenFOAM is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + for more details. + + You should have received a copy of the GNU General Public License + along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>. + +\*---------------------------------------------------------------------------*/ + +#include "OFstream.H" +#include "OSspecific.H" + +// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * // + +template<class Type> +void Foam::vtkSurfaceWriter::writeData +( + Ostream& os, + const Field<Type>& values +) +{ + os << "1 " << values.size() << " float" << nl; + + forAll(values, elemI) + { + os << float(0) << nl; + } +} + + +template<class Type> +Foam::fileName Foam::vtkSurfaceWriter::writeTemplate +( + const fileName& outputDir, + const fileName& surfaceName, + const pointField& points, + const faceList& faces, + const word& fieldName, + const Field<Type>& values, + const bool isNodeValues, + const bool verbose +) const +{ + if (!isDir(outputDir)) + { + mkDir(outputDir); + } + + OFstream os(outputDir/fieldName + '_' + surfaceName + ".vtk"); + + if (verbose) + { + Info<< "Writing field " << fieldName << " to " << os.name() << endl; + } + + writeGeometry(os, points, faces); + + // start writing data + if (isNodeValues) + { + os << "POINT_DATA "; + } + else + { + os << "CELL_DATA "; + } + + os << values.size() << nl + << "FIELD attributes 1" << nl + << fieldName << " "; + + // Write data + writeData(os, values); + + return os.name(); +} + + +// ************************************************************************* //