openfoam文件讀取

来源:https://www.cnblogs.com/heloveHe/archive/2023/02/21/17142100.html
-Advertisement-
Play Games

對於openfoam或其他c++程式而言,文件的讀取是尤為重要的 我們最開始學習C++時,會學到類的初始化,或者是變數定義為某個值,再對某個值進行遍歷,,, 類似如下: 點擊查看代碼 #include <iostream> // 包含頭文件。 using namespace std; // 指定預設 ...


對於openfoam或其他c++程式而言,文件的讀取是尤為重要的

我們最開始學習C++時,會學到類的初始化,或者是變數定義為某個值,再對某個值進行遍歷,,,
類似如下:

點擊查看代碼
#include <iostream>         // 包含頭文件。

using namespace std;        // 指定預設的命名空間。

int main()
{
    int a = 10;
    int b = (10);
    int c(10);
    int e = {10};
    int f{ 10 };

    cout << "a=" << a << endl;
    cout << "b=" << b << endl;
    cout << "c=" << c << endl;
    cout << "e=" << e << endl;
    cout << "f=" << f << endl;
}

尤其c++,初學時候內心非常感慨,怎麼這麼多初始化方式,我該用哪個
現在回頭看,其實能熟悉一個,其他看懂就行,看不懂都沒關係,畢竟我們還有gdb或者typeid()幫忙,可以看看這個變數類型具體是什麼
說到底我們要問題導向目標導向,我們學習C++是為了類似openfoam這樣的大工程服務的
那學這麼多初始化賦值,有必要嗎
如果是個大工程或者大程式是完全沒必要的,
因為大工程的數據都是從文件或者資料庫中獲得的
你想想,要計算一個流體問題,如果有一萬個網格,手打一萬個三維位置就已經非常讓人頭疼了,更不要說上百個組分和壓力等參數了,不現實
所以又回到了問題的起點,讀取文件很重要,那麼如何從文件中初始化程式,如何讀取文件


在看of源碼之前,不妨複習下C++是怎麼讀取文件的,進行下知識鞏固

C++多使用fstream類或ifstream類

點擊查看代碼
#include <iostream>
#include <fstream>  // ifstream類需要包含的頭文件。
#include <string>     // getline()函數需要包含的頭文件。
using  namespace std;

int main()
{
    string filename = R"(./test.txt)";

    //ifstream fin(filename, ios::in);
    ifstream fin;
    fin.open(filename , ios::in);

    // 判斷打開文件是否成功。
    // 失敗的原因主要有:1)目錄不存在;2)文件不存在;3)沒有許可權,Linux平臺下很常見。
    if (fin.is_open() == false)
    {
        cout << "打開文件" << filename << "失敗。\n";  return 0;
    }

    string buffer;
    while (fin >> buffer)
    {
        cout << buffer << endl;
    }

    fin.close();	   // 關閉文件,fin對象失效前會自動調用close()。

    cout << "操作文件完成。\n";
}


OPENFOAM的文件讀寫,主要是用IOdictionary類

打開IOdictionary類的頭文件,並不複雜

點擊查看代碼
class IOdictionary
:
    public baseIOdictionary
{

public:

    // Constructors

        //- Construct given an IOobject
        IOdictionary(const IOobject&);

        //- Construct given an IOobject and dictionary
        IOdictionary(const IOobject&, const dictionary&);

        //- Construct given an IOobject and Istream
        IOdictionary(const IOobject&, Istream&);

        //- Copy constructor
        IOdictionary(const IOdictionary&);

        //- Move constructor
        IOdictionary(IOdictionary&&);


    //- Destructor
    virtual ~IOdictionary();


    // Member Functions

        //- Is object global
        virtual bool global() const
        {
            return true;
        }

        //- Return complete path + object name if the file exists
        //  either in the case/processor or case otherwise null
        virtual fileName filePath() const
        {
            return globalFilePath(type());
        }


    // Member Operators

        //- Move assignment
        void operator=(IOdictionary&&);
};

繼承於baseIOdictionary類,藉助於IOobject介面有五個構造函數,這五個中一個移動構造一個拷貝構造,其他類繼承可以創建自己成員函數global()和filePath(),頭文件還對移動構造創建了等號賦值運算符
我們再看IOdictionary類的關鍵先生IOobject


