Slide 1

Similar documents
Microsoft PowerPoint - C++_第1回.pptx

JavaプログラミングⅠ

Microsoft PowerPoint - 12.ppt [互換モード]

基礎プログラミング2015

Microsoft PowerPoint - 13.ppt [互換モード]

Microsoft PowerPoint - 計算機言語 第7回.ppt

プログラミング基礎

Javaプログラムの実行手順

PowerPoint プレゼンテーション

JavaプログラミングⅠ

Microsoft PowerPoint - prog03.ppt

メディプロ1 Javaプログラミング補足資料.ppt

Microsoft PowerPoint - 12.ppt [互換モード]

Javaの作成の前に

memo

プログラミング実習I

RX ファミリ用 C/C++ コンパイラ V.1.00 Release 02 ご使用上のお願い RX ファミリ用 C/C++ コンパイラの使用上の注意事項 4 件を連絡します #pragma option 使用時の 1 または 2 バイトの整数型の関数戻り値に関する注意事項 (RXC#012) 共用

Microsoft PowerPoint Java基本技術PrintOut.ppt [互換モード]

Microsoft Word - C言語研修 C++編 3.doc

/*Source.cpp*/ #include<stdio.h> //printf はここでインクルードして初めて使えるようになる // ここで関数 average を定義 3 つの整数の平均値を返す double 型の関数です double average(int a,int b,int c){

Prog1_6th

PowerPoint プレゼンテーション

バイオプログラミング第 1 榊原康文 佐藤健吾 慶應義塾大学理工学部生命情報学科

プログラミング基礎I(再)

関数 C 言語は関数の言語 関数とは 関数の定義 : f(x) = x * x ; 使うときは : y = f(x) 戻り値 引数

Prog2_9th

