119int main(
int argc,
char *argv[])
126 const char *msh_path =
"";
127 const char *msh_filename =
"naca-cmesh";
128 args.
AddOption(&msh_path,
"-p",
"--mesh-path",
129 "Path in which the generated mesh is saved.");
130 args.
AddOption(&msh_filename,
"-m",
"--mesh-file",
131 "File where the generated mesh is written to.");
135 real_t foil_thickness = 0.12;
137 args.
AddOption(&foil_length,
"-l",
"--foil-length",
138 "Length of the used foil in the mesh. ");
139 args.
AddOption(&foil_thickness,
"-t",
"--foil-thickness",
140 "Thickness of the foil in the mesh as a fraction of length.");
141 args.
AddOption(&aoa,
"-aoa",
"--angle-of-attack",
142 "Angle of attack of the foil. ");
145 real_t boundary_dist = 3.0;
147 real_t tip_fraction = 0.05;
149 args.
AddOption(&boundary_dist,
"-b",
"--boundary-distance",
150 "Radius of the c-mesh, distance between foil and boundary");
151 args.
AddOption(&wake_length,
"-w",
"--wake_length",
152 "Length of the mesh after the foil");
153 args.
AddOption(&tip_fraction,
"-tf",
"--tip-fraction",
154 "Fraction of the length of foil that will be in tip patch");
155 args.
AddOption(&flair,
"-f",
"--flair-angle",
156 "Flair angle of top and bottom boundary to enforce inflow. If\
157 left at default, the flair angle is determined automatically\
158 to create an elegant mesh.");
164 args.
AddOption(&ncp_tip,
"-ntip",
"--ncp-tip",
165 "Number of control points used over the tip of the foil.");
166 args.
AddOption(&ncp_tail,
"-ntail",
"--ncp-tail",
167 "Number of control points used over the tail of the foil.");
168 args.
AddOption(&ncp_wake,
"-nwake",
"--ncp-wake",
169 "Number of control points over the wake behind the foil.");
170 args.
AddOption(&ncp_bnd,
"-nbnd",
"--ncp-circ",
171 "Number of control points between the foil and boundary.");
177 args.
AddOption(&str_tip,
"-stip",
"--str-tip",
178 "Stretch of the knot vector of the tip.");
179 args.
AddOption(&str_tail,
"-stail",
"--str-tail",
180 "Stretch of the knot vector of the tail.");
181 args.
AddOption(&str_wake,
"-sw",
"--str-wake",
182 "Stretch of the knot vector of the wake.");
183 args.
AddOption(&str_bnd,
"-sbnd",
"--str-circ",
184 "Stretch of the knot vector of the circle.");
186 bool visualization =
true;
188 args.
AddOption(&visualization,
"-vis",
"--visualization",
"-no-vis",
189 "--no-visualization",
190 "Enable or disable GLVis visualization.");
191 args.
AddOption(&visit,
"-visit",
"--visit",
"-no-visit",
"--no-visit",
192 "Enable/disable VisIt visualization in output Naca_cmesh.");
204 const real_t tail_fraction = 1.0 - tip_fraction;
207 constexpr real_t deg2rad = M_PI/180;
211 unique_ptr<KnotVector> kv0 =
TanhKnotVector(order, ncp_wake, str_wake);
213 unique_ptr<KnotVector> kv4 (
new KnotVector(*kv0));
220 unique_ptr<KnotVector> kvr =
TanhKnotVector(order, ncp_bnd, str_bnd);
233 const NACA4 foil_section(foil_thickness, foil_length);
239 flair = atan(foil_section.dydx(tip_fraction*foil_length));
250 NURBSPatch patch0(kv_o1.get(), kv_o1.get(), 3);
252 for (
int i = 0; i < 2; i++)
253 for (
int j = 0; j < 2; j++)
259 patch0(0,0,0) = foil_length + wake_length;
262 patch0(1,0,0) = foil_length;
265 patch0(0,1,0) = foil_length + wake_length;
266 patch0(0,1,1) = -
FlairBoundDist(flair, boundary_dist, patch0(0,1,0));
268 patch0(1,1,0) = foil_length;
269 patch0(1,1,1) = -
FlairBoundDist(flair, boundary_dist, patch0(1,1,0));
279 NURBSPatch patch1(kv_o1.get(), kv_o1.get(), 3);
281 for (
int i = 0; i < 2; i++)
282 for (
int j = 0; j < 2; j++)
288 patch1(0,0,0) = foil_length;
291 patch1(1,0,0) = tip_fraction*foil_length;
292 patch1(1,0,1) = -foil_section.y(patch1(1,0,0));
294 patch1(0,1,0) = foil_length;
295 patch1(0,1,1) = -
FlairBoundDist(flair, boundary_dist, patch1(0,1,0));
297 patch1(1,1,0) = -boundary_dist*sin(flair) + tip_fraction*foil_length;
298 patch1(1,1,1) = -boundary_dist*cos(flair);
304 int ncp = kv1->GetNCP();
308 kv1->FindMaxima(i_args,xi_args, u_args);
309 for (
int i = 0; i < ncp; i++)
311 (*xyf[0])[i] = foil_length*(1.0 - tail_fraction*u_args[i]);
312 (*xyf[1])[i] = -foil_section.y((*xyf[0])[i]);
315 kv1->FindInterpolant(xyf);
316 for (
int i = 0; i < ncp; i++)
318 patch1(i,0,0) = (*xyf[0])[i];
319 patch1(i,0,1) = (*xyf[1])[i];
327 NURBSPatch patch2(kv_o2.get(), kv_o1.get(), 3);
330 for (
int i = 0; i < 3; i++)
331 for (
int j = 0; j < 2; j++)
337 patch2(2,0,0) = tip_fraction*foil_length;
338 patch2(2,0,1) = foil_section.y(patch2(2,0,0));
342 patch2(1,0,2) = cos((180*deg2rad-2*flair)/2);
344 patch2(0,0,0) = tip_fraction*foil_length;
345 patch2(0,0,1) = -foil_section.y(patch2(0,0,0));
348 patch2(2,1,0) = -boundary_dist*cos(90*deg2rad-flair)
349 + tip_fraction*foil_length;
350 patch2(2,1,1) = boundary_dist*sin(90*deg2rad-flair);
352 patch2(1,1,0) = -boundary_dist/sin(flair);
354 patch2(1,1,2) = cos((180*deg2rad-2*flair)/2);
356 patch2(0,1,0) = -boundary_dist*cos(90*deg2rad-flair)
357 + tip_fraction*foil_length;
358 patch2(0,1,1) = -boundary_dist*sin(90*deg2rad-flair);
361 patch2(1,0,0) *= patch2(1,0,2);
362 patch2(1,0,1) *= patch2(1,0,2);
363 patch2(1,1,0) *= patch2(1,1,2);
364 patch2(1,1,1) *= patch2(1,1,2);
371 int ncp = kv2->GetNCP();
374 GetTipXY(foil_section, *kv2, tip_fraction, xyf);
376 kv2->FindInterpolant(xyf);
377 for (
int i = 0; i < ncp; i++)
381 patch2(i,0,0) = (*xyf[0])[i]*patch2(i,0,2);
382 patch2(i,0,1) = (*xyf[1])[i]*patch2(i,0,2);
391 NURBSPatch patch3(kv_o1.get(), kv_o1.get(), 3);
393 for (
int i = 0; i < 2; i++)
394 for (
int j = 0; j < 2; j++)
400 patch3(0,0,0) = tip_fraction*foil_length;
401 patch3(0,0,1) = foil_section.y(patch3(0,0,0));
403 patch3(1,0,0) = foil_length;
406 patch3(0,1,0) = -boundary_dist*sin(flair) + tip_fraction*foil_length;
407 patch3(0,1,1) = boundary_dist*cos(flair);
409 patch3(1,1,0) = foil_length;
410 patch3(1,1,1) =
FlairBoundDist(flair, boundary_dist, patch3(1,1,0));
416 int ncp = kv3->GetNCP();
420 kv3->FindMaxima(i_args,xi_args, u_args);
421 for (
int i = 0; i < ncp; i++)
423 (*xyf[0])[i] = foil_length*(tip_fraction + tail_fraction*u_args[i]);
424 (*xyf[1])[i] = foil_section.y((*xyf[0])[i]);
427 kv3->FindInterpolant(xyf);
428 for (
int i = 0; i < ncp; i++)
430 patch3(i,0,0) = (*xyf[0])[i];
431 patch3(i,0,1) = (*xyf[1])[i];
439 NURBSPatch patch4(kv_o1.get(), kv_o1.get(), 3);
441 for (
int i = 0; i < 2; i++)
442 for (
int j = 0; j < 2; j++)
448 patch4(0,0,0) = foil_length;
451 patch4(1,0,0) = foil_length+ wake_length;
454 patch4(0,1,0) = foil_length;
455 patch4(0,1,1) =
FlairBoundDist(flair, boundary_dist, patch4(0,1,0));
457 patch4(1,1,0) = foil_length+ wake_length;
458 patch4(1,1,1) =
FlairBoundDist(flair, boundary_dist, patch4(1,1,0));
478 mesh_file.append(msh_path);
479 mesh_file.append(msh_filename);
480 mesh_file.append(
".mesh");
481 ofstream output(mesh_file.c_str());
484 output<<
"MFEM NURBS mesh v1.0"<<endl;
485 output<< endl <<
"# " << mdim
486 <<
"D C-mesh around a symmetric NACA foil section"
488 output<<
"dimension"<<endl;
489 output<< mdim <<endl;
493 output <<
"elements"<<endl;
495 output <<
"1 3 0 1 5 4" << endl;
496 output <<
"1 3 1 2 6 5" << endl;
497 output <<
"1 3 2 3 7 6" << endl;
498 output <<
"1 3 3 1 8 7" << endl;
499 output <<
"1 3 1 0 9 8" << endl;
503 output <<
"boundary" <<endl;
504 output <<
"10" <<endl;
505 output <<
"1 1 5 4" << endl;
506 output <<
"1 1 6 5" << endl;
507 output <<
"2 1 7 6" << endl;
508 output <<
"3 1 8 7" << endl;
509 output <<
"3 1 9 8" << endl;
510 output <<
"4 1 4 0" << endl;
511 output <<
"4 1 0 9" << endl;
512 output <<
"5 1 1 2" << endl;
513 output <<
"5 1 2 3" << endl;
514 output <<
"5 1 3 1" << endl;
518 output <<
"edges"<<endl;
520 output <<
"0 0 1"<<endl;
521 output <<
"1 1 2"<<endl;
522 output <<
"2 2 3"<<endl;
523 output <<
"3 3 1"<<endl;
525 output <<
"0 4 5"<<endl;
526 output <<
"1 5 6"<<endl;
527 output <<
"2 6 7"<<endl;
528 output <<
"3 7 8"<<endl;
529 output <<
"0 9 8"<<endl;
531 output <<
"4 0 4"<<endl;
532 output <<
"4 1 5"<<endl;
533 output <<
"4 2 6"<<endl;
534 output <<
"4 3 7"<<endl;
535 output <<
"4 1 8"<<endl;
536 output <<
"4 0 9"<<endl;
540 output <<
"vertices" << endl;
541 output << 10 << endl;
545 output<<
"patches"<<endl;
548 output <<
"# Patch 0 " << endl;
549 patch0.
Print(output); output<<endl;
550 output <<
"# Patch 1 " << endl;
551 patch1.
Print(output); output<<endl;
552 output <<
"# Patch 2 " << endl;
553 patch2.
Print(output); output<<endl;
554 output <<
"# Patch 3 " << endl;
555 patch3.
Print(output); output<<endl;
556 output <<
"# Patch 4 " << endl;
557 patch4.
Print(output); output<<endl;
564 cout << endl <<
"Boundary identifiers:" << endl;
565 cout <<
" 1 Bottom" << endl;
566 cout <<
" 2 Inflow" << endl;
567 cout <<
" 3 Top" << endl;
568 cout <<
" 4 Outflow" << endl;
569 cout <<
" 5 Foil section" << endl;
570 cout <<
"=========================================================="<< endl;
571 cout <<
" "<< mdim <<
"D mesh generated: " <<mesh_file.c_str()<< endl ;
572 cout <<
"=========================================================="<< endl;
575 cout <<
"=========================================================="<< endl;
576 cout <<
" Attempting to read mesh: " <<mesh_file.c_str()<< endl ;
577 cout <<
"=========================================================="<< endl;
578 Mesh mesh(mesh_file.c_str(), 1, 1);
595 glvis_file.append(msh_path);
596 glvis_file.append(
"glvis_");
597 glvis_file.append(msh_filename);
598 glvis_file.append(
".mesh");
599 ofstream glvis_output(glvis_file.c_str());
600 mesh.
Print(glvis_output);
601 glvis_output.close();