118int main(
int argc,
char *argv[])
125 const char *msh_path =
"";
126 const char *msh_filename =
"naca-cmesh";
127 args.
AddOption(&msh_path,
"-p",
"--mesh-path",
128 "Path in which the generated mesh is saved.");
129 args.
AddOption(&msh_filename,
"-m",
"--mesh-file",
130 "File where the generated mesh is written to.");
134 real_t foil_thickness = 0.12;
136 args.
AddOption(&foil_length,
"-l",
"--foil-length",
137 "Length of the used foil in the mesh. ");
138 args.
AddOption(&foil_thickness,
"-t",
"--foil-thickness",
139 "Thickness of the foil in the mesh as a fraction of length.");
140 args.
AddOption(&aoa,
"-aoa",
"--angle-of-attack",
141 "Angle of attack of the foil. ");
144 real_t boundary_dist = 3.0;
146 real_t tip_fraction = 0.05;
148 args.
AddOption(&boundary_dist,
"-b",
"--boundary-distance",
149 "Radius of the c-mesh, distance between foil and boundary");
150 args.
AddOption(&wake_length,
"-w",
"--wake_length",
151 "Length of the mesh after the foil");
152 args.
AddOption(&tip_fraction,
"-tf",
"--tip-fraction",
153 "Fraction of the length of foil that will be in tip patch");
154 args.
AddOption(&flair,
"-f",
"--flair-angle",
155 "Flair angle of top and bottom boundary to enforce inflow. If\
156 left at default, the flair angle is determined automatically\
157 to create an elegant mesh.");
163 args.
AddOption(&ncp_tip,
"-ntip",
"--ncp-tip",
164 "Number of control points used over the tip of the foil.");
165 args.
AddOption(&ncp_tail,
"-ntail",
"--ncp-tail",
166 "Number of control points used over the tail of the foil.");
167 args.
AddOption(&ncp_wake,
"-nwake",
"--ncp-wake",
168 "Number of control points over the wake behind the foil.");
169 args.
AddOption(&ncp_bnd,
"-nbnd",
"--ncp-circ",
170 "Number of control points between the foil and boundary.");
176 args.
AddOption(&str_tip,
"-stip",
"--str-tip",
177 "Stretch of the knot vector of the tip.");
178 args.
AddOption(&str_tail,
"-stail",
"--str-tail",
179 "Stretch of the knot vector of the tail.");
180 args.
AddOption(&str_wake,
"-sw",
"--str-wake",
181 "Stretch of the knot vector of the wake.");
182 args.
AddOption(&str_bnd,
"-sbnd",
"--str-circ",
183 "Stretch of the knot vector of the circle.");
185 bool visualization =
true;
187 args.
AddOption(&visualization,
"-vis",
"--visualization",
"-no-vis",
188 "--no-visualization",
189 "Enable or disable GLVis visualization.");
190 args.
AddOption(&visit,
"-visit",
"--visit",
"-no-visit",
"--no-visit",
191 "Enable/disable VisIt visualization in output Naca_cmesh.");
203 const real_t tail_fraction = 1.0 - tip_fraction;
206 constexpr real_t deg2rad = M_PI/180;
210 unique_ptr<KnotVector> kv0 =
TanhKnotVector(order, ncp_wake, str_wake);
212 unique_ptr<KnotVector> kv4 (
new KnotVector(*kv0));
219 unique_ptr<KnotVector> kvr =
TanhKnotVector(order, ncp_bnd, str_bnd);
228 const NACA4 foil_section(foil_thickness, foil_length);
234 flair = atan(foil_section.dydx(tip_fraction*foil_length));
245 NURBSPatch patch0(kv_o1.get(), kv_o1.get(), 3);
247 for (
int i = 0; i < 2; i++)
248 for (
int j = 0; j < 2; j++)
254 patch0(0,0,0) = foil_length + wake_length;
257 patch0(1,0,0) = foil_length;
260 patch0(0,1,0) = foil_length + wake_length;
261 patch0(0,1,1) = -
FlairBoundDist(flair, boundary_dist, patch0(0,1,0));
263 patch0(1,1,0) = foil_length;
264 patch0(1,1,1) = -
FlairBoundDist(flair, boundary_dist, patch0(1,1,0));
274 NURBSPatch patch1(kv_o1.get(), kv_o1.get(), 3);
276 for (
int i = 0; i < 2; i++)
277 for (
int j = 0; j < 2; j++)
283 patch1(0,0,0) = foil_length;
286 patch1(1,0,0) = tip_fraction*foil_length;
287 patch1(1,0,1) = -foil_section.y(patch1(1,0,0));
289 patch1(0,1,0) = foil_length;
290 patch1(0,1,1) = -
FlairBoundDist(flair, boundary_dist, patch1(0,1,0));
292 patch1(1,1,0) = -boundary_dist*sin(flair) + tip_fraction*foil_length;
293 patch1(1,1,1) = -boundary_dist*cos(flair);
299 int ncp = kv1->GetNCP();
302 Vector u(ncp),x(ncp),y(ncp),interp(ncp);
303 for (
int i = 0; i < ncp; i++)
305 u[i] = kv1->GetBotella(i);
308 for (
int i = 0; i < ncp; i++)
310 x[i] = foil_length*(1.0 - tail_fraction*
u[i]);
312 kv1->GetInterpolant(x,
u,interp);
313 for (
int i = 0; i < ncp; i++)
315 patch1(i,0,0) = interp[i];
318 for (
int i = 0; i < ncp; i++)
320 y[i] = -foil_section.y(x[i]);
322 kv1->GetInterpolant(y,
u,interp);
323 for (
int i = 0; i < ncp; i++)
325 patch1(i,0,1) = interp[i];
333 NURBSPatch patch2(kv_o2.get(), kv_o1.get(), 3);
336 for (
int i = 0; i < 3; i++)
337 for (
int j = 0; j < 2; j++)
343 patch2(2,0,0) = tip_fraction*foil_length;
344 patch2(2,0,1) = foil_section.y(patch2(2,0,0));
348 patch2(1,0,2) = cos((180*deg2rad-2*flair)/2);
350 patch2(0,0,0) = tip_fraction*foil_length;
351 patch2(0,0,1) = -foil_section.y(patch2(0,0,0));
354 patch2(2,1,0) = -boundary_dist*cos(90*deg2rad-flair)
355 + tip_fraction*foil_length;
356 patch2(2,1,1) = boundary_dist*sin(90*deg2rad-flair);
358 patch2(1,1,0) = -boundary_dist/sin(flair);
360 patch2(1,1,2) = cos((180*deg2rad-2*flair)/2);
362 patch2(0,1,0) = -boundary_dist*cos(90*deg2rad-flair)
363 + tip_fraction*foil_length;
364 patch2(0,1,1) = -boundary_dist*sin(90*deg2rad-flair);
367 patch2(1,0,0) *= patch2(1,0,2);
368 patch2(1,0,1) *= patch2(1,0,2);
369 patch2(1,1,0) *= patch2(1,1,2);
370 patch2(1,1,1) *= patch2(1,1,2);
377 int ncp = kv2->GetNCP();
380 GetTipXY(foil_section, *kv2, tip_fraction,x,y);
383 for (
int i = 0; i < ncp; i++)
385 u[i] = kv2->GetBotella(i);
387 kv2->GetInterpolant(x,
u,interp);
388 for (
int i = 0; i < ncp; i++)
390 patch2(i,0,0) = interp[i]*patch2(i,0,2);
392 kv2->GetInterpolant(y,
u,interp);
393 for (
int i = 0; i < ncp; i++)
395 patch2(i,0,1) = interp[i]*patch2(i,0,2);
404 NURBSPatch patch3(kv_o1.get(), kv_o1.get(), 3);
406 for (
int i = 0; i < 2; i++)
407 for (
int j = 0; j < 2; j++)
413 patch3(0,0,0) = tip_fraction*foil_length;
414 patch3(0,0,1) = foil_section.y(patch3(0,0,0));
416 patch3(1,0,0) = foil_length;
419 patch3(0,1,0) = -boundary_dist*sin(flair) + tip_fraction*foil_length;
420 patch3(0,1,1) = boundary_dist*cos(flair);
422 patch3(1,1,0) = foil_length;
423 patch3(1,1,1) =
FlairBoundDist(flair, boundary_dist, patch3(1,1,0));
429 int ncp = kv3->GetNCP();
431 Vector u(ncp),x(ncp),y(ncp),interp(ncp);
432 for (
int i = 0; i < ncp; i++)
434 u[i] = kv3->GetBotella(i);
437 for (
int i = 0; i < ncp; i++)
439 x[i] = foil_length*(tip_fraction + tail_fraction*
u[i]);
441 kv3->GetInterpolant(x,
u,interp);
442 for (
int i = 0; i < ncp; i++)
444 patch3(i,0,0) = interp[i];
447 for (
int i = 0; i < ncp; i++)
449 y[i] = foil_section.y(x[i]);
451 kv3->GetInterpolant(y,
u,interp);
452 for (
int i = 0; i < ncp; i++)
454 patch3(i,0,1) = interp[i];
462 NURBSPatch patch4(kv_o1.get(), kv_o1.get(), 3);
464 for (
int i = 0; i < 2; i++)
465 for (
int j = 0; j < 2; j++)
471 patch4(0,0,0) = foil_length;
474 patch4(1,0,0) = foil_length+ wake_length;
477 patch4(0,1,0) = foil_length;
478 patch4(0,1,1) =
FlairBoundDist(flair, boundary_dist, patch4(0,1,0));
480 patch4(1,1,0) = foil_length+ wake_length;
481 patch4(1,1,1) =
FlairBoundDist(flair, boundary_dist, patch4(1,1,0));
501 mesh_file.append(msh_path);
502 mesh_file.append(msh_filename);
503 mesh_file.append(
".mesh");
504 ofstream output(mesh_file.c_str());
507 output<<
"MFEM NURBS mesh v1.0"<<endl;
508 output<< endl <<
"# " << mdim
509 <<
"D C-mesh around a symmetric NACA foil section"
511 output<<
"dimension"<<endl;
512 output<< mdim <<endl;
516 output <<
"elements"<<endl;
518 output <<
"1 3 0 1 5 4" << endl;
519 output <<
"1 3 1 2 6 5" << endl;
520 output <<
"1 3 2 3 7 6" << endl;
521 output <<
"1 3 3 1 8 7" << endl;
522 output <<
"1 3 1 0 9 8" << endl;
526 output <<
"boundary" <<endl;
527 output <<
"10" <<endl;
528 output <<
"1 1 5 4" << endl;
529 output <<
"1 1 6 5" << endl;
530 output <<
"2 1 7 6" << endl;
531 output <<
"3 1 8 7" << endl;
532 output <<
"3 1 9 8" << endl;
533 output <<
"4 1 4 0" << endl;
534 output <<
"4 1 0 9" << endl;
535 output <<
"5 1 1 2" << endl;
536 output <<
"5 1 2 3" << endl;
537 output <<
"5 1 3 1" << endl;
541 output <<
"edges"<<endl;
543 output <<
"0 0 1"<<endl;
544 output <<
"1 1 2"<<endl;
545 output <<
"2 2 3"<<endl;
546 output <<
"3 3 1"<<endl;
548 output <<
"0 4 5"<<endl;
549 output <<
"1 5 6"<<endl;
550 output <<
"2 6 7"<<endl;
551 output <<
"3 7 8"<<endl;
552 output <<
"0 9 8"<<endl;
554 output <<
"4 0 4"<<endl;
555 output <<
"4 1 5"<<endl;
556 output <<
"4 2 6"<<endl;
557 output <<
"4 3 7"<<endl;
558 output <<
"4 1 8"<<endl;
559 output <<
"4 0 9"<<endl;
563 output <<
"vertices" << endl;
564 output << 10 << endl;
568 output<<
"patches"<<endl;
571 output <<
"# Patch 0 " << endl;
572 patch0.
Print(output); output<<endl;
573 output <<
"# Patch 1 " << endl;
574 patch1.
Print(output); output<<endl;
575 output <<
"# Patch 2 " << endl;
576 patch2.
Print(output); output<<endl;
577 output <<
"# Patch 3 " << endl;
578 patch3.
Print(output); output<<endl;
579 output <<
"# Patch 4 " << endl;
580 patch4.
Print(output); output<<endl;
585 cout << endl <<
"Boundary identifiers:" << endl;
586 cout <<
" 1 Bottom" << endl;
587 cout <<
" 2 Inflow" << endl;
588 cout <<
" 3 Top" << endl;
589 cout <<
" 4 Outflow" << endl;
590 cout <<
" 5 Foil section" << endl;
591 cout <<
"=========================================================="<< endl;
592 cout <<
" "<< mdim <<
"D mesh generated: " <<mesh_file.c_str()<< endl ;
593 cout <<
"=========================================================="<< endl;
596 cout <<
"=========================================================="<< endl;
597 cout <<
" Attempting to read mesh: " <<mesh_file.c_str()<< endl ;
598 cout <<
"=========================================================="<< endl;
599 Mesh mesh(mesh_file.c_str(), 1, 1);
616 glvis_file.append(msh_path);
617 glvis_file.append(
"glvis_");
618 glvis_file.append(msh_filename);
619 glvis_file.append(
".mesh");
620 ofstream glvis_output(glvis_file.c_str());
621 mesh.
Print(glvis_output);
622 glvis_output.close();