/* This file is part of the OpenLB library * * Copyright (C) 2014-2015 Mathias J. Krause, Marie-Luise Maier * 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. */ #ifndef ANALYTICAL_FRAME_CHANGE_F_2D_H #define ANALYTICAL_FRAME_CHANGE_F_2D_H #include #include #include #include"math.h" #include "functors/genericF.h" #include "analyticalF.h" #include "core/superLattice2D.h" /** \file This file contains two different classes of functors, in the FIRST part - for simulations in a rotating frame - different functors for velocity (3d, RotatingLinear3D), pressure (1d, RotatingQuadratic1D) and force (3d, RotatingForceField3D) The functors return the displacement of a point x in a fixed amount of time. The ones in the SECOND part are useful to set Poiseuille velocity profiles on - pipes with round cross-section and - pipes with square-shaped cross-section. */ /** To enable simulations in a rotating frame, the axis is set in the * constructor with axisPoint and axisDirection. The axisPoint can be the * coordinate of any point on the axis. The axisDirection has to be a normed to * 1. The pulse w is in rad/s. It determines the pulse speed by its norm while * the trigonometric or clockwise direction is determined by its sign: When the * axisDirection is pointing "towards you", a positive pulse makes it turn in * the trigonometric way. It has to be noticed that putting both axisDirection * into -axisDirection and w into -w yields an exactly identical situation. */ namespace olb { template class PowerLaw2D : public AnalyticalF2D { protected: std::vector _axisPoint; std::vector _axisDirection; T _maxVelocity; T _radius; T _exponent; public: PowerLaw2D(std::vector axisPoint, std::vector axisDirection, T maxVelocity, T radius, T exponent); /// construct from material number, note: untested PowerLaw2D(SuperGeometry2D& superGeometry, int material, T maxVelocity, T distance2Wall, T exponent); bool operator()(T output[], const T input[]) override; }; template class Poiseuille2D : public PowerLaw2D { public: Poiseuille2D(std::vector axisPoint, std::vector axisDirection, T maxVelocity, T radius); /// construct from material number, note: untested Poiseuille2D(SuperGeometry2D& superGeometry, int material, T maxVelocity, T distance2Wall); //bool operator()(T output[], const T x[]); }; template class PoiseuilleStrainRate2D : public AnalyticalF2D { protected: T _lengthY; T _maxVelocity; public: PoiseuilleStrainRate2D(UnitConverter const& converter, T ly); bool operator()(T output[], const S input[]) override; }; /// Analytical solution of porous media channel flow with low Reynolds number /// See Spaid and Phelan (doi:10.1063/1.869392) template class AnalyticalPorousVelocity2D : public AnalyticalF2D { protected: std::vector axisDirection; T K, mu, gradP, radius; T eps; public: AnalyticalPorousVelocity2D(std::vector axisDirection_, T K_, T mu_, T gradP_, T radius_, T eps_=T(1)); T getPeakVelocity(); bool operator()(T output[], const T input[]) override; }; ////////// Polar & Cartesian /////////////// /// This class converts polar coordinates of point x (x[0] = radius, x[1] = phi) /// to Cartesian coordinates (wrote into output field). /// Initial situation for the Cartesian coordinate system is that angle phi /// lies in the x-y-plane and turns round the _polarOrigin in math. pos sense. template class PolarToCartesian2D : public AnalyticalF2D { protected: /// origin of the polar coordinate system to which point x is related std::vector _polarOrigin; // std::vector _normalToPlane; public: /// constructor to obtain Cartesian coordinates of polar coordinates PolarToCartesian2D(std::vector polarOrigin); /// operator writes Cartesian coordinates of polar coordinates /// x[0] = radius >= 0, x[1] = phi in [0, 2*Pi) into output field bool operator()(T output[], const S x[]) override; }; /// This class converts Cartesian coordinates of point x to polar coordinates /// wrote into output field /// (output[0] = radius>= 0, output[1] = phi in [0, 2Pi). /// Initial situation for the polar coordinate system is that angle phi /// lies in plane perpendicular to the _axisDirection and turns around /// the _cartesianOrigin. The radius is the distance of point x to the /// _axisDirection. template class CartesianToPolar2D : public AnalyticalF2D { protected: /// origin of the Cartesian coordinate system std::vector _cartesianOrigin; /// direction of the axis along which the polar coordinates are calculated std::vector _axisDirection; /// direction to know orientation for math positive to obtain angle phi /// of Cartesian point x std::vector _orientation; public: CartesianToPolar2D(std::vector cartesianOrigin, std::vector axisDirection, std::vector orientation = {T(1),T(),T()}); CartesianToPolar2D(T cartesianOriginX, T cartesianOriginY, T cartesianOriginZ, T axisDirectionX, T axisDirectionY, T axisDirectionZ, T orientationX = T(1), T orientationY = T(), T orientationZ = T()); /// operator writes polar coordinates of Cartesian point x into output /// field, /// returns output[0] = radius ( >= 0 ), output[1] = phi in [0, 2Pi) bool operator()(T output[], const S x[]) override; }; } // end namespace olb #endif