IOobject就稍顯複雜了,我們先看openfoam對其的描述:

IOobject defines the attributes of an object for which implicit objectRegistry management is supported, and provides the infrastructure for performing stream I/O.
An IOobject is constructed with an object name, a class name, an instance path, a reference to a objectRegistry, and parameters determining its storage status.

下麵這張圖是openfoam與該介面有關的類譜圖
image
打開regIOobject類,這是個抽象類,openfoam對regIOobject的描述為:

regIOobject is an abstract class derived from IOobject to handle automatic object registration with the objectRegistry.

這裡不贅述了,最後查了好半天,大概是哈希表來的,方便查詢讀取。openfoam中/0,/constant以及/system文件夾中那種奇怪的文件格式肯定有適合自己的讀取方法。

那我們看看IOobject類相關源碼,
IOobject類有四個枚舉控制讀取許可權以及文件檢查

點擊查看代碼
        //- Enumeration defining the valid states of an IOobject
        enum objectState
        {
            GOOD,
            BAD
        };

        //- Enumeration defining the read options
        enum readOption
        {
            MUST_READ,
            MUST_READ_IF_MODIFIED,
            READ_IF_PRESENT,
            NO_READ
        };

        //- Enumeration defining the write options
        enum writeOption
        {
            AUTO_WRITE = 0,
            NO_WRITE = 1
        };

        //- Enumeration defining the file checking options
        enum fileCheckTypes
        {
            timeStamp,
            timeStampMaster,
            inotify,
            inotifyMaster
        };

內共有六個構造函數,其中一個拷貝構造

點擊查看代碼
    // Constructors

        //- Construct from name, instance, registry, io options
        IOobject
        (
            const word& name,
            const fileName& instance,
            const objectRegistry& registry,
            readOption r=NO_READ,
            writeOption w=NO_WRITE,
            bool registerObject=true
        );

        //- Construct from name, instance, local, registry, io options
        IOobject
        (
            const word& name,
            const fileName& instance,
            const fileName& local,
            const objectRegistry& registry,
            readOption r=NO_READ,
            writeOption w=NO_WRITE,
            bool registerObject=true
        );

        //- Construct from path, registry, io options
        //  Uses fileNameComponents() to split path into components.
        IOobject
        (
            const fileName& path,
            const objectRegistry& registry,
            readOption r=NO_READ,
            writeOption w=NO_WRITE,
            bool registerObject=true
        );

        //- Construct from copy resetting registry
        IOobject
        (
            const IOobject& io,
            const objectRegistry& registry
        );

        //- Construct from copy resetting name
        IOobject
        (
            const IOobject& io,
            const word& name
        );

        //- Copy constructor
        IOobject(const IOobject& io) = default;

我們舉個例子,基於這些構造函數可以這樣寫類似這樣的讀取埠:

點擊查看代碼
IOobject dicName(
    "dicName",
    runTime.timeName(),
    //runTime.constant(),
    mesh,
    IOobject::MUST_READ,
    IOobject::AUTO_WRITE
) ;

再回到IOdictionary類,

通過查看IOdictionary類的構造函數,我們瞭解到可以在創建好的IOobject埠基礎上構建,也可以直接構建IOobject埠

點擊查看代碼
    IOdictionary dicName(
        IOobject (
            "dicName",
            //runTime.constant(),
            runTime.system(),
            mesh,
            IOobject::MUST_READ,
            IOobject::AUTO_WRITE
        )
    ) ;

