我在使用buoyantSimpleFoam的时候也出现了如下报错:
--> FOAM FATAL ERROR: (openfoam-2306) Maximum number of iterations exceeded: 100 when starting from T0:300 old T:20112.8 new T:-884.425 f:1.0349e+07 p:105000 tol:0.03
这段报错代码位于$FOAM_SRC/thermophysicalModels/specie/thermo/thermo/thermoI.H: 67~86行的do循环里,这段应该是热物理模型计算温度的代码。
这里有个项目(第24页)绕过了循环求解温度,直接通过temperature-enthalpy表格插值来计算温度:https://www.tfd.chalmers.se/~hani/kurser/OS_CFD_2017/DanielHummel/hummelReport.pdf
想请教各位大佬在thermoI.H文件第46行标量f是什么,项目里说是current
enthalpy,是比焓吗?单位是 J/kg 吗?
上面的报错信息在尤其在设定为第二类边界条件的时候基本不能运行起来,所以我打算仿照上面这个项目的办法绕过原来的循环求解温度,通过比焓(J/kg)-温度(K)来实现温度场的计算。
附一个thermoI.H文件:
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | www.openfoam.com
\\/ M anipulation |
-------------------------------------------------------------------------------
Copyright (C) 2011-2017 OpenFOAM Foundation
Copyright (C) 2020 OpenCFD Ltd.
-------------------------------------------------------------------------------
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 "thermo.H"
// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
template<class Thermo, template<class> class Type>
inline Foam::species::thermo<Thermo, Type>::thermo
(
const Thermo& sp
)
:
Thermo(sp)
{}
template<class Thermo, template<class> class Type>
inline Foam::scalar Foam::species::thermo<Thermo, Type>::T
(
scalar f,
scalar p,
scalar T0,
scalar (thermo<Thermo, Type>::*F)(const scalar, const scalar) const,
scalar (thermo<Thermo, Type>::*dFdT)(const scalar, const scalar)
const,
scalar (thermo<Thermo, Type>::*limit)(const scalar) const
) const
{
if (T0 < 0)
{
FatalErrorInFunction
<< "Negative initial temperature T0: " << T0
<< abort(FatalError);
}
scalar Test = T0;
scalar Tnew = T0;
scalar Ttol = T0*tol_;
int iter = 0;
do
{
Test = Tnew;
Tnew =
(this->*limit)
(Test - ((this->*F)(p, Test) - f)/(this->*dFdT)(p, Test));
if (iter++ > maxIter_)
{
FatalErrorInFunction
<< "Maximum number of iterations exceeded: " << maxIter_
<< " when starting from T0:" << T0
<< " old T:" << Test << " new T:" << Tnew
<< " f:" << f
<< " p:" << p
<< " tol:" << Ttol
<< abort(FatalError);
}
} while (mag(Tnew - Test) > Ttol);
return Tnew;
}
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
template<class Thermo, template<class> class Type>
inline Foam::species::thermo<Thermo, Type>::thermo
(
const word& name,
const thermo& st
)
:
Thermo(name, st)
{}
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
template<class Thermo, template<class> class Type>
inline Foam::word
Foam::species::thermo<Thermo, Type>::heName()
{
return Type<thermo<Thermo, Type>>::energyName();
}
template<class Thermo, template<class> class Type>
inline Foam::scalar
Foam::species::thermo<Thermo, Type>::Cpv(const scalar p, const scalar T) const
{
return Type<thermo<Thermo, Type>>::Cpv(*this, p, T);
}
template<class Thermo, template<class> class Type>
inline Foam::scalar
Foam::species::thermo<Thermo, Type>::gamma(const scalar p, const scalar T) const
{
#ifdef __clang__
volatile const scalar Cp = this->Cp(p, T);
#else
const scalar Cp = this->Cp(p, T);
#endif
return Cp/(Cp - this->CpMCv(p, T));
}
template<class Thermo, template<class> class Type>
inline Foam::scalar
Foam::species::thermo<Thermo, Type>::CpByCpv
(
const scalar p,
const scalar T
) const
{
return Type<thermo<Thermo, Type>>::CpByCpv(*this, p, T);
}
template<class Thermo, template<class> class Type>
inline Foam::scalar
Foam::species::thermo<Thermo, Type>::HE(const scalar p, const scalar T) const
{
return Type<thermo<Thermo, Type>>::HE(*this, p, T);
}
template<class Thermo, template<class> class Type>
inline Foam::scalar
Foam::species::thermo<Thermo, Type>::G(const scalar p, const scalar T) const
{
return this->Ha(p, T) - T*this->S(p, T);
}
template<class Thermo, template<class> class Type>
inline Foam::scalar
Foam::species::thermo<Thermo, Type>::A(const scalar p, const scalar T) const
{
return this->Ea(p, T) - T*this->S(p, T);
}
template<class Thermo, template<class> class Type>
inline Foam::scalar
Foam::species::thermo<Thermo, Type>::cp(const scalar p, const scalar T) const
{
return this->Cp(p, T)*this->W();
}
template<class Thermo, template<class> class Type>
inline Foam::scalar
Foam::species::thermo<Thermo, Type>::ha(const scalar p, const scalar T) const
{
return this->Ha(p, T)*this->W();
}
template<class Thermo, template<class> class Type>
inline Foam::scalar
Foam::species::thermo<Thermo, Type>::hs(const scalar p, const scalar T) const
{
return this->Hs(p, T)*this->W();
}
template<class Thermo, template<class> class Type>
inline Foam::scalar
Foam::species::thermo<Thermo, Type>::hc() const
{
return this->Hc()*this->W();
}
template<class Thermo, template<class> class Type>
inline Foam::scalar
Foam::species::thermo<Thermo, Type>::s(const scalar p, const scalar T) const
{
return this->S(p, T)*this->W();
}
template<class Thermo, template<class> class Type>
inline Foam::scalar
Foam::species::thermo<Thermo, Type>::he(const scalar p, const scalar T) const
{
return this->HE(p, T)*this->W();
}
template<class Thermo, template<class> class Type>
inline Foam::scalar
Foam::species::thermo<Thermo, Type>::cv(const scalar p, const scalar T) const
{
return this->Cv(p, T)*this->W();
}
template<class Thermo, template<class> class Type>
inline Foam::scalar
Foam::species::thermo<Thermo, Type>::es(const scalar p, const scalar T) const
{
return this->Es(p, T)*this->W();
}
template<class Thermo, template<class> class Type>
inline Foam::scalar
Foam::species::thermo<Thermo, Type>::ea(const scalar p, const scalar T) const
{
return this->Ea(p, T)*this->W();
}
template<class Thermo, template<class> class Type>
inline Foam::scalar
Foam::species::thermo<Thermo, Type>::g(const scalar p, const scalar T) const
{
return this->G(p, T)*this->W();
}
template<class Thermo, template<class> class Type>
inline Foam::scalar
Foam::species::thermo<Thermo, Type>::a(const scalar p, const scalar T) const
{
return this->A(p, T)*this->W();
}
template<class Thermo, template<class> class Type>
inline Foam::scalar
Foam::species::thermo<Thermo, Type>::K(const scalar p, const scalar T) const
{
scalar arg = -this->Y()*this->G(Pstd, T)/(RR*T);
if (arg < 600)
{
return exp(arg);
}
else
{
return VGREAT;
}
}
template<class Thermo, template<class> class Type>
inline Foam::scalar
Foam::species::thermo<Thermo, Type>::Kp(const scalar p, const scalar T) const
{
return K(p, T);
}
template<class Thermo, template<class> class Type>
inline Foam::scalar
Foam::species::thermo<Thermo, Type>::Kc(const scalar p, const scalar T) const
{
const scalar nm = this->Y()/this->W();
if (equal(nm, SMALL))
{
return Kp(p, T);
}
else
{
return Kp(p, T)*pow(Pstd/(RR*T), nm);
}
}
template<class Thermo, template<class> class Type>
inline Foam::scalar Foam::species::thermo<Thermo, Type>::Kx
(
const scalar p,
const scalar T
) const
{
const scalar nm = this->Y()/this->W();
if (equal(nm, SMALL))
{
return Kp(p, T);
}
else
{
return Kp(p, T)*pow(Pstd/p, nm);
}
}
template<class Thermo, template<class> class Type>
inline Foam::scalar Foam::species::thermo<Thermo, Type>::Kn
(
const scalar p,
const scalar T,
const scalar n
) const
{
const scalar nm = this->Y()/this->W();
if (equal(nm, SMALL))
{
return Kp(p, T);
}
else
{
return Kp(p, T)*pow(n*Pstd/p, nm);
}
}
template<class Thermo, template<class> class Type>
inline Foam::scalar Foam::species::thermo<Thermo, Type>::THE
(
const scalar he,
const scalar p,
const scalar T0
) const
{
return Type<thermo<Thermo, Type>>::THE(*this, he, p, T0);
}
template<class Thermo, template<class> class Type>
inline Foam::scalar Foam::species::thermo<Thermo, Type>::THs
(
const scalar hs,
const scalar p,
const scalar T0
) const
{
return T
(
hs,
p,
T0,
&thermo<Thermo, Type>::Hs,
&thermo<Thermo, Type>::Cp,
&thermo<Thermo, Type>::limit
);
}
template<class Thermo, template<class> class Type>
inline Foam::scalar Foam::species::thermo<Thermo, Type>::THa
(
const scalar ha,
const scalar p,
const scalar T0
) const
{
return T
(
ha,
p,
T0,
&thermo<Thermo, Type>::Ha,
&thermo<Thermo, Type>::Cp,
&thermo<Thermo, Type>::limit
);
}
template<class Thermo, template<class> class Type>
inline Foam::scalar Foam::species::thermo<Thermo, Type>::TEs
(
const scalar es,
const scalar p,
const scalar T0
) const
{
return T
(
es,
p,
T0,
&thermo<Thermo, Type>::Es,
&thermo<Thermo, Type>::Cv,
&thermo<Thermo, Type>::limit
);
}
template<class Thermo, template<class> class Type>
inline Foam::scalar Foam::species::thermo<Thermo, Type>::TEa
(
const scalar ea,
const scalar p,
const scalar T0
) const
{
return T
(
ea,
p,
T0,
&thermo<Thermo, Type>::Ea,
&thermo<Thermo, Type>::Cv,
&thermo<Thermo, Type>::limit
);
}
template<class Thermo, template<class> class Type>
inline Foam::scalar
Foam::species::thermo<Thermo, Type>::dKcdTbyKc
(
const scalar p,
const scalar T
) const
{
const scalar dKcdTbyKc =
(this->S(Pstd, T) + this->Gstd(T)/T)*this->Y()/(RR*T);
const scalar nm = this->Y()/this->W();
if (equal(nm, SMALL))
{
return dKcdTbyKc;
}
else
{
return dKcdTbyKc - nm/T;
}
}
template<class Thermo, template<class> class Type>
inline Foam::scalar
Foam::species::thermo<Thermo, Type>::dcpdT(const scalar p, const scalar T) const
{
return this->dCpdT(p, T)*this->W();
}
// * * * * * * * * * * * * * * * Member Operators * * * * * * * * * * * * * //
template<class Thermo, template<class> class Type>
inline void Foam::species::thermo<Thermo, Type>::operator+=
(
const thermo<Thermo, Type>& st
)
{
Thermo::operator+=(st);
}
template<class Thermo, template<class> class Type>
inline void Foam::species::thermo<Thermo, Type>::operator*=(const scalar s)
{
Thermo::operator*=(s);
}
// * * * * * * * * * * * * * * * Friend Operators * * * * * * * * * * * * * //
template<class Thermo, template<class> class Type>
inline Foam::species::thermo<Thermo, Type> Foam::species::operator+
(
const thermo<Thermo, Type>& st1,
const thermo<Thermo, Type>& st2
)
{
return thermo<Thermo, Type>
(
static_cast<const Thermo&>(st1) + static_cast<const Thermo&>(st2)
);
}
template<class Thermo, template<class> class Type>
inline Foam::species::thermo<Thermo, Type> Foam::species::operator*
(
const scalar s,
const thermo<Thermo, Type>& st
)
{
return thermo<Thermo, Type>
(
s*static_cast<const Thermo&>(st)
);
}
template<class Thermo, template<class> class Type>
inline Foam::species::thermo<Thermo, Type> Foam::species::operator==
(
const thermo<Thermo, Type>& st1,
const thermo<Thermo, Type>& st2
)
{
return thermo<Thermo, Type>
(
static_cast<const Thermo&>(st1) == static_cast<const Thermo&>(st2)
);
}
// ************************************************************************* //