42 const Foam::scalar Foam::meshToMesh0::directHitTol = 1
e-5;
47 void Foam::meshToMesh0::calcAddressing()
52 <<
"Calculating mesh-to-mesh cell addressing" <<
endl;
75 List<bool> boundaryCell(fromCells.size(),
false);
87 boundaryCell[bCells[facei]] =
true;
91 treeBoundBox
meshBb(fromPoints);
93 scalar typDim =
meshBb.avgDim()/(2.0*
cbrt(scalar(fromCells.size())));
95 treeBoundBox shiftedBb
104 <<
" bounding box : " <<
meshBb <<
nl
105 <<
" bounding box (shifted) : " << shiftedBb <<
nl
106 <<
" typical dimension :" << shiftedBb.typDim() <<
endl;
109 indexedOctree<treeDataCell> oc
111 treeDataCell(
false, fromMesh_),
120 oc.print(
Pout,
false, 0);
136 if (cuttingPatches_.
found(toPatch.name()))
142 boundaryAddressing_[
patchi],
143 toPatch.faceCentres(),
151 patchMap_.found(toPatch.name())
152 && fromMeshPatches_.
found(patchMap_.find(toPatch.name())())
155 const polyPatch& fromPatch = fromMesh_.
poly().
boundary()
157 fromMeshPatches_.
find(patchMap_.find(toPatch.name())())()
160 if (fromPatch.empty())
163 <<
"Source patch " << fromPatch.name()
164 <<
" has no faces. Not performing mapping for it."
167 boundaryAddressing_[
patchi] = -1;
171 treeBoundBox wallBb(fromPatch.localPoints());
173 wallBb.avgDim()/(2.0*
sqrt(scalar(fromPatch.size())));
175 treeBoundBox shiftedBb
178 wallBb.max() +
vector(typDim, typDim, typDim)
183 indexedOctree<treeDataFace> oc
185 treeDataFace(
false, fromPatch),
193 toPatch.faceCentres();
197 const scalar distSqr =
sqr(wallBb.mag());
201 boundaryAddressing_[
patchi][toi] = oc.findNearest
203 centresToBoundary[toi],
214 <<
"Finished calculating mesh-to-mesh cell addressing" <<
endl;
219 void Foam::meshToMesh0::cellAddresses
223 const fvMesh& fromMesh,
225 const indexedOctree<treeDataCell>& oc
240 const vectorField& centresFrom = fromMesh.cellCentres();
249 scalar distSqr =
magSqr(
p - centresFrom[curCell]);
258 const labelList& neighbours = cc[curCell];
262 const scalar curDistSqr =
263 magSqr(
p - centresFrom[neighbours[ni]]);
267 if (curDistSqr < (1 - small)*distSqr)
269 curCell = neighbours[ni];
270 distSqr = curDistSqr;
276 cellAddressing_[toi] = -1;
281 cellAddressing_[toi] = curCell;
288 if (boundaryCell[curCell])
290 cellAddressing_[toi] =
293 if (cellAddressing_[toi] != -1)
295 curCell = cellAddressing_[toi];
304 const labelList& neighbours = cc[curCell];
312 cellAddressing_[toi] = neighbours[ni];
323 const labelList& neighbours = cc[curCell];
328 const labelList& nn = cc[neighbours[ni]];
336 cellAddressing_[toi] = nn[ni];
348 cellAddressing_[toi] =
351 if (cellAddressing_[toi] != -1)
353 curCell = cellAddressing_[toi];
362 void Foam::meshToMesh0::calculateInverseDistanceWeights()
const
367 <<
"Calculating inverse distance weighting factors" <<
endl;
370 if (inverseDistanceWeightsPtr_)
373 <<
"weighting factors already calculated"
380 inverseDistanceWeightsPtr_ =
new scalarListList(toMesh_.nCells());
388 forAll(cellAddressing_, celli)
390 if (cellAddressing_[celli] != -1)
392 const vector& target = centreTo[celli];
393 scalar m =
mag(target - centreFrom[cellAddressing_[celli]]);
395 const labelList& neighbours = cc[cellAddressing_[celli]];
399 label directCelli = -1;
400 if (m < directHitTol || neighbours.empty())
408 scalar nm =
mag(target - centreFrom[neighbours[ni]]);
409 if (nm < directHitTol)
411 directCelli = neighbours[ni];
418 if (directCelli != -1)
421 invDistCoeffs[directCelli].setSize(1);
422 invDistCoeffs[directCelli][0] = 1.0;
423 V_ += fromMesh_.V()[cellAddressing_[directCelli]];
427 invDistCoeffs[celli].setSize(neighbours.size() + 1);
431 scalar invDist = 1.0/m;
432 invDistCoeffs[celli][0] = invDist;
433 scalar sumInvDist = invDist;
438 invDist = 1.0/
mag(target - centreFrom[neighbours[ni]]);
439 invDistCoeffs[celli][ni + 1] = invDist;
440 sumInvDist += invDist;
444 forAll(invDistCoeffs[celli], i)
446 invDistCoeffs[celli][i] /= sumInvDist;
451 invDistCoeffs[celli][0]
452 *fromMesh_.V()[cellAddressing_[celli]];
453 for (
label i = 1; i < invDistCoeffs[celli].size(); i++)
456 invDistCoeffs[celli][i]*fromMesh_.V()[neighbours[i-1]];
464 void Foam::meshToMesh0::calculateInverseVolumeWeights()
const
469 <<
"Calculating inverse volume weighting factors" <<
endl;
472 if (inverseVolumeWeightsPtr_)
475 <<
"weighting factors already calculated"
487 tetOverlapVolume overlapEngine;
491 const labelList& overlapCells = cellToCell[celli];
493 if (overlapCells.size() > 0)
495 invVolCoeffs[celli].
setSize(overlapCells.size());
499 label cellFrom = overlapCells[j];
500 treeBoundBox bbFromMesh
505 fromMesh_.cellPoints()[cellFrom]
509 scalar v = overlapEngine.cellCellOverlapVolumeMinDecomp
518 invVolCoeffs[celli][j] = v/toMesh_.V()[celli];
527 void Foam::meshToMesh0::calculateCellToCellAddressing()
const
532 <<
"Calculating cell to cell addressing" <<
endl;
535 if (cellToCellAddressingPtr_)
538 <<
"addressing already calculated"
547 cellToCellAddressingPtr_ =
new labelListList(toMesh_.nCells());
553 fromSearchEngine.cellTree().findBox
555 treeBoundBox(toMesh_.points(), toMesh_.cellPoints()[iTo])
558 if (overLapCells.size() > 0)
560 cellToCell[iTo].
setSize(overLapCells.size());
563 cellToCell[iTo][j] = overLapCells[j];
564 V_ += fromMesh_.V()[overLapCells[j]];
575 const fvMesh& meshFrom,
576 const fvMesh& meshTo,
577 const HashTable<word>& patchMap,
584 cellAddressing_(toMesh_.nCells()),
585 boundaryAddressing_(toMesh_.poly().
boundary().size()),
586 inverseDistanceWeightsPtr_(nullptr),
587 inverseVolumeWeightsPtr_(nullptr),
588 cellToCellAddressingPtr_(nullptr),
593 fromMeshPatches_.insert
595 fromMesh_.poly().boundary()[
patchi].name(),
602 toMeshPatches_.insert
604 toMesh_.poly().boundary()[
patchi].name(),
609 forAll(cuttingPatchNames, i)
611 if (toMeshPatches_.found(cuttingPatchNames[i]))
613 cuttingPatches_.insert
615 cuttingPatchNames[i],
616 toMeshPatches_.find(cuttingPatchNames[i])()
622 <<
"Cannot find cutting-patch " << cuttingPatchNames[i]
623 <<
" in destination mesh" <<
endl;
630 if (isA<processorPolyPatch>(toMesh_.poly().boundary()[
patchi]))
632 cuttingPatches_.insert
634 toMesh_.poly().boundary()[
patchi].name(),
646 const fvMesh& meshFrom,
652 cellAddressing_(toMesh_.nCells()),
653 boundaryAddressing_(toMesh_.poly().
boundary().size()),
654 inverseDistanceWeightsPtr_(nullptr),
655 inverseVolumeWeightsPtr_(nullptr),
656 cellToCellAddressingPtr_(nullptr),
661 if (fromMesh_.boundary().size() != toMesh_.boundary().size())
664 <<
"Incompatible meshes: different number of patches, "
665 <<
"fromMesh = " << fromMesh_.boundary().size()
666 <<
", toMesh = " << toMesh_.boundary().size()
674 fromMesh_.poly().boundary()[
patchi].name()
675 != toMesh_.poly().boundary()[
patchi].name()
679 <<
"Incompatible meshes: different patch names for patch "
681 <<
", fromMesh = " << fromMesh_.boundary()[
patchi].name()
682 <<
", toMesh = " << toMesh_.boundary()[
patchi].name()
688 fromMesh_.poly().boundary()[
patchi].type()
689 != toMesh_.poly().boundary()[
patchi].type()
693 <<
"Incompatible meshes: different patch types for patch "
695 <<
", fromMesh = " << fromMesh_.boundary()[
patchi].type()
696 <<
", toMesh = " << toMesh_.boundary()[
patchi].type()
700 fromMeshPatches_.insert
702 fromMesh_.poly().boundary()[
patchi].name(),
706 toMeshPatches_.insert
708 toMesh_.poly().boundary()[
patchi].name(),
714 toMesh_.poly().boundary()[
patchi].name(),
715 fromMesh_.poly().boundary()[
patchi].name()
737 if (!inverseDistanceWeightsPtr_)
739 calculateInverseDistanceWeights();
742 return *inverseDistanceWeightsPtr_;
748 if (!inverseVolumeWeightsPtr_)
750 calculateInverseVolumeWeights();
753 return *inverseVolumeWeightsPtr_;
759 if (!cellToCellAddressingPtr_)
761 calculateCellToCellAddressing();
764 return *cellToCellAddressingPtr_;
#define forAll(list, i)
Loop across all elements in list.
SubField< vector > subField
Declare type of subField.
iterator find(const Key &)
Find and return an iterator set at the hashedEntry.
bool found(const Key &) const
Return true if hashedEntry is found in table.
void setSize(const label)
Reset size of List.
const polyMesh & poly() const
Return reference to polyMesh.
static const meshSearch & New(const polyMesh &mesh, const pointInCellShapes=pointInCellShapes::tets)
Lookup or construct from mesh and cell decomposition option.
meshToMesh0(const fvMesh &fromMesh, const fvMesh &toMesh, const HashTable< word > &patchMap, const wordList &cuttingPatchNames)
Construct from the two meshes, the patch name map for the patches.
~meshToMesh0()
Destructor.
Motion of the mesh specified as a list of pointMeshMovers.
const polyBoundaryMesh & boundary() const
Return boundary mesh.
virtual const pointField & points() const
Return raw points.
const vectorField & cellCentres() const
const cellList & cells() const
Template functions to aid in the implementation of demand driven data.
#define FatalErrorInFunction
Report an error message using Foam::FatalError.
#define WarningInFunction
Report a warning using Foam::Warning.
#define InfoInFunction
Report an information message using Foam::Info.
const dimensionedScalar e
Elementary charge.
List< scalarList > scalarListList
errorManipArg< error, int > exit(error &err, const int errNo=1)
List< word > wordList
A List of words.
List< label > labelList
A List of labels.
intWM_LABEL_SIZE_t label
A label is an int32_t or int64_t as specified by the pre-processor macro WM_LABEL_SIZE.
List< cell > cellList
list of cells
Ostream & endl(Ostream &os)
Add newline and flush stream.
void deleteDemandDrivenData(DataType *&dataPtr)
vectorField pointField
pointField is a vectorField.
tmp< DimensionedField< typename outerProduct< Type, Type >::type, GeoMesh, Field >> sqr(const DimensionedField< Type, GeoMesh, PrimitiveField > &df)
Vector< scalar > vector
A scalar version of the templated Vector.
List< labelList > labelListList
A List of labelList.
PtrList< polyPatch > polyPatchList
container classes for polyPatch
Field< vector > vectorField
Specialisation of Field<T> for vector.
void cbrt(LagrangianPatchField< scalar > &f, const LagrangianPatchField< scalar > &f1)
prefixOSstream Pout(cout, "Pout")
tmp< DimensionedField< scalar, GeoMesh, Field > > mag(const DimensionedField< Type, GeoMesh, PrimitiveField > &df)
void sqrt(LagrangianPatchField< scalar > &f, const LagrangianPatchField< scalar > &f1)
tmp< DimensionedField< scalar, GeoMesh, Field > > magSqr(const DimensionedField< Type, GeoMesh, PrimitiveField > &df)
bool pointInCell(const point &p, const polyMesh &mesh, const label celli, const pointInCellShapes=pointInCellShapes::tets)
Test if a point is in a given cell.
defineTypeNameAndDebug(atmosphericBoundaryLayer, 0)
UList< label > labelUList
Function for determining if a point is within a cell of a polyMesh.
faceListList boundary(nPatches)
List< treeBoundBox > meshBb(1, treeBoundBox(boundBox(coarseMesh.points(), false)).extend(1e-3))