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

📄 poiseuille.cpp

📁 open lattice boltzmann project www.openlb.org
💻 CPP
字号:
/*  This file is part of the OpenLB library * *  Copyright (C) 2007 Orestis Malaspinas, 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.*/#include <vector>#include <cmath>#include <iostream>#include <iomanip>#include <fstream>#include "olb2D.h"#include "olb2D.hh"   // Use only generic version!#define DESCRIPTOR MRTD2Q9Descriptorusing namespace olb;using namespace olb::descriptors;using namespace olb::graphics;using namespace std;typedef enum {velocity, pressure} BoundaryType;typedef double T;T poiseuilleVelocity(int iY, LBunits<T> const& converter) {    T y = (T)iY / converter.getResolution();    return 4.*converter.getLatticeU() * (y-y*y);}T poiseuillePressure(int iX, LBunits<T> const& converter) {    T Lx = converter.getNx()-1;    T Ly = converter.getNy()-1;    return 8.*converter.getLatticeNu()*converter.getLatticeU() / (Ly*Ly) * (Lx/(T)2-(T)iX);}void iniGeometry( BlockStructure2D<T, DESCRIPTOR>& lattice,                  LBunits<T> const& converter,                  Dynamics<T, DESCRIPTOR>& bulkDynamics,                  OnLatticeBoundaryCondition2D<T,DESCRIPTOR>& boundaryCondition,                  BoundaryType boundaryType ){    int nx = converter.getNx();    int ny = converter.getNy();    T   omega = converter.getOmega();    lattice.defineDynamics(0,nx-1, 0,ny-1, &bulkDynamics);    boundaryCondition.addVelocityBoundary1P(1,nx-2,ny-1,ny-1, omega);    boundaryCondition.addVelocityBoundary1N(1,nx-2,   0,   0, omega);    if (boundaryType==velocity) {        boundaryCondition.addVelocityBoundary0N(0,0, 1, ny-2, omega);        boundaryCondition.addVelocityBoundary0P(nx-1,nx-1, 1, ny-2, omega);    }    else {        boundaryCondition.addPressureBoundary0N(0,0, 1, ny-2, omega);        boundaryCondition.addPressureBoundary0P(nx-1,nx-1, 1, ny-2, omega);    }    boundaryCondition.addExternalVelocityCornerNN(0,0, omega);    boundaryCondition.addExternalVelocityCornerNP(0,ny-1, omega);    boundaryCondition.addExternalVelocityCornerPN(nx-1,0, omega);    boundaryCondition.addExternalVelocityCornerPP(nx-1,ny-1, omega);    for (int iX=0; iX<nx; ++iX) {        for (int iY=0; iY<ny; ++iY) {            T u[2] = {poiseuilleVelocity(iY, converter),0.};            T rho = (T)1 + poiseuillePressure(iX, converter) * DESCRIPTOR<T>::invCs2;            lattice.get(iX,iY).defineRhoU(rho, u);            lattice.get(iX,iY).iniEquilibrium(rho, u);        }    }    lattice.initialize();}void plotStatistics(int                              iT,                    BlockStructure2D<T, DESCRIPTOR>& lattice,                    LBunits<T>&                      converter,                    T                                middleU){    T dx = converter.getDeltaX();    T dt = converter.getDeltaT();    cout << "Iteration " << setw(5) << iT;    cout << "; t=" << setprecision(3) << setw(6)         << iT*converter.getDeltaT();    cout << "; E=" << setprecision(10) << setw(15)         << lattice.getStatistics().getAverageEnergy()*dx*dx/dt/dt;    cout << "; rho=" << setprecision(8) << setw(11)         << lattice.getStatistics().getAverageRho();    cout << "; uMax= " << setprecision(8) << setw(11)         << middleU*dx/dt;    cout << endl;}void produceGif(int iT, BlockStructure2D<T, DESCRIPTOR>& lattice) {    const int imSize = 400;    DataAnalysisBase2D<T,DESCRIPTOR> const& analysis = lattice.getDataAnalysis();    ImageWriter<T> imageWriter("leeloo");    imageWriter.writeScaledGif(createFileName("p", iT, 6),                                analysis.getPressure(), imSize, imSize);    imageWriter.writeScaledGif(createFileName("u", iT, 6),                                analysis.getVelocityNorm(), imSize, imSize);}void writeProfile ( string fName,                    BlockStructure2D<T, DESCRIPTOR>& lattice,                    LBunits<T>& converter ){    ofstream *ofile = 0;    if (singleton::mpi().isMainProcessor()) {        ofile = new ofstream((singleton::directories().getLogOutDir()+fName).c_str());    }    for (int iY=0; iY<converter.getNy(); ++iY) {        T dx = converter.getDeltaX();        T dt = converter.getDeltaT();        T analytical = poiseuilleVelocity(iY, converter);        T numerical[2];        lattice.get(converter.getNx()/2, iY).computeU(numerical);        if (singleton::mpi().isMainProcessor()) {            *ofile << iY*dx << " " << analytical*dx/dt                            << " " << numerical[0]*dx/dt << "\n";        }    }    delete ofile;}int main(int argc, char* argv[]) {    olbInit(&argc, &argv);    singleton::directories().setOutputDir("./tmp/");    const BoundaryType boundaryType = velocity;    const T uMax = 0.02;    const T Re   = 10.;    const int N  = 50;    const T lx   = 2.;    const T ly   = 1.;    const int maxIter  = 20000;    const int saveIter = 2000;    const int statIter = 100;    LBunits<T> converter(uMax, Re, N, lx, ly);    writeLogFile(converter, "2D Poiseuille flow");#ifndef PARALLEL_MODE_MPI  // sequential program execution    BlockLattice2D<T, DESCRIPTOR> lattice(converter.getNx(), converter.getNy() );#else                      // parallel program execution    MultiDataDistribution2D distribution =        createRegularDataDistribution( converter.getNx(), converter.getNy() );    MultiBlockLattice2D<T, DESCRIPTOR> lattice(distribution);#endif    // Choose between local and non-local boundary condition    OnLatticeBoundaryCondition2D<T,DESCRIPTOR>* boundaryCondition =            createLocalBoundaryCondition2D<T,DESCRIPTOR,MRTdynamics<T,DESCRIPTOR> >(lattice);            // createInterpBoundaryCondition2D<T,DESCRIPTOR,MRTdynamics<T,DESCRIPTOR> >(lattice);    MRTdynamics<T, DESCRIPTOR> bulkDynamics (                      converter.getOmega(),                      instances::getBulkMomenta<T,DESCRIPTOR>()    );    iniGeometry(lattice, converter, bulkDynamics, *boundaryCondition, boundaryType);    for (int iT=0; iT<maxIter; ++iT) {        if (iT%statIter==0) {            T middleU[2];            lattice.get(converter.getNx()/2, converter.getNy()/2).computeU(middleU);            plotStatistics(iT, lattice, converter, middleU[0]);        }        if (iT%saveIter==0) {            produceGif(iT, lattice);            writeProfile("centerVel.dat", lattice, converter);        }        lattice.collideAndStream();    }    delete boundaryCondition;}

⌨️ 快捷键说明

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