faMeshDemandDrivenData.C
Go to the documentation of this file.
1 /*---------------------------------------------------------------------------*\
2  ========= |
3  \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
4  \\ / O peration |
5  \\ / A nd | www.openfoam.com
6  \\/ M anipulation |
7 -------------------------------------------------------------------------------
8  Copyright (C) 2016-2017 Wikki Ltd
9  Copyright (C) 2018-2020 OpenCFD Ltd.
10 -------------------------------------------------------------------------------
11 License
12  This file is part of OpenFOAM.
13 
14  OpenFOAM is free software: you can redistribute it and/or modify it
15  under the terms of the GNU General Public License as published by
16  the Free Software Foundation, either version 3 of the License, or
17  (at your option) any later version.
18 
19  OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
20  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
21  FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
22  for more details.
23 
24  You should have received a copy of the GNU General Public License
25  along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
26 
27 \*---------------------------------------------------------------------------*/
28 
29 #include "faMesh.H"
30 #include "faMeshLduAddressing.H"
31 #include "areaFields.H"
32 #include "edgeFields.H"
33 #include "primitiveFacePatch.H"
34 #include "fac.H"
35 #include "processorFaPatch.H"
36 #include "wedgeFaPatch.H"
38 #include "cartesianCS.H"
39 #include "scalarMatrices.H"
40 #include "processorFaPatchFields.H"
41 #include "emptyFaPatchFields.H"
42 
43 // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
44 
45 void Foam::faMesh::calcLduAddressing() const
46 {
48  << "Calculating addressing" << endl;
49 
50  if (lduPtr_)
51  {
53  << "lduPtr_ already allocated"
54  << abort(FatalError);
55  }
56 
57  lduPtr_ = new faMeshLduAddressing(*this);
58 }
59 
60 
61 void Foam::faMesh::calcPatchStarts() const
62 {
64  << "Calculating patch starts" << endl;
65 
66  if (patchStartsPtr_)
67  {
69  << "patchStartsPtr_ already allocated"
70  << abort(FatalError);
71  }
72 
73  patchStartsPtr_ = new labelList(boundary().size(), -1);
74  labelList& patchStarts = *patchStartsPtr_;
75 
76  patchStarts[0] = nInternalEdges();
77 
78  for (label i = 1; i < boundary().size(); ++i)
79  {
80  patchStarts[i] =
81  patchStarts[i - 1] + boundary()[i - 1].faPatch::size();
82  }
83 }
84 
85 
86 void Foam::faMesh::calcLe() const
87 {
89  << "Calculating local edges" << endl;
90 
91  if (LePtr_)
92  {
94  << "LePtr_ already allocated"
95  << abort(FatalError);
96  }
97 
98  LePtr_ =
99  new edgeVectorField
100  (
101  IOobject
102  (
103  "Le",
104  mesh().pointsInstance(),
105  meshSubDir,
106  mesh()
107  ),
108  *this,
109  dimLength
110  );
111 
112  edgeVectorField& Le = *LePtr_;
113 
114 
115  const pointField& pPoints = points();
116  const edgeList& pEdges = edges();
117 
118  const edgeVectorField& eCentres = edgeCentres();
119  const areaVectorField& fCentres = areaCentres();
120 
121  const edgeVectorField& edgeNormals = edgeAreaNormals();
122 
123  vectorField& leInternal = Le.ref();
124  const vectorField& edgeNormalsInternal = edgeNormals.internalField();
125  const vectorField& fCentresInternal = fCentres.internalField();
126  const vectorField& eCentresInternal = eCentres.internalField();
127  const scalarField& magLeInternal = magLe().internalField();
128 
129  forAll(leInternal, edgeI)
130  {
131  leInternal[edgeI] =
132  pEdges[edgeI].vec(pPoints) ^ edgeNormalsInternal[edgeI];
133 
134  leInternal[edgeI] *=
135  - sign
136  (
137  leInternal[edgeI] &
138  (
139  fCentresInternal[owner()[edgeI]]
140  - eCentresInternal[edgeI]
141  )
142  );
143 
144  leInternal[edgeI] *=
145  magLeInternal[edgeI]/mag(leInternal[edgeI]);
146  }
147 
148  forAll(boundary(), patchI)
149  {
150  const labelUList& bndEdgeFaces = boundary()[patchI].edgeFaces();
151 
152  const edgeList::subList bndEdges =
153  boundary()[patchI].patchSlice(pEdges);
154 
155  const vectorField& bndEdgeNormals =
156  edgeNormals.boundaryField()[patchI];
157 
158  vectorField& patchLe = Le.boundaryFieldRef()[patchI];
159  const vectorField& patchECentres = eCentres.boundaryField()[patchI];
160 
161  forAll(patchLe, edgeI)
162  {
163  patchLe[edgeI] =
164  bndEdges[edgeI].vec(pPoints) ^ bndEdgeNormals[edgeI];
165 
166  patchLe[edgeI] *=
167  - sign
168  (
169  patchLe[edgeI]&
170  (
171  fCentresInternal[bndEdgeFaces[edgeI]]
172  - patchECentres[edgeI]
173  )
174  );
175 
176  patchLe[edgeI] *=
177  magLe().boundaryField()[patchI][edgeI]
178  /mag(patchLe[edgeI]);
179  }
180  }
181 }
182 
183 
184 void Foam::faMesh::calcMagLe() const
185 {
187  << "Calculating local edge magnitudes" << endl;
188 
189  if (magLePtr_)
190  {
192  << "magLePtr_ already allocated"
193  << abort(FatalError);
194  }
195 
196  magLePtr_ =
197  new edgeScalarField
198  (
199  IOobject
200  (
201  "magLe",
202  mesh().pointsInstance(),
203  meshSubDir,
204  mesh()
205  ),
206  *this,
207  dimLength
208  );
209 
210  edgeScalarField& magLe = *magLePtr_;
211 
212  const pointField& localPoints = points();
213 
214  const edgeList::subList internalEdges =
215  edgeList::subList(edges(), nInternalEdges());
216 
217 
218  forAll(internalEdges, edgeI)
219  {
220  magLe.ref()[edgeI] = internalEdges[edgeI].mag(localPoints);
221  }
222 
223 
224  forAll(boundary(), patchI)
225  {
226  const edgeList::subList patchEdges =
227  boundary()[patchI].patchSlice(edges());
228 
229  forAll(patchEdges, edgeI)
230  {
231  magLe.boundaryFieldRef()[patchI][edgeI] =
232  patchEdges[edgeI].mag(localPoints);
233  }
234  }
235 }
236 
237 
238 void Foam::faMesh::calcAreaCentres() const
239 {
241  << "Calculating face centres" << endl;
242 
243  if (centresPtr_)
244  {
246  << "centresPtr_ already allocated"
247  << abort(FatalError);
248  }
249 
250  centresPtr_ =
251  new areaVectorField
252  (
253  IOobject
254  (
255  "centres",
256  mesh().pointsInstance(),
257  meshSubDir,
258  mesh()
259  ),
260  *this,
261  dimLength
262  );
263 
264  areaVectorField& centres = *centresPtr_;
265 
266  const pointField& localPoints = points();
267  const faceList& localFaces = faces();
268 
269  forAll(localFaces, faceI)
270  {
271  centres.ref()[faceI] = localFaces[faceI].centre(localPoints);
272  }
273 
274  forAll(boundary(), patchI)
275  {
276  const edgeList::subList patchEdges =
277  boundary()[patchI].patchSlice(edges());
278 
279  forAll(patchEdges, edgeI)
280  {
281  centres.boundaryFieldRef()[patchI][edgeI] =
282  patchEdges[edgeI].centre(localPoints);
283  }
284  }
285 
286  forAll(centres.boundaryField(), patchI)
287  {
288  //HJ: this is wrong! 5/Aug/2011
289  if
290  (
291  isA<processorFaPatchVectorField>
292  (
293  centres.boundaryField()[patchI]
294  )
295  )
296  {
297  centres.boundaryFieldRef()[patchI].initEvaluate();
298  centres.boundaryFieldRef()[patchI].evaluate();
299  }
300  }
301 }
302 
303 
304 void Foam::faMesh::calcEdgeCentres() const
305 {
307  << "Calculating edge centres" << endl;
308 
309  if (edgeCentresPtr_)
310  {
312  << "edgeCentresPtr_ already allocated"
313  << abort(FatalError);
314  }
315 
316  edgeCentresPtr_ =
317  new edgeVectorField
318  (
319  IOobject
320  (
321  "edgeCentres",
322  mesh().pointsInstance(),
323  meshSubDir,
324  mesh()
325  ),
326  *this,
327  dimLength
328  );
329 
330  edgeVectorField& edgeCentres = *edgeCentresPtr_;
331 
332  const pointField& localPoints = points();
333 
334  const edgeList::subList internalEdges =
335  edgeList::subList(edges(), nInternalEdges());
336 
337 
338  forAll(internalEdges, edgeI)
339  {
340  edgeCentres.ref()[edgeI] = internalEdges[edgeI].centre(localPoints);
341  }
342 
343 
344  forAll(boundary(), patchI)
345  {
346  const edgeList::subList patchEdges =
347  boundary()[patchI].patchSlice(edges());
348 
349  forAll(patchEdges, edgeI)
350  {
351  edgeCentres.boundaryFieldRef()[patchI][edgeI] =
352  patchEdges[edgeI].centre(localPoints);
353  }
354  }
355 }
356 
357 
358 void Foam::faMesh::calcS() const
359 {
361  << "Calculating areas" << endl;
362 
363  if (SPtr_)
364  {
366  << "SPtr_ already allocated"
367  << abort(FatalError);
368  }
369 
370  SPtr_ = new DimensionedField<scalar, areaMesh>
371  (
372  IOobject
373  (
374  "S",
375  time().timeName(),
376  mesh(),
379  ),
380  *this,
381  dimArea
382  );
383  DimensionedField<scalar, areaMesh>& S = *SPtr_;
384 
385  const pointField& localPoints = points();
386  const faceList& localFaces = faces();
387 
388  forAll(S, faceI)
389  {
390  S[faceI] = localFaces[faceI].mag(localPoints);
391  }
392 }
393 
394 
395 void Foam::faMesh::calcFaceAreaNormals() const
396 {
398  << "Calculating face area normals" << endl;
399 
400  if (faceAreaNormalsPtr_)
401  {
403  << "faceAreaNormalsPtr_ already allocated"
404  << abort(FatalError);
405  }
406 
407  faceAreaNormalsPtr_ =
408  new areaVectorField
409  (
410  IOobject
411  (
412  "faceAreaNormals",
413  mesh().pointsInstance(),
414  meshSubDir,
415  mesh()
416  ),
417  *this,
418  dimless
419  );
420 
421  areaVectorField& faceAreaNormals = *faceAreaNormalsPtr_;
422 
423  const pointField& localPoints = points();
424  const faceList& localFaces = faces();
425 
426  vectorField& nInternal = faceAreaNormals.ref();
427  forAll(localFaces, faceI)
428  {
429  nInternal[faceI] = localFaces[faceI].unitNormal(localPoints);
430  }
431 
432  forAll(boundary(), patchI)
433  {
434  faceAreaNormals.boundaryFieldRef()[patchI] =
435  edgeAreaNormals().boundaryField()[patchI];
436  }
437 
438  forAll(faceAreaNormals.boundaryField(), patchI)
439  {
440  if
441  (
442  isA<processorFaPatchVectorField>
443  (
444  faceAreaNormals.boundaryField()[patchI]
445  )
446  )
447  {
448  faceAreaNormals.boundaryFieldRef()[patchI].initEvaluate();
449  faceAreaNormals.boundaryFieldRef()[patchI].evaluate();
450  }
451  }
452 }
453 
454 
455 void Foam::faMesh::calcEdgeAreaNormals() const
456 {
458  << "Calculating edge area normals" << endl;
459 
460  if (edgeAreaNormalsPtr_)
461  {
463  << "edgeAreaNormalsPtr_ already allocated"
464  << abort(FatalError);
465  }
466 
467  edgeAreaNormalsPtr_ =
468  new edgeVectorField
469  (
470  IOobject
471  (
472  "edgeAreaNormals",
473  mesh().pointsInstance(),
474  meshSubDir,
475  mesh()
476  ),
477  *this,
478  dimless
479  );
480 
481  edgeVectorField& edgeAreaNormals = *edgeAreaNormalsPtr_;
482 
483 
484  // Point area normals
485  const vectorField& pointNormals = pointAreaNormals();
486 
487 
488 // // Primitive patch edge normals
489 // const labelListList& patchPointEdges = patch().pointEdges();
490 
491 // vectorField patchEdgeNormals(nEdges(), Zero);
492 
493 // forAll(pointNormals, pointI)
494 // {
495 // const labelList& curPointEdges = patchPointEdges[pointI];
496 
497 // forAll(curPointEdges, edgeI)
498 // {
499 // label curEdge = curPointEdges[edgeI];
500 
501 // patchEdgeNormals[curEdge] += 0.5*pointNormals[pointI];
502 // }
503 // }
504 
505 // patchEdgeNormals /= mag(patchEdgeNormals);
506 
507 
508 // // Edge area normals
509 // label nIntEdges = patch().nInternalEdges();
510 
511 // for (label edgeI = 0; edgeI < nIntEdges; ++edgeI)
512 // {
513 // edgeAreaNormals.ref()[edgeI] =
514 // patchEdgeNormals[edgeI];
515 // }
516 
517 // forAll(boundary(), patchI)
518 // {
519 // const labelList& edgeLabels = boundary()[patchI];
520 
521 // forAll(edgeAreaNormals.boundaryFieldRef()[patchI], edgeI)
522 // {
523 // edgeAreaNormals.boundaryFieldRef()[patchI][edgeI] =
524 // patchEdgeNormals[edgeLabels[edgeI]];
525 // }
526 // }
527 
528 
529  forAll(edgeAreaNormals.internalField(), edgeI)
530  {
531  const vector e = edges()[edgeI].unitVec(points());
532 
533 // scalar wStart =
534 // 1.0 - sqr(mag(e^pointNormals[edges()[edgeI].end()]));
535 
536 // scalar wEnd =
537 // 1.0 - sqr(mag(e^pointNormals[edges()[edgeI].start()]));
538 
539 // wStart = 1.0;
540 // wEnd = 1.0;
541 
542 // edgeAreaNormals.ref()[edgeI] =
543 // wStart*pointNormals[edges()[edgeI].start()]
544 // + wEnd*pointNormals[edges()[edgeI].end()];
545 
546 // vector eC =
547 // 0.5
548 // *(
549 // points()[edges()[edgeI].start()]
550 // + points()[edges()[edgeI].end()]
551 // );
552 
553 // vector eCp = 0.5*
554 // (
555 // points()[edges()[edgeI].start()]
556 // + pointNormals[edges()[edgeI].start()]
557 // points()[edges()[edgeI].end()] +
558 // );
559 
560  edgeAreaNormals.ref()[edgeI] =
561  pointNormals[edges()[edgeI].start()]
562  + pointNormals[edges()[edgeI].end()];
563 
564  edgeAreaNormals.ref()[edgeI] -=
565  e*(e&edgeAreaNormals.internalField()[edgeI]);
566  }
567 
568  edgeAreaNormals.ref() /= mag(edgeAreaNormals.internalField());
569 
570  forAll(boundary(), patchI)
571  {
572  const edgeList::subList patchEdges =
573  boundary()[patchI].patchSlice(edges());
574 
575  forAll(patchEdges, edgeI)
576  {
577  edgeAreaNormals.boundaryFieldRef()[patchI][edgeI] =
578  pointNormals[patchEdges[edgeI].start()]
579  + pointNormals[patchEdges[edgeI].end()];
580 
581  const vector e = patchEdges[edgeI].unitVec(points());
582 
583  edgeAreaNormals.boundaryFieldRef()[patchI][edgeI] -=
584  e*(e&edgeAreaNormals.boundaryField()[patchI][edgeI]);
585  }
586 
587  edgeAreaNormals.boundaryFieldRef()[patchI] /=
588  mag(edgeAreaNormals.boundaryField()[patchI]);
589  }
590 }
591 
592 
593 void Foam::faMesh::calcFaceCurvatures() const
594 {
596  << "Calculating face curvatures" << endl;
597 
598  if (faceCurvaturesPtr_)
599  {
601  << "faceCurvaturesPtr_ already allocated"
602  << abort(FatalError);
603  }
604 
605  faceCurvaturesPtr_ =
606  new areaScalarField
607  (
608  IOobject
609  (
610  "faceCurvatures",
611  mesh().pointsInstance(),
612  meshSubDir,
613  mesh()
614  ),
615  *this,
617  );
618 
619  areaScalarField& faceCurvatures = *faceCurvaturesPtr_;
620 
621 
622 // faceCurvatures =
623 // fac::edgeIntegrate(Le()*edgeLengthCorrection())
624 // &faceAreaNormals();
625 
626  areaVectorField kN(fac::edgeIntegrate(Le()*edgeLengthCorrection()));
627 
628  faceCurvatures = sign(kN&faceAreaNormals())*mag(kN);
629 }
630 
631 
632 void Foam::faMesh::calcEdgeTransformTensors() const
633 {
635  << "Calculating edge transformation tensors" << endl;
636 
637  if (edgeTransformTensorsPtr_)
638  {
640  << "edgeTransformTensorsPtr_ already allocated"
641  << abort(FatalError);
642  }
643 
644  edgeTransformTensorsPtr_ = new FieldField<Field, tensor>(nEdges());
645  FieldField<Field, tensor>& edgeTransformTensors =
646  *edgeTransformTensorsPtr_;
647 
648  const areaVectorField& Nf = faceAreaNormals();
649  const areaVectorField& Cf = areaCentres();
650 
651  const edgeVectorField& Ne = edgeAreaNormals();
652  const edgeVectorField& Ce = edgeCentres();
653 
654  // Internal edges transformation tensors
655  for (label edgeI=0; edgeI<nInternalEdges(); ++edgeI)
656  {
657  edgeTransformTensors.set(edgeI, new Field<tensor>(3, I));
658 
659  vector E = Ce.internalField()[edgeI];
660 
661  if (skew())
662  {
663  E -= skewCorrectionVectors().internalField()[edgeI];
664  }
665 
666  // Edge transformation tensor
667  vector il = E - Cf.internalField()[owner()[edgeI]];
668 
669  il -= Ne.internalField()[edgeI]
670  *(Ne.internalField()[edgeI]&il);
671 
672  il /= mag(il);
673 
674  vector kl = Ne.internalField()[edgeI];
675  vector jl = kl^il;
676 
677  edgeTransformTensors[edgeI][0] =
678  tensor
679  (
680  il.x(), il.y(), il.z(),
681  jl.x(), jl.y(), jl.z(),
682  kl.x(), kl.y(), kl.z()
683  );
684 
685  // Owner transformation tensor
686  il = E - Cf.internalField()[owner()[edgeI]];
687 
688  il -= Nf.internalField()[owner()[edgeI]]
689  *(Nf.internalField()[owner()[edgeI]]&il);
690 
691  il /= mag(il);
692 
693  kl = Nf.internalField()[owner()[edgeI]];
694  jl = kl^il;
695 
696  edgeTransformTensors[edgeI][1] =
697  tensor
698  (
699  il.x(), il.y(), il.z(),
700  jl.x(), jl.y(), jl.z(),
701  kl.x(), kl.y(), kl.z()
702  );
703 
704  // Neighbour transformation tensor
705  il = Cf.internalField()[neighbour()[edgeI]] - E;
706 
707  il -= Nf.internalField()[neighbour()[edgeI]]
708  *(Nf.internalField()[neighbour()[edgeI]]&il);
709 
710  il /= mag(il);
711 
712  kl = Nf.internalField()[neighbour()[edgeI]];
713  jl = kl^il;
714 
715  edgeTransformTensors[edgeI][2] =
716  tensor
717  (
718  il.x(), il.y(), il.z(),
719  jl.x(), jl.y(), jl.z(),
720  kl.x(), kl.y(), kl.z()
721  );
722  }
723 
724  // Boundary edges transformation tensors
725  forAll(boundary(), patchI)
726  {
727  if (boundary()[patchI].coupled())
728  {
729  const labelUList& edgeFaces =
730  boundary()[patchI].edgeFaces();
731 
732  vectorField ngbCf(Cf.boundaryField()[patchI].patchNeighbourField());
733 
734  vectorField ngbNf(Nf.boundaryField()[patchI].patchNeighbourField());
735 
736  forAll(edgeFaces, edgeI)
737  {
738  edgeTransformTensors.set
739  (
740  boundary()[patchI].start() + edgeI,
741  new Field<tensor>(3, I)
742  );
743 
744  vector E = Ce.boundaryField()[patchI][edgeI];
745 
746  if (skew())
747  {
748  E -= skewCorrectionVectors()
749  .boundaryField()[patchI][edgeI];
750  }
751 
752  // Edge transformation tensor
753  vector il = E - Cf.internalField()[edgeFaces[edgeI]];
754 
755  il -= Ne.boundaryField()[patchI][edgeI]
756  *(Ne.boundaryField()[patchI][edgeI]&il);
757 
758  il /= mag(il);
759 
760  vector kl = Ne.boundaryField()[patchI][edgeI];
761  vector jl = kl^il;
762 
763  edgeTransformTensors[boundary()[patchI].start() + edgeI][0] =
764  tensor(il, jl, kl);
765 
766  // Owner transformation tensor
767  il = E - Cf.internalField()[edgeFaces[edgeI]];
768 
769  il -= Nf.internalField()[edgeFaces[edgeI]]
770  *(Nf.internalField()[edgeFaces[edgeI]]&il);
771 
772  il /= mag(il);
773 
774  kl = Nf.internalField()[edgeFaces[edgeI]];
775  jl = kl^il;
776 
777  edgeTransformTensors[boundary()[patchI].start() + edgeI][1] =
778  tensor(il, jl, kl);
779 
780  // Neighbour transformation tensor
781  il = ngbCf[edgeI] - E;
782 
783  il -= ngbNf[edgeI]*(ngbNf[edgeI]&il);
784 
785  il /= mag(il);
786 
787  kl = ngbNf[edgeI];
788 
789  jl = kl^il;
790 
791  edgeTransformTensors[boundary()[patchI].start() + edgeI][2] =
792  tensor(il, jl, kl);
793  }
794  }
795  else
796  {
797  const labelUList& edgeFaces = boundary()[patchI].edgeFaces();
798 
799  forAll(edgeFaces, edgeI)
800  {
801  edgeTransformTensors.set
802  (
803  boundary()[patchI].start() + edgeI,
804  new Field<tensor>(3, I)
805  );
806 
807  vector E = Ce.boundaryField()[patchI][edgeI];
808 
809  if (skew())
810  {
811  E -= skewCorrectionVectors()
812  .boundaryField()[patchI][edgeI];
813  }
814 
815  // Edge transformation tensor
816  vector il = E - Cf.internalField()[edgeFaces[edgeI]];
817 
818  il -= Ne.boundaryField()[patchI][edgeI]
819  *(Ne.boundaryField()[patchI][edgeI]&il);
820 
821  il /= mag(il);
822 
823  vector kl = Ne.boundaryField()[patchI][edgeI];
824  vector jl = kl^il;
825 
826  edgeTransformTensors[boundary()[patchI].start() + edgeI][0] =
827  tensor(il, jl, kl);
828 
829  // Owner transformation tensor
830  il = E - Cf.internalField()[edgeFaces[edgeI]];
831 
832  il -= Nf.internalField()[edgeFaces[edgeI]]
833  *(Nf.internalField()[edgeFaces[edgeI]]&il);
834 
835  il /= mag(il);
836 
837  kl = Nf.internalField()[edgeFaces[edgeI]];
838  jl = kl^il;
839 
840  edgeTransformTensors[boundary()[patchI].start() + edgeI][1] =
841  tensor(il, jl, kl);
842  }
843  }
844  }
845 }
846 
847 
849 {
851  << "Calculating internal points" << endl;
852 
853  const edgeList& edges = patch().edges();
854  label nIntEdges = patch().nInternalEdges();
855 
856  List<bool> internal(nPoints(), true);
857 
858  for (label curEdge = nIntEdges; curEdge < edges.size(); ++curEdge)
859  {
860  internal[edges[curEdge].start()] = false;
861 
862  internal[edges[curEdge].end()] = false;
863  }
864 
865  SLList<label> internalPoints;
866 
867  forAll(internal, pointI)
868  {
869  if (internal[pointI])
870  {
871  internalPoints.append(pointI);
872  }
873  }
874 
875  labelList result(internalPoints);
876 
877  return result;
878 }
879 
880 
882 {
884  << "Calculating boundary points" << endl;
885 
886  const edgeList& edges = patch().edges();
887  label nIntEdges = patch().nInternalEdges();
888 
889  List<bool> internal(nPoints(), true);
890 
891  for (label curEdge = nIntEdges; curEdge < edges.size(); ++curEdge)
892  {
893  internal[edges[curEdge].start()] = false;
894 
895  internal[edges[curEdge].end()] = false;
896  }
897 
898  SLList<label> boundaryPoints;
899 
900  forAll(internal, pointI)
901  {
902  if (!internal[pointI])
903  {
904  boundaryPoints.append(pointI);
905  }
906  }
907 
908  labelList result(boundaryPoints);
909 
910  return result;
911 }
912 
913 
914 void Foam::faMesh::calcPointAreaNormals() const
915 {
916  if (pointAreaNormalsPtr_)
917  {
919  << "pointAreaNormalsPtr_ already allocated"
920  << abort(FatalError);
921  }
922 
923 
924  pointAreaNormalsPtr_ = new vectorField(nPoints(), Zero);
925 
926  vectorField& result = *pointAreaNormalsPtr_;
927 
928  labelList intPoints(internalPoints());
929  labelList bndPoints(boundaryPoints());
930 
931  const pointField& points = patch().localPoints();
932  const faceList& faces = patch().localFaces();
933  const labelListList& pointFaces = patch().pointFaces();
934 
935  for (const label curPoint : intPoints)
936  {
937  faceList curFaceList(pointFaces[curPoint].size());
938 
939  forAll(curFaceList, faceI)
940  {
941  curFaceList[faceI] = faces[pointFaces[curPoint][faceI]];
942  }
943 
944  primitiveFacePatch curPatch(curFaceList, points);
945 
946  labelList curPointPoints = curPatch.edgeLoops()[0];
947 
948  for (int i = 0; i < curPointPoints.size(); ++i)
949  {
950  vector d1 =
951  points[curPatch.meshPoints()[curPointPoints[i]]]
952  - points[curPoint];
953 
954  label p = i + 1;
955 
956  if (i == (curPointPoints.size() - 1))
957  {
958  p = 0;
959  }
960 
961  vector d2 =
962  points[curPatch.meshPoints()[curPointPoints[p]]]
963  - points[curPoint];
964 
965  vector n = (d1 ^ d2)/(mag(d1 ^ d2) + SMALL);
966 
967  scalar sinAlpha = mag(d1^d2)/(mag(d1)*mag(d2));
968 
969  scalar w = sinAlpha/(mag(d1)*mag(d2));
970 
971  result[curPoint] += w*n;
972  }
973  }
974 
975  for (const label curPoint : bndPoints)
976  {
977  faceList curFaceList(pointFaces[curPoint].size());
978 
979  forAll(curFaceList, faceI)
980  {
981  curFaceList[faceI] = faces[pointFaces[curPoint][faceI]];
982  }
983 
984  primitiveFacePatch curPatch(curFaceList, points);
985 
986  labelList agglomFacePoints = curPatch.edgeLoops()[0];
987 
988  SLList<label> slList;
989 
990  label curPointLabel = -1;
991 
992  for (label i=0; i<agglomFacePoints.size(); ++i)
993  {
994  if (curPatch.meshPoints()[agglomFacePoints[i]] == curPoint)
995  {
996  curPointLabel = i;
997  }
998  else if ( curPointLabel != -1 )
999  {
1000  slList.append(curPatch.meshPoints()[agglomFacePoints[i]]);
1001  }
1002  }
1003 
1004  for (label i=0; i<curPointLabel; ++i)
1005  {
1006  slList.append(curPatch.meshPoints()[agglomFacePoints[i]]);
1007  }
1008 
1009  labelList curPointPoints(slList);
1010 
1011  for (label i=0; i < (curPointPoints.size() - 1); ++i)
1012  {
1013  vector d1 = points[curPointPoints[i]] - points[curPoint];
1014 
1015  vector d2 = points[curPointPoints[i + 1]] - points[curPoint];
1016 
1017  vector n = (d1 ^ d2)/(mag(d1 ^ d2) + SMALL);
1018 
1019  scalar sinAlpha = mag(d1 ^ d2)/(mag(d1)*mag(d2));
1020 
1021  scalar w = sinAlpha/(mag(d1)*mag(d2));
1022 
1023  result[curPoint] += w*n;
1024  }
1025  }
1026 
1027  // Correct wedge points
1028  forAll(boundary(), patchI)
1029  {
1030  const faPatch& fap = boundary()[patchI];
1031 
1032  if (isA<wedgeFaPatch>(fap))
1033  {
1034  const wedgeFaPatch& wedgePatch = refCast<const wedgeFaPatch>(fap);
1035 
1036  const labelList& patchPoints = wedgePatch.pointLabels();
1037 
1038  vector N =
1039  transform
1040  (
1041  wedgePatch.edgeT(),
1042  wedgePatch.centreNormal()
1043  );
1044 
1045  N /= mag(N);
1046 
1047  for (const label pti : patchPoints)
1048  {
1049  result[pti] -= N*(N&result[pti]);
1050  }
1051 
1052  // Axis point correction
1053  if (wedgePatch.axisPoint() > -1)
1054  {
1055  result[wedgePatch.axisPoint()] =
1056  wedgePatch.axis()
1057  *(
1058  wedgePatch.axis()
1059  &result[wedgePatch.axisPoint()]
1060  );
1061  }
1062  }
1063  }
1064 
1065 
1066  // Processor patch points correction
1067  for (const faPatch& fap : boundary())
1068  {
1069  if (Pstream::parRun() && isA<processorFaPatch>(fap))
1070  {
1071  const processorFaPatch& procPatch =
1072  refCast<const processorFaPatch>(fap);
1073 
1074  const labelList& patchPointLabels = procPatch.pointLabels();
1075 
1076  vectorField patchPointNormals
1077  (
1078  patchPointLabels.size(),
1079  Zero
1080  );
1081 
1082  forAll(patchPointNormals, pointI)
1083  {
1084  patchPointNormals[pointI] = result[patchPointLabels[pointI]];
1085  }
1086 
1087  {
1089  (
1091  procPatch.neighbProcNo(),
1092  reinterpret_cast<const char*>(patchPointNormals.cdata()),
1093  patchPointNormals.byteSize()
1094  );
1095  }
1096 
1097  vectorField ngbPatchPointNormals
1098  (
1099  procPatch.neighbPoints().size(),
1100  Zero
1101  );
1102 
1103  {
1105  (
1107  procPatch.neighbProcNo(),
1108  reinterpret_cast<char*>(ngbPatchPointNormals.data()),
1109  ngbPatchPointNormals.byteSize()
1110  );
1111  }
1112 
1113  const labelList& nonGlobalPatchPoints =
1114  procPatch.nonGlobalPatchPoints();
1115 
1116  for (const label pti : nonGlobalPatchPoints)
1117  {
1118  result[patchPointLabels[pti]] +=
1119  ngbPatchPointNormals[procPatch.neighbPoints()[pti]];
1120  }
1121  }
1122  }
1123 
1124 
1125  // Correct global points
1126  if (globalData().nGlobalPoints() > 0)
1127  {
1128  const labelList& spLabels(globalData().sharedPointLabels());
1129 
1130  vectorField spNormals(spLabels.size(), Zero);
1131  forAll(spNormals, pointI)
1132  {
1133  spNormals[pointI] = result[spLabels[pointI]];
1134  }
1135 
1136  const labelList& addr = globalData().sharedPointAddr();
1137 
1138  vectorField gpNormals
1139  (
1140  globalData().nGlobalPoints(),
1141  Zero
1142  );
1143 
1144  forAll(addr, i)
1145  {
1146  gpNormals[addr[i]] += spNormals[i];
1147  }
1148 
1149  combineReduce(gpNormals, plusEqOp<vectorField>());
1150 
1151  // Extract local data
1152  forAll(addr, i)
1153  {
1154  spNormals[i] = gpNormals[addr[i]];
1155  }
1156 
1157  forAll(spNormals, pointI)
1158  {
1159  result[spLabels[pointI]] = spNormals[pointI];
1160  }
1161  }
1162 
1163 
1164  // Boundary points correction
1165  forAll(boundary(), patchI)
1166  {
1167  const faPatch& fap = boundary()[patchI];
1168 
1169  if (correctPatchPointNormals(patchI) && !fap.coupled())
1170  {
1171  if (fap.ngbPolyPatchIndex() == -1)
1172  {
1174  << "Neighbour polyPatch index is not defined "
1175  << "for faPatch " << fap.name()
1176  << abort(FatalError);
1177  }
1178 
1179  const labelList& patchPoints = fap.pointLabels();
1180 
1181  const vectorField N(fap.ngbPolyPatchPointNormals());
1182 
1183  forAll(patchPoints, pointI)
1184  {
1185  result[patchPoints[pointI]]
1186  -= N[pointI]*(N[pointI]&result[patchPoints[pointI]]);
1187  }
1188  }
1189  }
1190 
1191  result /= mag(result);
1192 }
1193 
1194 
1195 void Foam::faMesh::calcPointAreaNormalsByQuadricsFit() const
1196 {
1197  vectorField& result = *pointAreaNormalsPtr_;
1198 
1199  const labelList intPoints(internalPoints());
1200  const labelList bndPoints(boundaryPoints());
1201 
1202  const pointField& points = patch().localPoints();
1203  const faceList& faces = patch().localFaces();
1204  const labelListList& pointFaces = patch().pointFaces();
1205 
1206  forAll(intPoints, pointI)
1207  {
1208  label curPoint = intPoints[pointI];
1209 
1210  const labelHashSet faceSet(pointFaces[curPoint]);
1211  const labelList curFaces(faceSet.toc());
1212 
1213  labelHashSet pointSet;
1214 
1215  pointSet.insert(curPoint);
1216  for (label i=0; i<curFaces.size(); ++i)
1217  {
1218  const labelList& facePoints = faces[curFaces[i]];
1219  for (label j=0; j<facePoints.size(); ++j)
1220  {
1221  if (!pointSet.found(facePoints[j]))
1222  {
1223  pointSet.insert(facePoints[j]);
1224  }
1225  }
1226  }
1227  pointSet.erase(curPoint);
1228  labelList curPoints(pointSet.toc());
1229 
1230  if (curPoints.size() < 5)
1231  {
1232  DebugInfo
1233  << "WARNING: Extending point set for fitting." << endl;
1234 
1235  labelHashSet faceSet(pointFaces[curPoint]);
1236  labelList curFaces(faceSet.toc());
1237  forAll(curFaces, faceI)
1238  {
1239  const labelList& curFaceFaces =
1240  patch().faceFaces()[curFaces[faceI]];
1241 
1242  forAll(curFaceFaces, fI)
1243  {
1244  label curFaceFace = curFaceFaces[fI];
1245 
1246  if (!faceSet.found(curFaceFace))
1247  {
1248  faceSet.insert(curFaceFace);
1249  }
1250  }
1251  }
1252  curFaces = faceSet.toc();
1253 
1254  labelHashSet pointSet;
1255 
1256  pointSet.insert(curPoint);
1257  for (label i=0; i<curFaces.size(); ++i)
1258  {
1259  const labelList& facePoints = faces[curFaces[i]];
1260  for (label j=0; j<facePoints.size(); ++j)
1261  {
1262  if (!pointSet.found(facePoints[j]))
1263  {
1264  pointSet.insert(facePoints[j]);
1265  }
1266  }
1267  }
1268 
1269  pointSet.erase(curPoint);
1270  curPoints = pointSet.toc();
1271  }
1272 
1273  pointField allPoints(curPoints.size());
1274  scalarField W(curPoints.size(), 1.0);
1275  for (label i=0; i<curPoints.size(); ++i)
1276  {
1277  allPoints[i] = points[curPoints[i]];
1278  W[i] = 1.0/magSqr(allPoints[i] - points[curPoint]);
1279  }
1280 
1281  // Transform points
1282  coordSystem::cartesian cs
1283  (
1284  points[curPoint], // origin
1285  result[curPoint], // axis [e3] (normalized by constructor)
1286  allPoints[0] - points[curPoint] // direction [e1]
1287  );
1288 
1289  for (point& p : allPoints)
1290  {
1291  p = cs.localPosition(p);
1292  }
1293 
1295  (
1296  allPoints.size(),
1297  5,
1298  0.0
1299  );
1300 
1301  for (label i = 0; i < allPoints.size(); ++i)
1302  {
1303  M[i][0] = sqr(allPoints[i].x());
1304  M[i][1] = sqr(allPoints[i].y());
1305  M[i][2] = allPoints[i].x()*allPoints[i].y();
1306  M[i][3] = allPoints[i].x();
1307  M[i][4] = allPoints[i].y();
1308  }
1309 
1310  scalarSquareMatrix MtM(5, Zero);
1311 
1312  for (label i = 0; i < MtM.n(); ++i)
1313  {
1314  for (label j = 0; j < MtM.m(); ++j)
1315  {
1316  for (label k = 0; k < M.n(); ++k)
1317  {
1318  MtM[i][j] += M[k][i]*M[k][j]*W[k];
1319  }
1320  }
1321  }
1322 
1323  scalarField MtR(5, Zero);
1324 
1325  for (label i=0; i<MtR.size(); ++i)
1326  {
1327  for (label j=0; j<M.n(); ++j)
1328  {
1329  MtR[i] += M[j][i]*allPoints[j].z()*W[j];
1330  }
1331  }
1332 
1333  LUsolve(MtM, MtR);
1334 
1335  vector curNormal = vector(MtR[3], MtR[4], -1);
1336 
1337  curNormal = cs.globalVector(curNormal);
1338 
1339  curNormal *= sign(curNormal&result[curPoint]);
1340 
1341  result[curPoint] = curNormal;
1342  }
1343 
1344 
1345  forAll(boundary(), patchI)
1346  {
1347  const faPatch& fap = boundary()[patchI];
1348 
1349  if (Pstream::parRun() && isA<processorFaPatch>(fap))
1350  {
1351  const processorFaPatch& procPatch =
1352  refCast<const processorFaPatch>(boundary()[patchI]);
1353 
1354  const labelList& patchPointLabels = procPatch.pointLabels();
1355 
1356  labelList toNgbProcLsPointStarts(patchPointLabels.size(), Zero);
1357  vectorField toNgbProcLsPoints
1358  (
1359  10*patchPointLabels.size(),
1360  Zero
1361  );
1362  label nPoints = 0;
1363 
1364  for (label pointI=0; pointI<patchPointLabels.size(); ++pointI)
1365  {
1366  label curPoint = patchPointLabels[pointI];
1367 
1368  toNgbProcLsPointStarts[pointI] = nPoints;
1369 
1370  const labelHashSet faceSet(pointFaces[curPoint]);
1371  const labelList curFaces(faceSet.toc());
1372 
1373  labelHashSet pointSet;
1374 
1375  pointSet.insert(curPoint);
1376  for (label i=0; i<curFaces.size(); ++i)
1377  {
1378  const labelList& facePoints = faces[curFaces[i]];
1379  for (label j=0; j<facePoints.size(); ++j)
1380  {
1381  if (!pointSet.found(facePoints[j]))
1382  {
1383  pointSet.insert(facePoints[j]);
1384  }
1385  }
1386  }
1387  pointSet.erase(curPoint);
1388  labelList curPoints = pointSet.toc();
1389 
1390  for (label i=0; i<curPoints.size(); ++i)
1391  {
1392  toNgbProcLsPoints[nPoints++] = points[curPoints[i]];
1393  }
1394  }
1395 
1396  toNgbProcLsPoints.setSize(nPoints);
1397 
1398  {
1399  OPstream toNeighbProc
1400  (
1402  procPatch.neighbProcNo(),
1403  toNgbProcLsPoints.byteSize()
1404  + toNgbProcLsPointStarts.byteSize()
1405  + 10*sizeof(label)
1406  );
1407 
1408  toNeighbProc
1409  << toNgbProcLsPoints
1410  << toNgbProcLsPointStarts;
1411  }
1412  }
1413  }
1414 
1415  for (const faPatch& fap : boundary())
1416  {
1417  if (Pstream::parRun() && isA<processorFaPatch>(fap))
1418  {
1419  const processorFaPatch& procPatch =
1420  refCast<const processorFaPatch>(fap);
1421 
1422  const labelList& patchPointLabels = procPatch.pointLabels();
1423 
1424  labelList fromNgbProcLsPointStarts(patchPointLabels.size(), Zero);
1425  vectorField fromNgbProcLsPoints;
1426 
1427  {
1428  IPstream fromNeighbProc
1429  (
1431  procPatch.neighbProcNo(),
1432  10*patchPointLabels.size()*sizeof(vector)
1433  + fromNgbProcLsPointStarts.byteSize()
1434  + 10*sizeof(label)
1435  );
1436 
1437  fromNeighbProc
1438  >> fromNgbProcLsPoints
1439  >> fromNgbProcLsPointStarts;
1440  }
1441 
1442  const labelList& nonGlobalPatchPoints =
1443  procPatch.nonGlobalPatchPoints();
1444 
1445  forAll(nonGlobalPatchPoints, pointI)
1446  {
1447  label curPoint =
1448  patchPointLabels[nonGlobalPatchPoints[pointI]];
1449  label curNgbPoint =
1450  procPatch.neighbPoints()[nonGlobalPatchPoints[pointI]];
1451 
1452  labelHashSet faceSet;
1453  faceSet.insert(pointFaces[curPoint]);
1454 
1455  labelList curFaces = faceSet.toc();
1456 
1457  labelHashSet pointSet;
1458 
1459  pointSet.insert(curPoint);
1460  for (label i=0; i<curFaces.size(); ++i)
1461  {
1462  const labelList& facePoints = faces[curFaces[i]];
1463  for (label j=0; j<facePoints.size(); ++j)
1464  {
1465  if (!pointSet.found(facePoints[j]))
1466  {
1467  pointSet.insert(facePoints[j]);
1468  }
1469  }
1470  }
1471  pointSet.erase(curPoint);
1472  labelList curPoints = pointSet.toc();
1473 
1474  label nAllPoints = curPoints.size();
1475 
1476  if (curNgbPoint == fromNgbProcLsPointStarts.size() - 1)
1477  {
1478  nAllPoints +=
1479  fromNgbProcLsPoints.size()
1480  - fromNgbProcLsPointStarts[curNgbPoint];
1481  }
1482  else
1483  {
1484  nAllPoints +=
1485  fromNgbProcLsPointStarts[curNgbPoint + 1]
1486  - fromNgbProcLsPointStarts[curNgbPoint];
1487  }
1488 
1489  vectorField allPointsExt(nAllPoints);
1490  label counter = 0;
1491  for (label i=0; i<curPoints.size(); ++i)
1492  {
1493  allPointsExt[counter++] = points[curPoints[i]];
1494  }
1495 
1496  if (curNgbPoint == fromNgbProcLsPointStarts.size() - 1)
1497  {
1498  for
1499  (
1500  label i=fromNgbProcLsPointStarts[curNgbPoint];
1501  i<fromNgbProcLsPoints.size();
1502  ++i
1503  )
1504  {
1505  allPointsExt[counter++] = fromNgbProcLsPoints[i];
1506  }
1507  }
1508  else
1509  {
1510  for
1511  (
1512  label i=fromNgbProcLsPointStarts[curNgbPoint];
1513  i<fromNgbProcLsPointStarts[curNgbPoint+1];
1514  ++i
1515  )
1516  {
1517  allPointsExt[counter++] = fromNgbProcLsPoints[i];
1518  }
1519  }
1520 
1521  // Remove duplicate points
1522  vectorField allPoints(nAllPoints, Zero);
1523  boundBox bb(allPointsExt, false);
1524  scalar tol = 0.001*mag(bb.max() - bb.min());
1525 
1526  nAllPoints = 0;
1527  forAll(allPointsExt, pI)
1528  {
1529  bool duplicate = false;
1530  for (label i=0; i<nAllPoints; ++i)
1531  {
1532  if
1533  (
1534  mag
1535  (
1536  allPoints[i]
1537  - allPointsExt[pI]
1538  )
1539  < tol
1540  )
1541  {
1542  duplicate = true;
1543  break;
1544  }
1545  }
1546 
1547  if (!duplicate)
1548  {
1549  allPoints[nAllPoints++] = allPointsExt[pI];
1550  }
1551  }
1552 
1553  allPoints.setSize(nAllPoints);
1554 
1555  if (nAllPoints < 5)
1556  {
1558  << "There are no enough points for quadrics "
1559  << "fitting for a point at processor patch"
1560  << abort(FatalError);
1561  }
1562 
1563  // Transform points
1564  const vector& origin = points[curPoint];
1565  const vector axis = normalised(result[curPoint]);
1566  vector dir(allPoints[0] - points[curPoint]);
1567  dir -= axis*(axis&dir);
1568  dir.normalise();
1569 
1570  const coordinateSystem cs("cs", origin, axis, dir);
1571 
1572  scalarField W(allPoints.size(), 1.0);
1573 
1574  forAll(allPoints, pI)
1575  {
1576  W[pI] = 1.0/magSqr(allPoints[pI] - points[curPoint]);
1577 
1578  allPoints[pI] = cs.localPosition(allPoints[pI]);
1579  }
1580 
1582  (
1583  allPoints.size(),
1584  5,
1585  0.0
1586  );
1587 
1588  for (label i=0; i<allPoints.size(); ++i)
1589  {
1590  M[i][0] = sqr(allPoints[i].x());
1591  M[i][1] = sqr(allPoints[i].y());
1592  M[i][2] = allPoints[i].x()*allPoints[i].y();
1593  M[i][3] = allPoints[i].x();
1594  M[i][4] = allPoints[i].y();
1595  }
1596 
1597  scalarSquareMatrix MtM(5, Zero);
1598 
1599  for (label i = 0; i < MtM.n(); ++i)
1600  {
1601  for (label j = 0; j < MtM.m(); ++j)
1602  {
1603  for (label k = 0; k < M.n(); ++k)
1604  {
1605  MtM[i][j] += M[k][i]*M[k][j]*W[k];
1606  }
1607  }
1608  }
1609 
1610  scalarField MtR(5, Zero);
1611 
1612  for (label i = 0; i < MtR.size(); ++i)
1613  {
1614  for (label j = 0; j < M.n(); ++j)
1615  {
1616  MtR[i] += M[j][i]*allPoints[j].z()*W[j];
1617  }
1618  }
1619 
1620  LUsolve(MtM, MtR);
1621 
1622  vector curNormal = vector(MtR[3], MtR[4], -1);
1623 
1624  curNormal = cs.globalVector(curNormal);
1625 
1626  curNormal *= sign(curNormal&result[curPoint]);
1627 
1628  result[curPoint] = curNormal;
1629  }
1630  }
1631  }
1632 
1633  // Correct global points
1634  if (globalData().nGlobalPoints() > 0)
1635  {
1636  const labelList& spLabels = globalData().sharedPointLabels();
1637 
1638  const labelList& addr = globalData().sharedPointAddr();
1639 
1640  for (label k=0; k<globalData().nGlobalPoints(); ++k)
1641  {
1642  List<List<vector>> procLsPoints(Pstream::nProcs());
1643 
1644  const label curSharedPointIndex = addr.find(k);
1645 
1646  scalar tol = 0.0;
1647 
1648  if (curSharedPointIndex != -1)
1649  {
1650  label curPoint = spLabels[curSharedPointIndex];
1651 
1652  const labelHashSet faceSet(pointFaces[curPoint]);
1653  const labelList curFaces(faceSet.toc());
1654 
1655  labelHashSet pointSet;
1656  pointSet.insert(curPoint);
1657  for (label i=0; i<curFaces.size(); ++i)
1658  {
1659  const labelList& facePoints = faces[curFaces[i]];
1660  for (label j=0; j<facePoints.size(); ++j)
1661  {
1662  if (!pointSet.found(facePoints[j]))
1663  {
1664  pointSet.insert(facePoints[j]);
1665  }
1666  }
1667  }
1668  pointSet.erase(curPoint);
1669  labelList curPoints = pointSet.toc();
1670 
1671  vectorField locPoints(points, curPoints);
1672 
1673  procLsPoints[Pstream::myProcNo()] = locPoints;
1674 
1675  const boundBox bb(locPoints, false);
1676  tol = 0.001*mag(bb.max() - bb.min());
1677  }
1678 
1679  Pstream::gatherList(procLsPoints);
1680  Pstream::scatterList(procLsPoints);
1681 
1682  if (curSharedPointIndex != -1)
1683  {
1684  label curPoint = spLabels[curSharedPointIndex];
1685 
1686  label nAllPoints = 0;
1687  forAll(procLsPoints, procI)
1688  {
1689  nAllPoints += procLsPoints[procI].size();
1690  }
1691 
1692  vectorField allPoints(nAllPoints, Zero);
1693 
1694  nAllPoints = 0;
1695  forAll(procLsPoints, procI)
1696  {
1697  forAll(procLsPoints[procI], pointI)
1698  {
1699  bool duplicate = false;
1700  for (label i=0; i<nAllPoints; ++i)
1701  {
1702  if
1703  (
1704  mag
1705  (
1706  allPoints[i]
1707  - procLsPoints[procI][pointI]
1708  )
1709  < tol
1710  )
1711  {
1712  duplicate = true;
1713  break;
1714  }
1715  }
1716 
1717  if (!duplicate)
1718  {
1719  allPoints[nAllPoints++] =
1720  procLsPoints[procI][pointI];
1721  }
1722  }
1723  }
1724 
1725  allPoints.setSize(nAllPoints);
1726 
1727  if (nAllPoints < 5)
1728  {
1730  << "There are no enough points for quadratic "
1731  << "fitting for a global processor point "
1732  << abort(FatalError);
1733  }
1734 
1735  // Transform points
1736  const vector& origin = points[curPoint];
1737  const vector axis = normalised(result[curPoint]);
1738  vector dir(allPoints[0] - points[curPoint]);
1739  dir -= axis*(axis&dir);
1740  dir.normalise();
1741 
1742  coordinateSystem cs("cs", origin, axis, dir);
1743 
1744  scalarField W(allPoints.size(), 1.0);
1745 
1746  forAll(allPoints, pointI)
1747  {
1748  W[pointI]=
1749  1.0/magSqr(allPoints[pointI] - points[curPoint]);
1750 
1751  allPoints[pointI] = cs.localPosition(allPoints[pointI]);
1752  }
1753 
1755  (
1756  allPoints.size(),
1757  5,
1758  0.0
1759  );
1760 
1761  for (label i=0; i<allPoints.size(); ++i)
1762  {
1763  M[i][0] = sqr(allPoints[i].x());
1764  M[i][1] = sqr(allPoints[i].y());
1765  M[i][2] = allPoints[i].x()*allPoints[i].y();
1766  M[i][3] = allPoints[i].x();
1767  M[i][4] = allPoints[i].y();
1768  }
1769 
1770  scalarSquareMatrix MtM(5, Zero);
1771  for (label i = 0; i < MtM.n(); ++i)
1772  {
1773  for (label j = 0; j < MtM.m(); ++j)
1774  {
1775  for (label k = 0; k < M.n(); ++k)
1776  {
1777  MtM[i][j] += M[k][i]*M[k][j]*W[k];
1778  }
1779  }
1780  }
1781 
1782  scalarField MtR(5, Zero);
1783  for (label i = 0; i < MtR.size(); ++i)
1784  {
1785  for (label j = 0; j < M.n(); ++j)
1786  {
1787  MtR[i] += M[j][i]*allPoints[j].z()*W[j];
1788  }
1789  }
1790 
1791  LUsolve(MtM, MtR);
1792 
1793  vector curNormal = vector(MtR[3], MtR[4], -1);
1794 
1795  curNormal = cs.globalVector(curNormal);
1796 
1797  curNormal *= sign(curNormal&result[curPoint]);
1798 
1799  result[curPoint] = curNormal;
1800  }
1801  }
1802  }
1803 
1804  result /= mag(result);
1805 }
1806 
1807 
1809 {
1811  << "Calculating edge length correction" << endl;
1812 
1813  tmp<edgeScalarField> tcorrection
1814  (
1815  new edgeScalarField
1816  (
1817  IOobject
1818  (
1819  "edgeLengthCorrection",
1820  mesh().pointsInstance(),
1821  meshSubDir,
1822  mesh()
1823  ),
1824  *this,
1825  dimless
1826  )
1827  );
1828  edgeScalarField& correction = tcorrection.ref();
1829 
1830  const vectorField& pointNormals = pointAreaNormals();
1831 
1832  forAll(correction.internalField(), edgeI)
1833  {
1834  scalar sinAlpha = mag
1835  (
1836  pointNormals[edges()[edgeI].start()]^
1837  pointNormals[edges()[edgeI].end()]
1838  );
1839 
1840  scalar alpha = asin(sinAlpha);
1841 
1842  correction.ref()[edgeI] = cos(0.5*alpha);
1843  }
1844 
1845 
1846  forAll(boundary(), patchI)
1847  {
1848  const edgeList::subList patchEdges
1849  (
1850  boundary()[patchI].patchSlice(edges())
1851  );
1852 
1853  forAll(patchEdges, edgeI)
1854  {
1855  scalar sinAlpha =
1856  mag
1857  (
1858  pointNormals[patchEdges[edgeI].start()]
1859  ^ pointNormals[patchEdges[edgeI].end()]
1860  );
1861 
1862  scalar alpha = asin(sinAlpha);
1863 
1864  correction.boundaryFieldRef()[patchI][edgeI] = cos(0.5*alpha);
1865  }
1866  }
1867 
1868  return tcorrection;
1869 }
1870 
1871 
1872 // ************************************************************************* //
Foam::LList::append
void append(const T &item)
Add copy at tail of list.
Definition: LList.H:237
Foam::IOobject::NO_WRITE
Definition: IOobject.H:130
Foam::labelList
List< label > labelList
A List of labels.
Definition: List.H:71
Foam::LUsolve
void LUsolve(scalarSquareMatrix &matrix, List< Type > &source)
Definition: scalarMatricesTemplates.C:215
Foam::pointField
vectorField pointField
pointField is a vectorField.
Definition: pointFieldFwd.H:44
Foam::UPstream::commsTypes::blocking
Foam::scalarField
Field< scalar > scalarField
Specialisation of Field<T> for scalar.
Definition: primitiveFieldsFwd.H:52
Foam::IOobject
Defines the attributes of an object for which implicit objectRegistry management is supported,...
Definition: IOobject.H:104
p
volScalarField & p
Definition: createFieldRefs.H:8
Foam::dimless
const dimensionSet dimless(0, 0, 0, 0, 0, 0, 0)
Dimensionless.
Definition: dimensionSets.H:50
Foam::edgeList
List< edge > edgeList
A List of edges.
Definition: edgeList.H:63
Foam::skew
dimensionedTensor skew(const dimensionedTensor &dt)
Definition: dimensionedTensor.C:138
Foam::dimLength
const dimensionSet dimLength(0, 1, 0, 0, 0, 0, 0)
Definition: dimensionSets.H:53
Foam::primitiveFacePatch
PrimitivePatch< List< face >, const pointField & > primitiveFacePatch
A PrimitivePatch with List storage for the faces, const reference for the point field.
Definition: primitiveFacePatch.H:51
Foam::tmp
A class for managing temporary objects.
Definition: PtrList.H:61
Foam::edgeVectorField
GeometricField< vector, faePatchField, edgeMesh > edgeVectorField
Definition: edgeFieldsFwd.H:57
Foam::Zero
static constexpr const zero Zero
Global zero (0)
Definition: zero.H:131
Foam::faMesh::edgeLengthCorrection
tmp< edgeScalarField > edgeLengthCorrection() const
Return edge length correction.
Definition: faMeshDemandDrivenData.C:1808
Foam::Pstream::scatterList
static void scatterList(const List< commsStruct > &comms, List< T > &Values, const int tag, const label comm)
Scatter data. Reverse of gatherList.
Definition: gatherScatterList.C:215
Foam::constant::atomic::alpha
const dimensionedScalar alpha
Fine-structure constant: default SI units: [].
Definition: readThermalProperties.H:212
Foam::SubList
A List obtained as a section of another List.
Definition: SubList.H:53
processorFaPatch.H
Foam::UPstream::parRun
static bool & parRun()
Test if this a parallel run, or allow modify access.
Definition: UPstream.H:434
Foam::faMesh::internalPoints
labelList internalPoints() const
Return internal point labels.
Definition: faMeshDemandDrivenData.C:848
primitiveFacePatch.H
Foam::combineReduce
void combineReduce(const List< UPstream::commsStruct > &comms, T &Value, const CombineOp &cop, const int tag, const label comm)
Definition: PstreamCombineReduceOps.H:54
emptyFaPatchFields.H
Foam::List::append
void append(const T &val)
Append an element at the end of the list.
Definition: ListI.H:182
Foam::endl
Ostream & endl(Ostream &os)
Add newline and flush stream.
Definition: Ostream.H:350
faMesh.H
Foam::correction
tmp< fvMatrix< Type > > correction(const fvMatrix< Type > &)
Foam::sign
dimensionedScalar sign(const dimensionedScalar &ds)
Definition: dimensionedScalar.C:166
Foam::transform
dimensionSet transform(const dimensionSet &ds)
Return the argument; transformations do not change the dimensions.
Definition: dimensionSet.C:519
cartesianCS.H
forAll
#define forAll(list, i)
Loop across all elements in list.
Definition: stdFoam.H:296
Foam::vectorField
Field< vector > vectorField
Specialisation of Field<T> for vector.
Definition: primitiveFieldsFwd.H:54
Foam::magSqr
dimensioned< typename typeOfMag< Type >::type > magSqr(const dimensioned< Type > &dt)
Foam::UIPstream::read
static label read(const commsTypes commsType, const int fromProcNo, char *buf, const std::streamsize bufSize, const int tag=UPstream::msgType(), const label communicator=0)
Read into given buffer from given processor and return the.
Definition: UIPread.C:81
nPoints
label nPoints
Definition: gmvOutputHeader.H:2
Foam::LList
Template class for non-intrusive linked lists.
Definition: LList.H:54
PstreamCombineReduceOps.H
Combination-Reduction operation for a parallel run. The information from all nodes is collected on th...
Foam::areaVectorField
GeometricField< vector, faPatchField, areaMesh > areaVectorField
Definition: areaFieldsFwd.H:58
n
label n
Definition: TABSMDCalcMethod2.H:31
Foam::UOPstream::write
static bool write(const commsTypes commsType, const int toProcNo, const char *buf, const std::streamsize bufSize, const int tag=UPstream::msgType(), const label communicator=0)
Write given buffer to given processor.
Definition: UOPwrite.C:36
Foam::tmp::ref
T & ref() const
Definition: tmpI.H:228
Foam::dimArea
const dimensionSet dimArea(sqr(dimLength))
Definition: dimensionSets.H:60
fac.H
Namespace of functions to calculate explicit derivatives.
Foam::Field< vector >
DebugInFunction
#define DebugInFunction
Report an information message using Foam::Info.
Definition: messageStream.H:365
edgeFields.H
Foam::edgeScalarField
GeometricField< scalar, faePatchField, edgeMesh > edgeScalarField
Definition: edgeFieldsFwd.H:52
areaFields.H
timeName
word timeName
Definition: getTimeIndex.H:3
Foam::fac::edgeIntegrate
tmp< GeometricField< Type, faPatchField, areaMesh > > edgeIntegrate(const GeometricField< Type, faePatchField, edgeMesh > &ssf)
Definition: facEdgeIntegrate.C:47
Foam::List::subList
SubList< T > subList
Declare type of subList.
Definition: List.H:114
Foam::scalarSquareMatrix
SquareMatrix< scalar > scalarSquareMatrix
Definition: scalarMatrices.H:57
Foam::FatalError
error FatalError
mesh
dynamicFvMesh & mesh
Definition: createDynamicFvMesh.H:6
stdFoam::end
constexpr auto end(C &c) -> decltype(c.end())
Return iterator to the end of the container c.
Definition: stdFoam.H:121
Foam::areaScalarField
GeometricField< scalar, faPatchField, areaMesh > areaScalarField
Definition: areaFieldsFwd.H:53
Foam::abort
errorManip< error > abort(error &err)
Definition: errorManip.H:144
Foam::vector
Vector< scalar > vector
A scalar version of the templated Vector.
Definition: vector.H:51
Foam::faMesh::boundaryPoints
labelList boundaryPoints() const
Return boundary point labels.
Definition: faMeshDemandDrivenData.C:881
Foam::normalised
VectorSpace< Form, Cmpt, Ncmpts > normalised(const VectorSpace< Form, Cmpt, Ncmpts > &vs)
Definition: VectorSpaceI.H:483
processorFaPatchFields.H
Foam::labelListList
List< labelList > labelListList
A List of labelList.
Definition: labelList.H:56
FatalErrorInFunction
#define FatalErrorInFunction
Report an error message using Foam::FatalError.
Definition: error.H:381
Foam::Pstream::gatherList
static void gatherList(const List< commsStruct > &comms, List< T > &Values, const int tag, const label comm)
Gather data but keep individual values separate.
Definition: gatherScatterList.C:52
Foam::sqr
dimensionedSymmTensor sqr(const dimensionedVector &dv)
Definition: dimensionedSymmTensor.C:51
DebugInfo
#define DebugInfo
Report an information message using Foam::Info.
Definition: messageStream.H:359
Foam::UPstream::myProcNo
static int myProcNo(const label communicator=worldComm)
Number of this process (starting from masterNo() = 0)
Definition: UPstream.H:464
Foam::foamVersion::patch
const std::string patch
OpenFOAM patch number as a std::string.
Foam::faceList
List< face > faceList
A List of faces.
Definition: faceListFwd.H:47
Foam::List< label >
faMeshLduAddressing.H
Foam::mag
dimensioned< typename typeOfMag< Type >::type > mag(const dimensioned< Type > &dt)
M
#define M(I)
points
const pointField & points
Definition: gmvOutputHeader.H:1
k
label k
Boltzmann constant.
Definition: LISASMDCalcMethod2.H:41
Foam::constant::electromagnetic::e
const dimensionedScalar e
Elementary charge.
Definition: createFields.H:11
Foam::HashSet::insert
bool insert(const Key &key)
Insert a new entry, not overwriting existing entries.
Definition: HashSet.H:181
x
x
Definition: LISASMDCalcMethod2.H:52
scalarMatrices.H
Foam::DelaunayMeshTools::allPoints
tmp< pointField > allPoints(const Triangulation &t)
Extract all points in vertex-index order.
N
const Vector< label > N(dict.get< Vector< label >>("N"))
Foam::point
vector point
Point is a vector.
Definition: point.H:43
Foam::labelUList
UList< label > labelUList
A UList of labels.
Definition: UList.H:80
Foam::labelHashSet
HashSet< label, Hash< label > > labelHashSet
A HashSet with label keys and label hasher.
Definition: HashSet.H:409
Foam::GeometricField
Generic GeometricField class.
Definition: areaFieldsFwd.H:53
Foam::IOobject::NO_READ
Definition: IOobject.H:123
wedgeFaPatch.H
Foam::scalarRectangularMatrix
RectangularMatrix< scalar > scalarRectangularMatrix
Definition: scalarMatrices.H:56
Foam::tensor
Tensor< scalar > tensor
Tensor of scalars, i.e. Tensor<scalar>.
Definition: symmTensor.H:61
boundary
faceListList boundary
Definition: createBlockMesh.H:4
Foam::asin
dimensionedScalar asin(const dimensionedScalar &ds)
Definition: dimensionedScalar.C:267
Foam::UPstream::nProcs
static label nProcs(const label communicator=worldComm)
Number of processes in parallel run, and 1 for serial run.
Definition: UPstream.H:446
Foam::I
static const Identity< scalar > I
Definition: Identity.H:95
y
scalar y
Definition: LISASMDCalcMethod1.H:14
Foam::cos
dimensionedScalar cos(const dimensionedScalar &ds)
Definition: dimensionedScalar.C:265