/* This file is part of the OpenLB library * * Copyright (C) 2017-2018 Max Gaedtke, Albert Mink, Davide Dapelo * E-mail contact: info@openlb.net * The most recent release of OpenLB can be downloaded at * * * This program 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 2 * of the License, or (at your option) any later version. * * This program 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 this program; if not, write to the Free * Software Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. */ /** \file * Unit conversion handling -- header file. */ #ifndef PL_UNITCONVERTER_H #define PL_UNITCONVERTER_H #include #include "io/ostreamManager.h" #include "core/util.h" #include "io/xmlReader.h" #include "unitConverter.h" /// All OpenLB code is contained in this namespace. namespace olb { /** Conversion between physical and lattice units, as well as discretization specialized for power-law rheology: \f$\nu=m^{n-1}\f$, with \f$m$ being the consistency coefficient and \f$n\f$ the power-law index. * The Newtonian case is recovered for \f$n=1\f$. * A characteristic (apparent) kinematic viscosity for problem similarity (e.g., to compute the Reynolds number) is obtained as __physViscosity = poweLawConsistencyCoeff * [physVelocity / (2*physLength)]^(n-1)__. * Be aware of the nomenclature: * We distingish between physical (dimensioned) and lattice (dimensionless) values. * A specific conversion factor maps the two different scopes, * e.g. __physLength = conversionLength * latticeLength__ * * For pressure and temperature we first shift the physical values by a characteristic value to asure a lattice pressure and lattice temperature between 0 and 1, e.g. __physPressure - charPhysPressure = conversionPressure * latticePressure__ * * \param latticeRelaxationTime relaxation time, have to be greater than 0.5! * - - - * \param physViscosity physical kinematic viscosity in __m^2 / s__ * \param poweLawIndex power-law index * \param physConsistencyCoeff physicsl consistency coefficient __m^2 s^(n-2)__ * \param physDensity physical density in __kg / m^3__ * - - - * \param conversionLength conversion factor for length __m__ * \param conversionTime conversion factor for time __s__ * \param conversionMass conversion factor for mass __kg__ * - - - * \param conversionVelocity conversion velocity __m / s__ * \param conversionViscosity conversion kinematic viscosity __m^2 / s__ * \param conversionConsistencyCoeff conversion power-law consistency coefficient __m^2 s^(n-2)__ * \param conversionDensity conversion density __kg / m^3__ * \param conversionForce conversion force __kg m / s^2__ * \param conversionPressure conversion pressure __kg / m s^2__ * - - - * \param resolution number of grid points per charPhysLength * - - - * \param charLatticeVelocity */ template class PowerLawUnitConverter : public UnitConverter { public: /** Documentation of constructor: * \param physDeltaX spacing between two lattice cells in __m__ * \param physDeltaT time step in __s__ * \param charPhysLength reference/characteristic length of simulation geometry in __m__ * \param charPhysVelocity maximal or highest expected velocity during simulation in __m / s__ * \param physConsistencyCoeff physical power-law consistency coefficient in __m^2 s^(n-2)__ * \param powerLawIndex Power-law index * \param physDensity physical density in __kg / m^3__ * \param charPhysPressure reference/characteristic physical pressure in Pa = kg / m s^2 */ constexpr PowerLawUnitConverter( T physDeltaX, T physDeltaT, T charPhysLength, T charPhysVelocity, T physConsistencyCoeff, T powerLawIndex, T physDensity, T charPhysPressure = 0 ) : UnitConverter( physDeltaX, physDeltaT, charPhysLength, charPhysVelocity, physConsistencyCoeff * pow(charPhysVelocity / (2*charPhysLength), powerLawIndex-1), physDensity, charPhysPressure ), _conversionConsistencyCoeff(pow( physDeltaT,powerLawIndex-2 ) * pow( physDeltaX,2 ) ), _powerLawIndex(powerLawIndex), _physConsistencyCoeff(physConsistencyCoeff), clout(std::cout,"PowerLawUnitConverter") { } /// return consistency coefficient in physical units constexpr T getPhysConsistencyCoeff( ) const { return _physConsistencyCoeff; } /// conversion from lattice to physical consistency coefficient constexpr T getPhysConsistencyCoeff( T latticeConsistencyCoeff ) const { return _conversionConsistencyCoeff * latticeConsistencyCoeff; } /// conversion from physical to lattice consistency coefficient constexpr T getLatticeConsistencyCoeff( ) const { return _physConsistencyCoeff / _conversionConsistencyCoeff; } /// access (read-only) to private member variable constexpr T getConversionFactorConsistencyCoeff() const { return _conversionConsistencyCoeff; } /// access (read-only) to private member variable constexpr T getPowerLawIndex() const { return _powerLawIndex; } /// nice terminal output for conversion factors, characteristical and physical data virtual void print() const; void write(std::string const& fileName = "unitConverter") const; protected: // conversion factors const T _conversionConsistencyCoeff; // m^2 s^(n-2) // physical units, e.g characteristic or reference values const T _powerLawIndex; const T _physConsistencyCoeff; // m^2 s^(n-2) private: mutable OstreamManager clout; }; /// creator function with data given by a XML file template PowerLawUnitConverter* createPowerLawUnitConverter(XMLreader const& params); template class PowerLawUnitConverterFrom_Resolution_RelaxationTime_Reynolds_PLindex : public PowerLawUnitConverter { public: constexpr PowerLawUnitConverterFrom_Resolution_RelaxationTime_Reynolds_PLindex( int resolution, T latticeRelaxationTime, T charPhysLength, T charPhysVelocity, T Re, T powerLawIndex, T physDensity, T charPhysPressure = 0) : PowerLawUnitConverter( (charPhysLength/resolution), (latticeRelaxationTime - 0.5) / descriptors::invCs2() * pow((charPhysLength/resolution),2) / ( ( charPhysLength * charPhysVelocity * pow( charPhysVelocity / ( 2 * charPhysLength ), 1 - powerLawIndex ) / Re ) * pow( charPhysVelocity / (2 * charPhysLength ), powerLawIndex - 1 ) ), charPhysLength, charPhysVelocity, charPhysLength * charPhysVelocity * pow( charPhysVelocity / ( 2 * charPhysLength ), 1 - powerLawIndex ) / Re, powerLawIndex, physDensity, charPhysPressure ) { } }; } // namespace olb #endif