47 namespace cellCellStencils
78 for (label faceI = 0; faceI <
mesh.nInternalFaces(); faceI++)
85 || (ownType !=
HOLE && neiType ==
HOLE)
88 isBlockedFace[faceI] =
true;
95 for (label faceI =
mesh.nInternalFaces(); faceI <
mesh.nFaces(); faceI++)
98 label neiType = nbrCellTypes[faceI-
mesh.nInternalFaces()];
102 (ownType ==
HOLE && neiType !=
HOLE)
103 || (ownType !=
HOLE && neiType ==
HOLE)
106 isBlockedFace[faceI] =
true;
112 Info<< typeName <<
" : detected " << cellRegion.
nRegions()
113 <<
" mesh regions after overset" <<
nl <<
endl;
131 for (label faceI = 0; faceI <
mesh.nInternalFaces(); faceI++)
133 if (isBlockedFace[faceI])
135 label ownRegion = cellRegion[own[faceI]];
139 if (regionType[ownRegion] == 0)
145 regionType[ownRegion] = 1;
149 label neiRegion = cellRegion[nei[faceI]];
153 if (regionType[neiRegion] == 0)
159 regionType[neiRegion] = 1;
166 label faceI =
mesh.nInternalFaces();
167 faceI <
mesh.nFaces();
171 if (isBlockedFace[faceI])
173 label ownRegion = cellRegion[own[faceI]];
175 if (regionType[ownRegion] == 0)
181 regionType[ownRegion] = 1;
191 const fvPatch& fvp = pbm[patchI];
193 if (isA<oversetFvPatch>(fvp))
203 label regionI = cellRegion[fc[i]];
210 regionType[regionI] = 2;
240 const fvPatch& fvp = pbm[patchI];
242 if (isA<oversetFvPatch>(fvp))
248 label regionI = cellRegion[cellI];
250 if (regionType[regionI] != 2)
252 const labelList& slots = compactStencil[cellI];
255 label otherType = cellRegionType[slots[i]];
262 regionType[regionI] = 2;
283 label
type = regionType[cellRegion[cellI]];
299 const fvBoundaryMesh& pbm =
mesh.boundary();
303 const fvPatch& fvp = pbm[patchI];
306 if (isA<oversetFvPatch>(fvp))
312 patchCellTypes[cellMap[cellI]] = OVERSET;
322 if (patchCellTypes[cellMap[cellI]] != OVERSET)
324 patchCellTypes[cellMap[cellI]] =
PATCH;
341 const labelList& slots = addressing[cellI];
349 result[cellI] = OVERSET;
355 result[cellI] =
PATCH;
358 else if (result[cellI] == -1)
361 result[cellI] = OTHER;
370 const autoPtr<mapDistribute>& mapPtr,
376 if (result.size() != addressing.size())
390 mapPtr().distribute(work);
392 interpolatePatchTypes(addressing, work, result);
396 interpolatePatchTypes(addressing,
patchTypes, result);
403 const label subZoneID,
407 const label donorZoneID,
411 const labelList& interpolatedOtherPatchTypes,
419 forAll(subCellMap, subCellI)
421 label cellI = subCellMap[subCellI];
423 bool validDonors =
true;
424 switch (interpolatedOtherPatchTypes[subCellI])
441 allCellTypes[cellI] = HOLE;
487 label currentDiff =
mag(subZoneID-allDonorID[cellI]);
488 label thisDiff =
mag(subZoneID-donorZoneID);
492 allDonorID[cellI] == -1
493 || (thisDiff < currentDiff)
494 || (thisDiff == currentDiff && donorZoneID > allDonorID[cellI])
497 allWeights[cellI] = weights[subCellI];
500 allDonorID[cellI] = donorZoneID;
509 Foam::cellCellStencils::cellVolumeWeight::cellVolumeWeight
518 overlapTolerance_(defaultOverlapTolerance_),
520 interpolationCells_(0),
521 cellInterpolationMap_(),
523 cellInterpolationWeights_(0),
524 cellInterpolationWeight_
528 "cellInterpolationWeight",
529 mesh_.facesInstance(),
537 zeroGradientFvPatchScalarField::typeName
539 allowInterpolatedDonors_
541 dict.getOrDefault(
"allowInterpolatedDonors", true)
551 const word w(
"snGradCorr(cellDisplacement)");
552 const word d(
"((viscosity*faceDiffusivity)*magSf)");
580 forAll(volCellTypes, celli)
604 scalar layerRelax(dict_.getOrDefault(
"layerRelax", 1.0));
607 label nZones =
gMax(zoneID)+1;
611 nCellsPerZone[zoneID[cellI]]++;
615 Info<< typeName <<
" : detected " << nZones
616 <<
" mesh regions" <<
nl <<
endl;
624 Info<<
indent<<
"zone:" << zonei <<
" nCells:" 625 << nCellsPerZone[zonei] <<
nl;
638 labelList allCellTypes(mesh_.nCells(), CALCULATED);
639 labelList allPatchTypes(mesh_.nCells(), OTHER);
643 labelList allDonorID(mesh_.nCells(), -1);
649 const fvMesh& partMesh = meshParts[partI].subMesh();
650 const labelList& partCellMap = meshParts[partI].cellMap();
656 Info<<
"Marking patch-cells on zone " << partI <<
endl;
657 markPatchCells(partMesh, partCellMap, allPatchTypes);
660 if ((
debug&2) && (mesh_.time().outputTime()))
664 createField(mesh_,
"allPatchTypes", allPatchTypes)
672 <<
"After patch analysis : nCells : " 675 <<
indent <<
"other : " << nCells[OTHER] <<
nl 677 <<
indent <<
"overset: " << nCells[OVERSET] <<
nl 682 for (label srcI = 0; srcI < meshParts.
size()-1; srcI++)
684 const fvMesh& srcMesh = meshParts[srcI].subMesh();
685 const labelList& srcCellMap = meshParts[srcI].cellMap();
687 for (label tgtI = srcI+1; tgtI < meshParts.
size(); tgtI++)
689 const fvMesh& tgtMesh = meshParts[tgtI].subMesh();
690 const labelList& tgtCellMap = meshParts[tgtI].cellMap();
706 interpolatePatchTypes
711 interpolatedTgtPatchTypes
718 forAll(tgtCellMap, tgtCellI)
720 label cellI = tgtCellMap[tgtCellI];
721 tgtGlobalCells[tgtCellI] = globalCells.
toGlobal(cellI);
725 mapper.
tgtMap()->distribute(tgtGlobalCells);
740 interpolatedTgtPatchTypes,
753 interpolatePatchTypes
758 interpolatedSrcPatchTypes
763 forAll(srcCellMap, srcCellI)
765 label cellI = srcCellMap[srcCellI];
766 srcGlobalCells[srcCellI] = globalCells.
toGlobal(cellI);
770 mapper.
srcMap()->distribute(srcGlobalCells);
784 interpolatedSrcPatchTypes,
797 if ((
debug&2) && (mesh_.time().outputTime()))
801 createField(mesh_,
"allCellTypes", allCellTypes)
807 createField(mesh_,
"allDonorID", allDonorID)
815 forAll(allPatchTypes, cellI)
817 if (allCellTypes[cellI] != HOLE)
819 switch (allPatchTypes[cellI])
824 scalar v = mesh_.V()[cellI];
825 scalar overlapVol =
sum(allWeights[cellI]);
826 if (overlapVol > overlapTolerance_*v)
828 allCellTypes[cellI] = INTERPOLATED;
832 allCellTypes[cellI] = HOLE;
833 allWeights[cellI].
clear();
834 allStencil[cellI].
clear();
843 if ((
debug&2) && (mesh_.time().outputTime()))
847 createField(mesh_,
"allCellTypes_patch", allCellTypes)
854 stencilSize[celli] = allStencil[celli].
size();
858 createField(mesh_,
"allStencil_patch", stencilSize)
860 tfldStencil().write();
865 findHoles(globalCells, mesh_, zoneID, allStencil, allCellTypes);
867 if ((
debug&2) && (mesh_.time().outputTime()))
871 createField(mesh_,
"allCellTypes_hole", allCellTypes)
878 stencilSize[celli] = allStencil[celli].
size();
882 createField(mesh_,
"allStencil_hole", stencilSize)
884 tfldStencil().write();
893 mapDistribute map(globalCells, compactStencil, compactStencilMap);
908 dict_.getOrDefault(
"holeLayers", 1),
909 dict_.getOrDefault(
"useLayer", -1)
913 if ((
debug&2) && (mesh_.time().outputTime()))
917 createField(mesh_,
"allCellTypes_front", allCellTypes)
924 stencilSize[celli] = allStencil[celli].
size();
928 createField(mesh_,
"allStencil_front", stencilSize)
930 tfldStencil().write();
938 label nCalculated = 0;
942 if (allCellTypes[celli] == CALCULATED && cellTypes_[celli] == HOLE)
944 if (allStencil[celli].size() == 0)
947 allCellTypes[celli] = HOLE;
948 allWeights[celli].
clear();
949 allStencil[celli].
clear();
953 allCellTypes[celli] = INTERPOLATED;
961 Pout<<
"Detected " << nCalculated <<
" cells changing from hole" 962 <<
" to calculated. Changed these to interpolated" 968 labelList compactCellTypes(allCellTypes);
971 label nHoleDonors = 0;
972 forAll(allCellTypes, cellI)
974 if (allCellTypes[cellI] == INTERPOLATED)
976 const labelList& slots = compactStencil[cellI];
981 compactCellTypes[slots[0]] == HOLE
984 !allowInterpolatedDonors_
985 && compactCellTypes[slots[0]] == INTERPOLATED
989 allWeights[cellI][subCellI] = 0;
996 allWeights[cellI].
clear();
997 allStencil[cellI].
clear();
1004 forAll(allCellTypes, cellI)
1006 if (allCellTypes[cellI] == INTERPOLATED)
1008 const scalar
s =
sum(allWeights[cellI]);
1012 allCellTypes[cellI] = POROUS;
1013 allWeights[cellI].
clear();
1014 allStencil[cellI].
clear();
1018 forAll(allWeights[cellI], i)
1020 allWeights[cellI][i] /=
s;
1027 if ((
debug&2) && (mesh_.time().outputTime()))
1029 if ((
debug&2) && (mesh_.time().outputTime()))
1033 createField(mesh_,
"allCellTypes_final", allCellTypes)
1040 cellTypes_.transfer(allCellTypes);
1041 cellStencil_.transfer(allStencil);
1042 cellInterpolationWeights_.transfer(allWeights);
1043 cellInterpolationWeight_.transfer(allWeight);
1049 >(cellInterpolationWeight_.boundaryFieldRef(),
false);
1052 forAll(cellStencil_, cellI)
1054 if (cellStencil_[cellI].size())
1056 interpolationCells.append(cellI);
1059 interpolationCells_.transfer(interpolationCells);
1063 cellInterpolationMap_.reset
1069 if ((
debug&2) && (mesh_.time().outputTime()))
1072 cellInterpolationWeight_.instance() = mesh_.time().timeName();
1073 cellInterpolationWeight_.write();
1076 mkDir(mesh_.time().timePath());
1077 OBJstream str(mesh_.time().timePath()/
"stencil2.obj");
1078 Info<< typeName <<
" : dumping to " << str.name() <<
endl;
1080 cellInterpolationMap().distribute(cc);
1082 forAll(interpolationCells_, compactI)
1084 label cellI = interpolationCells_[compactI];
1085 const labelList& slots = cellStencil_[cellI];
1087 Pout<<
"cellI:" << cellI <<
" at:" 1088 << mesh_.cellCentres()[cellI]
1089 <<
" calculated from slots:" << slots
1091 <<
" weights:" << cellInterpolationWeights_[cellI]
1096 if (cellInterpolationWeights_[cellI][slots[i]] > 0)
1098 const point& donorCc = cc[slots[i]];
1099 const point& accCc = mesh_.cellCentres()[cellI];
1100 str.writeLine(accCc, 0.1*accCc+0.9*donorCc);
1108 Info<<
"Overset analysis : nCells : " 1111 <<
indent <<
"calculated : " << nCells[CALCULATED] <<
nl 1112 <<
indent <<
"interpolated : " << nCells[INTERPOLATED] <<
nl 1113 <<
indent <<
"hole : " << nCells[HOLE] <<
nl 1123 const point& sample,
1134 scalar d =
mag(sample-donorCcs[i]);
This class separates the mesh into distinct unconnected regions, each of which is then given a label ...
List< labelList > labelListList
A List of labelList.
scalar overlapTolerance_
Tolerance for volume overlap. Fraction of volume.
const autoPtr< mapDistribute > & tgtMap() const
Target map pointer - valid if no singleMeshProc.
void size(const label n)
Older name for setAddressableSize.
Ostream & indent(Ostream &os)
Indent stream.
errorManipArg< error, int > exit(error &err, const int errNo=1)
dimensioned< typename typeOfMag< Type >::type > mag(const dimensioned< Type > &dt)
error FatalError
Error stream (stdout output on all processes), with additional 'FOAM FATAL ERROR' header text and sta...
A list of keyword definitions, which are a keyword followed by a number of values (eg...
virtual void stencilWeights(const point &sample, const pointList &donorCcs, scalarList &weights) const
Calculate inverse distance weights for a single acceptor. Revert.
#define FatalErrorInFunction
Report an error message using Foam::FatalError.
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
void distribute(List< T > &fld, const bool dummyTransform=true, const int tag=UPstream::msgType()) const
Distribute data using default commsType.
constexpr char nl
The newline '\n' character (0x0a)
wordList patchTypes(nPatches)
virtual bool update()
Update stencils. Return false if nothing changed.
Ostream & endl(Ostream &os)
Add newline and flush stream.
A finiteVolume patch using a polyPatch and a fvBoundaryMesh.
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.
defineTypeNameAndDebug(cellVolumeWeight, 0)
Class to calculate the cell-addressing between two overlapping meshes.
Ignore writing from objectRegistry::writeObject()
const dimensionSet dimless
Dimensionless.
const Time & time() const
Return the top-level database.
bool insert(const Key &key)
Insert a new entry, not overwriting existing entries.
T returnReduce(const T &value, const BinaryOp &bop, const int tag=UPstream::msgType(), const label comm=UPstream::worldComm)
Perform reduction on a copy, using specified binary operation.
Macros for easy insertion into run-time selection tables.
wordHashSet nonInterpolatedFields_
Set of fields that should not be interpolated.
dimensioned< Type > sum(const DimensionedField< Type, GeoMesh > &df)
#define forAll(list, i)
Loop across all elements in list.
const dictionary dict_
Dictionary of motion control parameters.
GeometricField< scalar, fvPatchField, volMesh > volScalarField
fileName::Type type(const fileName &name, const bool followLink=true)
Return the file type: DIRECTORY or FILE, normally following symbolic links.
const labelListList & srcToTgtCellAddr() const
Return const access to the source to target cell addressing.
unsigned int count(const UList< bool > &bools, const bool val=true)
Count number of 'true' entries.
Calculates a unique integer (label so might not have enough room - 2G max) for processor + local inde...
const dimensionedScalar e
Elementary charge.
void setSize(const label n)
Alias for resize()
IOobject io("surfaceFilmProperties", mesh.time().constant(), mesh, IOobject::READ_IF_PRESENT, IOobject::NO_WRITE, false)
bool mkDir(const fileName &pathName, mode_t mode=0777)
Make a directory and return an error if it could not be created.
Calculation of interpolation stencils.
const autoPtr< mapDistribute > & srcMap() const
Source map pointer - valid if no singleMeshProc.
void clear()
Clear the list, i.e. set size to zero.
A class for handling words, derived from Foam::string.
virtual const labelUList & faceCells() const
Return faceCells.
label size() const noexcept
The number of elements in the list.
A HashTable similar to std::unordered_map.
const T * set(const label i) const
Return const pointer to element (can be nullptr), or nullptr for out-of-range access (ie...
const fvMesh & mesh_
Reference to the mesh.
const labelList & cellTypes
static void correctBoundaryConditions(typename GeoField::Boundary &bfld, const bool typeOnly)
Correct boundary conditions of certain type (typeOnly = true)
addToRunTimeSelectionTable(cellCellStencil, cellVolumeWeight, mesh)
A Vector of values with scalar precision, where scalar is float/double depending on the compilation f...
An OFstream that keeps track of vertices and provides convenience output methods for OBJ files...
static word timeName(const scalar t, const int precision=precision_)
Return time name of given scalar time formatted with the given precision.
int debug
Static debugging option.
Type gMax(const FieldField< Field, Type > &f)
void interpolatePatchTypes(const labelListList &addressing, const labelList &patchTypes, labelList &result) const
interpolate (= combine) patch types
labelList cellTypes_
Per cell the cell type.
Ostream & decrIndent(Ostream &os)
Decrement the indent level.
Holds a reference to the original mesh (the baseMesh) and optionally to a subset of that mesh (the su...
static bool constraintType(const word &patchType)
Return true if the given type is a constraint type.
List< word > wordList
A List of words.
const labelListList & tgtToSrcCellAddr() const
Return const access to the target to source cell addressing.
label toGlobal(const label i) const
From local to global index.
const labelIOList & zoneID() const
Helper: get reference to registered zoneID. Loads volScalarField.
UIndirectList< label > labelUIndList
UIndirectList of labels.
Volume-weighted interpolation stencil.
Class containing processor-to-processor mapping information.
static scalar defaultOverlapTolerance_
Default overlap tolerance. Fraction of volume.
label nCells() const noexcept
Number of mesh cells.
A list of pointers to objects of type <T>, with allocation/deallocation management of the pointers...
Mesh data needed to do the Finite Volume discretisation.
A List with indirect addressing. Like IndirectList but does not store addressing. ...
virtual const labelUList & cellTypes() const
Return the cell type list.
label nRegions() const
Return total number of regions.
void reduce(const List< UPstream::commsStruct > &comms, T &value, const BinaryOp &bop, const int tag, const label comm)
Reduce inplace (cf. MPI Allreduce) using specified communication schedule.
messageStream Info
Information stream (stdout output on master, null elsewhere)
const scalarListList & srcToTgtCellWght() const
Return const access to the source to target cell weights.
T getOrDefault(const word &keyword, const T &deflt, enum keyType::option matchOpt=keyType::REGEX) const
Find and return a T, or return the given default value. FatalIOError if it is found and the number of...
List< label > labelList
A List of labels.
A class for managing temporary objects.
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))
bool returnReduceOr(const bool value, const label comm=UPstream::worldComm)
Perform logical (or) MPI Allreduce on a copy. Uses UPstream::reduceOr.
void markPatchCells(const fvMesh &mesh, const labelList &cellMap, labelList &patchCellTypes) const
according to additionalDocumentation/MEJ_oversetMesh.txt
Ostream & incrIndent(Ostream &os)
Increment the indent level.
Defines the attributes of an object for which implicit objectRegistry management is supported...
prefixOSstream Pout
OSstream wrapped stdout (std::cout) with parallel prefix.
virtual ~cellVolumeWeight()
Destructor.
Boundary condition for use on overset patches. To be run in combination with special dynamicFvMesh ty...
static void listCombineReduce(List< T > &values, const CombineOp &cop, const int tag=UPstream::msgType(), const label comm=UPstream::worldComm)
After completion all processors have the same data.
const scalarListList & tgtToSrcCellWght() const
Return const access to the target to source cell weights.
static constexpr const zero Zero
Global zero (0)