栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > .Net

OpenFOAM热物理类代码详解

.Net 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

OpenFOAM热物理类代码详解

热物理类的RTS机制

OpenFOAM利用RTS机制来动态创建模型实例,核心思想在于利用C++中静态成员会在类的实例化之前创建,
以buoyantSimpleFoam.C对于生成热物理类的代码的为例,其中

  rhoThermo::New(mesh)

作者网址:https://blog.csdn.net/dsfsdffgfd

调用rhoThermo类中静态成员函数:

  Foam::autoPtr Foam::rhoThermo::New
  (
      const fvMesh& mesh,
      const word& phaseName
  )
  {
      return basicThermo::New(mesh, phaseName);
  }

返回了基类basicThermo中名为New的静态模板类,在RTS机制中也被称为Selector,其函数的定义如下:

  template
  Foam::autoPtr Foam::basicThermo::New
  (
      const fvMesh& mesh,
      const word& phaseName
  )
  {
      IOdictionary thermoDict
      (
          IOobject
          (
              phasePropertyName(dictName, phaseName),
              mesh.time().constant(),
              mesh,
              IOobject::MUST_READ_IF_MODIFIED,
              IOobject::NO_WRITE,
              false
          )
      );

      auto cstrIter =
          lookupThermo
          (
              thermoDict,
              Thermo::fvMeshConstructorTablePtr_
          );

      return autoPtr(cstrIter()(mesh, phaseName));
  }

  template
  typename Table::iterator Foam::basicThermo::lookupThermo
  (
      const dictionary& thermoDict,
      Table* tablePtr
  )
  {
      if (thermoDict.isDict("thermoType"))
      {
          const dictionary& thermoTypeDict = thermoDict.subDict("thermoType");

          Info<< "Selecting thermodynamics package " << thermoTypeDict << endl;

          if (thermoTypeDict.found("properties"))
          {
              std::initializer_list cmptNames
              {
                  "type",
                  "mixture",
                  "properties",
                  "energy"
              };

              // Construct the name of the thermo package from the components
              const word thermoTypeName
              (
                  thermoTypeDict.get("type") + '<'
                + thermoTypeDict.get("mixture") + '<'
                + thermoTypeDict.get("properties") + ','
                + thermoTypeDict.get("energy") + ">>"
              );

              return lookupThermo
              (
                  thermoTypeDict,
                  tablePtr,
                  cmptNames,
                  thermoTypeName
              );
          }
          else
          {
              std::initializer_list cmptNames
              {
                  "type",
                  "mixture",
                  "transport",
                  "thermo",
                  "equationOfState",
                  "specie",
                  "energy"
              };

              // Construct the name of the thermo package from the components
              const word thermoTypeName
              (
                  thermoTypeDict.get("type") + '<'
                + thermoTypeDict.get("mixture") + '<'
                + thermoTypeDict.get("transport") + '<'
                + thermoTypeDict.get("thermo") + '<'
                + thermoTypeDict.get("equationOfState") + '<'
                + thermoTypeDict.get("specie") + ">>,"
                + thermoTypeDict.get("energy") + ">>>"
              );

              return lookupThermo
              (
                  thermoTypeDict,
                  tablePtr,
                  cmptNames,
                  thermoTypeName
              );
          }
      }
      else
      {
          const word thermoTypeName(thermoDict.get("thermoType"));

          Info<< "Selecting thermodynamics package " << thermoTypeName << endl;

          // Table iterator, not const_iterator
          auto cstrIter = tablePtr->find(thermoTypeName);

          if (!cstrIter.found())
          {
              FatalIOErrorInLookup
              (
                  thermoDict,
                  Thermo::typeName,
                  thermoTypeName,
                  *tablePtr
              ) << exit(FatalIOError);
          }

          return cstrIter;
      }
  }

