[OpenFOAM] 변경 수법 추가 처리 ③: 함수 또는 클래스로 추가 처리
개시하다
"OpenFOAM" 변경 수법 추가 처리 ②: 구해기에서 추가 처리 "의 계속.
OpenFOAM의 계산에서 수법을 바꾸어 추가 처리하다.지난번에 구해기의main () 함수에서 처리를 설명했습니다.
이번에 소개한 것은 이 처리를 함수나 클래스로 만들고main() 함수로 호출하는 방법이다.
방법 일람
이 기사는 다양한 기법을 소개하는 시리즈 중 하나로 전체적으로 다음과 같은 방법으로 진행될 예정이다.실행이 확인된 파일은 GitHub에 공개됩니다.
pimpleFoam)functionObjects)codedFunctionObject)IOdictionaryrunTimeSelectionTablewmake libsocodedTemplete작업 환경
함수 추가 처리
우선 처리의 함수화를 시도해 보자.따라서 여러 곳에서 호출 처리를 할 때 코드가 대폭 간소화된다.
미리 준비하다
다음 스크립트를 만들고 실행합니다.이것에 따라 원래
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.scoreFuncPimpleFoamscore를 출력했는지 확인한다.$ 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.)