DNDSR 0.1.0.dev1+gcd065ad
Distributed Numeric Data Structure for CFV
Loading...
Searching...
No Matches
FiniteVolume.cpp
Go to the documentation of this file.
1#include "FiniteVolume.hpp"
2
3#include "Geom/Quadrature.hpp"
4
5namespace DNDS::CFV
6{
8 {
9 this->MakePairDefaultOnCell(cellAtr, "FV::cellAtr");
10#ifdef DNDS_USE_OMP
11# pragma omp parallel for
12#endif
13 for (index iCell = 0; iCell < mesh->NumCellProc(); iCell++)
14 {
15 cellAtr(iCell, 0).intOrder = settings.intOrder;
16 cellAtr(iCell, 0).Order = settings.maxOrder;
17 cellAtr(iCell, 0).NDIFF = this->maxNDOF();
18 cellAtr(iCell, 0).NDOF = this->maxNDOF();
19 }
20 }
21
23 {
24 using namespace Geom;
25 using namespace Geom::Elem;
26 this->MakePairDefaultOnCell(volumeLocal, "FV::volumeLocal");
27
28 sumVolume = 0.0;
31
32#ifdef DNDS_USE_OMP
33# pragma omp parallel for
34#endif
35 for (index iCell = 0; iCell < mesh->NumCellProc(); iCell++)
36 {
37 auto eCell = mesh->GetCellElement(iCell);
38 auto qCellMax = Quadrature{eCell, INT_ORDER_MAX};
39 tSmallCoords coordsCell;
40 mesh->GetCoordsOnCell(iCell, coordsCell);
41 //****** Get Int Point Det and Vol
42 real v{0};
43 { // using more accurate sum volume
44 real v1{0};
45 qCellMax.Integration(
46 v1,
47 [&](auto &vInc, int iG, const tPoint &pParam, const Elem::tD01Nj &DiNj)
48 {
49 tPoint pPhy = Elem::PPhysicsCoordD01Nj(coordsCell, DiNj);
50 real JDet = CellJacobianDet(getDim(), coordsCell, DiNj) * (axisSymmetric ? pPhy(1) : 1.);
51 vInc = 1 * JDet;
52 });
53 v = v1;
54 }
56 {
57 DNDS_assert_info(v >= 0, fmt::format("cell has ill area result, v = {}, cellType {}", v, int(eCell.type)));
58 }
59 else
60 {
61 if (v > 0)
62 ; // good
63 else
64 { // v = std::max(0.0, v);
65 v = std::abs(v);
66 }
67 }
69 volumeLocal[iCell][0] = v;
70
71 if (iCell < mesh->NumCell()) // non-ghost
72#ifdef DNDS_USE_OMP
73# pragma omp critical
74#endif
75 {
76 sumVolume += v;
77 minVolume = std::min(minVolume, v);
78 maxVolume = std::max(maxVolume, v);
79 }
80 }
85 }
86
88 {
89 using namespace Geom;
90 using namespace Geom::Elem;
91 DNDS_assert_info(volumeLocal.father->Size() == mesh->NumCell(), "need to do ConstructCellVolume() first");
92 DNDS_assert_info(cellAtr.father->Size() == mesh->NumCell(), "need to do SetCellAtrBasic() first");
93
94 this->MakePairDefaultOnCell(cellIntJacobiDet, "FV::cellIntJacobiDet");
95#ifdef DNDS_USE_OMP
96# pragma omp parallel for
97#endif
98 for (index iCell = 0; iCell < mesh->NumCellProc(); iCell++)
99 {
100 auto eCell = mesh->GetCellElement(iCell);
101 auto qCell = Quadrature{eCell, GetCellAtr(iCell).intOrder};
102 cellIntJacobiDet.ResizeRow(iCell, qCell.GetNumPoints());
103
104 tSmallCoords coordsCell;
105 mesh->GetCoordsOnCell(iCell, coordsCell);
106 //****** Get Int Point Det and Vol
107 real v{0};
108 qCell.Integration(
109 v,
110 [&](auto &vInc, int iG, const tPoint &pParam, const Elem::tD01Nj &DiNj)
111 {
112 tJacobi J = Elem::ShapeJacobianCoordD01Nj(coordsCell, DiNj);
113 tPoint pPhy = Elem::PPhysicsCoordD01Nj(coordsCell, DiNj);
114 real JDet = CellJacobianDet(getDim(), coordsCell, DiNj);
115 // JDet = std::abs(JDet); // use this to pass check even with bad mesh
116 if (axisSymmetric)
117 JDet *= std::max(verySmallReal, pPhy(1));
118 vInc = 1 * JDet;
119 cellIntJacobiDet(iCell, iG) = JDet;
120 });
121 v = GetCellVol(iCell);
123 {
124 for (int iG = 0; iG < qCell.GetNumPoints(); iG++)
127 fmt::format("cell has ill jacobi det, det/V {}, cellType {}", cellIntJacobiDet(iCell, iG) / v, int(eCell.type)));
128 }
129 else
130 {
131 if ((cellIntJacobiDet[iCell].array() > 0.0).all())
132 ; // good
133 else
134 { // v = std::max(0.0, v);
136 }
137 }
138 for (int iG = 0; iG < qCell.GetNumPoints(); iG++)
140 }
142 }
143
145 {
146 using namespace Geom;
147 using namespace Geom::Elem;
148 DNDS_assert_info(volumeLocal.father->Size() == mesh->NumCell(), "need to do ConstructCellVolume() first");
149 DNDS_assert_info(cellAtr.father->Size() == mesh->NumCell(), "need to do SetCellAtrBasic() first");
150
151 this->MakePairDefaultOnCell(cellIntPPhysics, "FV::cellIntPPhysics");
152#ifdef DNDS_USE_OMP
153# pragma omp parallel for
154#endif
155 for (index iCell = 0; iCell < mesh->NumCellProc(); iCell++)
156 {
157 auto eCell = mesh->GetCellElement(iCell);
158 auto qCell = Quadrature{eCell, GetCellAtr(iCell).intOrder};
159 cellIntPPhysics.ResizeRow(iCell, qCell.GetNumPoints());
160
161 tSmallCoords coordsCell;
162 mesh->GetCoordsOnCell(iCell, coordsCell);
163 //****** Get Int Point Det and PPhy
164 real v{0};
165 qCell.Integration(
166 v,
167 [&](auto &vInc, int iG, const tPoint &pParam, const Elem::tD01Nj &DiNj)
168 {
169 tPoint pPhy = Elem::PPhysicsCoordD01Nj(coordsCell, DiNj);
171 });
172 }
174 }
175
177 {
178 using namespace Geom;
179 using namespace Geom::Elem;
180 DNDS_assert_info(volumeLocal.father->Size() == mesh->NumCell(), "need to do ConstructCellVolume() first");
181 DNDS_assert_info(cellAtr.father->Size() == mesh->NumCell(), "need to do SetCellAtrBasic() first");
182
183 this->MakePairDefaultOnCell(cellBary, "FV::cellBary");
184#ifdef DNDS_USE_OMP
185# pragma omp parallel for
186#endif
187 for (index iCell = 0; iCell < mesh->NumCellProc(); iCell++)
188 {
189 auto eCell = mesh->GetCellElement(iCell);
190 auto qCell = Quadrature{eCell, GetCellAtr(iCell).intOrder};
191 auto qCellMax = Quadrature{eCell, INT_ORDER_MAX};
192
193 tSmallCoords coordsCell;
194 mesh->GetCoordsOnCell(iCell, coordsCell);
195 //****** Get Bary
196 real v{0};
197 tPoint b{0, 0, 0};
198 qCell.Integration(
199 b,
200 [&](auto &vInc, int iG, const tPoint &pParam, const Elem::tD01Nj &DiNj)
201 {
202 tPoint pPhy = Elem::PPhysicsCoordD01Nj(coordsCell, DiNj);
203 real JDet = CellJacobianDet(getDim(), coordsCell, DiNj);
204 // JDet = std::abs(JDet); // use this to pass check even with bad mesh
205 if (axisSymmetric)
206 JDet *= std::max(verySmallReal, pPhy(1));
207 vInc = pPhy * JDet;
208 v += JDet * qCell.GetWeight(iG);
209 });
210 v = GetCellVol(iCell); //! FIX: is this good choice?
211 cellBary[iCell] = b / v;
212 }
213 }
214
216 {
217 using namespace Geom;
218 using namespace Geom::Elem;
219
220 this->MakePairDefaultOnCell(cellCent, "FV::cellCent");
221#ifdef DNDS_USE_OMP
222# pragma omp parallel for
223#endif
224 for (index iCell = 0; iCell < mesh->NumCellProc(); iCell++)
225 {
226 auto eCell = mesh->GetCellElement(iCell);
227 auto qCellO1 = Quadrature{eCell, 1};
228
229 tSmallCoords coordsCell;
230 mesh->GetCoordsOnCell(iCell, coordsCell);
231 //****** Get Int Point Det and PPhy
232 SummationNoOp noOp;
233 qCellO1.Integration(
234 noOp,
235 [&](auto &vInc, int iG, const tPoint &pParam, const Elem::tD01Nj &DiNj)
236 {
237 tPoint pPhy = Elem::PPhysicsCoordD01Nj(coordsCell, DiNj);
239 });
240 }
241 }
242
244 {
245 using namespace Geom;
246 using namespace Geom::Elem;
247 DNDS_assert_info(cellBary.father->Size() == mesh->NumCell(), "need to do ConstructCellBary() first");
248
249 this->MakePairDefaultOnCell(cellAlignedHBox, "FV::cellAlignedHBox");
250#ifdef DNDS_USE_OMP
251# pragma omp parallel for
252#endif
253 for (index iCell = 0; iCell < mesh->NumCellProc(); iCell++)
254 {
255 auto eCell = mesh->GetCellElement(iCell);
256 auto qCell = Quadrature{eCell, GetCellAtr(iCell).intOrder};
257 auto qCellMax = Quadrature{eCell, INT_ORDER_MAX};
258
259 tSmallCoords coordsCell;
260 mesh->GetCoordsOnCell(iCell, coordsCell);
261 //****** Get HBox aligned
262 tSmallCoords coordsCellC = coordsCell.colwise() - this->GetCellBary(iCell);
263 DNDS_assert(coordsCellC.cols() == coordsCell.cols());
264 tPoint hBox = coordsCellC.array().abs().rowwise().maxCoeff();
265 if (getDim() == 2)
266 hBox(2) = 1;
268 }
269 }
270
272 {
273 using namespace Geom;
274 using namespace Geom::Elem;
275
276 this->MakePairDefaultOnCell(cellMajorHBox, "FV::cellMajorHBox");
277 this->MakePairDefaultOnCell(cellMajorCoord, "FV::cellMajorCoord", 3, 3);
278 this->MakePairDefaultOnCell(cellInertia, "FV::cellInertia", 3, 3);
279 DNDS_assert_info(cellBary.father->Size() == mesh->NumCell(), "need to do ConstructCellBary() first");
280
281#ifdef DNDS_USE_OMP
282# pragma omp parallel for
283#endif
284 for (index iCell = 0; iCell < mesh->NumCellProc(); iCell++)
285 {
286 auto eCell = mesh->GetCellElement(iCell);
287 auto qCellMax = Quadrature{eCell, INT_ORDER_MAX};
288
289 tSmallCoords coordsCell;
290 mesh->GetCoordsOnCell(iCell, coordsCell);
291 //****** Get Int Point Det and Vol
293 tSmallCoords coordsCellC = coordsCell.colwise() - this->GetCellBary(iCell);
294 DNDS_assert(coordsCellC.cols() == coordsCell.cols());
295
296 //****** Get Major Axis
297 tJacobi inertia;
298 inertia.setZero();
299 qCellMax.Integration(
300 inertia,
301 [&](auto &vInc, int iG, const tPoint &pParam, const Elem::tD01Nj &DiNj)
302 {
303 tPoint pPhy = Elem::PPhysicsCoordD01Nj(coordsCell, DiNj);
304 real JDet = CellJacobianDet(getDim(), coordsCell, DiNj) * (axisSymmetric ? 1 /* using geometrical */ : 1.);
305 tPoint pPhyC = (pPhy - GetCellBary(iCell));
306 vInc = (pPhyC * pPhyC.transpose()) * JDet;
307 });
308 inertia /= this->GetCellVol(iCell);
309 real inerNorm = inertia.norm();
310 real inerCond = 1;
311 if (getDim() == 2)
313 else
315
316 if (inerCond < 1 + smallReal)
317 {
318 inertia(0, 0) += inerNorm * smallReal * 10;
319 inertia(1, 1) += inerNorm * smallReal;
320 }
321
323 tJacobi decRet;
324 decRet.setIdentity();
325 if (getDim() == 3)
327 else
330 tSmallCoords coordsCellM = cellMajorCoord[iCell].transpose() * coordsCellC;
331 tPoint hBoxM = coordsCellM.array().abs().rowwise().maxCoeff();
332 if (getDim() == 2)
333 hBoxM(2) = 1;
335 }
336 }
337
339 {
340 this->MakePairDefaultOnFace(faceAtr, "FV::faceAtr");
341#ifdef DNDS_USE_OMP
342# pragma omp parallel for
343#endif
344 for (index iFace = 0; iFace < mesh->NumFaceProc(); iFace++)
345 {
346 faceAtr(iFace, 0).intOrder = settings.intOrder;
347 // faceAtr(iCell, 0).Order = settings.maxOrder;
348 faceAtr(iFace, 0).NDIFF = this->maxNDOF();
349 faceAtr(iFace, 0).NDOF = 0;
350 }
351 }
352
354 {
355 using namespace Geom;
356 using namespace Geom::Elem;
357 DNDS_assert_info(faceAtr.father->Size() == mesh->NumFace(), "need to do SetFaceAtrBasic() first");
358
359 this->MakePairDefaultOnFace(faceArea, "FV::faceArea");
360 axisFaces.clear();
361#ifdef DNDS_USE_OMP
362# pragma omp parallel for
363#endif
364 for (index iFace = 0; iFace < mesh->NumFaceProc(); iFace++)
365 {
366 auto eFace = mesh->GetFaceElement(iFace);
367 auto qFace = Quadrature{eFace, GetFaceAtr(iFace).intOrder};
368 auto qFaceO1 = Quadrature{eFace, 1};
369 DNDS_assert(qFaceO1.GetNumPoints() == 1);
370
371 tSmallCoords coords;
372 mesh->GetCoordsOnFace(iFace, coords);
373
374 //****** Get Int Point Det and Vol
375 real v{0};
376 qFace.Integration(
377 v,
378 [&](auto &vInc, int iG, const tPoint &pParam, const Elem::tD01Nj &DiNj)
379 {
380 tJacobi J = Elem::ShapeJacobianCoordD01Nj(coords, DiNj);
381 tPoint pPhy = Elem::PPhysicsCoordD01Nj(coords, DiNj);
382 real JDet = FaceJacobianDet(getDim(), coords, DiNj);
383 if (axisSymmetric)
384 JDet *= std::max(verySmallReal, pPhy(1));
385 vInc = 1 * JDet;
386 });
387 v += verySmallReal;
388 if (axisSymmetric) // could this be helpful out of axisSymmetric context?
389 {
390 if (v < std::pow(this->GetCellVol(mesh->face2cell[iFace][0]), (real(getDim()) - 1) / real(getDim())) * smallReal)
391 axisFaces.insert(iFace);
392 }
393 faceArea[iFace][0] = v;
394 DNDS_assert_info(v > 0, "face has ill area result");
395 }
396 }
397
399 {
400 using namespace Geom;
401 using namespace Geom::Elem;
402
403 this->MakePairDefaultOnFace(faceCent, "FV::faceCent");
404#ifdef DNDS_USE_OMP
405# pragma omp parallel for
406#endif
407 for (index iFace = 0; iFace < mesh->NumFaceProc(); iFace++)
408 {
409 auto eFace = mesh->GetFaceElement(iFace);
410 auto qFaceO1 = Quadrature{eFace, 1};
411 DNDS_assert(qFaceO1.GetNumPoints() == 1);
412
413 tSmallCoords coords;
414 mesh->GetCoordsOnFace(iFace, coords);
415
416 //****** Get Center
417 SummationNoOp noOp;
418 qFaceO1.Integration(
419 noOp,
420 [&](auto &vInc, int iG, const tPoint &pParam, const Elem::tD01Nj &DiNj)
421 {
422 tPoint pPhy = Elem::PPhysicsCoordD01Nj(coords, DiNj);
424 });
425 }
426 }
427
429 {
430 using namespace Geom;
431 using namespace Geom::Elem;
432 DNDS_assert_info(faceAtr.father->Size() == mesh->NumFace(), "need to do SetFaceAtrBasic() first");
433 // DNDS_assert_info(faceArea.father->Size() == mesh->NumFace(), "need to do ConstructFaceArea() first");
434
435 this->MakePairDefaultOnFace(faceIntJacobiDet, "FV::faceIntJacobiDet");
436#ifdef DNDS_USE_OMP
437# pragma omp parallel for
438#endif
439 for (index iFace = 0; iFace < mesh->NumFaceProc(); iFace++)
440 {
441 auto eFace = mesh->GetFaceElement(iFace);
442 auto qFace = Quadrature{eFace, GetFaceAtr(iFace).intOrder};
443 auto qFaceO1 = Quadrature{eFace, 1};
444 DNDS_assert(qFaceO1.GetNumPoints() == 1);
445 faceIntJacobiDet.ResizeRow(iFace, qFace.GetNumPoints());
446 tSmallCoords coords;
447 mesh->GetCoordsOnFace(iFace, coords);
448 //****** Get Int Point Det and Vol
449 real v{0};
450 qFace.Integration(
451 v,
452 [&](auto &vInc, int iG, const tPoint &pParam, const Elem::tD01Nj &DiNj)
453 {
454 tJacobi J = Elem::ShapeJacobianCoordD01Nj(coords, DiNj);
455 tPoint pPhy = Elem::PPhysicsCoordD01Nj(coords, DiNj);
456 real JDet = FaceJacobianDet(getDim(), coords, DiNj);
457 if (axisSymmetric)
458 JDet *= std::max(verySmallReal, pPhy(1));
459 vInc = 1 * JDet;
460 faceIntJacobiDet(iFace, iG) = JDet;
461 });
462 // v = GetFaceArea(iFace);
463 for (int iG = 0; iG < qFace.GetNumPoints(); iG++)
465 for (int iG = 0; iG < qFace.GetNumPoints(); iG++)
466 DNDS_assert_info(faceIntJacobiDet(iFace, iG) / v > 1e-10, "face has ill jacobi det");
467 }
469 }
470
472 {
473 using namespace Geom;
474 using namespace Geom::Elem;
475 DNDS_assert_info(faceAtr.father->Size() == mesh->NumFace(), "need to do SetFaceAtrBasic() first");
476
477 this->MakePairDefaultOnFace(faceIntPPhysics, "FV::faceIntPPhysics");
478#ifdef DNDS_USE_OMP
479# pragma omp parallel for
480#endif
481 for (index iFace = 0; iFace < mesh->NumFaceProc(); iFace++)
482 {
483 auto eFace = mesh->GetFaceElement(iFace);
484 auto qFace = Quadrature{eFace, GetFaceAtr(iFace).intOrder};
485 faceIntPPhysics.ResizeRow(iFace, qFace.GetNumPoints());
486 tSmallCoords coords;
487 mesh->GetCoordsOnFace(iFace, coords);
488 //****** Get Int Point Det and Vol
489 real v{0};
490 qFace.Integration(
491 v,
492 [&](auto &vInc, int iG, const tPoint &pParam, const Elem::tD01Nj &DiNj)
493 {
494 tPoint pPhy = Elem::PPhysicsCoordD01Nj(coords, DiNj);
496 });
497 }
499 }
500
502 {
503 using namespace Geom;
504 using namespace Geom::Elem;
505 DNDS_assert_info(faceAtr.father->Size() == mesh->NumFace(), "need to do SetFaceAtrBasic() first");
506 // DNDS_assert_info(faceIntJacobiDet.father->Size() == mesh->NumFace(), "need to do ConstructFaceIntJacobiDet() first");
507
508 this->MakePairDefaultOnFace(faceUnitNorm, "FV::faceUnitNorm");
509#ifdef DNDS_USE_OMP
510# pragma omp parallel for
511#endif
512 for (index iFace = 0; iFace < mesh->NumFaceProc(); iFace++)
513 {
514 auto eFace = mesh->GetFaceElement(iFace);
515 auto qFace = Quadrature{eFace, GetFaceAtr(iFace).intOrder};
516 faceUnitNorm.ResizeRow(iFace, qFace.GetNumPoints());
517 tSmallCoords coords;
518 mesh->GetCoordsOnFace(iFace, coords);
519 //****** Get Int Point Norm/pPhy and Mean Norm
520 tPoint n{0, 0, 0};
521 qFace.Integration(
522 n,
523 [&](auto &vInc, int iG, const tPoint &pParam, const Elem::tD01Nj &DiNj)
524 {
525 tJacobi J = Elem::ShapeJacobianCoordD01Nj(coords, DiNj);
526 tPoint np;
527 if (getDim() == 2)
529 else
531 np.stableNormalize();
533 // vInc = np * GetFaceJacobiDet(iFace, iG);
534 });
535 }
537 }
538
540 {
541 using namespace Geom;
542 using namespace Geom::Elem;
543 DNDS_assert_info(faceAtr.father->Size() == mesh->NumFace(), "need to do SetFaceAtrBasic() first");
544 DNDS_assert_info(faceCent.father->Size() == mesh->NumFace(), "need to do ConstructFaceCent() first");
545 DNDS_assert_info(cellCent.father->Size() == mesh->NumCell(), "need to do ConstructCellCent() first");
546
547 this->MakePairDefaultOnFace(faceMeanNorm, "FV::faceMeanNorm");
548 axisFaces.clear();
549#ifdef DNDS_USE_OMP
550# pragma omp parallel for
551#endif
552 for (index iFace = 0; iFace < mesh->NumFaceProc(); iFace++)
553 {
554 auto eFace = mesh->GetFaceElement(iFace);
555 auto qFace = Quadrature{eFace, GetFaceAtr(iFace).intOrder};
556 tSmallCoords coords;
557 mesh->GetCoordsOnFace(iFace, coords);
558
559 //****** Get Int Point Norm/pPhy and Mean Norm
560 tPoint n{0, 0, 0};
561 qFace.Integration(
562 n,
563 [&](auto &vInc, int iG, const tPoint &pParam, const Elem::tD01Nj &DiNj)
564 {
565 tJacobi J = Elem::ShapeJacobianCoordD01Nj(coords, DiNj);
566 tPoint np;
567 if (getDim() == 2)
569 else
571 np.stableNormalize();
572 tPoint pPhy = Elem::PPhysicsCoordD01Nj(coords, DiNj);
573 real JDet = FaceJacobianDet(getDim(), coords, DiNj);
574 if (axisSymmetric)
575 JDet *= std::max(verySmallReal, pPhy(1));
576 vInc = np * JDet;
577 });
578 // faceMeanNorm[iFace] = n / v;
580 faceMeanNorm[iFace].stableNormalize(); // might not be unit if is on axis face for axisSymmetric
581
582 /// ! if the faces and f2c are created right, and not distorting too much
585 (this->GetFaceQuadraturePPhysFromCell(iFace, mesh->face2cell(iFace, 0), -1, -1) -
586 this->GetCellQuadraturePPhys(mesh->face2cell(iFace, 0), -1))
587 .dot(faceMeanNorm[iFace]) >= 0,
588 "face mean norm is not the same side as faceCenter - cellCenter");
589 }
590 }
591
593 {
594 DNDS_assert_info(volumeLocal.father->Size() == mesh->NumCell(), "need to do ConstructCellVolume() first");
595 DNDS_assert_info(faceArea.father->Size() == mesh->NumFace(), "need to do ConstructFaceArea() first");
596
597 this->MakePairDefaultOnCell(cellSmoothScale, "FV::cellSmoothScale");
599 cellSmoothScale.trans.BorrowGGIndexing(mesh->cell2cell.trans);
600 cellSmoothScale.trans.createMPITypes();
601 cellSmoothScale.trans.initPersistentPull();
602 std::vector<real> cellScale(mesh->NumCellProc());
603 for (index iCell = 0; iCell < mesh->NumCell(); iCell++)
604 {
605 real faceSum{0};
606 for (auto iFace : mesh->cell2face[iCell])
607 faceSum += this->GetFaceArea(iFace);
610 }
611 std::vector<real> cellScaleNew = cellScale;
612 for (int iter = 1; iter <= settings.nIterCellSmoothScale; iter++)
613 {
614 cellSmoothScale.trans.startPersistentPull();
615 cellSmoothScale.trans.waitPersistentPull();
616 for (index iCell = 0; iCell < mesh->NumCell(); iCell++)
617 {
618 real nAdj{0}, sum{0};
619 for (index iFace : mesh->cell2face[iCell])
620 {
622 if (iCellOther != UnInitIndex)
623 {
624 nAdj += 1.;
625 sum += cellSmoothScale(iCellOther, 0);
626 }
627 }
630 sum /= nAdj * (1 + smootherCentWeight);
631 cellScaleNew[iCell] = std::min(cellSmoothScale(iCell, 0), sum);
632 }
633 for (index iCell = 0; iCell < mesh->NumCell(); iCell++)
635 }
636 for (index iCell = 0; iCell < mesh->NumCell(); iCell++)
638 cellSmoothScale.trans.startPersistentPull();
639 cellSmoothScale.trans.waitPersistentPull();
640
642 for (index iCell = 0; iCell < mesh->NumCell(); iCell++)
645
646 if (mpi.rank == mRank)
647 log() << fmt::format("=== cellSmoothScale min [{:.5g}]", minCellSmoothScale)
648 << std::endl;
649 }
650}
#define DNDS_assert_info(expr, info)
Debug-only assertion with an extra std::string info message.
Definition Errors.hpp:113
#define DNDS_assert(expr)
Debug-only assertion (compiled out when DNDS_NDEBUG is defined). Prints the expression + file/line + ...
Definition Errors.hpp:108
DNDS_DEVICE_CALLABLE Geom::tPoint GetCellQuadraturePPhys(index iCell, int iG)
t3VecsPair faceUnitNorm
constructed using ConstructMetrics()
t3VecPair faceMeanNorm
constructed using ConstructMetrics()
t3MatPair cellMajorCoord
constructed using ConstructMetrics()
tRecAtrPair faceAtr
constructed using ConstructMetrics()
void MakePairDefaultOnFace(TArrayPair &aPair, const std::string &name, TOthers... others)
make pair with default MPI type, match face layout
t3VecPair cellBary
constructed using ConstructMetrics()
Geom::tPoint GetCellBary(index iCell)
t3VecPair cellCent
constructed using ConstructMetrics()
ssp< Geom::UnstructuredMesh > mesh
index CellFaceOther(index iCell, index iFace) const
tCoeffPair faceIntJacobiDet
constructed using ConstructMetrics()
tCoeffPair cellIntJacobiDet
constructed using ConstructMetrics()
t3MatPair cellInertia
constructed using ConstructMetrics()
t3VecsPair faceIntPPhysics
constructed using ConstructMetrics()
real GetCellVol(index iCell) const
Geom::tPoint GetFaceQuadraturePPhysFromCell(index iFace, index iCell, rowsize if2c, int iG)
tScalarPair faceArea
constructed using ConstructMetrics()
std::set< index > axisFaces
FiniteVolumeSettings settings
FiniteVolumeDeviceView< B > t_deviceView
t3VecPair faceCent
constructed using ConstructMetrics()
void MakePairDefaultOnCell(TArrayPair &aPair, const std::string &name, TOthers... others)
make pair with default MPI type, match cell layout
real GetFaceArea(index iFace) const
t3VecPair cellMajorHBox
constructed using ConstructMetrics()
tRecAtrPair cellAtr
constructed using ConstructMetrics()
real GetCellParamVol(index iCell) const
t3VecsPair cellIntPPhysics
constructed using ConstructMetrics()
tScalarPair cellSmoothScale
constructed using ConstructMetrics()
t3VecPair cellAlignedHBox
constructed using ConstructMetrics()
tScalarPair volumeLocal
constructed using ConstructMetrics()
RecAtr & GetFaceAtr(index iFace)
RecAtr & GetCellAtr(index iCell)
Eigen::Matrix3d Eigen3x3RealSymEigenDecompositionNormalized(const Eigen::Matrix3d &A)
Eigen-decomposition with eigenvector columns normalised to unit length.
Eigen::Matrix2d Eigen2x2RealSymEigenDecompositionNormalized(const Eigen::Matrix2d &A)
2x2 analogue of Eigen3x3RealSymEigenDecompositionNormalized.
real Eigen3x3RealSymEigenDecompositionGetCond(const Eigen::Matrix3d &A)
Condition number of a 3x3 SPD matrix from its eigenvalues.
real Eigen2x2RealSymEigenDecompositionGetCond(const Eigen::Matrix2d &A)
2x2 analogue of Eigen3x3RealSymEigenDecompositionGetCond.
void AllreduceOneReal(real &v, MPI_Op op, const MPIInfo &mpi)
Single-scalar Allreduce helper for reals (in-place, count = 1).
Definition MPI.hpp:673
DNDS_CONSTANT const index UnInitIndex
Sentinel "not initialised" index value (= INT64_MIN).
Definition Defines.hpp:176
DNDS_CONSTANT const real verySmallReal
Catch-all lower bound ("effectively zero").
Definition Defines.hpp:194
int64_t index
Global row / DOF index type (signed 64-bit; handles multi-billion-cell meshes).
Definition Defines.hpp:107
double real
Canonical floating-point scalar used throughout DNDSR (double precision).
Definition Defines.hpp:105
DNDS_CONSTANT const real smallReal
Loose lower bound (for iterative-solver tolerances etc.).
Definition Defines.hpp:196
std::ostream & log()
Return the current DNDSR log stream (either std::cout or the installed file).
Definition Defines.cpp:49
DNDS_CONSTANT const real veryLargeReal
Catch-all upper bound ("practically infinity") for physical scalars.
Definition Defines.hpp:190
void TransAttach()
Bind the transformer to the current father / son pointers.
ssp< TArray > father
Owned-side array (must be resized before ghost setup).
void ResizeRow(index i, rowsize rs)
Resize a single row in the combined address space.
TTrans trans
Ghost-communication engine bound to father and son.
void CompressBoth()
Compress both father and son CSR arrays (no-op for non-CSR layouts).
int intOrder
polynomial degree of reconstruction
bool ignoreMeshGeometryDeficiency
integration degree globally set
int rank
This rank's 0-based index within comm (-1 until initialised).
Definition MPI.hpp:219
Eigen::Matrix< real, 5, 1 > v
tVec b(NCells)
Eigen::Vector3d n(1.0, 0.0, 0.0)