motionSmootherAlgo.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 | Copyright (C) 2011-2015 OpenFOAM Foundation
6  \\/ M anipulation |
7 -------------------------------------------------------------------------------
8 License
9  This file is part of OpenFOAM.
10 
11  OpenFOAM is free software: you can redistribute it and/or modify it
12  under the terms of the GNU General Public License as published by
13  the Free Software Foundation, either version 3 of the License, or
14  (at your option) any later version.
15 
16  OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
17  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
18  FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
19  for more details.
20 
21  You should have received a copy of the GNU General Public License
22  along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
23 
24 \*---------------------------------------------------------------------------*/
25 
26 #include "motionSmootherAlgo.H"
27 #include "twoDPointCorrector.H"
28 #include "faceSet.H"
29 #include "pointSet.H"
31 #include "pointConstraints.H"
32 #include "syncTools.H"
33 #include "meshTools.H"
34 #include "OFstream.H"
35 
36 // * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
37 
38 namespace Foam
39 {
40  defineTypeNameAndDebug(motionSmootherAlgo, 0);
41 }
42 
43 
44 // * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
45 
47 (
48  const pointField& fld,
49  const scalar maxMag
50 ) const
51 {
52  pointField syncedFld(fld);
53 
54  syncTools::syncPointPositions
55  (
56  mesh_,
57  syncedFld,
58  minEqOp<point>(), // combine op
59  point(GREAT,GREAT,GREAT) // null
60  );
61 
62  forAll(syncedFld, i)
63  {
64  if (mag(syncedFld[i] - fld[i]) > maxMag)
65  {
67  << "On point " << i << " point:" << fld[i]
68  << " synchronised point:" << syncedFld[i]
69  << abort(FatalError);
70  }
71  }
72 }
73 
74 
76 {
77  forAll(fld, pointI)
78  {
79  const scalar val = fld[pointI];
80 
81  if ((val > -GREAT) && (val < GREAT))
82  {}
83  else
84  {
86  << "Problem : point:" << pointI << " value:" << val
87  << abort(FatalError);
88  }
89  }
90 }
91 
92 
94 (
95  const labelHashSet& faceLabels
96 ) const
97 {
98  labelHashSet usedPoints(mesh_.nPoints()/100);
99 
100  forAllConstIter(labelHashSet, faceLabels, iter)
101  {
102  const face& f = mesh_.faces()[iter.key()];
103 
104  forAll(f, fp)
105  {
106  usedPoints.insert(f[fp]);
107  }
108  }
109 
110  return usedPoints;
111 }
112 
113 
115 (
116  const pointField& points
117 ) const
118 {
119  const edgeList& edges = mesh_.edges();
120 
121  tmp<scalarField> twght(new scalarField(edges.size()));
122  scalarField& wght = twght();
123 
124  forAll(edges, edgeI)
125  {
126  wght[edgeI] = 1.0/(edges[edgeI].mag(points)+SMALL);
127  }
128  return twght;
129 }
130 
131 
132 // Smooth on selected points (usually patch points)
134 (
135  const scalarField& edgeWeights,
136  const PackedBoolList& isAffectedPoint,
137  const labelList& meshPoints,
138  const pointScalarField& fld,
139  pointScalarField& newFld
140 ) const
141 {
142  tmp<pointScalarField> tavgFld = avg
143  (
144  fld,
145  edgeWeights //scalarField(mesh_.nEdges(), 1.0) // uniform weighting
146  );
147  const pointScalarField& avgFld = tavgFld();
148 
149  forAll(meshPoints, i)
150  {
151  label pointI = meshPoints[i];
152  if (isAffectedPoint.get(pointI) == 1)
153  {
154  newFld[pointI] = min
155  (
156  fld[pointI],
157  0.5*fld[pointI] + 0.5*avgFld[pointI]
158  );
159  }
160  }
161 
162  // Single and multi-patch constraints
163  pointConstraints::New(pMesh()).constrain(newFld, false);
164 }
165 
166 
167 // Smooth on all internal points
169 (
170  const scalarField& edgeWeights,
171  const PackedBoolList& isAffectedPoint,
172  const pointScalarField& fld,
173  pointScalarField& newFld
174 ) const
175 {
176  tmp<pointScalarField> tavgFld = avg
177  (
178  fld,
179  edgeWeights //scalarField(mesh_.nEdges(), 1.0) // uniform weighting
180  );
181  const pointScalarField& avgFld = tavgFld();
182 
183  forAll(fld, pointI)
184  {
185  if (isAffectedPoint.get(pointI) == 1 && isInternalPoint(pointI))
186  {
187  newFld[pointI] = min
188  (
189  fld[pointI],
190  0.5*fld[pointI] + 0.5*avgFld[pointI]
191  );
192  }
193  }
194 
195  // Single and multi-patch constraints
196  pointConstraints::New(pMesh()).constrain(newFld, false);
197 
198 }
199 
200 
201 // Scale on all internal points
203 (
204  const labelHashSet& pointLabels,
205  const scalar scale,
207 ) const
208 {
210  {
211  if (isInternalPoint(iter.key()))
212  {
213  fld[iter.key()] *= scale;
214  }
215  }
216 
217  // Single and multi-patch constraints
218  pointConstraints::New(pMesh()).constrain(fld, false);
219 }
220 
221 
222 // Scale on selected points (usually patch points)
224 (
225  const labelList& meshPoints,
226  const labelHashSet& pointLabels,
227  const scalar scale,
229 ) const
230 {
231  forAll(meshPoints, i)
232  {
233  label pointI = meshPoints[i];
234 
235  if (pointLabels.found(pointI))
236  {
237  fld[pointI] *= scale;
238  }
239  }
240 }
241 
242 
243 // Lower on internal points
245 (
246  const labelHashSet& pointLabels,
247  const scalar f,
249 ) const
250 {
252  {
253  if (isInternalPoint(iter.key()))
254  {
255  fld[iter.key()] = max(0.0, fld[iter.key()]-f);
256  }
257  }
258 
259  // Single and multi-patch constraints
261 }
262 
263 
264 // Scale on selected points (usually patch points)
266 (
267  const labelList& meshPoints,
268  const labelHashSet& pointLabels,
269  const scalar f,
271 ) const
272 {
273  forAll(meshPoints, i)
274  {
275  label pointI = meshPoints[i];
276 
277  if (pointLabels.found(pointI))
278  {
279  fld[pointI] = max(0.0, fld[pointI]-f);
280  }
281  }
282 }
283 
284 
286 {
287  return isInternalPoint_.get(pointI) == 1;
288 }
289 
290 
292 (
293  const label nPointIter,
294  const faceSet& wrongFaces,
295 
296  labelList& affectedFaces,
297  PackedBoolList& isAffectedPoint
298 ) const
299 {
300  isAffectedPoint.setSize(mesh_.nPoints());
301  isAffectedPoint = 0;
302 
303  faceSet nbrFaces(mesh_, "checkFaces", wrongFaces);
304 
305  // Find possible points influenced by nPointIter iterations of
306  // scaling and smoothing by doing pointCellpoint walk.
307  // Also update faces-to-be-checked to extend one layer beyond the points
308  // that will get updated.
309 
310  for (label i = 0; i < nPointIter; i++)
311  {
312  pointSet nbrPoints(mesh_, "grownPoints", getPoints(nbrFaces.toc()));
313 
314  forAllConstIter(pointSet, nbrPoints, iter)
315  {
316  const labelList& pCells = mesh_.pointCells(iter.key());
317 
318  forAll(pCells, pCellI)
319  {
320  const cell& cFaces = mesh_.cells()[pCells[pCellI]];
321 
322  forAll(cFaces, cFaceI)
323  {
324  nbrFaces.insert(cFaces[cFaceI]);
325  }
326  }
327  }
328  nbrFaces.sync(mesh_);
329 
330  if (i == nPointIter - 2)
331  {
332  forAllConstIter(faceSet, nbrFaces, iter)
333  {
334  const face& f = mesh_.faces()[iter.key()];
335  forAll(f, fp)
336  {
337  isAffectedPoint.set(f[fp], 1);
338  }
339  }
340  }
341  }
342 
343  affectedFaces = nbrFaces.toc();
344 }
345 
346 
347 // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
348 
350 (
351  polyMesh& mesh,
352  pointMesh& pMesh,
354  pointVectorField& displacement,
355  pointScalarField& scale,
356  pointField& oldPoints,
357  const labelList& adaptPatchIDs,
358  const dictionary& paramDict
359 )
360 :
361  mesh_(mesh),
362  pMesh_(pMesh),
363  pp_(pp),
364  displacement_(displacement),
365  scale_(scale),
366  oldPoints_(oldPoints),
367  adaptPatchIDs_(adaptPatchIDs),
368  paramDict_(paramDict),
369  isInternalPoint_(mesh_.nPoints(), 1)
370 {
371  updateMesh();
372 }
373 
374 
375 // * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * //
376 
378 {}
379 
380 
381 // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
382 
384 {
385  return mesh_;
386 }
387 
388 
390 {
391  return pMesh_;
392 }
393 
394 
396 {
397  return pp_;
398 }
399 
400 
402 {
403  return adaptPatchIDs_;
404 }
405 
406 
408 {
409  return paramDict_;
410 }
411 
412 
414 {
415  oldPoints_ = mesh_.points();
416 
417  scale_ = 1.0;
418 
419  // No need to update twoDmotion corrector since only holds edge labels
420  // which will remain the same as before. So unless the mesh was distorted
421  // severely outside of motionSmootherAlgo there will be no need.
422 }
423 
424 
426 (
427  const labelList& patchIDs,
428  pointVectorField& displacement
429 )
430 {
431  // Adapt the fixedValue bc's (i.e. copy internal point data to
432  // boundaryField for all affected patches)
433  forAll(patchIDs, i)
434  {
435  label patchI = patchIDs[i];
436 
437  displacement.boundaryField()[patchI] ==
438  displacement.boundaryField()[patchI].patchInternalField();
439  }
440 
441  // Make consistent with non-adapted bc's by evaluating those now and
442  // resetting the displacement from the values.
443  // Note that we're just doing a correctBoundaryConditions with
444  // fixedValue bc's first.
445  labelHashSet adaptPatchSet(patchIDs);
446 
447  const lduSchedule& patchSchedule = displacement.mesh().globalData().
448  patchSchedule();
449 
450  forAll(patchSchedule, patchEvalI)
451  {
452  label patchI = patchSchedule[patchEvalI].patch;
453 
454  if (!adaptPatchSet.found(patchI))
455  {
456  if (patchSchedule[patchEvalI].init)
457  {
458  displacement.boundaryField()[patchI]
459  .initEvaluate(Pstream::scheduled);
460  }
461  else
462  {
463  displacement.boundaryField()[patchI]
465  }
466  }
467  }
468 
469  // Multi-patch constraints
470  pointConstraints::New(displacement.mesh()).constrainCorners(displacement);
471 
472  // Adapt the fixedValue bc's (i.e. copy internal point data to
473  // boundaryField for all affected patches) to take the changes caused
474  // by multi-corner constraints into account.
475  forAll(patchIDs, i)
476  {
477  label patchI = patchIDs[i];
478 
479  displacement.boundaryField()[patchI] ==
480  displacement.boundaryField()[patchI].patchInternalField();
481  }
482 }
483 
484 
486 {
487  setDisplacementPatchFields(adaptPatchIDs_, displacement_);
488 }
489 
490 
492 (
493  const labelList& patchIDs,
494  const indirectPrimitivePatch& pp,
495  pointField& patchDisp,
496  pointVectorField& displacement
497 )
498 {
499  const polyMesh& mesh = displacement.mesh()();
500 
501  // See comment in .H file about shared points.
502  // We want to disallow effect of loose coupled points - we only
503  // want to see effect of proper fixedValue boundary conditions
504 
505  const labelList& cppMeshPoints =
507 
508  const labelList& ppMeshPoints = pp.meshPoints();
509 
510  // Knock out displacement on points which are not on pp but are coupled
511  // to them since we want 'proper' values from displacement to take
512  // precedence.
513  {
514  PackedBoolList isPatchPoint(mesh.nPoints());
515  isPatchPoint.set(ppMeshPoints);
517  (
518  mesh,
519  isPatchPoint,
521  0
522  );
523  forAll(cppMeshPoints, i)
524  {
525  label pointI = cppMeshPoints[i];
526  if (isPatchPoint[pointI])
527  {
528  displacement[pointI] = vector::zero;
529  }
530  }
531  }
532 
533 
534  // Set internal point data from displacement on combined patch points.
535  forAll(ppMeshPoints, patchPointI)
536  {
537  displacement[ppMeshPoints[patchPointI]] = patchDisp[patchPointI];
538  }
539 
540 
541  // Combine any coupled points
543  (
544  mesh,
545  displacement,
546  maxMagEqOp(), // combine op
547  vector::zero // null value
548  );
549 
550 
551  // Adapt the fixedValue bc's (i.e. copy internal point data to
552  // boundaryField for all affected patches)
553  setDisplacementPatchFields(patchIDs, displacement);
554 
555 
556  if (debug)
557  {
558  OFstream str(mesh.db().path()/"changedPoints.obj");
559  label nVerts = 0;
560  forAll(ppMeshPoints, patchPointI)
561  {
562  const vector& newDisp = displacement[ppMeshPoints[patchPointI]];
563 
564  if (mag(newDisp-patchDisp[patchPointI]) > SMALL)
565  {
566  const point& pt = mesh.points()[ppMeshPoints[patchPointI]];
567 
568  meshTools::writeOBJ(str, pt);
569  nVerts++;
570  //Pout<< "Point:" << pt
571  // << " oldDisp:" << patchDisp[patchPointI]
572  // << " newDisp:" << newDisp << endl;
573  }
574  }
575  Pout<< "Written " << nVerts << " points that are changed to file "
576  << str.name() << endl;
577  }
578 
579  // Now reset input displacement
580  forAll(ppMeshPoints, patchPointI)
581  {
582  patchDisp[patchPointI] = displacement[ppMeshPoints[patchPointI]];
583  }
584 }
585 
586 
588 {
589  setDisplacement(adaptPatchIDs_, pp_, patchDisp, displacement_);
590 }
591 
592 
593 // correctBoundaryConditions with fixedValue bc's first.
595 (
596  pointVectorField& displacement
597 ) const
598 {
599  labelHashSet adaptPatchSet(adaptPatchIDs_);
600 
601  const lduSchedule& patchSchedule = mesh_.globalData().patchSchedule();
602 
603  // 1. evaluate on adaptPatches
604  forAll(patchSchedule, patchEvalI)
605  {
606  label patchI = patchSchedule[patchEvalI].patch;
607 
608  if (adaptPatchSet.found(patchI))
609  {
610  if (patchSchedule[patchEvalI].init)
611  {
612  displacement.boundaryField()[patchI]
613  .initEvaluate(Pstream::blocking);
614  }
615  else
616  {
617  displacement.boundaryField()[patchI]
619  }
620  }
621  }
622 
623 
624  // 2. evaluate on non-AdaptPatches
625  forAll(patchSchedule, patchEvalI)
626  {
627  label patchI = patchSchedule[patchEvalI].patch;
628 
629  if (!adaptPatchSet.found(patchI))
630  {
631  if (patchSchedule[patchEvalI].init)
632  {
633  displacement.boundaryField()[patchI]
634  .initEvaluate(Pstream::blocking);
635  }
636  else
637  {
638  displacement.boundaryField()[patchI]
640  }
641  }
642  }
643 
644  // Multi-patch constraints
645  pointConstraints::New(displacement.mesh()).constrainCorners(displacement);
646 
647  // Correct for problems introduced by corner constraints
649  (
650  mesh_,
651  displacement,
652  maxMagEqOp(), // combine op
653  vector::zero // null value
654  );
655 }
656 
657 
658 
660 {
661  // Correct for 2-D motion
662  const twoDPointCorrector& twoDCorrector = twoDPointCorrector::New(mesh_);
663 
664  if (twoDCorrector.required())
665  {
666  Info<< "Correcting 2-D mesh motion";
667 
668  if (mesh_.globalData().parallel())
669  {
671  << "2D mesh-motion probably not correct in parallel" << endl;
672  }
673 
674  // We do not want to move 3D planes so project all points onto those
675  const pointField& oldPoints = mesh_.points();
676  const edgeList& edges = mesh_.edges();
677 
678  const labelList& neIndices = twoDCorrector.normalEdgeIndices();
679  const vector& pn = twoDCorrector.planeNormal();
680 
681  forAll(neIndices, i)
682  {
683  const edge& e = edges[neIndices[i]];
684 
685  point& pStart = newPoints[e.start()];
686 
687  pStart += pn*(pn & (oldPoints[e.start()] - pStart));
688 
689  point& pEnd = newPoints[e.end()];
690 
691  pEnd += pn*(pn & (oldPoints[e.end()] - pEnd));
692  }
693 
694  // Correct tangentially
695  twoDCorrector.correctPoints(newPoints);
696  Info<< " ...done" << endl;
697  }
698 
699  if (debug)
700  {
701  Pout<< "motionSmootherAlgo::modifyMotionPoints :"
702  << " testing sync of newPoints."
703  << endl;
704  testSyncPositions(newPoints, 1e-6*mesh_.bounds().mag());
705  }
706 }
707 
708 
710 {
711  // Make sure to clear out tetPtIs since used in checks (sometimes, should
712  // really check)
713  mesh_.clearAdditionalGeom();
714  pp_.movePoints(mesh_.points());
715 }
716 
717 
719 (
720  const scalar errorReduction
721 )
722 {
723  scalar oldErrorReduction = readScalar(paramDict_.lookup("errorReduction"));
724 
725  paramDict_.remove("errorReduction");
726  paramDict_.add("errorReduction", errorReduction);
727 
728  return oldErrorReduction;
729 }
730 
731 
733 (
734  labelList& checkFaces,
735  const bool smoothMesh,
736  const label nAllowableErrors
737 )
738 {
739  List<labelPair> emptyBaffles;
740  return scaleMesh
741  (
742  checkFaces,
743  emptyBaffles,
744  smoothMesh,
745  nAllowableErrors
746  );
747 }
748 
749 
751 (
752  labelList& checkFaces,
753  const List<labelPair>& baffles,
754  const bool smoothMesh,
755  const label nAllowableErrors
756 )
757 {
758  return scaleMesh
759  (
760  checkFaces,
761  baffles,
762  paramDict_,
763  paramDict_,
764  smoothMesh,
765  nAllowableErrors
766  );
767 }
768 
769 
771 {
772  // Set newPoints as old + scale*displacement
773 
774  // Create overall displacement with same b.c.s as displacement_
775  wordList actualPatchTypes;
776  {
777  const pointBoundaryMesh& pbm = displacement_.mesh().boundary();
778  actualPatchTypes.setSize(pbm.size());
779  forAll(pbm, patchI)
780  {
781  actualPatchTypes[patchI] = pbm[patchI].type();
782  }
783  }
784 
785  wordList actualPatchFieldTypes;
786  {
788  displacement_.boundaryField();
789  actualPatchFieldTypes.setSize(pfld.size());
790  forAll(pfld, patchI)
791  {
792  if (isA<fixedValuePointPatchField<vector> >(pfld[patchI]))
793  {
794  // Get rid of funny
795  actualPatchFieldTypes[patchI] =
797  }
798  else
799  {
800  actualPatchFieldTypes[patchI] = pfld[patchI].type();
801  }
802  }
803  }
804 
805  pointVectorField totalDisplacement
806  (
807  IOobject
808  (
809  "totalDisplacement",
810  mesh_.time().timeName(),
811  mesh_,
814  false
815  ),
816  scale_*displacement_,
817  actualPatchFieldTypes,
818  actualPatchTypes
819  );
820  correctBoundaryConditions(totalDisplacement);
821 
822  if (debug)
823  {
824  Pout<< "scaleMesh : testing sync of totalDisplacement" << endl;
825  testSyncField
826  (
827  totalDisplacement,
828  maxMagEqOp(),
829  vector::zero, // null value
830  1e-6*mesh_.bounds().mag()
831  );
832  }
833 
834  tmp<pointField> tnewPoints(oldPoints_ + totalDisplacement.internalField());
835 
836  // Correct for 2-D motion
837  modifyMotionPoints(tnewPoints());
838 
839  return tnewPoints;
840 }
841 
842 
844 (
845  labelList& checkFaces,
846  const List<labelPair>& baffles,
847  const dictionary& paramDict,
848  const dictionary& meshQualityDict,
849  const bool smoothMesh,
850  const label nAllowableErrors
851 )
852 {
853  if (!smoothMesh && adaptPatchIDs_.empty())
854  {
856  << "You specified both no movement on the internal mesh points"
857  << " (smoothMesh = false)" << nl
858  << "and no movement on the patch (adaptPatchIDs is empty)" << nl
859  << "Hence nothing to adapt."
860  << exit(FatalError);
861  }
862 
863  if (debug)
864  {
865  // Had a problem with patches moved non-synced. Check transformations.
866  const polyBoundaryMesh& patches = mesh_.boundaryMesh();
867 
868  Pout<< "Entering scaleMesh : coupled patches:" << endl;
869  forAll(patches, patchI)
870  {
871  if (patches[patchI].coupled())
872  {
873  const coupledPolyPatch& pp =
874  refCast<const coupledPolyPatch>(patches[patchI]);
875 
876  Pout<< '\t' << patchI << '\t' << pp.name()
877  << " parallel:" << pp.parallel()
878  << " separated:" << pp.separated()
879  << " forwardT:" << pp.forwardT().size()
880  << endl;
881  }
882  }
883  }
884 
885  const scalar errorReduction =
886  readScalar(paramDict.lookup("errorReduction"));
887  const label nSmoothScale =
888  readLabel(paramDict.lookup("nSmoothScale"));
889 
890 
891  // Note: displacement_ should already be synced already from setDisplacement
892  // but just to make sure.
894  (
895  mesh_,
896  displacement_,
897  maxMagEqOp(),
898  vector::zero // null value
899  );
900 
901  Info<< "Moving mesh using displacement scaling :"
902  << " min:" << gMin(scale_.internalField())
903  << " max:" << gMax(scale_.internalField())
904  << endl;
905 
906  // Get points using current displacement and scale. Optionally 2D corrected.
907  pointField newPoints(curPoints());
908 
909  // Move. No need to do 2D correction since curPoints already done that.
910  mesh_.movePoints(newPoints);
911  movePoints();
912 
913 
914  // Check. Returns parallel number of incorrect faces.
915  faceSet wrongFaces(mesh_, "wrongFaces", mesh_.nFaces()/100+100);
916  checkMesh(false, mesh_, meshQualityDict, checkFaces, baffles, wrongFaces);
917 
918  if (returnReduce(wrongFaces.size(), sumOp<label>()) <= nAllowableErrors)
919  {
920  return true;
921  }
922  else
923  {
924  // Sync across coupled faces by extending the set.
925  wrongFaces.sync(mesh_);
926 
927  // Special case:
928  // if errorReduction is set to zero, extend wrongFaces
929  // to face-Cell-faces to ensure quick return to previously valid mesh
930 
931  if (mag(errorReduction) < SMALL)
932  {
933  labelHashSet newWrongFaces(wrongFaces);
934  forAllConstIter(labelHashSet, wrongFaces, iter)
935  {
936  label own = mesh_.faceOwner()[iter.key()];
937  const cell& ownFaces = mesh_.cells()[own];
938 
939  forAll(ownFaces, cfI)
940  {
941  newWrongFaces.insert(ownFaces[cfI]);
942  }
943 
944  if (iter.key() < mesh_.nInternalFaces())
945  {
946  label nei = mesh_.faceNeighbour()[iter.key()];
947  const cell& neiFaces = mesh_.cells()[nei];
948 
949  forAll(neiFaces, cfI)
950  {
951  newWrongFaces.insert(neiFaces[cfI]);
952  }
953  }
954  }
955  wrongFaces.transfer(newWrongFaces);
956  wrongFaces.sync(mesh_);
957  }
958 
959 
960  // Find out points used by wrong faces and scale displacement.
961  // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
962 
963  pointSet usedPoints(mesh_, "usedPoints", getPoints(wrongFaces));
964  usedPoints.sync(mesh_);
965 
966 
967 
968  // Grow a few layers to determine
969  // - points to be smoothed
970  // - faces to be checked in next iteration
971  PackedBoolList isAffectedPoint(mesh_.nPoints());
972  getAffectedFacesAndPoints
973  (
974  nSmoothScale, // smoothing iterations
975  wrongFaces, // error faces
976  checkFaces,
977  isAffectedPoint
978  );
979 
980  if (debug)
981  {
982  Pout<< "Faces in error:" << wrongFaces.size()
983  << " with points:" << usedPoints.size()
984  << endl;
985  }
986 
987  if (adaptPatchIDs_.size())
988  {
989  // Scale conflicting patch points
990  scaleField(pp_.meshPoints(), usedPoints, errorReduction, scale_);
991  //subtractField(pp_.meshPoints(), usedPoints, 0.1, scale_);
992  }
993  if (smoothMesh)
994  {
995  // Scale conflicting internal points
996  scaleField(usedPoints, errorReduction, scale_);
997  //subtractField(usedPoints, 0.1, scale_);
998  }
999 
1000  scalarField eWeights(calcEdgeWeights(oldPoints_));
1001 
1002  for (label i = 0; i < nSmoothScale; i++)
1003  {
1004  if (adaptPatchIDs_.size())
1005  {
1006  // Smooth patch values
1007  pointScalarField oldScale(scale_);
1008  minSmooth
1009  (
1010  eWeights,
1011  isAffectedPoint,
1012  pp_.meshPoints(),
1013  oldScale,
1014  scale_
1015  );
1016  checkFld(scale_);
1017  }
1018  if (smoothMesh)
1019  {
1020  // Smooth internal values
1021  pointScalarField oldScale(scale_);
1022  minSmooth(eWeights, isAffectedPoint, oldScale, scale_);
1023  checkFld(scale_);
1024  }
1025  }
1026 
1028  (
1029  mesh_,
1030  scale_,
1031  maxEqOp<scalar>(),
1032  -GREAT // null value
1033  );
1034 
1035 
1036  if (debug)
1037  {
1038  Pout<< "scale_ after smoothing :"
1039  << " min:" << Foam::gMin(scale_)
1040  << " max:" << Foam::gMax(scale_)
1041  << endl;
1042  }
1043 
1044  return false;
1045  }
1046 }
1047 
1048 
1050 {
1051  const pointBoundaryMesh& patches = pMesh_.boundary();
1052 
1053  // Check whether displacement has fixed value b.c. on adaptPatchID
1054  forAll(adaptPatchIDs_, i)
1055  {
1056  label patchI = adaptPatchIDs_[i];
1057 
1058  if
1059  (
1060  !isA<fixedValuePointPatchVectorField>
1061  (
1062  displacement_.boundaryField()[patchI]
1063  )
1064  )
1065  {
1067  << "Patch " << patches[patchI].name()
1068  << " has wrong boundary condition "
1069  << displacement_.boundaryField()[patchI].type()
1070  << " on field " << displacement_.name() << nl
1071  << "Only type allowed is "
1072  << fixedValuePointPatchVectorField::typeName
1073  << exit(FatalError);
1074  }
1075  }
1076 
1077 
1078  // Determine internal points. Note that for twoD there are no internal
1079  // points so we use the points of adaptPatchIDs instead
1080 
1081  const labelList& meshPoints = pp_.meshPoints();
1082 
1083  forAll(meshPoints, i)
1084  {
1085  isInternalPoint_.unset(meshPoints[i]);
1086  }
1087 
1088  // Calculate master edge addressing
1089  isMasterEdge_ = syncTools::getMasterEdges(mesh_);
1090 }
1091 
1092 
1093 // ************************************************************************* //
Foam::pointConstraints::constrainCorners
void constrainCorners(GeometricField< Type, pointPatchField, pointMesh > &pf) const
Apply patch-patch constraints only.
Definition: pointConstraintsTemplates.C:114
Foam::GeometricField::GeometricBoundaryField::evaluate
void evaluate()
Evaluate boundary conditions.
Definition: GeometricBoundaryField.C:465
Foam::polyMesh::points
virtual const pointField & points() const
Return raw points.
Definition: polyMesh.C:979
Foam::scalarField
Field< scalar > scalarField
Specialisation of Field<T> for scalar.
Definition: primitiveFieldsFwd.H:48
Foam::IOobject
IOobject defines the attributes of an object for which implicit objectRegistry management is supporte...
Definition: IOobject.H:91
meshTools.H
Foam::PackedBoolList
A bit-packed bool list.
Definition: PackedBoolList.H:63
Foam::motionSmootherAlgo::setErrorReduction
scalar setErrorReduction(const scalar)
Set the errorReduction (by how much to scale the displacement.
Definition: motionSmootherAlgo.C:719
Foam::pointMesh::boundary
const pointBoundaryMesh & boundary() const
Return reference to boundary mesh.
Definition: pointMesh.H:106
Foam::Vector< scalar >::zero
static const Vector zero
Definition: Vector.H:80
Foam::polyMeshGenChecks::checkMesh
bool checkMesh(const polyMeshGen &mesh, const bool report)
Check mesh for correctness. Returns false for no error.
Definition: polyMeshGenChecks.C:104
Foam::motionSmootherAlgo::modifyMotionPoints
void modifyMotionPoints(pointField &newPoints) const
Apply optional point constraint (2d correction)
Definition: motionSmootherAlgo.C:659
Foam::motionSmootherAlgo::getPoints
labelHashSet getPoints(const labelHashSet &) const
Get points used by given faces.
Definition: motionSmootherAlgo.C:94
Foam::returnReduce
T returnReduce(const T &Value, const BinaryOp &bop, const int tag=Pstream::msgType(), const label comm=UPstream::worldComm)
Definition: PstreamReduceOps.H:86
Foam::polyBoundaryMesh
Foam::polyBoundaryMesh.
Definition: polyBoundaryMesh.H:60
Foam::motionSmootherAlgo::correctBoundaryConditions
void correctBoundaryConditions(pointVectorField &) const
Special correctBoundaryConditions which evaluates fixedValue.
Definition: motionSmootherAlgo.C:595
Foam::HashTable::toc
List< Key > toc() const
Return the table of contents.
Definition: HashTable.C:201
Foam::twoDPointCorrector::planeNormal
const vector & planeNormal() const
Return plane normal.
Definition: twoDPointCorrector.C:248
Foam::UPstream::scheduled
@ scheduled
Definition: UPstream.H:67
forAll
#define forAll(list, i)
Loop across all elements in list.
Definition: UList.H:406
Foam::HashTable::transfer
void transfer(HashTable< T, Key, Hash > &)
Transfer the contents of the argument table into this table.
Definition: HashTable.C:518
Foam::tmp
A class for managing temporary objects.
Definition: PtrList.H:118
Foam::meshTools::writeOBJ
void writeOBJ(Ostream &os, const point &pt)
Write obj representation of point.
Definition: meshTools.C:203
Foam::motionSmootherAlgo::correct
void correct()
Take over existing mesh position.
Definition: motionSmootherAlgo.C:413
Foam::motionSmootherAlgo::updateMesh
void updateMesh()
Update for new mesh topology.
Definition: motionSmootherAlgo.C:1049
Foam::motionSmootherAlgo::patch
const indirectPrimitivePatch & patch() const
Reference to patch.
Definition: motionSmootherAlgo.C:395
Foam::motionSmootherAlgo::adaptPatchIDs
const labelList & adaptPatchIDs() const
Patch labels that are being adapted.
Definition: motionSmootherAlgo.C:401
Foam::coupledPolyPatch::forwardT
virtual const tensorField & forwardT() const
Return face transformation tensor.
Definition: coupledPolyPatch.H:294
Foam::PackedBoolList::set
void set(const PackedList< 1 > &)
Set specified bits.
Definition: PackedBoolList.C:169
Foam::motionSmootherAlgo::checkFld
static void checkFld(const pointScalarField &)
Definition: motionSmootherAlgo.C:75
Foam::motionSmootherAlgo::curPoints
tmp< pointField > curPoints() const
Get the current points (oldPoints+scale*displacement)
Definition: motionSmootherAlgo.C:770
Foam::dictionary::lookup
ITstream & lookup(const word &, bool recursive=false, bool patternMatch=true) const
Find and return an entry data stream.
Definition: dictionary.C:449
Foam::edge
An edge is a list of two point labels. The functionality it provides supports the discretisation on a...
Definition: edge.H:58
Foam::maxEqOp
Definition: ops.H:77
Foam::motionSmootherAlgo::scaleMesh
bool scaleMesh(labelList &checkFaces, const bool smoothMesh=true, const label nAllow=0)
Move mesh with given scale. Return true if mesh ok or has.
Definition: motionSmootherAlgo.C:733
Foam::GeometricField::boundaryField
GeometricBoundaryField & boundaryField()
Return reference to GeometricBoundaryField.
Definition: GeometricField.C:735
Foam::faceSet
A list of face labels.
Definition: faceSet.H:48
Foam::endl
Ostream & endl(Ostream &os)
Add newline and flush stream.
Definition: Ostream.H:251
Foam::coupledPolyPatch
The coupledPolyPatch is an abstract base class for patches that couple regions of the computational d...
Definition: coupledPolyPatch.H:51
Foam::motionSmootherAlgo::setDisplacementPatchFields
void setDisplacementPatchFields()
Set patch fields on displacement to be consistent with.
Definition: motionSmootherAlgo.C:485
Foam::mag
dimensioned< scalar > mag(const dimensioned< Type > &)
Foam::HashSet< label, Hash< label > >
Foam::motionSmootherAlgo::subtractField
void subtractField(const labelHashSet &pointLabels, const scalar f, pointScalarField &) const
Lower on internal points.
Definition: motionSmootherAlgo.C:245
syncTools.H
Foam::polyMesh
Mesh consisting of general polyhedral cells.
Definition: polyMesh.H:74
Foam::IOobject::NO_WRITE
@ NO_WRITE
Definition: IOobject.H:118
Foam::MeshObject< pointMesh, UpdateableMeshObject, pointConstraints >::New
static const pointConstraints & New(const pointMesh &mesh)
Definition: MeshObject.C:44
Foam::PackedList::setSize
void setSize(const label, const unsigned int &val=0u)
Alias for resize()
Definition: PackedListI.H:823
forAllConstIter
forAllConstIter(PtrDictionary< phaseModel >, mixture.phases(), phase)
Definition: pEqn.H:39
OFstream.H
Foam::IOobject::db
const objectRegistry & db() const
Return the local objectRegistry.
Definition: IOobject.C:239
Foam::faceSet::sync
virtual void sync(const polyMesh &mesh)
Sync faceSet across coupled patches.
Definition: faceSet.C:113
Foam::coupledPolyPatch::parallel
virtual bool parallel() const
Are the cyclic planes parallel.
Definition: coupledPolyPatch.H:288
Foam::twoDPointCorrector
Class applies a two-dimensional correction to mesh motion point field.
Definition: twoDPointCorrector.H:61
Foam::UPstream::blocking
@ blocking
Definition: UPstream.H:66
Foam::coupledPolyPatch::separated
virtual bool separated() const
Are the planes separated.
Definition: coupledPolyPatch.H:276
Foam::primitiveMesh::nPoints
label nPoints() const
Definition: primitiveMeshI.H:35
Foam::fixedValuePointPatchField< vector >
Foam::label
intWM_LABEL_SIZE_t label
A label is an int32_t or int64_t as specified by the pre-processor macro WM_LABEL_SIZE.
Definition: label.H:59
Foam::motionSmootherAlgo::~motionSmootherAlgo
~motionSmootherAlgo()
Destructor.
Definition: motionSmootherAlgo.C:377
Foam::Field
Pre-declare SubField and related Field type.
Definition: Field.H:57
Foam::motionSmootherAlgo::isInternalPoint
bool isInternalPoint(const label pointI) const
Helper function. Is point internal?
Definition: motionSmootherAlgo.C:285
Foam::IOobject::NO_READ
@ NO_READ
Definition: IOobject.H:111
Foam::nl
static const char nl
Definition: Ostream.H:260
Foam::Info
messageStream Info
Foam::minEqOp
Definition: ops.H:78
pointConstraints.H
Foam::motionSmootherAlgo::testSyncPositions
void testSyncPositions(const pointField &, const scalar maxMag) const
Test synchronisation of points.
Definition: motionSmootherAlgo.C:47
faceSet.H
Foam::GeometricField::internalField
InternalField & internalField()
Return internal field.
Definition: GeometricField.C:724
Foam::pointSet::sync
virtual void sync(const polyMesh &mesh)
Sync set across coupled patches. Adds coupled points to set.
Definition: pointSet.C:113
Foam::pointBoundaryMesh::mesh
const pointMesh & mesh() const
Return the mesh reference.
Definition: pointBoundaryMesh.H:93
Foam::FatalError
error FatalError
Foam::dictionary
A list of keyword definitions, which are a keyword followed by any number of values (e....
Definition: dictionary.H:137
Foam::HashTable::size
label size() const
Return number of elements in table.
Definition: HashTableI.H:65
mesh
dynamicFvMesh & mesh
Definition: createDynamicFvMesh.H:18
fld
gmvFile<< "tracers "<< particles.size()<< nl;forAllConstIter(Cloud< passiveParticle >, particles, iter){ gmvFile<< iter().position().x()<< ' ';}gmvFile<< nl;forAllConstIter(Cloud< passiveParticle >, particles, iter){ gmvFile<< iter().position().y()<< ' ';}gmvFile<< nl;forAllConstIter(Cloud< passiveParticle >, particles, iter){ gmvFile<< iter().position().z()<< ' ';}gmvFile<< nl;forAll(lagrangianScalarNames, i){ const word &name=lagrangianScalarNames[i];IOField< scalar > fld(IOobject(name, runTime.timeName(), cloud::prefix, mesh, IOobject::MUST_READ, IOobject::NO_WRITE))
Foam::HashTable::found
bool found(const Key &) const
Return true if hashedEntry is found in table.
Definition: HashTable.C:109
Foam
Namespace for OpenFOAM.
Definition: combustionModel.C:30
Foam::pointMesh
Mesh representing a set of points created from polyMesh.
Definition: pointMesh.H:48
Foam::abort
errorManip< error > abort(error &err)
Definition: errorManip.H:131
Foam::PackedList::get
unsigned int get(const label) const
Get value at index I.
Definition: PackedListI.H:964
Foam::e
const double e
Elementary charge.
Definition: doubleFloat.H:94
Foam::motionSmootherAlgo::motionSmootherAlgo
motionSmootherAlgo(const motionSmootherAlgo &)
Disallow default bitwise copy construct.
Foam::motionSmootherAlgo::paramDict
const dictionary & paramDict() const
Definition: motionSmootherAlgo.C:407
fixedValuePointPatchFields.H
Foam::exit
errorManipArg< error, int > exit(error &err, const int errNo=1)
Definition: errorManip.H:124
Foam::OFstream
Output to file stream.
Definition: OFstream.H:81
Foam::syncTools::getMasterEdges
static PackedBoolList getMasterEdges(const polyMesh &)
Get per edge whether it is uncoupled or a master of a.
Definition: syncTools.C:109
Foam::pointBoundaryMesh
Foam::pointBoundaryMesh.
Definition: pointBoundaryMesh.H:52
Foam::max
dimensioned< Type > max(const dimensioned< Type > &, const dimensioned< Type > &)
Foam::List::setSize
void setSize(const label)
Reset size of List.
FatalErrorInFunction
#define FatalErrorInFunction
Report an error message using Foam::FatalError.
Definition: error.H:318
Foam::motionSmootherAlgo::getAffectedFacesAndPoints
void getAffectedFacesAndPoints(const label nPointIter, const faceSet &wrongFaces, labelList &affectedFaces, PackedBoolList &isAffectedPoint) const
Given a set of faces that cause smoothing and a number of.
Definition: motionSmootherAlgo.C:292
Foam::sumOp
Definition: ops.H:162
Foam::pointSet
A set of point labels.
Definition: pointSet.H:48
Foam::readScalar
bool readScalar(const char *buf, doubleScalar &s)
Read whole of buf as a scalar. Return true if succesful.
Definition: doubleScalar.H:63
Foam::Pout
prefixOSstream Pout(cout, "Pout")
Definition: IOstreams.H:53
correctBoundaryConditions
U correctBoundaryConditions()
f
labelList f(nPoints)
Foam::Vector< scalar >
Foam::isA
bool isA(const Type &t)
Check if a dynamic_cast to typeid is possible.
Definition: typeInfo.H:134
Foam::List
A 1D array of objects of type <T>, where the size of the vector is known and used for subscript bound...
Definition: HashTable.H:59
Foam::globalMeshData::coupledPatch
const indirectPrimitivePatch & coupledPatch() const
Return patch of all coupled faces.
Definition: globalMeshData.C:2046
Foam::motionSmootherAlgo::mesh
const polyMesh & mesh() const
Reference to mesh.
Definition: motionSmootherAlgo.C:383
motionSmootherAlgo.H
Foam::motionSmootherAlgo::setDisplacement
static void setDisplacement(const labelList &patchIDs, const indirectPrimitivePatch &pp, pointField &patchDisp, pointVectorField &displacement)
Set displacement field from displacement on patch points.
Definition: motionSmootherAlgo.C:492
points
const pointField & points
Definition: gmvOutputHeader.H:1
Foam::PtrList::size
label size() const
Return the number of elements in the PtrList.
Definition: PtrListI.H:32
Foam::HashSet::insert
bool insert(const Key &key)
Insert a new entry.
Definition: HashSet.H:116
Foam::motionSmootherAlgo::maxMagEqOp
To synchronise displacements. We want max displacement since.
Definition: motionSmootherAlgo.H:104
Foam::readLabel
label readLabel(Istream &is)
Definition: label.H:64
Foam::twoDPointCorrector::required
bool required() const
Is 2D correction required, i.e. is the mesh a wedge or slab.
Definition: twoDPointCorrector.H:130
Foam::motionSmootherAlgo::movePoints
void movePoints()
Update for new mesh geometry.
Definition: motionSmootherAlgo.C:709
Foam::motionSmootherAlgo::pMesh
const pointMesh & pMesh() const
Reference to pointMesh.
Definition: motionSmootherAlgo.C:389
twoDPointCorrector.H
patches
patches[0]
Definition: createSingleCellMesh.H:36
Foam::face
A face is a list of labels corresponding to mesh vertices.
Definition: face.H:75
Foam::pointConstraints::constrain
void constrain(GeometricField< Type, pointPatchField, pointMesh > &pf, const bool overrideValue=false) const
Apply boundary conditions (single-patch constraints) and.
Definition: pointConstraintsTemplates.C:131
Foam::twoDPointCorrector::normalEdgeIndices
const labelList & normalEdgeIndices() const
Return indices of normal edges.
Definition: twoDPointCorrector.C:259
Foam::OFstream::name
const fileName & name() const
Return the name of the stream.
Definition: OFstream.H:118
Foam::List::size
void size(const label)
Override size to be inconsistent with allocated storage.
Foam::twoDPointCorrector::correctPoints
void correctPoints(pointField &p) const
Correct motion points.
Definition: twoDPointCorrector.C:270
Foam::gMin
Type gMin(const FieldField< Field, Type > &f)
Definition: FieldFieldFunctions.C:563
Foam::motionSmootherAlgo::scaleField
void scaleField(const labelHashSet &pointLabels, const scalar scale, pointScalarField &) const
Scale certain (internal) points of a field.
Definition: motionSmootherAlgo.C:203
Foam::polyMesh::globalData
const globalMeshData & globalData() const
Return parallel info.
Definition: polyMesh.C:1143
Foam::point
vector point
Point is a vector.
Definition: point.H:41
Foam::PrimitivePatch::meshPoints
const labelList & meshPoints() const
Return labelList of mesh points in patch.
Definition: PrimitivePatchTemplate.C:392
Foam::GeometricField
Generic GeometricField class.
Definition: surfaceFieldsFwd.H:52
Foam::motionSmootherAlgo::minSmooth
void minSmooth(const scalarField &edgeWeights, const PackedBoolList &isAffectedPoint, const pointScalarField &fld, pointScalarField &newFld) const
Explicit smoothing and min on all affected internal points.
Definition: motionSmootherAlgo.C:169
Foam::IOobject::path
fileName path() const
Return complete path.
Definition: IOobject.C:293
Foam::defineTypeNameAndDebug
defineTypeNameAndDebug(combustionModel, 0)
Foam::min
dimensioned< Type > min(const dimensioned< Type > &, const dimensioned< Type > &)
Foam::patchIdentifier::name
const word & name() const
Return name.
Definition: patchIdentifier.H:109
WarningInFunction
#define WarningInFunction
Report a warning using Foam::Warning.
Definition: messageStream.H:259
Foam::cell
A cell is defined as a list of faces with extra functionality.
Definition: cell.H:56
Foam::GeometricField::GeometricBoundaryField
Definition: GeometricField.H:105
pointLabels
labelList pointLabels(nPoints, -1)
Foam::motionSmootherAlgo::calcEdgeWeights
tmp< scalarField > calcEdgeWeights(const pointField &) const
Calculate per-edge weight.
Definition: motionSmootherAlgo.C:115
Foam::gMax
Type gMax(const FieldField< Field, Type > &f)
Definition: FieldFieldFunctions.C:562
Foam::syncTools::syncPointList
static void syncPointList(const polyMesh &, List< T > &, const CombineOp &cop, const T &nullValue, const TransformOp &top)
Synchronize values on all mesh points.
Definition: syncToolsTemplates.C:984
Foam::PrimitivePatch
A list of faces which address into the list of points.
Definition: PrimitivePatchTemplate.H:88
pointSet.H