[OpenFOAM] 변경 수법 추가 처리 ③: 함수 또는 클래스로 추가 처리
개시하다
"OpenFOAM" 변경 수법 추가 처리 ②: 구해기에서 추가 처리 "의 계속.
OpenFOAM의 계산에서 수법을 바꾸어 추가 처리하다.지난번에 구해기의main () 함수에서 처리를 설명했습니다.
이번에 소개한 것은 이 처리를 함수나 클래스로 만들고main() 함수로 호출하는 방법이다.
방법 일람
이 기사는 다양한 기법을 소개하는 시리즈 중 하나로 전체적으로 다음과 같은 방법으로 진행될 예정이다.실행이 확인된 파일은 GitHub에 공개됩니다.
pimpleFoam
)functionObjects
)codedFunctionObject
)IOdictionary
runTimeSelectionTable
wmake libso
codedTemplete
작업 환경
함수 추가 처리
우선 처리의 함수화를 시도해 보자.따라서 여러 곳에서 호출 처리를 할 때 코드가 대폭 간소화된다.
미리 준비하다
다음 스크립트를 만들고 실행합니다.이것에 따라 원래
pimpleFoam
와 그 강좌가 복제되었다.앞으로 이 스크립트를 실행했다는 전제로 진행될 겁니다.prepareFuncCase.sh
#!/bin/bash
# (任意) 今回作成するディレクトリとソルバーとケースに名前をつける
dirName=$FOAM_RUN/003.class
solverName=scoreFuncPimpleFoam
caseName=funcCase
mkdir -p $dirName
# ソルバーのコピー
cp -r $FOAM_SOLVERS/incompressible/pimpleFoam $dirName/$solverName
rm -r $dirName/$solverName/overPimpleDyMFoam $dirName/$solverName/SRFPimpleFoam
sed -i -e "s/APPBIN)\/pimpleFoam/USER\_APPBIN)\/${solverName}/g" $dirName/$solverName/Make/files
cp $FOAM_SRC/finiteVolume/cfdTools/general/CorrectPhi/CorrectPhi.H $dirName/$solverName/cpCorrectPhi.H
sed -i -e "s/CorrectPhi.H/cpCorrectPhi.H/" $dirName/$solverName/pimpleFoam.C
echo "Solver : $dirName/$solverName"
# チュートリアルのコピー
cp -r $FOAM_TUTORIALS/incompressible/pimpleFoam/RAS/TJunction $dirName/$caseName
sed -i -e "s/pimpleFoam/${solverName}/" ${dirName}/${caseName}/system/controlDict
# 元々の1.5秒を計算する必要は無いので減らす
sed -i -e "s/^endTime.*/endTime 0.3;/" ${dirName}/${caseName}/system/controlDict
# functionObjectの記述を削除
startLine=`cat ${dirName}/${caseName}/system/controlDict | grep -n "^functions" | sed -e 's/:.*//g'`
endLine=`cat ${dirName}/${caseName}/system/controlDict | wc -l`
sed -i -e "${startLine},${endLine}d" ${dirName}/${caseName}/system/controlDict
echo "Case : $dirName/$caseName"
함수 정의
함수는main () 함수 앞에 정의됩니다.다음은 pimpleFoam입니다.함수가 C의
#include
와 main()
사이에서 어떻게 움직이는지 기술하다.다음은
getScore
라는 함수를 정의했다.fvMesh
는 클래스를 매개 변수로 하고 출입구 유량의 총계를 scalar
클래스로 정의한다.#include "fvCFD.H"
#include "dynamicFvMesh.H"
#include "singlePhaseTransportModel.H"
#include "turbulentTransportModel.H"
#include "pimpleControl.H"
#include "cpCorrectPhi.H"
#include "fvOptions.H"
// 85行目付近 ここを追加
scalar getScore(const fvMesh& mesh_)
{
const surfaceScalarField& phi = mesh_.lookupObject<surfaceScalarField>("phi");
scalar score_ = 0.0;
forAll(phi.boundaryField(), patchI)
{
const fvPatch& patch = phi.boundaryField()[patchI].patch();
const scalarField& pphi = phi.boundaryField()[patchI];
if (!(patch.name()=="inlet" || patch.name()=="outlet1" || patch.name()=="outlet2")) continue;
Info << " sum(" << patch.name() << ") of phi = " << gSum(pphi) << endl;
score_ += gSum(pphi);
}
return score_;
}
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
int main(int argc, char *argv[])
{
호출 함수
이 정의의 함수를 호출하기 위해
pimpleFoam.C
의 main()
함수에서 다음과 같다. if (pimple.turbCorr())
{
laminarTransport.correct();
turbulence->correct();
}
}
// 187行目付近。この2行を追加する。
const scalar score = getScore(mesh);
Info << nl << "score: " << runTime.value() << tab << score << nl << endl;
runTime.write();
에서 score
이라는 변수에 getScore()
함수로 계산된 유량 총계를 저장하고 Info
로 출력한다.컴파일 및 테스트
다음과 같이 컴파일합니다.
$ cd $FOAM_RUN/003.class/scoreFuncPimpleFoam
$ wclean
$ wmake
출력이 잘못되지 않으면 다음과 같이 해답을 실행해 보십시오.$ cd $FOAM_RUN/003.class/funcCase
$ foamCleanTutorials
$ foamRunTutorials
는 다음과 같다log.scoreFuncPimpleFoam
score를 출력했는지 확인한다.$ cat $FOAM_RUN/003.class/funcCase/log.scoreFuncPimpleFoam | grep -e "score:" | sed "s/score: //"
0.00120482 7.00171e-10
0.00265769 1.88353e-10
0.00439595 -7.65986e-10
0.00647429 2.55232e-09
0.0089355 3.27205e-09
0.0118731 -1.48406e-09
0.0153981 2.49265e-09
0.0196282 2.54628e-09
0.0246515 -9.17793e-09
0.0304475 -6.57753e-09
0.0374028 -4.7443e-09
0.0452274 5.67256e-09
0.0543562 -5.79236e-09
0.0619635 -3.46103e-09
0.0695708 -4.28805e-09
0.0756566 -5.23626e-09
0.0817425 2.75405e-09
...
위의 그림과 같이 출력하면 됩니다.클래스에 처리 추가
다음엔 처리용 클래스를 만들어 보자.
미리 준비하다
다음 스크립트를 실행하여 이전 이름과 다른 구해기
scoreClassPimpleFoam
와 상황funcCase
을 만듭니다.아까 대본과 다른 건 첫 번째밖에 없어요.prepareClassCase.sh
#!/bin/bash
# (任意) 今回作成するディレクトリとソルバーとケースに名前をつける
dirName=$FOAM_RUN/003.class
solverName=scoreClassPimpleFoam #scoreFuncPimpleFoam
caseName=classCase #funcCase
mkdir -p $dirName
# ソルバーのコピー
cp -r $FOAM_SOLVERS/incompressible/pimpleFoam $dirName/$solverName
rm -r $dirName/$solverName/overPimpleDyMFoam $dirName/$solverName/SRFPimpleFoam
sed -i -e "s/APPBIN)\/pimpleFoam/USER\_APPBIN)\/${solverName}/g" $dirName/$solverName/Make/files
cp $FOAM_SRC/finiteVolume/cfdTools/general/CorrectPhi/CorrectPhi.H $dirName/$solverName/cpCorrectPhi.H
sed -i -e "s/CorrectPhi.H/cpCorrectPhi.H/" $dirName/$solverName/pimpleFoam.C
echo "Solver : $dirName/$solverName"
# チュートリアルのコピー
cp -r $FOAM_TUTORIALS/incompressible/pimpleFoam/RAS/TJunction $dirName/$caseName
sed -i -e "s/pimpleFoam/${solverName}/" ${dirName}/${caseName}/system/controlDict
# 元々の1.5秒を計算する必要は無いので減らす
sed -i -e "s/^endTime.*/endTime 0.3;/" ${dirName}/${caseName}/system/controlDict
# functionObjectの記述を削除
startLine=`cat ${dirName}/${caseName}/system/controlDict | grep -n "^functions" | sed -e 's/:.*//g'`
endLine=`cat ${dirName}/${caseName}/system/controlDict | wc -l`
sed -i -e "${startLine},${endLine}d" ${dirName}/${caseName}/system/controlDict
echo "Case : $dirName/$caseName"
.C 및.H
오픈봄은 학급을 만들면서 선언과 정의를 분리하는 데 익숙해졌기 때문에 이번에도 그것대로 만들었다.즉, 구성은 다음과 같다.
.C
과 .H
(예: getScore.C
및 getScore.H
설명:
.H
에서 "어떤 함수 변수 매개 변수가 있는지 설명합니다.정의:
.C
에서'함수 등 어떻게 동작하는지'를 기술합니다..H
.include
구해기와 분리하여 컴파일하고 구해기와 연결그렇다면 이 구성을 답습해 먼저 제작
.C
과getScore.H
를 진행한다.디렉토리 구조
이번 목표는 다음 목록 구성을 목표로 한다.
├── getScore
│ ├── getScore.C
│ └── getScore.H
├── Make
│ ├── files
│ └── options
├── UEqn.H
├── correctPhi.H
├── cpCorrectPhi.H
├── createFields.H
├── pEqn.H
└── pimpleFoam.C
따라서 다음과 같이 구해기의 디렉터리에 getScore.C
디렉터리를 만듭니다.$ mkdir -p $FOAM_RUN/003.class/scoreClassPimpleFoam/getScore
아래에서 제작getScore
과getScore.C
.getScore/getScore.H
먼저 아래와 같이 제작
getScore.H
.#ifndef getScore_H
#define getScore_H
#include "fvMesh.H"
namespace Foam
{
class getScore
{
protected:
// Protected data
const fvMesh& mesh_;
scalar score_;
public:
// Constructors
getScore(const fvMesh& mesh);
//- Destructor
~getScore()
{}
// Member Functions
void calculate();
const scalar& value() const
{
return score_;
}
};
}
#endif
우선 이 반의 골격은 다음과 같다.namespace Foam
{
class getScore
{
public:
// Constructors
getScore(const fvMesh& mesh);
//- Destructor
~getScore()
{}
};
}
getScore/getScore.H
라는 OpenFOAM의namespace에서 getScore라는 반을 발표했다.또 구조기는 분석기Foam
에 대해서도'아무것도 하지 않는다'는 정의를 내렸다고 밝혔다.또한 다음 부분에서 이 분류에 저장된 변수를 정의합니다.
protected:
// Protected data
const fvMesh& mesh_;
scalar score_;
{}
이기 때문에 이 종류에서만 protected
와mesh_
를 호출할 수 있다.다음 섹션에서는 함수를 설명합니다.
public:
// Member Functions
void calculate();
const scalar& value() const
{
return score_;
}
이 함수들score_
이기 때문에 클래스 밖, 즉 구해기 등에서 호출할 수 있다.이번public
에 점수 계산calculate()
을 해서 그 값과 같은 구성을 되돌려줍니다.또한 value()
는 간단한 함수이기 때문에 여기에 정의합니다.또한 본 클래스
value()
클래스는 변수로 사용되며, fvMesh
클래스 성명을 읽기 위해 먼저 다음과 같다.#include "fvMesh.H"
다음 부분은 다른 곳에fvMesh
성명 유형의 기술이 있을 때 중복을 피하는 데 쓰인다.이 경우 이전에 읽은 getScore
를 사용합니다.하지만 신중하게 보기 위해서다. 원래 이름은 중복하지 않는 것이 좋으니 이름은 중복하지 않는 것이 좋다.#ifndef getScore_H
#define getScore_H
...
#endif
getScore/getScore.C
다음과 같이 정의 섹션을 생성합니다.
#include "getScore.H"
#include "surfaceFields.H"
Foam::getScore::getScore
(
const fvMesh& mesh
)
:
mesh_(mesh)
{
}
void Foam::getScore::calculate()
{
Info << "Running calculate()" << endl;
const surfaceScalarField& phi = mesh_.lookupObject<surfaceScalarField>("phi");
score_ = 0.0;
forAll(phi.boundaryField(), patchI)
{
const fvPatch& patch = phi.boundaryField()[patchI].patch();
const scalarField& pphi = phi.boundaryField()[patchI];
if (!(patch.name()=="inlet" || patch.name()=="outlet1" || patch.name()=="outlet2")) continue;
Info << " sum(" << patch.name() << ") of phi = " << gSum(pphi) << endl;
score_ += gSum(pphi);
}
}
이 종류는 구조기, 분석기, 함수getScore
, 함수calculate()
가 있지만 분석기와 함수value()
는 이미 value()
에 정의되었고 나머지 구조기와 **함수getScore.H
는 calculate()
**에 의해 정의되었다.먼저 다음과 같이 구조기를 정의했다.
Foam::getScore::getScore
(
const fvMesh& mesh
)
:
mesh_(mesh)
{
}
getScore.C
수신 클래스 지침은 클래스 내 변수fvMesh
의 정의로 한다.이렇게 하면 구해기 옆의 격자에 접근할 수 있다.OpenFOAM의 경우 mesh_
에 접근할 수 있다면 기본적으로 모든 것이 가능하지만 다른 구해기 측의 변수와 정보 등이 있다면 매개 변수와 변수를 만들 수 있다.이하
fvMesh
는 이번 목적의'출입구 유량의 총계를 구하는 것'으로 처리하고 있다.되돌아오는 값은 calculate()
이기 때문에 이 함수 자체는 되돌아오지 않고'갱신 클래스 내 변수void
'이다.void Foam::getScore::calculate()
{
Info << "Running calculate()" << endl;
const surfaceScalarField& phi = mesh_.lookupObject<surfaceScalarField>("phi");
score_ = 0.0;
forAll(phi.boundaryField(), patchI)
{
const fvPatch& patch = phi.boundaryField()[patchI].patch();
const scalarField& pphi = phi.boundaryField()[patchI];
if (!(patch.name()=="inlet" || patch.name()=="outlet1" || patch.name()=="outlet2")) continue;
Info << " sum(" << patch.name() << ") of phi = " << gSum(pphi) << endl;
score_ += gSum(pphi);
}
}
최초score_
에서 이#include
류의 선언으로 된 getScore.H와getScore
내 등장calculate()
이 선언된surfaceFields.H를 불러오는 중입니다.surfaceScalarField
중 다른 사용하고 싶은 종류가 있을 때도 선언문을 읽어야 한다.#include "getScore.H"
#include "surfaceFields.H"
pimpleFoam.C
calculate()
함수에서 위에서 설명한 getScore.C
와 getScore.H
를 호출합니다.이를 위해 다음과 같이 3곳main()
을 변경한다.pimpleFoam.C: 110번째 줄 근처
(前略)
#include "fvCFD.H"
#include "dynamicFvMesh.H"
#include "singlePhaseTransportModel.H"
#include "turbulentTransportModel.H"
#include "pimpleControl.H"
#include "cpCorrectPhi.H"
#include "fvOptions.H"
// 85行目付近
#include "getScore.H" // ★これを追加
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
int main(int argc, char *argv[])
{
#incl...(略)
#include "CourantNo.H"
#include "setInitialDeltaT.H"
// 110行目付近
getScore myScore(mesh); // ★これを追加
turbulence->validate();
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
Info<< "\nStarting time loop\n" << endl;
while (runTime.run())
{
(中略)
if (pimple.turbCorr())
{
laminarTransport.correct();
turbulence->correct();
}
}
// ★この2行を追加
myScore.calculate();
Info << nl << "score: " << runTime.value() << tab << myScore.value() << nl << endl;
runTime.write();
runTime.printExecutionTime(Info);
}
(後略)
는 다음과 같이 pimpleFoam.C
의 이름으로 클래스 대상을 만든다. getScore myScore(mesh);
및 getScore
함수 업데이트myScore
의 calculate()
변수 myScore.calculate();
함수 호출 변수myScore
. Info << nl << "score: " << runTime.value() << tab << myScore.value() << nl << endl;
따라서 다음과 같이 구성된다.getScore.C의 컴파일
이러다 getScoreC와 관련된 정보를 읽을 수 없습니다.getScore.C를 컴파일하기 위해 다음과 같이
score_
디렉터리의 내용을 수정합니다.Make/files
getScore/getScore.C # ★ここを追加
pimpleFoam.C
EXE = $(FOAM_USER_APPBIN)/scoreClassPimpleFoam
Make/optionsEXE_INC = \
-IgetScore \ # ★ここを追加
-I$(LIB_SRC)/finiteVolume/lnInclude \
-I$(LIB_SRC)/meshTools/lnInclude \
-I$(LIB_SRC)/sampling/lnInclude \
-I$(LIB_SRC)/TurbulenceModels/turbulenceModels/lnInclude \
-I$(LIB_SRC)/TurbulenceModels/incompressible/lnInclude \
-I$(LIB_SRC)/transportModels \
-I$(LIB_SRC)/transportModels/incompressible/singlePhaseTransportModel \
-I$(LIB_SRC)/dynamicMesh/lnInclude \
-I$(LIB_SRC)/dynamicFvMesh/lnInclude
EXE_LIBS = \
-lfiniteVolume \
-lfvOptions \
-lmeshTools \
-lsampling \
-lturbulenceModels \
-lincompressibleTurbulenceModels \
-lincompressibleTransportModels \
-ldynamicMesh \
-ldynamicFvMesh \
-ltopoChangerFvMesh \
-latmosphericModels
컴파일 및 테스트
다음과 같이 컴파일합니다.
$ cd $FOAM_RUN/003.class/scoreClassPimpleFoam
$ wclean
$ wmake
출력이 잘못되지 않으면 다음과 같이 해답을 실행해 보십시오.$ cd $FOAM_RUN/003.class/classCase
$ foamCleanTutorials
$ foamRunTutorials
는 다음과 같다value()
score를 출력했는지 확인한다.$ cat $FOAM_RUN/003.class/classCase/log.scoreClassPimpleFoam | grep -e "score:" | sed "s/score: //"
0.00120482 7.00171e-10
0.00265769 1.88353e-10
0.00439595 -7.65986e-10
0.00647429 2.55232e-09
0.0089355 3.27205e-09
0.0118731 -1.48406e-09
0.0153981 2.49265e-09
0.0196282 2.54628e-09
0.0246515 -9.17793e-09
0.0304475 -6.57753e-09
0.0374028 -4.7443e-09
0.0452274 5.67256e-09
0.0543562 -5.79236e-09
0.0619635 -3.46103e-09
0.0695708 -4.28805e-09
0.0756566 -5.23626e-09
0.0817425 2.75405e-09
...
위의 그림과 같이 출력하면 됩니다.최후
이번에는 함수와 반을 추가하는 방법을 소개했다.
처리가 복잡해진 상황에서 이처럼 함수나 클래스로 만들면 관리와 변경 등이 쉬워진다.
다음에 이 반에 관해서 이 기능을 계승하는 것을 소개합니다.
Reference
이 문제에 관하여([OpenFOAM] 변경 수법 추가 처리 ③: 함수 또는 클래스로 추가 처리), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://zenn.dev/inabower/articles/d9f6696cdad598텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)