1週目:2次元Taylor-Green渦の数値生成
2週目:中心差分を用いた渦度場の算出
1週目と2週目で,渦度場とベクトル場を重畳した図を描画してください.右の動画のように減衰項を付けると時間発展の場も描画可能です.Gnuplotはカウントアップ描画が簡単なので良いです.
読み込みデータ(xy格子座標(x, y),渦度(ωz),速度(u, v):2dvec_vortex000001.dat
下のデータのように1軸方向の区切り(作例の場合なら,一番ひだりのx軸が増えるごと,31×31のデータなので31行目を1塊とします.)で空白行が必要なるので注意して下さい.
0 0 -2.000000 0.000000 -0.000000
0 1 -1.956295 0.207912 -0.000000
0 2 -1.827091 0.406737 -0.000000
0 3 -1.618034 0.587785 -0.000000
0 4 -1.338261 0.743145 -0.000000
0 5 -1.000000 0.866025 -0.000000
0 6 -0.618034 0.951057 -0.000000
0 7 -0.209057 0.994522 -0.000000
0 8 0.209057 0.994522 0.000000
0 9 0.618034 0.951057 0.000000
0 10 1.000000 0.866025 0.000000
0 11 1.338261 0.743145 0.000000
0 12 1.618034 0.587785 0.000000
0 13 1.827091 0.406737 0.000000
0 14 1.956295 0.207912 0.000000
0 15 2.000000 0.000000 0.000000
0 16 1.956295 -0.207912 0.000000
0 17 1.827091 -0.406737 0.000000
0 18 1.618034 -0.587785 0.000000
0 19 1.338261 -0.743145 0.000000
0 20 1.000000 -0.866025 0.000000
0 21 0.618034 -0.951057 0.000000
0 22 0.209057 -0.994522 0.000000
0 23 -0.209057 -0.994522 -0.000000
0 24 -0.618034 -0.951057 -0.000000
0 25 -1.000000 -0.866025 -0.000000
0 26 -1.338261 -0.743145 -0.000000
0 27 -1.618034 -0.587785 -0.000000
0 28 -1.827091 -0.406737 -0.000000
0 29 -1.956295 -0.207912 -0.000000
0 30 -2.000000 -0.000000 -0.000000
1 0 -1.956295 0.000000 -0.207912
1 1 -1.913545 0.203368 -0.203368
1 2 -1.787165 0.397848 -0.189937
............
プログラム(2d_vector_with_contour.cpp)の概要
プログラムと同じディレクトリに01_plot_vec_vorexという名前のフォルダを作成して,2dvec_vortex000001.datを保存します.
#define GNUPLOT_PATHでPCにあるgnuplotをプログラムから動かせるようにパスを通します.
direct.hをつかって保存するフォルダ(02_splot_2dvec_vortex_map)を作成します.
splotは本来xyz成分必要なので,($1*0.0)を使ってz成分を空読みしています.
/******************************************************************************
AUTHER: Yohsuke Tanaka
DATE: 2018.08.01
******************************************************************************/
#include
#include
#ifdef __linux
#include
#endif
#ifdef _WIN32
#include
#endif
const char* xxlabel = "{/Times-New-Roman:Italic=20 x} [pixel]";
const char* yylabel = "{/Times-New-Roman:Italic=20 y} [pixel]";
const char* cb_label = "{/Symbol:Italic=20 w}_{/Times-New-Roman:Italic=20 z} [sec]";///color bar range min
const double v_r = 1.0;///magnified ratio for vector length
const int x_min = 0;///x range min
const int x_max = 30;///x range max
const int y_min = 0;///y range min
const int y_max = 30;///y range max
const int cb_min = -2;///color bar range min
const int cb_max = 2;///color bar range max
const char* read_file_dir = "01_plot_vec_vorex";
const char* read_file_header = "2dvec_vortex";
const char* write_file_dir = "02_splot_2dvec_vortex_map";
const char* write_file_header = "2dvec_vortex_map";
//Graph parameters for GNU
#ifdef _WIN32
#define GNUPLOT_PATH "C:/PROGRA~2/gnuplot/bin/gnuplot.exe" // gnuplot.exe in your PC
#endif
char read_file[100];
void graph_GNU();//png & eps
FILE *gp; //gnuplot
FILE *infile;
/********************************* MAIN *********************************/
main(){
#ifdef __linux
mode_t mode= S_IRWXU | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH;
mkdir(write_file_dir,mode);
#endif
#ifdef _WIN32
_mkdir(write_file_dir);//png directry
#endif
int i =0; int UP =0;
while(UP==0){
i++;
sprintf(read_file,"%s//%s%06d.dat",read_file_dir,read_file_header,i);
printf("%s//%s%06d.dat\n",read_file_dir,read_file_header,i);
infile=fopen(read_file,"rb");
fclose(infile);
if(infile==NULL)
{
printf("break!");
break;
}
#ifdef __linux
if ((gp = popen("gnuplot", "w")) == NULL) {
printf("gnuplot is not here!\n");
exit(0);
}
#endif
#ifdef _WIN32
if ((gp = _popen(GNUPLOT_PATH, "w")) == NULL) {
printf("gnuplot is not here!\n");
exit(0);
}
#endif
//PNG image
fprintf(gp,"set terminal pngcairo enhanced font 'Times New Roman,15' \n");
fprintf(gp,"set output '%s//%s%06d.png'\n",write_file_dir,write_file_header,i);
fprintf(gp,"set multiplot\n");// ,
fprintf(gp,"unset key\n");// ,
fprintf(gp,"set size ratio -1\n");// ,
fprintf(gp,"set lmargin screen 0.15\n");// ,
fprintf(gp,"set rmargin screen 0.85\n");// ,
fprintf(gp,"set tmargin screen 0.85\n");// ,
fprintf(gp,"set bmargin screen 0.15\n");// ,
fprintf(gp,"set xrange [%d:%d]\n",x_min,x_max);// ,
fprintf(gp,"set xlabel '%s'offset 0.0,0.5\n",xxlabel);// ,
fprintf(gp,"set yrange [%d:%d]\n",y_min,y_max);// ,
fprintf(gp,"set ylabel '%s'offset 0.5,0.0\n",yylabel);// ,
fprintf(gp,"set cblabel '%s'offset 0.0,0.0\n",cb_label);
fprintf(gp,"set cbrange['%d':'%d']\n",cb_min,cb_max);
fprintf(gp,"set colorbox vertical user origin 0.8, 0.2 size 0.025,0.6\n");
fprintf(gp,"set palette rgbformulae 22,13,-31\n");
fprintf(gp,"set pm3d map\n");// ,
fprintf(gp,"splot '%s//%s%06d.dat' using 2:1:3 with pm3d, '%s//%s%06d.dat' using 2:1:($1*0.0):(%lf*$5):(%lf*$4):($1*0.0) with vectors head filled lt 2 lc 'black' \n",read_file_dir,read_file_header,i,read_file_dir,read_file_header,i,v_r,v_r);
fflush(gp); //Clean up Data
fprintf(gp, "exit\n"); // Quit gnuplot
#ifdef __linux
pclose(gp);
#endif
#ifdef _WIN32
_pclose(gp);
#endif
}
return(0);
}
1週目:画像の空間フィルタリング処理
2週目:Taylor-Green渦のPIV用粒子画像
読み込みデータから下図のような粒度分布をヒストグラムでPNG画像作成します.ヒストグラムと積算分布のセット表示が一般的です.ヒストグラムを半透明にしておいたので,時間のある方は積算分布も追加してください.
読み込みデータ(dp_distribution_histgram.dat)
/histogram.png)
プログラム(dp_histgram.cpp)の概要
#define GNUPLOT_PATHでPCにあるgnuplotをプログラムから動かせるようにパスを通します.
Windows(direct.h)とLinux(sys/stat.h)で両用できるようにしています.
/******************************************************************************
PROGRAM NAME:Histogram by GNU plot
AUTHER: Yohsuke Tanaka
DATE: 2022.01.17
******************************************************************************/
#include
#include
#ifdef __linux
#include
#endif
#ifdef _WIN32
#include
#endif
//out-input file name
const char* write_file01 = "dp_distribution_histgram.dat"; //Input file
const char* write_file_dir = "00_graph"; //Output file directory
const char* output_graph = "histgram"; //Output file name
const char* xxlabel = "Diameter [{/Symbol m}m]";
const double min_x = 0.0;
const double max_x = 130.0;
const char* yylabel = "Frequency";
const double min_y = 0;
const double max_y = 100.0;
//Graph parameters for GNU
#ifdef _WIN32
#define GNUPLOT_PATH "C:/PROGRA~1/gnuplot/bin/gnuplot.exe" // gnuplot.exe in your
//PROGRA~1 as Program Files, PROGRA~2 as Program Files(x86)
#endif
FILE *gp;
/********************************* MAIN *********************************/
main(){
#ifdef __linux
mode_t mode= S_IRWXU | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH;
mkdir(write_file_dir,mode);
#endif
#ifdef _WIN32
_mkdir(write_file_dir);
#endif
#ifdef __linux
if ((gp = popen("gnuplot", "w")) == NULL) {
printf("gnuplot is not here!\n");
exit(0);
}
#endif
#ifdef _WIN32
if ((gp = _popen(GNUPLOT_PATH, "w")) == NULL) {
printf("gnuplot is not here!\n");
exit(0);
}
#endif
fprintf(gp,"set terminal pngcairo color size 1280, 960 font 'Times-New-Roman,30' \n");
fprintf(gp,"set output '%s//%s.png'\n",write_file_dir,output_graph);
fprintf(gp, "set border lw 3\n");
fprintf(gp, "set xrange [%f:%f]\n",min_x,max_x);
fprintf(gp, "set xlabel '%s' offset 0.0,0.5\n",xxlabel);
fprintf(gp, "set yrange [%f:%f]\n",min_y,max_y);
fprintf(gp, "set ylabel '%s' offset 2.0,0.0\n",yylabel);
fprintf(gp,"set style fill transparent solid 0.8\n");
fprintf(gp,"plot '%s' using 1:2 with boxes lc rgb 'black' notitle\n",write_file01);
fflush(gp); //Clean up Data
fprintf(gp, "exit\n"); // Quit gnuplot
#ifdef __linux
pclose(gp);
#endif
#ifdef _WIN32
_pclose(gp);
#endif
return(0);
}
1週目:2次元Taylor-Green渦のPIV計測
2週目:実験で得られた粒子画像のPIV計測
演習のデータに合わせて下図のように表示してみてください.レポートに貼付する図の瞬時場と月末報告会に向けて動画も作って下さい.
プログラム(2d_vector_vortex_cylinder.cpp)の概要
プログラムと同じディレクトリに02_vecというフォルダを作成して,読み込みデータ(av-vec_v0001.dat)を保存.
03_splot_vec_contour_mapに図が出力されます.入力データが連番だと,ここに対応する図が連番で出力されます.
円柱マップ(cylinder.dat)もプログラムと同じディレクトリに置いて下さい.
1つめのsplotで渦度とベクトルを描画した図の上に円柱のマップを重ねて描画しています.2つめのsplotで背景は描画せずに円柱のみを描画することで下にある渦度とベクトルが見えます.($3 == 0 ? NaN : $3)のところで,$3が円柱と背景の値です.0が背景で1が円柱にしています.0でなければ表示しない(NaN)という設定になります.本来はグラフのデータ欠損表現で使います.
円柱は実験画像から二値化などして作成して下さい.時間ごとに変動する物体も応用が可能です.回転する円柱なら,円のフチ辺りに小さい白抜き円があるとわかりやすいです.
/******************************************************************************
AUTHER: Yohsuke Tanaka
DATE: 2018.07.27
******************************************************************************/
#include
#include
#ifdef __linux
#include
#endif
#ifdef _WIN32
#include
#endif
const char* xxlabel = "x [pixel]";///color bar range min
const char* yylabel = "y [pixel]";///color bar range min
const int x_min = 0;///color bar range min
const int x_max = 1280;///color bar range min
const int y_min = 0;///color bar range min
const int y_max = 1024;///color bar range min
const double v_r = 6.0;///magnified ratio for vector length
const char* cb_label = "|U| [pixel]";///color bar range min
const int cb_min = 0;///color bar range min
const int cb_max = 8;///color bar range min
const char* read_file_object = "cylinder.dat";
const char* read_file_dir = "02_vec";
const char* read_file_header = "av-vec_v";
const char* write_file_dir = "03_splot_vec_contour_map";
const char* write_file_header = "splot_vec_contour_map";
//Graph parameters for GNU
#ifdef _WIN32
#define GNUPLOT_PATH "C:/PROGRA~2/gnuplot/bin/gnuplot.exe" // gnuplot.exe in your PC
#endif
char read_file[100];
void graph_GNU();//png & eps
FILE *gp; //gnuplot
FILE *infile;
/********************************* MAIN *********************************/
main(){
#ifdef __linux
mode_t mode= S_IRWXU | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH;
mkdir(write_file_dir,mode);
#endif
#ifdef _WIN32
_mkdir(write_file_dir);//png directry
#endif
int i =0; int UP =0;
while(UP==0){
i++;
sprintf(read_file,"%s//%s%04d.dat",read_file_dir,read_file_header,i);
printf("%s//%s%04d.dat\n",read_file_dir,read_file_header,i);
infile=fopen(read_file,"rb");
fclose(infile);
if(infile==NULL)
{
printf("break!");
break;
}
#ifdef __linux
if ((gp = popen("gnuplot", "w")) == NULL) {
printf("gnuplot is not here!\n");
exit(0);
}
#endif
#ifdef _WIN32
if ((gp = _popen(GNUPLOT_PATH, "w")) == NULL) {
printf("gnuplot is not here!\n");
exit(0);
}
#endif
//PNG image
fprintf(gp,"set terminal pngcairo enhanced\n");
fprintf(gp,"set output '%s//%s%04d.png'\n",write_file_dir,write_file_header,i);
fprintf(gp,"set multiplot\n");// ,
fprintf(gp,"unset key\n");// ,
fprintf(gp,"set lmargin screen 0.15\n");// ,
fprintf(gp,"set rmargin screen 0.85\n");// ,
fprintf(gp,"set tmargin screen 0.85\n");// ,
fprintf(gp,"set bmargin screen 0.15\n");// ,
fprintf(gp,"set xrange [%d:%d]\n",x_min,x_max);// ,
fprintf(gp,"set xlabel '%s'offset 0.0,0.5\n",xxlabel);// ,
fprintf(gp,"set yrange [%d:%d]\n",y_min,y_max);// ,
fprintf(gp,"set ylabel '%s'offset 1.0,0.0\n",yylabel);// ,
fprintf(gp,"set cblabel '%s'offset 0.0,0.0\n",cb_label);
fprintf(gp,"set cbrange['%d':'%d']\n",cb_min,cb_max);
fprintf(gp,"set colorbox vertical user origin 0.895, 0.2 size 0.025,0.6\n");
fprintf(gp,"set palette rgbformulae 22,13,-31\n");
fprintf(gp,"set pm3d map\n");// ,
fprintf(gp,"splot '%s//%s%04d.dat' using 2:1:3 with pm3d, '%s//%s%04d.dat' using 2:1:($1*0.0):(%lf*$5):(%lf*$4)::($1*0.0) with vectors head filled lt 2 lc 'black' \n",read_file_dir,read_file_header,i,read_file_dir,read_file_header,i,v_r,v_r);
fprintf(gp,"set palette rgbformulae 0,0,0\n");
fprintf(gp,"unset colorbox\n");
fprintf(gp,"unset border\n");
fprintf(gp,"splot '%s' using 2:1:($3 == 0 ? NaN : $3) with pm3d\n",read_file_object);
fprintf(gp,"unset multiplot\n");// ,
fflush(gp); //Clean up Data
fprintf(gp, "exit\n"); // Quit gnuplot
#ifdef __linux
pclose(gp);
#endif
#ifdef _WIN32
_pclose(gp);
#endif
}
return(0);
}
下図の作例は,PIV計測で得られたアクリル模型の家の周囲と内部のベクトル場を模型の絵に重ねて表示しています.ベクトル場だけでは分かりませんでしたが,重ねることで,思った以上に屋根の前縁で剥離している様子や,模型の1F入口から流入した流れが,2F右上のスリットから流出する様子を容易に絵と対応することで理解出来ます.データはオープンキャンパスのデモで撮影しました.このときの描画はC++の自作ソフトでした.ベクトル作図の際に,Bresenhamのアルゴリズムは勉強になりましたが,ベクトル(線の長さ,頭,長さetc)から作り込むので面倒です.gnuplotを呼び出した方が簡単です.
読み込みデータ(av-vec0001.dat)
/lowest-intensity.png)
プログラム(2d_vector_back_image.cpp)の概要
プログラムと同じディレクトリに02_vecというフォルダを作成して,av-vec0001.datを保存.
03_plot_vecに図が出力されます.入力データが連番だと,ここに対応する図が出力されます.
背景のpng画像(lowest-intensity.png)もプログラムと同じディレクトリに置いて下さい.
plot '%s' binary filetype=auto with rgbimage,'%s' with vector linecolor rgbcolor 'white'はmultiplotを使ってもかけます.ベクトルの大きさに合わせて色を付けたいのですが,スケールが上手く合わなかったり,グラデーションが出なかったりです.上手くいったら教えてください.(2015.12.28)下記のプログラムで可能です(2018.08.02).
/******************************************************************************
AUTHER: Yohsuke Tanaka
DATE: 2018.08.02
******************************************************************************/
#include
#include
#ifdef __linux
#include
#endif
#ifdef _WIN32
#include
#endif
const char* xxlabel = "x [pixel]";///color bar range min
const char* yylabel = "y [pixel]";///color bar range min
const int x_min = 0;///color bar range min
const int x_max = 1280;///color bar range min
const int y_min = 0;///color bar range min
const int y_max = 1024;///color bar range min
const double v_r = 5.0;///magnified ratio for vector length
const char* cb_label = "|U| [pixel/step]";///color bar range min
const int cb_min = 0;///color bar range min
const int cb_max = 15;///color bar range min
const char* read_file_dir = "02_vec";
const char* read_file_header = "av-vec";
const char* write_file_dir = "03_plot_vec";
const char* write_file_header = "plot";
const char* read_back_img = "lowest-intensity.png";
//Graph parameters for GNU
#ifdef _WIN32
#define GNUPLOT_PATH "C:/PROGRA~2/gnuplot/bin/gnuplot.exe" // gnuplot.exe in your PC
#endif
char read_file[100];
void graph_GNU();//png & eps
FILE *gp; //gnuplot
FILE *infile;
/********************************* MAIN *********************************/
main(){
#ifdef __linux
mode_t mode= S_IRWXU | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH;
mkdir(write_file_dir,mode);
#endif
#ifdef _WIN32
_mkdir(write_file_dir);//png directry
#endif
int i =0; int UP =0;
while(UP==0){
i++;
sprintf(read_file,"%s//%s%04d.dat",read_file_dir,read_file_header,i);
printf("%s//%s%04d.dat\n",read_file_dir,read_file_header,i);
infile=fopen(read_file,"rb");
fclose(infile);
if(infile==NULL)
{
printf("break!");
break;
}
#ifdef __linux
if ((gp = popen("gnuplot", "w")) == NULL) {
printf("gnuplot is not here!\n");
exit(0);
}
#endif
#ifdef _WIN32
if ((gp = _popen(GNUPLOT_PATH, "w")) == NULL) {
printf("gnuplot is not here!\n");
exit(0);
}
#endif
//PNG image
fprintf(gp,"set terminal pngcairo enhanced\n");
fprintf(gp,"set output '%s//%s%04d.png'\n",write_file_dir,write_file_header,i);
fprintf(gp,"set multiplot\n");// ,
fprintf(gp,"unset key\n");// ,
fprintf(gp,"set lmargin screen 0.125\n");// ,
fprintf(gp,"set rmargin screen 0.875\n");// ,
fprintf(gp,"set tmargin screen 0.875\n");// ,
fprintf(gp,"set bmargin screen 0.125\n");// ,
fprintf(gp,"set xrange [%d:%d]\n",x_min,x_max);// ,
fprintf(gp,"set xlabel '%s'offset 0.0,0.5\n",xxlabel);// ,
fprintf(gp,"set yrange [%d:%d]\n",y_min,y_max);// ,
fprintf(gp,"set ylabel '%s'offset 2.0,0.0\n",yylabel);// ,
fprintf(gp,"plot '%s' binary filetype=png with rgbimage \n",read_back_img);
fprintf(gp,"set cblabel '%s'offset 0.0,0.0\n",cb_label);
fprintf(gp,"set cbrange['%d':'%d']\n",cb_min,cb_max);
fprintf(gp,"set colorbox vertical user origin 0.895, 0.2 size 0.025,0.6\n");
fprintf(gp,"set palette rgbformulae 22,13,-31\n");
fprintf(gp,"plot '%s//%s%04d.dat' u 2:1:(%lf*$5):(%lf*$4):(sqrt($4*$4+$5*$5)) with vectors head filled lt 2 lc palette \n",read_file_dir,read_file_header,i,v_r,v_r);
fprintf(gp,"unset multiplot\n");// ,
fflush(gp); //Clean up Data
fprintf(gp, "exit\n"); // Quit gnuplot
#ifdef __linux
pclose(gp);
#endif
#ifdef _WIN32
_pclose(gp);
#endif
}
return(0);
}
1週目:マイクロフォン測定データのスペクトル計算
2週目: バンドパスフィルタ
今回の離散Fourier変換は計測研での全ての研究テーマで必須になるので必ず使いこなしてください.流体計測では円柱後方の速度ベクトル変動から渦の放出周波数を求めますし,光計測では2次元Fourier変換がないとホログラフィックパターンの記録・再生が出来ません.また音響計測ではどの周波数の音が大きいか小さいかを今回のようにパワースペクトルで確認します.
/spectrum.png)
読み込みデータ(spectrum.dat)
プログラム(power_spectrum.cpp)の概要
課題のプログラムではdatファイル読み込みではなく,配列から直接プロットするよう変更願います.
X軸,Y軸の範囲も自動で決めると簡単です.
/******************************************************************************
PROGRAM NAME:power_spectrum.cpp
AUTHER: Yohsuke Tanaka
DATE: 2016.1.17
******************************************************************************/
#include
#include
#include
#include
const char* read_spectrum_data = "spectrum.dat"; //Intput file
const char* write_spectrum_data = "png\\spectrum.png"; //Output file
const int x_max =50;
const int x_min =0;
const int y_max =3;
const int y_min =0;
//Graph parameters for GNU
#define GNUPLOT_PATH "C:/PROGRA~2/gnuplot/bin/gnuplot.exe" // gnuplot.exe in your PC
FILE *gp; //gnuplot
/********************************* MAIN *********************************/
main(){
_mkdir("png");//png directry
if ((gp = _popen(GNUPLOT_PATH, "w")) == NULL)
{printf("gnuplot is not detected!\n");exit(0);}
fprintf(gp,"set terminal pngcairo enhanced \n");
fprintf(gp,"set output '%s'\n",write_spectrum_data);
fprintf(gp, "unset key\n");
fprintf(gp, "set xlabel 'f [Hz]'\n");
fprintf(gp, "set ylabel 'I^2 [V^2]'\n");
fprintf(gp, "set xrange [%d:%d]\n",x_min,x_max);
fprintf(gp, "set yrange [%d:%d]\n",y_min,y_max);
fprintf(gp, "plot '%s' with lines lc -1 lw 2\n",read_spectrum_data);
fflush(gp); //Clean up Data
fprintf(gp, "exit\n"); // Quit gnuplot
_pclose(gp);
return(0);
}
1週目:1次元高速Fourier変換の実装
2週目:窓関数によるスペクトル信号の改善
1週目:2次元高速Fourier変換による2次元スペクトル分布の作成
2週目:顔画像の2次元フィルタリング処理
1週目:ホログラフィックパターンの作成
2週目:ホログラフィックパターンの再生
© Measurement System Laboratory, Kyoto Institute of Technology.

|