cellVolumeWeightCellCellStencil.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) 2014-2020 OpenCFD Ltd.
9 -------------------------------------------------------------------------------
10 License
11  This file is part of OpenFOAM.
12 
13  OpenFOAM is free software: you can redistribute it and/or modify i
14  under the terms of the GNU General Public License as published by
15  the Free Software Foundation, either version 3 of the License, or
16  (at your option) any later version.
17 
18  OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
19  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
20  FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
21  for more details.
22 
23  You should have received a copy of the GNU General Public License
24  along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
25 
26 \*---------------------------------------------------------------------------*/
27 
30 #include "OBJstream.H"
31 #include "Time.H"
32 #include "meshToMesh.H"
33 #include "cellVolumeWeightMethod.H"
34 #include "fvMeshSubset.H"
35 #include "regionSplit.H"
36 #include "globalIndex.H"
37 #include "oversetFvPatch.H"
39 #include "syncTools.H"
40 #include "dynamicOversetFvMesh.H"
41 
42 // * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
43 
44 namespace Foam
45 {
46 namespace cellCellStencils
47 {
50 }
51 }
52 
53 Foam::scalar
55 
56 
57 // * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
58 
60 (
61  const scalar layerRelax,
62  labelList& allCellTypes,
63  scalarField& allWeight
64 ) const
65 {
66  // Current front
67  bitSet isFront(mesh_.nFaces());
68  // unused: bitSet doneCell(mesh_.nCells());
69 
70  const fvBoundaryMesh& fvm = mesh_.boundary();
71 
72 
73  // 'overset' patches
74 
75  forAll(fvm, patchI)
76  {
77  if (isA<oversetFvPatch>(fvm[patchI]))
78  {
79  //Pout<< "Storing faces on patch " << fvm[patchI].name() << endl;
80  forAll(fvm[patchI], i)
81  {
82  isFront.set(fvm[patchI].start()+i);
83  }
84  }
85  }
86 
87 
88  // Outside of 'hole' region
89  {
90  const labelList& own = mesh_.faceOwner();
91  const labelList& nei = mesh_.faceNeighbour();
92 
93  for (label faceI = 0; faceI < mesh_.nInternalFaces(); faceI++)
94  {
95  label ownType = allCellTypes[own[faceI]];
96  label neiType = allCellTypes[nei[faceI]];
97  if
98  (
99  (ownType == HOLE && neiType != HOLE)
100  || (ownType != HOLE && neiType == HOLE)
101  )
102  {
103  //Pout<< "Front at face:" << faceI
104  // << " at:" << mesh_.faceCentres()[faceI] << endl;
105  isFront.set(faceI);
106  }
107  }
108 
109  labelList nbrCellTypes;
110  syncTools::swapBoundaryCellList(mesh_, allCellTypes, nbrCellTypes);
111 
112  for
113  (
114  label faceI = mesh_.nInternalFaces();
115  faceI < mesh_.nFaces();
116  faceI++
117  )
118  {
119  label ownType = allCellTypes[own[faceI]];
120  label neiType = nbrCellTypes[faceI-mesh_.nInternalFaces()];
121 
122  if
123  (
124  (ownType == HOLE && neiType != HOLE)
125  || (ownType != HOLE && neiType == HOLE)
126  )
127  {
128  //Pout<< "Front at coupled face:" << faceI
129  // << " at:" << mesh_.faceCentres()[faceI] << endl;
130  isFront.set(faceI);
131  }
132  }
133  }
134 
135 
136 
137  // Current interpolation fraction
138  scalar fraction = 1.0;
139 
140  while (fraction > SMALL && returnReduce(isFront.count(), sumOp<label>()))
141  {
142  // Interpolate cells on front
143 
144  Info<< "Front : fraction:" << fraction
145  << " size:" << returnReduce(isFront.count(), sumOp<label>())
146  << endl;
147 
148  bitSet newIsFront(mesh_.nFaces());
149  forAll(isFront, faceI)
150  {
151  if (isFront.test(faceI))
152  {
153  label own = mesh_.faceOwner()[faceI];
154  if (allCellTypes[own] != HOLE)
155  {
156  if (allWeight[own] < fraction)
157  {
158  allWeight[own] = fraction;
159 
160  //if (debug)
161  //{
162  // Pout<< " setting cell "
163  // << mesh_.cellCentres()[own]
164  // << " to " << fraction << endl;
165  //}
166  allCellTypes[own] = INTERPOLATED;
167  newIsFront.set(mesh_.cells()[own]);
168  }
169  }
170  if (mesh_.isInternalFace(faceI))
171  {
172  label nei = mesh_.faceNeighbour()[faceI];
173  if (allCellTypes[nei] != HOLE)
174  {
175  if (allWeight[nei] < fraction)
176  {
177  allWeight[nei] = fraction;
178 
179  //if (debug)
180  //{
181  // Pout<< " setting cell "
182  // << mesh_.cellCentres()[nei]
183  // << " to " << fraction << endl;
184  //}
185 
186  allCellTypes[nei] = INTERPOLATED;
187  newIsFront.set(mesh_.cells()[nei]);
188  }
189  }
190  }
191  }
192  }
193 
194  syncTools::syncFaceList(mesh_, newIsFront, orEqOp<unsigned int>());
195 
196  isFront.transfer(newIsFront);
197 
198  fraction -= layerRelax;
199  }
200 }
201 
202 
204 (
205  const globalIndex& globalCells,
206  const fvMesh& mesh,
207  const labelList& zoneID,
208  const labelListList& stencil,
210 ) const
211 {
212  const fvBoundaryMesh& pbm = mesh.boundary();
213  const labelList& own = mesh.faceOwner();
214  const labelList& nei = mesh.faceNeighbour();
215 
216 
217  // The input cellTypes will be
218  // - HOLE : cell part covered by other-mesh patch
219  // - INTERPOLATED : cell fully covered by other-mesh patch
220  // or next to 'overset' patch
221  // - CALCULATED : otherwise
222  //
223  // so we start a walk from our patches and any cell we cannot reach
224  // (because we walk is stopped by other-mesh patch) is a hole.
225 
226 
227  boolList isBlockedFace(mesh.nFaces(), false);
228  for (label faceI = 0; faceI < mesh.nInternalFaces(); faceI++)
229  {
230  label ownType = cellTypes[own[faceI]];
231  label neiType = cellTypes[nei[faceI]];
232  if
233  (
234  (ownType == HOLE && neiType != HOLE)
235  || (ownType != HOLE && neiType == HOLE)
236  )
237  {
238  isBlockedFace[faceI] = true;
239  }
240  }
241 
242  labelList nbrCellTypes;
243  syncTools::swapBoundaryCellList(mesh, cellTypes, nbrCellTypes);
244 
245  for (label faceI = mesh.nInternalFaces(); faceI < mesh.nFaces(); faceI++)
246  {
247  label ownType = cellTypes[own[faceI]];
248  label neiType = nbrCellTypes[faceI-mesh.nInternalFaces()];
249 
250  if
251  (
252  (ownType == HOLE && neiType != HOLE)
253  || (ownType != HOLE && neiType == HOLE)
254  )
255  {
256  isBlockedFace[faceI] = true;
257  }
258  }
259 
260  regionSplit cellRegion(mesh, isBlockedFace);
261 
262  Info<< typeName << " : detected " << cellRegion.nRegions()
263  << " mesh regions after overset" << nl << endl;
264 
265 
266 
267  // Now we'll have a mesh split according to where there are cells
268  // covered by the other-side patches. See what we can reach from our
269  // real patches
270 
271  // 0 : region not yet determined
272  // 1 : borders blockage so is not ok (but can be overridden by real
273  // patch)
274  // 2 : has real patch in it so is reachable
275  labelList regionType(cellRegion.nRegions(), Zero);
276 
277 
278  // See if any regions borders blockage. Note: isBlockedFace is already
279  // parallel synchronised.
280  {
281  for (label faceI = 0; faceI < mesh.nInternalFaces(); faceI++)
282  {
283  if (isBlockedFace[faceI])
284  {
285  label ownRegion = cellRegion[own[faceI]];
286 
287  if (cellTypes[own[faceI]] != HOLE)
288  {
289  if (regionType[ownRegion] == 0)
290  {
291  //Pout<< "Mark region:" << ownRegion
292  // << " on zone:" << zoneID[own[faceI]]
293  // << " as next to blockage at:"
294  // << mesh.faceCentres()[faceI] << endl;
295  regionType[ownRegion] = 1;
296  }
297  }
298 
299  label neiRegion = cellRegion[nei[faceI]];
300 
301  if (cellTypes[nei[faceI]] != HOLE)
302  {
303  if (regionType[neiRegion] == 0)
304  {
305  //Pout<< "Mark region:" << neiRegion
306  // << " on zone:" << zoneID[nei[faceI]]
307  // << " as next to blockage at:"
308  // << mesh.faceCentres()[faceI] << endl;
309  regionType[neiRegion] = 1;
310  }
311  }
312  }
313  }
314  for
315  (
316  label faceI = mesh.nInternalFaces();
317  faceI < mesh.nFaces();
318  faceI++
319  )
320  {
321  if (isBlockedFace[faceI])
322  {
323  label ownRegion = cellRegion[own[faceI]];
324 
325  if (regionType[ownRegion] == 0)
326  {
327  //Pout<< "Mark region:" << ownRegion
328  // << " on zone:" << zoneID[own[faceI]]
329  // << " as next to blockage at:"
330  // << mesh.faceCentres()[faceI] << endl;
331  regionType[ownRegion] = 1;
332  }
333  }
334  }
335  }
336 
337 
338  // Override with real patches
339  forAll(pbm, patchI)
340  {
341  const fvPatch& fvp = pbm[patchI];
342 
343  if (isA<oversetFvPatch>(fvp))
344  {}
345  else if (!fvPatch::constraintType(fvp.type()))
346  {
347  //Pout<< "Proper patch " << fvp.name() << " of type " << fvp.type()
348  // << endl;
349 
350  const labelList& fc = fvp.faceCells();
351  forAll(fc, i)
352  {
353  label regionI = cellRegion[fc[i]];
354 
355  if (cellTypes[fc[i]] != HOLE && regionType[regionI] != 2)
356  {
357  //Pout<< "reachable region : " << regionI
358  // << " at cell " << mesh.cellCentres()[fc[i]]
359  // << " on zone " << zoneID[fc[i]] << endl;
360  regionType[regionI] = 2;
361  }
362  }
363  }
364  }
365 
366  // Now we've handled
367  // - cells next to blocked cells
368  // - coupled boundaries
369  // Only thing to handle is the interpolation between regions
370 
371 
372  labelListList compactStencil(stencil);
373  List<Map<label>> compactMap;
374  mapDistribute map(globalCells, compactStencil, compactMap);
375 
376  while (true)
377  {
378  // Synchronise region status on processors
379  // (could instead swap status through processor patches)
380  Pstream::listCombineGather(regionType, maxEqOp<label>());
381  Pstream::listCombineScatter(regionType);
382 
383  // Communicate region status through interpolative cells
384  labelList cellRegionType(labelUIndList(regionType, cellRegion));
385  map.distribute(cellRegionType);
386 
387 
388  label nChanged = 0;
389  forAll(pbm, patchI)
390  {
391  const fvPatch& fvp = pbm[patchI];
392 
393  if (isA<oversetFvPatch>(fvp))
394  {
395  const labelUList& fc = fvp.faceCells();
396  forAll(fc, i)
397  {
398  label cellI = fc[i];
399  label regionI = cellRegion[cellI];
400 
401  if (regionType[regionI] != 2)
402  {
403  const labelList& slots = compactStencil[cellI];
404  forAll(slots, i)
405  {
406  label otherType = cellRegionType[slots[i]];
407 
408  if (otherType == 2)
409  {
410  //Pout<< "Reachable through interpolation : "
411  // << regionI << " at cell "
412  // << mesh.cellCentres()[cellI] << endl;
413  regionType[regionI] = 2;
414  nChanged++;
415  break;
416  }
417  }
418  }
419  }
420  }
421  }
422 
423 
424  reduce(nChanged, sumOp<label>());
425  if (nChanged == 0)
426  {
427  break;
428  }
429  }
430 
431 
432  // See which regions have not been visited (regionType == 1)
433  forAll(cellRegion, cellI)
434  {
435  label type = regionType[cellRegion[cellI]];
436  if (type == 1 && cellTypes[cellI] != HOLE)
437  {
438  cellTypes[cellI] = HOLE;
439  }
440  }
441 }
442 
443 
445 (
446  const fvMesh& mesh,
447  const labelList& cellMap,
448  labelList& patchCellTypes
449 ) const
450 {
451  const fvBoundaryMesh& pbm = mesh.boundary();
452 
453  forAll(pbm, patchI)
454  {
455  const fvPatch& fvp = pbm[patchI];
456  const labelList& fc = fvp.faceCells();
457 
458  if (isA<oversetFvPatch>(fvp))
459  {
460  //Pout<< "Marking cells on overset patch " << fvp.name() << endl;
461  forAll(fc, i)
462  {
463  label cellI = fc[i];
464  patchCellTypes[cellMap[cellI]] = OVERSET;
465  }
466  }
467  else if (!fvPatch::constraintType(fvp.type()))
468  {
469  //Pout<< "Marking cells on proper patch " << fvp.name()
470  // << " with type " << fvp.type() << endl;
471  forAll(fc, i)
472  {
473  label cellI = fc[i];
474  if (patchCellTypes[cellMap[cellI]] != OVERSET)
475  {
476  patchCellTypes[cellMap[cellI]] = PATCH;
477  }
478  }
479  }
480  }
481 }
482 
483 
485 (
486  const labelListList& addressing,
487  const labelList& patchTypes,
488  labelList& result
489 ) const
490 {
491  forAll(result, cellI)
492  {
493  const labelList& slots = addressing[cellI];
494  forAll(slots, i)
495  {
496  label type = patchTypes[slots[i]];
497 
498  if (type == OVERSET)
499  {
500  // 'overset' overrides anything
501  result[cellI] = OVERSET;
502  break;
503  }
504  else if (type == PATCH)
505  {
506  // 'patch' overrides -1 and 'other'
507  result[cellI] = PATCH;
508  }
509  else if (result[cellI] == -1)
510  {
511  // 'other' overrides -1 only
512  result[cellI] = OTHER;
513  }
514  }
515  }
516 }
517 
518 
520 (
521  const autoPtr<mapDistribute>& mapPtr,
522  const labelListList& addressing,
523  const labelList& patchTypes,
524  labelList& result
525 ) const
526 {
527  if (result.size() != addressing.size())
528  {
529  FatalErrorInFunction << "result:" << result.size()
530  << " addressing:" << addressing.size() << exit(FatalError);
531  }
532 
533 
534  // Initialise to not-mapped
535  result = -1;
536 
537  if (mapPtr)
538  {
539  // Pull remote data into order of addressing
540  labelList work(patchTypes);
541  mapPtr().distribute(work);
542 
543  interpolatePatchTypes(addressing, work, result);
544  }
545  else
546  {
547  interpolatePatchTypes(addressing, patchTypes, result);
548  }
549 }
550 
551 
553 (
554  const label subZoneID,
555  const fvMesh& subMesh,
556  const labelList& subCellMap,
557 
558  const label donorZoneID,
559  const labelListList& addressing,
560  const List<scalarList>& weights,
561  const labelList& otherCells,
562  const labelList& interpolatedOtherPatchTypes,
563 
564  labelListList& allStencil,
565  scalarListList& allWeights,
566  labelList& allCellTypes,
567  labelList& allDonorID
568 ) const
569 {
570  forAll(subCellMap, subCellI)
571  {
572  label cellI = subCellMap[subCellI];
573 
574  bool validDonors = true;
575  switch (interpolatedOtherPatchTypes[subCellI])
576  {
577  case -1:
578  {
579  validDonors = false;
580  }
581  break;
582 
583  case OTHER:
584  {
585  // No patch interaction so keep valid
586  }
587  break;
588 
589  case PATCH:
590  {
591  // Patch-patch interaction... For now disable always
592  allCellTypes[cellI] = HOLE;
593  validDonors = false;
594 
595  // Alternative is to look at the amount of overlap but this
596  // is not very robust
597  //if (allCellTypes[cellI] != HOLE)
598  //{
599  // scalar overlapVol = sum(weights[subCellI]);
600  // scalar v = mesh_.V()[cellI];
601  // if (overlapVol < (1.0-overlapTolerance_)*v)
602  // {
603  // //Pout<< "** Patch overlap:" << cellI
604  // // << " at:" << mesh_.cellCentres()[cellI] << endl;
605  // allCellTypes[cellI] = HOLE;
606  // validDonors = false;
607  // }
608  //}
609  }
610  break;
611 
612  case OVERSET:
613  {
614  validDonors = false;
615  }
616  break;
617  }
618 
619 
620  if (validDonors)
621  {
622  // There are a few possible choices how to choose between multiple
623  // donor candidates:
624  // 1 highest overlap volume. However this is generally already
625  // 99.9% so you're just measuring truncation error.
626  // 2 smallest donors cells or most donor cells. This is quite
627  // often done but can cause switching of donor zone from one
628  // time step to the other if the donor meshes are non-uniform
629  // and the acceptor cells just happens to be sweeping through
630  // some small donor cells.
631  // 3 nearest zoneID. So zone 0 preferentially interpolates from
632  // zone 1, zone 1 preferentially from zone 2 etc.
633 
634  //- Option 1:
635  //scalar currentVol = sum(allWeights[cellI]);
636  //if (overlapVol[subCellI] > currentVol)
637 
638  //- Option 3:
639  label currentDiff = mag(subZoneID-allDonorID[cellI]);
640  label thisDiff = mag(subZoneID-donorZoneID);
641 
642  if
643  (
644  allDonorID[cellI] == -1
645  || (thisDiff < currentDiff)
646  || (thisDiff == currentDiff && donorZoneID > allDonorID[cellI])
647  )
648  {
649  allWeights[cellI] = weights[subCellI];
650  allStencil[cellI] =
651  labelUIndList(otherCells, addressing[subCellI]);
652  allDonorID[cellI] = donorZoneID;
653  }
654  }
655  }
656 }
657 
658 
659 // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
660 
661 Foam::cellCellStencils::cellVolumeWeight::cellVolumeWeight
662 (
663  const fvMesh& mesh,
664  const dictionary& dict,
665  const bool doUpdate
666 )
667 :
669  dict_(dict),
670  overlapTolerance_(defaultOverlapTolerance_),
671  cellTypes_(labelList(mesh.nCells(), CALCULATED)),
672  interpolationCells_(0),
673  cellInterpolationMap_(),
674  cellStencil_(0),
675  cellInterpolationWeights_(0),
676  cellInterpolationWeight_
677  (
678  IOobject
679  (
680  "cellInterpolationWeight",
681  mesh_.facesInstance(),
682  mesh_,
683  IOobject::NO_READ,
684  IOobject::NO_WRITE,
685  false
686  ),
687  mesh_,
689  zeroGradientFvPatchScalarField::typeName
690  )
691 {
692  // Protect local fields from interpolation
693  nonInterpolatedFields_.insert("cellTypes");
694  nonInterpolatedFields_.insert("cellInterpolationWeight");
695 
696  // For convenience also suppress frequently used displacement field
697  nonInterpolatedFields_.insert("cellDisplacement");
698  nonInterpolatedFields_.insert("grad(cellDisplacement)");
699  const word w("snGradCorr(cellDisplacement)");
700  const word d("((viscosity*faceDiffusivity)*magSf)");
701  nonInterpolatedFields_.insert("surfaceIntegrate(("+d+"*"+w+"))");
702 
703  // Read zoneID
704  this->zoneID();
705 
706  // Read old-time cellTypes
707  IOobject io
708  (
709  "cellTypes",
710  mesh_.time().timeName(),
711  mesh_,
712  IOobject::READ_IF_PRESENT,
713  IOobject::NO_WRITE,
714  false
715  );
716  if (io.typeHeaderOk<volScalarField>(true))
717  {
718  if (debug)
719  {
720  Pout<< "Reading cellTypes from time " << mesh_.time().timeName()
721  << endl;
722  }
723 
724  const volScalarField volCellTypes(io, mesh_);
725  forAll(volCellTypes, celli)
726  {
727  // Round to integer
728  cellTypes_[celli] = volCellTypes[celli];
729  }
730  }
731 
732  if (doUpdate)
733  {
734  update();
735  }
736 }
737 
738 
739 // * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * //
740 
742 {}
743 
744 
745 // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
746 
748 {
749  scalar layerRelax(dict_.getOrDefault("layerRelax", 1.0));
750  const labelIOList& zoneID = this->zoneID();
751 
752  label nZones = gMax(zoneID)+1;
754  forAll(zoneID, cellI)
755  {
756  nCellsPerZone[zoneID[cellI]]++;
757  }
760 
761 
762  Info<< typeName << " : detected " << nZones
763  << " mesh regions" << nl << endl;
764 
765 
767 
768  Info<< incrIndent;
769  forAll(meshParts, zonei)
770  {
771  Info<< indent<< "zone:" << zonei << " nCells:"
772  << nCellsPerZone[zonei] << nl;
773 
774  meshParts.set
775  (
776  zonei,
777  new fvMeshSubset(mesh_, zonei, zoneID)
778  );
779  }
780  Info<< decrIndent;
781 
782 
783 
784  // Current best guess for cells. Includes best stencil. Weights should
785  // add up to volume.
786  labelList allCellTypes(mesh_.nCells(), CALCULATED);
787  labelList allPatchTypes(mesh_.nCells(), OTHER);
788  labelListList allStencil(mesh_.nCells());
789  scalarListList allWeights(mesh_.nCells());
790  // zoneID of donor
791  labelList allDonorID(mesh_.nCells(), -1);
792 
793 
794  // Marking patch cells
795  forAll(meshParts, partI)
796  {
797  const fvMesh& partMesh = meshParts[partI].subMesh();
798  const labelList& partCellMap = meshParts[partI].cellMap();
799 
800  // Mark cells with
801  // - overset boundary
802  // - other, proper boundary
803  // - other cells
804  Info<< "Marking patch-cells on zone " << partI << endl;
805  markPatchCells(partMesh, partCellMap, allPatchTypes);
806  }
807 
808 
809  labelList nCells(count(3, allPatchTypes));
810  Info<< nl
811  << "After patch analysis : nCells : "
812  << returnReduce(allPatchTypes.size(), sumOp<label>()) << nl
813  << incrIndent
814  << indent << "other : " << nCells[OTHER] << nl
815  << indent << "patch : " << nCells[PATCH] << nl
816  << indent << "overset: " << nCells[OVERSET] << nl
817  << decrIndent << endl;
818 
819  globalIndex globalCells(mesh_.nCells());
820 
821 
822  for (label srcI = 0; srcI < meshParts.size()-1; srcI++)
823  {
824  const fvMesh& srcMesh = meshParts[srcI].subMesh();
825  const labelList& srcCellMap = meshParts[srcI].cellMap();
826 
827  for (label tgtI = srcI+1; tgtI < meshParts.size(); tgtI++)
828  {
829  const fvMesh& tgtMesh = meshParts[tgtI].subMesh();
830  const labelList& tgtCellMap = meshParts[tgtI].cellMap();
831 
832  meshToMesh mapper
833  (
834  srcMesh,
835  tgtMesh,
837  HashTable<word>(0), // patchMap,
838  wordList(0), // cuttingPatches
840  false // do not normalise
841  );
842 
843 
844  {
845  // Get tgt patch types on src mesh
846  labelList interpolatedTgtPatchTypes(srcMesh.nCells(), -1);
847  interpolatePatchTypes
848  (
849  mapper.tgtMap(), // How to get remote data local
850  mapper.srcToTgtCellAddr(),
851  labelList(labelUIndList(allPatchTypes, tgtCellMap)),
852  interpolatedTgtPatchTypes
853  );
854 
855  // Get target cell labels in global cell indexing (on overall
856  // mesh)
857  labelList tgtGlobalCells(tgtMesh.nCells());
858  {
859  forAll(tgtCellMap, tgtCellI)
860  {
861  label cellI = tgtCellMap[tgtCellI];
862  tgtGlobalCells[tgtCellI] = globalCells.toGlobal(cellI);
863  }
864  if (mapper.tgtMap())
865  {
866  mapper.tgtMap()->distribute(tgtGlobalCells);
867  }
868  }
869  combineCellTypes
870  (
871  srcI,
872  srcMesh,
873  srcCellMap,
874 
875  tgtI,
876  mapper.srcToTgtCellAddr(),
877  mapper.srcToTgtCellWght(),
878  tgtGlobalCells,
879  interpolatedTgtPatchTypes,
880 
881  // Overall mesh data
882  allStencil,
883  allWeights,
884  allCellTypes,
885  allDonorID
886  );
887  }
888 
889  {
890  // Get src patch types on tgt mesh
891  labelList interpolatedSrcPatchTypes(tgtMesh.nCells(), -1);
892  interpolatePatchTypes
893  (
894  mapper.srcMap(), // How to get remote data local
895  mapper.tgtToSrcCellAddr(),
896  labelList(labelUIndList(allPatchTypes, srcCellMap)),
897  interpolatedSrcPatchTypes
898  );
899 
900  labelList srcGlobalCells(srcMesh.nCells());
901  {
902  forAll(srcCellMap, srcCellI)
903  {
904  label cellI = srcCellMap[srcCellI];
905  srcGlobalCells[srcCellI] = globalCells.toGlobal(cellI);
906  }
907  if (mapper.srcMap())
908  {
909  mapper.srcMap()->distribute(srcGlobalCells);
910  }
911  }
912 
913  combineCellTypes
914  (
915  tgtI,
916  tgtMesh,
917  tgtCellMap,
918 
919  srcI,
920  mapper.tgtToSrcCellAddr(),
921  mapper.tgtToSrcCellWght(),
922  srcGlobalCells,
923  interpolatedSrcPatchTypes,
924 
925  // Overall mesh data
926  allStencil,
927  allWeights,
928  allCellTypes,
929  allDonorID
930  );
931  }
932  }
933  }
934 
935 
936  if (debug)
937  {
939  (
940  createField(mesh_, "allCellTypes", allCellTypes)
941  );
942  tfld().write();
943  }
944 
945 
946  // Use the patch types and weights to decide what to do
947  forAll(allPatchTypes, cellI)
948  {
949  if (allCellTypes[cellI] != HOLE)
950  {
951  switch (allPatchTypes[cellI])
952  {
953  case OVERSET:
954  {
955  // Interpolate. Check if enough overlap
956  scalar v = mesh_.V()[cellI];
957  scalar overlapVol = sum(allWeights[cellI]);
958  if (overlapVol > overlapTolerance_*v)
959  {
960  allCellTypes[cellI] = INTERPOLATED;
961  }
962  else
963  {
964  //Pout<< "Holeing interpolated cell:" << cellI
965  // << " at:" << mesh_.cellCentres()[cellI] << endl;
966  allCellTypes[cellI] = HOLE;
967  allWeights[cellI].clear();
968  allStencil[cellI].clear();
969  }
970  break;
971  }
972  }
973  }
974  }
975 
976 /*
977  // Knock out cell with insufficient interpolation weights
978  forAll(allCellTypes, cellI)
979  {
980  if (allCellTypes[cellI] == INTERPOLATED)
981  {
982  scalar v = mesh_.V()[cellI];
983  scalar overlapVol = sum(allWeights[cellI]);
984  if (overlapVol < (1.0-overlapTolerance_)*v)
985  {
986  //Pout<< "Holeing cell:" << cellI
987  // << " at:" << mesh_.cellCentres()[cellI] << endl;
988  allCellTypes[cellI] = HOLE;
989  allWeights[cellI].clear();
990  allStencil[cellI].clear();
991  }
992  }
993  }
994 */
995  if (debug)
996  {
998  (
999  createField(mesh_, "allCellTypes_patch", allCellTypes)
1000  );
1001  //tfld.ref().correctBoundaryConditions();
1002  tfld().write();
1003  }
1004 
1005 
1006  // Check previous iteration cellTypes_ for any hole->calculated changes
1007  // If so set the cell either to interpolated (if there are donors) or
1008  // holes (if there are no donors). Note that any interpolated cell might
1009  // still be overwritten by the flood filling
1010  {
1011  label nCalculated = 0;
1012 
1013  forAll(cellTypes_, celli)
1014  {
1015  if (allCellTypes[celli] == CALCULATED && cellTypes_[celli] == HOLE)
1016  {
1017  if (allStencil[celli].size() == 0)
1018  {
1019  // Reset to hole
1020  allCellTypes[celli] = HOLE;
1021  allWeights[celli].clear();
1022  allStencil[celli].clear();
1023  }
1024  else
1025  {
1026  allCellTypes[celli] = INTERPOLATED;
1027  nCalculated++;
1028  }
1029  }
1030  }
1031 
1032  if (debug)
1033  {
1034  Pout<< "Detected " << nCalculated << " cells changing from hole"
1035  << " to calculated. Changed these to interpolated"
1036  << endl;
1037  }
1038  }
1039 
1040 
1041  // Mark unreachable bits
1042  findHoles(globalCells, mesh_, zoneID, allStencil, allCellTypes);
1043 
1044  if (debug)
1045  {
1046  tmp<volScalarField> tfld
1047  (
1048  createField(mesh_, "allCellTypes_hole", allCellTypes)
1049  );
1050  //tfld.ref().correctBoundaryConditions();
1051  tfld().write();
1052  }
1053 
1054 
1055  // Add buffer interpolation layer around holes
1056  scalarField allWeight(mesh_.nCells(), Zero);
1057  walkFront(layerRelax, allCellTypes, allWeight);
1058 
1059  if (debug)
1060  {
1061  tmp<volScalarField> tfld
1062  (
1063  createField(mesh_, "allCellTypes_front", allCellTypes)
1064  );
1065  //tfld.ref().correctBoundaryConditions();
1066  tfld().write();
1067  }
1068 
1069  // Normalise weights, Clear storage
1070  forAll(allCellTypes, cellI)
1071  {
1072  if (allCellTypes[cellI] == INTERPOLATED)
1073  {
1074  if (allWeight[cellI] < SMALL || allStencil[cellI].size() == 0)
1075  {
1076  //Pout<< "Clearing cell:" << cellI
1077  // << " at:" << mesh_.cellCentres()[cellI] << endl;
1078  allWeights[cellI].clear();
1079  allStencil[cellI].clear();
1080  allWeight[cellI] = 0.0;
1081  }
1082  else
1083  {
1084  scalar s = sum(allWeights[cellI]);
1085  forAll(allWeights[cellI], i)
1086  {
1087  allWeights[cellI][i] /= s;
1088  }
1089  }
1090  }
1091  else
1092  {
1093  allWeights[cellI].clear();
1094  allStencil[cellI].clear();
1095  }
1096  }
1097 
1098 
1099  // Write to volField for debugging
1100  if (debug)
1101  {
1103  (
1104  IOobject
1105  (
1106  "patchTypes",
1107  mesh_.time().timeName(),
1108  mesh_,
1111  false
1112  ),
1113  mesh_,
1115  zeroGradientFvPatchScalarField::typeName
1116  );
1117 
1118  forAll(patchTypes.internalField(), cellI)
1119  {
1120  patchTypes[cellI] = allPatchTypes[cellI];
1121  }
1122  //patchTypes.correctBoundaryConditions();
1124  <
1127  >(patchTypes.boundaryFieldRef(), false);
1128  patchTypes.write();
1129  }
1130  if (debug)
1131  {
1132  volScalarField volTypes
1133  (
1134  IOobject
1135  (
1136  "cellTypes",
1137  mesh_.time().timeName(),
1138  mesh_,
1141  false
1142  ),
1143  mesh_,
1145  zeroGradientFvPatchScalarField::typeName
1146  );
1147 
1148  forAll(volTypes.internalField(), cellI)
1149  {
1150  volTypes[cellI] = allCellTypes[cellI];
1151  }
1152  //volTypes.correctBoundaryConditions();
1154  <
1157  >(volTypes.boundaryFieldRef(), false);
1158  volTypes.write();
1159  }
1160 
1161 
1162 // // Check previous iteration cellTypes_ for any hole->calculated changes
1163 // {
1164 // label nCalculated = 0;
1165 //
1166 // forAll(cellTypes_, celli)
1167 // {
1168 // if (allCellTypes[celli] == CALCULATED && cellTypes_[celli] == HOLE)
1169 // {
1170 // if (allStencil[celli].size() == 0)
1171 // {
1172 // FatalErrorInFunction
1173 // << "Cell:" << celli
1174 // << " at:" << mesh_.cellCentres()[celli]
1175 // << " zone:" << zoneID[celli]
1176 // << " changed from hole to calculated"
1177 // << " but there is no donor"
1178 // << exit(FatalError);
1179 // }
1180 // else
1181 // {
1182 // allCellTypes[celli] = INTERPOLATED;
1183 // nCalculated++;
1184 // }
1185 // }
1186 // }
1187 //
1188 // if (debug)
1189 // {
1190 // Pout<< "Detected " << nCalculated << " cells changing from hole"
1191 // << " to calculated. Changed these to interpolated"
1192 // << endl;
1193 // }
1194 // }
1195 
1196 
1197  cellTypes_.transfer(allCellTypes);
1198  cellStencil_.transfer(allStencil);
1199  cellInterpolationWeights_.transfer(allWeights);
1200  cellInterpolationWeight_.transfer(allWeight);
1201  //cellInterpolationWeight_.correctBoundaryConditions();
1203  <
1206  >(cellInterpolationWeight_.boundaryFieldRef(), false);
1207 
1208  DynamicList<label> interpolationCells;
1209  forAll(cellStencil_, cellI)
1210  {
1211  if (cellStencil_[cellI].size())
1212  {
1213  interpolationCells.append(cellI);
1214  }
1215  }
1216  interpolationCells_.transfer(interpolationCells);
1217 
1218 
1219  List<Map<label>> compactMap;
1220  cellInterpolationMap_.reset
1221  (
1222  new mapDistribute(globalCells, cellStencil_, compactMap)
1223  );
1224 
1225  // Dump interpolation stencil
1226  if (debug)
1227  {
1228  // Dump weight
1229  cellInterpolationWeight_.instance() = mesh_.time().timeName();
1230  cellInterpolationWeight_.write();
1231 
1232 
1233  mkDir(mesh_.time().timePath());
1234  OBJstream str(mesh_.time().timePath()/"stencil2.obj");
1235  Info<< typeName << " : dumping to " << str.name() << endl;
1236  pointField cc(mesh_.cellCentres());
1237  cellInterpolationMap().distribute(cc);
1238 
1239  forAll(interpolationCells_, compactI)
1240  {
1241  label cellI = interpolationCells_[compactI];
1242  const labelList& slots = cellStencil_[cellI];
1243 
1244  Pout<< "cellI:" << cellI << " at:"
1245  << mesh_.cellCentres()[cellI]
1246  << " calculated from slots:" << slots
1247  << " cc:" << UIndirectList<point>(cc, slots)
1248  << " weights:" << cellInterpolationWeights_[cellI]
1249  << endl;
1250 
1251  forAll(slots, i)
1252  {
1253  const point& donorCc = cc[slots[i]];
1254  const point& accCc = mesh_.cellCentres()[cellI];
1255 
1256  str.write(linePointRef(accCc, 0.1*accCc+0.9*donorCc));
1257  }
1258  }
1259  }
1260 
1261 
1262  {
1263  labelList nCells(count(3, cellTypes_));
1264  Info<< "Overset analysis : nCells : "
1265  << returnReduce(cellTypes_.size(), sumOp<label>()) << nl
1266  << incrIndent
1267  << indent << "calculated : " << nCells[CALCULATED] << nl
1268  << indent << "interpolated : " << nCells[INTERPOLATED] << nl
1269  << indent << "hole : " << nCells[HOLE] << nl
1270  << decrIndent << endl;
1271  }
1272 
1273  // Tbd: detect if anything changed. Most likely it did!
1274  return true;
1275 }
1276 
1277 
1280  const point& sample,
1281  const pointList& donorCcs,
1282  scalarList& weights
1283 ) const
1284 {
1285  // Inverse-distance weighting
1286 
1287  weights.setSize(donorCcs.size());
1288  scalar sum = 0.0;
1289  forAll(donorCcs, i)
1290  {
1291  scalar d = mag(sample-donorCcs[i]);
1292 
1293  if (d > ROOTVSMALL)
1294  {
1295  weights[i] = 1.0/d;
1296  sum += weights[i];
1297  }
1298  else
1299  {
1300  // Short circuit
1301  weights = 0.0;
1302  weights[i] = 1.0;
1303  return;
1304  }
1305  }
1306  forAll(weights, i)
1307  {
1308  weights[i] /= sum;
1309  }
1310 }
1311 
1312 
1313 // ************************************************************************* //
Foam::expressions::patchExpr::debug
int debug
Static debugging option.
nZones
label nZones
Definition: interpolatedFaces.H:24
Foam::IOobject::NO_WRITE
Definition: IOobject.H:195
Foam::labelList
List< label > labelList
A List of labels.
Definition: List.H:67
cellVolumeWeightCellCellStencil.H
Foam::IOobject
Defines the attributes of an object for which implicit objectRegistry management is supported,...
Definition: IOobject.H:169
Foam::meshToMesh::tgtToSrcCellWght
const scalarListList & tgtToSrcCellWght() const
Return const access to the target to source cell weights.
Definition: meshToMeshI.H:63
Foam::dynamicOversetFvMesh::correctBoundaryConditions
static void correctBoundaryConditions(typename GeoField::Boundary &bfld, const bool typeOnly)
Correct boundary conditions of certain type (typeOnly = true)
Definition: dynamicOversetFvMeshTemplates.C:117
Foam::word
A class for handling words, derived from Foam::string.
Definition: word.H:65
Foam::returnReduce
T returnReduce(const T &Value, const BinaryOp &bop, const int tag=Pstream::msgType(), const label comm=UPstream::worldComm)
Definition: PstreamReduceOps.H:94
s
gmvFile<< "tracers "<< particles.size()<< nl;for(const passiveParticle &p :particles){ gmvFile<< p.position().x()<< " ";}gmvFile<< nl;for(const passiveParticle &p :particles){ gmvFile<< p.position().y()<< " ";}gmvFile<< nl;for(const passiveParticle &p :particles){ gmvFile<< p.position().z()<< " ";}gmvFile<< nl;forAll(lagrangianScalarNames, i){ word name=lagrangianScalarNames[i];IOField< scalar > s(IOobject(name, runTime.timeName(), cloud::prefix, mesh, IOobject::MUST_READ, IOobject::NO_WRITE))
Definition: gmvOutputSpray.H:25
Foam::bitSet
A bitSet stores bits (elements with only two states) in packed internal format and supports a variety...
Definition: bitSet.H:63
Foam::cellCellStencils::cellVolumeWeight::~cellVolumeWeight
virtual ~cellVolumeWeight()
Destructor.
Definition: cellVolumeWeightCellCellStencil.C:741
Foam::OBJstream
OFstream that keeps track of vertices.
Definition: OBJstream.H:58
update
mesh update()
Foam::tmp
A class for managing temporary objects.
Definition: PtrList.H:61
Foam::fvMeshSubset
Given the original mesh and the list of selected cells, it creates the mesh consisting only of the de...
Definition: fvMeshSubset.H:73
Foam::Zero
static constexpr const zero Zero
Global zero (0)
Definition: zero.H:131
Foam::DynamicList< label >
fvMeshSubset.H
Foam::meshToMesh::interpolationMethod::imCellVolumeWeight
globalIndex.H
meshToMesh.H
dynamicOversetFvMesh.H
Foam::orEqOp
Definition: ops.H:86
Foam::endl
Ostream & endl(Ostream &os)
Add newline and flush stream.
Definition: Ostream.H:369
Foam::cellCellStencils::cellVolumeWeight
Volume-weighted interpolation stencil.
Definition: cellVolumeWeightCellCellStencil.H:54
Foam::Pout
prefixOSstream Pout
OSstream wrapped stdout (std::cout) with parallel prefix.
Foam::incrIndent
Ostream & incrIndent(Ostream &os)
Increment the indent level.
Definition: Ostream.H:346
Foam::cellCellStencils::cellVolumeWeight::markPatchCells
void markPatchCells(const fvMesh &mesh, const labelList &cellMap, labelList &patchCellTypes) const
according to additionalDocumentation/MEJ_oversetMesh.txt
Definition: cellVolumeWeightCellCellStencil.C:445
syncTools.H
Foam::sumOp
Definition: ops.H:213
forAll
#define forAll(list, i)
Loop across all elements in list.
Definition: stdFoam.H:296
Foam::meshToMesh::srcToTgtCellAddr
const labelListList & srcToTgtCellAddr() const
Return const access to the source to target cell addressing.
Definition: meshToMeshI.H:45
patchTypes
wordList patchTypes(nPatches)
Foam::fvBoundaryMesh
Foam::fvBoundaryMesh.
Definition: fvBoundaryMesh.H:57
Foam::wordList
List< word > wordList
A List of words.
Definition: fileName.H:62
Foam::oversetFvPatchField::write
virtual void write(Ostream &os) const
Write.
Definition: oversetFvPatchField.C:222
Foam::cellCellStencils::cellVolumeWeight::combineCellTypes
void combineCellTypes(const label subZoneID, const fvMesh &subMesh, const labelList &subCellMap, const label donorZoneID, const labelListList &toOtherCells, const List< scalarList > &weights, const labelList &otherCells, const labelList &interpolatedOtherPatchTypes, labelListList &allStencil, scalarListList &allWeights, labelList &allCellTypes, labelList &allDonorID) const
Definition: cellVolumeWeightCellCellStencil.C:553
meshParts
PtrList< fvMeshSubset > meshParts(nZones)
Foam::primitiveMesh::nCells
label nCells() const noexcept
Number of mesh cells.
Definition: primitiveMeshI.H:96
Foam::cellCellStencils::cellVolumeWeight::interpolatePatchTypes
void interpolatePatchTypes(const labelListList &addressing, const labelList &patchTypes, labelList &result) const
interpolate (= combine) patch types
Definition: cellVolumeWeightCellCellStencil.C:485
Foam::meshToMesh
Class to calculate the cell-addressing between two overlapping meshes.
Definition: meshToMesh.H:64
Foam::Field< scalar >
Foam::Info
messageStream Info
Information stream (stdout output on master, null elsewhere)
Foam::List::setSize
void setSize(const label n)
Alias for resize()
Definition: List.H:222
Foam::mapDistribute
Class containing processor-to-processor mapping information.
Definition: mapDistribute.H:163
Foam::fvPatch
A finiteVolume patch using a polyPatch and a fvBoundaryMesh.
Definition: fvPatch.H:65
regionSplit.H
Foam::dimensionedScalar
dimensioned< scalar > dimensionedScalar
Dimensioned scalar obtained from generic dimensioned type.
Definition: dimensionedScalarFwd.H:42
Foam::regionSplit
This class separates the mesh into distinct unconnected regions, each of which is then given a label ...
Definition: regionSplit.H:140
Foam::cellCellStencils::cellVolumeWeight::walkFront
void walkFront(const scalar layerRelax, labelList &allCellTypes, scalarField &allWeight) const
Definition: cellVolumeWeightCellCellStencil.C:60
Foam::PtrList
A list of pointers to objects of type <T>, with allocation/deallocation management of the pointers....
Definition: List.H:59
Foam::volScalarField
GeometricField< scalar, fvPatchField, volMesh > volScalarField
Definition: volFieldsFwd.H:57
Foam::meshToMesh::tgtMap
const autoPtr< mapDistribute > & tgtMap() const
Target map pointer - valid if no singleMeshProc.
Definition: meshToMeshI.H:95
Foam::regionSplit::nRegions
label nRegions() const
Return total number of regions.
Definition: regionSplit.H:294
Foam::mapDistribute::distribute
void distribute(List< T > &fld, const bool dummyTransform=true, const int tag=UPstream::msgType()) const
Distribute data using default commsType.
Definition: mapDistributeTemplates.C:152
dict
dictionary dict
Definition: searchingEngine.H:14
Foam::FatalError
error FatalError
Foam::dictionary
A list of keyword definitions, which are a keyword followed by a number of values (eg,...
Definition: dictionary.H:123
reduce
reduce(hasMovingMesh, orOp< bool >())
mesh
dynamicFvMesh & mesh
Definition: createDynamicFvMesh.H:6
addToRunTimeSelectionTable.H
Macros for easy insertion into run-time selection tables.
zoneID
const labelIOList & zoneID
Definition: interpolatedFaces.H:22
Foam::fvMesh
Mesh data needed to do the Finite Volume discretisation.
Definition: fvMesh.H:85
Foam
Namespace for OpenFOAM.
Definition: atmBoundaryLayer.C:33
Foam::decrIndent
Ostream & decrIndent(Ostream &os)
Decrement the indent level.
Definition: Ostream.H:353
Foam::globalIndex
Calculates a unique integer (label so might not have enough room - 2G max) for processor + local inde...
Definition: globalIndex.H:68
Foam::indent
Ostream & indent(Ostream &os)
Indent stream.
Definition: Ostream.H:339
Foam::meshToMesh::procMapMethod::pmAABB
Foam::maxEqOp
Definition: ops.H:80
nCellsPerZone
labelList nCellsPerZone(nZones, Zero)
Foam::exit
errorManipArg< error, int > exit(error &err, const int errNo=1)
Definition: errorManip.H:130
Foam::cellCellStencils::addToRunTimeSelectionTable
addToRunTimeSelectionTable(cellCellStencil, cellVolumeWeight, mesh)
Foam::HashTable
A HashTable similar to std::unordered_map.
Definition: HashTable.H:105
Foam::Pstream::listCombineGather
static void listCombineGather(const List< commsStruct > &comms, List< T > &Value, const CombineOp &cop, const int tag, const label comm)
Definition: combineGatherScatter.C:290
Time.H
Foam::autoPtr
Pointer management similar to std::unique_ptr, with some additional methods and type checking.
Definition: HashPtrTable.H:53
Foam::linePointRef
line< point, const point & > linePointRef
A line using referred points.
Definition: linePointRef.H:47
FatalErrorInFunction
#define FatalErrorInFunction
Report an error message using Foam::FatalError.
Definition: error.H:453
Foam::cellCellStencils::cellVolumeWeight::findHoles
void findHoles(const globalIndex &globalCells, const fvMesh &mesh, const labelList &zoneID, const labelListList &stencil, labelList &cellTypes) const
Find cells next to cells of type PATCH.
Definition: cellVolumeWeightCellCellStencil.C:204
cellTypes
const labelList & cellTypes
Definition: setCellMask.H:33
Foam::nl
constexpr char nl
Definition: Ostream.H:404
Foam::cellCellStencil
Calculation of interpolation stencils.
Definition: cellCellStencil.H:61
Foam::BitOps::count
unsigned int count(const UList< bool > &bools, const bool val=true)
Count number of 'true' entries.
Definition: BitOps.H:77
Foam::cellCellStencils::cellVolumeWeight::defaultOverlapTolerance_
static scalar defaultOverlapTolerance_
Default overlap tolerance. Fraction of volume.
Definition: cellVolumeWeightCellCellStencil.H:63
Foam::Vector< scalar >
Foam::List< label >
Foam::mag
dimensioned< typename typeOfMag< Type >::type > mag(const dimensioned< Type > &dt)
Foam::UList< label >
Foam::constant::electromagnetic::e
const dimensionedScalar e
Elementary charge.
Definition: createFields.H:11
Foam::PDRpatchDef
Bookkeeping for patch definitions.
Definition: PDRpatchDef.H:53
Foam::IOList< label >
Foam::List::clear
void clear()
Clear the list, i.e. set size to zero.
Definition: ListI.H:116
oversetFvPatch.H
Foam::sum
dimensioned< Type > sum(const DimensionedField< Type, GeoMesh > &df)
Definition: DimensionedFieldFunctions.C:327
Foam::List::set
std::enable_if< std::is_same< bool, TypeT >::value, bool >::type set(const label i, bool val=true)
A bitSet::set() method for a list of bool.
Definition: List.H:341
Foam::roots::type
type
Types of root.
Definition: Roots.H:54
Foam::oversetFvPatchField
Boundary condition for use on overset patches. To be run in combination with special dynamicFvMesh ty...
Definition: oversetFvPatchField.H:56
Foam::fvPatch::faceCells
virtual const labelUList & faceCells() const
Return faceCells.
Definition: fvPatch.C:113
Foam::UIndirectList
A List with indirect addressing.
Definition: faMatrix.H:60
Foam::meshToMesh::tgtToSrcCellAddr
const labelListList & tgtToSrcCellAddr() const
Return const access to the target to source cell addressing.
Definition: meshToMeshI.H:51
cellVolumeWeightMethod.H
Foam::cellCellStencils::defineTypeNameAndDebug
defineTypeNameAndDebug(cellVolumeWeight, 0)
Foam::plusEqOp
Definition: ops.H:72
Foam::PATCH
PDRpatchDef PATCH
Definition: PDRpatchDef.H:112
Foam::Pstream::listCombineScatter
static void listCombineScatter(const List< commsStruct > &comms, List< T > &Value, const int tag, const label comm)
Scatter data. Reverse of combineGather.
Definition: combineGatherScatter.C:432
Foam::meshToMesh::srcMap
const autoPtr< mapDistribute > & srcMap() const
Source map pointer - valid if no singleMeshProc.
Definition: meshToMeshI.H:88
Foam::cellCellStencils::cellVolumeWeight::stencilWeights
virtual void stencilWeights(const point &sample, const pointList &donorCcs, scalarList &weights) const
Calculate inverse distance weights for a single acceptor. Revert.
Definition: cellVolumeWeightCellCellStencil.C:1279
Foam::GeometricField< scalar, fvPatchField, volMesh >
Foam::meshToMesh::srcToTgtCellWght
const scalarListList & srcToTgtCellWght() const
Return const access to the source to target cell weights.
Definition: meshToMeshI.H:57
Foam::IOobject::NO_READ
Definition: IOobject.H:188
Foam::mkDir
bool mkDir(const fileName &pathName, mode_t mode=0777)
Make a directory and return an error if it could not be created.
Definition: MSwindows.C:507
zeroGradientFvPatchFields.H
Foam::gMax
Type gMax(const FieldField< Field, Type > &f)
Definition: FieldFieldFunctions.C:592
OBJstream.H
Foam::dimless
const dimensionSet dimless
Dimensionless.
Definition: dimensionSets.C:189
Foam::globalIndex::toGlobal
label toGlobal(const label i) const
From local to global index.
Definition: globalIndexI.H:240
Foam::cellCellStencils::cellVolumeWeight::update
virtual bool update()
Update stencils. Return false if nothing changed.
Definition: cellVolumeWeightCellCellStencil.C:747
sample
Minimal example by using system/controlDict.functions:
Foam::labelUIndList
UIndirectList< label > labelUIndList
UIndirectList of labels.
Definition: UIndirectList.H:58