関数の動作 / printhw(); 7 printf(" n"); printhw(); printf("############ n"); 4 printhw(); 5 関数の作り方 ( 関数名 ) 戻り値 ( 後述 ) void である. 関数名 (

プログラミング実習I

PowerPoint プレゼンテーション

GEC-Java

C のコード例 (Z80 と同機能 ) int main(void) { int i,sum=0; for (i=1; i<=10; i++) sum=sum + i; printf ("sum=%d n",sum); 2

Microsoft PowerPoint - prog04.ppt

SuperH RISC engineファミリ用 C/C++コンパイラパッケージ V.7~V.9 ご使用上のお願い

Microsoft PowerPoint - CproNt02.ppt [互換モード]

.NETプログラマー早期育成ドリル ~VB編 付録 文法早見表~

Microsoft Word - Training10_プリプロセッサ.docx

た場合クラスを用いて 以下のように書くことが出来る ( 教科書 p.270) プログラム例 2( ソースファイル名 :Chap08/AccountTester.java) // 銀行口座クラスとそれをテストするクラス第 1 版 // 銀行口座クラス class Account String name

Microsoft PowerPoint - 04.pptx

Taro-ポインタ変数Ⅰ(公開版).j

Week 1 理解度確認クイズ解答 解説 問題 1 (4 2 点 =8 点 ) 以下の各問いに答えよ 問題 bit 版の Windows8.1 に Java をインストールする時 必要なパッケージはどれか 但し Java のコンパイルができる環境をインストールするものとする 1. jdk

Microsoft PowerPoint - exp2-02_intro.ppt [互換モード]

Java知識テスト問題

微分方程式 モデリングとシミュレーション

PowerPoint プレゼンテーション

第 2 章インタフェース定義言語 (IDL) IDL とは 言語や OS に依存しないインタフェース定義を行うためのインタフェース定義言語です CORBA アプリケーションを作成する場合は インタフェースを定義した IDL ファイルを作成する必要があります ここでは IDL の文法や IDL ファイ

Microsoft Word - Cプログラミング演習(12)

gengo1-2

Microsoft PowerPoint - handout07.ppt [互換モード]

Prog1_10th

gengo1-11

program7app.ppt

Boost.Preprocessor でプログラミングしましょう DigitalGhost

<4D F736F F D2091E63589F182628CBE8CEA8D758DC08E9197BF2E646F6378>

Microsoft PowerPoint - class2-OperatorOverLoad.pptx

C 言語経験者のための C++ 入門

C プログラミング演習 1( 再 ) 2 講義では C プログラミングの基本を学び 演習では やや実践的なプログラミングを通して学ぶ

プログラミングA

Microsoft Word - 03

<4D F736F F D20438CBE8CEA8D758DC03389F0939A82C282AB2E646F63>

第3回 配列とリスト

Microsoft PowerPoint - 13th.ppt [互換モード]

講習No.1

JavaプログラミングⅠ

7 ポインタ (P.61) ポインタを使うと, メモリ上のデータを直接操作することができる. 例えばデータの変更 やコピーなどが簡単にできる. また処理が高速になる. 7.1 ポインタの概念 変数を次のように宣言すると, int num; メモリにその領域が確保される. 仮にその開始のアドレスを 1

情報処理Ⅰ演習

JavaプログラミングⅠ

プログラミング入門1

Microsoft PowerPoint - adi05.ppt [互換モード]

Microsoft PowerPoint - 09.pptx

講習No.10

C 資料 電脳梁山泊烏賊塾 構造体 C++ の構造体 初めに 此処では Visual Studio 2017 を起動し 新しいプロジェクトで Visual C++ の Windows デスクトップを選択し Windows コンソールアプリケーションを作成する 定義と変数宣言 C++ に

Prog1_10th

JAVA入門

デジタル表現論・第6回

C#の基本2 ~プログラムの制御構造~

Method(C 言語では関数と呼ぶ ) メソッドを使うと 処理を纏めて管理することができる 処理 ( メソッド ) の再実行 ( 再利用 ) が簡単にできる y 元々はC 言語の関数であり 入力値に対する値を 定義するもの 数学では F(x) = 2x + 1 など F(x)=2x+1 入力値 (

4-3- 基 C++ に関する知識 オープンソースシステムのソースを解読する上で C++ の知識は必須であるといえる 本カリキュラムでは まずオブジェクト指向に関する Ⅰ. 概要理解を深め クラスの扱い方について学習し STL を使用してアルゴリズムとデータ構造を実装する方法を学習する Ⅱ. 対象専

基礎プログラミング2015

コンピュータ中級B ~Javaプログラミング~ 第3回 コンピュータと情報をやりとりするには?

Java言語 第1回

Java講座

演算増幅器

#include<math.h> 数学関係の関数群で sin() cos() tan() などの三角関数や累乗の pow() 平方根を求める sqrt() 対数 log() などがあります #include<string.h> 文字列を扱う関数群 コイツもまた後日に 4. 自作関数 実は 関数は自分

数値計算

JavaプログラミングⅠ

プログラミング及び演習 第1回 講義概容・実行制御

memo

Microsoft PowerPoint - prog08.ppt

ソフトゼミC 第二回 C++の基礎

プログラミング入門1

JavaプログラミングⅠ

講習No.12

Microsoft PowerPoint - ep_cpp04.ppt

02: 変数と標準入出力

Make the Future Java FY13 PPT Template

デジタル表現論・第4回

Microsoft PowerPoint - chap10_OOP.ppt

基礎プログラミング2015

02: 変数と標準入出力

Microsoft PowerPoint - prog06.ppt

Transcription:

OpenFoam のための C/C++ 第 3 回 OpenFoam で勉強るテンプレート 田中昭雄 1

目的 この勉強会の資料があれば OpenFoam カスタマイズ時に C/C++ で迷わない 2

予定 第 1 回メモリ管理 第 2 回 CFDの例で勉強するクラス 第 3 回 OpenFOAMで勉強するテンプレート 第 4 回 OpenFOAMカスタマイズ 第 5 回未定 第 6 回未定 3

今回のテーマ テンプレート機能を使えるようになる 4

今回の前提 C 言語で 配列を使ったことがある 構造体を使ったことがある 関数を使ったことがある include ファイルを使ったことがある クラスという言葉を聞いたことがある C++ ベースで解説していきます 5

Agenda テンプレート概要 テンプレート関数 テンプレートクラス OpenFoamのVector 6

Agenda テンプレート概要 テンプレート関数 テンプレートクラス OpenFoamのVector 7

テンプレートとは 型指定を利用側で定義することで コード重複を防ぐ ( 型に対して汎用的なコード記述が可能 ) テンプレートの活用例 平均計算関数 T average(int n, T* seq) T sum = 0; for(int i = 0; i < n; ++i) sum += seq[i]; return sum / n; 利用方法 int main() int n = 3; double[] seq = 0.1, 2.5, 3.2; std::cout << average<double>(n, seq) << n ; return 0; 型違い同じ機能を 1 つの定義で実現 8

テンプレートとは 型違い同じ機能は酷似したコードになりやすい テンプレートの活用しない場合 float 型の平均計算関数 float average(int n, float* seq) float sum = 0; for(int i = 0; i < n; ++i) sum += seq[i]; return sum / n; double 型の平均計算関数 double average(int n, double* seq) double sum = 0; for(int i = 0; i < n; ++i) sum += seq[i]; return sum / n; バグがあると全ての型違いに対して修正が必要 9

テンプレート機能一覧 今回の対象はテンプレート関数 テンプレートクラス テンプレート テンプレート関数 テンプレートクラス 共通機能 特殊化 テンプレート引数 今回は対象外 10

Agenda テンプレート概要 テンプレート関数 テンプレートクラス OpenFoamのVector 11

テンプレート関数 関数の戻り値 引数を抽象化した関数 平均計算関数 T average(int n, T* seq) T sum = 0; for(int i = 0; i < n; ++i) sum += seq[i]; return sum / n; 利用方法 int main() int n = 3; double seq = 0.1, 2.5, 3.2; std::cout << average<double>(n, seq) << n ; return 0; 12

テンプレート関数 テンプレート引数は複数指定が可能 最小値取得関数例 1: 最小値取得関数例 2: T min(t a, T b) if(a < b) return a; return b; template<typename T1, typename T2, typename T3> T3 min(t1 a, T2 b) if(a < b) return a; return (T3)b; 利用方法 int main() int a = 3, b = 4; int m = min(a, b); return 0; 型が自明の場合は利用時に省略可能 利用方法 int main() int a = 3; float b = 2.1; double m = min<double>(a, b); return 0; 13

Agenda テンプレート概要 テンプレート関数 テンプレートクラス OpenFoamのVector 14

テンプレートクラス メンバ変数をテンプレート メンバ関数をテンプレート関数 3 次元ベクトルクラス例 : class Vector3D public: T x, y, z; Vector3D(T X, T Y, T Z) x = X, y = Y, z = Z; ; ~Vector3D() ; T innerproduct(const Vector3D<T>& vec) const return x * vec.x + y * vec.y + z * vec.z; ; ; 15

利用時の注意 型が一致していること 3 次元ベクトルクラス利用例 OK な場合 : class Vector3D public: T x, y, z; Vector3D(T X, T Y, T Z) x = X, y = Y, z = Z; ; ~Vector3D() ; T innerproduct(const Vector3D<T>& vec) const return x * vec.x + y * vec.y + z * vec.z; ; ; int main() Vector3D<int> a(10, 10, 10); Vector3D<int> b(2, 3, 4); std::cout << "inner product = << a.innerproduct(b) << " n"; return 0; Inner product = 90 16

利用時の注意 型が一致していること 3 次元ベクトルクラス利用例 NG な場合 : class Vector3D public: T x, y, z; Vector3D(T X, T Y, T Z) x = X, y = Y, z = Z; ; ~Vector3D() ; T innerproduct(const Vector3D<T>& vec) const return x * vec.x + y * vec.y + z * vec.z; ; ; int main() Vector3D<int> a(10, 10, 10); Vector3D<double> b(2.001, 3, 4); std::cout << "inner product = << a.innerproduct(b) << " n"; return 0; コンパイルエラー 17

コンパイルエラー解説 メンバ関数 innerproduct() の引数の型の不一致 3 次元ベクトルクラス : 利用側 : class Vector3D T innerproduct(const Vector3D<T>& vec) const return x * vec.x + y * vec.y + z * vec.z; ; ; int main() Vector3D<int> a(10, 10, 10); Vector3D<double> b(2.001, 3, 4); std::cout << "inner product = << a.innerproduct(b) << " n"; return 0; innerproduct() の引数は Vector3D<T> 型 変数 aの型はvector3d<int> Vector3D<int> のメンバ関数 innerproduct() の引数はVector3D<int> Vector3D<double> は引数として受け取れない 18

対策 メンバ関数 innerproduct() をテンプレート関数化 3 次元ベクトルクラス : 利用側 : class Vector3D template<typename T2> T innerproduct(const Vector3D<T2>& vec) const return (T)(x * vec.x + y * vec.y + z * vec.z); ; ; int main() Vector3D<int> a(10, 10, 10); Vector3D<double> b(2.001, 3, 4); std::cout << "inner product = << a.innerproduct(b) << " n"; return 0; 型 T にキャスト自動型変換 ( たとえば double から int) のコンパイル時警告発生を防ぐため Inner product = 90 19

対策 型違い (= 数値精度の違い ) わかりづらいので要注意 3 次元ベクトルクラス : class Vector3D template<typename T2> T innerproduct(const Vector3D<T2>& vec) const return (T)(x * vec.x + y * vec.y + z * vec.z); ; ; 利用側 : int main() Vector3D<int> a(10, 10, 10); Vector3D<double> b(2.001, 3, 4); std::cout << "inner product1 = << a.innerproduct(b) << " n"; std::cout << "inner product2 = << b.innerproduct(a) << " n"; return 0; Inner product1 = 90 Inner product2 = 90.01 20

ビルド時の注意 ヘッダファイルに定義記述が必要 Vector3D.h( 宣言を記述 ) Vector3D.cpp( 定義を記述 ) class Vector3D public: T x, y, z; #include <Vector3D.h> Vector3D<T>::Vector3D<T>(T X, T Y, T Z) x = X, y = Y, z = Z; Vector3D(T X, T Y, T Z); ~Vector3D(); template<typename T2> T innerproduct(const Vector3D<T2>& vec) const; ; Vector3D<T>:: ~Vector3D() ; T Vector3D<T>:: innerproduct(const Vector3D<T>& vec) const return x * vec.x + y * vec.y + z * vec.z; 利用側コードのコンパイル時に コンパイラが定義を見つけられずビルドエラー 21

ビルド時の注意 利用側コードコンパイル時にテンプレート定義たどれないため 関数の定義 Vector3D.h インクルード Vector3D.cpp T Vector3D<T>:: innerproduct(const Vector3D<T>& vec) const return x * vec.x + y * vec.y + z * vec.z; 宣言のみ定義なし インクルード main.cpp 関数の利用側 int main() Vector3D<int> a(10, 10, 10); Vector3D<double> b(2.001, 3, 4); std::cout << "inner product = << a.innerproduct(b) << " n"; return 0; 22

ビルド時の注意 解決策 定義も全てヘッダファイルに記載 定義のみを記述したヘッダファイルをインクルード Vector3D.h インクルード Vector3D_Impl.h class Vector3D public: T x, y, z; Vector3D(T X, T Y, T Z); ~Vector3D(); 宣言のみ定義なし 宣言なし定義のみ template<typename T2> T innerproduct(const Vector3D<T2>& vec) const; ; #include Vector3D_Impl.h インクルード main.cpp 23

Agenda テンプレート概要 テンプレート関数 テンプレートクラス OpenFoamのVector 24

OpenFoam の Vector ベクトルはテンプレートクラス VectorSpace Form, Cmpt, ncmpt ベクトル要素演算用構造体に近い template<class Form, class Cmpt, int ncmpt> class VectorSpace Cmpt v_[ncmpt]; ; Cmpt 型 (int / float / double) の ncmpt 次元ベクトル (Form は Cmpt と基本的に一致 CRTP イディオム ) Vector Cmpt 3 次元ベクトル template<class Cmpt> class Vector : public VectorSpace<Vector<Cmpt>, Cmpt, 3> ; 3 次元ベクトルとして定義ただし型 (int / float/ double など ) は利用側で決定 25

OpenFoam の Vector 演算 ベクトル演算はテンプレート関数 ベクトル同士の足し算 ( 演算子のオーバーロード ) template<class Form, class Cmpt, int ncmpt> inline Form operator+ ( const VectorSpace<Form, Cmpt, ncmpt>& vs1, const VectorSpace<Form, Cmpt, ncmpt>& vs2 ) Form v; VectorSpaceOps<nCmpt, 0>::op(v, vs1, vs2, plusop<cmpt>()); 足し算の実装は VectorSpaceOps<nCmpt, 0> plusop<cmpt> Form は VectorSpace<Foam, Cmpt, ncmpt> と一致する必要あり 26

OpenFoam の Vector 演算 VectorSpaceOps クラスは抽象化したベクトル演算用 VectorSpaceOps クラスの定義 : template<int N, int I> class VectorSpaceOps public: static const int endloop = (l < N-1)? 1 : 0; template<class V, class V1, class Op> static inline void op(v& vs, const V1 vs1, const V1& vs2, Op o) vs.v_[l] = o(vs1.v_[l], vs2.v_[l]); VectorSpaceOps<endLoop*N, endloop*(l+1)>::op(vs, vs1, vs2, o); ; メンバ関数 opはn 次元のベクトルのI 番目の要素の演算演算終了後 I+1 番目の演算を実行するVecstorSpaceOpsのメンバ関数 opを呼び出し 27 ( 再帰処理 ( のような ) プログラミング )

OpenFoam の Vector 演算 各演算はテンプレートクラスのファンクタ 足し算の実行呼び出しは VectorSpaceOps<nCmpt, 0>::op(v, vs1, vs2, plusop<cmpt>()); template<int N, int I> class VectorSpaceOps static inline void op(v& vs, const V1 vs1, const V1& vs2, Op o) vs.v_[l] = o(vs1.v_[l], vs2.v_[l]); ; template<class T> VectorSpaceOps<endLoop*N, endloop*(l+1)>::op(vs, vs1, vs2, o); class plusop Public: T operator()(const T& x, const T& y) const return x + y; ; コンパイル時に自動生成されるコード 28

OpenFoam の Vector まとめ Vector 使うのは簡単だが 内部実装はややこしい Form, Cmpt, ncmpt VectorSpace 利用 ベクトル実装 演算用実装群 N, I VectorSpaceOps plusops Cmpt Vector Cmpt 演算時の演算対象要素の制御 要素の演算実装 3 次元ベクトル 利用 プログラマ 29