Skip to content

OpenFOAM

OpenFOAM交流区

5.3k 主题 31.3k 帖子
  • OpenFOAM 粗糙度

    13
    13 帖子
    13k 浏览

    @Regina roughnessHeight是粗糙度高度,不同的材料有着不同的参数,roughnessConstant是粗糙度常数的意思,fluent默认0.5;其他的就不清楚了,抱歉

  • CFDEM中如何监测颗粒流速

    3
    3 帖子
    1k 浏览

    @chapaofan 非常感谢老师提供思路!

  • Openfoam 实现fluent薄壳传热边界设置

    1
    1 帖子
    536 浏览

    计算火焰对铜管的加热,火焰仿真已经解决,现在需要考虑流固耦合对流换热和铜的热传导。
    方案1.网格目前只考虑流体网格,暂时不考虑固体网格。已知fluent中有类似的薄壳边界可以实现,openfoam中pyrolysisZones貌似能实现。
    方案1存在问题:1)设置指导;2)pyrolysisZones能考虑三维传热吗?还是只能一维径向?
    方案2.划分流体区域和固体区域,耦合计算。
    方案2存在问题:固体部分不熟悉,网格耦合和区域划分设置求指导还有就是tut参照。:140:

  • 同心圆柱体wedge的使用

    4
    4 帖子
    1k 浏览
    K

    @Kong action用的是delete也不行,或者🧵new建立一个obstacal然后再invert也没有成功删除

  • denseParticleFoam的问题

    2
    2 帖子
    901 浏览
    李东岳

    你的求解器某个模型需要调用phi,但是这个求解器里面的phi叫做phi.air或者phi.water啥的,你得看看你的哪个设置调用了phi

  • CFDEM中的并行运算问题

    4
    4 帖子
    2k 浏览
    B

    时隔一个月说一下结果,这样做不会报错,不过liggghts运算显示的是1×1×4(假设分成四个processor),但是of里的确是scotch划分的,不知道liggghts有没有自动识别:136:

  • 2 帖子
    953 浏览
    S

    各位大佬好,目前我在用OpenFOAM做多浮体在波浪作用下的数值模拟。有些问题想要请教:
    1、在constant文件夹中有dynamicMeshDict文件,在之前的学习过程中我主要接触到的是sixDoFRigidBodyMotion和rigidBodyMotion这两类求解器。据我目前了解,前者只可以用来模拟单物体,后者可以模拟多物体。不知我理解的是否正确?
    2、在学习过程中,我对一些算例进行sixDoFRigidBodyMotion和rigidBodyMotion这两类求解器的计算结果比较,目前是找到了两个算例,分别是OpenFOAM中tutorials/multiphase/interFoam/RAS/floatingObject以及foamMooring中关于overset的算例,连接如下:https://gitlab.com/hfchen20/foamMooring/-/tree/master/tutorial/rgb_overset?ref_type=heads
    我对这两个算例都分别使用采用sixDoFRigidBodyMotion和rigidBodyMotion的dynamicMeshDict进行了试算比较。然后发现计算得到的结果,如物体的位移、旋转的角度时程曲线基本一致。但是当我在此基础上新设算例,就是在dynamicMeshDict中加入一个linearAxialAngularSpring后,再计算出来的结果就会出现较大不同,这可能是哪些原因导致的呢?
    以下是我整理后画出来的时程图:

    floatingObject算例
    微信图片_20240829202727.png 微信图片_20240829202740.png 微信图片_20240829202756.png 微信图片_20240829202807.png 微信图片_20240829202816.png
    上面是没有加linearAxialAngularSpring,下面是加了之后的:
    微信图片_20240829203048.png 微信图片_20240829203056.png 微信图片_20240829203102.png 微信图片_20240829203109.png 微信图片_20240829203117.png

    这是dynamicMeshDict代码对比:

    /*--------------------------------*- C++ -*----------------------------------*\ | ========= | | | \\ / F ield | OpenFOAM: The Open Source CFD Toolbox | | \\ / O peration | Version: v2012 | | \\ / A nd | Website: www.openfoam.com | | \\/ M anipulation | | \*---------------------------------------------------------------------------*/ FoamFile { version 2.0; format ascii; class dictionary; object dynamicMeshDict; } // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // dynamicFvMesh dynamicMotionSolverFvMesh; motionSolverLibs (rigidBodyMeshMotion); motionSolver rigidBodyMotion; rigidBodyMotionCoeffs { report on; solver { type Newmark; } accelerationRelaxation 0.7; bodies { floatingObject { type cuboid; parent root; // Cuboid dimensions Lx 0.3; Ly 0.2; Lz 0.5; // Density of the cuboid rho 500; // Cuboid mass mass #eval{ $rho*$Lx*$Ly*$Lz }; L ($Lx $Ly $Lz); centreOfMass (0 0 0.25); transform (1 0 0 0 1 0 0 0 1) (0.5 0.45 0.1); joint { type composite; joints ( { type Py; } { type Ry; } ); } patches (floatingObject); innerDistance 0.05; outerDistance 0.35; } } restraints { /*axialSpring { type linearAxialAngularSpring; body floatingObject; axis (0 1 0); stiffness 10; damping 0; referenceOrientation (1 0 0 0 1 0 0 0 1); }*/ } } // ************************************************************************* // /*--------------------------------*- C++ -*----------------------------------*\ | ========= | | | \\ / F ield | OpenFOAM: The Open Source CFD Toolbox | | \\ / O peration | Version: v2012 | | \\ / A nd | Website: www.openfoam.com | | \\/ M anipulation | | \*---------------------------------------------------------------------------*/ FoamFile { version 2.0; format ascii; class dictionary; object dynamicMeshDict; } // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // dynamicFvMesh dynamicMotionSolverFvMesh; motionSolverLibs (sixDoFRigidBodyMotion); motionSolver sixDoFRigidBodyMotion; sixDoFRigidBodyMotionCoeffs { patches (floatingObject); innerDistance 0.05; outerDistance 0.35; centreOfMass (0.5 0.45 0.35); // Cuboid dimensions Lx 0.3; Ly 0.2; Lz 0.5; // Density of the solid rhoSolid 500; // Cuboid mass mass #eval{ $rhoSolid*$Lx*$Ly*$Lz }; // Cuboid moment of inertia about the centre of mass momentOfInertia #codeStream { codeInclude #{ #include "diagTensor.H" #}; code #{ scalar sqrLx = sqr($Lx); scalar sqrLy = sqr($Ly); scalar sqrLz = sqr($Lz); os << $mass *diagTensor(sqrLy + sqrLz, sqrLx + sqrLz, sqrLx + sqrLy)/12.0; #}; }; report on; accelerationRelaxation 0.7; //accelerationDamping 0; solver { type Newmark; } constraints { // fixedPoint // { // sixDoFRigidBodyMotionConstraint point; // centreOfRotation (0.5 0.45 0.1); // } fixedLine { sixDoFRigidBodyMotionConstraint line; centreOfRotation (0.5 0.45 0.1); direction (0 1 0); } fixedAxis { sixDoFRigidBodyMotionConstraint axis; axis (0 1 0); } } /*restraints { axialSpring { sixDoFRigidBodyMotionRestraint linearAxialAngularSpring; axis (0 1 0); stiffness 10; damping 0; referenceOrientation (1 0 0 0 1 0 0 0 1); } }*/ } // ************************************************************************* //

    3.为了搞清楚linearAxialAngularSpring,我还试着对tutorials/incompressible/pimpleFoam/RAS/wingMotion进行改写。因为这个算例中的dynamicMeshDict文件里使用了linearAxialAngularSpring。但是在原版的算例中,其使用的是sixDoFRigidBodyMotion,我想要将他改成rigidBodyMotion,但是我改后的算例只能算0.20s左右就会发散。在此我想请教一下有没有人做过类似的工作,能不能请教一下经验。
    下面是我改的dynamicMeshDict文件:

    /*--------------------------------*- C++ -*----------------------------------*\ | ========= | | | \\ / F ield | OpenFOAM: The Open Source CFD Toolbox | | \\ / O peration | Version: v2012 | | \\ / A nd | Website: www.openfoam.com | | \\/ M anipulation | | \*---------------------------------------------------------------------------*/ FoamFile { version 2.0; format ascii; class dictionary; object dynamicMeshDict; } // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // dynamicFvMesh dynamicMotionSolverFvMesh; motionSolverLibs ("librigidBodyMeshMotion.so"); motionSolver rigidBodyMotion; //accelerationRelaxation 0.4; updateControl timeStep; updateInterval 1; rho rhoInf; rhoInf 1; rigidBodyMotionCoeffs { report on; solver { type symplectic; } rho rhoInf; rhoInf 1; bodies { wing { type rigidBody; parent root; mass 22.9; centreOfMass (0.2474612746 -0.02371895744 0); inertia (1.958864357 0 0 3.920839234 0 2.057121362); // Transformation tensor and centre of rotation transform (0.9953705935 0.09611129781 0 -0.09611129781 0.9953705935 0 0 0 1) (0.25 0.007 0.125); angularMomentum (0 0 -2); joint { type composite; joints ( { type Py; } { type Rz; } ); } patches (wing); innerDistance 0.3; outerDistance 1; } } restraints { verticalSpring { type linearSpring; body wing; anchor (0.25 0.007 0.125); refAttachmentPt (0 0 0); stiffness 4000; damping 2; restLength 0; } axialSpring { type linearAxialAngularSpring; body wing; axis (0 0 1); stiffness 700; damping 0.5; referenceOrientation (0.9953705935 0.09611129781 0 -0.09611129781 0.9953705935 0 0 0 1); } } } // ************************************************************************* //
  • 5 帖子
    2k 浏览

    @李东岳 在 波物作用of仿真:用k-omega SST湍流模型,k和omega初始时刻的值如何设置? 中说:

    瞬态流场的模拟,internalField对结果没有影响,只会影响最初的收敛性。internalField直接取0

    哦哦,老师,那入口处呢?

  • 6 帖子
    5k 浏览
    H

    yes ,i do and it solve.thank you .

  • 9 帖子
    3k 浏览
    李东岳

    :146: :146: :146:

    是的,对算法的理解影响到算例

  • 基于OF重叠网格模拟结构物入水的问题

    16
    16 帖子
    10k 浏览
    Z

    @李东岳 老师你好,我想请问下,设置了重力加速度g后,dynamicDict下不设置初速度,物体不能下落,这是哪里没设置好吗?

  • 关于结构入水的问题有些疑问

    3
    3 帖子
    3k 浏览
    Z

    @李东岳 老师我想请问一下,设置了重力加速度g后,我将dynamicDict文件下将 velcity设为(0 0 0),物体就停着不动了,请问需要怎么设置一下呢。

  • 3 帖子
    1k 浏览

    是不是一开始里面就有水然后没给速度

  • opf计算蒸汽气泡在过冷水中直接接触冷凝问题

    11
    11 帖子
    7k 浏览
    M

    请问大佬您算这个问题用的是哪个求解器,或是在哪个求解器中植入的相变模型

  • 拉格朗日求解器代码求助

    14
    14 帖子
    5k 浏览
    李东岳

    我在几年前做了个一拉格朗日粒子直径变化的代码。我现在已经记不起来太多了。能想起来的是:

    粒子直径跟流场的湍流动能耗散率有关系 植入的是一个跟PBM有关的粒径变化方程,考虑了coalescense和破碎 代码可以编译并且测试过可以体现粒径变化

    可以把下面的MomentumCloud.C:替换到OpenFOAM原来的代码然后编译。搞明白之后看看思路然后适配到你们的算法上。

    MomentumCloud.C:

    /*---------------------------------------------------------------------------*\ ========= | \\ / F ield | OpenFOAM: The Open Source CFD Toolbox \\ / O peration | Website: https://openfoam.org \\ / A nd | Copyright (C) 2011-2021 OpenFOAM Foundation \\/ M anipulation | ------------------------------------------------------------------------------- License This file is part of OpenFOAM. OpenFOAM 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 3 of the License, or (at your option) any later version. OpenFOAM 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 OpenFOAM. If not, see <http://www.gnu.org/licenses/>. \*---------------------------------------------------------------------------*/ #include "MomentumCloud.H" #include "integrationScheme.H" #include "interpolation.H" #include "subCycleTime.H" #include "InjectionModelList.H" #include "DispersionModel.H" #include "PatchInteractionModel.H" #include "StochasticCollisionModel.H" #include "SurfaceFilmModel.H" // * * * * * * * * * * * * * Protected Member Functions * * * * * * * * * * // template<class CloudType> void Foam::MomentumCloud<CloudType>::setModels() { dispersionModel_.reset ( DispersionModel<MomentumCloud<CloudType>>::New ( subModelProperties_, *this ).ptr() ); patchInteractionModel_.reset ( PatchInteractionModel<MomentumCloud<CloudType>>::New ( subModelProperties_, *this ).ptr() ); stochasticCollisionModel_.reset ( StochasticCollisionModel<MomentumCloud<CloudType>>::New ( subModelProperties_, *this ).ptr() ); surfaceFilmModel_.reset ( SurfaceFilmModel<MomentumCloud<CloudType>>::New ( subModelProperties_, *this ).ptr() ); UIntegrator_.reset ( integrationScheme::New ( "U", solution_.integrationSchemes() ).ptr() ); } template<class CloudType> template<class TrackCloudType> void Foam::MomentumCloud<CloudType>::solve ( TrackCloudType& cloud, typename parcelType::trackingData& td ) { if (solution_.steadyState()) { cloud.storeState(); cloud.preEvolve(); evolveCloud(cloud, td); if (solution_.coupled()) { cloud.relaxSources(cloud.cloudCopy()); } } else { ///////////////////////////////// Info<< "Dyfluid: Evolve function in MomentumCloud.C" << nl; List<DynamicList<label>> PartLabelPre(U_.size()); List<DynamicList<label>> PartLabelPost(U_.size()); DynamicList<label> cellWithPartPre; DynamicList<label> cellWithPartPost; pNumber_.primitiveFieldRef() = 0.0; forAllIter(typename MomentumCloud<CloudType>, *this, iter) { parcelType& p = iter(); pNumber_[p.cell()] += p.nParticle(); PartLabelPre[p.cell()].append(p.origId()); } forAll(U_, cell) { if (PartLabelPre[cell].size() != 0) { cellWithPartPre.append(cell); } } //Info<< cellWithPartPre << nl; ///////////////////////////////// cloud.preEvolve(); evolveCloud(cloud, td); if (solution_.coupled()) { cloud.scaleSources(); } ///////////////////////////////// forAllIter(typename MomentumCloud<CloudType>, *this, iter) { parcelType& p = iter(); PartLabelPost[p.cell()].append(p.origId()); } const volScalarField& epsi = U_.mesh().lookupObject<volScalarField>("epsilon.water"); scalar C1 = 0.00481; scalar C2 = 0.08; scalar sigma = 0.072; scalar rhoc = 998.0; scalar D1 = 0.88; scalar D2 = 9e6; scalar muc = 1e-3; const scalar dt = this->mesh().time().deltaTValue(); forAll(U_, cell) { // if there are particles in some cell if (PartLabelPost[cell].size() != 0) { cellWithPartPost.append(cell); scalar allVolume = 0.0; scalar allnParticle = 0.0; scalar allnParticleNew = 0.0; scalar diamAve = 0.0; //Info<< "Cell [" << cell << "] has " << PartLabelPost[cell].size() // << " particles" << nl; // loop all over particles forAllIter(typename MomentumCloud<CloudType>, *this, iter) { parcelType& p = iter(); // loop particles label in this cell forAll(PartLabelPost[cell], i) { // if this particle belongs to this cell if (p.origId() == PartLabelPost[cell](i)) { allVolume += p.nParticle()*M_PI/6.0*pow3(p.d()); allnParticle += p.nParticle(); diamAve = pow(allVolume/allnParticle*6.0/M_PI, 1.0/3.0); //Info<< " Labels are " << PartLabelPost[cell](i) // << ", its nParticle is " << p.nParticle() // << ", volume is " << allVolume << nl; } } } const scalar d = diamAve; // cell manipulation, calculate average diameter if (d > SMALL) { const scalar epsilon = epsi[cell]; scalar gN = allnParticle*C1*pow(epsilon, 1.0/3.0)/pow(d, 2.0/3.0) *exp(-C2*sigma/(rhoc*pow(epsilon, 2.0/3.0)*pow(d, 5.0/3.0))); scalar aSqrN = sqr(allnParticle)*D1*pow(epsilon, 1.0/3.0)*4.0*sqrt(2.0)*pow(d, 7.0/6.0) *exp(-D2*muc*rhoc*epsilon/sqr(sigma)*pow4(d)/16.0); allnParticleNew = allnParticle + (gN - aSqrN)*dt; diamAve = diamAve*pow(allnParticle/allnParticleNew, 1.0/3.0); //Info<< "gN = " << gN << nl; //Info<< "aSqrN = " << aSqrN << nl; //Info<< "Particle increased by " << allnParticleNew - allnParticle << nl; //Info<< "diamAve is " << diamAve << nl; } scalar newVolume = 0.0; forAllIter(typename MomentumCloud<CloudType>, *this, iter) { parcelType& p = iter(); forAll(PartLabelPost[cell], i) { if (p.origId() == PartLabelPost[cell](i)) { p.nParticle() = allnParticleNew/PartLabelPost[cell].size(); p.d() = diamAve; newVolume += p.nParticle()*M_PI/6.0*pow3(p.d()); //Info<< " after brecoa, volume is " << newVolume // << "p.nParticle is " << p.nParticle() << nl; } } } } } ///////////////////////////////// } cloud.info(); cloud.postEvolve(); if (solution_.steadyState()) { cloud.restoreState(); } } template<class CloudType> void Foam::MomentumCloud<CloudType>::buildCellOccupancy() { if (cellOccupancyPtr_.empty()) { cellOccupancyPtr_.reset ( new List<DynamicList<parcelType*>>(this->mesh().nCells()) ); } else if (cellOccupancyPtr_().size() != this->mesh().nCells()) { // If the size of the mesh has changed, reset the // cellOccupancy size cellOccupancyPtr_().setSize(this->mesh().nCells()); } List<DynamicList<parcelType*>>& cellOccupancy = cellOccupancyPtr_(); forAll(cellOccupancy, cO) { cellOccupancy[cO].clear(); } forAllIter(typename MomentumCloud<CloudType>, *this, iter) { cellOccupancy[iter().cell()].append(&iter()); } } template<class CloudType> void Foam::MomentumCloud<CloudType>::updateCellOccupancy() { // Only build the cellOccupancy if the pointer is set, i.e. it has // been requested before. if (cellOccupancyPtr_.valid()) { buildCellOccupancy(); } } template<class CloudType> template<class TrackCloudType> void Foam::MomentumCloud<CloudType>::evolveCloud ( TrackCloudType& cloud, typename parcelType::trackingData& td ) { if (solution_.coupled()) { cloud.resetSourceTerms(); } if (solution_.transient()) { label preInjectionSize = this->size(); this->surfaceFilm().inject(cloud); // Update the cellOccupancy if the size of the cloud has changed // during the injection. if (preInjectionSize != this->size()) { updateCellOccupancy(); preInjectionSize = this->size(); } injectors_.inject(cloud, td); // Assume that motion will update the cellOccupancy as necessary // before it is required. cloud.motion(cloud, td); stochasticCollision().update(td, solution_.trackTime()); } else { // this->surfaceFilm().injectSteadyState(cloud); injectors_.injectSteadyState(cloud, td, solution_.trackTime()); CloudType::move(cloud, td, solution_.trackTime()); } } template<class CloudType> void Foam::MomentumCloud<CloudType>::postEvolve() { Info<< endl; if (debug) { this->writePositions(); } this->dispersion().cacheFields(false); forces_.cacheFields(false); functions_.postEvolve(); solution_.nextIter(); if (this->db().time().writeTime()) { outputProperties_.writeObject ( IOstream::ASCII, IOstream::currentVersion, this->db().time().writeCompression(), true ); } } template<class CloudType> void Foam::MomentumCloud<CloudType>::cloudReset(MomentumCloud<CloudType>& c) { CloudType::cloudReset(c); rndGen_ = c.rndGen_; forces_.transfer(c.forces_); functions_.transfer(c.functions_); injectors_.transfer(c.injectors_); dispersionModel_.reset(c.dispersionModel_.ptr()); patchInteractionModel_.reset(c.patchInteractionModel_.ptr()); stochasticCollisionModel_.reset(c.stochasticCollisionModel_.ptr()); surfaceFilmModel_.reset(c.surfaceFilmModel_.ptr()); UIntegrator_.reset(c.UIntegrator_.ptr()); } // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * // template<class CloudType> Foam::MomentumCloud<CloudType>::MomentumCloud ( const word& cloudName, const volScalarField& rho, const volVectorField& U, const volScalarField& mu, const dimensionedVector& g, const bool readFields ) : CloudType(cloudName, rho, U, mu, g, false), cloudCopyPtr_(nullptr), particleProperties_ ( IOobject ( cloudName + "Properties", this->mesh().time().constant(), this->mesh(), IOobject::MUST_READ_IF_MODIFIED, IOobject::NO_WRITE ) ), outputProperties_ ( IOobject ( cloudName + "OutputProperties", this->mesh().time().timeName(), "uniform"/cloud::prefix/cloudName, this->mesh(), IOobject::READ_IF_PRESENT, IOobject::NO_WRITE ) ), solution_(this->mesh(), particleProperties_.subDict("solution")), constProps_(particleProperties_), subModelProperties_ ( particleProperties_.subOrEmptyDict("subModels", true) ), rndGen_(0), cellOccupancyPtr_(), cellLengthScale_(mag(cbrt(this->mesh().V()))), pNumber_ ( IOobject ( "pNumbers", this->mesh().time().timeName(), this->mesh(), IOobject::NO_READ, IOobject::AUTO_WRITE ), this->mesh(), dimensionedScalar(dimless, 0.0) ), rho_(rho), U_(U), mu_(mu), g_(g), pAmbient_(0.0), forces_ ( *this, this->mesh(), subModelProperties_.subOrEmptyDict ( "particleForces", true ), true ), functions_ ( *this, particleProperties_.subOrEmptyDict("cloudFunctions"), true ), injectors_ ( subModelProperties_.subOrEmptyDict("injectionModels"), *this ), dispersionModel_(nullptr), patchInteractionModel_(nullptr), stochasticCollisionModel_(nullptr), surfaceFilmModel_(nullptr), UIntegrator_(nullptr), UTrans_ ( new volVectorField::Internal ( IOobject ( this->name() + ":UTrans", this->db().time().timeName(), this->db(), IOobject::READ_IF_PRESENT, IOobject::AUTO_WRITE ), this->mesh(), dimensionedVector(dimMass*dimVelocity, Zero) ) ), UCoeff_ ( new volScalarField::Internal ( IOobject ( this->name() + ":UCoeff", this->db().time().timeName(), this->db(), IOobject::READ_IF_PRESENT, IOobject::AUTO_WRITE ), this->mesh(), dimensionedScalar( dimMass, 0) ) ) { setModels(); if (readFields) { parcelType::readFields(*this); this->deleteLostParticles(); } if (solution_.resetSourcesOnStartup()) { resetSourceTerms(); } } template<class CloudType> Foam::MomentumCloud<CloudType>::MomentumCloud ( const word& cloudName, const volScalarField& rho, const volVectorField& U, const dimensionedVector& g, const fluidThermo& carrierThermo, const bool readFields ) : MomentumCloud(cloudName, rho, U, carrierThermo.mu(), g, readFields) {} template<class CloudType> Foam::MomentumCloud<CloudType>::MomentumCloud ( MomentumCloud<CloudType>& c, const word& name ) : CloudType(c, name), cloudCopyPtr_(nullptr), particleProperties_(c.particleProperties_), outputProperties_(c.outputProperties_), solution_(c.solution_), constProps_(c.constProps_), subModelProperties_(c.subModelProperties_), rndGen_(c.rndGen_), cellOccupancyPtr_(nullptr), cellLengthScale_(c.cellLengthScale_), pNumber_(c.pNumber_), rho_(c.rho_), U_(c.U_), mu_(c.mu_), g_(c.g_), pAmbient_(c.pAmbient_), forces_(c.forces_), functions_(c.functions_), injectors_(c.injectors_), dispersionModel_(c.dispersionModel_->clone()), patchInteractionModel_(c.patchInteractionModel_->clone()), stochasticCollisionModel_(c.stochasticCollisionModel_->clone()), surfaceFilmModel_(c.surfaceFilmModel_->clone()), UIntegrator_(c.UIntegrator_->clone()), UTrans_ ( new volVectorField::Internal ( IOobject ( this->name() + ":UTrans", this->db().time().timeName(), this->db(), IOobject::NO_READ, IOobject::NO_WRITE, false ), c.UTrans_() ) ), UCoeff_ ( new volScalarField::Internal ( IOobject ( name + ":UCoeff", this->db().time().timeName(), this->db(), IOobject::NO_READ, IOobject::NO_WRITE, false ), c.UCoeff_() ) ) {} template<class CloudType> Foam::MomentumCloud<CloudType>::MomentumCloud ( const fvMesh& mesh, const word& name, const MomentumCloud<CloudType>& c ) : CloudType(mesh, name, c), cloudCopyPtr_(nullptr), particleProperties_ ( IOobject ( name + "Properties", mesh.time().constant(), mesh, IOobject::NO_READ, IOobject::NO_WRITE, false ) ), outputProperties_ ( IOobject ( name + "OutputProperties", this->mesh().time().timeName(), "uniform"/cloud::prefix/name, this->mesh(), IOobject::NO_READ, IOobject::NO_WRITE, false ) ), solution_(mesh), constProps_(), subModelProperties_(dictionary::null), rndGen_(0), cellOccupancyPtr_(nullptr), cellLengthScale_(c.cellLengthScale_), pNumber_(c.pNumber_), rho_(c.rho_), U_(c.U_), mu_(c.mu_), g_(c.g_), pAmbient_(c.pAmbient_), forces_(*this, mesh), functions_(*this), injectors_(*this), dispersionModel_(nullptr), patchInteractionModel_(nullptr), stochasticCollisionModel_(nullptr), surfaceFilmModel_(nullptr), UIntegrator_(nullptr), UTrans_(nullptr), UCoeff_(nullptr) {} // * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * // template<class CloudType> Foam::MomentumCloud<CloudType>::~MomentumCloud() {} // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * // template<class CloudType> void Foam::MomentumCloud<CloudType>::setParcelThermoProperties ( parcelType& parcel, const scalar lagrangianDt ) { parcel.rho() = constProps_.rho0(); } template<class CloudType> void Foam::MomentumCloud<CloudType>::checkParcelProperties ( parcelType& parcel, const scalar lagrangianDt, const bool fullyDescribed ) { const scalar carrierDt = this->mesh().time().deltaTValue(); parcel.stepFraction() = (carrierDt - lagrangianDt)/carrierDt; if (parcel.typeId() == -1) { parcel.typeId() = constProps_.parcelTypeId(); } } template<class CloudType> void Foam::MomentumCloud<CloudType>::storeState() { cloudCopyPtr_.reset ( static_cast<MomentumCloud<CloudType>*> ( clone(this->name() + "Copy").ptr() ) ); } template<class CloudType> void Foam::MomentumCloud<CloudType>::restoreState() { cloudReset(cloudCopyPtr_()); cloudCopyPtr_.clear(); } template<class CloudType> void Foam::MomentumCloud<CloudType>::resetSourceTerms() { UTransRef().field() = Zero; UCoeffRef().field() = 0.0; } template<class CloudType> template<class Type> void Foam::MomentumCloud<CloudType>::relax ( DimensionedField<Type, volMesh>& field, const DimensionedField<Type, volMesh>& field0, const word& name ) const { const scalar coeff = solution_.relaxCoeff(name); field = field0 + coeff*(field - field0); } template<class CloudType> template<class Type> void Foam::MomentumCloud<CloudType>::scale ( DimensionedField<Type, volMesh>& field, const word& name ) const { const scalar coeff = solution_.relaxCoeff(name); field *= coeff; } template<class CloudType> void Foam::MomentumCloud<CloudType>::relaxSources ( const MomentumCloud<CloudType>& cloudOldTime ) { this->relax(UTrans_(), cloudOldTime.UTrans_(), "U"); this->relax(UCoeff_(), cloudOldTime.UCoeff_(), "U"); } template<class CloudType> void Foam::MomentumCloud<CloudType>::scaleSources() { this->scale(UTrans_(), "U"); this->scale(UCoeff_(), "U"); } template<class CloudType> void Foam::MomentumCloud<CloudType>::preEvolve() { // force calculation of mesh dimensions - needed for parallel runs // with topology change due to lazy evaluation of valid mesh dimensions label nGeometricD = this->mesh().nGeometricD(); Info<< "\nSolving " << nGeometricD << "-D cloud " << this->name() << endl; this->dispersion().cacheFields(true); forces_.cacheFields(true); updateCellOccupancy(); pAmbient_ = constProps_.dict().template lookupOrDefault<scalar>("pAmbient", pAmbient_); functions_.preEvolve(); } template<class CloudType> void Foam::MomentumCloud<CloudType>::evolve() { if (solution_.canEvolve()) { typename parcelType::trackingData td(*this); solve(*this, td); } } template<class CloudType> template<class TrackCloudType> void Foam::MomentumCloud<CloudType>::motion ( TrackCloudType& cloud, typename parcelType::trackingData& td ) { CloudType::move(cloud, td, solution_.trackTime()); updateCellOccupancy(); } template<class CloudType> void Foam::MomentumCloud<CloudType>::patchData ( const parcelType& p, const polyPatch& pp, vector& nw, vector& Up ) const { p.patchData(nw, Up); Up /= p.mesh().time().deltaTValue(); // If this is a wall patch, then there may be a non-zero tangential velocity // component; the lid velocity in a lid-driven cavity case, for example. We // want the particle to interact with this velocity, so we look it up in the // velocity field and use it to set the wall-tangential component. if (!this->mesh().moving() && isA<wallPolyPatch>(pp)) { const label patchi = pp.index(); const label patchFacei = pp.whichFace(p.face()); // We only want to use the boundary condition value only if it is set // by the boundary condition. If the boundary values are extrapolated // (e.g., slip conditions) then they represent the motion of the fluid // just inside the domain rather than that of the wall itself. if (U_.boundaryField()[patchi].fixesValue()) { const vector Uw1 = U_.boundaryField()[patchi][patchFacei]; const vector& Uw0 = U_.oldTime().boundaryField()[patchi][patchFacei]; const scalar f = p.currentTimeFraction(); const vector Uw = Uw0 + f*(Uw1 - Uw0); const tensor nnw = nw*nw; Up = (nnw & Up) + Uw - (nnw & Uw); } } } template<class CloudType> void Foam::MomentumCloud<CloudType>::updateMesh() { updateCellOccupancy(); injectors_.updateMesh(); cellLengthScale_ = mag(cbrt(this->mesh().V())); } template<class CloudType> void Foam::MomentumCloud<CloudType>::autoMap(const mapPolyMesh& mapper) { Cloud<parcelType>::autoMap(mapper); updateMesh(); } template<class CloudType> void Foam::MomentumCloud<CloudType>::info() { vector linearMomentum = linearMomentumOfSystem(); reduce(linearMomentum, sumOp<vector>()); scalar linearKineticEnergy = linearKineticEnergyOfSystem(); reduce(linearKineticEnergy, sumOp<scalar>()); Info<< "Cloud: " << this->name() << nl << " Current number of parcels = " << returnReduce(this->size(), sumOp<label>()) << nl << " Current mass in system = " << returnReduce(massInSystem(), sumOp<scalar>()) << nl << " Linear momentum = " << linearMomentum << nl << " |Linear momentum| = " << mag(linearMomentum) << nl << " Linear kinetic energy = " << linearKineticEnergy << nl; injectors_.info(Info); this->surfaceFilm().info(Info); this->patchInteraction().info(Info); } // ************************************************************************* //
  • 关于k-w SST湍流模型边界条件设置的疑惑

    8
    8 帖子
    8k 浏览
    ShaneHEEES
    //k rho_*epsilon_/k_ //epsilon rho_*Cmu_*sqr(k_)/epsilon_ 为k_和epsilon_接近0,导致除法崩溃,所以使用bound()

    可以试试增大epsilon 减小k;连续性残差也偏大,可以试试fvSchemes散度项二阶换一阶。

  • 多孔介质捕捉边界

    2
    2 帖子
    734 浏览
    李东岳

    因为你用的是正方形网格,因此只能是这样的。

  • 6 帖子
    2k 浏览
    S

    确实您说的非常对,直接做blastfoam,总有种空中楼阁的黑盒子的感觉,那我去研究一下openfoam的映射算例,非常感谢

  • 时间步长对连续性方程的影响

    8
    8 帖子
    5k 浏览

    可以参考这一篇JCP 2018, Unified formulation of the momentum-weighted interpolation for collocated variable arrangements.

    image.png

  • 传热计算中物性参数分段线性插值问题

    8
    8 帖子
    6k 浏览
    L

    @王慧博 大佬您好,我最近也使用openfoam做超临界二氧化碳流动换热这块,和您出现了类似的问题,计算时连续性那块总是很差也很难收敛。然后我也尝试过使用定物性,计算则能很快的收敛,所以想向您请教下是不是buoyantPimpleFoam求解器本省对这种变物性问题不能很好的求解呢,或者目前有什么方法可以提高稳定性呢。