那麼我們如何通過IOdictionary類讀取openfoam內文件呢,
以openfoam內置icoFoam為例
$ ls cavity/
0 constant system
$ tree cavity/
cavity/
├── 0
│ ├── U
│ └── p
├── constant
│ ├── polyMesh
│ │ ├── boundary
│ │ ├── faces
│ │ ├── neighbour
│ │ ├── owner
│ │ └── points
│ └── transportProperties
└── system
├── blockMeshDict
├── controlDict
├── fvSchemes
└── fvSolution
$ head cavity/0/* -n15

  • cavity/0/U *
    /--------------------------------- C++ -----------------------------------
    ========= |
    \ / F ield | OpenFOAM: The Open Source CFD Toolbox
    \ / O peration | Website: https://openfoam.org
    \ / A nd | Version: 8
    \/ M anipulation |
    *---------------------------------------------------------------------------*/
    FoamFile
    {
    version 2.0;
    format ascii;
    class ** volVectorField;**
    object U;
    }
    // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //

  • cavity/0/p *
    /--------------------------------- C++ -----------------------------------
    ========= |
    \ / F ield | OpenFOAM: The Open Source CFD Toolbox
    \ / O peration | Website: https://openfoam.org
    \ / A nd | Version: 8
    \/ M anipulation |
    *---------------------------------------------------------------------------*/
    FoamFile
    {
    version 2.0;
    format ascii;
    class ** volScalarField;**
    object p;
    }
    // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
    從以上內容可以看到,U和v分別屬於volVectorField類以及volScalarField類,那麼就利用IOobject介面分別創建相關類如下所示:

點擊查看代碼
    volVectorField U(
        IOobject(
            "U" ,
            runTime.timeName() ,
            mesh ,
            IOobject::MUST_READ ,
            IOobject::AUTO_WRITE
        ) ,
        mesh
    );
    volScalarField p(
        IOobject(
            "p" ,
            runTime.timeName() ,
            mesh ,
            IOobject::MUST_READ ,
            IOobject::AUTO_WRITE
        ) ,
        mesh
    );

再看其他兩個文件夾
$ grep -rn "dicti" .
./cavity/constant/transportProperties:12: class dictionary;
./cavity/system/controlDict:12: class dictionary;
./cavity/system/fvSolution:12: class dictionary;
./cavity/system/blockMeshDict:12: class dictionary;
./cavity/system/fvSchemes:12: class dictionary;
./constant/transportProperties:12: class dictionary;
./system/controlDict:12: class dictionary;
./system/fvSolution:12: class dictionary;
./system/blockMeshDict:12: class dictionary;
./system/fvSchemes:12: class dictionary;
都是dictionary類,那創建起來更方便了,比如說contorlDict文件

點擊查看代碼
    IOdictionary controlDict(
        IOobject (
            "controlDict",
            runTime.constant(),
            //runTime.system(),
            mesh,
            IOobject::MUST_READ,
            IOobject::AUTO_WRITE
        )
    ) ;

有了dictionary這個字典類,顧名思義,字典當然是很方便查找啊,而且本身也是在鏈表以及哈希列表基礎上建立的,能用的函數就很豐富了,如lookup()等。


綜上,openfoam創建了一個讀取方便查找容易的類支持of進行數據處理,尋根溯源很麻煩,但是用起來還是很簡單的。

正因為文件讀取占用很大的比重,這篇文章寫了三個多小時,我們也是藉此機會對openfoam內部略窺一二,這樣我們就知道我們的程式在寫什麼,知道其所能為與不能為。


最後奉上自己編寫的openfoam codesnip ,節約大家時間

