/* This file is part of the OpenLB library * * Copyright (C) 2016-2017 Davide Dapelo, Mathias J. Krause * OpenLB 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 * Helper functions for the implementation of the * Guo-ZhapLB dynamics. */ #ifndef LB_GUOZHAO_HELPERS_H #define LB_GUOZHAO_HELPERS_H #include "dynamics/guoZhaoLatticeDescriptors.h" #include "core/cell.h" #include "core/util.h" namespace olb { // Forward declarations template struct GuoZhaoLbDynamicsHelpers; template struct GuoZhaoLbExternalHelpers; /// This structure forwards the calls to the appropriate Guo Zhao helper class template struct GuoZhaoLbHelpers { static T equilibrium(int iPop, T epsilon, T rho, const T u[DESCRIPTOR::d], const T uSqr) { return GuoZhaoLbDynamicsHelpers ::equilibrium(iPop, epsilon, rho, u, uSqr); } static T bgkCollision(Cell& cell, T const& epsilon, T const& rho, const T u[DESCRIPTOR::d], T const& omega) { return GuoZhaoLbDynamicsHelpers ::bgkCollision(cell, epsilon, rho, u, omega); } static void updateGuoZhaoForce(Cell& cell, const T u[DESCRIPTOR::d]) { GuoZhaoLbExternalHelpers::updateGuoZhaoForce(cell, u); } static void addExternalForce(Cell& cell, const T u[DESCRIPTOR::d], T omega, T rho, T epsilon=(T)1) { GuoZhaoLbExternalHelpers::addExternalForce(cell, u, omega, rho, epsilon); } }; // struct GuoZhaoLbHelpers /// All Guo Zhao helper functions are inside this structure template struct GuoZhaoLbDynamicsHelpers { /// Computation of Guo Zhao equilibrium distribution - original (compressible) formulation following Guo and Zhao (2002). static T forceEquilibrium(int iPop, T epsilon, T rho, const T u[DESCRIPTORBASE::d], const T force[DESCRIPTORBASE::d], T nu) { } /// Computation of Guo Zhao equilibrium distribution - original (compressible) formulation following Guo and Zhao (2002). static T equilibrium(int iPop, T epsilon, T rho, const T u[DESCRIPTORBASE::d], const T uSqr) { T c_u = T(); for (int iD=0; iD < DESCRIPTORBASE::d; ++iD) { c_u += descriptors::c(iPop,iD)*u[iD]; } return rho * descriptors::t(iPop) * ( (T)1 + descriptors::invCs2() * c_u + descriptors::invCs2() * descriptors::invCs2()/((T)2*epsilon) * c_u*c_u - descriptors::invCs2()/((T)2*epsilon) * uSqr ) - descriptors::t(iPop); } /// Guo Zhao BGK collision step static T bgkCollision(CellBase& cell, T const& epsilon, T const& rho, const T u[DESCRIPTORBASE::d], T const& omega) { const T uSqr = util::normSqr(u); for (int iPop=0; iPop < DESCRIPTORBASE::q; ++iPop) { cell[iPop] *= (T)1-omega; cell[iPop] += omega * GuoZhaoLbDynamicsHelpers::equilibrium ( iPop, epsilon, rho, u, uSqr ); } return uSqr; } }; // struct GuoZhaoLbDynamicsHelpers /// Helper functions for dynamics that access external field template /// Updates Guo Zhao porous force struct GuoZhaoLbExternalHelpers { static void updateGuoZhaoForce(Cell& cell, const T u[DESCRIPTOR::d]) { T epsilon = *cell.template getFieldPointer(); T k = *cell.template getFieldPointer(); T nu = *cell.template getFieldPointer(); T* force[DESCRIPTOR::d]; for (int iDim=0; iDim () + iDim; } T bodyF[DESCRIPTOR::d]; for (int iDim=0; iDim ()[iDim]; } T uMag = 0.; for (int iDim=0; iDim & cell, const T u[DESCRIPTOR::d], T omega, T rho, T epsilon) { T* force = cell.template getFieldPointer(); for (int iPop=0; iPop < DESCRIPTOR::q; ++iPop) { T c_u = T(); for (int iD=0; iD < DESCRIPTOR::d; ++iD) { c_u += descriptors::c(iPop,iD)*u[iD]; } c_u *= descriptors::invCs2()*descriptors::invCs2()/epsilon; T forceTerm = T(); for (int iD=0; iD < DESCRIPTOR::d; ++iD) { forceTerm += ( (epsilon*(T)descriptors::c(iPop,iD)-u[iD]) * descriptors::invCs2()/epsilon + c_u * descriptors::c(iPop,iD) ) * force[iD]; } forceTerm *= descriptors::t(iPop); forceTerm *= T(1) - omega/T(2); forceTerm *= rho; cell[iPop] += forceTerm; } } }; // struct GuoZhaoLbExternalHelpers } // namespace olb #endif