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

📄 inamuronewtonraphsondynamics.hh

📁 open lattice boltzmann project www.openlb.org
💻 HH
📖 第 1 页 / 共 2 页
字号:
/*  This file is part of the OpenLB library * *  Copyright (C) 2006, Orestis Malaspinas and Jonas Latt *  Address: Rue General Dufour 24,  1211 Geneva 4, Switzerland  *  E-mail: jonas.latt@gmail.com * *  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 INAMURO_NEWTON_RAPHSON_DYNAMICS_HH#define INAMURO_NEWTON_RAPHSON_DYNAMICS_HH#include "inamuroNewtonRaphsonDynamics.h"#include "core/latticeDescriptors.h"#include "core/util.h"#include "core/lbHelpers.h"#include <cmath>namespace olb {using namespace descriptors;template<typename T, template<typename U> class Lattice, typename Dynamics, int direction, int orientation>InamuroNewtonRaphsonDynamics<T,Lattice,Dynamics,direction,orientation>::InamuroNewtonRaphsonDynamics (        T omega_, Momenta<T,Lattice>& momenta_ )    : BasicDynamics<T,Lattice>(momenta_),      boundaryDynamics(omega_, momenta_){    xi[0] = (T)1;    for (int iDim = 1; iDim < Lattice<T>::d; ++iDim)    {        xi[iDim] = T();    }}template<typename T, template<typename U> class Lattice, typename Dynamics, int direction, int orientation>InamuroNewtonRaphsonDynamics<T,Lattice,Dynamics,direction,orientation>*    InamuroNewtonRaphsonDynamics<T,Lattice, Dynamics, direction, orientation>::clone() const{    return new InamuroNewtonRaphsonDynamics<T,Lattice,Dynamics,direction,orientation>(*this);}template<typename T, template<typename U> class Lattice, typename Dynamics, int direction, int orientation>T InamuroNewtonRaphsonDynamics<T,Lattice, Dynamics, direction, orientation>::    computeEquilibrium(int iPop, T rho, const T u[Lattice<T>::d], T uSqr) const{    return boundaryDynamics.computeEquilibrium(iPop, rho, u, uSqr);}template<typename T, template<typename U> class Lattice, typename Dynamics, int direction, int orientation>void InamuroNewtonRaphsonDynamics<T,Lattice,Dynamics,direction,orientation>::collide (        Cell<T,Lattice>& cell,        LatticeStatistics<T>& statistics ){    typedef Lattice<T> L;    T rho, u[L::d];    this->momenta.computeRhoU(cell,rho,u);    std::vector<int> missingIndexes = util::subIndexOutgoing<L,direction,orientation>();    std::vector<int> knownIndexes;    bool test[L::q];    for (int iPop = 0; iPop < L::q; ++iPop)    {        test[iPop] = true;    }    for (unsigned iPop = 0; iPop < missingIndexes.size(); ++iPop)    {        test[missingIndexes[iPop]] = false;    }    for (int iPop = 0; iPop < L::q; ++iPop)    {        if (test[iPop])        {            knownIndexes.push_back(iPop);        }    }    T approxMomentum[L::d];    computeApproxMomentum(approxMomentum,cell,rho,u,xi,knownIndexes,missingIndexes);    T error = computeError(rho, u,approxMomentum);    int counter = 0;    while (error > 1.0e-15)    {        ++counter;        T gradError[L::d], gradGradError[L::d][L::d];        computeGradGradError(gradGradError,gradError,rho,u,xi,approxMomentum,missingIndexes);        bool everythingWentFine = newtonRaphson(xi,gradError,gradGradError);        if ((counter > 100000) || everythingWentFine == false)        {            // if we need more that 100000 iterations or            // if we have a problem with the inversion of the             // jacobian matrix, we stop the program and            // print this error message on the screen.            std::cout << "Failed to converge....\n";            std::cout << "Error = " << error << "\n";            std::cout << "u = (" << rho*u[0];            for (int iD=1; iD<Lattice<T>::d; ++iD) {                std::cout << ", " << rho*u[iD];            }            std::cout << ")\n";            std::cout << "uApprox = (" << approxMomentum[0];            for (int iD=1; iD<Lattice<T>::d; ++iD) {                std::cout << ", " << approxMomentum[iD];            }            std::cout << ")\n";            std::cout << "xi = (" << xi[0];            for (int iD=1; iD<Lattice<T>::d; ++iD) {                std::cout << ", " << xi[iD];            }            std::cout << ")\n";            exit(1);        }        computeApproxMomentum(approxMomentum,cell,rho,u,xi,knownIndexes,missingIndexes);        error = computeError(rho, u,approxMomentum);    }    T uCs[L::d];    int counterDim = 0;    for (int iDim = 0; iDim < L::d; ++iDim)    {        if (direction == iDim)        {            ++counterDim;            uCs[iDim] = u[iDim];        }        else        {            uCs[iDim] = u[iDim] + xi[iDim+1-counterDim];        }    }    T uCsSqr = util::normSqr<T,L::d>(uCs);    for (unsigned iPop = 0; iPop < missingIndexes.size(); ++iPop)    {        cell[missingIndexes[iPop]] = computeEquilibrium(missingIndexes[iPop],xi[0],uCs,uCsSqr);    }    boundaryDynamics.collide(cell, statistics);}template<typename T, template<typename U> class Lattice, typename Dynamics, int direction, int orientation>void InamuroNewtonRaphsonDynamics<T,Lattice,Dynamics,direction,orientation>::staticCollide (        Cell<T,Lattice>& cell,        const T u[Lattice<T>::d],        LatticeStatistics<T>& statistics ){    typedef Lattice<T> L;        T rho = this->momenta.computeRho(cell);    std::vector<int> missingIndexes = util::subIndexOutgoing<L,direction,orientation>();    std::vector<int> knownIndexes;    bool test[L::q];    for (int iPop = 0; iPop < L::q; ++iPop)    {        test[iPop] = true;    }    for (unsigned iPop = 0; iPop < missingIndexes.size(); ++iPop)    {        test[missingIndexes[iPop]] = false;    }    for (int iPop = 0; iPop < L::q; ++iPop)    {        if (test[iPop])        {            knownIndexes.push_back(iPop);        }    }    T approxMomentum[L::d];    computeApproxMomentum(approxMomentum,cell,rho,u,xi,knownIndexes,missingIndexes);    T error = computeError(rho, u,approxMomentum);    int counter = 0;    while (error > 1.0e-15)    {        ++counter;        T gradError[L::d], gradGradError[L::d][L::d];        computeGradGradError(gradGradError,gradError,rho,u,xi,approxMomentum,missingIndexes);        bool everythingWentFine = newtonRaphson(xi,gradError,gradGradError);        if ((counter > 100000) || everythingWentFine == false)        {            // if we need more that 100000 iterations or            // if we have a problem with the inversion of the             // jacobian matrix, we stop the program and            // print this error message on the screen.            std::cout << "Failed to converge....\n";            std::cout << "Error = " << error << "\n";            std::cout << "u = (" << rho*u[0];            for (int iD=1; iD<Lattice<T>::d; ++iD) {                std::cout << ", " << rho*u[iD];            }            std::cout << ")\n";            std::cout << "uApprox = (" << approxMomentum[0];            for (int iD=1; iD<Lattice<T>::d; ++iD) {                std::cout << ", " << approxMomentum[iD];            }            std::cout << ")\n";            std::cout << "xi = (" << xi[0];            for (int iD=1; iD<Lattice<T>::d; ++iD) {                std::cout << ", " << xi[iD];            }            std::cout << ")\n";            exit(1);        }        computeApproxMomentum(approxMomentum,cell,rho,u,xi,knownIndexes,missingIndexes);        error = computeError(rho, u,approxMomentum);    }    T uCs[L::d];    int counterDim = 0;    for (int iDim = 0; iDim < L::d; ++iDim)    {        if (direction == iDim)        {            ++counterDim;            uCs[iDim] = u[iDim];        }        else        {            uCs[iDim] = u[iDim] + xi[iDim+1-counterDim];        }    }    T uCsSqr = util::normSqr<T,L::d>(uCs);    for (unsigned iPop = 0; iPop < missingIndexes.size(); ++iPop)    {        cell[missingIndexes[iPop]] = computeEquilibrium(missingIndexes[iPop],xi[0],uCs,uCsSqr);    }    boundaryDynamics.staticCollide(cell, u, statistics);}template<typename T, template<typename U> class Lattice, typename Dynamics, int direction, int orientation>T InamuroNewtonRaphsonDynamics<T,Lattice,Dynamics,direction,orientation>::getOmega() const {    return boundaryDynamics.getOmega();}template<typename T, template<typename U> class Lattice, typename Dynamics, int direction, int orientation>void InamuroNewtonRaphsonDynamics<T,Lattice,Dynamics,direction,orientation>::setOmega(T omega_){    boundaryDynamics.setOmega(omega_);}template<typename T, template<typename U> class Lattice, typename Dynamics, int direction, int orientation>T InamuroNewtonRaphsonDynamics<T,Lattice,Dynamics,direction,orientation>::getParameter(int whichParameter) const {    return boundaryDynamics.getParameter(whichParameter);}template<typename T, template<typename U> class Lattice, typename Dynamics, int direction, int orientation>void InamuroNewtonRaphsonDynamics<T,Lattice,Dynamics,direction,orientation>::setParameter(int whichParameter, T value){    boundaryDynamics.setParameter(whichParameter, value);}template<typename T, template<typename U> class Lattice, typename Dynamics, int direction, int orientation>void InamuroNewtonRaphsonDynamics<T,Lattice,Dynamics,direction,orientation>::    computeApproxMomentum(T approxMomentum[Lattice<T>::d],const Cell<T,Lattice> &cell,        const T &rho, const T u[Lattice<T>::d], const T xi[Lattice<T>::d],        const std::vector<int> knownIndexes,const std::vector<int> missingIndexes){    typedef Lattice<T> L;    T csVel[L::d];    int counter = 0;    for (int iDim = 0; iDim < L::d; ++iDim)    {        if (direction == iDim)        {            ++counter;            csVel[iDim] = u[iDim];        }        else        {            csVel[iDim] = u[iDim] + xi[iDim+1-counter];        }    }    T csVelSqr = util::normSqr<T,L::d>(csVel);    for (int iDim = 0; iDim < L::d; ++iDim)    {        approxMomentum[iDim] = T();        for (unsigned iPop = 0; iPop < knownIndexes.size(); ++iPop)

⌨️ 快捷键说明

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