メインコンテンツに移動

直方格子2

ここでは, 体積要素ではなく, 体積要素の境界にある面積要素のデータを構築する手法を説明します.詳細はXCodeでVTK楽園を参照

基本は先ほどと同じです.

フォルダー指定等

        //      時間ステップ{{{
        unsigned int ntMax=100;
        boost::filesystem::path bodyFolder("myBody");
        boost::filesystem::path wallFolder("myWall");     //  stemNameを下にするなら, 同フォルダーでいいかもしれないが,まあいいぢゃん
        std::string bodyStemName="body";    //      ファイル名は    folderName/stemName時間ステップ(N桁の数字)extName
        std::string wallStemName="wall";       //      ファイル名は    folderName/stemName時間ステップ(N桁の数字)extName
        std::string extName=".vtm";
        int fileN=4;
        //}}}
        //      フォルダーを作成{{{
        try
        {
                //      既存は削除
                if (boost::filesystem::exists(bodyFolder)) boost::filesystem::remove_all(bodyFolder);
                if (boost::filesystem::exists(wallFolder)) boost::filesystem::remove_all(wallFolder);
                boost::filesystem::create_directory(bodyFolder);
                boost::filesystem::create_directory(wallFolder);
        }
        catch (std::exception& e)
        {
                std::cerr << bodyFolder << "フォルダあるいは" << wallFolder << "がエラー:" << e.what() << std::endl;
                return 1;
        }//}}}

領域定義の部分

        //      時間ステップだけ作業する
        for(unsigned int nt=1;nt<=ntMax;nt++)
        {
                vtkSmartPointer<vtkMultiBlockDataSet> body=vtkSmartPointer<vtkMultiBlockDataSet>::New();
                vtkSmartPointer<vtkMultiBlockDataSet> wall=vtkSmartPointer<vtkMultiBlockDataSet>::New();
                //      領域達を定義    {{{
                for(int idom=0;idom<2;idom++)
                {
                        double imageSpacing[3]={0.05,0.05,0.05};
                        int imageExtent[6]={0,0,0,0,0,0};
                        double imageOrigin[3]={0.,0.,0.};
+---- 60 行:本体を定義-------------------------------------------------------------------------------------------------------------------------------------------
+---- 78 行:境界達を定義-----------------------------------------------------------------------------------------------------------------------------------------
                        std::cout << "作製:" << idom << std::endl;
                }//}}}
 

本体を定義

                for(int idom=0;idom<2;idom++)
                {
                        double imageSpacing[3]={0.05,0.05,0.05};
                        int imageExtent[6]={0,0,0,0,0,0};
                        double imageOrigin[3]={0.,0.,0.};
                        //      本体を定義{{{
                        {
                                //      本体の形状を定義{{{
                                typedef vtkSmartPointer<vtkImageData> ImageDataPtr;
                                ImageDataPtr image=ImageDataPtr::New();
                                image->SetSpacing(imageSpacing);
                                switch (idom)
                                {
                                case 0: //      領域0           0,0.05,0.10
                                        imageExtent[1]=20;      imageExtent[3]=10;      imageExtent[5]=10;
                                        imageOrigin[0]=0;       imageOrigin[1]=0;       imageOrigin[2]=0;
                                        break;
                                        ;;
                                case 1: //      領域1
                                        imageExtent[1]=10;      imageExtent[3]=40;      imageExtent[5]=40;
                                        imageOrigin[0]=1;       imageOrigin[1]=-0.5;    imageOrigin[2]=-0.5;
                                        break;
                                        ;;
                                }
                                image->SetExtent(imageExtent);
                                image->SetOrigin(imageOrigin);
                                body->SetBlock(idom,image);
                                //}}}
+----- 35 行:本体の物理量を定義 ---------------------------------------------------------------------------------------------------------------------------------
                        }
+---- 63 行:境界達を定義 -----------------------------------------------------------------------------------------------------------------------------------------
                        std::cout << "作製:" << idom << std::endl;
                }//}}}
 

境界たちを定義

                        //      境界達を定義{{{
                        for(int iwall=0;iwall<6;iwall++)
                        {
                                typedef vtkSmartPointer<vtkImageData> ImageDataPtr;
                                ImageDataPtr image=ImageDataPtr::New();
                                image->SetSpacing(imageSpacing);
                                int wimageExtent[6];    for(int iii=0;iii<6;iii++) wimageExtent[iii]=imageExtent[iii];
                                double wimageOrigin[3]; for(int iii=0;iii<3;iii++) wimageOrigin[iii]=imageOrigin[iii];
                                std::string name;
                                switch (iwall)
                                {
                                case 0: //      左側面:X幅がない
                                        wimageExtent[1]=wimageExtent[0]=0; name="left";break;;
                                case 1: //      右側面:X幅がない & 原点がずれる
                                        wimageExtent[0]=wimageExtent[1];name="right"; break;;
                                case 2: //      下側面:Y幅がない
                                        wimageExtent[3]=wimageExtent[2];name="floor"; break;;
                                case 3: //      上側面:Y幅がない
                                        wimageExtent[2]=wimageExtent[3];name="ceiling"; break;;
                                case 4: //      奥側面:Z幅がない
                                        wimageExtent[5]=wimageExtent[4];name="away"; break;;
                                case 5: //      前側面:Z幅がない
                                        wimageExtent[4]=wimageExtent[5];name="home"; break;;
                                }
                                image->SetExtent(wimageExtent);
                                image->SetOrigin(wimageOrigin);
                                int iBL=6*idom+iwall;
                                wall->SetBlock(iBL,image);
                                wall->GetMetaData(iBL)->Set(vtkImageData::NAME(),name.c_str()); // イメージに名前を付ける
+----- 35 行:境界面の物理量を定義 -------------------------------------------------------------------------------------------------------------------------------
                        }
 

動作

上記のプログラムでは, myBody.vtm が本体の体積要素のデータを, myWall.vtmに境界の面積要素のデータが入る. 境界の面積要素データは, 各領域・各境界の壁面が別々のデータとして入る.場合によっては,選択を行うときに困難かもしれないが,これはMultiDataSetのツリー構成を各自工夫すればよい.