/*---------------------------------------------------------------------------*\ ========= | \\ / F ield | OpenFOAM: The Open Source CFD Toolbox \\ / O peration | \\ / A nd | Copyright (C) 2011-2016 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 . \*---------------------------------------------------------------------------*/ #include "dimensionSet.H" #include "dimensionedScalar.H" #include "simpleRegIOobject.H" #include "demandDrivenData.H" // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // namespace Foam { /* * * * * * * * * * * * * * * Static Member Data * * * * * * * * * * * * * */ // Since dimensionSystems() can be reread we actually store a copy of // the controlDict subDict (v.s. a reference to the subDict for e.g. // dimensionedConstants) dictionary* dimensionSystemsPtr_(nullptr); HashTable* unitSetPtr_(nullptr); dimensionSets* writeUnitSetPtr_(nullptr); // Helper class to // register re-reader // deallocate demand-driven data class addDimensionSetsToDebug : public ::Foam::simpleRegIOobject { public: addDimensionSetsToDebug(const char* name) : ::Foam::simpleRegIOobject(Foam::debug::addDimensionSetObject, name) {} virtual ~addDimensionSetsToDebug() { deleteDemandDrivenData(dimensionSystemsPtr_); deleteDemandDrivenData(unitSetPtr_); deleteDemandDrivenData(writeUnitSetPtr_); } virtual void readData(Foam::Istream& is) { deleteDemandDrivenData(dimensionSystemsPtr_); deleteDemandDrivenData(unitSetPtr_); deleteDemandDrivenData(writeUnitSetPtr_); dimensionSystemsPtr_ = new dictionary(is); } virtual void writeData(Foam::Ostream& os) const { os << dimensionSystems(); } }; addDimensionSetsToDebug addDimensionSetsToDebug_("DimensionSets"); dictionary& dimensionSystems() { if (!dimensionSystemsPtr_) { dictionary* cachedPtr = nullptr; dimensionSystemsPtr_ = new dictionary ( debug::switchSet ( "DimensionSets", cachedPtr ) ); } return *dimensionSystemsPtr_; } const HashTable& unitSet() { if (!unitSetPtr_) { const dictionary& dict = dimensionSystems(); if (!dict.found("unitSet")) { FatalIOErrorInFunction(dict) << "Cannot find unitSet in dictionary " << dict.name() << exit(FatalIOError); } const word unitSetCoeffs(word(dict.lookup("unitSet")) + "Coeffs"); if (!dict.found(unitSetCoeffs)) { FatalIOErrorInFunction(dict) << "Cannot find " << unitSetCoeffs << " in dictionary " << dict.name() << exit(FatalIOError); } const dictionary& unitDict = dict.subDict(unitSetCoeffs); unitSetPtr_ = new HashTable(unitDict.size()); forAllConstIter(dictionary, unitDict, iter) { if (iter().keyword() != "writeUnits") { dimensionedScalar dt; dt.read(iter().stream(), unitDict); bool ok = unitSetPtr_->insert(iter().keyword(), dt); if (!ok) { FatalIOErrorInFunction(dict) << "Duplicate unit " << iter().keyword() << " in DimensionSets dictionary" << exit(FatalIOError); } } } wordList writeUnitNames ( unitDict.lookupOrDefault ( "writeUnits", wordList(0) ) ); writeUnitSetPtr_ = new dimensionSets(*unitSetPtr_, writeUnitNames); if (writeUnitNames.size() != 0 && writeUnitNames.size() != 7) { FatalIOErrorInFunction(dict) << "Cannot find entry \"writeUnits\" in " << unitDict.name() << " or it is not a wordList of size 7" << exit(FatalIOError); } } return *unitSetPtr_; } const dimensionSets& writeUnitSet() { if (!writeUnitSetPtr_) { (void)unitSet(); } return *writeUnitSetPtr_; } const dimensionSet dimless(0, 0, 0, 0, 0, 0, 0); const dimensionSet dimMass(1, 0, 0, 0, 0, 0, 0); const dimensionSet dimLength(0, 1, 0, 0, 0, 0, 0); const dimensionSet dimTime(0, 0, 1, 0, 0, 0, 0); const dimensionSet dimTemperature(0, 0, 0, 1, 0, 0, 0); const dimensionSet dimMoles(0, 0, 0, 0, 1, 0, 0); const dimensionSet dimCurrent(0, 0, 0, 0, 0, 1, 0); const dimensionSet dimLuminousIntensity(0, 0, 0, 0, 0, 0, 1); const dimensionSet dimArea(sqr(dimLength)); const dimensionSet dimVolume(pow3(dimLength)); const dimensionSet dimVol(dimVolume); const dimensionSet dimVelocity(dimLength/dimTime); const dimensionSet dimAcceleration(dimVelocity/dimTime); const dimensionSet dimDensity(dimMass/dimVolume); const dimensionSet dimForce(dimMass*dimAcceleration); const dimensionSet dimEnergy(dimForce*dimLength); const dimensionSet dimPower(dimEnergy/dimTime); const dimensionSet dimPressure(dimForce/dimArea); const dimensionSet dimCompressibility(dimDensity/dimPressure); const dimensionSet dimGasConstant(dimEnergy/dimMass/dimTemperature); const dimensionSet dimSpecificHeatCapacity(dimGasConstant); const dimensionSet dimViscosity(dimArea/dimTime); const dimensionSet dimDynamicViscosity(dimDensity*dimViscosity); // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // } // End namespace Foam // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * // Foam::dimensionSets::dimensionSets ( const HashTable& units, const wordList& unitNames ) : units_(unitNames.size()), conversion_(unitNames.size()), conversionPivots_(unitNames.size()), valid_(false) { forAll(unitNames, i) { units_.set ( i, new dimensionedScalar ( units[unitNames[i]] ) ); } if (unitNames.size() == 7) { valid_ = true; // Determine conversion from basic units to write units for (label rowI = 0; rowI < conversion_.m(); rowI++) { scalar* row = conversion_[rowI]; for (label columnI = 0; columnI < conversion_.n(); columnI++) { const dimensionedScalar& dSet = units_[columnI]; row[columnI] = dSet.dimensions()[rowI]; } } conversionPivots_.setSize(conversion_.m()); LUDecompose(conversion_, conversionPivots_); } } void Foam::dimensionSets::coefficients(scalarField& exponents) const { LUBacksubstitute(conversion_, conversionPivots_, exponents); } // ************************************************************************* //