Nektar++
Loading...
Searching...
No Matches
FilterLagrangianPoints.cpp
Go to the documentation of this file.
1///////////////////////////////////////////////////////////////////////////////
2//
3// File: FilterLagrangianPoints.cpp
4//
5// For more information, please see: http://www.nektar.info
6//
7// The MIT License
8//
9// Copyright (c) 2006 Division of Applied Mathematics, Brown University (USA),
10// Department of Aeronautics, Imperial College London (UK), and Scientific
11// Computing and Imaging Institute, University of Utah (USA).
12//
13// Permission is hereby granted, free of charge, to any person obtaining a
14// copy of this software and associated documentation files (the "Software"),
15// to deal in the Software without restriction, including without limitation
16// the rights to use, copy, modify, merge, publish, distribute, sublicense,
17// and/or sell copies of the Software, and to permit persons to whom the
18// Software is furnished to do so, subject to the following conditions:
19//
20// The above copyright notice and this permission notice shall be included
21// in all copies or substantial portions of the Software.
22//
23// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
24// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
25// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
26// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
27// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
28// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
29// DEALINGS IN THE SOFTWARE.
30//
31// Description: Evaluate physics values at a set of points.
32//
33///////////////////////////////////////////////////////////////////////////////
34
35#include <iomanip>
36using namespace std;
37
42#include <boost/format.hpp>
43
44namespace Nektar::SolverUtils
45{
46
48 GetFilterFactory().RegisterCreatorFunction("LagrangianPoints",
50
52{
53 for (int d = 0; d < m_dim; ++d)
54 {
55 gcoords[d] = m_coords[0][d][id];
56 }
57}
58
60 const Array<OneD, NekDouble> &gcoords)
61{
62 for (int d = 0; d < m_dim; ++d)
63 {
64 m_coords[0][d][id] = gcoords[d];
65 }
66}
67
69{
70 for (int d = 0; d < m_dim; ++d)
71 {
72 data[d] = m_velocity[0][d][id];
73 }
74}
75
77 const Array<OneD, NekDouble> &data)
78{
79 for (int d = 0; d < m_dim; ++d)
80 {
81 m_velocity[0][d][id] = data[d];
82 }
83 for (size_t d = 0; d < m_extraPhysVars.size(); ++d)
84 {
85 m_extraPhysics[d][id] = data[d + m_dim];
86 }
87}
88
90{
91 int n = data.size();
92 if (n <= 1)
93 {
94 return;
95 }
96 Array<OneD, Array<OneD, NekDouble>> res = data[n - 1];
97 for (int i = n - 1; i > 0; --i)
98 {
99 data[i] = data[i - 1];
100 }
101 data[0] = res;
102}
103
105{
106 order = min(order, m_intOrder);
107 if (order == 1)
108 {
109 for (int d = 0; d < m_dim; ++d)
110 {
111 Vmath::Svtvp(m_totPts, m_dt, m_velocity[0][d], 1, m_coords[0][d], 1,
112 m_coords[0][d], 1);
113 }
115 }
116 else if (order == 2)
117 {
118 for (int d = 0; d < m_dim; ++d)
119 {
121 Vmath::Svtvm(m_totPts, 3., m_velocity[0][d], 1, m_velocity[1][d], 1,
122 res, 1);
123 Vmath::Svtvp(m_totPts, 0.5 * m_dt, res, 1, m_coords[0][d], 1, res,
124 1);
125 }
128 }
129 else
130 {
131 ASSERTL0(false, "Integration order not supported.");
132 }
133}
134
136{
137 if (Np > m_totPts)
138 {
139 for (int i = 0; i < m_coords.size(); ++i)
140 {
141 for (int d = 0; d < m_dim; ++d)
142 {
145 }
146 }
147 }
148 m_totPts = Np;
149 m_localIDToGlobal.clear();
150 m_globalIDToLocal.clear();
151}
152
153static int BinaryWrite(std::ofstream &ofile, std::string str)
154{
155 int tmp = 0;
156 for (size_t i = 0; i < str.size(); ++i)
157 {
158 tmp = str[i];
159 ofile.write((char *)&tmp, 4);
160 }
161 tmp = 0;
162 ofile.write((char *)&tmp, 4);
163 return 4;
164}
165
166static int OutputTec360_binary(const std::string filename,
167 const std::vector<std::string> &variables,
168 const std::vector<int> &rawN,
169 std::vector<Array<OneD, NekDouble>> &data,
170 int isdouble)
171{
172 std::vector<int> N = rawN;
173 for (int i = N.size(); i < 3; ++i)
174 {
175 N.push_back(1);
176 }
177 std::ofstream odata;
178 odata.open(filename, std::ios::binary);
179 if (!odata.is_open())
180 {
181 printf("error unable to open file %s\n", filename.c_str());
182 return -1;
183 }
184 char tecplotversion[] = "#!TDV112";
185 odata.write((char *)tecplotversion, 8);
186 int value1 = 1;
187 odata.write((char *)&value1, 4);
188 int filetype = 0;
189 odata.write((char *)&filetype, 4);
190 // read file title and variable names
191 std::string filetitle = "";
192 BinaryWrite(odata, filetitle);
193 int nvar = variables.size();
194 odata.write((char *)&nvar, 4); // number of variables
195 std::vector<std::string> vartitle;
196 for (int i = 0; i < nvar; ++i)
197 {
198 BinaryWrite(odata, variables[i]);
199 }
200 float zonemarker299I = 299.0f;
201 odata.write((char *)&zonemarker299I, 4);
202 // zone title
203 std::string zonetitle("ZONE 0");
204 BinaryWrite(odata, zonetitle);
205 int parentzone = -1;
206 odata.write((char *)&parentzone, 4);
207 int strandid = -1;
208 odata.write((char *)&strandid, 4);
209 double soltime = 0.0;
210 odata.write((char *)&soltime, 8);
211 int unused = -1;
212 odata.write((char *)&unused, 4);
213 int zonetype = 0;
214 odata.write((char *)&zonetype, 4);
215 int zero = 0;
216 odata.write((char *)&zero, 4);
217 odata.write((char *)&zero, 4);
218 odata.write((char *)&zero, 4);
219 for (int i = 0; i < 3; ++i)
220 {
221 int tmp = N[i];
222 odata.write((char *)&tmp, 4);
223 }
224
225 odata.write((char *)&zero, 4);
226 float eohmarker357 = 357.0f;
227 odata.write((char *)&eohmarker357, 4);
228 float zonemarker299II = 299.0f;
229 odata.write((char *)&zonemarker299II, 4);
230 std::vector<int> binarydatatype(nvar, 1 + (isdouble > 0));
231 odata.write((char *)binarydatatype.data(), 4 * nvar);
232 odata.write((char *)&zero, 4);
233 odata.write((char *)&zero, 4);
234 int minus1 = -1;
235 odata.write((char *)&minus1, 4);
236
237 int datanumber, datasize;
238 datanumber = N[0] * N[1] * N[2];
239 datasize = N[0] * N[1] * N[2] * 4;
240 for (int i = 0; i < nvar; ++i)
241 {
242 double minv = 0., maxv = 1.;
243 for (int p = 0; p < datanumber; ++p)
244 {
245 if (maxv < data[i][p])
246 {
247 maxv = data[i][p];
248 }
249 if (minv > data[i][p])
250 {
251 minv = data[i][p];
252 }
253 }
254 odata.write((char *)&minv, 8);
255 odata.write((char *)&maxv, 8);
256 }
257
258 std::vector<float> vardata(datanumber);
259 for (int i = 0; i < nvar; ++i)
260 {
261 if (isdouble)
262 {
263 odata.write((char *)data[i].data(), datasize * 2);
264 }
265 else
266 {
267 std::vector<float> fdata(datanumber);
268 for (int j = 0; j < datanumber; ++j)
269 {
270 fdata[j] = data[i][j];
271 }
272 odata.write((char *)fdata.data(), datasize);
273 }
274 }
275 odata.close();
276 return 0;
277}
278
280 std::string filename, [[maybe_unused]] bool verbose,
281 std::map<std::string, NekDouble> &params)
282{
283 std::vector<std::string> COORDS = {"x", "y", "z"};
284 std::vector<std::string> VELOCI = {"u", "v", "w"};
285 std::vector<std::string> variables;
286 std::vector<Array<OneD, NekDouble>> data;
287 for (int d = 0; d < m_dim; ++d)
288 {
289 variables.push_back(COORDS[d]);
290 }
291 for (int d = 0; d < m_dim; ++d)
292 {
293 variables.push_back(VELOCI[d]);
294 }
295 if (params.size() > 0)
296 {
297 for (int d = 0; d < m_dim; ++d)
298 {
300 Vmath::Sadd(m_totPts, params[COORDS[d]], m_coords[0][d], 1, x, 1);
301 data.push_back(x);
302 }
303 for (int d = 0; d < m_dim; ++d)
304 {
306 Vmath::Sadd(m_totPts, params[VELOCI[d]], m_velocity[0][d], 1, x, 1);
307 data.push_back(x);
308 }
309 }
310 else
311 {
312 for (int d = 0; d < m_dim; ++d)
313 {
314 data.push_back(m_coords[0][d]);
315 }
316 for (int d = 0; d < m_dim; ++d)
317 {
318 data.push_back(m_velocity[0][d]);
319 }
320 }
321 for (size_t d = 0; d < m_extraPhysics.size(); ++d)
322 {
323 data.push_back(m_extraPhysics[d]);
324 variables.push_back(m_extraPhysVars[d]);
325 }
326 OutputTec360_binary(filename, variables, m_N, data, 1);
327 if (verbose)
328 {
329 cout << "Write file " << filename << endl;
330 }
331}
332
334{
335 int Np = m_coords[0][0].size();
336 std::vector<std::string> COORDS = {"x", "y", "z"};
337 std::vector<std::string> VELOCI = {"u", "v", "w"};
338 for (int d = 0; d < m_dim; ++d)
339 {
340 NekDouble value = 0.;
341 for (int i = 0; i < Np; ++i)
342 {
343 value += m_coords[0][d][i] * m_coords[0][d][i];
344 }
345 value = sqrt(value / Np);
346 cout << "L 2 error (variable L" << COORDS[d] << ") : " << value << endl;
347 }
348 for (int d = 0; d < m_dim; ++d)
349 {
350 NekDouble value = 0.;
351 for (int i = 0; i < Np; ++i)
352 {
353 value += m_velocity[0][d][i] * m_velocity[0][d][i];
354 }
355 value = sqrt(value / Np);
356 cout << "L 2 error (variable L" << VELOCI[d] << ") : " << value << endl;
357 }
358}
359
361 const Array<OneD, NekDouble> &gcoords)
362{
363 StationaryPoints::v_AssignPoint(id, pid, gcoords);
364 for (int d = 0; d < m_dim; ++d)
365 {
366 m_coords[0][d][id] = gcoords[d];
367 }
368}
369
370StatLagrangianPoints::StatLagrangianPoints([[maybe_unused]] int rank, int dim,
371 int intOrder, int idOffset,
372 NekDouble dt,
373 const std::vector<int> &Np,
374 const std::vector<NekDouble> &Box,
375 std::vector<std::string> extraVars)
376{
377 m_idOffset = idOffset;
378 m_dim = dim;
379 if (intOrder < 0)
380 {
381 m_intOrder = -intOrder;
382 m_dt = -dt;
383 }
384 else
385 {
386 m_intOrder = intOrder;
387 m_dt = dt;
388 }
389 if (Np.size() < m_dim || Box.size() < m_dim * 2)
390 {
391 throw ErrorUtil::NekError("Not enough input for StationaryPoints.");
392 }
393 Array<OneD, NekDouble> delta(3, 1.);
394 m_N.resize(3, 1);
395 m_totPts = 1;
396 for (int d = 0; d < m_dim; ++d)
397 {
398 m_N[d] = Np[d];
399 m_totPts *= Np[d];
400 delta[d] = Np[d] < 2 ? 1. : (Box[d * 2 + 1] - Box[d * 2]) / (Np[d] - 1);
401 }
404 for (int i = 0; i < m_intOrder; ++i)
405 {
408 for (int d = 0; d < m_dim; ++d)
409 {
412 }
413 }
415 for (size_t i = 0; i < extraVars.size(); ++i)
416 {
417 m_extraPhysVars.push_back(extraVars[i]);
419 }
420 // initialise points
421 int count = 0;
422 for (int k = 0; k < m_N[2]; ++k)
423 {
424 for (int j = 0; j < m_N[1]; ++j)
425 {
426 for (int i = 0; i < m_N[0]; ++i)
427 {
428 if (m_dim > 0)
429 {
430 m_coords[0][0][count] = Box[0] + delta[0] * i;
431 }
432 if (m_dim > 1)
433 {
434 m_coords[0][1][count] = Box[2] + delta[1] * j;
435 }
436 if (m_dim > 2)
437 {
438 m_coords[0][2][count] = Box[4] + delta[2] * k;
439 }
440 m_localIDToGlobal[count] = m_idOffset + count;
441 m_globalIDToLocal[m_idOffset + count] = count;
442 ++count;
443 }
444 }
445 }
446}
447
448/**
449 *
450 */
453 const std::shared_ptr<EquationSystem> &pEquation,
454 const std::map<std::string, std::string> &pParams)
455 : Filter(pSession, pEquation), v_params(pParams)
456{
457}
458
459/**
460 *
461 */
466
467/**
468 *
469 */
472 const NekDouble &time)
473{
474 auto it = v_params.find("DefaultValues");
475 if (it != v_params.end())
476 {
478 }
480 NekDouble dt;
481 m_session->LoadParameter("TimeStep", dt);
482
483 it = v_params.find("FrameVelocity");
484 if (it != v_params.end())
485 {
486 std::vector<std::string> strs;
487 ParseUtils::GenerateVector(it->second, strs);
488 for (int i = strs.size(); i < m_spacedim; ++i)
489 {
490 strs.push_back("0");
491 }
492 for (int i = 0; i < m_spacedim; ++i)
493 {
496 pFields[0]->GetSession()->GetInterpreter(), strs[i]);
497 }
498 }
499
500 it = v_params.find("FrameDisplacement");
501 if (it != v_params.end())
502 {
503 std::vector<std::string> strs;
504 ParseUtils::GenerateVector(it->second, strs);
505 for (int i = strs.size(); i < m_spacedim; ++i)
506 {
507 strs.push_back("0");
508 }
509 for (int i = 0; i < m_spacedim; ++i)
510 {
513 pFields[0]->GetSession()->GetInterpreter(), strs[i]);
514 }
515 }
516
517 int intOrder = 1;
518 it = v_params.find("IntOrder");
519 if (it != v_params.end())
520 {
521 LibUtilities::Equation equ(m_session->GetInterpreter(), it->second);
522 intOrder = round(equ.Evaluate());
523 }
524 if (intOrder == 0)
525 {
526 intOrder = 1;
527 m_isMovablePoints = false;
528 }
529 else
530 {
531 m_isMovablePoints = true;
532 }
533
534 it = v_params.find("RootOutputL2Norm");
535 if (it != v_params.end())
536 {
537 std::string value = it->second;
538 m_outputL2Norm = m_rank == 0 && (value == "1" || value == "Yes");
539 }
540 else
541 {
542 m_outputL2Norm = false;
543 }
544
545 it = v_params.find("OutputFile");
546 std::string outputFilename;
547 if (it == v_params.end())
548 {
549 outputFilename = m_session->GetSessionName();
550 }
551 else
552 {
553 ASSERTL0(it->second.length() > 0, "Missing parameter 'OutputFile'.");
554 outputFilename = it->second;
555 }
556 m_outputFile = outputFilename + "_R%05d_T%010.6lf.plt";
557
558 // OutputFrequency
559 it = v_params.find("OutputFrequency");
560 if (it == v_params.end())
561 {
563 }
564 else
565 {
566 LibUtilities::Equation equ(m_session->GetInterpreter(), it->second);
567 m_outputFrequency = round(equ.Evaluate());
568 }
569
570 it = v_params.find("OutputSampleFrequency");
571 if (it == v_params.end())
572 {
574 }
575 else
576 {
577 LibUtilities::Equation equ(m_session->GetInterpreter(), it->second);
578 m_outputSampleFrequency = round(equ.Evaluate());
579 }
580
581 it = v_params.find("Box_" + std::to_string(m_rank));
582 if (it != v_params.end())
583 {
584 std::vector<NekDouble> values;
585 ParseUtils::GenerateVector(it->second, values);
586 if (values.size() < m_spacedim * 3 + 1)
587 {
589 "Box formate error "
590 "(offset,Nx,Ny,Nx,xmin,xmax,ymin,ymax,zmin,zmax): " +
591 it->second);
592 }
593 m_frame.Update(time);
594 std::vector<int> Np(m_spacedim, 1);
595 m_box.resize(2 * m_spacedim, 0.);
596 int idOffset = std::round(values[0]);
597 for (int d = 0; d < m_spacedim; ++d)
598 {
599 Np[d] = std::round(values[d + 1]);
600 }
601 for (int d = 0; d < 2 * m_spacedim; ++d)
602 {
603 m_box[d] = values[1 + d + m_spacedim] - m_frame.m_frameDisp[d / 2];
604 }
605 std::vector<std::string> extraVars;
606 ExtraPhysicsVars(extraVars);
608 m_rank, m_spacedim, intOrder, idOffset, dt, Np, m_box, extraVars);
610
611 it = v_params.find("OutputSamplePoints");
612 std::vector<unsigned int> samplepts;
613 if (it != v_params.end())
614 {
615 ParseUtils::GenerateSeqVector(it->second, samplepts);
616 }
617 std::set<int> sampleIds(samplepts.begin(), samplepts.end());
618 it = v_params.find("OutputSamplePointsCondition");
619 LibUtilities::EquationSharedPtr sampleCondition;
620 if (it != v_params.end())
621 {
622 sampleCondition =
624 pFields[0]->GetSession()->GetInterpreter(), it->second);
625 }
626
627 for (int p = 0; p < m_staticPts->GetTotPoints(); ++p)
628 {
630 m_staticPts->GetCoords(p, data);
631 int globalId = m_staticPts->LocalToGlobal(p);
632 NekDouble x = data[0] + m_frame.m_frameDisp[0],
633 y = data[1] + m_frame.m_frameDisp[1];
634 NekDouble z =
635 m_spacedim > 2 ? data[2] : 0. + m_frame.m_frameDisp[2];
636 bool issample =
637 (sampleCondition == nullptr)
638 ? false
639 : (sampleCondition->Evaluate(x, y, z, time) > 0);
640 if (sampleIds.find(globalId) != sampleIds.end() || issample)
641 {
642 m_samplePointIDs.insert(globalId);
643 }
644 }
645 }
646 if (!m_samplePointIDs.empty())
647 {
648 std::string sampleFilename = outputFilename + "_Sample_R%05d.dat";
649 boost::format filename(sampleFilename);
650 filename % m_rank;
651 m_ofstreamSamplePoints.open(filename.str(), std::ofstream::out);
652 std::vector<std::string> COORDS = {"x", "y", "z"};
653 std::vector<std::string> VELOCI = {"u", "v", "w"};
654 m_ofstreamSamplePoints << "variables = pid, time ";
655 for (int d = 0; d < m_spacedim; ++d)
656 {
657 m_ofstreamSamplePoints << COORDS[d] << " ";
658 }
659 for (int d = 0; d < m_spacedim; ++d)
660 {
661 m_ofstreamSamplePoints << VELOCI[d] << " ";
662 }
664 }
667 {
668 v_Update(pFields, time);
669 }
670}
671
673 [[maybe_unused]] Array<OneD, NekDouble> gcoords,
674 [[maybe_unused]] NekDouble time, Array<OneD, NekDouble> vel)
675{
676 if (m_frame.m_frameVelFunction.size() > 0)
677 {
678 for (int i = 0; i < m_spacedim; ++i)
679 {
680 vel[i] -= m_frame.m_frameVel[i];
681 }
682 }
683}
684
686 std::vector<std::string> &extraVars)
687{
688 if (m_spacedim == 2)
689 {
690 extraVars.push_back("u_x");
691 extraVars.push_back("u_y");
692 extraVars.push_back("v_x");
693 extraVars.push_back("v_y");
694 extraVars.push_back("LW_z");
695 }
696 else if (m_spacedim == 3)
697 {
698 extraVars.push_back("u_x");
699 extraVars.push_back("u_y");
700 extraVars.push_back("u_z");
701 extraVars.push_back("v_x");
702 extraVars.push_back("v_y");
703 extraVars.push_back("v_z");
704 extraVars.push_back("w_x");
705 extraVars.push_back("w_y");
706 extraVars.push_back("w_z");
707 extraVars.push_back("LW_x");
708 extraVars.push_back("LW_y");
709 extraVars.push_back("LW_z");
710 }
711}
712
715 std::vector<Array<OneD, NekDouble>> &PhysicsData)
716{
717 int npts = pFields[0]->GetTotPoints();
718 for (int i = 0; i < m_spacedim; ++i)
719 {
720 PhysicsData.push_back(pFields[i]->UpdatePhys());
721 }
722 int offset = PhysicsData.size();
723 for (int d = 0; d < m_spacedim; ++d)
724 {
726 for (int i = 0; i < m_spacedim; ++i)
727 {
728 data[i] = Array<OneD, NekDouble>(npts, 0.);
729 }
730 if (m_spacedim == 2)
731 {
732 pFields[d]->PhysDeriv(pFields[d]->UpdatePhys(), data[0], data[1]);
733 }
734 else if (m_spacedim == 3)
735 {
736 pFields[d]->PhysDeriv(pFields[d]->UpdatePhys(), data[0], data[1],
737 data[2]);
738 }
739 for (int i = 0; i < m_spacedim; ++i)
740 {
741 PhysicsData.push_back(data[i]);
742 }
743 }
744 int vortexdim = m_spacedim == 3 ? 3 : 1;
745 Array<OneD, Array<OneD, NekDouble>> vorticity(vortexdim);
746 Array<OneD, Array<OneD, NekDouble>> Ldata(vortexdim);
748 Array<OneD, NekDouble> temps(npts, 0.);
749 for (int d = 0; d < vortexdim; ++d)
750 {
751 Ldata[d] = Array<OneD, NekDouble>(npts, 0.);
752 vorticity[d] = Array<OneD, NekDouble>(npts, 0.);
753 }
754 for (int d = 0; d < m_spacedim; ++d)
755 {
756 temp[d] = Array<OneD, NekDouble>(npts, 0.);
757 }
758 if (m_spacedim == 2)
759 {
760 // 0 ux, 1 uy, 2 vx, 3 vy
761 Vmath::Vsub(npts, PhysicsData[offset + 2], 1, PhysicsData[offset + 1],
762 1, vorticity[0], 1); // vx-uy
763 }
764 else if (m_spacedim == 3)
765 {
766 // 0 ux, 1 uy, 2 uz, 3 vx, 4 vy, 5 vz, 6 wx, 7 wy, 8 wz
767 Vmath::Vsub(npts, PhysicsData[offset + 7], 1, PhysicsData[offset + 5],
768 1, vorticity[0], 1); // wy-vz
769 Vmath::Vsub(npts, PhysicsData[offset + 2], 1, PhysicsData[offset + 6],
770 1, vorticity[1], 1); // uz-wx
771 Vmath::Vsub(npts, PhysicsData[offset + 3], 1, PhysicsData[offset + 1],
772 1, vorticity[2], 1); // vx-uy
773 }
774 for (int d = 0; d < vortexdim; ++d)
775 {
776 if (m_spacedim == 2)
777 {
778 pFields[0]->PhysDeriv(vorticity[d], temp[0], temp[1]);
779 }
780 else if (m_spacedim == 3)
781 {
782 pFields[0]->PhysDeriv(vorticity[d], temp[0], temp[1], temp[2]);
783 }
784 for (int j = 0; j < m_spacedim; ++j)
785 {
786 pFields[0]->PhysDeriv(j, temp[j], temps);
787 Vmath::Vadd(npts, temps, 1, Ldata[d], 1, Ldata[d], 1);
788 }
789 PhysicsData.push_back(Ldata[d]);
790 }
791}
792
795 const NekDouble &time)
796{
797 if (m_isMovablePoints || m_index == 0)
798 {
799 PartitionMobilePts(pFields);
800 }
801 std::vector<Array<OneD, NekDouble>> PhysicsData;
802 GetPhysicsData(pFields, PhysicsData);
803 m_frame.Update(time);
804 EvaluateMobilePhys(pFields[0], PhysicsData, time);
805 std::map<int, std::set<int>> callbackUpdateMobCoords;
806 PassMobilePhysToStatic(callbackUpdateMobCoords);
807 // output Lagrangian coordinates
808
809 if (m_index % m_outputFrequency == 0 && m_staticPts != nullptr)
810 {
811 OutputStatPoints(time);
812 if (m_outputL2Norm)
813 {
814 m_staticPts->OutputError();
815 }
816 }
817
818 // output sample points
819 if (m_index % m_outputSampleFrequency == 0 && !m_samplePointIDs.empty())
820 {
821 OutputSamplePoints(time);
822 }
823 // update Lagrangian coordinates
825 {
826 if (m_staticPts != nullptr)
827 {
828 m_staticPts->TimeAdvance(m_index + 1);
829 }
830 // return the updated global coordinates to mobile points
831 PassStaticCoordsToMobile(callbackUpdateMobCoords);
832 }
833 ++m_index;
834}
835
837{
838 m_ofstreamSamplePoints << "ZONE T=\"" << time
839 << "\", I=" << m_samplePointIDs.size() << endl;
840 for (auto &pid : m_samplePointIDs)
841 {
842 m_ofstreamSamplePoints << pid << " " << time << " ";
844 m_staticPts->GetCoordsByPID(pid, data);
845 for (int d = 0; d < m_spacedim; ++d)
846 {
847 m_ofstreamSamplePoints << data[d] + m_frame.m_frameDisp[d] << " ";
848 }
849 m_staticPts->GetPhysicsByPID(pid, data);
850 for (int d = 0; d < m_spacedim; ++d)
851 {
852 m_ofstreamSamplePoints << data[d] + m_frame.m_frameVel[d] << " ";
853 }
855 }
856}
857
859{
860 boost::format filename(m_outputFile);
861 filename % m_rank % time;
862 std::map<std::string, NekDouble> params;
863 if (m_frame.m_frameVelFunction.size())
864 {
865 std::vector<std::string> COORDS = {"x", "y", "z"};
866 std::vector<std::string> VELOCI = {"u", "v", "w"};
867 for (auto it : m_frame.m_frameVelFunction)
868 {
869 params[VELOCI[it.first]] = m_frame.m_frameVel[it.first];
870 }
871 for (auto it : m_frame.m_frameDispFunction)
872 {
873 params[COORDS[it.first]] = m_frame.m_frameDisp[it.first];
874 }
875 }
876 m_staticPts->OutputData(filename.str(), m_outputL2Norm, params);
877}
878
881 &pFields,
882 [[maybe_unused]] const NekDouble &time)
883{
884}
885
887{
888 return true;
889}
890
891} // namespace Nektar::SolverUtils
#define ASSERTL0(condition, msg)
tKey RegisterCreatorFunction(tKey idKey, CreatorFunction classCreator, std::string pDesc="")
Register a class with the factory.
static std::shared_ptr< DataType > AllocateSharedPtr(const Args &...args)
Allocate a shared pointer from the memory pool.
static bool GenerateVector(const std::string &str, std::vector< T > &out)
Takes a comma-separated string and converts it to entries in a vector.
static bool GenerateSeqVector(const std::string &str, std::vector< unsigned int > &out)
Takes a comma-separated compressed string and converts it to entries in a vector.
SOLVER_UTILS_EXPORT void EvaluateMobilePhys(const MultiRegions::ExpListSharedPtr &pField, std::vector< Array< OneD, NekDouble > > &PhysicsData, NekDouble time)
SOLVER_UTILS_EXPORT void Initialise(const Array< OneD, const MultiRegions::ExpListSharedPtr > &pFields, const NekDouble &time, std::vector< std::string > &defaultValues)
SOLVER_UTILS_EXPORT void PassMobilePhysToStatic(std::map< int, std::set< int > > &callbackUpdateMobCoords)
SOLVER_UTILS_EXPORT void PartitionMobilePts(const Array< OneD, const MultiRegions::ExpListSharedPtr > &pFields)
SOLVER_UTILS_EXPORT void SetUpCommInfo()
SOLVER_UTILS_EXPORT void CopyStaticPtsToMobile()
StationaryPointsSharedPtr m_staticPts
SOLVER_UTILS_EXPORT void PassStaticCoordsToMobile(std::map< int, std::set< int > > &callbackUpdateMobCoords)
LibUtilities::SessionReaderSharedPtr m_session
Definition Filter.h:93
static FilterSharedPtr create(const LibUtilities::SessionReaderSharedPtr &pSession, const std::shared_ptr< EquationSystem > &pEquation, const std::map< std::string, std::string > &pParams)
void v_Update(const Array< OneD, const MultiRegions::ExpListSharedPtr > &pFields, const NekDouble &time) override
void ExtraPhysicsVars(std::vector< std::string > &extraVars)
struct Nektar::SolverUtils::FilterLagrangianPoints::MovingFrame m_frame
std::map< std::string, std::string > v_params
void v_Finalise(const Array< OneD, const MultiRegions::ExpListSharedPtr > &pFields, const NekDouble &time) override
SOLVER_UTILS_EXPORT void v_Initialise(const Array< OneD, const MultiRegions::ExpListSharedPtr > &pFields, const NekDouble &time) override
SOLVER_UTILS_EXPORT FilterLagrangianPoints(const LibUtilities::SessionReaderSharedPtr &pSession, const std::shared_ptr< EquationSystem > &pEquation, const std::map< std::string, std::string > &pParams)
void v_ModifyVelocity(Array< OneD, NekDouble > gcoords, NekDouble time, Array< OneD, NekDouble > vel) override
void GetPhysicsData(const Array< OneD, const MultiRegions::ExpListSharedPtr > &pFields, std::vector< Array< OneD, NekDouble > > &PhysicsData)
StatLagrangianPoints(int rank, int dim, int intOrder, int idOffset, NekDouble dt, const std::vector< int > &Np, const std::vector< NekDouble > &Box, std::vector< std::string > extraVars)
void v_GetCoords(int pid, Array< OneD, NekDouble > &gcoords) override
void v_SetPhysics(int pid, const Array< OneD, NekDouble > &data) override
void v_OutputData(std::string filename, bool verbose, std::map< std::string, NekDouble > &params) override
void v_SetCoords(int pid, const Array< OneD, NekDouble > &gcoords) override
void v_GetPhysics(int pid, Array< OneD, NekDouble > &data) override
Array< OneD, Array< OneD, NekDouble > > m_extraPhysics
Array< OneD, Array< OneD, Array< OneD, NekDouble > > > m_velocity
void v_AssignPoint(int id, int pid, const Array< OneD, NekDouble > &gcoords) override
Array< OneD, Array< OneD, Array< OneD, NekDouble > > > m_coords
virtual void v_AssignPoint(int id, int pid, const Array< OneD, NekDouble > &gcoords)
std::shared_ptr< SessionReader > SessionReaderSharedPtr
std::shared_ptr< Equation > EquationSharedPtr
Definition Equation.h:131
static void RollOver(Array< OneD, Array< OneD, Array< OneD, NekDouble > > > &data)
static int OutputTec360_binary(const std::string filename, const std::vector< std::string > &variables, const std::vector< int > &rawN, std::vector< Array< OneD, NekDouble > > &data, int isdouble)
FilterFactory & GetFilterFactory()
static int BinaryWrite(std::ofstream &ofile, std::string str)
void Svtvp(int n, const T alpha, const T *x, const int incx, const T *y, const int incy, T *z, const int incz)
Svtvp (scalar times vector plus vector): z = alpha*x + y.
Definition Vmath.hpp:396
void Svtvm(int n, const T alpha, const T *x, const int incx, const T *y, const int incy, T *z, const int incz)
Svtvm (scalar times vector minus vector): z = alpha*x - y.
Definition Vmath.hpp:424
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 Sadd(int n, const T alpha, const T *x, const int incx, T *y, const int incy)
Add vector y = alpha + x.
Definition Vmath.hpp:194
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
STL namespace.
scalarT< T > min(scalarT< T > lhs, scalarT< T > rhs)
Definition scalar.hpp:300
scalarT< T > sqrt(scalarT< T > in)
Definition scalar.hpp:290
std::map< int, LibUtilities::EquationSharedPtr > m_frameVelFunction
std::map< int, LibUtilities::EquationSharedPtr > m_frameDispFunction