Nektar++
Functions
ExtractSurface2DCFS.cpp File Reference
#include <cstdio>
#include <cstdlib>
#include <iomanip>
#include <iostream>
#include <string>
#include <MultiRegions/AssemblyMap/AssemblyMapDG.h>
#include <MultiRegions/ExpList2DHomogeneous1D.h>
#include <MultiRegions/ExpList3DHomogeneous1D.h>
#include <MultiRegions/ExpList3DHomogeneous2D.h>
#include <LocalRegions/Expansion2D.h>
#include <LocalRegions/MatrixKey.h>
#include <MultiRegions/DisContField.h>
#include <LibUtilities/BasicUtils/ErrorUtil.hpp>
#include <LibUtilities/BasicUtils/FieldIO.h>
#include <LibUtilities/BasicUtils/NekFactory.hpp>
#include <LibUtilities/BasicUtils/SessionReader.h>
#include <LibUtilities/BasicUtils/SharedArray.hpp>
#include <LibUtilities/Memory/NekMemoryManager.hpp>
#include <MultiRegions/ContField.h>
#include <SpatialDomains/MeshGraph.h>
#include <SolverUtils/SolverUtilsDeclspec.h>
#include <boost/program_options.hpp>

Go to the source code of this file.

Functions

int main (int argc, char *argv[])
 

Function Documentation

◆ main()

int main ( int  argc,
char *  argv[] 
)

Evaluation of the velocity gradient in the cartesian directions Du_x: traceFieldsAdded[10] Du_y: traceFieldsAdded[11] Dv_x: traceFieldsAdded[12] Dv_y: traceFieldsAdded[13]

Definition at line 70 of file ExtractSurface2DCFS.cpp.