點擊查看代碼
//***********************************************//
	//openfoam
	"Foam_IOobject": {
		"prefix": "IOobject_Foam_",
		"body": [
			"IOobject ${1|U,p,T,dicName|}(",
			// "\t${2|\"U\",\"p\",\"T\"|}",
			"\t\"${1}\",",
			"\t//runTime.timeName(),",
			"\t//runTime.constant(),",
			"\tmesh,",
			"\tIOobject::MUST_READ,",
			"\tIOobject::AUTO_WRITE",
			") ;"
		],
		"description": "FOAM::IOobject"
	},
	"Foam::IOdictionary": {
		"prefix": "IOdictionary_Foam_",
		"body": [
			"IOdictionary ${1:dicName}(",
			"\tIOobject (",
			// "\t${2|\"U\",\"p\",\"T\"|}",
			"\t\t\"${1}\",",
			"\t\t//runTime.constant(),",
			"\t\t//runTime.system(),",
			"\t\tmesh,",
			"\t\tIOobject::MUST_READ,",
			"\t\tIOobject::AUTO_WRITE",
			"\t)",
			") ;"
		],
		"description": "Foam::IOdictionary"
	},
	"Foam::volVectorField": {
		"prefix": "volVectorField_Foam_",
		"body": [
			"volVectorField ${U}(",
			"\tIOobject (",
			"\t\t\"${U}\",",
			"\t\trunTime.timeName(),",
			"\t\tmesh,",
			"\t\tIOobject::MUST_READ,",
			"\t\tIOobject::AUTO_WRITE",
			"\t),",
			"\tmesh",
			") ;"
		],
		"description": "Foam::volVectorField"
	},
	"Foam::volScalarField": {
		"prefix": "volScalarField_Foam_",
		"body": [
			"volScalarField ${p}(",
			"\tIOobject (",
			"\t\t\"${p}\",",
			"\t\trunTime.timeName(),",
			"\t\tmesh,",
			"\t\tIOobject::MUST_READ,",
			"\t\tIOobject::AUTO_WRITE",
			"\t),",
			"\tmesh",
			") ;"
		],
		"description": "Foam::volScalarField"
	},
	"Foam::scalar": {
		"prefix": "scalar",
		"body": [
			"scalar "
		],
		"description": "Foam::scalar"
	},
	//***********************************************//

創作不易,如若喜歡,不勝感激,歡迎支持,歡迎指正


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 如何優化線上WebAssembly WebAssembly部署使用 HTTPS : 為什麼?我可以通過一個案例查看 ,下麵我們會通過masa docs站點進行測試 打開 http://docs.masastack.com/blazor/getting-started/installation 網站 ...
  • 如何使用命名行指令去運行和打包.net6項目 前言 之前發佈了一個.net webApi入門項目,項目文章,在文章中我推薦的是Docker部署,只說明瞭如何打包,但是沒有說怎麼運行,考慮到很多人寫代碼不是用的Visual Studio。這裡講一下控制台怎麼去管理項目。 準備工作 安裝.net6 SD ...
  • 接前上一篇:平臺調用 (P/Invoke):DllImport特性說明 首先,我們知道C#和C/C++都是跨平臺的,但是原理上他們是不一樣的: C#首先編譯成一種中間語言(IL)的程式集,然後將這種程式集放到不同平臺下的解釋器裡面去執行,這就是說一次編譯到處運行 C/C++是針對不同的平臺直接編譯, ...
  • 1.說說.NET7中 _ViewImports文件的作用? 2.什麼是Razor頁面? 3.說說.NET5中 __ViewStart文件的作用? 4.如何在Razor頁面中實現數據模型綁定? 5.如何在Controller中註入service? 6.描述一下依賴註入後的服務生命周期? 7.說說ASP ...
  • 今年開年,最火的莫過於ChatGPT的相關討論,這個提供了非常強大的AI處理,並且整個平臺也提供了很多對應的API進行接入的處理,使得我們可以在各種程式上無縫接入AI的後端處理,從而實現智能AI的各種應用。ChatGPT的API可以在前端,以及一些後端進行API的接入,本篇隨筆主要介紹基於ChatG... ...
  • 一、什麼時候需要用到NuGet私有伺服器 很多公司中架構師會搭建一個統一的項目基礎架構模板,然後全部新項目都會拿這個基礎架構來開發新的項目,那架構中就會有很多的中間件,比喻公司內部的封裝好的Redis中間件,訪問資料庫的中間件,MQ中間件,小程式中間件等等。 現在很多項目都用這個模板開發了,然後其中 ...
  • 概述 使用原型實例指定創建對象的種類,並且通過拷貝這些原型創建新的對象。 在軟體系統開發中,有時候會遇到這樣的情況:我們需要用到多個相同實例,最簡單直接的方法是通過多次調用new方法來創建相同的實例。 student s=new student(); student s1=new student() ...
  • 一 背景 在我們的工作中我們經常有一種場景就是要使用到隊列,特別是對於這樣的一種情況:就是生產的速度明顯快於消費的速度,而且在多線程的環境下消息的生產由多個線程產生消息的消費則沒有這種限制,通過使用隊列這種方式能夠很大程度上將多線程的問題通過入隊的方式變成單個線程內的消息的聚合,然後通過單獨的線程進 ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...