首先定义了读写的字典IOdictionary thermoDict,其中dictName为静态变量定义为:const Foam::word Foam::basicThermo::dictName("thermophysicalProperties"); ,下一步是调用了静态模板函数lookupThermo,其模板参数为rhoThermo::fvMeshConstructorTable,也就是返回值rhoThermo::fvMeshConstructorTable::iterator,参数为Thermo::fvMeshConstructorTablePtr_。lookupThermo函数先读取thermophysicalProperties文件,三种字典形式通过上述代码合为一体,例如字典经过读入写成:
hePsiThermo>,sensibleEnthalpy>>>,或者直接读入这种形式
thermoType hePsiThermo>,sensibleEnthalpy>>>;,把这个值赋给thermoTypeName后返回rhoThermo::fvMeshConstructorTablePtr_->find(thermoTypeName)。这段代码的HashTable是通过如下宏定义:

  declareRunTimeSelectionTable
    (
        autoPtr,
        rhoThermo,
        fvMesh,
        (const fvMesh& mesh, const word& phaseName),
        (mesh, phaseName)
    )

  #define declareRunTimeSelectionTable(autoPtr,baseType,argNames,argList,parList)
                                                                               
                             
    typedef autoPtr (*argNames##ConstructorPtr)argList;              
                                                                               
                               
    typedef HashTable            
        argNames##ConstructorTable;                                            
                                                                               
                    
    static argNames##ConstructorTable* argNames##ConstructorTablePtr_;         
                                                                               
                     
    static void construct##argNames##ConstructorTables();                      
                                                                               
           
    static void destroy##argNames##ConstructorTables();                        
                                                                               
                           
    template                                             
    class add##argNames##ConstructorToTable                                    
    {                                                                          
    public:                                                                    
                                                                               
        static autoPtr New argList                                   
        {                                                                      
            return autoPtr(new baseType##Type parList);              
        }                                                                      
                                                                               
        explicit add##argNames##ConstructorToTable                             
        (                                                                      
            const word& lookup = baseType##Type::typeName                      
        )                                                                      
        {                                                                      
            construct##argNames##ConstructorTables();                          
            if (!argNames##ConstructorTablePtr_->insert(lookup, New))          
            {                                                                  
                std::cerr<< "Duplicate entry " << lookup                       
                    << " in runtime selection table " << #baseType             
                    << std::endl;                                              
                error::safePrintStack(std::cerr);                              
            }                                                                  
        }                                                                      
                                                                               
        ~add##argNames##ConstructorToTable()                                   
        {                                                                      
            destroy##argNames##ConstructorTables();                            
        }                                                                      
                                                                               
        add##argNames##ConstructorToTable                                      
            (const add##argNames##ConstructorToTable&) = delete;               
                                                                               
        void operator=                                                         
            (const add##argNames##ConstructorToTable&) = delete;               
    };                                                                         
                                                                               
                           
                   
    template                                             
    class addRemovable##argNames##ConstructorToTable                           
    {                                                                          
    public:                                                                    
                                                                               
        const word name;                    
                                                                               
        static autoPtr New argList                                   
        {                                                                      
            return autoPtr(new baseType##Type parList);              
        }                                                                      
                                                                               
        explicit addRemovable##argNames##ConstructorToTable                    
        (                                                                      
            const word& lookup = baseType##Type::typeName                      
        )                                                                      
        :                                                                      
            name(lookup)                                                       
        {                                                                      
            construct##argNames##ConstructorTables();                          
            argNames##ConstructorTablePtr_->set(lookup, New);                  
        }                                                                      
                                                                               
        ~addRemovable##argNames##ConstructorToTable()                          
        {                                                                      
            if (argNames##ConstructorTablePtr_)                                
            {                                                                  
                argNames##ConstructorTablePtr_->erase(name);                   
            }                                                                  
        }                                                                      
                                                                               
        addRemovable##argNames##ConstructorToTable                             
            (const addRemovable##argNames##ConstructorToTable&) = delete;      
                                                                               
        void operator=                                                         
            (const addRemovable##argNames##ConstructorToTable&) = delete;      
    };

上面代码翻译一下:

                             
    typedef autoPtr (*fvMeshConstructorPtr)(const fvMesh& mesh, const word& phaseName);              
                                                                               
                               
    typedef HashTable fvMeshConstructorTable;                                            
                                                                               
                    
    static fvMeshConstructorTable* fvMeshConstructorTablePtr_;         
                                                                               
                     
    static void constructfvMeshConstructorTables();                      
                                                                               
           
    static void destroyfvMeshConstructorTables();                        
                                                                               
                           
    template                                             
    class addfvMeshConstructorToTable                                    
    {                                                                          
    public:                                                                    
                                                                               
        static autoPtr New (const fvMesh& mesh, const word phaseName)
        {                                                                      
            return autoPtr(new rhoThermoType (mesh, phaseName));
        }                                                                      

        explicit addfvMeshConstructorToTable
        (                                                                      
            const word& lookup = rhoThermoType::typeName
        )                                                                      
        {                                                                      
            constructfvMeshConstructorTables();
            if (!fvMeshConstructorTablePtr_->insert(lookup, New))
            {
                std::cerr<< "Duplicate entry " << lookup
                    << " in runtime selection table " << "rhoThermo"
                    << std::endl;
                error::safePrintStack(std::cerr);
            }
        }
                                                                               
        ~addfvMeshConstructorToTable()                                   
        {                                                                      
            destroyfvMeshConstructorTables();                            
        }                                                                      
                                                                               
        addfvMeshConstructorToTable                                      
            (const addfvMeshConstructorToTable&) = delete;               
                                                                               
        void operator=                                                         
            (const addfvMeshConstructorToTable&) = delete;               
    };                                                                         
                                                                               
                           
                   
    template                                             
    class addRemovablefvMeshConstructorToTable                           
    {                                                                          
    public:                                                                    
                                                                               
        const word name;                    
                                                                               
        static autoPtr New (const fvMesh& mesh, const word phaseName)                                   
        {                                                                      
            return autoPtr(new rhoThermoType (mesh, phaseName));              
        }                                                                      
                                                                               
        explicit addRemovablefvMeshConstructorToTable                    
        (                                                                      
            const word& lookup = rhoThermoType::typeName                      
        )                                                                      
        :                                                                      
            name(lookup)                                                       
        {                                                                      
            constructfvMeshConstructorTables();                          
            fvMeshConstructorTablePtr_->set(lookup, New);                  
        }                                                                      
                                                                               
        ~addRemovablefvMeshConstructorToTable()                          
        {                                                                      
            if (fvMeshConstructorTablePtr_)                                
            {                                                                  
                fvMeshConstructorTablePtr_->erase(name);                   
            }                                                                  
        }                                                                      
                                                                               
        addRemovablefvMeshConstructorToTable                             
            (const addRemovablefvMeshConstructorToTable&) = delete;      
                                                                               
        void operator=                                                         
            (const addRemovablefvMeshConstructorToTable&) = delete;      
    };

上端代码主要是创建了HashTable,热物理类的独特性在于HashTable的元素不是在派生类中添加,而是通过下面宏进行定义:

makeThermos
(
    rhoThermo,
    heRhoThermo,
    pureMixture,
    constTransport,
    sensibleEnthalpy,
    hConstThermo,
    perfectGas,
    specie
);

这里直接对上面的宏进行翻译得到如下:

  // **************************************步骤一*****************************************************
  typedef                                                                    
      constTransport                                                              
      <                                                                      
          species::thermo                                                    
          <                                                                  
              hConstThermo                                                         
              <                                                              
                  perfectGas                                                 
                  <                                                          
                      Specie                                                 
                  >                                                          
              >,                                                             
              sensibleEnthalpy                                                           
          >                                                                  
      >                                                                      
      constTransportsensibleEnthalpyhConstThermoperfectGasSpecie
                                                                              
  typedef                                                                    
    heRhoThermo                                                                
    <                                                                      
        rhoThermo,                                                        
        pureMixture                         
    >                                                                      
    heRhoThermopureMixtureconstTransportsensibleEnthalpyhConstThermoperfectGasSpecie;

    // **************************************步骤二*****************************************************
    template<>
    const ::Foam::word heRhoThermopureMixtureconstTransportsensibleEnthalpyhConstThermoperfectGasSpecie::typeName("heRhoThermo>")

    // **************************************步骤三*****************************************************
    addToRunTimeSelectionTable                                                 
    (                                                                          
        basicThermo,
        heRhoThermopureMixtureconstTransportsensibleEnthalpyhConstThermoperfectGasSpecie,
        fvMesh
    );
    addToRunTimeSelectionTable
    (
        basicThermo,
        heRhoThermopureMixtureconstTransportsensibleEnthalpyhConstThermoperfectGasSpecie,
        fvMeshDictPhase
    );
    addToRunTimeSelectionTable                                                 
    (                                                                          
        fluidThermo,
        heRhoThermopureMixtureconstTransportsensibleEnthalpyhConstThermoperfectGasSpecie,
        fvMesh
    );
    addToRunTimeSelectionTable                                                 
    (                                                                          
        fluidThermo,
        heRhoThermopureMixtureconstTransportsensibleEnthalpyhConstThermoperfectGasSpecie,
        fvMeshDictPhase
    );
    addToRunTimeSelectionTable                                                 
    (                                                                          
        rhoThermo,
        heRhoThermopureMixtureconstTransportsensibleEnthalpyhConstThermoperfectGasSpecie,                                              
        fvMesh
    );
    addToRunTimeSelectionTable                                                 
    (                                                                          
        rhoThermo,
        heRhoThermopureMixtureconstTransportsensibleEnthalpyhConstThermoperfectGasSpecie,                                              
        fvMeshDictPhase
    );

上面的代码步骤一先用typedef给一定模板参数下constTransport和heRhoThermo的别称,再在步骤二中对这一参数下的模板类特例话其静态变量,最后的步骤三利用addToRunTimeSelectionTable宏命令,在rhoThermo,fluidThermo,basicThermo的HashTable中添加上面参数的模板类,再次把上述宏命令展开:

  rhoThermo::addfvMeshConstructorToTable
    addthisTypeheRhoThermopureMixtureconstTransportsensibleEnthalpyhConstThermoperfectGasSpecieConstructorTorhoThermoTable_;

终于,再次回到了rhoThermo中通过宏定义模板类 addfvMeshConstructorToTable ,实例化了一个addfvMeshConstructorToTable对象,在其构造函数中,首先调用了constructfvMeshConstructorTables函数,这一函数通过如下的宏进行定义:

#define defineRunTimeSelectionTableConstructor(baseType,argNames)              
                                                                               
                     
    void baseType::construct##argNames##ConstructorTables()                    
    {                                                                          
        static bool constructed = false;                                       
        if (!constructed)                                                      
        {                                                                      
            constructed = true;                                                
            baseType::argNames##ConstructorTablePtr_                           
                = new baseType::argNames##ConstructorTable;                    
        }                                                                      
    }
#define defineRunTimeSelectionTableDestructor(baseType,argNames)               
                                                                               
           
    void baseType::destroy##argNames##ConstructorTables()                      
    {                                                                          
        if (baseType::argNames##ConstructorTablePtr_)                          
        {                                                                      
            delete baseType::argNames##ConstructorTablePtr_;                   
            baseType::argNames##ConstructorTablePtr_ = nullptr;                
        }     
    }
                                                                     
// Create pointer to hash-table of functions
#define defineRunTimeSelectionTablePtr(baseType,argNames)                      
                                                                               
                                    
    baseType::argNames##ConstructorTable*                                      
        baseType::argNames##ConstructorTablePtr_(nullptr)

展开后写为:

                   
  void rhoThermo::constructfvMeshConstructorTables()                    
  {                                                                          
      static bool constructed = false;                                       
      if (!constructed)                                                      
      {                                                                      
          constructed = true;                                                
          rhoThermo::fvMeshConstructorTablePtr_                           
              = new rhoThermo::fvMeshConstructorTable;                    
      }                                                                      
  }

  void rhoThermo::destroyfvMeshConstructorTables()                      
  {                                                                          
        if (rhoThermo::fvMeshConstructorTablePtr_)                          
        {                                                                      
            delete rhoThermo::fvMeshConstructorTablePtr_;                   
            rhoThermo::fvMeshConstructorTablePtr_ = nullptr;                
        }     
  }

  rhoThermo::fvMeshConstructorTable*                                      
        rhoThermo::fvMeshConstructorTablePtr_(nullptr)

上面的constructed为局部静态变量,在计算中只会初始化一次,不会重复调用,也就是对于rhoThermo只会生成一个fvMeshConstructorTablePtr_,接下来调用了
fvMeshConstructorTablePtr_->insert(lookup, New),回到HashTable的定义:

    typedef autoPtr (*fvMeshConstructorPtr)(const fvMesh& mesh, const word& phaseName);              
    typedef HashTable fvMeshConstructorTable; 

其key为’lookup’即之前特例化的模板名heRhoThermo>,value为返回值autoPtr参数const fvMesh& mesh, const word& phaseName的函数指针,其值为类中的静态函数static autoPtr New (const fvMesh& mesh, const word phaseName),具体调动关系可以详见表驱动模式。层层代入最后返回到buoyantSimple.C的代码就是:

autoPtr(autoPtr(
  new heRhoThermo>,
        sensibleEnthalpy>>>> (mesh, phaseName)))

也就是:

autoPtr pThermo(
    new heRhoThermo>,sensibleEnthalpy>>>> 
        (mesh, null));

热物理类的代码实现

通过热物理类的RTS机制代码,同样以字典为例最终代码得到了指向heRhoThermo>,sensibleEnthalpy>>>>实例的指针,首先看看heRhoThermo的代码实现上的区别:


Appendix I

能量方程可以表示为:
ρ D E D t ⏞ 总能 = − ∇ ⋅ ( p U ) ⏞ 压力功 − ∇ ⋅ q ˙ ′ ′ ⏞ 热流 + ∇ ⋅ ( τ ⋅ U ) ⏞ 粘性力功 + ρ g ⋅ U ⏞ 重力功 + ρ q ˙ ′ ′ ′ ⏞ 热源 (1) overbrace{rhofrac{DE}{Dt}}^{textbf{总能}}= overbrace{-nablacdot(pbold{U})}^{textbf{压力功}} -overbrace{nablacdotbold{dot{q}''}}^{textbf{热流}} +overbrace{nablacdot(bold{tau}cdotbold{U})}^{textbf{粘性力功}} +overbrace{rhobold{g}cdotbold{U}}^{textbf{重力功}} +overbrace{rho dot{q}'''}^{textbf{热源}} tag{1} ρDtDE​ ​总能​=−∇⋅(pU) ​压力功​−∇⋅q˙​′′ ​热流​+∇⋅(τ⋅U) ​粘性力功​+ρg⋅U ​重力功​+ρq˙​′′′ ​热源​(1)

(1)为能量方程的非守恒形式,通过随体导数的展开公式 D D t ≡ ∂ ∂ t + U ⋅ ∇ frac{D}{Dt}equivfrac{partial}{partial t}+bold{U}cdotnabla DtD​≡∂t∂​+U⋅∇公式及质量守恒可以把并把任一张量 Q bold{Q} Q的非守恒形式展开为守恒形式:
ρ D Q D t ≡ ∂ ρ Q ∂ t + ∇ ⋅ ( ρ Q U ) rhofrac{Dbold{Q}}{Dt}equivfrac{partialrho bold{Q}}{partial t}+nablacdot(rhobold{Q}bold{U}) ρDtDQ​≡∂t∂ρQ​+∇⋅(ρQU)

把(1)写为守恒形式并把总能量 E E E展开为内能 e e e和机械能 K K K之和得到:

∂ ρ e ∂ t + ∇ ⋅ ( ρ e U ) + ∂ ρ K ∂ t + ∇ ⋅ ( ρ K U ) = − ∇ ⋅ ( p U ) − ∇ ⋅ q ˙ ′ ′ + ∇ ⋅ ( τ ⋅ U ) + ρ g ⋅ U + ρ q ˙ ′ ′ ′ (2) frac{partial rho e}{partial t}+nablacdot(rho ebold{U}) +frac{partial rho K}{partial t}+nablacdot(rho Kbold{U}) = -nablacdot(pbold{U}) -nablacdotbold{dot{q}''} +nablacdot(bold{tau}cdotbold{U}) +rhobold{g}cdotbold{U} +rho dot{q}''' tag{2} ∂t∂ρe​+∇⋅(ρeU)+∂t∂ρK​+∇⋅(ρKU)=−∇⋅(pU)−∇⋅q˙​′′+∇⋅(τ⋅U)+ρg⋅U+ρq˙​′′′(2)

公式(2)即为基于内能形式的能量方程。根据焓的定义:

h = e + p ρ h = e+frac{p}{rho} h=e+ρp​

把:

∂ ρ e ∂ t + ∇ ⋅ ( ρ e U ) = ∂ ρ ( h − p ρ ) ∂ t + ∇ ⋅ ( ρ ( h − p ρ ) U ) = ∂ ρ h ∂ t + ∇ ⋅ ( ρ h U ) − ∂ p ∂ t − ∇ ⋅ ( p U ) frac{partial rho e}{partial t}+nablacdot(rho ebold{U}) = frac{partial rho (h-frac{p}{rho})}{partial t}+nablacdot(rho (h - frac{p}{rho})bold{U}) =frac{partial rho h}{partial t}+nablacdot(rho hbold{U})- frac{partial p}{partial t} - nablacdot(pbold{U}) ∂t∂ρe​+∇⋅(ρeU)=∂t∂ρ(h−ρp​)​+∇⋅(ρ(h−ρp​)U)=∂t∂ρh​+∇⋅(ρhU)−∂t∂p​−∇⋅(pU)

代入公式(2)可以得到基于焓形式的能量方程:

∂ ρ h ∂ t + ∇ ⋅ ( ρ h U ) + ∂ ρ K ∂ t + ∇ ⋅ ( ρ K U ) = ∂ p ∂ t − ∇ ⋅ q ˙ ′ ′ + ∇ ⋅ ( τ ⋅ U ) + ρ g ⋅ U + ρ q ˙ ′ ′ ′ (3) frac{partial rho h}{partial t}+nablacdot(rho hbold{U}) +frac{partial rho K}{partial t}+nablacdot(rho Kbold{U}) = frac{partial p}{partial t} -nablacdotbold{dot{q}''} +nablacdot(bold{tau}cdotbold{U}) +rhobold{g}cdotbold{U} +rho dot{q}''' tag{3} ∂t∂ρh​+∇⋅(ρhU)+∂t∂ρK​+∇⋅(ρKU)=∂t∂p​−∇⋅q˙​′′+∇⋅(τ⋅U)+ρg⋅U+ρq˙​′′′(3)

内能形式与焓形式的能量方程是完全一致的,只是形式不同,因此在理论上两者没有差别。

对动量方程:

∂ ρ U ∂ t + ∇ ⋅ ( ρ U U ) = ∇ ⋅ τ + ρ g − ∇ p frac{partial rho bold{U}}{partial t}+nablacdot(rho bold{U}bold{U}) =nablacdotbold{tau}+rhobold{g}-nabla p ∂t∂ρU​+∇⋅(ρUU)=∇⋅τ+ρg−∇p
两边同时点乘速度 U bold{U} U可以得到机械能守恒方程:

∂ ρ K ∂ t + ∇ ⋅ ( ρ K U ) = ( ∇ ⋅ τ ) ⋅ U + ρ g ⋅ U − ∇ p ⋅ U (4) frac{partial rho K}{partial t}+nablacdot(rho Kbold{U}) = (nablacdotbold{tau})cdotbold{U}+rhobold{g}cdotbold{U}-nabla pcdotbold{U} tag{4} ∂t∂ρK​+∇⋅(ρKU)=(∇⋅τ)⋅U+ρg⋅U−∇p⋅U(4)
把公式(4)分别代入(2)(3)并且去除粘性力影响,内能形式的能量方程的源项为 − p ( ∇ ⋅ U ) -p(nablacdotbold{U}) −p(∇⋅U):

∂ ρ e ∂ t + ∇ ⋅ ( ρ e U ) = − p ( ∇ ⋅ U ) − ∇ ⋅ q ˙ ′ ′ + ρ q ˙ ′ ′ ′ (5) frac{partial rho e}{partial t}+nablacdot(rho ebold{U}) = -p(nablacdotbold{U}) -nablacdotbold{dot{q}''} +rho dot{q}''' tag{5} ∂t∂ρe​+∇⋅(ρeU)=−p(∇⋅U)−∇⋅q˙​′′+ρq˙​′′′(5)
而焓形式的能量方程则替换为 ∂ p ∂ t + U ⋅ ( ∇ p ) frac{partial p}{partial t} +bold{U}cdot(nabla p) ∂t∂p​+U⋅(∇p):

∂ ρ h ∂ t + ∇ ⋅ ( ρ h U ) = U ⋅ ( ∇ p ) + ∂ p ∂ t − ∇ ⋅ q ˙ ′ ′ + ρ g ⋅ U + ρ q ˙ ′ ′ ′ (6) frac{partial rho h}{partial t}+nablacdot(rho hbold{U}) = bold{U}cdot(nabla p) +frac{partial p}{partial t} -nablacdotbold{dot{q}''} +rhobold{g}cdotbold{U} +rho dot{q}''' tag{6} ∂t∂ρh​+∇⋅(ρhU)=U⋅(∇p)+∂t∂p​−∇⋅q˙​′′+ρg⋅U+ρq˙​′′′(6)

对比公式(5)(6),对于不可压流体或者压缩性较小的流体,(5)中的 − p ( ∇ ⋅ U ) -p(nablacdotbold{U}) −p(∇⋅U)会很小,这在数值中具有收敛性的优势,因此对于 ψ psi ψ很小的流动状况,可以 使用内能形式的能量方程增强计算的收敛性 ,但收敛后两者的结果没有区别。

另外不同的求解器也会选择忽略(4)(5)中的一些做功项情况,在buoyantSimpleFoam的能量方程中忽略了粘性力的做功项:

    fvScalarMatrix EEqn
    (
        fvm::div(phi, he)
      + (
            he.name() == "e"
          ? fvc::div(phi, volScalarField("Ekp", 0.5*magSqr(U) + p/rho))
          : fvc::div(phi, volScalarField("K", 0.5*magSqr(U)))
        )
      - fvm::laplacian(turbulence->alphaEff(), he) 
     ==
        rho*(U&g)
      + radiation->Sh(thermo, he)
      + fvOptions(rho, he)
    );

而在rhoSimpleFoam的能量方程中同时忽略了粘性力和重力的做功:

    fvScalarMatrix EEqn
    (
        fvm::div(phi, he)
      + (
            he.name() == "e"
          ? fvc::div(phi, volScalarField("Ekp", 0.5*magSqr(U) + p/rho))
          : fvc::div(phi, volScalarField("K", 0.5*magSqr(U)))
        )
      - fvm::laplacian(turbulence->alphaEff(), he)
     ==
        fvOptions(rho, he)
    );

在rhoCentralFoam的能量方程主要考虑公式(4)(5)中的粘性力做功:

    volScalarField rhoE
    (
        IOobject
        (
            "rhoE",
            runTime.timeName(),
            mesh,
            IOobject::NO_READ,
            IOobject::NO_WRITE
        ),
        rho*(e + 0.5*magSqr(U))
    );
    surfaceScalarField sigmaDotU
    (
        "sigmaDotU",
        (
            fvc::interpolate(muEff)*mesh.magSf()*fvc::snGrad(U)
            + fvc::dotInterpolate(mesh.Sf(), tauMC)
        )
        & (a_pos*U_pos + a_neg*U_neg)
    );
    solve
    (
        fvm::ddt(rhoE)
        + fvc::div(phiEp)
        - fvc::div(sigmaDotU)
    );

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/984481.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号