71{
72 string fname;
73 po::options_description desc("Available options");
74 desc.add_options()("help,h", "Produce this help message.");
75
76 po::options_description hidden("Hidden options");
77 hidden.add_options()("input-file", po::value<vector<string>>(),
78 "input filename");
79
80 po::options_description cmdline_options;
81 cmdline_options.add(desc).add(hidden);
82
83 po::options_description visible("Allowed options");
84 visible.add(desc);
85
86 po::positional_options_description p;
87 p.add("input-file", -1);
88
89 po::variables_map vm;
90
91 try
92 {
93 po::store(po::command_line_parser(argc, argv)
94 .options(cmdline_options)
95 .positional(p)
96 .run(),
97 vm);
98 po::notify(vm);
99 }
100 catch (const std::exception &e)
101 {
102 cerr << e.what() << endl;
103 cerr << desc;
104 return 1;
105 }
106
107 std::vector<std::string> filenames;
108 if (vm.count("input-file"))
109 {
110 filenames = vm["input-file"].as<std::vector<std::string>>();
111 }
112
113 if (vm.count("help") || vm.count("input-file") != 1)
114 {
115 cerr << "Description: Extracts a surface from a 2D .fld file created "
116 "by the CompressibleFlowSolver and places it into a .cfs file"
117 << endl;
118 cerr << "Usage: ExtractSurface2DCFS [options] meshFile fieldFile"
119 << endl;
120 cout << desc;
121 return 1;
122 }
123
125 LibUtilities::SessionReader::CreateInstance(argc, argv);
127 SpatialDomains::MeshGraph::Read(vSession);
128
129 fname = vSession->GetSessionName() + ".cfs";
130
131 // Find .fld or .chk file name
132 std::string fieldFile;
133 for (auto &file : filenames)
134 {
135 if (file.size() > 4 && (file.substr(file.size() - 4, 4) == ".fld" ||
136 file.substr(file.size() - 4, 4) == ".chk"))
137 {
138 fieldFile = file;
139 break;
140 }
141 }
142
143 int cnt;
144 int id1 = 0;
145 int id2 = 0;
146 int i, j, n, e, b;
147 Array<OneD, NekDouble> auxArray;
148
149 int nBndEdgePts, nBndEdges, nBndRegions;
150
151 std::string m_ViscosityType;
152 NekDouble m_gamma;
153 NekDouble m_pInf;
157 NekDouble m_wInf;
158 NekDouble m_gasConstant;
161
162 int m_spacedim = 2;
163 int nDimensions = m_spacedim;
164 int phys_offset;
165
166 // Get gamma parameter from session file.
167 ASSERTL0(vSession->DefinesParameter("Gamma"),
168 "Compressible flow sessions must define a Gamma parameter.");
169 vSession->LoadParameter("Gamma", m_gamma, 1.4);
170
171 // Get E0 parameter from session file.
172 ASSERTL0(vSession->DefinesParameter("pInf"),
173 "Compressible flow sessions must define a pInf parameter.");
174 vSession->LoadParameter("pInf", m_pInf, 101325);
175
176 // Get rhoInf parameter from session file.
177 ASSERTL0(vSession->DefinesParameter("rhoInf"),
178 "Compressible flow sessions must define a rhoInf parameter.");
179 vSession->LoadParameter("rhoInf", m_rhoInf, 1.225);
180
181 // Get uInf parameter from session file.
182 ASSERTL0(vSession->DefinesParameter("uInf"),
183 "Compressible flow sessions must define a uInf parameter.");
184 vSession->LoadParameter("uInf", m_uInf, 0.1);
185
186 // Get vInf parameter from session file.
187 if (m_spacedim == 2 || m_spacedim == 3)
188 {
189 ASSERTL0(vSession->DefinesParameter("vInf"),
190 "Compressible flow sessions must define a vInf parameter"
191 "for 2D/3D problems.");
192 vSession->LoadParameter("vInf", m_vInf, 0.0);
193 }
194
195 // Get wInf parameter from session file.
196 if (m_spacedim == 3)
197 {
198 ASSERTL0(vSession->DefinesParameter("wInf"),
199 "Compressible flow sessions must define a wInf parameter"
200 "for 3D problems.");
201 vSession->LoadParameter("wInf", m_wInf, 0.0);
202 }
203
204 vSession->LoadParameter("GasConstant", m_gasConstant, 287.058);
205 vSession->LoadParameter("Twall", m_Twall, 300.15);
206 vSession->LoadSolverInfo("ViscosityType", m_ViscosityType, "Constant");
207 vSession->LoadParameter("mu", m_mu, 1.78e-05);
208
209 //--------------------------------------------------------------------------
210 // Import field file
211 vector<LibUtilities::FieldDefinitionsSharedPtr> fieldDef;
212 vector<vector<NekDouble>> fieldData;
213
214 LibUtilities::FieldMetaDataMap fieldMetaDataMap;
215 LibUtilities::Import(fieldFile, fieldDef, fieldData, fieldMetaDataMap);
216 //--------------------------------------------------------------------------
217
218 //--------------------------------------------------------------------------
219 // Set up Expansion information
220 vector<vector<LibUtilities::PointsType>> pointsType;
221 for (i = 0; i < fieldDef.size(); ++i)
222 {
223 vector<LibUtilities::PointsType> ptype;
224 for (j = 0; j < 2; ++j)
225 {
226 ptype.push_back(LibUtilities::ePolyEvenlySpaced);
227 }
228 pointsType.push_back(ptype);
229 }
230 graphShPt->SetExpansionInfo(fieldDef, pointsType);
231
232 //--------------------------------------------------------------------------
233
234 //--------------------------------------------------------------------------
235 // Define Expansion
236 int nfields = vSession->GetVariables().size();
239
240 for (i = 0; i < pFields.size(); i++)
241 {
242 pFields[i] =
244 vSession, graphShPt, vSession->GetVariable(i));
245 }
246
249 graphShPt);
250
251 Exp[0] = Exp2D;
252
253 for (i = 1; i < nfields; ++i)
254 {
255 Exp[i] =
257 }
258
259 int nSolutionPts = pFields[0]->GetNpoints();
260 int nTracePts = pFields[0]->GetTrace()->GetTotPoints();
261 int nElements = pFields[0]->GetExpSize();
262
263 Array<OneD, NekDouble> tmp(nSolutionPts, 0.0);
264
265 Array<OneD, NekDouble> x(nSolutionPts);
266 Array<OneD, NekDouble> y(nSolutionPts);
267 Array<OneD, NekDouble> z(nSolutionPts);
268
269 Array<OneD, NekDouble> traceX(nTracePts);
270 Array<OneD, NekDouble> traceY(nTracePts);
271 Array<OneD, NekDouble> traceZ(nTracePts);
272
273 Array<OneD, NekDouble> surfaceX(nTracePts);
274 Array<OneD, NekDouble> surfaceY(nTracePts);
275 Array<OneD, NekDouble> surfaceZ(nTracePts);
276
277 pFields[0]->GetCoords(x, y, z);
278
279 pFields[0]->ExtractTracePhys(x, traceX);
280 pFields[0]->ExtractTracePhys(y, traceY);
281 pFields[0]->ExtractTracePhys(z, traceZ);
282 //--------------------------------------------------------------------------
283
284 //--------------------------------------------------------------------------
285 // Copy data from field file
286 Array<OneD, Array<OneD, NekDouble>> uFields(nfields);
287 Array<OneD, Array<OneD, NekDouble>> traceFields(nfields);
288 Array<OneD, Array<OneD, NekDouble>> surfaceFields(nfields);
289
290 // Extract the physical values of the solution at the boundaries
291 for (j = 0; j < nfields; ++j)
292 {
293 uFields[j] = Array<OneD, NekDouble>(nSolutionPts, 0.0);
294 traceFields[j] = Array<OneD, NekDouble>(nTracePts, 0.0);
295 surfaceFields[j] = Array<OneD, NekDouble>(nTracePts, 0.0);
296
297 for (i = 0; i < fieldData.size(); ++i)
298 {
299 Exp[j]->ExtractDataToCoeffs(fieldDef[i], fieldData[i],
300 fieldDef[i]->m_fields[j],
301 Exp[j]->UpdateCoeffs());
302 }
303 Exp[j]->BwdTrans(Exp[j]->GetCoeffs(), Exp[j]->UpdatePhys());
304 Vmath::Vcopy(nSolutionPts, Exp[j]->GetPhys(), 1, uFields[j], 1);
305 pFields[0]->ExtractTracePhys(uFields[j], traceFields[j]);
306 }
307
308 // Fields to add in the output file
309
310 int nfieldsAdded = 20;
311 Array<OneD, Array<OneD, NekDouble>> traceFieldsAdded(nfieldsAdded);
312 Array<OneD, Array<OneD, NekDouble>> surfaceFieldsAdded(nfieldsAdded);
313
314 for (j = 0; j < nfieldsAdded; ++j)
315 {
316 traceFieldsAdded[j] = Array<OneD, NekDouble>(nTracePts, 0.0);
317 surfaceFieldsAdded[j] = Array<OneD, NekDouble>(nTracePts, 0.0);
318 }
319
320 /******** Evaluation of normals and tangents on the trace *****************
321 * nx -> traceFieldsAdded[0];
322 * ny -> traceFieldsAdded[1];
323 * tx -> traceFieldsAdded[2];
324 * ty -> traceFieldsAdded[3];
325 ***************************************************************************/
326
327 Array<OneD, Array<OneD, NekDouble>> m_traceNormals(nDimensions);
328 for (i = 0; i < nDimensions; ++i)
329 {
330 m_traceNormals[i] = Array<OneD, NekDouble>(nTracePts, 0.0);
331 }
332 pFields[0]->GetTrace()->GetNormals(m_traceNormals);
333
334 Array<OneD, Array<OneD, NekDouble>> m_traceTangents(nDimensions);
335 for (i = 0; i < nDimensions; ++i)
336 {
337 m_traceTangents[i] = Array<OneD, NekDouble>(nTracePts, 0.0);
338 }
339
340 // nx
341 Vmath::Vcopy(nTracePts, &m_traceNormals[0][0], 1, &traceFieldsAdded[0][0],
342 1);
343
344 // ny
345 Vmath::Vcopy(nTracePts, &m_traceNormals[1][0], 1, &traceFieldsAdded[1][0],
346 1);
347
348 // t_x = - n_y
349 Vmath::Vcopy(nTracePts, &m_traceNormals[1][0], 1, &m_traceTangents[0][0],
350 1);
351 Vmath::Neg(nTracePts, &m_traceTangents[0][0], 1);
352
353 Vmath::Vcopy(nTracePts, &m_traceTangents[0][0], 1, &traceFieldsAdded[2][0],
354 1);
355
356 // t_y = n_x
357 Vmath::Vcopy(nTracePts, &m_traceNormals[0][0], 1, &m_traceTangents[1][0],
358 1);
359
360 Vmath::Vcopy(nTracePts, &m_traceTangents[1][0], 1, &traceFieldsAdded[3][0],
361 1);
362
363 /******** Evaluation of the pressure ***************************************
364 * P = (E-1/2.*rho.*((rhou./rho).^2+(rhov./rho).^2))*(gamma - 1);
365 * P -> traceFieldsAdded[4];
366 ***************************************************************************/
367
368 Array<OneD, NekDouble> pressure(nSolutionPts, 0.0);
369 NekDouble gammaMinusOne = m_gamma - 1.0;
370
371 for (i = 0; i < m_spacedim; i++)
372 {
373 Vmath::Vmul(nSolutionPts, &uFields[i + 1][0], 1, &uFields[i + 1][0], 1,
374 &tmp[0], 1);
375
376 Vmath::Smul(nSolutionPts, 0.5, &tmp[0], 1, &tmp[0], 1);
377
378 Vmath::Vadd(nSolutionPts, &pressure[0], 1, &tmp[0], 1, &pressure[0], 1);
379 }
380
381 Vmath::Vdiv(nSolutionPts, &pressure[0], 1, &uFields[0][0], 1, &pressure[0],
382 1);
383
384 Vmath::Vsub(nSolutionPts, &uFields[nfields - 1][0], 1, &pressure[0], 1,
385 &pressure[0], 1);
386
387 Vmath::Smul(nSolutionPts, gammaMinusOne, &pressure[0], 1, &pressure[0], 1);
388
389 // Extract trace
390 pFields[0]->ExtractTracePhys(pressure, traceFieldsAdded[4]);
391
392 /******** Evaluation of the temperature ************************************
393 * T = P/(R*rho);
394 * T -> traceFieldsAdded[5];
395 ***************************************************************************/
396
397 Array<OneD, NekDouble> temperature(nSolutionPts, 0.0);
398
399 Vmath::Vdiv(nSolutionPts, &pressure[0], 1, &uFields[0][0], 1,
400 &temperature[0], 1);
401
402 NekDouble GasConstantInv = 1.0 / m_gasConstant;
403 Vmath::Smul(nSolutionPts, GasConstantInv, &temperature[0], 1,
404 &temperature[0], 1);
405
406 // Extract trace
407 pFields[0]->ExtractTracePhys(temperature, traceFieldsAdded[5]);
408
409 /*** Evaluation of the temperature gradient in the normal direction ********
410 * DT_n -> traceFieldsAdded[6]
411 ***************************************************************************/
412
413 Array<OneD, Array<OneD, NekDouble>> Dtemperature(nDimensions);
414 Array<OneD, Array<OneD, NekDouble>> traceDtemperature(nDimensions);
415
416 for (i = 0; i < nDimensions; ++i)
417 {
418 Dtemperature[i] = Array<OneD, NekDouble>(nSolutionPts, 0.0);
419 traceDtemperature[i] = Array<OneD, NekDouble>(nTracePts, 0.0);
420 }
421
422 for (i = 0; i < nDimensions; ++i)
423 {
424 for (n = 0; n < nElements; n++)
425 {
426 phys_offset = pFields[0]->GetPhys_Offset(n);
427
428 pFields[i]->GetExp(n)->PhysDeriv(i, temperature + phys_offset,
429 auxArray =
430 Dtemperature[i] + phys_offset);
431 }
432 // Extract trace
433 pFields[0]->ExtractTracePhys(Dtemperature[i], traceDtemperature[i]);
434 }
435
436 for (i = 0; i < nDimensions; ++i)
437 {
438 Vmath::Vmul(nTracePts, &m_traceNormals[i][0], 1,
439 &traceDtemperature[i][0], 1, &tmp[0], 1);
440
441 Vmath::Vadd(nTracePts, &traceFieldsAdded[6][0], 1, &tmp[0], 1,
442 &traceFieldsAdded[6][0], 1);
443 }
444
445 /*** Evaluation of the pressure gradient ***********************************
446 * DP_t -> traceFieldsAdded[7] tangent direction
447 * DP_x -> traceFieldsAdded[8]
448 * DP_y -> traceFieldsAdded[9]
449 ***************************************************************************/
450
451 Array<OneD, Array<OneD, NekDouble>> Dpressure(nDimensions);
452 Array<OneD, Array<OneD, NekDouble>> traceDpressure(nDimensions);
453
454 for (i = 0; i < nDimensions; ++i)
455 {
456 Dpressure[i] = Array<OneD, NekDouble>(nSolutionPts, 0.0);
457 traceDpressure[i] = Array<OneD, NekDouble>(nTracePts, 0.0);
458 }
459
460 for (i = 0; i < nDimensions; ++i)
461 {
462 for (n = 0; n < nElements; n++)
463 {
464 phys_offset = pFields[0]->GetPhys_Offset(n);
465
466 pFields[i]->GetExp(n)->PhysDeriv(i, pressure + phys_offset,
467 auxArray =
468 Dpressure[i] + phys_offset);
469 }
470 // Extract trace
471 pFields[0]->ExtractTracePhys(Dpressure[i], traceDpressure[i]);
472 }
473
474 // Dp_t
475 for (i = 0; i < nDimensions; ++i)
476 {
477 Vmath::Vmul(nTracePts, &m_traceTangents[i][0], 1, &traceDpressure[i][0],
478 1, &tmp[0], 1);
479
480 Vmath::Vadd(nTracePts, &traceFieldsAdded[7][0], 1, &tmp[0], 1,
481 &traceFieldsAdded[7][0], 1);
482 }
483
484 // Dp_x
485 Vmath::Vcopy(nTracePts, &traceDpressure[0][0], 1, &traceFieldsAdded[8][0],
486 1);
487
488 // Dp_y
489 Vmath::Vcopy(nTracePts, &traceDpressure[1][0], 1, &traceFieldsAdded[9][0],
490 1);
491
492 /** Evaluation of the velocity gradient in the cartesian directions
493 * Du_x: traceFieldsAdded[10]
494 * Du_y: traceFieldsAdded[11]
495 * Dv_x: traceFieldsAdded[12]
496 * Dv_y: traceFieldsAdded[13]
497 **/
498 Array<OneD, Array<OneD, Array<OneD, NekDouble>>> Dvelocity(nDimensions);
500 nDimensions);
502
503 for (i = 0; i < nDimensions; ++i)
504 {
505 Dvelocity[i] = Array<OneD, Array<OneD, NekDouble>>(nDimensions);
506 traceDvelocity[i] = Array<OneD, Array<OneD, NekDouble>>(nDimensions);
507 velocity[i] = Array<OneD, NekDouble>(nSolutionPts, 0.0);
508
509 Vmath::Vdiv(nSolutionPts, uFields[i + 1], 1, uFields[0], 1, velocity[i],
510 1);
511
512 for (j = 0; j < nDimensions; ++j)
513 {
514 Dvelocity[i][j] = Array<OneD, NekDouble>(nSolutionPts, 0.0);
515 traceDvelocity[i][j] = Array<OneD, NekDouble>(nTracePts, 0.0);
516 }
517 }
518
519 for (i = 0; i < nDimensions; ++i)
520 {
521 for (j = 0; j < nDimensions; ++j)
522 {
523 for (n = 0; n < nElements; n++)
524 {
525 phys_offset = pFields[0]->GetPhys_Offset(n);
526
527 pFields[i]->GetExp(n)->PhysDeriv(j, velocity[i] + phys_offset,
528 auxArray = Dvelocity[i][j] +
529 phys_offset);
530 }
531
532 // Extract trace
533 pFields[0]->ExtractTracePhys(Dvelocity[i][j], traceDvelocity[i][j]);
534 }
535 }
536
537 Vmath::Vcopy(nTracePts, &traceDvelocity[0][0][0], 1,
538 &traceFieldsAdded[10][0], 1);
539 Vmath::Vcopy(nTracePts, &traceDvelocity[0][1][0], 1,
540 &traceFieldsAdded[11][0], 1);
541 Vmath::Vcopy(nTracePts, &traceDvelocity[1][0][0], 1,
542 &traceFieldsAdded[12][0], 1);
543 Vmath::Vcopy(nTracePts, &traceDvelocity[1][1][0], 1,
544 &traceFieldsAdded[13][0], 1);
545
546 /*** Evaluation of shear stresses ******************************************
547 * tau_xx -> traceFieldsAdded[14]
548 * tau_yy -> traceFieldsAdded[15]
549 * tau_xy -> traceFieldsAdded[16]
550 ***************************************************************************/
551
552 // Stokes hypotesis
553 const NekDouble lambda = -2.0 / 3.0;
554
555 // Auxiliary variables
556 Array<OneD, NekDouble> mu(nSolutionPts, 0.0);
557 Array<OneD, NekDouble> mu2(nSolutionPts, 0.0);
558 Array<OneD, NekDouble> divVel(nSolutionPts, 0.0);
559
560 // Variable viscosity through the Sutherland's law
561 if (m_ViscosityType == "Variable")
562 {
563 NekDouble mu_star = m_mu;
564 NekDouble T_star = m_pInf / (m_rhoInf * m_gasConstant);
565 NekDouble ratio;
566
567 for (int i = 0; i < nSolutionPts; ++i)
568 {
569 ratio = temperature[i] / T_star;
570 mu[i] = mu_star * ratio * sqrt(ratio) * (T_star + 110.0) /
571 (temperature[i] + 110.0);
572 }
573 }
574 else
575 {
576 Vmath::Fill(nSolutionPts, m_mu, &mu[0], 1);
577 }
578
579 // Computing diagonal terms of viscous stress tensor
580 Array<OneD, Array<OneD, NekDouble>> temp(m_spacedim);
581 Array<OneD, Array<OneD, NekDouble>> Sgg(m_spacedim);
582
583 // mu2 = 2 * mu
584 Vmath::Smul(nSolutionPts, 2.0, &mu[0], 1, &mu2[0], 1);
585
586 // Velocity divergence
587 Vmath::Vadd(nSolutionPts, &divVel[0], 1, &Dvelocity[0][0][0], 1, &divVel[0],
588 1);
589 Vmath::Vadd(nSolutionPts, &divVel[0], 1, &Dvelocity[1][1][0], 1, &divVel[0],
590 1);
591
592 // Velocity divergence scaled by lambda * mu
593 Vmath::Smul(nSolutionPts, lambda, &divVel[0], 1, &divVel[0], 1);
594 Vmath::Vmul(nSolutionPts, &mu[0], 1, &divVel[0], 1, &divVel[0], 1);
595
596 // Diagonal terms of viscous stress tensor (Sxx, Syy)
597 // Sjj = 2 * mu * du_j/dx_j - (2 / 3) * mu * sum_j(du_j/dx_j)
598 for (j = 0; j < m_spacedim; ++j)
599 {
600 temp[j] = Array<OneD, NekDouble>(nSolutionPts, 0.0);
601 Sgg[j] = Array<OneD, NekDouble>(nSolutionPts, 0.0);
602
603 Vmath::Vmul(nSolutionPts, &mu2[0], 1, &Dvelocity[j][j][0], 1,
604 &temp[j][0], 1);
605
606 Vmath::Vadd(nSolutionPts, &temp[j][0], 1, &divVel[0], 1, &Sgg[j][0], 1);
607 }
608
609 // Extra diagonal terms of viscous stress tensor (Sxy = Syx)
610 Array<OneD, NekDouble> Sxy(nSolutionPts, 0.0);
611
612 // Sxy = (du/dy + dv/dx)
613 Vmath::Vadd(nSolutionPts, &Dvelocity[0][1][0], 1, &Dvelocity[1][0][0], 1,
614 &Sxy[0], 1);
615
616 // Sxy = mu * (du/dy + dv/dx)
617 Vmath::Vmul(nSolutionPts, &mu[0], 1, &Sxy[0], 1, &Sxy[0], 1);
618
619 pFields[0]->ExtractTracePhys(Sgg[0], traceFieldsAdded[14]);
620 pFields[0]->ExtractTracePhys(Sgg[1], traceFieldsAdded[15]);
621 pFields[0]->ExtractTracePhys(Sxy, traceFieldsAdded[16]);
622
623 /*** Evaluation of the shear stress in tangent direction *******************
624 * tau_t -> traceFieldsAdded[17]
625 ***************************************************************************/
626 Array<OneD, NekDouble> sigma_diff(nTracePts, 0.0);
627 Array<OneD, NekDouble> cosTeta(nTracePts, 0.0);
628 Array<OneD, NekDouble> sinTeta(nTracePts, 0.0);
629 Array<OneD, NekDouble> cos2Teta(nTracePts, 0.0);
630 Array<OneD, NekDouble> sin2Teta(nTracePts, 0.0);
631 Array<OneD, NekDouble> tau_t(nTracePts, 0.0);
632
633 Array<OneD, NekDouble> tmpTeta(nTracePts, 0.0);
634
635 // cos(teta) = nx
636 Vmath::Vcopy(nTracePts, &m_traceNormals[0][0], 1, &cosTeta[0], 1);
637
638 // sin(teta) = ny
639 Vmath::Vcopy(nTracePts, &m_traceNormals[1][0], 1, &sinTeta[0], 1);
640
641 // sigma_diff = sigma_x - sigma_y
642 Vmath::Vsub(nTracePts, &traceFieldsAdded[14][0], 1,
643 &traceFieldsAdded[15][0], 1, &sigma_diff[0], 1);
644
645 // sin(2*teta)
646 Vmath::Vmul(nTracePts, &cosTeta[0], 1, &sinTeta[0], 1, &tmpTeta[0], 1);
647 Vmath::Smul(nTracePts, 2.0, &tmpTeta[0], 1, &sin2Teta[0], 1);
648
649 // cos(2*teta)
650 Vmath::Vmul(nTracePts, &cosTeta[0], 1, &cosTeta[0], 1, &cos2Teta[0], 1);
651 Vmath::Vmul(nTracePts, &sinTeta[0], 1, &sinTeta[0], 1, &tmpTeta[0], 1);
652 Vmath::Vsub(nTracePts, &cos2Teta[0], 1, &tmpTeta[0], 1, &cos2Teta[0], 1);
653
654 // tau_t = -0.5*sigma_diff * sin(2*teta) + tau_xy * cos(2*teta)
655 Vmath::Smul(nTracePts, -0.5, &sigma_diff[0], 1, &sigma_diff[0], 1);
656 Vmath::Vmul(nTracePts, &sigma_diff[0], 1, &sin2Teta[0], 1, &tau_t[0], 1);
657 Vmath::Vmul(nTracePts, &traceFieldsAdded[16][0], 1, &cos2Teta[0], 1,
658 &tmpTeta[0], 1);
659 Vmath::Vadd(nTracePts, &tau_t[0], 1, &tmpTeta[0], 1, &tau_t[0], 1);
660
661 Vmath::Vcopy(nTracePts, &tau_t[0], 1, &traceFieldsAdded[17][0], 1);
662
663 /*** Evaluation of dinamic viscosity ***************************************
664 * mu -> traceFieldsAdded[18]
665 ***************************************************************************/
666
667 pFields[0]->ExtractTracePhys(mu, traceFieldsAdded[18]);
668
669 /*** Evaluation of Mach number *********************************************
670 * M -> traceFieldsAdded[18]
671 ***************************************************************************/
672 NekDouble gamma = m_gamma;
673
674 // Speed of sound
675 Array<OneD, NekDouble> soundspeed(nSolutionPts, 0.0);
676
677 Vmath::Vdiv(nSolutionPts, pressure, 1, uFields[0], 1, soundspeed, 1);
678 Vmath::Smul(nSolutionPts, gamma, soundspeed, 1, soundspeed, 1);
679 Vmath::Vsqrt(nSolutionPts, soundspeed, 1, soundspeed, 1);
680
681 // Mach
682 Array<OneD, NekDouble> mach(nSolutionPts, 0.0);
683
684 for (int i = 0; i < m_spacedim; ++i)
685 {
686 Vmath::Vvtvp(nSolutionPts, uFields[i + 1], 1, uFields[i + 1], 1, mach,
687 1, mach, 1);
688 }
689
690 Vmath::Vdiv(nSolutionPts, mach, 1, uFields[0], 1, mach, 1);
691 Vmath::Vdiv(nSolutionPts, mach, 1, uFields[0], 1, mach, 1);
692 Vmath::Vsqrt(nSolutionPts, mach, 1, mach, 1);
693 Vmath::Vdiv(nSolutionPts, mach, 1, soundspeed, 1, mach, 1);
694
695 pFields[0]->ExtractTracePhys(mach, traceFieldsAdded[19]);
696
697 /**************************************************************************/
698 // Extract coordinates
699
700 if (pFields[0]->GetBndCondExpansions().size())
701 {
702 id1 = 0;
703 cnt = 0;
704 nBndRegions = pFields[0]->GetBndCondExpansions().size();
705 for (b = 0; b < nBndRegions; ++b)
706 {
707 nBndEdges = pFields[0]->GetBndCondExpansions()[b]->GetExpSize();
708 for (e = 0; e < nBndEdges; ++e)
709 {
710 nBndEdgePts = pFields[0]
711 ->GetBndCondExpansions()[b]
712 ->GetExp(e)
713 ->GetNumPoints(0);
714
715 id2 = pFields[0]->GetTrace()->GetPhys_Offset(
716 pFields[0]->GetTraceMap()->GetBndCondIDToGlobalTraceID(
717 cnt++));
718
719 if (pFields[0]->GetBndConditions()[b]->GetUserDefined() ==
720 "WallViscous" ||
721 pFields[0]->GetBndConditions()[b]->GetUserDefined() ==
722 "WallAdiabatic" ||
723 pFields[0]->GetBndConditions()[b]->GetUserDefined() ==
724 "Wall")
725 {
726 Vmath::Vcopy(nBndEdgePts, &traceX[id2], 1, &surfaceX[id1],
727 1);
728
729 Vmath::Vcopy(nBndEdgePts, &traceY[id2], 1, &surfaceY[id1],
730 1);
731
732 Vmath::Vcopy(nBndEdgePts, &traceZ[id2], 1, &surfaceZ[id1],
733 1);
734
735 id1 += nBndEdgePts;
736 }
737 }
738 }
739 }
740
741 // Extract fields
742 if (pFields[0]->GetBndCondExpansions().size())
743 {
744 for (j = 0; j < nfields; ++j)
745 {
746 id1 = 0;
747 cnt = 0;
748 nBndRegions = pFields[j]->GetBndCondExpansions().size();
749 for (b = 0; b < nBndRegions; ++b)
750 {
751 nBndEdges = pFields[j]->GetBndCondExpansions()[b]->GetExpSize();
752 for (e = 0; e < nBndEdges; ++e)
753 {
754 nBndEdgePts = pFields[j]
755 ->GetBndCondExpansions()[b]
756 ->GetExp(e)
757 ->GetNumPoints(0);
758
759 id2 = pFields[j]->GetTrace()->GetPhys_Offset(
760 pFields[j]->GetTraceMap()->GetBndCondIDToGlobalTraceID(
761 cnt++));
762
763 if (pFields[j]->GetBndConditions()[b]->GetUserDefined() ==
764 "WallViscous" ||
765 pFields[j]->GetBndConditions()[b]->GetUserDefined() ==
766 "WallAdiabatic" ||
767 pFields[j]->GetBndConditions()[b]->GetUserDefined() ==
768 "Wall")
769 {
770 Vmath::Vcopy(nBndEdgePts, &traceFields[j][id2], 1,
771 &surfaceFields[j][id1], 1);
772
773 id1 += nBndEdgePts;
774 }
775 }
776 }
777 }
778 }
779
780 // Extract fields added
781 if (pFields[0]->GetBndCondExpansions().size())
782 {
783 for (j = 0; j < nfieldsAdded; ++j)
784 {
785 id1 = 0;
786 cnt = 0;
787 nBndRegions = pFields[0]->GetBndCondExpansions().size();
788 for (b = 0; b < nBndRegions; ++b)
789 {
790 nBndEdges = pFields[0]->GetBndCondExpansions()[b]->GetExpSize();
791 for (e = 0; e < nBndEdges; ++e)
792 {
793 nBndEdgePts = pFields[0]
794 ->GetBndCondExpansions()[b]
795 ->GetExp(e)
796 ->GetNumPoints(0);
797
798 id2 = pFields[0]->GetTrace()->GetPhys_Offset(
799 pFields[0]->GetTraceMap()->GetBndCondIDToGlobalTraceID(
800 cnt++));
801
802 if (pFields[0]->GetBndConditions()[b]->GetUserDefined() ==
803 "WallViscous" ||
804 pFields[0]->GetBndConditions()[b]->GetUserDefined() ==
805 "WallAdiabatic" ||
806 pFields[0]->GetBndConditions()[b]->GetUserDefined() ==
807 "Wall")
808 {
809 Vmath::Vcopy(nBndEdgePts, &traceFieldsAdded[j][id2], 1,
810 &surfaceFieldsAdded[j][id1], 1);
811
812 id1 += nBndEdgePts;
813 }
814 }
815 }
816 }
817 }
818 //===================================================================================================
819 //===================================================================================================
820 //===================================================================================================
821 std::string vEquation = vSession->GetSolverInfo("EQType");
822
824 BndExp = pFields[0]->GetBndCondExpansions();
826
827 NekDouble Fxp(0.0);
828 NekDouble Fyp(0.0);
829 NekDouble Fxv(0.0);
830 NekDouble Fyv(0.0);
831 NekDouble Sref(0.0);
832
833 int GlobalIndex(0);
834
835 for (int i = 0; i < BndExp[0]->GetExpSize(); ++i)
836 {
837 bc = BndExp[0]->GetExp(i)->as<LocalRegions::Expansion1D>();
838
839 int nbc = bc->GetTotPoints();
840
841 Array<OneD, NekDouble> nxOnBnd(nbc, 0.0);
842 Array<OneD, NekDouble> nyOnBnd(nbc, 0.0);
843 Array<OneD, NekDouble> txOnBnd(nbc, 0.0);
844 Array<OneD, NekDouble> tyOnBnd(nbc, 0.0);
845 // Array<OneD, NekDouble> CoeffAero(nbc,0.0);
846 // Array<OneD, NekDouble> tmp(nbc,0.0);
847
848 Array<OneD, NekDouble> drag_p(nbc, 0.0);
849 Array<OneD, NekDouble> lift_p(nbc, 0.0);
850 Array<OneD, NekDouble> PressurOnBnd(nbc, 0.0);
851
852 Array<OneD, NekDouble> drag_v(nbc, 0.0);
853 Array<OneD, NekDouble> lift_v(nbc, 0.0);
854 Array<OneD, NekDouble> ShearStressOnBnd(nbc, 0.0);
855
856 Array<OneD, NekDouble> Unity(nbc, 1.0);
857
858 for (int j = 0; j < nbc; ++j)
859 {
860
861 nxOnBnd[j] = surfaceFieldsAdded[0][GlobalIndex];
862 nyOnBnd[j] = surfaceFieldsAdded[1][GlobalIndex];
863 txOnBnd[j] = surfaceFieldsAdded[2][GlobalIndex];
864 tyOnBnd[j] = surfaceFieldsAdded[3][GlobalIndex];
865
866 PressurOnBnd[j] = surfaceFieldsAdded[4][GlobalIndex];
867
868 if (vEquation == "NavierStokesCFE")
869 {
870 ShearStressOnBnd[j] = surfaceFieldsAdded[17][GlobalIndex];
871 }
872
873 // CoeffAero[j] = surfaceFields[0][GlobalIndex];
874 // tmp[j] =
875 // surfaceFields[1][GlobalIndex]*surfaceFields[1][GlobalIndex];
876 // tmp[j] = tmp[j] +
877 // surfaceFields[2][GlobalIndex]*surfaceFields[2][GlobalIndex];
878 // tmp[j] = sqrt(tmp[j]);
879 // CoeffAero[j] = CoeffAero[j]*tmp[j];
880 // CoeffAero[j] = 1.0/CoeffAero[j];
881 //
882 // PressurOnBnd[j] =
883 // CoeffAero[j]*surfaceFieldsAdded[4][GlobalIndex];
884 //
885 // cout << "CoeffAero = " << CoeffAero[j] << endl;
886
887 GlobalIndex++;
888 }
889
890 Vmath::Vmul(nbc, PressurOnBnd, 1, nxOnBnd, 1, drag_p, 1);
891 Vmath::Vmul(nbc, PressurOnBnd, 1, nyOnBnd, 1, lift_p, 1);
892
893 // Vmath::Vmul(nbc,drag_p,1,CoeffAero,1, drag_p,1);
894 // Vmath::Vmul(nbc,lift_p,1,CoeffAero,1, lift_p,1);
895
896 Fxp += bc->Integral(drag_p);
897 Fyp += bc->Integral(lift_p);
898
899 if (vEquation == "NavierStokesCFE")
900 {
901 Vmath::Vmul(nbc, ShearStressOnBnd, 1, txOnBnd, 1, drag_v, 1);
902 Vmath::Vmul(nbc, ShearStressOnBnd, 1, tyOnBnd, 1, lift_v, 1);
903
904 // Vmath::Vdiv(nbc,drag_v,1,CoeffAero,1, drag_v,1);
905 // Vmath::Vdiv(nbc,lift_v,1,CoeffAero,1, lift_v,1);
906
907 Fxv += bc->Integral(drag_v);
908 Fyv += bc->Integral(lift_v);
909 }
910
911 Sref += bc->Integral(Unity);
912 }
913
914 cout << "\n Sref = " << Sref << endl;
915 Fxp = Fxp / Sref;
916 Fyp = Fyp / Sref;
917 Fxv = Fxv / Sref;
918 Fyv = Fyv / Sref;
919 cout << " Pressure drag (Fxp) = " << Fxp << endl;
920 cout << " Pressure lift (Fyp) = " << Fyp << endl;
921 cout << " Viscous drag (Fxv) = " << Fxv << endl;
922 cout << " Viscous lift (Fyv) = " << Fyv << endl;
923 cout << "\n ==> Total drag = " << Fxp + Fxv << endl;
924 cout << " ==> Total lift = " << Fyp + Fyv << "\n" << endl;
925
926 //===================================================================================================
927 //===================================================================================================
928 //===================================================================================================
929
930 // Print the surface coordinates and the surface solution in a .txt file
931 ofstream outfile;
932 outfile.open(fname.c_str());
933 outfile << "% x[m] "
934 << " \t"
935 << "y[m] "
936 << " \t"
937 << "z[m] "
938 << " \t"
939 << "nx[] "
940 << " \t"
941 << "ny[] "
942 << " \t"
943 << "tx[] "
944 << " \t"
945 << "ty[] "
946 << " \t"
947 << "rho[kg/m^3] "
948 << " \t"
949 << "rhou[kg/(m^2 s)] "
950 << " \t"
951 << "rhov[kg/(m^2 s)] "
952 << " \t"
953 << "E[Pa] "
954 << " \t"
955 << "p[Pa] "
956 << " \t"
957 << "T[k] "
958 << " \t"
959 << "dT/dn[k/m] "
960 << " \t"
961 << "dp/dT[Pa/m] "
962 << " \t"
963 << "dp/dx[Pa/m] "
964 << " \t"
965 << "dp/dy[Pa/m] "
966 << " \t"
967 << "du/dx[s^-1] "
968 << " \t"
969 << "du/dy[s^-1] "
970 << " \t"
971 << "dv/dx[s^-1] "
972 << " \t"
973 << "dv/dy[s^-1] "
974 << " \t"
975 << "tau_xx[Pa] "
976 << " \t"
977 << "tau_yy[Pa] "
978 << " \t"
979 << "tau_xy[Pa] "
980 << " \t"
981 << "tau_t[Pa] "
982 << " \t"
983 << "mu[Pa s] "
984 << " \t"
985 << "M[] "
986 << " \t"
987 // << "Fxp " << " \t"
988 << endl;
989 for (i = 0; i < id1; ++i)
990 {
991 outfile << scientific << setw(17) << setprecision(16) << surfaceX[i]
992 << " \t " << surfaceY[i] << " \t " << surfaceZ[i] << " \t "
993 << surfaceFieldsAdded[0][i] << " \t "
994 << surfaceFieldsAdded[1][i] << " \t "
995 << surfaceFieldsAdded[2][i] << " \t "
996 << surfaceFieldsAdded[3][i] << " \t " << surfaceFields[0][i]
997 << " \t " << surfaceFields[1][i] << " \t "
998 << surfaceFields[2][i] << " \t " << surfaceFields[3][i]
999 << " \t " << surfaceFieldsAdded[4][i] << " \t "
1000 << surfaceFieldsAdded[5][i] << " \t "
1001 << surfaceFieldsAdded[6][i] << " \t "
1002 << surfaceFieldsAdded[7][i] << " \t "
1003 << surfaceFieldsAdded[8][i] << " \t "
1004 << surfaceFieldsAdded[9][i] << " \t "
1005 << surfaceFieldsAdded[10][i] << " \t "
1006 << surfaceFieldsAdded[11][i] << " \t "
1007 << surfaceFieldsAdded[12][i] << " \t "
1008 << surfaceFieldsAdded[13][i] << " \t "
1009 << surfaceFieldsAdded[14][i] << " \t "
1010 << surfaceFieldsAdded[15][i] << " \t "
1011 << surfaceFieldsAdded[16][i] << " \t "
1012 << surfaceFieldsAdded[17][i] << " \t "
1013 << surfaceFieldsAdded[18][i] << " \t "
1014 << surfaceFieldsAdded[19][i]
1015 << " \t "
1016 // << Fxp << " \t "
1017 << endl;
1018 }
1019 outfile << endl << endl;
1020 outfile.close();
1021
1022 return 0;
1023}
NekDouble m_mu
NekDouble m_Twall
NekDouble m_rhoInf
NekDouble m_vInf
NekDouble m_uInf
#define ASSERTL0(condition, msg)
Definition: ErrorUtil.hpp:208
General purpose memory allocation routines with the ability to allocate from thread specific memory p...
int GetTotPoints() const
This function returns the total number of quadrature points used in the element.
Definition: StdExpansion.h:134
void Import(const std::string &infilename, std::vector< FieldDefinitionsSharedPtr > &fielddefs, std::vector< std::vector< NekDouble > > &fielddata, FieldMetaDataMap &fieldinfomap, const Array< OneD, int > &ElementIDs)
This function allows for data to be imported from an FLD file when a session and/or communicator is n...
Definition: FieldIO.cpp:288
std::map< std::string, std::string > FieldMetaDataMap
Definition: FieldIO.h:50
std::shared_ptr< SessionReader > SessionReaderSharedPtr
@ ePolyEvenlySpaced
1D Evenly-spaced points using Lagrange polynomial
Definition: PointsType.h:73
const std::vector< NekDouble > velocity
std::shared_ptr< ExpList > ExpListSharedPtr
Shared pointer to an ExpList object.
std::shared_ptr< MeshGraph > MeshGraphSharedPtr
Definition: MeshGraph.h:174
std::shared_ptr< StdExpansion1D > StdExpansion1DSharedPtr
std::vector< double > z(NPUPPER)
double NekDouble
void Vsqrt(int n, const T *x, const int incx, T *y, const int incy)
sqrt y = sqrt(x)
Definition: Vmath.hpp:340
void Vmul(int n, const T *x, const int incx, const T *y, const int incy, T *z, const int incz)
Multiply vector z = x*y.
Definition: Vmath.hpp:72
void Neg(int n, T *x, const int incx)
Negate x = -x.
Definition: Vmath.hpp:292
void Vvtvp(int n, const T *w, const int incw, const T *x, const int incx, const T *y, const int incy, T *z, const int incz)
vvtvp (vector times vector plus vector): z = w*x + y
Definition: Vmath.hpp:366
void Vadd(int n, const T *x, const int incx, const T *y, const int incy, T *z, const int incz)
Add vector z = x+y.
Definition: Vmath.hpp:180
void Smul(int n, const T alpha, const T *x, const int incx, T *y, const int incy)
Scalar multiply y = alpha*x.
Definition: Vmath.hpp:100
void Vdiv(int n, const T *x, const int incx, const T *y, const int incy, T *z, const int incz)
Multiply vector z = x/y.
Definition: Vmath.hpp:126
void Fill(int n, const T alpha, T *x, const int incx)
Fill a vector with a constant value.
Definition: Vmath.hpp:54
void Vcopy(int n, const T *x, const int incx, T *y, const int incy)
Definition: Vmath.hpp:825
void Vsub(int n, const T *x, const int incx, const T *y, const int incy, T *z, const int incz)
Subtract vector z = x-y.
Definition: Vmath.hpp:220
scalarT< T > sqrt(scalarT< T > in)
Definition: scalar.hpp:294

References ASSERTL0, Nektar::LibUtilities::ePolyEvenlySpaced, Vmath::Fill(), Nektar::StdRegions::StdExpansion::GetTotPoints(), Nektar::LibUtilities::Import(), m_mu, m_rhoInf, m_Twall, m_uInf, m_vInf, Vmath::Neg(), CellMLToNektar.cellml_metadata::p, CG_Iterations::pressure, CellMLToNektar.translators::run(), Vmath::Smul(), tinysimd::sqrt(), Vmath::Vadd(), Vmath::Vcopy(), Vmath::Vdiv(), Nektar::MovementTests::velocity, Vmath::Vmul(), Vmath::Vsqrt(), Vmath::Vsub(), Vmath::Vvtvp(), and Nektar::UnitTests::z().