/*---------------------------------------------------------------------------*\ ========= | \\ / F ield | OpenFOAM: The Open Source CFD Toolbox \\ / O peration | \\ / A nd | www.openfoam.com \\/ M anipulation | ------------------------------------------------------------------------------- Copyright (C) 2015 OpenFOAM Foundation Copyright (C) 2015-2022 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 . \*---------------------------------------------------------------------------*/ // * * * * * * * * * * * * * Protected Member Functions * * * * * * * * * * // template bool Foam::functionObjects::valueAverageBase::calc ( const label fieldi, bool& converged, dictionary& dict ) { const word& fieldName = fieldNames_[fieldi]; const word valueType = state_.objectResultType(functionObjectName_, fieldName); if (pTraits::typeName != valueType) { return false; } const scalar dt = state_.time().deltaTValue(); const Type currentValue = state_.getObjectResult(functionObjectName_, fieldName); // Current mean value const word meanName(fieldName + "Mean"); Type meanValue = state_.getResult(meanName); switch (windowType_) { case windowType::NONE: { const scalar Dt = totalTime_[fieldi]; const scalar beta = dt/Dt; meanValue = (1 - beta)*meanValue + beta*currentValue; break; } case windowType::APPROXIMATE: { const scalar Dt = totalTime_[fieldi]; scalar beta = dt/Dt; if (Dt - dt >= window_) { beta = dt/window_; } else { converged = false; } meanValue = (1 - beta)*meanValue + beta*currentValue; break; } case windowType::EXACT: { FIFOStack windowTimes; FIFOStack windowValues; dictionary& fieldDict = dict.subDict(fieldName); fieldDict.readIfPresent("windowTimes", windowTimes); fieldDict.readIfPresent("windowValues", windowValues); // Increment time for all existing values for (scalar& dti : windowTimes) { dti += dt; } // Remove any values outside the window bool removeValue = true; while (removeValue && windowTimes.size()) { removeValue = windowTimes.first() > window_; if (removeValue) { windowTimes.pop(); windowValues.pop(); } } // Add the current value windowTimes.push(dt); windowValues.push(currentValue); // Calculate the window average auto timeIter = windowTimes.cbegin(); auto valueIter = windowValues.cbegin(); meanValue = pTraits::zero; Type valueOld(pTraits::zero); for ( label i = 0; timeIter.good(); ++i, ++timeIter, ++valueIter ) { const Type& value = valueIter(); const scalar dt = timeIter(); meanValue += dt*value; if (i) { meanValue -= dt*valueOld; } valueOld = value; } meanValue /= windowTimes.first(); // Store the state information for the next step fieldDict.set("windowTimes", windowTimes); fieldDict.set("windowValues", windowValues); break; } } scalar delta = mag(meanValue - currentValue); Log << indent << " " << meanName << ": " << meanValue << ", delta: " << delta << nl; file() << tab << meanValue; state_.setResult(meanName, meanValue); if ((tolerance_ > 0) && (delta > tolerance_)) { converged = false; } return true; } // ************************************************************************* //