MAIA bb96820c
Multiphysics at AIA
Loading...
Searching...
No Matches
fvstructuredpostprocessing.cpp
Go to the documentation of this file.
1// Copyright (C) 2024 The m-AIA AUTHORS
2//
3// This file is part of m-AIA (https://git.rwth-aachen.de/aia/m-AIA/m-AIA)
4//
5// SPDX-License-Identifier: LGPL-3.0-only
6
8
9#include "fvstructuredcell.h"
10#include "fvstructuredsolver.h"
11#include "globals.h"
12
13using namespace std;
14
25template <MInt nDim, class SolverType>
27 TRACE();
39template <MInt nDim, class SolverType>
41 TRACE();
43 if(m_postprocessing) {
44 if(m_noPostprocessingOps > 0)
45 for(MInt op = 0; op < m_noPostprocessingOps; op++) {
46 switch(string2enum(m_postprocessingOps[op])) {
55 mDeallocate(m_summedVars);
56 mDeallocate(m_square);
57 if(m_useKahan) {
58 mDeallocate(m_cSum);
59 mDeallocate(m_ySum);
60 mDeallocate(m_tSum);
61
62 mDeallocate(m_cSquare);
63 mDeallocate(m_ySquare);
64 mDeallocate(m_tSquare);
66 if(m_kurtosis) {
67 mDeallocate(m_cCube);
68 mDeallocate(m_yCube);
69 mDeallocate(m_tCube);
70
71 mDeallocate(m_cFourth);
72 mDeallocate(m_yFourth);
73 mDeallocate(m_tFourth);
74 } else if(m_skewness) {
75 mDeallocate(m_cCube);
76 mDeallocate(m_yCube);
77 mDeallocate(m_tCube);
78 }
79 }
80 if(m_kurtosis) {
81 mDeallocate(m_cube);
82 mDeallocate(m_fourth);
83 } else if(m_skewness) {
84 mDeallocate(m_cube);
85 }
86 break;
87 }
89 mDeallocate(m_production);
90 break;
91 }
93 mDeallocate(m_dissipation);
94 break;
95 }
99 break;
100 }
101 default: {
102 mTerm(1, AT_, "Unknown postprocessing operation");
103 }
104 }
105 }
106 delete[] m_postprocessingOps;
107 }
108}
109
110template <MInt nDim, class SolverType>
112 TRACE();
113
114
115 m_movingGrid = false;
116 m_movingGrid = Context::getSolverProperty<MBool>("movingGrid", ppsolver()->solverId(), AT_, &m_movingGrid);
117
118
131 m_postprocessing = false;
132 m_postprocessing =
133 Context::getSolverProperty<MBool>("postprocessing", ppsolver()->solverId(), AT_, &m_postprocessing);
134
148 m_averageVorticity = 0;
149 m_averageVorticity =
150 Context::getSolverProperty<MBool>("pp_averageVorticity", ppsolver()->solverId(), AT_, &m_averageVorticity);
151
152 m_skewness = false;
153 m_skewness = Context::getSolverProperty<MBool>("pp_skewness", ppsolver()->solverId(), AT_, &m_skewness);
154
167 m_kurtosis = false;
168 m_kurtosis = Context::getSolverProperty<MBool>("pp_kurtosis", ppsolver()->solverId(), AT_, &m_kurtosis);
169 if(m_kurtosis) m_skewness = 1;
170
183 m_computeProductionTerms = false;
184 m_computeProductionTerms = Context::getSolverProperty<MBool>(
185 "pp_turbulentProduction", ppsolver()->solverId(), AT_, &m_computeProductionTerms);
186
187 // if(m_kurtosis==1 || m_skewness==1)
188 // mTerm(1,AT_,"check fvsolver and all computations because pressure ampl was introduced at position 11");
189
203 m_twoPass = false;
204 m_twoPass = Context::getSolverProperty<MBool>("pp_twoPass", ppsolver()->solverId(), AT_, &m_twoPass);
205
219 m_useKahan = false;
220 m_useKahan = Context::getSolverProperty<MBool>("pp_useKahan", ppsolver()->solverId(), AT_, &m_useKahan);
221
235 m_postprocessFileName = "";
236 m_postprocessFileName =
237 Context::getSolverProperty<MString>("pp_fileName", ppsolver()->solverId(), AT_, &m_postprocessFileName);
238
239 // Init vars
240 m_averageInterval = 0;
241 m_averageRestart = 0;
242 m_averageRestartInterval = 0;
243 m_averageStartTimestep = 0;
244 m_averageStopTimestep = 0;
245 m_noPostprocessingOps = 0;
246 m_noSamples = 0;
247
248 m_noVariables = ppsolver()->noVariables();
249
250 if(m_postprocessing) {
251 for(MInt i = 0; i < 3; i++) {
252 tvecpost tmp;
253 vector<MString> st;
254 m_postprocessingMethods.push_back(tmp);
255 m_postprocessingMethodsDesc.push_back(st);
256 }
257
274 m_noPostprocessingOps = Context::propertyLength("postprocessingOps", ppsolver()->solverId());
275 m_postprocessingOps = nullptr;
276 if(m_noPostprocessingOps > 0) {
277 // mAlloc( m_postprocessingOps, m_noPostprocessingOps, "m_postprocessingOps", AT_ );
278 m_postprocessingOps = new MString[m_noPostprocessingOps];
279 for(MInt op = 0; op < m_noPostprocessingOps; op++) {
280 m_postprocessingOps[op] = Context::getSolverProperty<MString>(
281 "postprocessingOps", ppsolver()->solverId(), AT_, &m_postprocessingOps[op], op);
282
283 switch(string2enum(m_postprocessingOps[op])) {
284 case PP_AVERAGE_IN: {
285 m_postprocessingMethodsDesc[1].push_back(m_postprocessingOps[op]);
286 m_postprocessingMethods[1].push_back(&StructuredPostprocessing::averageSolutionsInSolve);
287 initAverageIn();
288 initAverageVariables();
289 break;
290 }
291 case PP_AVERAGE_PRE: {
292 m_postprocessingMethodsDesc[0].push_back(m_postprocessingOps[op]);
293 m_postprocessingMethods[0].push_back(&StructuredPostprocessing::averageSolutions);
294 initTimeStepProperties();
295 initAverageVariables();
296 break;
297 }
298 case PP_AVERAGE_POST: {
299 m_postprocessingMethodsDesc[2].push_back(m_postprocessingOps[op]);
300 m_postprocessingMethods[2].push_back(&StructuredPostprocessing::averageSolutions);
301 initTimeStepProperties();
302 initAverageVariables();
303 break;
304 }
306 m_postprocessingMethodsDesc[0].push_back(m_postprocessingOps[op]);
307 m_postprocessingMethods[0].push_back(&StructuredPostprocessing::loadAveragedSolution);
308 initTimeStepProperties();
309 initAverageVariables();
310 break;
311 }
313 m_postprocessingMethodsDesc[0].push_back(m_postprocessingOps[op]);
314 m_postprocessingMethods[0].push_back(&StructuredPostprocessing::computeProductionTerms);
315 initProductionVariables();
316 break;
317 }
319 m_postprocessingMethodsDesc[0].push_back(m_postprocessingOps[op]);
320 m_postprocessingMethods[0].push_back(&StructuredPostprocessing::computeDissipationTerms);
321 initDissipationVariables();
322 break;
323 }
324 case PP_TAUW_PRE: {
325 m_postprocessingMethodsDesc[0].push_back(m_postprocessingOps[op]);
326 m_postprocessingMethods[0].push_back(&StructuredPostprocessing::computeAverageSkinFriction);
327 initTimeStepProperties();
328 initAverageVariables();
329 break;
330 }
332 m_postprocessingMethodsDesc[0].push_back(m_postprocessingOps[op]);
333 m_postprocessingMethods[0].push_back(&StructuredPostprocessing::subtractPeriodicFluctuations);
334
335 mAlloc(m_spanAvg, m_noVariables, ppsolver()->getNoCells(), "m_spanAvg", F0, FUN_);
336 initTimeStepProperties();
337 initAverageVariables();
338 break;
339 }
340 case PP_SUBTRACT_MEAN: {
341 m_postprocessingMethodsDesc[0].push_back(m_postprocessingOps[op]);
342 m_postprocessingMethods[0].push_back(&StructuredPostprocessing::subtractMean);
343 initTimeStepProperties();
344 initAverageVariables();
345 break;
346 }
347 case PP_WRITE_GRADIENTS: {
348 m_postprocessingMethodsDesc[0].push_back(m_postprocessingOps[op]);
349 m_postprocessingMethods[0].push_back(&StructuredPostprocessing::writeGradients);
350 // for 3 dimensions and 9 variables (u,v,w,uu,vv,ww,uv,uw,vw)
351 mAlloc(m_gradients, 3 * 9, ppsolver()->getNoCells(), "m_gradients", F0, FUN_);
352 initTimeStepProperties();
353 initAverageVariables();
354 break;
355 }
356 case PP_DECOMPOSE_CF: {
357 m_postprocessingMethodsDesc[0].push_back(m_postprocessingOps[op]);
358 m_postprocessingMethods[0].push_back(&StructuredPostprocessing::decomposeCfDouble);
359 initTimeStepProperties();
360 initAverageVariables();
361 break;
362 }
364 m_postprocessingMethodsDesc[1].push_back(m_postprocessingOps[op]);
365 m_postprocessingMethods[1].push_back(&StructuredPostprocessing::movingAverage);
366 initTimeStepProperties();
367 initMovingAverage();
368 break;
369 }
371 m_postprocessingMethodsDesc[0].push_back(m_postprocessingOps[op]);
372 m_postprocessingMethods[0].push_back(&StructuredPostprocessing::movingAveragePost);
373 initTimeStepProperties();
374 initMovingAverage();
375 break;
376 }
378 m_postprocessingMethodsDesc[2].push_back(m_postprocessingOps[op]);
379 m_postprocessingMethods[2].push_back(&StructuredPostprocessing::movingAveragePost);
380 initTimeStepProperties();
381 initMovingAverage();
382 break;
383 }
384 default: {
385 mTerm(1, AT_, "Unknown postprocessing operation");
386 }
387 }
388 }
389 }
390 }
391}
392
398template <MInt nDim, class SolverType>
400 TRACE();
401
402 if(m_averageRestart) {
403 m_restartTimeStep = ppsolver()->m_restartTimeStep;
404 }
405
406 if(m_noPostprocessingOps != 0 && m_postprocessing == 1) {
407 for(MInt op = 0; op < m_noPostprocessingOps; op++) {
408 switch(string2enum(m_postprocessingOps[op])) {
409 case PP_AVERAGE_POST:
410 case PP_AVERAGE_PRE:
411 case PP_AVERAGE_IN: {
412 // load the averaging restart
413 if(m_restartTimeStep > m_averageStartTimestep && m_restartTimeStep <= m_averageStopTimestep) {
414 MString name = ppsolver()->outputDir() + "PostprocessingRestart_";
415 MChar buf1[10];
416 MChar buf2[10];
417 sprintf(buf1, "%d", m_averageStartTimestep);
418 sprintf(buf2, "%d", m_restartTimeStep);
419 name.append(buf1);
420 name += "-";
421 name.append(buf2);
422 name.append(ppsolver()->m_outputFormat);
423
424 m_log << "\n\n"
425 << " ^^^^^^^^^^^^^^^ Entering postprocessing mode PreInit ^^^^^^^^^^^^^^^^ \n"
426 << " ^ - Loading restart for mean flow calculation: " << name << "\n"
427 << " ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ \n\n";
428
429 ppsolver()->loadAverageRestartFile(name.c_str(), m_summedVars, m_square, m_cube, m_fourth);
430 }
431 break;
432 }
433 case PP_SUBTRACT_MEAN: {
434 if(ppsolver()->domainId() == 0) {
435 cout << "Subtracting mean from restart file" << endl;
436 }
437
438 break;
439 }
440 default: {
441 // has to be filled
442 }
443 }
444 }
445 }
446}
447
448template <MInt nDim, class SolverType>
450 TRACE();
451
452 if(m_noPostprocessingOps != 0 && m_postprocessing == 1) {
453 m_log << "\n\n"
454 << " ^^^^^^^^^^^^^^^ Entering postprocessing mode PreSolve ^^^^^^^^^^^^^^^ \n"
455 << " ^ - Activated operations are:\n";
456 for(MInt op = 0; op < m_noPostprocessingOps; op++)
457 m_log << " ^ + " << m_postprocessingOps[op] << "\n";
458 m_log << " ^ - Running:\n";
459
460 for(MInt op = 0; op < (signed)m_postprocessingMethods[0].size(); op++) {
461 m_log << " ^ + " << m_postprocessingMethodsDesc[0][op] << "\n";
462 (this->*(m_postprocessingMethods[0][op]))();
463 }
464 m_log << " ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ \n" << endl;
465 }
466}
467
468template <MInt nDim, class SolverType>
470 TRACE();
471
472 if(m_noPostprocessingOps != 0 && m_postprocessing == 1) {
473 for(MInt op = 0; op < (signed)m_postprocessingMethods[1].size(); op++) {
474 (this->*(m_postprocessingMethods[1][op]))();
475 }
476 }
477}
478
479template <MInt nDim, class SolverType>
481 TRACE();
482
483 if(m_noPostprocessingOps != 0 && m_postprocessing == 1) {
484 m_log << "\n\n"
485 << " ^^^^^^^^^^^^^^^ Entering postprocessing mode PostSolve ^^^^^^^^^^^^^^^ \n"
486 << " ^ - Activated operations are:\n\n";
487 for(MInt op = 0; op < m_noPostprocessingOps; op++)
488 m_log << " ^ + " << m_postprocessingOps[op] << "\n";
489 m_log << " ^ - Running:\n";
490
491 for(MInt op = 0; op < (signed)m_postprocessingMethods[2].size(); op++) {
492 m_log << " ^ + " << m_postprocessingMethodsDesc[2][op] << "\n";
493 (this->*(m_postprocessingMethods[2][op]))();
494 }
495 m_log << " ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ \n" << endl;
496 }
497}
498
499
506template <MInt nDim, class SolverType>
508 // Average only at the right timestep
509 if(globalTimeStep >= m_averageStartTimestep && globalTimeStep <= m_averageStopTimestep) {
510 if((globalTimeStep - m_averageStartTimestep) % m_averageInterval == 0) {
511 if(!ppsolver()->isTravelingWave()) {
512 addAveragingSample();
513 } else {
514 ppsolver()->spanwiseWaveReorder();
515 addTempWaveSample();
516 if(ppsolver()->domainId() == 0) {
517 cout << ">>>>> wave sample with interval " << m_averageInterval
518 << " time steps at time step: " << globalTimeStep << " has been added <<<<<" << endl;
519 }
520 }
521 }
522 }
523
524 // Compute the averaged solution and write to file
525 if(globalTimeStep == m_averageStopTimestep) {
526 saveAveragedSolution(globalTimeStep);
527 }
528}
529
542template <MInt nDim, class SolverType>
544 TRACE();
545 const MInt noCells = ppsolver()->getNoCells();
546 const MInt noAveragedVorticities = (m_averageVorticity != 0) * (nDim * 2 - 3);
547
548 for(MInt cellId = 0; cellId < noCells; cellId++) {
549 MInt offset = 0;
550 MInt offsetSquare = 0;
551 // Primitive variables
552 for(MInt varId = 0; varId < m_noVariables; varId++) {
553 m_summedVars[varId + offset][cellId] += m_tempWaveSample[varId][cellId];
554 }
555 offset += m_noVariables;
556
557 // Favre-averaging
558 if(m_averagingFavre) {
559 const MFloat rho = m_tempWaveSample[nDim][cellId];
560 for(MInt varId = 0; varId < m_noVariables; varId++) {
561 m_favre[varId][cellId] += m_tempWaveSample[varId][cellId] * rho;
562 }
563 }
564
565 // Vorticities
566 if(m_averageVorticity) {
567 for(MInt varId = 0; varId < noAveragedVorticities; varId++) {
568 m_summedVars[varId + offset][cellId] += m_tempWaveSample[varId + offset][cellId];
569 }
570 offset += noAveragedVorticities;
571 }
572
573 // squares of velocity components ( uu, vv, ww )
574 for(MInt varId = 0; varId < nDim; varId++) {
575 m_square[varId + offsetSquare][cellId] += m_tempWaveSample[varId][cellId] * m_tempWaveSample[varId][cellId];
576 }
577 offsetSquare += nDim;
578
579 // product of different velocity componets ( uv, vw, wu )
580 for(MInt varId = 0; varId < 2 * nDim - 3; varId++) {
581 m_square[varId + offsetSquare][cellId] +=
582 m_tempWaveSample[varId % nDim][cellId] * m_tempWaveSample[(varId + 1) % nDim][cellId];
583 }
584 offsetSquare += 2 * nDim - 3;
585
586 // square of pressure (pp)
587 m_square[offsetSquare][cellId] += m_tempWaveSample[nDim + 1][cellId] * m_tempWaveSample[nDim + 1][cellId];
588 offsetSquare += 1;
589
590 // squares of the vorticity
591 if(m_averageVorticity) {
592 for(MInt varId = 0; varId < noAveragedVorticities; varId++) {
593 m_square[offsetSquare + varId][cellId] +=
594 m_tempWaveSample[varId + m_noVariables][cellId] * m_tempWaveSample[varId + m_noVariables][cellId];
595 }
596 offsetSquare += noAveragedVorticities;
597 }
598
599 // third and fouth powers of velocity components (skewness and kurtosis)
600 if(m_kurtosis) {
601 for(MInt varId = 0; varId < nDim; varId++) {
602 m_cube[varId][cellId] += pow(m_tempWaveSample[varId][cellId], 3);
603 m_fourth[varId][cellId] += pow(m_tempWaveSample[varId][cellId], 4);
604 }
605 }
606 // third power if velocity components (skewness)
607 if(m_skewness) {
608 for(MInt varId = 0; varId < nDim; varId++) {
609 m_cube[varId][cellId] += pow(m_tempWaveSample[varId][cellId], 3);
610 }
611 }
612 }
613}
614
615
622template <MInt nDim, class SolverType>
624 TRACE();
625
626 /***********************************************************
627 in properties: solutionInterval has to be equal to pp_averageInterval
628 if using this method.
629 ***********************************************************/
630
631 m_log << " ^ * Averaging solutions ";
632
633
634 // set the summationstart for averaging
635 MFloat avgStart = m_restartTimeStep;
636
637 for(MInt avgTimestep = avgStart; avgTimestep <= m_averageStopTimestep; avgTimestep += m_averageInterval) {
638 // load samples
639 stringstream filename;
640 filename << ppsolver()->outputDir() << avgTimestep << ppsolver()->m_outputFormat;
641 ppsolver()->loadSampleFile(filename.str());
642 ppsolver()->exchange();
643 ppsolver()->applyBoundaryCondition();
644 addAveragingSample();
645
646 // Write average restart file
647 if(m_averageRestartInterval != 0
648 && (avgTimestep >= m_averageStartTimestep && avgTimestep % m_averageRestartInterval == 0
649 && avgTimestep <= m_averageStopTimestep)) {
650 saveAverageRestart();
651 }
652 }
653
654 saveAveragedSolution(m_averageStopTimestep);
655}
656
657template <MInt nDim, class SolverType>
659 TRACE();
660
661 computeAveragedSolution();
662
663 // output filename
664 MString name = ppsolver()->outputDir() + "Mean_";
665 MChar buf1[10];
666 MChar buf2[10];
667 sprintf(buf1, "%d", m_averageStartTimestep);
668 sprintf(buf2, "%d", endTimeStep);
669 name.append(buf1);
670 name += "-";
671 name.append(buf2);
672
673 m_log << " ^ saving averaged variables " << name << endl;
674
675 ppsolver()->saveAveragedVariables(name, getNoPPVars(), m_summedVars);
676}
677
678
691template <MInt nDim, class SolverType>
693 TRACE();
694
695 const MInt noCells = ppsolver()->getNoCells();
696 const MInt noAveragedVorticities = (m_averageVorticity != 0) * (nDim * 2 - 3);
697
698 const MFloat weight = F1 / m_noSamples; // F1/(((m_averageStopTimestep-m_averageStartTimestep)/m_averageInterval)+1);
699 MInt offset = 0;
700 MInt offsetSquare = 0;
701
702 // mean of summed primitive variables
703 for(MInt cellId = 0; cellId < noCells; cellId++) {
704 for(MInt varId = 0; varId < m_noVariables; varId++) {
705 m_summedVars[varId + offset][cellId] *= weight;
706 }
707 }
708 offset += m_noVariables;
709
710 // mean of summed primitive variables
711 if(m_averagingFavre) {
712 for(MInt cellId = 0; cellId < noCells; cellId++) {
713 const MFloat frhom = F1 / m_summedVars[nDim][cellId];
714 for(MInt varId = 0; varId < m_noVariables; varId++) {
715 m_favre[varId][cellId] = m_favre[varId][cellId] * weight * frhom;
716 }
717 }
718 }
719
720 // Weighting of summed vorticity variables -> mean
721 if(m_averageVorticity) {
722 for(MInt cellId = 0; cellId < noCells; cellId++) {
723 for(MInt varId = 0; varId < noAveragedVorticities; varId++) {
724 m_summedVars[varId + offset][cellId] *= weight;
725 }
726 }
727
728 offset += noAveragedVorticities;
729 }
730
731 // compute mean(u'u'),mean(v'v'),mean(w'w') ( e.g.mean(u'u')=mean(u^2)-(u_mean))^2 )
732 for(MInt cellId = 0; cellId < noCells; cellId++) {
733 for(MInt varId = 0; varId < nDim; varId++) {
734 m_summedVars[varId + offset][cellId] =
735 weight * m_square[varId][cellId] - m_summedVars[varId][cellId] * m_summedVars[varId][cellId];
736 }
737 }
738 offset += nDim;
739 offsetSquare += nDim;
740
741
742 // compute mean(u'v'),mean(v'w'),mean(w'u') ( e.g. mean(u'v')=mean(u*v)-u_mean*v_mean )
743 for(MInt cellId = 0; cellId < noCells; cellId++) {
744 for(MInt varId = 0; varId < 2 * nDim - 3; varId++) {
745 m_summedVars[varId + offset][cellId] =
746 weight * m_square[varId + offsetSquare][cellId]
747 - m_summedVars[varId % nDim][cellId] * m_summedVars[(varId + 1) % nDim][cellId];
748 }
749 }
750 offset += 2 * nDim - 3;
751 offsetSquare += 2 * nDim - 3;
752
753 if(m_kurtosis) {
754 // compute skewness and kurtosis of velocity components
755 // e.g. skewness(u) = mean(u^3) - 3*u_mean*mean(u^2) + 2*u_mean^3
756 // e.g. kurtosis(u) = mean(u^4) - 4*u_mean*mean(u^3) + 6*u_mean^2*mean(u^2) - 3*u_mean^4
757 for(MInt cellId = 0; cellId < noCells; cellId++) {
758 for(MInt varId = 0; varId < nDim; varId++) {
759 m_summedVars[varId + offset][cellId] = weight * m_cube[varId][cellId]
760 - 3 * weight * m_summedVars[varId][cellId] * m_square[varId][cellId]
761 + 2 * pow(m_summedVars[varId][cellId], 3);
762
763 m_summedVars[varId + offset + nDim][cellId] =
764 weight * m_fourth[varId][cellId] - 4 * weight * m_cube[varId][cellId] * m_summedVars[varId][cellId]
765 + 6 * weight * m_square[varId][cellId] * m_summedVars[varId][cellId] * m_summedVars[varId][cellId]
766 - 3 * pow(m_summedVars[varId][cellId], 4);
767 }
768 }
769 offset += 2 * nDim;
770
771 } else if(m_skewness) {
772 // compute skewness of velocity components
773 for(MInt cellId = 0; cellId < noCells; cellId++) {
774 for(MInt varId = 0; varId < nDim; varId++) {
775 m_summedVars[varId + offset][cellId] = weight * m_cube[varId][cellId]
776 - 3 * weight * m_summedVars[varId][cellId] * m_square[varId][cellId]
777 + 2 * pow(m_summedVars[varId][cellId], 3);
778 }
779 }
780 offset += nDim;
781 }
782
783 // compute p'*p'
784 for(MInt cellId = 0; cellId < noCells; cellId++) {
785 m_summedVars[offset][cellId] = weight * m_square[offsetSquare][cellId]
786 - m_summedVars[nDim + 1][cellId] * m_summedVars[nDim + 1][cellId]; // pressure
787 }
788 offset += 1;
789 offsetSquare += 1;
790
791 if(m_averageVorticity) {
792 // compute vorticity symmetric rms
793 for(MInt cellId = 0; cellId < noCells; cellId++) {
794 for(MInt varId = 0; varId < nDim; varId++) {
795 m_summedVars[varId + offset][cellId] =
796 weight * m_square[varId + offsetSquare][cellId]
797 - m_summedVars[varId + m_noVariables][cellId] * m_summedVars[varId + m_noVariables][cellId];
798 }
799 }
800
801 offset += noAveragedVorticities;
802 offsetSquare += noAveragedVorticities;
803 }
804
805
806 // add aditional variables here -> otherwise the code for kurtosis will overwrite the summed vars of the new
807 // introduced variables
808}
809
821template <MInt nDim, class SolverType>
823 TRACE();
824
825 m_log << " ^ * Averaging timestep " << globalTimeStep << "\n";
826 m_noSamples++;
827
828 const MInt noCells = ppsolver()->getNoCells();
829 MFloatScratchSpace cellVars(m_noVariables, AT_, "cellVars");
830
831 const MInt noAveragedVorticities = (m_averageVorticity != 0) * (nDim * 2 - 3);
832
833 if(m_averageVorticity) {
834 ppsolver()->computeVorticity();
835 }
836
837 for(MInt cellId = 0; cellId < noCells; cellId++) {
838 /* List of Variables in m_summedVars after following computation
839 0=mean(u) 1=mean(v) 2=mean(w)
840 3=mean(rho) 4=mean(p)
841 5=mean(u'u') 6=mean(v'v') 7=mean(w'w')
842 8=mean(u'v') 9=mean(v'w') 10=mean(w'u')
843 11=skew u 12=skew v 13=skew w
844 14=kurt u 15=kurt v 16=kurt w
845 */
846
847 // Calculation of primitive variables
848 ppsolver()->getSampleVariables(cellId, cellVars.begin());
849
850 if(m_useKahan) { // Kahan summation
851
852 /* Kahan summation pseudocode
853 sum=0; c=0;
854 for i=0 to input.length
855 y = input[i] -c;
856 t = sum + y;
857 c = (t-sum) - y;
858 sum = t;
859 */
860
861 MInt offsetSquare = 0;
862 for(MInt varId = 0; varId < m_noVariables; varId++) { // sum up all primitive variables
863 m_ySum[varId][cellId] = cellVars[varId] - m_cSum[varId][cellId];
864 m_tSum[varId][cellId] = m_summedVars[varId][cellId] + m_ySum[varId][cellId];
865 m_cSum[varId][cellId] = (m_tSum[varId][cellId] - m_summedVars[varId][cellId]) - m_ySum[varId][cellId];
866 m_summedVars[varId][cellId] = m_tSum[varId][cellId];
867 }
868 for(MInt varId = 0; varId < nDim; varId++) { // squares of velocity components (u*u,v*v,w*w)
869 m_ySquare[varId][cellId] = (cellVars[varId] * cellVars[varId]) - m_cSquare[varId][cellId];
870 m_tSquare[varId][cellId] = m_square[varId][cellId] + m_ySquare[varId][cellId];
871 m_cSquare[varId][cellId] = (m_tSquare[varId][cellId] - m_square[varId][cellId]) - m_ySquare[varId][cellId];
872 m_square[varId][cellId] = m_tSquare[varId][cellId];
873 }
874 offsetSquare += 3;
875 for(MInt varId = 0; varId < nDim; varId++) { // products of different velocity components in order (u*v,v*w,w*)
876 m_ySquare[varId + offsetSquare][cellId] =
877 (cellVars[varId % 3] * cellVars[(varId + 1) % 3]) - m_cSquare[varId + offsetSquare][cellId];
878 m_tSquare[varId + offsetSquare][cellId] =
879 m_square[varId + offsetSquare][cellId] + m_ySquare[varId + offsetSquare][cellId];
880 m_cSquare[varId + offsetSquare][cellId] =
881 (m_tSquare[varId + offsetSquare][cellId] - m_square[varId + offsetSquare][cellId])
882 - m_ySquare[varId + offsetSquare][cellId];
883 m_square[varId + offsetSquare][cellId] = m_tSquare[varId + offsetSquare][cellId];
884 }
885 if(m_kurtosis) { // compute third and fourth power of velocity components for skewness and kurtosis
886 for(MInt varId = 0; varId < nDim; varId++) {
887 m_yCube[varId][cellId] = pow(cellVars[varId], 3) - m_cCube[varId][cellId];
888 m_tCube[varId][cellId] = m_cube[varId][cellId] + m_yCube[varId][cellId];
889 m_cCube[varId][cellId] = (m_tCube[varId][cellId] - m_cube[varId][cellId]) - m_yCube[varId][cellId];
890 m_cube[varId][cellId] = m_tCube[varId][cellId];
891
892 m_yFourth[varId][cellId] = pow(cellVars[varId], 4) - m_cFourth[varId][cellId];
893 m_tFourth[varId][cellId] = m_fourth[varId][cellId] + m_yFourth[varId][cellId];
894 m_cFourth[varId][cellId] = (m_tFourth[varId][cellId] - m_fourth[varId][cellId]) - m_yFourth[varId][cellId];
895 m_fourth[varId][cellId] = m_tFourth[varId][cellId];
896 }
897 } else if(m_skewness) { // compute only third power of velocity components for skewness
898 for(MInt varId = 0; varId < nDim; varId++) {
899 m_yCube[varId][cellId] = pow(cellVars[varId], 3) - m_cCube[varId][cellId];
900 m_tCube[varId][cellId] = m_cube[varId][cellId] + m_yCube[varId][cellId];
901 m_cCube[varId][cellId] = (m_tCube[varId][cellId] - m_cube[varId][cellId]) - m_yCube[varId][cellId];
902 m_cube[varId][cellId] = m_tCube[varId][cellId];
903 }
904 }
905
906 } else { // normal summation
907 // Reset offsets
908 MInt offset = 0;
909 MInt offsetSquare = 0;
910
911 // Primitive variables
912 for(MInt varId = 0; varId < m_noVariables; varId++) {
913 m_summedVars[varId + offset][cellId] += cellVars[varId];
914 }
915 offset += m_noVariables;
916
917 // Favre-averaging
918 if(m_averagingFavre) {
919 const MFloat rho = cellVars[nDim];
920 for(MInt varId = 0; varId < m_noVariables; varId++) {
921 m_favre[varId][cellId] += cellVars[varId] * rho;
922 }
923 }
924
925 // Vorticities
926 if(m_averageVorticity) {
927 for(MInt varId = 0; varId < noAveragedVorticities; varId++) {
928 m_summedVars[varId + offset][cellId] += ppsolver()->getSampleVorticity(cellId, varId);
929 }
930 offset += noAveragedVorticities;
931 }
932
933 for(MInt varId = 0; varId < nDim; varId++) { // squares of velocity components (u*u,v*v(,w*w))
934 m_square[varId][cellId] += cellVars[varId] * cellVars[varId];
935 }
936 offsetSquare += nDim;
937 for(MInt varId = 0; varId < 2 * nDim - 3; varId++) { // products of different velocity components
938 // (u*v(,v*w,w*u))
939 m_square[offsetSquare + varId][cellId] += (cellVars[varId % nDim]) * (cellVars[(varId + 1) % nDim]);
940 }
941 offsetSquare += 2 * nDim - 3;
942 m_square[offsetSquare][cellId] += cellVars[nDim + 1] * cellVars[nDim + 1]; // squares of pressure p*p
943 offsetSquare += 1;
944
945 // add aditional variables here -> otherwise the code for kurtosis will overwrite the summed vars of the new
946 // introduced variables
947 // squares of the vorticity
948 if(m_averageVorticity) {
949 for(MInt varId = 0; varId < noAveragedVorticities; varId++) {
950 m_square[offsetSquare + varId][cellId] +=
951 ppsolver()->getSampleVorticity(cellId, varId) * ppsolver()->getSampleVorticity(cellId, varId);
952 }
953 offsetSquare += noAveragedVorticities;
954 }
955
956
957 if(m_kurtosis) { // third and fourth powers of velocity components (skewness and kurtosis)
958 for(MInt varId = 0; varId < nDim; varId++) {
959 m_cube[varId][cellId] += pow(cellVars[varId], 3);
960 m_fourth[varId][cellId] += pow(cellVars[varId], 4);
961 }
962 } else if(m_skewness) { // third powers of velocity components (skewness)
963 for(MInt varId = 0; varId < nDim; varId++) {
964 m_cube[varId][cellId] += pow(cellVars[varId], 3);
965 }
966 }
967 }
968 }
969}
970
986template <MInt nDim, class SolverType>
988 if(ppsolver()->domainId() == 0) {
989 cout << "Loading postprocessing file " << m_postprocessFileName << endl;
990 }
991 if(m_averageRestart) {
992 ppsolver()->loadAverageRestartFile(m_postprocessFileName.c_str(), m_summedVars, m_square, m_cube, m_fourth);
993 computeAveragedSolution();
994 } else {
995 if(ppsolver()->domainId() == 0) {
996 cout << "Loading file " << m_postprocessFileName << endl;
997 }
998 ppsolver()->loadAveragedVariables(m_postprocessFileName.c_str());
999 }
1000
1001 if(ppsolver()->domainId() == 0) {
1002 cout << "Filling ghost-cells..." << endl;
1003 }
1004 vector<MFloat*> ppVariables;
1005 for(MInt var = 0; var < getNoPPVars(); var++) {
1006 ppVariables.push_back(m_summedVars[var]);
1007 }
1008 ppsolver()->gcFillGhostCells(ppVariables);
1009
1010 if(ppsolver()->domainId() == 0) {
1011 cout << "Filling ghost-cells... FINISHED!" << endl;
1012 }
1013
1014 const MInt noCells = ppsolver()->getNoCells();
1015 for(MInt cellId = 0; cellId < noCells; cellId++) {
1016 for(MInt var = 0; var < m_noVariables; var++) {
1017 ppsolver()->saveVarToPrimitive(cellId, var, m_summedVars[var][cellId]);
1018 }
1019 }
1020
1021 ppsolver()->exchange();
1022
1023 if(ppsolver()->isMovingGrid()) {
1024 cout << "Moving grid to correct position!" << endl;
1025 ppsolver()->moveGrid(true, true);
1026 }
1027
1028 ppsolver()->applyBoundaryCondition();
1029
1030 cout << "Computing conservative variables" << endl;
1031 ppsolver()->computeConservativeVariables();
1032}
1033
1042template <MInt nDim, class SolverType>
1044 ppsolver()->saveAuxData();
1045}
1046
1047
1048template <MInt nDim, class SolverType>
1050 if(m_movingGrid) {
1051 if(ppsolver()->domainId() == 0) {
1052 cout << "Moving grid" << endl;
1053 }
1054 ppsolver()->moveGrid(true, true);
1055
1056 if(ppsolver()->domainId() == 0) {
1057 cout << "Subtracting mean" << endl;
1058 }
1059
1060 vector<MFloat*> spanAvgList;
1061
1062 // save summed vars as preparation for spanwise average
1063 for(MInt var = 0; var < m_noVariables; var++) {
1064 for(MInt I = 0; I < ppsolver()->getNoCells(); I++) {
1065 m_spanAvg[var][I] = m_summedVars[var][I];
1066 }
1067 }
1068
1069 for(MInt var = 0; var < m_noVariables; var++) {
1070 spanAvgList.push_back(m_spanAvg[var]);
1071 }
1072
1073 ppsolver()->spanwiseAvgZonal(spanAvgList);
1074
1075 for(MInt var = 0; var < m_noVariables; var++) {
1076 for(MInt I = 0; I < ppsolver()->getNoCells(); I++) {
1077 const MFloat varMean = m_summedVars[var][I];
1078 const MFloat varSpanAvg = m_spanAvg[var][I];
1079 const MFloat varPerFluc = varMean - varSpanAvg;
1080 const MFloat varMeanWOPerFluc = varMean - varPerFluc;
1081 ppsolver()->saveVarToPrimitive(I, var, varMeanWOPerFluc);
1082 }
1083 }
1084 } else {
1085 MFloatScratchSpace cellVars(m_noVariables, AT_, "cellVars");
1086
1087 for(MInt I = 0; I < ppsolver()->getNoCells(); I++) {
1088 ppsolver()->getSampleVariables(I, cellVars.begin());
1089 for(MInt var = 0; var < m_noVariables; var++) {
1090 const MFloat varMean = m_summedVars[var][I];
1091 ppsolver()->saveVarToPrimitive(I, var, varMean);
1092 }
1093 }
1094 }
1095
1096 ppsolver()->exchange();
1097 ppsolver()->applyBoundaryCondition();
1098 ppsolver()->computeConservativeVariables();
1099}
1100
1101
1102template <MInt nDim, class SolverType>
1104 if(m_movingGrid) {
1105 if(ppsolver()->domainId() == 0) {
1106 cout << "Moving grid" << endl;
1107 }
1108 ppsolver()->moveGrid(true, true);
1109 if(ppsolver()->domainId() == 0) {
1110 cout << "Reordering cells" << endl;
1111 }
1112 ppsolver()->spanwiseWaveReorder();
1113 if(ppsolver()->domainId() == 0) {
1114 cout << "Subtracting mean" << endl;
1115 }
1116
1117 for(MInt var = 0; var < m_noVariables; var++) {
1118 for(MInt I = 0; I < ppsolver()->getNoCells(); I++) {
1119 const MFloat varMean = m_summedVars[var][I];
1120 const MFloat varInst = m_tempWaveSample[var][I];
1121 const MFloat varFluc = varInst - varMean;
1122 ppsolver()->saveVarToPrimitive(I, var, varFluc);
1123 }
1124 }
1125 } else {
1126 MFloatScratchSpace cellVars(m_noVariables, AT_, "cellVars");
1127
1128 if(ppsolver()->domainId() == 0) {
1129 cout << "Subtracting mean" << endl;
1130 }
1131 for(MInt I = 0; I < ppsolver()->getNoCells(); I++) {
1132 ppsolver()->getSampleVariables(I, cellVars.begin());
1133 for(MInt var = 0; var < m_noVariables; var++) {
1134 const MFloat varMean = m_summedVars[var][I];
1135 const MFloat varInst = cellVars[var];
1136 const MFloat varFluc = varInst - varMean;
1137 ppsolver()->saveVarToPrimitive(I, var, varFluc);
1138 }
1139 }
1140 }
1141
1142 ppsolver()->exchange();
1143 ppsolver()->applyBoundaryCondition();
1144 ppsolver()->computeConservativeVariables();
1145
1146 ppsolver()->computeLambda2Criterion();
1147 ppsolver()->saveBoxes();
1148}
1149
1150
1159template <MInt nDim, class SolverType>
1161 TRACE();
1162
1163 if(ppsolver()->isMovingGrid()) {
1164 cout << "Moving grid to correct position!" << endl;
1165 ppsolver()->moveGrid(true, true);
1166 }
1167
1168 const MInt noAveragedVorticities = (m_averageVorticity != 0) * (nDim * 2 - 3);
1169 const MInt offset = m_noVariables + noAveragedVorticities;
1170
1171 MFloat* ubar = &m_summedVars[0][0];
1172 MFloat* vbar = &m_summedVars[1][0];
1173 MFloat* wbar = &m_summedVars[2][0];
1174
1175 MFloat* uu = &m_summedVars[offset + 0][0];
1176 MFloat* vv = &m_summedVars[offset + 1][0];
1177 MFloat* ww = &m_summedVars[offset + 2][0];
1178 MFloat* uv = &m_summedVars[offset + 3][0];
1179 MFloat* vw = &m_summedVars[offset + 4][0];
1180 MFloat* uw = &m_summedVars[offset + 5][0];
1181
1182 for(MInt cellId = 0; cellId < ppsolver()->getNoCells(); cellId++) {
1183 m_production[0][cellId] = -uu[cellId] * ppsolver()->dvardxyz(cellId, 0, ubar)
1184 - uv[cellId] * ppsolver()->dvardxyz(cellId, 1, ubar)
1185 - uw[cellId] * ppsolver()->dvardxyz(cellId, 2, ubar);
1186 m_production[1][cellId] = -uv[cellId] * ppsolver()->dvardxyz(cellId, 0, vbar)
1187 - vv[cellId] * ppsolver()->dvardxyz(cellId, 1, vbar)
1188 - vw[cellId] * ppsolver()->dvardxyz(cellId, 2, vbar);
1189 m_production[2][cellId] = -uw[cellId] * ppsolver()->dvardxyz(cellId, 0, wbar)
1190 - vw[cellId] * ppsolver()->dvardxyz(cellId, 1, wbar)
1191 - ww[cellId] * ppsolver()->dvardxyz(cellId, 2, wbar);
1192 }
1193
1194 ppsolver()->saveProductionTerms(m_postprocessFileName.c_str(), m_production);
1195}
1196
1205template <MInt nDim, class SolverType>
1207 TRACE();
1208
1209 if(ppsolver()->isMovingGrid()) {
1210 cout << "Moving grid to correct position!" << endl;
1211 ppsolver()->moveGrid(true, true);
1212 }
1213
1214 MInt noFiles = (m_dissFileEnd - m_dissFileStart) / m_dissFileStep;
1215 MInt noSamples = 0;
1216
1217 if(ppsolver()->domainId() == 0) {
1218 cout << "Computing dissipation..." << endl;
1219 }
1220
1221 MFloatScratchSpace diss1(ppsolver()->getNoCells(), AT_, "diss1");
1222 MFloatScratchSpace diss2(ppsolver()->getNoCells(), AT_, "diss2");
1223
1224 for(MInt n = 0; n < noFiles; n++) {
1225 MInt currentStep = m_dissFileStart + n * m_dissFileStep;
1226 MBool result = ppsolver()->loadBoxFile(m_dissFileDir, m_dissFilePrefix, currentStep, m_dissFileBoxNr);
1227
1228 if(result == false) {
1229 continue;
1230 }
1231 noSamples++;
1232
1233 if(ppsolver()->isMovingGrid()) {
1234 ppsolver()->spanwiseWaveReorder();
1235 if(ppsolver()->domainId() == 0) {
1236 cout << "After spanwise wave reorder" << endl;
1237 }
1238
1239
1240 for(MInt I = 0; I < ppsolver()->getNoCells(); I++) {
1241 for(MInt var = 0; var < 5; var++) {
1242 ppsolver()->setPV(var, I, m_tempWaveSample[var][I]);
1243 }
1244 }
1245 }
1246
1247 ppsolver()->exchange();
1248 ppsolver()->applyBoundaryCondition();
1249
1250 MFloatScratchSpace velFluc(3, ppsolver()->getNoCells(), AT_, "uFluc");
1251
1252 if(ppsolver()->domainId() == 0) {
1253 cout << "Computing fluctuations..." << endl;
1254 }
1255
1256 for(MInt I = 0; I < ppsolver()->getNoCells(); I++) {
1257 for(MInt var = 0; var < 5; var++) {
1258 const MFloat varMean = m_summedVars[var][I];
1259 const MFloat varInst = ppsolver()->getPV(var, I);
1260 const MFloat fluc = varInst - varMean;
1261 ppsolver()->setPV(var, I, fluc);
1262 }
1263 }
1264
1265 ppsolver()->exchange();
1266 ppsolver()->applyBoundaryCondition();
1267
1268 for(MInt I = 0; I < ppsolver()->getNoCells(); I++) {
1269 for(MInt var = 0; var < 3; var++) {
1270 velFluc(var, I) = ppsolver()->getPV(var, I);
1271 }
1272 }
1273
1274 if(ppsolver()->domainId() == 0) {
1275 cout << "Computing strain tensor..." << endl;
1276 }
1277
1278 for(MInt I = 0; I < ppsolver()->getNoCells(); I++) {
1279 for(MInt ii = 0; ii < 3; ii++) {
1280 for(MInt jj = 0; jj < 3; jj++) {
1281 const MFloat sij = ppsolver()->dvardxyz(I, jj, &velFluc(ii, 0));
1282 const MFloat sji = ppsolver()->dvardxyz(I, ii, &velFluc(jj, 0));
1283
1284 diss1[I] += sij * sij;
1285 diss2[I] += sij * sji;
1286 }
1287 }
1288 }
1289 }
1290
1291 for(MInt I = 0; I < ppsolver()->getNoCells(); I++) {
1292 diss1[I] /= noSamples;
1293 diss2[I] /= noSamples;
1294
1295 m_dissipation[I] = diss1[I] + diss2[I];
1296 }
1297
1298 if(ppsolver()->domainId() == 0) {
1299 cout << "Computing dissipation..." << endl;
1300 }
1301
1302 ppsolver()->saveDissipation(m_postprocessFileName.c_str(), m_dissipation);
1303}
1304
1305template <MInt nDim, class SolverType>
1307 TRACE();
1308}
1309
1310template <MInt nDim, class SolverType>
1312 TRACE();
1313}
1314
1315
1316template <MInt nDim, class SolverType>
1318 TRACE();
1319 if(m_movingGrid) {
1320 if(ppsolver()->domainId() == 0) {
1321 cout << "Moving grid" << endl;
1322 }
1323 ppsolver()->moveGrid(true, true);
1324 }
1325
1326 const MInt noVars = 9;
1327 const MInt noCells = ppsolver()->getNoCells();
1328 const MInt noAveragedVorticities = (m_averageVorticity != 0) * (nDim * 2 - 3);
1329 const MInt offset = m_noVariables + noAveragedVorticities;
1330
1331
1332 // spanwise average for all
1333 if(!m_movingGrid) {
1334 vector<MFloat*> spanAvgList;
1335 for(MInt var = 0; var < getNoPPVars(); var++) {
1336 spanAvgList.push_back(m_summedVars[var]);
1337 }
1338
1339 ppsolver()->spanwiseAvgZonal(spanAvgList);
1340 vector<MFloat*> ppVariables;
1341 for(MInt var = 0; var < getNoPPVars(); var++) {
1342 ppVariables.push_back(m_summedVars[var]);
1343 }
1344 ppsolver()->gcFillGhostCells(ppVariables);
1345 }
1346
1347
1348 // first for u,v,w
1349 for(MInt dim = 0; dim < nDim; dim++) {
1350 for(MInt var = 0; var < 3; var++) {
1351 for(MInt cellId = 0; cellId < noCells; cellId++) {
1352 m_gradients[var + dim * noVars][cellId] = ppsolver()->dvardxyz(cellId, dim, m_summedVars[var]);
1353 }
1354 }
1355
1356 // then for uu,vv,ww,uv,uw,vw
1357 for(MInt var = 0; var < 6; var++) {
1358 for(MInt cellId = 0; cellId < noCells; cellId++) {
1359 m_gradients[3 + var + dim * noVars][cellId] = ppsolver()->dvardxyz(cellId, dim, m_summedVars[var + offset]);
1360 }
1361 }
1362 }
1363
1364 MStringScratchSpace gradientNames(27, AT_, "gradientNames");
1365
1366 gradientNames[0] = "dudx";
1367 gradientNames[1] = "dvdx";
1368 gradientNames[2] = "dwdx";
1369 gradientNames[3] = "duudx";
1370 gradientNames[4] = "dvvdx";
1371 gradientNames[5] = "dwwdx";
1372 gradientNames[6] = "duvdx";
1373 gradientNames[7] = "duwdx";
1374 gradientNames[8] = "dvwdx";
1375
1376 gradientNames[9] = "dudy";
1377 gradientNames[10] = "dvdy";
1378 gradientNames[11] = "dwdy";
1379 gradientNames[12] = "duudy";
1380 gradientNames[13] = "dvvdy";
1381 gradientNames[14] = "dwwdy";
1382 gradientNames[15] = "duvdy";
1383 gradientNames[16] = "duwdy";
1384 gradientNames[17] = "dvwdy";
1385
1386 gradientNames[18] = "dudz";
1387 gradientNames[19] = "dvdz";
1388 gradientNames[20] = "dwdz";
1389 gradientNames[21] = "duudz";
1390 gradientNames[22] = "dvvdz";
1391 gradientNames[23] = "dwwdz";
1392 gradientNames[24] = "duvdz";
1393 gradientNames[25] = "duwdz";
1394 gradientNames[26] = "dvwdz";
1395
1396 MString gradientFileName = "meanGradients.hdf5";
1397 ppsolver()->saveGradients(gradientFileName.c_str(), m_gradients, &gradientNames[0]);
1398}
1399
1400template <MInt nDim, class SolverType>
1402 TRACE();
1403 if(m_movingGrid) {
1404 if(ppsolver()->domainId() == 0) {
1405 cout << "Moving grid" << endl;
1406 }
1407 ppsolver()->moveGrid(true, true);
1408 }
1409
1410 const MInt noCells = ppsolver()->getNoCells();
1411 const MInt noAveragedVorticities = (m_averageVorticity != 0) * (nDim * 2 - 3);
1412 const MInt offset = m_noVariables + noAveragedVorticities;
1413
1414 MFloatScratchSpace uTilde(noCells, AT_, "uTilde");
1415 MFloatScratchSpace vTilde(noCells, AT_, "vTilde");
1416 MFloatScratchSpace wTilde(noCells, AT_, "wTilde");
1417 MFloatScratchSpace rhoTilde(noCells, AT_, "rhoTilde");
1418 MFloatScratchSpace pTilde(noCells, AT_, "pTilde");
1419
1420 MFloatScratchSpace uuTilde(noCells, AT_, "uuTilde");
1421 MFloatScratchSpace uvTilde(noCells, AT_, "uvTilde");
1422 MFloatScratchSpace uwTilde(noCells, AT_, "uwTilde");
1423 MFloatScratchSpace mue(noCells, AT_, "mue");
1424
1425 MFloat* const u = &m_summedVars[0][0];
1426 MFloat* const v = &m_summedVars[1][0];
1427 MFloat* const w = &m_summedVars[2][0];
1428 MFloat* const rho = &m_summedVars[3][0];
1429 MFloat* const p = &m_summedVars[4][0];
1430 MFloat* const uu = &m_summedVars[offset][0];
1431 MFloat* const uv = &m_summedVars[offset + 3][0];
1432 MFloat* const uw = &m_summedVars[offset + 4][0];
1433
1434 m_sutherlandConstant = ppsolver()->getSutherlandConstant();
1435 m_sutherlandPlusOne = m_sutherlandConstant + F1;
1436
1437 for(MInt I = 0; I < ppsolver()->getNoCells(); I++) {
1438 const MFloat T = ppsolver()->getGamma() * p[I] / rho[I];
1439 mue[I] = SUTHERLANDLAW(T);
1440 }
1441
1442 uuTilde.fill(F0);
1443 uvTilde.fill(F0);
1444 uwTilde.fill(F0);
1445
1446 if(ppsolver()->domainId() == 0) {
1447 cout << "Computing spanwise average/periodic fluctuations" << endl;
1448 }
1449
1450 if(m_movingGrid) {
1451 MFloatScratchSpace spanAvg(5, noCells, AT_, "spanAvg");
1452
1453 // for moving grid compute spanwise average to compute periodic fluctuations
1454 for(MInt var = 0; var < m_noVariables; var++) {
1455 for(MInt I = 0; I < ppsolver()->getNoCells(); I++) {
1456 spanAvg(var, I) = m_summedVars[var][I];
1457 }
1458 }
1459
1460 vector<MFloat*> spanVariables;
1461 for(MInt var = 0; var < m_noVariables; var++) {
1462 spanVariables.push_back(&spanAvg(var, 0));
1463 }
1464 ppsolver()->spanwiseAvgZonal(spanVariables);
1465 ppsolver()->gcFillGhostCells(spanVariables);
1466
1467 for(MInt I = 0; I < ppsolver()->getNoCells(); I++) {
1468 uTilde[I] = u[I] - spanAvg(0, I);
1469 vTilde[I] = v[I] - spanAvg(1, I);
1470 wTilde[I] = w[I] - spanAvg(2, I);
1471 rhoTilde[I] = rho[I] - spanAvg(3, I);
1472 pTilde[I] = p[I] - spanAvg(4, I);
1473
1474 uuTilde[I] = uTilde[I] * uTilde[I];
1475 uvTilde[I] = uTilde[I] * vTilde[I];
1476 uwTilde[I] = uTilde[I] * wTilde[I];
1477
1478 u[I] = spanAvg(0, I);
1479 v[I] = spanAvg(1, I);
1480 w[I] = spanAvg(2, I);
1481 rho[I] = spanAvg(3, I);
1482 p[I] = spanAvg(4, I);
1483 }
1484 } else {
1485 // for reference case only compute the spanwise average of the summed vars
1486 vector<MFloat*> ppVariables;
1487 for(MInt var = 0; var < getNoPPVars(); var++) {
1488 ppVariables.push_back(m_summedVars[var]);
1489 }
1490 ppsolver()->spanwiseAvgZonal(ppVariables);
1491 ppsolver()->gcFillGhostCells(ppVariables);
1492 }
1493
1494 MFloatScratchSpace dudx(noCells, AT_, "dudx");
1495 MFloatScratchSpace dudy(noCells, AT_, "dudy");
1496 MFloatScratchSpace dudz(noCells, AT_, "dudz");
1497 MFloatScratchSpace dpdx(noCells, AT_, "dpdx");
1498 MFloatScratchSpace duTildedx(noCells, AT_, "duTildedx");
1499 MFloatScratchSpace duTildedy(noCells, AT_, "duTildedy");
1500 MFloatScratchSpace duTildedz(noCells, AT_, "duTildedz");
1501 MFloatScratchSpace dpTildedx(noCells, AT_, "dpTildedx");
1502 MFloatScratchSpace duuTildedx(noCells, AT_, "duuTildedx");
1503 MFloatScratchSpace duwTildedz(noCells, AT_, "duuTildedz");
1504 MFloatScratchSpace duudx(noCells, AT_, "dudx");
1505 MFloatScratchSpace duwdz(noCells, AT_, "dudx");
1506
1507 dudx.fill(F0);
1508 dudy.fill(F0);
1509 dudz.fill(F0);
1510 dpdx.fill(F0);
1511 duTildedx.fill(F0);
1512 duTildedy.fill(F0);
1513 duTildedz.fill(F0);
1514 dpTildedx.fill(F0);
1515 duuTildedx.fill(F0);
1516 duwTildedz.fill(F0);
1517 duudx.fill(F0);
1518 duwdz.fill(F0);
1519
1520 MFloatScratchSpace nududx(noCells, AT_, "nududx");
1521 MFloatScratchSpace nududz(noCells, AT_, "nududz");
1522 MFloatScratchSpace nududxx(noCells, AT_, "nududxx");
1523 MFloatScratchSpace nududzz(noCells, AT_, "nududzz");
1524
1525 nududx.fill(F0);
1526 nududz.fill(F0);
1527 nududxx.fill(F0);
1528 nududzz.fill(F0);
1529
1530 MFloatScratchSpace nuduTildedx(noCells, AT_, "nuduTildedx");
1531 MFloatScratchSpace nuduTildedz(noCells, AT_, "nuduTildedz");
1532 MFloatScratchSpace nuduTildedxx(noCells, AT_, "nuduTildedxx");
1533 MFloatScratchSpace nuduTildedzz(noCells, AT_, "nuduTildedzz");
1534
1535 nuduTildedx.fill(F0);
1536 nuduTildedz.fill(F0);
1537 nuduTildedxx.fill(F0);
1538 nuduTildedzz.fill(F0);
1539
1540 if(ppsolver()->domainId() == 0) {
1541 cout << "Computing gradients" << endl;
1542 }
1543
1544 const MInt noGC = ppsolver()->getNoGhostLayers();
1545
1546 const MInt* nCells = ppsolver()->getCellGrid();
1547 const MInt* nActiveCells = ppsolver()->getActiveCells();
1548 const MInt* nOffsetCells = ppsolver()->getOffsetCells();
1549
1550 for(MInt i = 1; i < nCells[2] - 1; i++) {
1551 for(MInt k = 1; k < nCells[0] - 1; k++) {
1552 for(MInt j = 1; j < nCells[1] - 1; j++) {
1553 const MInt I = i + (j + k * nCells[1]) * nCells[2];
1554 dudx[I] = ppsolver()->dvardxyz(I, 0, u);
1555 dudy[I] = ppsolver()->dvardxyz(I, 1, u);
1556 dudz[I] = ppsolver()->dvardxyz(I, 2, u);
1557 dpdx[I] = ppsolver()->dvardxyz(I, 0, p);
1558
1559 duTildedx[I] = ppsolver()->dvardxyz(I, 0, &uTilde[0]);
1560 duTildedy[I] = ppsolver()->dvardxyz(I, 1, &uTilde[0]);
1561 duTildedz[I] = ppsolver()->dvardxyz(I, 2, &uTilde[0]);
1562 dpTildedx[I] = ppsolver()->dvardxyz(I, 0, &pTilde[0]);
1563
1564 duudx[I] = ppsolver()->dvardxyz(I, 0, uu);
1565 duwdz[I] = ppsolver()->dvardxyz(I, 2, uw);
1566
1567 duuTildedx[I] = ppsolver()->dvardxyz(I, 0, &uuTilde[0]);
1568 duwTildedz[I] = ppsolver()->dvardxyz(I, 2, &uwTilde[0]);
1569
1570 nududx[I] = mue[I] / rho[I] * dudx[I];
1571 nududz[I] = mue[I] / rho[I] * dudz[I];
1572
1573 nuduTildedx[I] = mue[I] / rho[I] * duTildedx[I];
1574 nuduTildedz[I] = mue[I] / rho[I] * duTildedz[I];
1575 }
1576 }
1577 }
1578
1579 if(ppsolver()->domainId() == 0) {
1580 cout << "Computing second order gradients" << endl;
1581 }
1582
1583 for(MInt i = 1; i < nCells[2] - 1; i++) {
1584 for(MInt k = 1; k < nCells[0] - 1; k++) {
1585 for(MInt j = 1; j < nCells[1] - 1; j++) {
1586 const MInt I = i + (j + k * nCells[1]) * nCells[2];
1587 nududxx[I] = ppsolver()->dvardxyz(I, 0, &nududx[0]);
1588 nududzz[I] = ppsolver()->dvardxyz(I, 2, &nududz[0]);
1589
1590 nuduTildedxx[I] = ppsolver()->dvardxyz(I, 0, &nuduTildedx[0]);
1591 nuduTildedzz[I] = ppsolver()->dvardxyz(I, 2, &nuduTildedz[0]);
1592 }
1593 }
1594 }
1595
1596 const MInt globalNoCellsI = ppsolver()->getGrid()->getMyBlockNoCells(2);
1597 const MInt globalNoCellsK = ppsolver()->getGrid()->getMyBlockNoCells(0);
1598 const MInt totalNoCellsIK = globalNoCellsI * globalNoCellsK;
1599
1600 const MInt noDecompVars = 11;
1601 MFloatScratchSpace cfDecomposedLocal(noDecompVars, totalNoCellsIK, AT_, "cfDecomposedLocal");
1602 MFloatScratchSpace cfDecomposedGlobal(noDecompVars, totalNoCellsIK, AT_, "cfDecomposedGlobal");
1603
1604 cfDecomposedLocal.fill(F0);
1605
1606 const MFloat gammaMinusOne = ppsolver()->getGamma() - 1.0;
1607 const MFloat t8 = 1.0 / (1.0 + F1B2 * gammaMinusOne * POW2(ppsolver()->getMa()));
1608 const MFloat u8 = ppsolver()->getMa() * sqrt(t8);
1609
1610 const MFloat fac = 2.0 / (POW3(u8));
1611 const MFloat fre0 = 1.0 / ppsolver()->getRe0();
1612
1613 if(ppsolver()->domainId() == 0) {
1614 cout << "Computing decomposition activeCells[0]: " << nActiveCells[0] << " activeCells[1]: " << nActiveCells[1]
1615 << " activeCells[2]: " << nActiveCells[2] << endl;
1616 cout << "GlobalCellsI: " << globalNoCellsI << endl;
1617 }
1618
1619 for(MInt i = 0; i < nActiveCells[2]; i++) {
1620 for(MInt k = 0; k < nActiveCells[0]; k++) {
1621 for(MInt j = 0; j < nActiveCells[1]; j++) {
1622 const MInt globalId = (i + nOffsetCells[2]) + (k + nOffsetCells[1]) * (globalNoCellsI);
1623 const MInt I = i + noGC + ((j + noGC) + (k + noGC) * nCells[1]) * nCells[2];
1624
1625 const MFloat dy = ppsolver()->getCellLengthY(i + noGC, j + noGC, k + noGC);
1626
1627 cfDecomposedLocal(0, globalId) += fac * fre0 * mue[I] / rho[I] * dudy[I] * dudy[I] * dy;
1628
1629 cfDecomposedLocal(1, globalId) += fac * fre0 * mue[I] / rho[I] * dudy[I] * duTildedy[I] * dy;
1630
1631 cfDecomposedLocal(2, globalId) += fac * (-uv[I] * dudy[I] * dy);
1632
1633 cfDecomposedLocal(3, globalId) += fac * (-uvTilde[I] * dudy[I] * dy);
1634
1635 cfDecomposedLocal(4, globalId) += fac * ((u[I] - u8) * (u[I] * dudx[I] + v[I] * dudy[I] + w[I] * dudz[I]) * dy);
1636
1637 cfDecomposedLocal(5, globalId) +=
1638 fac * ((u[I] - u8) * (u[I] * duTildedx[I] + v[I] * duTildedy[I] + w[I] * duTildedz[I]) * dy);
1639
1640 cfDecomposedLocal(6, globalId) +=
1641 fac * ((u[I] - u8) * (uTilde[I] * dudx[I] + vTilde[I] * dudy[I] + wTilde[I] * dudz[I]) * dy);
1642
1643 cfDecomposedLocal(7, globalId) += fac * (u[I] - u8) * dpdx[I] * dy;
1644
1645 cfDecomposedLocal(8, globalId) += fac * (u[I] - u8) * dpTildedx[I] * dy;
1646
1647 cfDecomposedLocal(9, globalId) -=
1648 fac * (u[I] - u8) * (fre0 * nududxx[I] + fre0 * nuduTildedxx[I] - duuTildedx[I] - duudx[I]) * dy;
1649 cfDecomposedLocal(10, globalId) -=
1650 fac * (u[I] - u8) * (fre0 * nududzz[I] + fre0 * nuduTildedzz[I] - duwTildedz[I] - duwdz[I]) * dy;
1651 }
1652 }
1653 }
1654
1655 if(ppsolver()->domainId() == 0) {
1656 cout << "Before MPI Allreduce" << endl;
1657 }
1658
1659 MPI_Allreduce(&cfDecomposedLocal(0, 0),
1660 &cfDecomposedGlobal(0, 0),
1661 noDecompVars * totalNoCellsIK,
1662 MPI_DOUBLE,
1663 MPI_SUM,
1664 ppsolver()->getCommunicator(),
1665 AT_,
1666 "cfDecomposedLocal",
1667 "cfDecomposedGlobal");
1668
1669 MFloatScratchSpace cfDecomposedLine(noDecompVars, globalNoCellsI, AT_, "cfDecomposedLine");
1670 cfDecomposedLine.fill(F0);
1671
1672 if(ppsolver()->domainId() == 0) {
1673 cout << "Now averaging in spanwise direction, no cells spanwise: " << globalNoCellsK << endl;
1674 }
1675
1676 for(MInt var = 0; var < noDecompVars; var++) {
1677 for(MInt i = 0; i < globalNoCellsI; i++) {
1678 for(MInt k = 0; k < globalNoCellsK; k++) {
1679 const MInt globalId = i + k * globalNoCellsI;
1680 cfDecomposedLine(var, i) += cfDecomposedGlobal(var, globalId);
1681 }
1682 cfDecomposedLine(var, i) /= (MFloat)globalNoCellsK;
1683 }
1684 }
1685
1686 // now write to file
1687 if(ppsolver()->domainId() == 0) {
1688 MString filename = "./cf_decomposed.dat";
1689 FILE* f_forces;
1690 f_forces = fopen(filename.c_str(), "w");
1691 for(MInt i = 0; i < globalNoCellsI; i++) {
1692 for(MInt var = 0; var < noDecompVars; var++) {
1693 fprintf(f_forces, "%f ", cfDecomposedLine(var, i));
1694 }
1695 fprintf(f_forces, "\n");
1696 }
1697 fclose(f_forces);
1698 }
1699
1700 if(ppsolver()->domainId() == 0) {
1701 cout << "Cf decomposition finished!" << endl;
1702 }
1703}
1704
1705
1706template <MInt nDim, class SolverType>
1708 TRACE();
1709 if(m_movingGrid) {
1710 if(ppsolver()->domainId() == 0) {
1711 cout << "Moving grid" << endl;
1712 }
1713 ppsolver()->moveGrid(true, true);
1714 }
1715
1716 const MInt noCells = ppsolver()->getNoCells();
1717 const MInt noAveragedVorticities = (m_averageVorticity != 0) * (nDim * 2 - 3);
1718 const MInt offset = m_noVariables + noAveragedVorticities;
1719
1720 MFloatScratchSpace mue(noCells, AT_, "mue");
1721
1722 MFloat* const u = &m_summedVars[0][0];
1723 MFloat* const v = &m_summedVars[1][0];
1724 MFloat* const w = &m_summedVars[2][0];
1725 MFloat* const rho = &m_summedVars[3][0];
1726 MFloat* const p = &m_summedVars[4][0];
1727 MFloat* const uu = &m_summedVars[offset][0];
1728 MFloat* const uv = &m_summedVars[offset + 3][0];
1729 MFloat* const uw = &m_summedVars[offset + 4][0];
1730
1731 m_sutherlandConstant = ppsolver()->getSutherlandConstant();
1732 m_sutherlandPlusOne = m_sutherlandConstant + F1;
1733
1734 for(MInt I = 0; I < ppsolver()->getNoCells(); I++) {
1735 const MFloat T = ppsolver()->getGamma() * p[I] / rho[I];
1736 mue[I] = SUTHERLANDLAW(T);
1737 }
1738
1739 if(!m_movingGrid) {
1740 // for reference case only compute the spanwise average of the summed vars
1741 vector<MFloat*> ppVariables;
1742 for(MInt var = 0; var < getNoPPVars(); var++) {
1743 ppVariables.push_back(m_summedVars[var]);
1744 }
1745 ppsolver()->spanwiseAvgZonal(ppVariables);
1746 ppsolver()->gcFillGhostCells(ppVariables);
1747 }
1748
1749 MFloatScratchSpace dudx(noCells, AT_, "dudx");
1750 MFloatScratchSpace dudy(noCells, AT_, "dudy");
1751 MFloatScratchSpace dudz(noCells, AT_, "dudz");
1752 MFloatScratchSpace dpdx(noCells, AT_, "dpdx");
1753 MFloatScratchSpace duudx(noCells, AT_, "dudx");
1754 MFloatScratchSpace duwdz(noCells, AT_, "dudx");
1755
1756 dudx.fill(F0);
1757 dudy.fill(F0);
1758 dudz.fill(F0);
1759 dpdx.fill(F0);
1760 duudx.fill(F0);
1761 duwdz.fill(F0);
1762
1763 MFloatScratchSpace nududx(noCells, AT_, "nududx");
1764 MFloatScratchSpace nududz(noCells, AT_, "nududz");
1765 MFloatScratchSpace nududxx(noCells, AT_, "nududxx");
1766 MFloatScratchSpace nududzz(noCells, AT_, "nududzz");
1767
1768 nududx.fill(F0);
1769 nududz.fill(F0);
1770 nududxx.fill(F0);
1771 nududzz.fill(F0);
1772
1773 if(ppsolver()->domainId() == 0) {
1774 cout << "Computing gradients" << endl;
1775 }
1776
1777 const MInt noGC = ppsolver()->getNoGhostLayers();
1778
1779 const MInt* nCells = ppsolver()->getCellGrid();
1780 const MInt* nActiveCells = ppsolver()->getActiveCells();
1781 const MInt* nOffsetCells = ppsolver()->getOffsetCells();
1782
1783 for(MInt i = 1; i < nCells[2] - 1; i++) {
1784 for(MInt k = 1; k < nCells[0] - 1; k++) {
1785 for(MInt j = 1; j < nCells[1] - 1; j++) {
1786 const MInt I = i + (j + k * nCells[1]) * nCells[2];
1787 dudx[I] = ppsolver()->dvardxyz(I, 0, u);
1788 dudy[I] = ppsolver()->dvardxyz(I, 1, u);
1789 dudz[I] = ppsolver()->dvardxyz(I, 2, u);
1790 dpdx[I] = ppsolver()->dvardxyz(I, 0, p);
1791
1792 duudx[I] = ppsolver()->dvardxyz(I, 0, uu);
1793 duwdz[I] = ppsolver()->dvardxyz(I, 2, uw);
1794
1795 nududx[I] = mue[I] / rho[I] * dudx[I];
1796 nududz[I] = mue[I] / rho[I] * dudz[I];
1797 }
1798 }
1799 }
1800
1801 if(ppsolver()->domainId() == 0) {
1802 cout << "Computing second order gradients" << endl;
1803 }
1804
1805 for(MInt i = 1; i < nCells[2] - 1; i++) {
1806 for(MInt k = 1; k < nCells[0] - 1; k++) {
1807 for(MInt j = 1; j < nCells[1] - 1; j++) {
1808 const MInt I = i + (j + k * nCells[1]) * nCells[2];
1809 nududxx[I] = ppsolver()->dvardxyz(I, 0, &nududx[0]);
1810 nududzz[I] = ppsolver()->dvardxyz(I, 2, &nududz[0]);
1811 }
1812 }
1813 }
1814
1815 const MInt globalNoCellsI = ppsolver()->getGrid()->getMyBlockNoCells(2);
1816 const MInt globalNoCellsJ = ppsolver()->getGrid()->getMyBlockNoCells(1);
1817 const MInt globalNoCellsK = ppsolver()->getGrid()->getMyBlockNoCells(0);
1818 const MInt totalNoCellsIK = globalNoCellsI * globalNoCellsK;
1819
1820 const MInt noDecompVars = 7;
1821 MFloatScratchSpace cfDecomposedLocal(noDecompVars, totalNoCellsIK, AT_, "cfDecomposedLocal");
1822 MFloatScratchSpace cfDecomposedGlobal(noDecompVars, totalNoCellsIK, AT_, "cfDecomposedGlobal");
1823
1824 cfDecomposedLocal.fill(F0);
1825
1826 const MFloat gammaMinusOne = ppsolver()->getGamma() - 1.0;
1827 const MFloat t8 = 1.0 / (1.0 + F1B2 * gammaMinusOne * POW2(ppsolver()->getMa()));
1828 const MFloat u8 = ppsolver()->getMa() * sqrt(t8);
1829
1830 const MFloat fac = 2.0 / (POW3(u8));
1831 const MFloat fre0 = 1.0 / ppsolver()->getRe0();
1832
1833 if(ppsolver()->domainId() == 0) {
1834 cout << "Computing decomposition activeCells[0]: " << nActiveCells[0] << " activeCells[1]: " << nActiveCells[1]
1835 << " activeCells[2]: " << nActiveCells[2] << endl;
1836 cout << "GlobalCellsI: " << globalNoCellsI << endl;
1837 }
1838
1839 for(MInt i = 0; i < nActiveCells[2]; i++) {
1840 for(MInt k = 0; k < nActiveCells[0]; k++) {
1841 for(MInt j = 0; j < nActiveCells[1]; j++) {
1842 const MInt I = i + noGC + ((j + noGC) + (k + noGC) * nCells[1]) * nCells[2];
1843 const MInt globalId = (i + nOffsetCells[2]) + (k + nOffsetCells[1]) * (globalNoCellsI);
1844 const MFloat dy = ppsolver()->getCellLengthY(i + noGC, j + noGC, k + noGC);
1845
1846 cfDecomposedLocal(0, globalId) += ppsolver()->getCellCoordinate(I, 0);
1847
1848 cfDecomposedLocal(1, globalId) += fac * fre0 * mue[I] / rho[I] * dudy[I] * dudy[I] * dy;
1849
1850 cfDecomposedLocal(2, globalId) += fac * (-uv[I] * dudy[I] * dy);
1851
1852 cfDecomposedLocal(3, globalId) += fac * ((u[I] - u8) * (u[I] * dudx[I] + v[I] * dudy[I] + w[I] * dudz[I]) * dy);
1853
1854 cfDecomposedLocal(4, globalId) += fac * (u[I] - u8) * dpdx[I] * dy;
1855
1856 cfDecomposedLocal(5, globalId) -= fac * (u[I] - u8) * (fre0 * nududxx[I] - duudx[I]) * dy;
1857 cfDecomposedLocal(6, globalId) -= fac * (u[I] - u8) * (fre0 * nududzz[I] - duwdz[I]) * dy;
1858 }
1859 }
1860 }
1861
1862 if(ppsolver()->domainId() == 0) {
1863 cout << "Before MPI Allreduce" << endl;
1864 }
1865
1866 MPI_Allreduce(&cfDecomposedLocal(0, 0),
1867 &cfDecomposedGlobal(0, 0),
1868 noDecompVars * totalNoCellsIK,
1869 MPI_DOUBLE,
1870 MPI_SUM,
1871 ppsolver()->getCommunicator(),
1872 AT_,
1873 "cfDecomposedLocal",
1874 "cfDecomposedGlobal");
1875
1876 MFloatScratchSpace cfDecomposedLine(noDecompVars, globalNoCellsI, AT_, "cfDecomposedLine");
1877 cfDecomposedLine.fill(F0);
1878
1879 if(ppsolver()->domainId() == 0) {
1880 cout << "Now averaging in spanwise direction, no cells spanwise: " << globalNoCellsK << endl;
1881 }
1882
1883 for(MInt var = 0; var < noDecompVars; var++) {
1884 for(MInt i = 0; i < globalNoCellsI; i++) {
1885 for(MInt k = 0; k < globalNoCellsK; k++) {
1886 const MInt globalId = i + k * globalNoCellsI;
1887 cfDecomposedLine(var, i) += cfDecomposedGlobal(var, globalId);
1888 }
1889 cfDecomposedLine(var, i) /= (MFloat)globalNoCellsK;
1890
1891 if(var == 0) {
1892 cfDecomposedLine(var, i) /= (MFloat)globalNoCellsJ;
1893 }
1894 }
1895 }
1896
1897 // now write to file
1898 if(ppsolver()->domainId() == 0) {
1899 MString filename = "./cf_decomposed.dat";
1900 FILE* f_forces;
1901 f_forces = fopen(filename.c_str(), "w");
1902 for(MInt i = 0; i < globalNoCellsI; i++) {
1903 for(MInt var = 0; var < noDecompVars; var++) {
1904 fprintf(f_forces, "%f ", cfDecomposedLine(var, i));
1905 }
1906 fprintf(f_forces, "\n");
1907 }
1908 fclose(f_forces);
1909 }
1910
1911 if(ppsolver()->domainId() == 0) {
1912 cout << "Cf decomposition finished!" << endl;
1913 }
1914}
1915
1925template <MInt nDim, class SolverType>
1927 TRACE();
1928
1929 initTimeStepProperties();
1930
1943 m_averageRestart =
1944 Context::getSolverProperty<MInt>("pp_averageRestart", ppsolver()->solverId(), AT_, &m_averageRestart);
1945
1956 m_averageRestartInterval = Context::getSolverProperty<MInt>(
1957 "pp_averageRestartInterval", ppsolver()->solverId(), AT_, &m_averageRestartInterval);
1958
1971 m_averagingFavre = false;
1972 m_averagingFavre =
1973 Context::getSolverProperty<MBool>("pp_averagingFavre", ppsolver()->solverId(), AT_, &m_averagingFavre);
1974
1975
1976 if(m_averageRestartInterval % ppsolver()->restartInterval() != 0) {
1977 mTerm(1, AT_, "The property 'averageRestartInterval' has to be a multiple of the property 'restartInterval'...");
1978 }
1979}
1980
1990template <MInt nDim, class SolverType>
1992 TRACE();
1993 const MInt noCells = ppsolver()->getNoCells();
1994 const MInt noVars = getNoPPVars();
1995 const MInt noSquareVars = getNoPPSquareVars();
1996
1997 mAlloc(m_summedVars, noVars, noCells, "m_summedVars", F0, FUN_); // +1 for pressure ampl
1998 mAlloc(m_square, noSquareVars, noCells, "m_square", F0, FUN_); // + 1 for pressure ampl
1999
2000 if(m_averagingFavre) {
2001 mAlloc(m_favre, getNoVars(), noCells, "m_favre", F0, FUN_); // for Favre averaging
2002 }
2003
2004 if(m_kurtosis) {
2005 m_log << "Allocating cube and fourth field for kurtosis computation for " << noCells << " cells" << endl;
2006 mAlloc(m_cube, nDim, noCells, "m_cube", F0, FUN_);
2007 mAlloc(m_fourth, nDim, noCells, "m_fourth", F0, FUN_);
2008 } else if(m_skewness /*&& !m_twoPass*/) {
2009 mAlloc(m_cube, nDim, noCells, "m_cube", F0, FUN_);
2010 }
2011
2012 if(m_useKahan) // allocate memory for kahan summation
2013 {
2014 m_log << "m_useKahan is activated" << endl;
2015 mAlloc(m_cSum, m_noVariables + 3 * (nDim - 1), noCells, "m_cSum", F0, FUN_);
2016 mAlloc(m_tSum, m_noVariables + 3 * (nDim - 1), noCells, "m_tSum", F0, FUN_);
2017 mAlloc(m_ySum, m_noVariables + 3 * (nDim - 1), noCells, "m_ySum", F0, FUN_);
2018 mAlloc(m_cSquare, 3 * (nDim - 1), noCells, "m_cSquare", F0, FUN_);
2019 mAlloc(m_tSquare, 3 * (nDim - 1), noCells, "m_tSquare", F0, FUN_);
2020 mAlloc(m_ySquare, 3 * (nDim - 1), noCells, "m_ySquare", F0, FUN_);
2021 if(m_kurtosis) {
2022 mAlloc(m_cCube, nDim, noCells, "m_cCube", F0, FUN_);
2023 mAlloc(m_tCube, nDim, noCells, "m_tCube", F0, FUN_);
2024 mAlloc(m_yCube, nDim, noCells, "m_yCube", F0, FUN_);
2025 mAlloc(m_cFourth, nDim, noCells, "m_cFourth", F0, FUN_);
2026 mAlloc(m_tFourth, nDim, noCells, "m_tFourth", F0, FUN_);
2027 mAlloc(m_yFourth, nDim, noCells, "m_yFourth", F0, FUN_);
2028 } else if(m_skewness) {
2029 mAlloc(m_cCube, nDim, noCells, "m_cCube", F0, FUN_);
2030 mAlloc(m_tCube, nDim, noCells, "m_tCube", F0, FUN_);
2031 mAlloc(m_yCube, nDim, noCells, "m_yCube", F0, FUN_);
2032 }
2033 }
2034
2035 mAlloc(m_avgVariableNames, noVars, "m_avgVariableNames", AT_);
2036 mAlloc(m_avgFavreNames, getNoVars(), "m_avgFavreNames", AT_);
2037
2038
2039 // Mean values
2040 m_avgVariableNames[0] = "um";
2041 m_avgVariableNames[1] = "vm";
2042 IF_CONSTEXPR(nDim == 3) { m_avgVariableNames[2] = "wm"; }
2043 m_avgVariableNames[nDim] = "rhom";
2044 m_avgVariableNames[nDim + 1] = "pm";
2045 MInt offset = m_noVariables;
2046
2047 // Vorticities
2048 if(m_averageVorticity) {
2049 IF_CONSTEXPR(nDim == 3) {
2050 m_avgVariableNames[offset + 0] = "vortxm";
2051 m_avgVariableNames[offset + 1] = "vortym";
2052 m_avgVariableNames[offset + 2] = "vortzm";
2053 offset += 3;
2054 }
2055 else {
2056 m_avgVariableNames[offset + 0] = "vortzm";
2057 offset += 1;
2058 }
2059 }
2060
2061 // reynolds stress components
2062 m_avgVariableNames[offset + 0] = "uu";
2063 m_avgVariableNames[offset + 1] = "vv";
2064 offset += 2;
2065 IF_CONSTEXPR(nDim == 3) {
2066 m_avgVariableNames[offset + 0] = "ww";
2067 m_avgVariableNames[offset + 1] = "uv";
2068 m_avgVariableNames[offset + 2] = "vw";
2069 m_avgVariableNames[offset + 3] = "uw";
2070 offset += 4;
2071 }
2072 else {
2073 m_avgVariableNames[offset + 0] = "uv";
2074 offset += 1;
2075 }
2076
2077 // Skewness variables
2078 if(noVars > m_noVariables + 3 * (nDim - 1) + 1 && m_skewness) {
2079 IF_CONSTEXPR(nDim == 3) {
2080 m_avgVariableNames[offset + 0] = "uuu";
2081 m_avgVariableNames[offset + 1] = "vvv";
2082 m_avgVariableNames[offset + 2] = "www";
2083 offset += 3;
2084 }
2085 else {
2086 m_avgVariableNames[offset + 0] = "uuu";
2087 m_avgVariableNames[offset + 1] = "vvv";
2088 offset += 2;
2089 }
2090 }
2091
2092 // Kurtosis variables
2093 if((noVars > m_noVariables + 3 * (nDim - 1) + nDim + 1) && m_kurtosis) {
2094 IF_CONSTEXPR(nDim == 3) {
2095 m_avgVariableNames[offset + 0] = "uuuu";
2096 m_avgVariableNames[offset + 1] = "vvvv";
2097 m_avgVariableNames[offset + 2] = "wwww";
2098 offset += 3;
2099 }
2100 else {
2101 m_avgVariableNames[offset + 0] = "uuuu";
2102 m_avgVariableNames[offset + 1] = "vvvv";
2103 offset += 2;
2104 }
2105 }
2106
2107 // pressure fluctuation
2108 m_avgVariableNames[offset + 0] = "pp";
2109 offset += 1;
2110
2111 // rms of the vorticities
2112 if(m_averageVorticity) {
2113 IF_CONSTEXPR(nDim == 3) {
2114 m_avgVariableNames[offset + 0] = "vortrmsx";
2115 m_avgVariableNames[offset + 1] = "vortrmsy";
2116 m_avgVariableNames[offset + 2] = "vortrmsz";
2117 offset += 3;
2118 }
2119 else {
2120 m_avgVariableNames[offset + 0] = "vortrmsz";
2121 offset += 1;
2122 }
2123 }
2124
2125 if(m_averagingFavre) {
2126 // Mean values
2127 m_avgFavreNames[0] = "um_favre";
2128 m_avgFavreNames[1] = "vm_favre";
2129 IF_CONSTEXPR(nDim == 3) { m_avgFavreNames[2] = "wm_favre"; }
2130 m_avgFavreNames[nDim] = "rhom_favre";
2131 m_avgFavreNames[nDim + 1] = "pm_favre";
2132 }
2133}
2134
2135template <MInt nDim, class SolverType>
2137 const MInt noCells = ppsolver()->getNoCells();
2138 mAlloc(m_production, nDim, noCells, "m_production", F0, FUN_);
2139}
2140
2141template <MInt nDim, class SolverType>
2143 const MInt noCells = ppsolver()->getNoCells();
2144 mAlloc(m_dissipation, noCells, "m_dissipation", F0, FUN_);
2145
2146
2147 m_dissFileDir = "";
2148 m_dissFileDir = Context::getSolverProperty<MString>("pp_dissFileDir", ppsolver()->solverId(), AT_, &m_dissFileDir);
2149
2150 m_dissFilePrefix = "";
2151 m_dissFilePrefix =
2152 Context::getSolverProperty<MString>("pp_dissFilePrefix", ppsolver()->solverId(), AT_, &m_dissFilePrefix);
2153
2154 m_dissFileBoxNr = 0;
2155 m_dissFileBoxNr = Context::getSolverProperty<MInt>("pp_dissFileBoxNr", ppsolver()->solverId(), AT_, &m_dissFileBoxNr);
2156
2157 m_dissFileStart = -1;
2158 m_dissFileStart = Context::getSolverProperty<MInt>("pp_dissFileStart", ppsolver()->solverId(), AT_, &m_dissFileStart);
2159
2160 m_dissFileStep = -1;
2161 m_dissFileStep = Context::getSolverProperty<MInt>("pp_dissFileStep", ppsolver()->solverId(), AT_, &m_dissFileStep);
2162
2163 m_dissFileEnd = -1;
2164 m_dissFileEnd = Context::getSolverProperty<MInt>("pp_dissFileEnd", ppsolver()->solverId(), AT_, &m_dissFileEnd);
2165}
2166
2167
2179template <MInt nDim, class SolverType>
2181 TRACE();
2182
2194 m_averageInterval = 0;
2195 m_averageInterval =
2196 Context::getSolverProperty<MInt>("pp_averageInterval", ppsolver()->solverId(), AT_, &m_averageInterval);
2197
2198
2199 if(m_averageInterval == 0) {
2200 mTerm(1, AT_, "Please specify the property 'averageInterval' ...");
2201 }
2202
2214 m_averageStartTimestep = -1;
2215 m_averageStartTimestep =
2216 Context::getSolverProperty<MInt>("pp_averageStartTimestep", ppsolver()->solverId(), AT_, &m_averageStartTimestep);
2217
2218 if(m_averageStartTimestep == 0) {
2219 mTerm(1, AT_, "Please specify the property 'averageStartTimestep' ...");
2220 }
2221
2233 m_averageStopTimestep = -1;
2234 m_averageStopTimestep =
2235 Context::getSolverProperty<MInt>("pp_averageStopTimestep", ppsolver()->solverId(), AT_, &m_averageStopTimestep);
2236
2237 if(m_averageStopTimestep == 0) {
2238 mTerm(1, AT_, "Please specify the property 'averageStopTimestep' ...");
2239 }
2240
2253 m_averageRestart = 0;
2254 m_averageRestart =
2255 Context::getSolverProperty<MInt>("pp_averageRestart", ppsolver()->solverId(), AT_, &m_averageRestart);
2256
2257
2268 m_averageRestartInterval = 1000000;
2269 m_averageRestartInterval = Context::getSolverProperty<MInt>(
2270 "pp_averageRestartInterval", ppsolver()->solverId(), AT_, &m_averageRestartInterval);
2271
2283}
2284template <MInt nDim, class SolverType>
2286 TRACE();
2287
2288 const MInt noCells = ppsolver()->getNoCells();
2289
2302 m_movingAvgInterval = 1;
2303 m_movingAvgInterval =
2304 Context::getSolverProperty<MInt>("pp_movingAvgInterval", ppsolver()->solverId(), AT_, &m_movingAvgInterval);
2305 if(m_movingAvgInterval < 1) {
2306 TERMM(1, "m_movingAvgInterval has to be >=1");
2307 }
2308 if(m_averageInterval % m_movingAvgInterval != 0 || m_movingAvgInterval > m_averageInterval) {
2309 TERMM(1, "m_movingAvgInterval has to be a factor of m_averageInterval");
2310 }
2311
2320 m_movingAvgDataPoints =
2321 Context::getSolverProperty<MInt>("pp_movingAvgDataPoints", ppsolver()->solverId(), AT_, &m_movingAvgDataPoints);
2322 if(m_movingAvgDataPoints < 2) {
2323 TERMM(1, "m_movingAvgDataPoints has to be at least 2");
2324 }
2325
2338 m_averageVorticity = 0;
2339 m_averageVorticity =
2340 Context::getSolverProperty<MBool>("pp_averageVorticity", ppsolver()->solverId(), AT_, &m_averageVorticity);
2341
2342 m_movingAvgCounter = 0;
2343
2344 m_movAvgNoVariables = m_noVariables;
2345 if(m_averageVorticity == 1) {
2346 m_movAvgNoVariables += (2 * nDim - 3);
2347 }
2348 mAlloc(m_movAvgVariables, noCells, m_movAvgNoVariables * m_movingAvgDataPoints, "m_movAvgVariables", F0, FUN_);
2349 mAlloc(m_movAvgVarNames, 2 * m_movAvgNoVariables, "m_movAvgVarNames", MString("default"), FUN_);
2350}
2351
2352
2353template <MInt nDim, class SolverType>
2355 TRACE();
2356
2357 if(m_postprocessing && (globalTimeStep >= m_averageStartTimestep && globalTimeStep <= m_averageStopTimestep)) {
2358 MString name = ppsolver()->outputDir() + "PostprocessingRestart_";
2359 MChar buf1[10];
2360 MChar buf2[10];
2361 sprintf(buf1, "%d", m_averageStartTimestep);
2362 sprintf(buf2, "%d", globalTimeStep);
2363 name.append(buf1);
2364 name += "-";
2365 name.append(buf2);
2366 m_log << " ^ saving average restart " << name << endl;
2367
2368 ppsolver()->saveAverageRestart(name, getNoPPVars(), m_summedVars, m_square, m_cube, m_fourth);
2369 }
2370}
2371
2380template <MInt nDim, class SolverType>
2382 TRACE();
2383 MInt c = 0;
2384 if(m_kurtosis)
2385 c = 2;
2386 else if(m_skewness)
2387 c = 1;
2388
2389
2390 // Determine number of averaged variables
2391 // Mean vorticities and symmetric rms components (6 for 3D, 4 for 2D)
2392 const MInt noAveragedVorticities = (m_averageVorticity != 0) * (nDim * 2 - 3);
2393 const MInt noVars = m_noVariables // primitive variables
2394 + noAveragedVorticities // mean vorticities
2395 + 3 * (nDim - 1) // Reynolds stress components
2396 + nDim * c // skewness/kurtosis
2397 + 1 // pressure amplitude p'
2398 + noAveragedVorticities; // rms vorticities
2399
2400 return noVars;
2401}
2402
2411template <MInt nDim, class SolverType>
2413 TRACE();
2414
2415 // Determine number of averaged variables
2416 const MInt noAveragedVorticities = (m_averageVorticity != 0) * (nDim * 2 - 3);
2417 const MInt noVars = 3 * (nDim - 1) // uu,vv,ww,uv,uw,vw
2418 + 1 // pressure amplitude p'
2419 + noAveragedVorticities; // vorticity rms
2420 return noVars;
2421}
2422
2423template <MInt nDim, class SolverType>
2425 TRACE();
2426 const MInt noVars = nDim + 2;
2427 return noVars;
2428}
2429
2430// Explicit instantiations for 2D and 3D
void mAlloc(T *&a, const MLong N, const MString &objectName, MString function)
allocates memory for one-dimensional array 'a' of size N
Definition: alloc.h:173
MBool mDeallocate(T *&a)
deallocates the memory previously allocated for element 'a'
Definition: alloc.h:544
static MInt propertyLength(const MString &name, MInt solverId=m_noSolvers)
Returns the number of elements of a property.
Definition: context.cpp:538
This class is a ScratchSpace.
Definition: scratch.h:758
void fill(T val)
fill the scratch with a given value
Definition: scratch.h:311
iterator begin()
Definition: scratch.h:273
void initAverageVariables()
allocates memory for averageSolutions() and averageSolutionsInSolve()
void computeAverageSkinFriction()
Computes skin friction of an averaged field.
MInt getNoPPSquareVars()
Returns number of pp Square variables.
void loadAveragedSolution()
Loads an averaged file again.
void computeAveragedSolution()
Computes the mean variables from summed vars.
void initTimeStepProperties()
Initializes timestep properties for postprocessing.
void initAverageIn()
Initializes properties for averaging during solver run.
MInt getNoPPVars()
Returns number of postprocessing variables.
void computeProductionTerms()
Computes the production terms from an averaged field.
void addAveragingSample()
Adds one sample to the summedVars.
StructuredPostprocessing()
Constructor for the postprocessing solver.
void computeDissipationTerms()
Computes the production terms from an averaged field.
void addTempWaveSample()
Adds for the travelling wave setups.
~StructuredPostprocessing()
Destructor for the postprocessing solver.
MInt string2enum(MString theString)
This global function translates strings in their corresponding enum values (integer values)....
Definition: enums.cpp:20
@ PP_AVERAGE_IN
Definition: enums.h:129
@ PP_AVERAGE_POST
Definition: enums.h:128
@ PP_COMPUTE_PRODUCTION_TERMS_PRE
Definition: enums.h:162
@ PP_WRITE_GRADIENTS
Definition: enums.h:164
@ PP_TAUW_PRE
Definition: enums.h:158
@ PP_DECOMPOSE_CF
Definition: enums.h:165
@ PP_MOVING_AVERAGE_PRE
Definition: enums.h:136
@ PP_LOAD_AVERAGED_SOLUTION_PRE
Definition: enums.h:161
@ PP_AVERAGE_PRE
Definition: enums.h:127
@ PP_SUBTRACT_PERIODIC_FLUCTUATIONS
Definition: enums.h:159
@ PP_SUBTRACT_MEAN
Definition: enums.h:160
@ PP_MOVING_AVERAGE_POST
Definition: enums.h:137
@ PP_COMPUTE_DISSIPATION_TERMS_PRE
Definition: enums.h:163
@ PP_MOVING_AVERAGE_IN
Definition: enums.h:138
void mTerm(const MInt errorCode, const MString &location, const MString &message)
Definition: functions.cpp:29
constexpr Real POW3(const Real x)
Definition: functions.h:123
constexpr Real POW2(const Real x)
Definition: functions.h:119
MInt globalTimeStep
InfoOutFile m_log
int32_t MInt
Definition: maiatypes.h:62
std::basic_string< char > MString
Definition: maiatypes.h:55
double MFloat
Definition: maiatypes.h:52
bool MBool
Definition: maiatypes.h:58
char MChar
Definition: maiatypes.h:56
int MPI_Allreduce(const void *sendbuf, void *recvbuf, int count, MPI_Datatype datatype, MPI_Op op, MPI_Comm comm, const MString &name, const MString &sndvarname, const MString &rcvvarname)
same as MPI_Allreduce