⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 lbhelpers.h

📁 open lattice boltzmann project www.openlb.org
💻 H
📖 第 1 页 / 共 2 页
字号:
        T rho = T();        for (int iPop=0; iPop < Descriptor::q; ++iPop) {            rho += cell[iPop];        }        rho += (T)1;        return rho;    }    /// Computation of momentum    static void computeJ(T const* cell, T j[Descriptor::d]) {        for (int iD=0; iD < Descriptor::d; ++iD) {            j[iD] = T();        }        for (int iPop=0; iPop < Descriptor::q; ++iPop) {            for (int iD=0; iD < Descriptor::d; ++iD) {                j[iD] += cell[iPop]*Descriptor::c[iPop][iD];            }        }    }    /// Computation of hydrodynamic variables    static void computeRhoU(T const* cell, T& rho, T u[Descriptor::d]) {        rho = T();        for (int iD=0; iD < Descriptor::d; ++iD) {            u[iD] = T();        }        for (int iPop=0; iPop < Descriptor::q; ++iPop) {            rho += cell[iPop];            for (int iD=0; iD < Descriptor::d; ++iD) {                u[iD] += cell[iPop]*Descriptor::c[iPop][iD];            }        }        rho += (T)1;        for (int iD=0; iD < Descriptor::d; ++iD) {            u[iD] /= rho;        }    }    /// Computation of stress tensor    static void computeStress(T const* cell, T rho, const T u[Descriptor::d],                              T pi[util::TensorVal<Descriptor>::n] )    {        int iPi = 0;        for (int iAlpha=0; iAlpha < Descriptor::d; ++iAlpha) {            for (int iBeta=iAlpha; iBeta < Descriptor::d; ++iBeta) {                pi[iPi] = T();                for (int iPop=0; iPop < Descriptor::q; ++iPop) {                    pi[iPi] += Descriptor::c[iPop][iAlpha]*                               Descriptor::c[iPop][iBeta] * cell[iPop];                }                // stripe off equilibrium contribution                pi[iPi] -= rho*u[iAlpha]*u[iBeta];                if (iAlpha==iBeta) {                    pi[iPi] -= 1./Descriptor::invCs2*(rho-(T)1);                }                ++iPi;            }        }    }        /// Computation of all hydrodynamic variables    static void computeAllMomenta(T const* cell, T& rho, T u[Descriptor::d],                                  T pi[util::TensorVal<Descriptor>::n] )    {        computeRhoU(cell, rho, u);        computeStress(cell, rho, u, pi);    }    static void modifyVelocity(T* cell, const T newU[Descriptor::d]) {        T rho, oldU[Descriptor::d];        computeRhoU(cell, rho, oldU);        const T oldUSqr = util::normSqr<T,Descriptor::d>(oldU);        const T newUSqr = util::normSqr<T,Descriptor::d>(newU);        for (int iPop=0; iPop<Descriptor::q; ++iPop) {            cell[iPop] = cell[iPop]                             - equilibrium(iPop, rho, oldU, oldUSqr)                             + equilibrium(iPop, rho, newU, newUSqr);        }    }};  // struct lbDynamicsHelpers/// Helper functions for dynamics that access external fieldtemplate<typename T, template<typename U> class Lattice>struct lbExternalHelpers {    /// Add a force term after BGK collision    static void addExternalForce(Cell<T,Lattice>& cell, const T u[Lattice<T>::d], T omega, T amplitude) {        static const int forceBeginsAt = Lattice<T>::ExternalField::forceBeginsAt;        T* force = cell.getExternal(forceBeginsAt);        for (int iPop=0; iPop < Lattice<T>::q; ++iPop) {            T c_u = T();            for (int iD=0; iD < Lattice<T>::d; ++iD) {               c_u += Lattice<T>::c[iPop][iD]*u[iD];            }            c_u *= Lattice<T>::invCs2 * Lattice<T>::invCs2;            T forceTerm = T();            for (int iD=0; iD < Lattice<T>::d; ++iD) {                forceTerm +=                    (   (Lattice<T>::c[iPop][iD]-u[iD]) * Lattice<T>::invCs2                      + c_u * Lattice<T>::c[iPop][iD]                    )                    * force[iD];            }            forceTerm *= Lattice<T>::t[iPop];            forceTerm *= 1-omega/(T)2;            forceTerm *= amplitude;            cell[iPop] += forceTerm;        }    }};  // struct externalFieldHelpers/// Helper functions with full-lattice accesstemplate<typename T, template<typename U> class Lattice>struct lbLatticeHelpers {    /// Swap ("bounce-back") values of a cell (2D), and apply streaming step    static void swapAndStream2D(Cell<T,Lattice> **grid, int iX, int iY)    {        const int half = Lattice<T>::q/2;        for (int iPop=1; iPop<=half; ++iPop) {            int nextX = iX + Lattice<T>::c[iPop][0];            int nextY = iY + Lattice<T>::c[iPop][1];            T fTmp                   = grid[iX][iY][iPop];            grid[iX][iY][iPop]       = grid[iX][iY][iPop+half];            grid[iX][iY][iPop+half]  = grid[nextX][nextY][iPop];            grid[nextX][nextY][iPop] = fTmp;         }    }    /// Swap ("bounce-back") values of a cell (3D), and apply streaming step    static void swapAndStream3D(Cell<T,Lattice> ***grid,                                int iX, int iY, int iZ)    {        const int half = Lattice<T>::q/2;        for (int iPop=1; iPop<=half; ++iPop) {            int nextX = iX + Lattice<T>::c[iPop][0];            int nextY = iY + Lattice<T>::c[iPop][1];            int nextZ = iZ + Lattice<T>::c[iPop][2];            T fTmp                          = grid[iX][iY][iZ][iPop];            grid[iX][iY][iZ][iPop]          = grid[iX][iY][iZ][iPop+half];            grid[iX][iY][iZ][iPop+half]     = grid[nextX][nextY][nextZ][iPop];            grid[nextX][nextY][nextZ][iPop] = fTmp;         }    }};/// All boundary helper functions are inside this structuretemplate<typename T, template<typename U> class Lattice, int direction, int orientation>struct BoundaryHelpers {    static void computeStress (         Cell<T,Lattice> const& cell, T rho, const T u[Lattice<T>::d],         T pi[util::TensorVal<Lattice<T> >::n] )    {        typedef Lattice<T> L;        const T uSqr = util::normSqr<T,L::d>(u);        std::vector<int> const& onWallIndices = util::subIndex<L, direction, 0>();        std::vector<int> const& normalIndices = util::subIndex<L, direction, orientation>();        T fNeq[Lattice<T>::q];        for (unsigned fIndex=0; fIndex<onWallIndices.size(); ++fIndex) {            int iPop = onWallIndices[fIndex];            fNeq[iPop] =                cell[iPop] -                lbHelpers<T,Lattice>::equilibrium(iPop, rho, u, uSqr);        }        for (unsigned fIndex=0; fIndex<normalIndices.size(); ++fIndex) {            int iPop = normalIndices[fIndex];            if (iPop == 0) {                fNeq[iPop] = T();  // fNeq[0] will not be used anyway            }            else {                fNeq[iPop] =                    cell[iPop] -                    lbHelpers<T,Lattice>::equilibrium(iPop, rho, u, uSqr);            }        }        int iPi = 0;        for (int iAlpha=0; iAlpha<L::d; ++iAlpha) {            for (int iBeta=iAlpha; iBeta<L::d; ++iBeta) {                pi[iPi] = T();                for (unsigned fIndex=0; fIndex<onWallIndices.size(); ++fIndex)                {                    const int iPop = onWallIndices[fIndex];                    pi[iPi] +=                        L::c[iPop][iAlpha]*L::c[iPop][iBeta]*fNeq[iPop];                }                for (unsigned fIndex=0; fIndex<normalIndices.size(); ++fIndex)                {                    const int iPop = normalIndices[fIndex];                    pi[iPi] += (T)2 * L::c[iPop][iAlpha]*L::c[iPop][iBeta]*                               fNeq[iPop];                }                ++iPi;            }        }    }};  // struct boundaryHelpers}  // namespace olb// The specialized code is directly included. That is because we never want// it to be precompiled so that in both the precompiled and the// "include-everything" version, the compiler can apply all the// optimizations it wants.#include "lbHelpers2D.h"#include "lbHelpers3D.h"#endif

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -