meshTools: Added patchToPatch class for patch mapping
This commit is contained in:
@ -256,6 +256,12 @@ $(AMIOverlapPatches)/cyclicRepeatAMIPolyPatch/cyclicRepeatAMIPolyPatch.C
|
|||||||
$(AMIOverlapPatches)/cyclicRepeatAMIPointPatch/cyclicRepeatAMIPointPatch.C
|
$(AMIOverlapPatches)/cyclicRepeatAMIPointPatch/cyclicRepeatAMIPointPatch.C
|
||||||
$(AMIOverlapPatches)/cyclicRepeatAMIPointPatchField/cyclicRepeatAMIPointPatchFields.C
|
$(AMIOverlapPatches)/cyclicRepeatAMIPointPatchField/cyclicRepeatAMIPointPatchFields.C
|
||||||
|
|
||||||
|
patchToPatch/patchToPatch/patchToPatch.C
|
||||||
|
patchToPatch/patchToPatch/patchToPatchParallelOps.C
|
||||||
|
patchToPatch/nearest/nearestPatchToPatch.C
|
||||||
|
patchToPatch/inverseDistance/inverseDistancePatchToPatch.C
|
||||||
|
patchToPatch/intersection/intersectionPatchToPatch.C
|
||||||
|
|
||||||
mappedPatches/mappedPolyPatch/mappedPatchBase.C
|
mappedPatches/mappedPolyPatch/mappedPatchBase.C
|
||||||
mappedPatches/mappedPolyPatch/mappedPolyPatch.C
|
mappedPatches/mappedPolyPatch/mappedPolyPatch.C
|
||||||
mappedPatches/mappedPolyPatch/mappedWallPolyPatch.C
|
mappedPatches/mappedPolyPatch/mappedWallPolyPatch.C
|
||||||
|
|||||||
235
src/meshTools/PrimitiveOldTimePatch/PrimitiveOldTimePatch.C
Normal file
235
src/meshTools/PrimitiveOldTimePatch/PrimitiveOldTimePatch.C
Normal file
@ -0,0 +1,235 @@
|
|||||||
|
/*---------------------------------------------------------------------------*\
|
||||||
|
========= |
|
||||||
|
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||||
|
\\ / O peration | Website: https://openfoam.org
|
||||||
|
\\ / A nd | Copyright (C) 2022 OpenFOAM Foundation
|
||||||
|
\\/ M anipulation |
|
||||||
|
-------------------------------------------------------------------------------
|
||||||
|
License
|
||||||
|
This file is part of OpenFOAM.
|
||||||
|
|
||||||
|
OpenFOAM is free software: you can redistribute it and/or modify it
|
||||||
|
under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation, either version 3 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
|
||||||
|
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||||
|
for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
\*---------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
#include "PrimitiveOldTimePatch.H"
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
template<class FaceList, class PointField>
|
||||||
|
Foam::PrimitiveOldTimePatch<FaceList, PointField>::PrimitiveOldTimePatch
|
||||||
|
(
|
||||||
|
const FaceList& faces,
|
||||||
|
const Field<PointType>& points,
|
||||||
|
const Field<PointType>& points0
|
||||||
|
)
|
||||||
|
:
|
||||||
|
PrimitivePatch<FaceList, PointField>(faces, points),
|
||||||
|
points0_(points0),
|
||||||
|
patch0Ptr_(new patch0Type(faces, points0_)),
|
||||||
|
localPoints0Ptr_(nullptr)
|
||||||
|
{}
|
||||||
|
|
||||||
|
|
||||||
|
template<class FaceList, class PointField>
|
||||||
|
Foam::PrimitiveOldTimePatch<FaceList, PointField>::PrimitiveOldTimePatch
|
||||||
|
(
|
||||||
|
const PrimitivePatch<FaceList, PointField>& patch,
|
||||||
|
const Field<PointType>& points0
|
||||||
|
)
|
||||||
|
:
|
||||||
|
PrimitivePatch<FaceList, PointField>(patch),
|
||||||
|
points0_(points0),
|
||||||
|
patch0Ptr_(new patch0Type(patch, points0_)),
|
||||||
|
localPoints0Ptr_(nullptr)
|
||||||
|
{}
|
||||||
|
|
||||||
|
|
||||||
|
template<class FaceList, class PointField>
|
||||||
|
Foam::PrimitiveOldTimePatch<FaceList, PointField>::PrimitiveOldTimePatch
|
||||||
|
(
|
||||||
|
const FaceList& faces,
|
||||||
|
const Field<PointType>& points
|
||||||
|
)
|
||||||
|
:
|
||||||
|
PrimitivePatch<FaceList, PointField>(faces, points),
|
||||||
|
points0_(NullObjectRef<Field<PointType>>()),
|
||||||
|
patch0Ptr_(nullptr),
|
||||||
|
localPoints0Ptr_(nullptr)
|
||||||
|
{}
|
||||||
|
|
||||||
|
|
||||||
|
template<class FaceList, class PointField>
|
||||||
|
Foam::PrimitiveOldTimePatch<FaceList, PointField>::PrimitiveOldTimePatch
|
||||||
|
(
|
||||||
|
const PrimitivePatch<FaceList, PointField>& patch
|
||||||
|
)
|
||||||
|
:
|
||||||
|
PrimitivePatch<FaceList, PointField>(patch),
|
||||||
|
points0_(NullObjectRef<Field<PointType>>()),
|
||||||
|
patch0Ptr_(nullptr),
|
||||||
|
localPoints0Ptr_(nullptr)
|
||||||
|
{}
|
||||||
|
|
||||||
|
|
||||||
|
template<class FaceList, class PointField>
|
||||||
|
Foam::PrimitiveOldTimePatch<FaceList, PointField>::PrimitiveOldTimePatch
|
||||||
|
(
|
||||||
|
const PrimitiveOldTimePatch<FaceList, PointField>& patch
|
||||||
|
)
|
||||||
|
:
|
||||||
|
PrimitivePatch<FaceList, PointField>(patch),
|
||||||
|
points0_(patch.points0_),
|
||||||
|
patch0Ptr_(patch.patch0Ptr_, false),
|
||||||
|
localPoints0Ptr_(nullptr)
|
||||||
|
{}
|
||||||
|
|
||||||
|
|
||||||
|
template<class FaceList, class PointField>
|
||||||
|
Foam::PrimitiveOldTimePatch<FaceList, PointField>::PrimitiveOldTimePatch
|
||||||
|
(
|
||||||
|
PrimitiveOldTimePatch<FaceList, PointField>&& patch
|
||||||
|
)
|
||||||
|
:
|
||||||
|
PrimitivePatch<FaceList, PointField>(move(patch)),
|
||||||
|
points0_(move(patch.points0_)),
|
||||||
|
patch0Ptr_(patch.patch0Ptr_),
|
||||||
|
localPoints0Ptr_(nullptr)
|
||||||
|
{}
|
||||||
|
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
template<class FaceList, class PointField>
|
||||||
|
Foam::PrimitiveOldTimePatch<FaceList, PointField>::~PrimitiveOldTimePatch()
|
||||||
|
{
|
||||||
|
clearOut();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
template<class FaceList, class PointField>
|
||||||
|
const Foam::Field
|
||||||
|
<
|
||||||
|
typename Foam::PrimitiveOldTimePatch<FaceList, PointField>::PointType
|
||||||
|
>& Foam::PrimitiveOldTimePatch<FaceList, PointField>::localPoints0() const
|
||||||
|
{
|
||||||
|
// !!! Cannot just call patch0Ptr_->localPoints() as this would generate
|
||||||
|
// topology in patch0Ptr_() that is already available in the base class.
|
||||||
|
// For now, we just duplicate the implementation in PrimitivePatch.
|
||||||
|
|
||||||
|
if (!localPoints0Ptr_)
|
||||||
|
{
|
||||||
|
const labelList& meshPts = this->meshPoints();
|
||||||
|
|
||||||
|
localPoints0Ptr_ = new Field<PointType>(meshPts.size());
|
||||||
|
|
||||||
|
Field<PointType>& locPts = *localPoints0Ptr_;
|
||||||
|
|
||||||
|
forAll(meshPts, pointi)
|
||||||
|
{
|
||||||
|
locPts[pointi] = points0_[meshPts[pointi]];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// But, it would be preferable to add a method to PrimitivePatch which
|
||||||
|
// calculates the local points given a list of points different to those
|
||||||
|
// that are stored. Then the implementations could be shared and we could
|
||||||
|
// do this:
|
||||||
|
/*
|
||||||
|
if (!localPoints0Ptr_)
|
||||||
|
{
|
||||||
|
localPoints0Ptr_ = this->calcLocalPoints(points0_);
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
|
return *localPoints0Ptr_;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
template<class FaceList, class PointField>
|
||||||
|
const Foam::Field
|
||||||
|
<
|
||||||
|
typename Foam::PrimitiveOldTimePatch<FaceList, PointField>::PointType
|
||||||
|
>& Foam::PrimitiveOldTimePatch<FaceList, PointField>::faceCentres0() const
|
||||||
|
{
|
||||||
|
return patch0Ptr_->faceCentres();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
template<class FaceList, class PointField>
|
||||||
|
const Foam::Field
|
||||||
|
<
|
||||||
|
typename Foam::PrimitiveOldTimePatch<FaceList, PointField>::PointType
|
||||||
|
>& Foam::PrimitiveOldTimePatch<FaceList, PointField>::faceAreas0() const
|
||||||
|
{
|
||||||
|
return patch0Ptr_->faceAreas();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
template<class FaceList, class PointField>
|
||||||
|
const Foam::Field
|
||||||
|
<
|
||||||
|
typename Foam::PrimitiveOldTimePatch<FaceList, PointField>::PointType
|
||||||
|
>& Foam::PrimitiveOldTimePatch<FaceList, PointField>::faceNormals0() const
|
||||||
|
{
|
||||||
|
return patch0Ptr_->faceNormals();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
template<class FaceList, class PointField>
|
||||||
|
const Foam::Field
|
||||||
|
<
|
||||||
|
typename Foam::PrimitiveOldTimePatch<FaceList, PointField>::PointType
|
||||||
|
>& Foam::PrimitiveOldTimePatch<FaceList, PointField>::pointNormals0() const
|
||||||
|
{
|
||||||
|
// !!! See comments in localPoints0. This isn't needed for now.
|
||||||
|
|
||||||
|
NotImplemented;
|
||||||
|
return NullObjectRef<Field<PointType>>();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
template<class FaceList, class PointField>
|
||||||
|
void Foam::PrimitiveOldTimePatch<FaceList, PointField>::clearOut()
|
||||||
|
{
|
||||||
|
PrimitivePatch<FaceList, PointField>::clearOut();
|
||||||
|
if (has0()) patch0Ptr_->clearOut();
|
||||||
|
|
||||||
|
deleteDemandDrivenData(localPoints0Ptr_);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
template<class FaceList, class PointField>
|
||||||
|
void Foam::PrimitiveOldTimePatch<FaceList, PointField>::clearGeom()
|
||||||
|
{
|
||||||
|
PrimitivePatch<FaceList, PointField>::clearGeom();
|
||||||
|
if (has0()) patch0Ptr_->clearGeom();
|
||||||
|
|
||||||
|
deleteDemandDrivenData(localPoints0Ptr_);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
template<class FaceList, class PointField>
|
||||||
|
void Foam::PrimitiveOldTimePatch<FaceList, PointField>::movePoints0
|
||||||
|
(
|
||||||
|
const Field<PointType>&
|
||||||
|
)
|
||||||
|
{
|
||||||
|
if (has0()) patch0Ptr_->clearGeom();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// ************************************************************************* //
|
||||||
230
src/meshTools/PrimitiveOldTimePatch/PrimitiveOldTimePatch.H
Normal file
230
src/meshTools/PrimitiveOldTimePatch/PrimitiveOldTimePatch.H
Normal file
@ -0,0 +1,230 @@
|
|||||||
|
/*---------------------------------------------------------------------------*\
|
||||||
|
========= |
|
||||||
|
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||||
|
\\ / O peration | Website: https://openfoam.org
|
||||||
|
\\ / A nd | Copyright (C) 2022 OpenFOAM Foundation
|
||||||
|
\\/ M anipulation |
|
||||||
|
-------------------------------------------------------------------------------
|
||||||
|
License
|
||||||
|
This file is part of OpenFOAM.
|
||||||
|
|
||||||
|
OpenFOAM is free software: you can redistribute it and/or modify it
|
||||||
|
under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation, either version 3 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
|
||||||
|
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||||
|
for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
Class
|
||||||
|
Foam::PrimitiveOldTimePatch
|
||||||
|
|
||||||
|
Description
|
||||||
|
|
||||||
|
SourceFiles
|
||||||
|
PrimitiveOldTimePatch.C
|
||||||
|
|
||||||
|
\*---------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
#ifndef PrimitiveOldTimePatch_H
|
||||||
|
#define PrimitiveOldTimePatch_H
|
||||||
|
|
||||||
|
#include "PrimitivePatch.H"
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
namespace Foam
|
||||||
|
{
|
||||||
|
|
||||||
|
// Trait to determine what face list should be used for the old-time patch
|
||||||
|
template<class Container>
|
||||||
|
struct UFaceList;
|
||||||
|
template<class Face>
|
||||||
|
struct UFaceList<UList<Face>> { typedef UList<Face> type; };
|
||||||
|
template<class Face>
|
||||||
|
struct UFaceList<List<Face>> : public UFaceList<UList<Face>> {};
|
||||||
|
template<class Face>
|
||||||
|
struct UFaceList<SubList<Face>> : public UFaceList<UList<Face>> {};
|
||||||
|
template<class Face>
|
||||||
|
struct UFaceList<UIndirectList<Face>> { typedef UIndirectList<Face> type; };
|
||||||
|
template<class Face>
|
||||||
|
struct UFaceList<IndirectList<Face>> : public UFaceList<UIndirectList<Face>> {};
|
||||||
|
|
||||||
|
/*---------------------------------------------------------------------------*\
|
||||||
|
Class PrimitiveOldTimePatch Declaration
|
||||||
|
\*---------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
template<class FaceList, class PointField>
|
||||||
|
class PrimitiveOldTimePatch
|
||||||
|
:
|
||||||
|
public PrimitivePatch<FaceList, PointField>
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
|
||||||
|
// Public Typedefs
|
||||||
|
|
||||||
|
using typename PrimitivePatch<FaceList, PointField>::FaceListType;
|
||||||
|
|
||||||
|
using typename PrimitivePatch<FaceList, PointField>::FaceType;
|
||||||
|
|
||||||
|
using typename PrimitivePatch<FaceList, PointField>::PointFieldType;
|
||||||
|
|
||||||
|
using typename PrimitivePatch<FaceList, PointField>::PointType;
|
||||||
|
|
||||||
|
|
||||||
|
private:
|
||||||
|
|
||||||
|
// Private Typedefs
|
||||||
|
|
||||||
|
typedef
|
||||||
|
PrimitivePatch
|
||||||
|
<
|
||||||
|
typename UFaceList<FaceListType>::type,
|
||||||
|
const PointFieldType&
|
||||||
|
>
|
||||||
|
patch0Type;
|
||||||
|
|
||||||
|
|
||||||
|
// Private Data
|
||||||
|
|
||||||
|
//- Reference to global list of old-time points
|
||||||
|
PointField points0_;
|
||||||
|
|
||||||
|
//- Engine for calculating old-time geometry. Note: Methods that
|
||||||
|
// generate topology should not be called here. The base patch should
|
||||||
|
// have all the necessary topology available. The calculation of some
|
||||||
|
// geometric quantities requires topological data to be available. In
|
||||||
|
// these cases, special steps need to be taken here to make sure that
|
||||||
|
// the old-time patch object does not generate duplicate topology.
|
||||||
|
autoPtr<patch0Type> patch0Ptr_;
|
||||||
|
|
||||||
|
//- Points local to patch
|
||||||
|
mutable Field<PointType>* localPoints0Ptr_;
|
||||||
|
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
// Constructors
|
||||||
|
|
||||||
|
//- Construct from components
|
||||||
|
PrimitiveOldTimePatch
|
||||||
|
(
|
||||||
|
const FaceList& faces,
|
||||||
|
const Field<PointType>& points,
|
||||||
|
const Field<PointType>& points0
|
||||||
|
);
|
||||||
|
|
||||||
|
//- Construct from patch and old-time points
|
||||||
|
PrimitiveOldTimePatch
|
||||||
|
(
|
||||||
|
const PrimitivePatch<FaceList, PointField>& patch,
|
||||||
|
const Field<PointType>& points0
|
||||||
|
);
|
||||||
|
|
||||||
|
//- Construct from components without old-time points
|
||||||
|
PrimitiveOldTimePatch
|
||||||
|
(
|
||||||
|
const FaceList& faces,
|
||||||
|
const Field<PointType>& points
|
||||||
|
);
|
||||||
|
|
||||||
|
//- Construct from patch without old-time points
|
||||||
|
PrimitiveOldTimePatch
|
||||||
|
(
|
||||||
|
const PrimitivePatch<FaceList, PointField>& patch
|
||||||
|
);
|
||||||
|
|
||||||
|
//- Copy constructor
|
||||||
|
PrimitiveOldTimePatch(const PrimitiveOldTimePatch& patch);
|
||||||
|
|
||||||
|
//- Move constructor
|
||||||
|
PrimitiveOldTimePatch(PrimitiveOldTimePatch&& patch);
|
||||||
|
|
||||||
|
//- Construct and return a clone
|
||||||
|
autoPtr<PrimitiveOldTimePatch<FaceList, PointField>> clone() const
|
||||||
|
{
|
||||||
|
return autoPtr<PrimitiveOldTimePatch<FaceList, PointField>>
|
||||||
|
(
|
||||||
|
new PrimitiveOldTimePatch<FaceList, PointField>(*this)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//- Destructor
|
||||||
|
virtual ~PrimitiveOldTimePatch();
|
||||||
|
|
||||||
|
|
||||||
|
// Member Functions
|
||||||
|
|
||||||
|
// Access
|
||||||
|
|
||||||
|
//- Return whether or not old-time geometry is available
|
||||||
|
bool has0() const
|
||||||
|
{
|
||||||
|
return patch0Ptr_.valid();
|
||||||
|
}
|
||||||
|
|
||||||
|
//- Return reference to old-time global points
|
||||||
|
const Field<PointType>& points0() const
|
||||||
|
{
|
||||||
|
return points0_;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// Geometry
|
||||||
|
|
||||||
|
//- Return pointField of old-time points in patch
|
||||||
|
const Field<PointType>& localPoints0() const;
|
||||||
|
|
||||||
|
//- Return old-time face centres for patch
|
||||||
|
const Field<PointType>& faceCentres0() const;
|
||||||
|
|
||||||
|
//- Return old-time face areas for patch
|
||||||
|
const Field<PointType>& faceAreas0() const;
|
||||||
|
|
||||||
|
//- Return old-time face normals for patch
|
||||||
|
const Field<PointType>& faceNormals0() const;
|
||||||
|
|
||||||
|
//- Return old-time point normals for patch
|
||||||
|
const Field<PointType>& pointNormals0() const;
|
||||||
|
|
||||||
|
|
||||||
|
// Edit
|
||||||
|
|
||||||
|
//- ...
|
||||||
|
void clearOut();
|
||||||
|
|
||||||
|
//- ...
|
||||||
|
void clearGeom();
|
||||||
|
|
||||||
|
//- Correct patch after moving points
|
||||||
|
virtual void movePoints0(const Field<PointType>&);
|
||||||
|
|
||||||
|
|
||||||
|
// Member Operators
|
||||||
|
|
||||||
|
//- Disallow default bitwise assignment
|
||||||
|
void operator=(const PrimitiveOldTimePatch&) = delete;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
} // End namespace Foam
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
#ifdef NoRepository
|
||||||
|
#include "PrimitiveOldTimePatch.C"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// ************************************************************************* //
|
||||||
53
src/meshTools/PrimitiveOldTimePatch/primitiveOldTimePatch.H
Normal file
53
src/meshTools/PrimitiveOldTimePatch/primitiveOldTimePatch.H
Normal file
@ -0,0 +1,53 @@
|
|||||||
|
/*---------------------------------------------------------------------------*\
|
||||||
|
========= |
|
||||||
|
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||||
|
\\ / O peration | Website: https://openfoam.org
|
||||||
|
\\ / A nd | Copyright (C) 2022 OpenFOAM Foundation
|
||||||
|
\\/ M anipulation |
|
||||||
|
-------------------------------------------------------------------------------
|
||||||
|
License
|
||||||
|
This file is part of OpenFOAM.
|
||||||
|
|
||||||
|
OpenFOAM is free software: you can redistribute it and/or modify it
|
||||||
|
under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation, either version 3 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
|
||||||
|
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||||
|
for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
Typedef
|
||||||
|
Foam::primitiveOldTimePatch
|
||||||
|
|
||||||
|
Description
|
||||||
|
Addressing for a faceList slice.
|
||||||
|
|
||||||
|
\*---------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
#ifndef primitiveOldTimePatch_H
|
||||||
|
#define primitiveOldTimePatch_H
|
||||||
|
|
||||||
|
#include "PrimitiveOldTimePatch.H"
|
||||||
|
#include "face.H"
|
||||||
|
#include "SubList.H"
|
||||||
|
#include "pointField.H"
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
namespace Foam
|
||||||
|
{
|
||||||
|
typedef
|
||||||
|
PrimitiveOldTimePatch<SubList<face>, const pointField&>
|
||||||
|
primitiveOldTimePatch;
|
||||||
|
}
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// ************************************************************************* //
|
||||||
@ -0,0 +1,53 @@
|
|||||||
|
/*---------------------------------------------------------------------------*\
|
||||||
|
========= |
|
||||||
|
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||||
|
\\ / O peration | Website: https://openfoam.org
|
||||||
|
\\ / A nd | Copyright (C) 2022 OpenFOAM Foundation
|
||||||
|
\\/ M anipulation |
|
||||||
|
-------------------------------------------------------------------------------
|
||||||
|
License
|
||||||
|
This file is part of OpenFOAM.
|
||||||
|
|
||||||
|
OpenFOAM is free software: you can redistribute it and/or modify it
|
||||||
|
under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation, either version 3 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
|
||||||
|
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||||
|
for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
Typedef
|
||||||
|
Foam::uindirectPrimitiveOldTimePatch
|
||||||
|
|
||||||
|
Description
|
||||||
|
Addressing for a faceList slice.
|
||||||
|
|
||||||
|
\*---------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
#ifndef uindirectPrimitiveOldTimePatch_H
|
||||||
|
#define uindirectPrimitiveOldTimePatch_H
|
||||||
|
|
||||||
|
#include "PrimitiveOldTimePatch.H"
|
||||||
|
#include "face.H"
|
||||||
|
#include "UIndirectList.H"
|
||||||
|
#include "pointField.H"
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
namespace Foam
|
||||||
|
{
|
||||||
|
typedef
|
||||||
|
PrimitiveOldTimePatch<UIndirectList<face>, const pointField&>
|
||||||
|
uindirectPrimitiveOldTimePatch;
|
||||||
|
}
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// ************************************************************************* //
|
||||||
@ -0,0 +1,937 @@
|
|||||||
|
/*---------------------------------------------------------------------------*\
|
||||||
|
========= |
|
||||||
|
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||||
|
\\ / O peration | Website: https://openfoam.org
|
||||||
|
\\ / A nd | Copyright (C) 2021-2022 OpenFOAM Foundation
|
||||||
|
\\/ M anipulation |
|
||||||
|
-------------------------------------------------------------------------------
|
||||||
|
License
|
||||||
|
This file is part of OpenFOAM.
|
||||||
|
|
||||||
|
OpenFOAM is free software: you can redistribute it and/or modify it
|
||||||
|
under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation, either version 3 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
|
||||||
|
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||||
|
for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
\*---------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
#include "intersectionPatchToPatch.H"
|
||||||
|
#include "triIntersect.H"
|
||||||
|
#include "vtkWritePolyData.H"
|
||||||
|
#include "addToRunTimeSelectionTable.H"
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
namespace Foam
|
||||||
|
{
|
||||||
|
namespace patchToPatches
|
||||||
|
{
|
||||||
|
defineTypeNameAndDebug(intersection, 0);
|
||||||
|
addToRunTimeSelectionTable(patchToPatch, intersection, bool);
|
||||||
|
|
||||||
|
int intersection::debugSrcFacei =
|
||||||
|
debug::debugSwitch((intersection::typeName + "SrcFace").c_str(), -1);
|
||||||
|
int intersection::debugTgtFacei =
|
||||||
|
debug::debugSwitch((intersection::typeName + "TgtFace").c_str(), -1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// * * * * * * * * * * * Private Static Member Functions * * * * * * * * * * //
|
||||||
|
|
||||||
|
template<class Type>
|
||||||
|
Foam::FixedList<Type, 3>
|
||||||
|
Foam::patchToPatches::intersection::triPointValues
|
||||||
|
(
|
||||||
|
const triFace& t,
|
||||||
|
const UList<Type>& values
|
||||||
|
)
|
||||||
|
{
|
||||||
|
FixedList<Type, 3> result;
|
||||||
|
forAll(t, i)
|
||||||
|
{
|
||||||
|
result[i] = values[t[i]];
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * Static Member Functions * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
Foam::treeBoundBox Foam::patchToPatches::intersection::srcBoxStatic
|
||||||
|
(
|
||||||
|
const face& srcFace,
|
||||||
|
const pointField& srcPoints,
|
||||||
|
const vectorField& srcPointNormals
|
||||||
|
)
|
||||||
|
{
|
||||||
|
static DynamicList<point> ps;
|
||||||
|
|
||||||
|
ps.clear();
|
||||||
|
|
||||||
|
const scalar l = sqrt(mag(srcFace.area(srcPoints)));
|
||||||
|
|
||||||
|
forAll(srcFace, srcFacePointi)
|
||||||
|
{
|
||||||
|
const label srcPointi = srcFace[srcFacePointi];
|
||||||
|
|
||||||
|
const point& p = srcPoints[srcPointi];
|
||||||
|
const vector& n = srcPointNormals[srcPointi];
|
||||||
|
|
||||||
|
ps.append(p - l/2*n);
|
||||||
|
ps.append(p + l/2*n);
|
||||||
|
}
|
||||||
|
|
||||||
|
return treeBoundBox(ps);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
|
||||||
|
|
||||||
|
Foam::treeBoundBox Foam::patchToPatches::intersection::srcBox
|
||||||
|
(
|
||||||
|
const face& srcFace,
|
||||||
|
const pointField& srcPoints,
|
||||||
|
const vectorField& srcPointNormals
|
||||||
|
) const
|
||||||
|
{
|
||||||
|
return srcBoxStatic(srcFace, srcPoints, srcPointNormals);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool Foam::patchToPatches::intersection::intersectFaces
|
||||||
|
(
|
||||||
|
const primitiveOldTimePatch& srcPatch,
|
||||||
|
const vectorField& srcPointNormals,
|
||||||
|
const vectorField& srcPointNormals0,
|
||||||
|
const primitiveOldTimePatch& tgtPatch,
|
||||||
|
const label srcFacei,
|
||||||
|
const label tgtFacei
|
||||||
|
)
|
||||||
|
{
|
||||||
|
// Quick rejection based on bound box
|
||||||
|
const treeBoundBox srcFaceBox =
|
||||||
|
srcBox
|
||||||
|
(
|
||||||
|
srcPatch.localFaces()[srcFacei],
|
||||||
|
srcPatch.localPoints(),
|
||||||
|
srcPointNormals
|
||||||
|
);
|
||||||
|
const treeBoundBox tgtFaceBox(tgtPatch.points(), tgtPatch[tgtFacei]);
|
||||||
|
if (!srcFaceBox.overlaps(tgtFaceBox)) return false;
|
||||||
|
|
||||||
|
// Construct face triangulations on demand
|
||||||
|
if (srcTriPoints_[srcFacei].empty())
|
||||||
|
{
|
||||||
|
triEngine_.triangulate
|
||||||
|
(
|
||||||
|
UIndirectList<point>
|
||||||
|
(
|
||||||
|
srcPatch.localPoints(),
|
||||||
|
srcPatch.localFaces()[srcFacei]
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
srcTriPoints_[srcFacei] =
|
||||||
|
triEngine_.triPoints(srcPatch.localFaces()[srcFacei]);
|
||||||
|
srcTriFaceEdges_[srcFacei] = triEngine_.triEdges();
|
||||||
|
}
|
||||||
|
if (tgtTriPoints_[tgtFacei].empty())
|
||||||
|
{
|
||||||
|
triEngine_.triangulate
|
||||||
|
(
|
||||||
|
UIndirectList<point>
|
||||||
|
(
|
||||||
|
tgtPatch.localPoints(),
|
||||||
|
tgtPatch.localFaces()[tgtFacei]
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
tgtTriPoints_[tgtFacei] =
|
||||||
|
triEngine_.triPoints(tgtPatch.localFaces()[tgtFacei]);
|
||||||
|
tgtTriFaceEdges_[tgtFacei] = triEngine_.triEdges();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Construct and initialise workspace
|
||||||
|
bool srcCouples = false;
|
||||||
|
couple srcCouple;
|
||||||
|
srcFaceEdgePart_.resize(srcPatch[srcFacei].size());
|
||||||
|
forAll(srcFaceEdgePart_, srcFaceEdgei)
|
||||||
|
{
|
||||||
|
const edge e =
|
||||||
|
srcPatch.localFaces()[srcFacei].faceEdge(srcFaceEdgei);
|
||||||
|
const vector eC = e.centre(srcPatch.localPoints());
|
||||||
|
srcFaceEdgePart_[srcFaceEdgei] = part(Zero, eC);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool tgtCouples = false;
|
||||||
|
couple tgtCouple;
|
||||||
|
tgtFaceEdgePart_.resize(tgtPatch[tgtFacei].size());
|
||||||
|
forAll(tgtFaceEdgePart_, tgtFaceEdgei)
|
||||||
|
{
|
||||||
|
const edge e =
|
||||||
|
tgtPatch.localFaces()[tgtFacei].faceEdge(tgtFaceEdgei);
|
||||||
|
const vector eC = e.centre(tgtPatch.localPoints());
|
||||||
|
tgtFaceEdgePart_[tgtFaceEdgei] = part(Zero, eC);
|
||||||
|
}
|
||||||
|
|
||||||
|
part errorPart(Zero, srcPatch.faceCentres()[srcFacei]);
|
||||||
|
|
||||||
|
// Cache the face area magnitudes
|
||||||
|
const scalar srcMagA = mag(srcPatch.faceAreas()[srcFacei]);
|
||||||
|
const scalar tgtMagA = mag(tgtPatch.faceAreas()[tgtFacei]);
|
||||||
|
|
||||||
|
// Determine whether or not to debug this tri intersection
|
||||||
|
const bool debugTriIntersect =
|
||||||
|
(debugSrcFacei != -1 || debugTgtFacei != -1)
|
||||||
|
&& (debugSrcFacei == -1 || debugSrcFacei == srcFacei)
|
||||||
|
&& (debugTgtFacei == -1 || debugTgtFacei == tgtFacei);
|
||||||
|
|
||||||
|
// Loop the face triangles and compute the intersections
|
||||||
|
bool anyCouples = false;
|
||||||
|
forAll(srcTriPoints_[srcFacei], srcFaceTrii)
|
||||||
|
{
|
||||||
|
const triFace& srcT = srcTriPoints_[srcFacei][srcFaceTrii];
|
||||||
|
|
||||||
|
const FixedList<point, 3> srcPs =
|
||||||
|
triPointValues(srcT, srcPatch.localPoints());
|
||||||
|
const FixedList<vector, 3> srcNs =
|
||||||
|
triPointValues(srcT, srcPointNormals);
|
||||||
|
|
||||||
|
forAll(tgtTriPoints_[tgtFacei], tgtFaceTrii)
|
||||||
|
{
|
||||||
|
const triFace tgtT =
|
||||||
|
reverse()
|
||||||
|
? tgtTriPoints_[tgtFacei][tgtFaceTrii].reverseFace()
|
||||||
|
: tgtTriPoints_[tgtFacei][tgtFaceTrii];
|
||||||
|
|
||||||
|
const FixedList<point, 3> tgtPs =
|
||||||
|
triPointValues(tgtT, tgtPatch.localPoints());
|
||||||
|
|
||||||
|
// Do tri-intersection
|
||||||
|
ictSrcPoints_.clear();
|
||||||
|
ictSrcPointNormals_.clear();
|
||||||
|
ictTgtPoints_.clear();
|
||||||
|
ictPointLocations_.clear();
|
||||||
|
triIntersect::intersectTris
|
||||||
|
(
|
||||||
|
srcPs,
|
||||||
|
srcNs,
|
||||||
|
{false, false, false},
|
||||||
|
{-1, -1, -1},
|
||||||
|
tgtPs,
|
||||||
|
{false, false, false},
|
||||||
|
{-1, -1, -1},
|
||||||
|
ictSrcPoints_,
|
||||||
|
ictSrcPointNormals_,
|
||||||
|
ictTgtPoints_,
|
||||||
|
ictPointLocations_,
|
||||||
|
debugTriIntersect,
|
||||||
|
debugTriIntersect
|
||||||
|
? word
|
||||||
|
(
|
||||||
|
typeName
|
||||||
|
+ "_srcFace=" + Foam::name(srcFacei)
|
||||||
|
+ "_tgtFace=" + Foam::name(tgtFacei)
|
||||||
|
+ "_intersection=" + Foam::name
|
||||||
|
(srcFaceTrii*tgtTriPoints_[tgtFacei].size() + tgtFaceTrii)
|
||||||
|
)
|
||||||
|
: word::null
|
||||||
|
);
|
||||||
|
|
||||||
|
// If there is no intersection then continue
|
||||||
|
if (ictPointLocations_.empty())
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Mark that there has been an intersection
|
||||||
|
anyCouples = true;
|
||||||
|
|
||||||
|
// Compute the intersection geometry
|
||||||
|
const part ictSrcPart(ictSrcPoints_);
|
||||||
|
const part ictTgtPart(ictTgtPoints_);
|
||||||
|
|
||||||
|
// If the intersection is below tolerance then continue
|
||||||
|
if
|
||||||
|
(
|
||||||
|
mag(ictSrcPart.area) < small*srcMagA
|
||||||
|
|| mag(ictTgtPart.area) < small*tgtMagA
|
||||||
|
)
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Mark that the source and target faces intersect
|
||||||
|
srcCouples = tgtCouples = true;
|
||||||
|
|
||||||
|
// Store the intersection geometry
|
||||||
|
srcCouple += ictSrcPart;
|
||||||
|
srcCouple.nbr += ictTgtPart;
|
||||||
|
if (reverse())
|
||||||
|
{
|
||||||
|
tgtCouple += ictTgtPart;
|
||||||
|
tgtCouple.nbr += ictSrcPart;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
tgtCouple -= ictTgtPart;
|
||||||
|
tgtCouple.nbr -= ictSrcPart;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Store the intersection polygons for debugging
|
||||||
|
const label debugSrcPoint0 = debugPoints_.size();
|
||||||
|
const label debugTgtPoint0 =
|
||||||
|
debugPoints_.size() + ictSrcPoints_.size();
|
||||||
|
if (debug)
|
||||||
|
{
|
||||||
|
debugPoints_.append(ictSrcPoints_);
|
||||||
|
debugPoints_.append(ictTgtPoints_);
|
||||||
|
debugFaces_.append
|
||||||
|
(
|
||||||
|
debugSrcPoint0 + identity(ictSrcPoints_.size())
|
||||||
|
);
|
||||||
|
debugFaceSrcFaces_.append(srcFacei);
|
||||||
|
debugFaceTgtFaces_.append(tgtFacei);
|
||||||
|
debugFaceSides_.append(1);
|
||||||
|
debugFaces_.append
|
||||||
|
(
|
||||||
|
debugTgtPoint0 + identity(ictTgtPoints_.size())
|
||||||
|
);
|
||||||
|
debugFaceSrcFaces_.append(srcFacei);
|
||||||
|
debugFaceTgtFaces_.append(tgtFacei);
|
||||||
|
debugFaceSides_.append(-1);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Store edge and error areas
|
||||||
|
forAll(ictPointLocations_, i0)
|
||||||
|
{
|
||||||
|
const label i1 = ictPointLocations_.fcIndex(i0);
|
||||||
|
|
||||||
|
// Get the locations on each end of this edge of the
|
||||||
|
// intersection polygon
|
||||||
|
const triIntersect::location l0 = ictPointLocations_[i0];
|
||||||
|
const triIntersect::location l1 = ictPointLocations_[i1];
|
||||||
|
|
||||||
|
// Get the geometry for the projection of this edge
|
||||||
|
const part ictEdgePart
|
||||||
|
(
|
||||||
|
FixedList<point, 4>
|
||||||
|
({
|
||||||
|
ictSrcPoints_[i0],
|
||||||
|
ictSrcPoints_[i1],
|
||||||
|
ictTgtPoints_[i1],
|
||||||
|
ictTgtPoints_[i0]
|
||||||
|
})
|
||||||
|
);
|
||||||
|
|
||||||
|
// Store the "side" of the intersection that this edge
|
||||||
|
// corresponds to
|
||||||
|
label ictEdgeSide = -labelMax;
|
||||||
|
|
||||||
|
// If this edge corresponds to an edge of the source
|
||||||
|
// triangle
|
||||||
|
if
|
||||||
|
(
|
||||||
|
l0.isSrcNotTgtPoint()
|
||||||
|
|| l1.isSrcNotTgtPoint()
|
||||||
|
|| (
|
||||||
|
l0.isIntersection()
|
||||||
|
&& l1.isIntersection()
|
||||||
|
&& l0.srcEdgei() == l1.srcEdgei()
|
||||||
|
)
|
||||||
|
)
|
||||||
|
{
|
||||||
|
const label srcEi =
|
||||||
|
l0.isSrcPoint() ? l0.srcPointi()
|
||||||
|
: l1.isSrcPoint() ? (l1.srcPointi() + 2) % 3
|
||||||
|
: l0.srcEdgei();
|
||||||
|
|
||||||
|
const label srcFaceEdgei =
|
||||||
|
srcTriFaceEdges_[srcFacei][srcFaceTrii][srcEi];
|
||||||
|
|
||||||
|
if (srcFaceEdgei < srcPatch[srcFacei].size())
|
||||||
|
{
|
||||||
|
srcFaceEdgePart_[srcFaceEdgei] += ictEdgePart;
|
||||||
|
ictEdgeSide = 1;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
errorPart += ictEdgePart;
|
||||||
|
ictEdgeSide = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// If this edge corresponds to an edge of the target
|
||||||
|
// triangle
|
||||||
|
else if
|
||||||
|
(
|
||||||
|
l0.isTgtNotSrcPoint()
|
||||||
|
|| l1.isTgtNotSrcPoint()
|
||||||
|
|| (
|
||||||
|
l0.isIntersection()
|
||||||
|
&& l1.isIntersection()
|
||||||
|
&& l0.tgtEdgei() == l1.tgtEdgei()
|
||||||
|
)
|
||||||
|
)
|
||||||
|
{
|
||||||
|
const label tgtEi =
|
||||||
|
l0.isTgtPoint() ? (l0.tgtPointi() + 2) % 3
|
||||||
|
: l1.isTgtPoint() ? l1.tgtPointi()
|
||||||
|
: l0.tgtEdgei();
|
||||||
|
|
||||||
|
const label tgtFaceEdgei =
|
||||||
|
tgtTriFaceEdges_[tgtFacei][tgtFaceTrii]
|
||||||
|
[reverse() ? 2 - tgtEi : tgtEi];
|
||||||
|
|
||||||
|
if (tgtFaceEdgei < tgtPatch[tgtFacei].size())
|
||||||
|
{
|
||||||
|
if (reverse())
|
||||||
|
{
|
||||||
|
tgtFaceEdgePart_[tgtFaceEdgei] += ictEdgePart;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
tgtFaceEdgePart_[tgtFaceEdgei] -= ictEdgePart;
|
||||||
|
}
|
||||||
|
ictEdgeSide = -1;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
errorPart += ictEdgePart;
|
||||||
|
ictEdgeSide = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// No other location combinations should be possible for an
|
||||||
|
// intersection without any shared points
|
||||||
|
else
|
||||||
|
{
|
||||||
|
FatalErrorInFunction
|
||||||
|
<< "Tri-intersection topology not recognised. "
|
||||||
|
<< "This is a bug." << exit(FatalError);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Store the projected edge quadrilateral for debugging
|
||||||
|
if (debug)
|
||||||
|
{
|
||||||
|
debugFaces_.append
|
||||||
|
(
|
||||||
|
labelList
|
||||||
|
({
|
||||||
|
debugSrcPoint0 + i0,
|
||||||
|
debugSrcPoint0 + i1,
|
||||||
|
debugTgtPoint0 + i1,
|
||||||
|
debugTgtPoint0 + i0
|
||||||
|
})
|
||||||
|
);
|
||||||
|
debugFaceSrcFaces_.append(srcFacei);
|
||||||
|
debugFaceTgtFaces_.append(tgtFacei);
|
||||||
|
debugFaceSides_.append(ictEdgeSide);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// If the source face couples the target, then store the intersection
|
||||||
|
if (srcCouples)
|
||||||
|
{
|
||||||
|
srcLocalTgtFaces_[srcFacei].append(tgtFacei);
|
||||||
|
srcCouples_[srcFacei].append(srcCouple);
|
||||||
|
}
|
||||||
|
|
||||||
|
// If any intersection has occurred then store the edge and error parts
|
||||||
|
if (anyCouples)
|
||||||
|
{
|
||||||
|
forAll(srcFaceEdgeParts_[srcFacei], srcFaceEdgei)
|
||||||
|
{
|
||||||
|
srcFaceEdgeParts_[srcFacei][srcFaceEdgei] +=
|
||||||
|
srcFaceEdgePart_[srcFaceEdgei];
|
||||||
|
}
|
||||||
|
srcErrorParts_[srcFacei] -= sum(tgtFaceEdgePart_);
|
||||||
|
srcErrorParts_[srcFacei] += errorPart;
|
||||||
|
}
|
||||||
|
|
||||||
|
// If the target face couples the source, then store in the intersection
|
||||||
|
if (tgtCouples)
|
||||||
|
{
|
||||||
|
tgtLocalSrcFaces_[tgtFacei].append(srcFacei);
|
||||||
|
tgtCouples_[tgtFacei].append(tgtCouple);
|
||||||
|
}
|
||||||
|
|
||||||
|
return anyCouples;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void Foam::patchToPatches::intersection::initialise
|
||||||
|
(
|
||||||
|
const primitiveOldTimePatch& srcPatch,
|
||||||
|
const vectorField& srcPointNormals,
|
||||||
|
const vectorField& srcPointNormals0,
|
||||||
|
const primitiveOldTimePatch& tgtPatch
|
||||||
|
)
|
||||||
|
{
|
||||||
|
patchToPatch::initialise
|
||||||
|
(
|
||||||
|
srcPatch,
|
||||||
|
srcPointNormals,
|
||||||
|
srcPointNormals0,
|
||||||
|
tgtPatch
|
||||||
|
);
|
||||||
|
|
||||||
|
srcCouples_.resize(srcPatch.size());
|
||||||
|
forAll(srcLocalTgtFaces_, i)
|
||||||
|
{
|
||||||
|
srcCouples_[i].clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
srcEdgeParts_.resize(srcPatch.nEdges());
|
||||||
|
forAll(srcEdgeParts_, srcEdgei)
|
||||||
|
{
|
||||||
|
const edge& e = srcPatch.edges()[srcEdgei];
|
||||||
|
const point c = e.centre(srcPatch.localPoints());
|
||||||
|
srcEdgeParts_[srcEdgei] = part(Zero, c);
|
||||||
|
}
|
||||||
|
|
||||||
|
srcErrorParts_.resize(srcPatch.size());
|
||||||
|
forAll(srcErrorParts_, srcFacei)
|
||||||
|
{
|
||||||
|
srcErrorParts_[srcFacei] =
|
||||||
|
part(Zero, srcPatch.faceCentres()[srcFacei]);
|
||||||
|
}
|
||||||
|
|
||||||
|
tgtCouples_.resize(tgtPatch.size());
|
||||||
|
forAll(tgtLocalSrcFaces_, i)
|
||||||
|
{
|
||||||
|
tgtCouples_[i].clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
srcTriPoints_ = List<triFaceList>(srcPatch.size());
|
||||||
|
srcTriFaceEdges_ = List<List<FixedList<label, 3>>>(srcPatch.size());
|
||||||
|
tgtTriPoints_ = List<triFaceList>(tgtPatch.size());
|
||||||
|
tgtTriFaceEdges_ = List<List<FixedList<label, 3>>>(tgtPatch.size());
|
||||||
|
|
||||||
|
srcFaceEdgeParts_.resize(srcPatch.size());
|
||||||
|
forAll(srcFaceEdgeParts_, srcFacei)
|
||||||
|
{
|
||||||
|
srcFaceEdgeParts_[srcFacei].resize(srcPatch[srcFacei].size());
|
||||||
|
forAll(srcFaceEdgeParts_[srcFacei], srcFaceEdgei)
|
||||||
|
{
|
||||||
|
const label srcEdgei =
|
||||||
|
srcPatch.faceEdges()[srcFacei][srcFaceEdgei];
|
||||||
|
srcFaceEdgeParts_[srcFacei][srcFaceEdgei] = srcEdgeParts_[srcEdgei];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (debug)
|
||||||
|
{
|
||||||
|
debugPoints_.clear();
|
||||||
|
debugFaces_.clear();
|
||||||
|
debugFaceSrcFaces_.clear();
|
||||||
|
debugFaceTgtFaces_.clear();
|
||||||
|
debugFaceSides_.clear();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void Foam::patchToPatches::intersection::rDistributeTgt
|
||||||
|
(
|
||||||
|
const primitiveOldTimePatch& tgtPatch,
|
||||||
|
const distributionMap& tgtMap
|
||||||
|
)
|
||||||
|
{
|
||||||
|
patchToPatch::rDistributeTgt(tgtPatch, tgtMap);
|
||||||
|
|
||||||
|
rDistributeListList(tgtPatch.size(), tgtMap, tgtCouples_);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Foam::label Foam::patchToPatches::intersection::finalise
|
||||||
|
(
|
||||||
|
const primitiveOldTimePatch& srcPatch,
|
||||||
|
const vectorField& srcPointNormals,
|
||||||
|
const vectorField& srcPointNormals0,
|
||||||
|
const primitiveOldTimePatch& tgtPatch,
|
||||||
|
const transformer& tgtToSrc
|
||||||
|
)
|
||||||
|
{
|
||||||
|
const label nCouples =
|
||||||
|
patchToPatch::finalise
|
||||||
|
(
|
||||||
|
srcPatch,
|
||||||
|
srcPointNormals,
|
||||||
|
srcPointNormals0,
|
||||||
|
tgtPatch,
|
||||||
|
tgtToSrc
|
||||||
|
);
|
||||||
|
|
||||||
|
// Convert face-edge-parts to edge-parts
|
||||||
|
labelList srcEdgeNParts(srcEdgeParts_.size(), 0);
|
||||||
|
forAll(srcEdgeParts_, srcEdgei)
|
||||||
|
{
|
||||||
|
const edge& e = srcPatch.edges()[srcEdgei];
|
||||||
|
|
||||||
|
srcEdgeParts_[srcEdgei] = part();
|
||||||
|
|
||||||
|
forAll(srcPatch.edgeFaces()[srcEdgei], i)
|
||||||
|
{
|
||||||
|
const label srcFacei = srcPatch.edgeFaces()[srcEdgei][i];
|
||||||
|
const label srcFaceEdgei =
|
||||||
|
findIndex(srcPatch.faceEdges()[srcFacei], srcEdgei);
|
||||||
|
|
||||||
|
const edge fe =
|
||||||
|
srcPatch.localFaces()[srcFacei].faceEdge(srcFaceEdgei);
|
||||||
|
|
||||||
|
if (edge::compare(e, fe) > 0)
|
||||||
|
{
|
||||||
|
srcEdgeParts_[srcEdgei] +=
|
||||||
|
srcFaceEdgeParts_[srcFacei][srcFaceEdgei];
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
srcEdgeParts_[srcEdgei] -=
|
||||||
|
srcFaceEdgeParts_[srcFacei][srcFaceEdgei];
|
||||||
|
}
|
||||||
|
|
||||||
|
srcEdgeNParts[srcEdgei] ++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
forAll(srcEdgeParts_, srcEdgei)
|
||||||
|
{
|
||||||
|
srcEdgeParts_[srcEdgei].area /= srcEdgeNParts[srcEdgei];
|
||||||
|
}
|
||||||
|
|
||||||
|
// Add the difference between the face-edge-part and the edge-part into the
|
||||||
|
// face-error-parts
|
||||||
|
forAll(srcEdgeParts_, srcEdgei)
|
||||||
|
{
|
||||||
|
const edge& e = srcPatch.edges()[srcEdgei];
|
||||||
|
|
||||||
|
forAll(srcPatch.edgeFaces()[srcEdgei], i)
|
||||||
|
{
|
||||||
|
const label srcFacei = srcPatch.edgeFaces()[srcEdgei][i];
|
||||||
|
const label srcFaceEdgei =
|
||||||
|
findIndex(srcPatch.faceEdges()[srcFacei], srcEdgei);
|
||||||
|
|
||||||
|
const edge fe =
|
||||||
|
srcPatch.localFaces()[srcFacei].faceEdge(srcFaceEdgei);
|
||||||
|
|
||||||
|
if (edge::compare(e, fe) > 0)
|
||||||
|
{
|
||||||
|
srcErrorParts_[srcFacei] -= srcEdgeParts_[srcEdgei];
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
srcErrorParts_[srcFacei] += srcEdgeParts_[srcEdgei];
|
||||||
|
}
|
||||||
|
|
||||||
|
srcErrorParts_[srcFacei] +=
|
||||||
|
srcFaceEdgeParts_[srcFacei][srcFaceEdgei];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Transform the target couples back to the target side
|
||||||
|
if (!isNull(tgtToSrc))
|
||||||
|
{
|
||||||
|
forAll(tgtCouples_, tgtFacei)
|
||||||
|
{
|
||||||
|
forAll(tgtCouples_[tgtFacei], i)
|
||||||
|
{
|
||||||
|
couple& c = tgtCouples_[tgtFacei][i];
|
||||||
|
|
||||||
|
c.area = tgtToSrc.invTransform(c.area);
|
||||||
|
c.centre = tgtToSrc.invTransformPosition(c.centre);
|
||||||
|
c.nbr.area = tgtToSrc.invTransform(c.nbr.area);
|
||||||
|
c.nbr.centre = tgtToSrc.invTransformPosition(c.nbr.centre);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Clear the triangulation workspace
|
||||||
|
srcTriPoints_.clear();
|
||||||
|
srcTriFaceEdges_.clear();
|
||||||
|
tgtTriPoints_.clear();
|
||||||
|
tgtTriFaceEdges_.clear();
|
||||||
|
|
||||||
|
// Clear face-edge-parts
|
||||||
|
srcFaceEdgePart_.clear();
|
||||||
|
tgtFaceEdgePart_.clear();
|
||||||
|
srcFaceEdgeParts_.clear();
|
||||||
|
|
||||||
|
// Checking and reporting
|
||||||
|
if (nCouples != 0)
|
||||||
|
{
|
||||||
|
scalar srcArea = 0, srcCoupleArea = 0;
|
||||||
|
scalarField srcCoverage(srcPatch.size());
|
||||||
|
scalarField srcOpenness(srcPatch.size());
|
||||||
|
scalarField srcError(srcPatch.size());
|
||||||
|
scalarField srcDepth(srcPatch.size());
|
||||||
|
scalarField srcAngle(srcPatch.size());
|
||||||
|
forAll(srcPatch, srcFacei)
|
||||||
|
{
|
||||||
|
const vector& a = srcPatch.faceAreas()[srcFacei];
|
||||||
|
const scalar magA = mag(a);
|
||||||
|
const point& c = srcPatch.faceCentres()[srcFacei];
|
||||||
|
|
||||||
|
couple Cpl(part(Zero, c), part(Zero, c));
|
||||||
|
forAll(srcCouples_[srcFacei], srcTgtFacei)
|
||||||
|
{
|
||||||
|
const couple& cpl = srcCouples_[srcFacei][srcTgtFacei];
|
||||||
|
|
||||||
|
Cpl += cpl;
|
||||||
|
Cpl.nbr += cpl.nbr;
|
||||||
|
}
|
||||||
|
const scalar magCA = mag(Cpl.area);
|
||||||
|
|
||||||
|
srcArea += magA;
|
||||||
|
srcCoupleArea += magCA;
|
||||||
|
srcCoverage[srcFacei] = magCA/magA;
|
||||||
|
|
||||||
|
vector projectionA = Zero;
|
||||||
|
scalar projectionV = 0;
|
||||||
|
forAll(srcCouples_[srcFacei], srcTgtFacei)
|
||||||
|
{
|
||||||
|
const couple& cpl = srcCouples_[srcFacei][srcTgtFacei];
|
||||||
|
|
||||||
|
projectionA += cpl.nbr.area;
|
||||||
|
projectionV +=
|
||||||
|
- (cpl.area/3 & (cpl.centre - Cpl.centre))
|
||||||
|
+ (cpl.nbr.area/3 & (cpl.nbr.centre - Cpl.centre));
|
||||||
|
}
|
||||||
|
forAll(srcPatch.faceEdges()[srcFacei], srcFaceEdgei)
|
||||||
|
{
|
||||||
|
const label srcEdgei =
|
||||||
|
srcPatch.faceEdges()[srcFacei][srcFaceEdgei];
|
||||||
|
|
||||||
|
const edge& e = srcPatch.edges()[srcEdgei];
|
||||||
|
const edge fe =
|
||||||
|
srcPatch.localFaces()[srcFacei].faceEdge(srcFaceEdgei);
|
||||||
|
|
||||||
|
const scalar sign = edge::compare(e, fe);
|
||||||
|
|
||||||
|
projectionA += sign*srcEdgeParts_[srcEdgei].area;
|
||||||
|
projectionV +=
|
||||||
|
sign*srcEdgeParts_[srcEdgei].area/3
|
||||||
|
& (srcEdgeParts_[srcEdgei].centre - Cpl.centre);
|
||||||
|
}
|
||||||
|
projectionA += srcErrorParts_[srcFacei].area;
|
||||||
|
projectionV +=
|
||||||
|
srcErrorParts_[srcFacei].area/3
|
||||||
|
& (srcErrorParts_[srcFacei].centre - Cpl.centre);
|
||||||
|
|
||||||
|
const vector aHat = normalised(a);
|
||||||
|
const vector aOppHat = normalised(a - Cpl.area + Cpl.nbr.area);
|
||||||
|
srcAngle[srcFacei] =
|
||||||
|
radToDeg(acos(min(max(aHat & aOppHat, -1), +1)));
|
||||||
|
srcOpenness[srcFacei] = mag(projectionA - Cpl.area)/magA;
|
||||||
|
srcError[srcFacei] = mag(srcErrorParts_[srcFacei].area)/magA;
|
||||||
|
srcDepth[srcFacei] = mag(projectionV)/pow3(sqrt(magA));
|
||||||
|
}
|
||||||
|
|
||||||
|
reduce(srcArea, sumOp<scalar>());
|
||||||
|
reduce(srcCoupleArea, sumOp<scalar>());
|
||||||
|
|
||||||
|
scalar tgtArea = 0, tgtCoupleArea = 0;
|
||||||
|
scalarField tgtCoverage(tgtPatch.size());
|
||||||
|
forAll(tgtPatch, tgtFacei)
|
||||||
|
{
|
||||||
|
const scalar magA = mag(tgtPatch.faceAreas()[tgtFacei]);
|
||||||
|
|
||||||
|
vector aCouple = Zero;
|
||||||
|
forAll(tgtCouples_[tgtFacei], tgtSrcFacei)
|
||||||
|
{
|
||||||
|
aCouple += tgtCouples_[tgtFacei][tgtSrcFacei].area;
|
||||||
|
}
|
||||||
|
const scalar magACouple = mag(aCouple);
|
||||||
|
|
||||||
|
tgtArea += magA;
|
||||||
|
tgtCoupleArea += magACouple;
|
||||||
|
tgtCoverage[tgtFacei] = magACouple/magA;
|
||||||
|
}
|
||||||
|
|
||||||
|
reduce(tgtArea, sumOp<scalar>());
|
||||||
|
reduce(tgtCoupleArea, sumOp<scalar>());
|
||||||
|
|
||||||
|
Info<< indent << "Source min/average/max coverage = "
|
||||||
|
<< gMin(srcCoverage) << '/' << srcCoupleArea/srcArea << '/'
|
||||||
|
<< gMax(srcCoverage) << endl
|
||||||
|
<< indent << "Target min/average/max coverage = "
|
||||||
|
<< gMin(tgtCoverage) << '/' << tgtCoupleArea/tgtArea << '/'
|
||||||
|
<< gMax(tgtCoverage) << endl
|
||||||
|
<< indent << "Source average openness/error/depth/angle = "
|
||||||
|
<< gAverage(srcOpenness) << '/' << gAverage(srcError) << '/'
|
||||||
|
<< gAverage(srcDepth) << '/' << gAverage(srcAngle) << endl
|
||||||
|
<< indent << "Source max openness/error/depth/angle = "
|
||||||
|
<< gMax(srcOpenness) << '/' << gMax(srcError) << '/'
|
||||||
|
<< gMax(srcDepth) << '/' << gMax(srcAngle) << endl;
|
||||||
|
|
||||||
|
if (debug)
|
||||||
|
{
|
||||||
|
word name = patchToPatch::typeName + '_' + typeName;
|
||||||
|
|
||||||
|
if (Pstream::parRun())
|
||||||
|
{
|
||||||
|
name += "_proc" + Foam::name(Pstream::myProcNo());
|
||||||
|
}
|
||||||
|
|
||||||
|
Info<< indent << "Writing intersected faces to "
|
||||||
|
<< name + ".vtk" << endl;
|
||||||
|
vtkWritePolyData::write
|
||||||
|
(
|
||||||
|
name + ".vtk",
|
||||||
|
name,
|
||||||
|
false,
|
||||||
|
debugPoints_,
|
||||||
|
labelList(),
|
||||||
|
labelListList(),
|
||||||
|
debugFaces_,
|
||||||
|
"srcFace", false, Field<label>(debugFaceSrcFaces_),
|
||||||
|
"tgtFace", false, Field<label>(debugFaceTgtFaces_),
|
||||||
|
"side", false, Field<label>(debugFaceSides_)
|
||||||
|
);
|
||||||
|
|
||||||
|
debugPoints_.clear();
|
||||||
|
debugFaces_.clear();
|
||||||
|
debugFaceSrcFaces_.clear();
|
||||||
|
debugFaceTgtFaces_.clear();
|
||||||
|
debugFaceSides_.clear();
|
||||||
|
|
||||||
|
Info<< indent << "Writing source patch to "
|
||||||
|
<< name + "_srcPatch.vtk" << endl;
|
||||||
|
vtkWritePolyData::write
|
||||||
|
(
|
||||||
|
name + "_srcPatch" + ".vtk",
|
||||||
|
name + "_srcPatch",
|
||||||
|
false,
|
||||||
|
srcPatch.localPoints(),
|
||||||
|
labelList(),
|
||||||
|
labelListList(),
|
||||||
|
srcPatch.localFaces(),
|
||||||
|
"coverage", false, srcCoverage,
|
||||||
|
"openness", false, srcOpenness,
|
||||||
|
"error", false, srcError,
|
||||||
|
"depth", false, srcDepth,
|
||||||
|
"angle", false, srcAngle
|
||||||
|
);
|
||||||
|
|
||||||
|
Info<< indent << "Writing target patch to "
|
||||||
|
<< name + "_tgtPatch.vtk" << endl;
|
||||||
|
vtkWritePolyData::write
|
||||||
|
(
|
||||||
|
name + "_tgtPatch" + ".vtk",
|
||||||
|
name + "_tgtPatch",
|
||||||
|
false,
|
||||||
|
tgtPatch.localPoints(),
|
||||||
|
labelList(),
|
||||||
|
labelListList(),
|
||||||
|
tgtPatch.localFaces(),
|
||||||
|
"coverage", false, tgtCoverage
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return nCouples;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
Foam::patchToPatches::intersection::intersection(const bool reverse)
|
||||||
|
:
|
||||||
|
patchToPatch(reverse),
|
||||||
|
|
||||||
|
srcCouples_(),
|
||||||
|
srcEdgeParts_(),
|
||||||
|
srcErrorParts_(),
|
||||||
|
tgtCouples_(),
|
||||||
|
|
||||||
|
triEngine_(),
|
||||||
|
|
||||||
|
srcTriPoints_(),
|
||||||
|
srcTriFaceEdges_(),
|
||||||
|
tgtTriPoints_(),
|
||||||
|
tgtTriFaceEdges_(),
|
||||||
|
|
||||||
|
ictSrcPoints_(),
|
||||||
|
ictSrcPointNormals_(),
|
||||||
|
ictTgtPoints_(),
|
||||||
|
ictPointLocations_(),
|
||||||
|
|
||||||
|
srcFaceEdgePart_(),
|
||||||
|
tgtFaceEdgePart_(),
|
||||||
|
|
||||||
|
srcFaceEdgeParts_(),
|
||||||
|
|
||||||
|
debugPoints_(),
|
||||||
|
debugFaces_(),
|
||||||
|
debugFaceSrcFaces_(),
|
||||||
|
debugFaceTgtFaces_(),
|
||||||
|
debugFaceSides_()
|
||||||
|
{}
|
||||||
|
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
Foam::patchToPatches::intersection::~intersection()
|
||||||
|
{}
|
||||||
|
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
Foam::tmpNrc<Foam::List<Foam::DynamicList<Foam::scalar>>>
|
||||||
|
Foam::patchToPatches::intersection::srcWeights
|
||||||
|
(
|
||||||
|
const primitivePatch& srcPatch
|
||||||
|
) const
|
||||||
|
{
|
||||||
|
List<DynamicList<scalar>> result(srcCouples_.size());
|
||||||
|
|
||||||
|
forAll(srcCouples_, srcFacei)
|
||||||
|
{
|
||||||
|
result[srcFacei].resize(srcCouples_[srcFacei].size());
|
||||||
|
|
||||||
|
const scalar magA = mag(srcPatch.faceAreas()[srcFacei]);
|
||||||
|
|
||||||
|
forAll(srcCouples_[srcFacei], i)
|
||||||
|
{
|
||||||
|
result[srcFacei][i] = mag(srcCouples_[srcFacei][i].area)/magA;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Foam::tmpNrc<Foam::List<Foam::DynamicList<Foam::scalar>>>
|
||||||
|
Foam::patchToPatches::intersection::tgtWeights
|
||||||
|
(
|
||||||
|
const primitivePatch& tgtPatch
|
||||||
|
) const
|
||||||
|
{
|
||||||
|
List<DynamicList<scalar>> result(tgtCouples_.size());
|
||||||
|
|
||||||
|
forAll(tgtCouples_, tgtFacei)
|
||||||
|
{
|
||||||
|
result[tgtFacei].resize(tgtCouples_[tgtFacei].size());
|
||||||
|
|
||||||
|
const scalar magA = mag(tgtPatch.faceAreas()[tgtFacei]);
|
||||||
|
|
||||||
|
forAll(tgtCouples_[tgtFacei], i)
|
||||||
|
{
|
||||||
|
result[tgtFacei][i] = mag(tgtCouples_[tgtFacei][i].area)/magA;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// ************************************************************************* //
|
||||||
@ -0,0 +1,424 @@
|
|||||||
|
/*---------------------------------------------------------------------------*\
|
||||||
|
========= |
|
||||||
|
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||||
|
\\ / O peration | Website: https://openfoam.org
|
||||||
|
\\ / A nd | Copyright (C) 2021-2022 OpenFOAM Foundation
|
||||||
|
\\/ M anipulation |
|
||||||
|
-------------------------------------------------------------------------------
|
||||||
|
License
|
||||||
|
This file is part of OpenFOAM.
|
||||||
|
|
||||||
|
OpenFOAM is free software: you can redistribute it and/or modify it
|
||||||
|
under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation, either version 3 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
|
||||||
|
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||||
|
for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
Class
|
||||||
|
Foam::patchToPatches::intersection
|
||||||
|
|
||||||
|
Description
|
||||||
|
Class to generate patchToPatch coupling geometry. A full geometric
|
||||||
|
intersection is done between a face and those opposite, and coupling
|
||||||
|
geometry is calculated accordingly.
|
||||||
|
|
||||||
|
SourceFiles
|
||||||
|
intersection.C
|
||||||
|
|
||||||
|
\*---------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
#ifndef intersectionPatchToPatch_H
|
||||||
|
#define intersectionPatchToPatch_H
|
||||||
|
|
||||||
|
#include "patchToPatch.H"
|
||||||
|
#include "polygonTriangulate.H"
|
||||||
|
#include "triFaceList.H"
|
||||||
|
#include "triIntersectLocation.H"
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
namespace Foam
|
||||||
|
{
|
||||||
|
namespace patchToPatches
|
||||||
|
{
|
||||||
|
|
||||||
|
/*---------------------------------------------------------------------------*\
|
||||||
|
Class intersection Declaration
|
||||||
|
\*---------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
class intersection
|
||||||
|
:
|
||||||
|
public patchToPatch
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
|
||||||
|
// Public Structures
|
||||||
|
|
||||||
|
//- Structure to store the geometry associated with part of a patch
|
||||||
|
// face
|
||||||
|
struct part
|
||||||
|
{
|
||||||
|
//- The area of this part
|
||||||
|
vector area;
|
||||||
|
|
||||||
|
//- The centre of this part
|
||||||
|
point centre;
|
||||||
|
|
||||||
|
//- Default construct
|
||||||
|
part()
|
||||||
|
:
|
||||||
|
area(Zero),
|
||||||
|
centre(point::uniform(NaN))
|
||||||
|
{}
|
||||||
|
|
||||||
|
//- Default construct
|
||||||
|
part(const zero&)
|
||||||
|
:
|
||||||
|
part()
|
||||||
|
{}
|
||||||
|
|
||||||
|
//- Construct from an area and a centre
|
||||||
|
part(const vector& a, const point& c)
|
||||||
|
:
|
||||||
|
area(a),
|
||||||
|
centre(c)
|
||||||
|
{}
|
||||||
|
|
||||||
|
//- Construct from a polygon
|
||||||
|
template<class PointField>
|
||||||
|
part(const PointField& ps)
|
||||||
|
:
|
||||||
|
area(face::area(ps)),
|
||||||
|
centre(face::centre(ps))
|
||||||
|
{}
|
||||||
|
|
||||||
|
//- Negate this part
|
||||||
|
part operator-() const
|
||||||
|
{
|
||||||
|
return part(- area, centre);
|
||||||
|
}
|
||||||
|
|
||||||
|
//- Add another part to this one
|
||||||
|
void operator+=(const part& p)
|
||||||
|
{
|
||||||
|
const scalar magArea = mag(area);
|
||||||
|
const scalar magPArea = mag(p.area);
|
||||||
|
|
||||||
|
area = area + p.area;
|
||||||
|
|
||||||
|
centre =
|
||||||
|
magArea == 0 ? p.centre
|
||||||
|
: magPArea == 0 ? centre
|
||||||
|
: (magArea*centre + magPArea*p.centre)/(magArea + magPArea);
|
||||||
|
}
|
||||||
|
|
||||||
|
//- Subtract another part from this one
|
||||||
|
void operator-=(const part& p)
|
||||||
|
{
|
||||||
|
this->operator+=(-p);
|
||||||
|
}
|
||||||
|
|
||||||
|
//- Equality comparison
|
||||||
|
friend bool operator==(const part& a, const part& b)
|
||||||
|
{
|
||||||
|
return a.area == b.area && a.centre == b.centre;
|
||||||
|
}
|
||||||
|
|
||||||
|
//- Inequality comparison
|
||||||
|
friend bool operator!=(const part& a, const part& b)
|
||||||
|
{
|
||||||
|
return !(a == b);
|
||||||
|
}
|
||||||
|
|
||||||
|
//- Output stream operator
|
||||||
|
friend Ostream& operator<<(Ostream& os, const part& p)
|
||||||
|
{
|
||||||
|
return os << p.area << p.centre;
|
||||||
|
}
|
||||||
|
|
||||||
|
//- Input stream operator
|
||||||
|
friend Istream& operator>>(Istream& is, part& p)
|
||||||
|
{
|
||||||
|
return is >> p.area >> p.centre;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
//- Structure to store the geometry associated with the coupling
|
||||||
|
// between parts of two patch faces
|
||||||
|
struct couple
|
||||||
|
:
|
||||||
|
public part
|
||||||
|
{
|
||||||
|
//- The neighbour part
|
||||||
|
part nbr;
|
||||||
|
|
||||||
|
//- Default construct
|
||||||
|
couple()
|
||||||
|
:
|
||||||
|
part(),
|
||||||
|
nbr()
|
||||||
|
{}
|
||||||
|
|
||||||
|
//- Construct from a coupled pair of parts
|
||||||
|
couple(const part& p, const part& nbrP)
|
||||||
|
:
|
||||||
|
part(p),
|
||||||
|
nbr(nbrP)
|
||||||
|
{}
|
||||||
|
|
||||||
|
//- Equality comparison
|
||||||
|
friend bool operator==(const couple& a, const couple& b)
|
||||||
|
{
|
||||||
|
return
|
||||||
|
static_cast<const part&>(a) == static_cast<const part&>(b)
|
||||||
|
&& a.nbr == b.nbr;
|
||||||
|
}
|
||||||
|
|
||||||
|
//- Inequality comparison
|
||||||
|
friend bool operator!=(const couple& a, const couple& b)
|
||||||
|
{
|
||||||
|
return !(a == b);
|
||||||
|
}
|
||||||
|
|
||||||
|
//- Output stream operator
|
||||||
|
friend Ostream& operator<<(Ostream& os, const couple& c)
|
||||||
|
{
|
||||||
|
return os << static_cast<const part&>(c) << c.nbr;
|
||||||
|
}
|
||||||
|
|
||||||
|
//- Input stream operator
|
||||||
|
friend Istream& operator>>(Istream& is, couple& c)
|
||||||
|
{
|
||||||
|
return is >> static_cast<part&>(c) >> c.nbr;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
private:
|
||||||
|
|
||||||
|
// Private Member Data
|
||||||
|
|
||||||
|
// Geometry
|
||||||
|
|
||||||
|
//- The coupling geometry for for each source face
|
||||||
|
List<DynamicList<couple>> srcCouples_;
|
||||||
|
|
||||||
|
//- The non-coupled geometry associated with each source edge
|
||||||
|
List<part> srcEdgeParts_;
|
||||||
|
|
||||||
|
//- The non-coupled geometry associated with mismatch in each
|
||||||
|
// source face's couplings
|
||||||
|
List<part> srcErrorParts_;
|
||||||
|
|
||||||
|
//- The coupling geometry for for each target face
|
||||||
|
List<DynamicList<couple>> tgtCouples_;
|
||||||
|
|
||||||
|
|
||||||
|
//- Triangulation engine
|
||||||
|
mutable polygonTriangulate triEngine_;
|
||||||
|
|
||||||
|
|
||||||
|
// Workspace
|
||||||
|
|
||||||
|
//- Source face triangulation points
|
||||||
|
mutable List<triFaceList> srcTriPoints_;
|
||||||
|
|
||||||
|
//- Source face triangulation edges
|
||||||
|
mutable List<List<FixedList<label, 3>>> srcTriFaceEdges_;
|
||||||
|
|
||||||
|
//- Target face triangulation points
|
||||||
|
mutable List<triFaceList> tgtTriPoints_;
|
||||||
|
|
||||||
|
//- Target face triangulation edges
|
||||||
|
mutable List<List<FixedList<label, 3>>> tgtTriFaceEdges_;
|
||||||
|
|
||||||
|
//- Source intersection points
|
||||||
|
mutable DynamicList<point> ictSrcPoints_;
|
||||||
|
|
||||||
|
//- Source intersection point normals
|
||||||
|
mutable DynamicList<vector> ictSrcPointNormals_;
|
||||||
|
|
||||||
|
//- Target intersection points
|
||||||
|
mutable DynamicList<point> ictTgtPoints_;
|
||||||
|
|
||||||
|
//- Intersection locations
|
||||||
|
mutable DynamicList<triIntersect::location> ictPointLocations_;
|
||||||
|
|
||||||
|
//- Source face edge parts
|
||||||
|
DynamicList<part> srcFaceEdgePart_;
|
||||||
|
|
||||||
|
//- Target face edge parts
|
||||||
|
DynamicList<part> tgtFaceEdgePart_;
|
||||||
|
|
||||||
|
//- Source face edge parts
|
||||||
|
List<List<part>> srcFaceEdgeParts_;
|
||||||
|
|
||||||
|
|
||||||
|
// Debugging
|
||||||
|
|
||||||
|
//- Intersection points
|
||||||
|
mutable DynamicList<point> debugPoints_;
|
||||||
|
|
||||||
|
//- Intersection faces
|
||||||
|
mutable DynamicList<labelList> debugFaces_;
|
||||||
|
|
||||||
|
//- The source face associated with each intersection face
|
||||||
|
mutable DynamicList<label> debugFaceSrcFaces_;
|
||||||
|
|
||||||
|
//- The target face associated with each intersection face
|
||||||
|
mutable DynamicList<label> debugFaceTgtFaces_;
|
||||||
|
|
||||||
|
//- The side of the intersection each face is on; 1 is the source
|
||||||
|
// side, -1 is the target side, and 0 is a face that spans the
|
||||||
|
// intersection volume; e.g., an edge or error face.
|
||||||
|
mutable DynamicList<label> debugFaceSides_;
|
||||||
|
|
||||||
|
|
||||||
|
// Private Static Member Functions
|
||||||
|
|
||||||
|
//- Return the values at the points of a tri face
|
||||||
|
template<class Type>
|
||||||
|
static FixedList<Type, 3> triPointValues
|
||||||
|
(
|
||||||
|
const triFace& t,
|
||||||
|
const UList<Type>& values
|
||||||
|
);
|
||||||
|
|
||||||
|
|
||||||
|
// Private Member Functions
|
||||||
|
|
||||||
|
//- Get the bound box for a source face
|
||||||
|
virtual treeBoundBox srcBox
|
||||||
|
(
|
||||||
|
const face& srcFace,
|
||||||
|
const pointField& srcPoints,
|
||||||
|
const vectorField& srcPointNormals
|
||||||
|
) const;
|
||||||
|
|
||||||
|
//- Intersect two faces
|
||||||
|
virtual bool intersectFaces
|
||||||
|
(
|
||||||
|
const primitiveOldTimePatch& srcPatch,
|
||||||
|
const vectorField& srcPointNormals,
|
||||||
|
const vectorField& srcPointNormals0,
|
||||||
|
const primitiveOldTimePatch& tgtPatch,
|
||||||
|
const label srcFacei,
|
||||||
|
const label tgtFacei
|
||||||
|
);
|
||||||
|
|
||||||
|
//- Initialise the workspace
|
||||||
|
virtual void initialise
|
||||||
|
(
|
||||||
|
const primitiveOldTimePatch& srcPatch,
|
||||||
|
const vectorField& srcPointNormals,
|
||||||
|
const vectorField& srcPointNormals0,
|
||||||
|
const primitiveOldTimePatch& tgtPatch
|
||||||
|
);
|
||||||
|
|
||||||
|
//- Send data that resulted from an intersection between the source
|
||||||
|
// patch and a distributed source-local-target patch back to the
|
||||||
|
// original target processes.
|
||||||
|
virtual void rDistributeTgt
|
||||||
|
(
|
||||||
|
const primitiveOldTimePatch& tgtPatch,
|
||||||
|
const distributionMap& tgtMap
|
||||||
|
);
|
||||||
|
|
||||||
|
//- Finalise the intersection
|
||||||
|
virtual label finalise
|
||||||
|
(
|
||||||
|
const primitiveOldTimePatch& srcPatch,
|
||||||
|
const vectorField& srcPointNormals,
|
||||||
|
const vectorField& srcPointNormals0,
|
||||||
|
const primitiveOldTimePatch& tgtPatch,
|
||||||
|
const transformer& tgtToSrc
|
||||||
|
);
|
||||||
|
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
//- Runtime type information
|
||||||
|
TypeName("intersection");
|
||||||
|
|
||||||
|
|
||||||
|
// Static Data Members
|
||||||
|
|
||||||
|
//- Extra debugging for intersections between specific faces. Named
|
||||||
|
// "intersectionSrcFace" and "intersectionTgtFace" respectively.
|
||||||
|
static int debugSrcFacei, debugTgtFacei;
|
||||||
|
|
||||||
|
|
||||||
|
// Static Member Functions
|
||||||
|
|
||||||
|
//- Get the bound box for a source face
|
||||||
|
static treeBoundBox srcBoxStatic
|
||||||
|
(
|
||||||
|
const face& srcFace,
|
||||||
|
const pointField& srcPoints,
|
||||||
|
const vectorField& srcPointNormals
|
||||||
|
);
|
||||||
|
|
||||||
|
|
||||||
|
// Constructors
|
||||||
|
|
||||||
|
//- Construct from components
|
||||||
|
intersection(const bool reverse);
|
||||||
|
|
||||||
|
|
||||||
|
//- Destructor
|
||||||
|
~intersection();
|
||||||
|
|
||||||
|
|
||||||
|
// Member Functions
|
||||||
|
|
||||||
|
//- For each source face, the source and target areas for each
|
||||||
|
// target coupling
|
||||||
|
inline const List<DynamicList<couple>>& srcCouples() const;
|
||||||
|
|
||||||
|
//- For each source edge, the non-coupled geometry associated
|
||||||
|
// with its projection
|
||||||
|
inline const List<part>& srcEdgeParts() const;
|
||||||
|
|
||||||
|
//- For each source face, the area associated with mismatch
|
||||||
|
// across the coupling
|
||||||
|
inline const List<part>& srcErrorParts() const;
|
||||||
|
|
||||||
|
//- For each target face, the target and source areas for each
|
||||||
|
// source coupling
|
||||||
|
inline const List<DynamicList<couple>>& tgtCouples() const;
|
||||||
|
|
||||||
|
//- For each source face, the coupled target weights
|
||||||
|
virtual tmpNrc<List<DynamicList<scalar>>> srcWeights
|
||||||
|
(
|
||||||
|
const primitivePatch& srcPatch
|
||||||
|
) const;
|
||||||
|
|
||||||
|
//- For each target face, the coupled source weights
|
||||||
|
virtual tmpNrc<List<DynamicList<scalar>>> tgtWeights
|
||||||
|
(
|
||||||
|
const primitivePatch& tgtPatch
|
||||||
|
) const;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
} // End namespace patchToPatches
|
||||||
|
} // End namespace Foam
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
#include "intersectionPatchToPatchI.H"
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// ************************************************************************* //
|
||||||
@ -0,0 +1,60 @@
|
|||||||
|
/*---------------------------------------------------------------------------*\
|
||||||
|
========= |
|
||||||
|
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||||
|
\\ / O peration | Website: https://openfoam.org
|
||||||
|
\\ / A nd | Copyright (C) 2011-2022 OpenFOAM Foundation
|
||||||
|
\\/ M anipulation |
|
||||||
|
-------------------------------------------------------------------------------
|
||||||
|
License
|
||||||
|
This file is part of OpenFOAM.
|
||||||
|
|
||||||
|
OpenFOAM is free software: you can redistribute it and/or modify it
|
||||||
|
under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation, either version 3 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
|
||||||
|
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||||
|
for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
\*---------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
#include "intersectionPatchToPatch.H"
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
inline const
|
||||||
|
Foam::List<Foam::DynamicList<Foam::patchToPatches::intersection::couple>>&
|
||||||
|
Foam::patchToPatches::intersection::srcCouples() const
|
||||||
|
{
|
||||||
|
return srcCouples_;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
inline const Foam::List<Foam::patchToPatches::intersection::part>&
|
||||||
|
Foam::patchToPatches::intersection::srcEdgeParts() const
|
||||||
|
{
|
||||||
|
return srcEdgeParts_;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
inline const Foam::List<Foam::patchToPatches::intersection::part>&
|
||||||
|
Foam::patchToPatches::intersection::srcErrorParts() const
|
||||||
|
{
|
||||||
|
return srcErrorParts_;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
inline const
|
||||||
|
Foam::List<Foam::DynamicList<Foam::patchToPatches::intersection::couple>>&
|
||||||
|
Foam::patchToPatches::intersection::tgtCouples() const
|
||||||
|
{
|
||||||
|
return tgtCouples_;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// ************************************************************************* //
|
||||||
@ -0,0 +1,284 @@
|
|||||||
|
/*---------------------------------------------------------------------------*\
|
||||||
|
========= |
|
||||||
|
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||||
|
\\ / O peration | Website: https://openfoam.org
|
||||||
|
\\ / A nd | Copyright (C) 2021-2022 OpenFOAM Foundation
|
||||||
|
\\/ M anipulation |
|
||||||
|
-------------------------------------------------------------------------------
|
||||||
|
License
|
||||||
|
This file is part of OpenFOAM.
|
||||||
|
|
||||||
|
OpenFOAM is free software: you can redistribute it and/or modify it
|
||||||
|
under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation, either version 3 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
|
||||||
|
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||||
|
for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
\*---------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
#include "inverseDistancePatchToPatch.H"
|
||||||
|
#include "mathematicalConstants.H"
|
||||||
|
#include "addToRunTimeSelectionTable.H"
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
namespace Foam
|
||||||
|
{
|
||||||
|
namespace patchToPatches
|
||||||
|
{
|
||||||
|
defineTypeNameAndDebug(inverseDistance, 0);
|
||||||
|
addToRunTimeSelectionTable(patchToPatch, inverseDistance, bool);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
|
||||||
|
|
||||||
|
Foam::treeBoundBox Foam::patchToPatches::inverseDistance::srcBox
|
||||||
|
(
|
||||||
|
const face& srcFace,
|
||||||
|
const pointField& srcPoints,
|
||||||
|
const vectorField& srcPointNormals
|
||||||
|
) const
|
||||||
|
{
|
||||||
|
const treeBoundBox bb(srcPoints, srcFace);
|
||||||
|
|
||||||
|
const point c = bb.midpoint();
|
||||||
|
const scalar l = bb.maxDim();
|
||||||
|
|
||||||
|
return treeBoundBox(c - l*vector::one, c + l*vector::one);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool Foam::patchToPatches::inverseDistance::inside
|
||||||
|
(
|
||||||
|
const face& f,
|
||||||
|
const pointField& ps,
|
||||||
|
const point& p,
|
||||||
|
const vector& r
|
||||||
|
) const
|
||||||
|
{
|
||||||
|
using namespace constant::mathematical;
|
||||||
|
|
||||||
|
const tensor T = tensor::I - sqr(r);
|
||||||
|
|
||||||
|
scalar angle = 0;
|
||||||
|
|
||||||
|
forAll(f, i)
|
||||||
|
{
|
||||||
|
const vector& a = T & (ps[f[i]] - p);
|
||||||
|
const vector& b = T & (ps[f[f.fcIndex(i)]] - p);
|
||||||
|
const scalar magAB = sqrt(magSqr(a)*magSqr(b));
|
||||||
|
angle -= sign(r & (a ^ b))*acos((a & b)/magAB);
|
||||||
|
}
|
||||||
|
|
||||||
|
return pi < angle && angle < 3*pi;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool Foam::patchToPatches::inverseDistance::intersectFaces
|
||||||
|
(
|
||||||
|
const primitivePatch& patch,
|
||||||
|
const primitivePatch& otherPatch,
|
||||||
|
const label facei,
|
||||||
|
const label otherFacei,
|
||||||
|
DynamicList<label>& faceOtherFaces,
|
||||||
|
DynamicList<scalar>& faceWeights
|
||||||
|
) const
|
||||||
|
{
|
||||||
|
const face& f = otherPatch[otherFacei];
|
||||||
|
const pointField& ps = otherPatch.points();
|
||||||
|
|
||||||
|
const point& p = patch.faceCentres()[facei];
|
||||||
|
const vector& r = patch.faceNormals()[facei];
|
||||||
|
|
||||||
|
bool intersectsOther = inside(f, ps, p, r);
|
||||||
|
|
||||||
|
if (!intersectsOther)
|
||||||
|
{
|
||||||
|
forAll(otherPatch.faceFaces()[otherFacei], otherFaceFacei)
|
||||||
|
{
|
||||||
|
const label otherFacej =
|
||||||
|
otherPatch.faceFaces()[otherFacei][otherFaceFacei];
|
||||||
|
|
||||||
|
const face& g = otherPatch[otherFacej];
|
||||||
|
|
||||||
|
if (inside(g, ps, p, r))
|
||||||
|
{
|
||||||
|
intersectsOther = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (intersectsOther)
|
||||||
|
{
|
||||||
|
faceOtherFaces.append(otherFacei);
|
||||||
|
faceWeights.append
|
||||||
|
(
|
||||||
|
1/max(mag(p - otherPatch.faceCentres()[otherFacei]), vSmall)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
return intersectsOther;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool Foam::patchToPatches::inverseDistance::intersectFaces
|
||||||
|
(
|
||||||
|
const primitiveOldTimePatch& srcPatch,
|
||||||
|
const vectorField& srcPointNormals,
|
||||||
|
const vectorField& srcPointNormals0,
|
||||||
|
const primitiveOldTimePatch& tgtPatch,
|
||||||
|
const label srcFacei,
|
||||||
|
const label tgtFacei
|
||||||
|
)
|
||||||
|
{
|
||||||
|
const bool srcCouples =
|
||||||
|
intersectFaces
|
||||||
|
(
|
||||||
|
srcPatch,
|
||||||
|
tgtPatch,
|
||||||
|
srcFacei,
|
||||||
|
tgtFacei,
|
||||||
|
srcLocalTgtFaces_[srcFacei],
|
||||||
|
srcWeights_[srcFacei]
|
||||||
|
);
|
||||||
|
|
||||||
|
const bool tgtCouples =
|
||||||
|
intersectFaces
|
||||||
|
(
|
||||||
|
tgtPatch,
|
||||||
|
srcPatch,
|
||||||
|
tgtFacei,
|
||||||
|
srcFacei,
|
||||||
|
tgtLocalSrcFaces_[tgtFacei],
|
||||||
|
tgtWeights_[tgtFacei]
|
||||||
|
);
|
||||||
|
|
||||||
|
return srcCouples || tgtCouples;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void Foam::patchToPatches::inverseDistance::initialise
|
||||||
|
(
|
||||||
|
const primitiveOldTimePatch& srcPatch,
|
||||||
|
const vectorField& srcPointNormals,
|
||||||
|
const vectorField& srcPointNormals0,
|
||||||
|
const primitiveOldTimePatch& tgtPatch
|
||||||
|
)
|
||||||
|
{
|
||||||
|
patchToPatch::initialise
|
||||||
|
(
|
||||||
|
srcPatch,
|
||||||
|
srcPointNormals,
|
||||||
|
srcPointNormals0,
|
||||||
|
tgtPatch
|
||||||
|
);
|
||||||
|
|
||||||
|
srcWeights_.resize(srcPatch.size());
|
||||||
|
tgtWeights_.resize(tgtPatch.size());
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void Foam::patchToPatches::inverseDistance::rDistributeTgt
|
||||||
|
(
|
||||||
|
const primitiveOldTimePatch& tgtPatch,
|
||||||
|
const distributionMap& tgtMap
|
||||||
|
)
|
||||||
|
{
|
||||||
|
patchToPatch::rDistributeTgt(tgtPatch, tgtMap);
|
||||||
|
|
||||||
|
rDistributeListList(tgtPatch.size(), tgtMap, tgtWeights_);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Foam::label Foam::patchToPatches::inverseDistance::finalise
|
||||||
|
(
|
||||||
|
const primitiveOldTimePatch& srcPatch,
|
||||||
|
const vectorField& srcPointNormals,
|
||||||
|
const vectorField& srcPointNormals0,
|
||||||
|
const primitiveOldTimePatch& tgtPatch,
|
||||||
|
const transformer& tgtToSrc
|
||||||
|
)
|
||||||
|
{
|
||||||
|
const label nCouples =
|
||||||
|
patchToPatch::finalise
|
||||||
|
(
|
||||||
|
srcPatch,
|
||||||
|
srcPointNormals,
|
||||||
|
srcPointNormals0,
|
||||||
|
tgtPatch,
|
||||||
|
tgtToSrc
|
||||||
|
);
|
||||||
|
|
||||||
|
forAll(srcWeights_, srcFacei)
|
||||||
|
{
|
||||||
|
const scalar w = sum(srcWeights_[srcFacei]);
|
||||||
|
|
||||||
|
forAll(srcWeights_[srcFacei], i)
|
||||||
|
{
|
||||||
|
srcWeights_[srcFacei][i] /= max(w, vSmall);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
forAll(tgtWeights_, tgtFacei)
|
||||||
|
{
|
||||||
|
const scalar w = sum(tgtWeights_[tgtFacei]);
|
||||||
|
|
||||||
|
forAll(tgtWeights_[tgtFacei], i)
|
||||||
|
{
|
||||||
|
tgtWeights_[tgtFacei][i] /= max(w, vSmall);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return nCouples;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
Foam::patchToPatches::inverseDistance::inverseDistance(const bool reverse)
|
||||||
|
:
|
||||||
|
patchToPatch(reverse),
|
||||||
|
srcWeights_(),
|
||||||
|
tgtWeights_()
|
||||||
|
{}
|
||||||
|
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
Foam::patchToPatches::inverseDistance::~inverseDistance()
|
||||||
|
{}
|
||||||
|
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
Foam::tmpNrc<Foam::List<Foam::DynamicList<Foam::scalar>>>
|
||||||
|
Foam::patchToPatches::inverseDistance::srcWeights
|
||||||
|
(
|
||||||
|
const primitivePatch& srcPatch
|
||||||
|
) const
|
||||||
|
{
|
||||||
|
return srcWeights_;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Foam::tmpNrc<Foam::List<Foam::DynamicList<Foam::scalar>>>
|
||||||
|
Foam::patchToPatches::inverseDistance::tgtWeights
|
||||||
|
(
|
||||||
|
const primitivePatch& tgtPatch
|
||||||
|
) const
|
||||||
|
{
|
||||||
|
return tgtWeights_;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// ************************************************************************* //
|
||||||
@ -0,0 +1,178 @@
|
|||||||
|
/*---------------------------------------------------------------------------*\
|
||||||
|
========= |
|
||||||
|
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||||
|
\\ / O peration | Website: https://openfoam.org
|
||||||
|
\\ / A nd | Copyright (C) 2021-2022 OpenFOAM Foundation
|
||||||
|
\\/ M anipulation |
|
||||||
|
-------------------------------------------------------------------------------
|
||||||
|
License
|
||||||
|
This file is part of OpenFOAM.
|
||||||
|
|
||||||
|
OpenFOAM is free software: you can redistribute it and/or modify it
|
||||||
|
under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation, either version 3 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
|
||||||
|
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||||
|
for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
Class
|
||||||
|
Foam::patchToPatches::inverseDistance
|
||||||
|
|
||||||
|
Description
|
||||||
|
Class to generate patchToPatch coupling geometry. Couples a face to the
|
||||||
|
opposite face onto which its centre-normal ray projects, plus the immediate
|
||||||
|
neighbours to that opposite face. The proportion of contribution from the
|
||||||
|
different faces is calculated using inverse distance weighting.
|
||||||
|
|
||||||
|
SourceFiles
|
||||||
|
inverseDistance.C
|
||||||
|
|
||||||
|
\*---------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
#ifndef inverseDistancePatchToPatch_H
|
||||||
|
#define inverseDistancePatchToPatch_H
|
||||||
|
|
||||||
|
#include "patchToPatch.H"
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
namespace Foam
|
||||||
|
{
|
||||||
|
namespace patchToPatches
|
||||||
|
{
|
||||||
|
|
||||||
|
/*---------------------------------------------------------------------------*\
|
||||||
|
Class inverseDistance Declaration
|
||||||
|
\*---------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
class inverseDistance
|
||||||
|
:
|
||||||
|
public patchToPatch
|
||||||
|
{
|
||||||
|
// Private Member Data
|
||||||
|
|
||||||
|
//- For each source face, the coupled target weights
|
||||||
|
List<DynamicList<scalar>> srcWeights_;
|
||||||
|
|
||||||
|
//- For each target face, the coupled source weights
|
||||||
|
List<DynamicList<scalar>> tgtWeights_;
|
||||||
|
|
||||||
|
|
||||||
|
// Private Member Functions
|
||||||
|
|
||||||
|
//- Get the bound box for a source face
|
||||||
|
virtual treeBoundBox srcBox
|
||||||
|
(
|
||||||
|
const face& srcFace,
|
||||||
|
const pointField& srcPoints,
|
||||||
|
const vectorField& srcPointNormals
|
||||||
|
) const;
|
||||||
|
|
||||||
|
//- Return whether or not the face contains a point
|
||||||
|
bool inside
|
||||||
|
(
|
||||||
|
const face& f,
|
||||||
|
const pointField& ps,
|
||||||
|
const point& p,
|
||||||
|
const vector& r
|
||||||
|
) const;
|
||||||
|
|
||||||
|
//- Intersect two faces
|
||||||
|
virtual bool intersectFaces
|
||||||
|
(
|
||||||
|
const primitivePatch& patch,
|
||||||
|
const primitivePatch& otherPatch,
|
||||||
|
const label facei,
|
||||||
|
const label otherFacei,
|
||||||
|
DynamicList<label>& faceOtherFaces,
|
||||||
|
DynamicList<scalar>& faceWeights
|
||||||
|
) const;
|
||||||
|
|
||||||
|
//- Intersect two faces
|
||||||
|
virtual bool intersectFaces
|
||||||
|
(
|
||||||
|
const primitiveOldTimePatch& srcPatch,
|
||||||
|
const vectorField& srcPointNormals,
|
||||||
|
const vectorField& srcPointNormals0,
|
||||||
|
const primitiveOldTimePatch& tgtPatch,
|
||||||
|
const label srcFacei,
|
||||||
|
const label tgtFacei
|
||||||
|
);
|
||||||
|
|
||||||
|
//- Initialisation
|
||||||
|
virtual void initialise
|
||||||
|
(
|
||||||
|
const primitiveOldTimePatch& srcPatch,
|
||||||
|
const vectorField& srcPointNormals,
|
||||||
|
const vectorField& srcPointNormals0,
|
||||||
|
const primitiveOldTimePatch& tgtPatch
|
||||||
|
);
|
||||||
|
|
||||||
|
//- Send data that resulted from an intersection between the source
|
||||||
|
// patch and a distributed source-local-target patch back to the
|
||||||
|
// original target processes.
|
||||||
|
virtual void rDistributeTgt
|
||||||
|
(
|
||||||
|
const primitiveOldTimePatch& tgtPatch,
|
||||||
|
const distributionMap& tgtMap
|
||||||
|
);
|
||||||
|
|
||||||
|
//- Finalise the intersection
|
||||||
|
virtual label finalise
|
||||||
|
(
|
||||||
|
const primitiveOldTimePatch& srcPatch,
|
||||||
|
const vectorField& srcPointNormals,
|
||||||
|
const vectorField& srcPointNormals0,
|
||||||
|
const primitiveOldTimePatch& tgtPatch,
|
||||||
|
const transformer& tgtToSrc
|
||||||
|
);
|
||||||
|
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
//- Runtime type information
|
||||||
|
TypeName("inverseDistance");
|
||||||
|
|
||||||
|
|
||||||
|
// Constructors
|
||||||
|
|
||||||
|
//- Construct from components
|
||||||
|
inverseDistance(const bool reverse);
|
||||||
|
|
||||||
|
|
||||||
|
//- Destructor
|
||||||
|
~inverseDistance();
|
||||||
|
|
||||||
|
|
||||||
|
// Member Functions
|
||||||
|
|
||||||
|
//- For each source face, the coupled target weights
|
||||||
|
virtual tmpNrc<List<DynamicList<scalar>>> srcWeights
|
||||||
|
(
|
||||||
|
const primitivePatch& srcPatch
|
||||||
|
) const;
|
||||||
|
|
||||||
|
//- For each target face, the coupled source weights
|
||||||
|
virtual tmpNrc<List<DynamicList<scalar>>> tgtWeights
|
||||||
|
(
|
||||||
|
const primitivePatch& tgtPatch
|
||||||
|
) const;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
} // End namespace patchToPatches
|
||||||
|
} // End namespace Foam
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// ************************************************************************* //
|
||||||
303
src/meshTools/patchToPatch/nearest/nearestPatchToPatch.C
Normal file
303
src/meshTools/patchToPatch/nearest/nearestPatchToPatch.C
Normal file
@ -0,0 +1,303 @@
|
|||||||
|
/*---------------------------------------------------------------------------*\
|
||||||
|
========= |
|
||||||
|
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||||
|
\\ / O peration | Website: https://openfoam.org
|
||||||
|
\\ / A nd | Copyright (C) 2021-2022 OpenFOAM Foundation
|
||||||
|
\\/ M anipulation |
|
||||||
|
-------------------------------------------------------------------------------
|
||||||
|
License
|
||||||
|
This file is part of OpenFOAM.
|
||||||
|
|
||||||
|
OpenFOAM is free software: you can redistribute it and/or modify it
|
||||||
|
under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation, either version 3 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
|
||||||
|
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||||
|
for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
\*---------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
#include "nearestPatchToPatch.H"
|
||||||
|
#include "addToRunTimeSelectionTable.H"
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
namespace Foam
|
||||||
|
{
|
||||||
|
namespace patchToPatches
|
||||||
|
{
|
||||||
|
defineTypeNameAndDebug(nearest, 0);
|
||||||
|
addToRunTimeSelectionTable(patchToPatch, nearest, bool);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
|
||||||
|
|
||||||
|
Foam::treeBoundBox Foam::patchToPatches::nearest::srcBox
|
||||||
|
(
|
||||||
|
const face& srcFace,
|
||||||
|
const pointField& srcPoints,
|
||||||
|
const vectorField& srcPointNormals
|
||||||
|
) const
|
||||||
|
{
|
||||||
|
const treeBoundBox bb(srcPoints, srcFace);
|
||||||
|
|
||||||
|
const point c = bb.midpoint();
|
||||||
|
const scalar l = bb.maxDim();
|
||||||
|
|
||||||
|
return treeBoundBox(c - l*vector::one, c + l*vector::one);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool Foam::patchToPatches::nearest::intersectFaces
|
||||||
|
(
|
||||||
|
const primitivePatch& patch,
|
||||||
|
const primitivePatch& otherPatch,
|
||||||
|
const label facei,
|
||||||
|
const label otherFacei,
|
||||||
|
DynamicList<label>& faceOtherFaces,
|
||||||
|
scalar& faceDistance
|
||||||
|
) const
|
||||||
|
{
|
||||||
|
auto closest = [&patch,&otherPatch]
|
||||||
|
(
|
||||||
|
const label facei,
|
||||||
|
const label otherFacei
|
||||||
|
)
|
||||||
|
{
|
||||||
|
const point& c = patch.faceCentres()[facei];
|
||||||
|
const point& otherC = otherPatch.faceCentres()[otherFacei];
|
||||||
|
const scalar distSqr = magSqr(c - otherC);
|
||||||
|
|
||||||
|
forAll(otherPatch.faceEdges()[otherFacei], otherFaceEdgei)
|
||||||
|
{
|
||||||
|
const label otherEdgei =
|
||||||
|
otherPatch.faceEdges()[otherFacei][otherFaceEdgei];
|
||||||
|
|
||||||
|
point otherNbrC;
|
||||||
|
|
||||||
|
if (otherPatch.edgeFaces()[otherEdgei].size() == 2)
|
||||||
|
{
|
||||||
|
const label facej =
|
||||||
|
otherPatch.edgeFaces()[otherEdgei]
|
||||||
|
[otherPatch.edgeFaces()[otherEdgei][0] == otherFacei];
|
||||||
|
|
||||||
|
otherNbrC = otherPatch.faceCentres()[facej];
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
const edge& e = otherPatch.edges()[otherEdgei];
|
||||||
|
const point& p = otherPatch.localPoints()[e[0]];
|
||||||
|
const vector dp = e.vec(otherPatch.localPoints());
|
||||||
|
const vector n = otherPatch.faceNormals()[otherFacei] ^ dp;
|
||||||
|
|
||||||
|
otherNbrC = p + ((tensor::I - 2*sqr(n)) & (otherC - p));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (magSqr(c - otherNbrC) < distSqr)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
};
|
||||||
|
|
||||||
|
if (closest(facei, otherFacei))
|
||||||
|
{
|
||||||
|
const point& c = patch.faceCentres()[facei];
|
||||||
|
const point& otherC = otherPatch.faceCentres()[otherFacei];
|
||||||
|
const scalar distSqr = magSqr(c - otherC);
|
||||||
|
|
||||||
|
if (faceOtherFaces.empty() || faceDistance > distSqr)
|
||||||
|
{
|
||||||
|
faceOtherFaces.clear();
|
||||||
|
faceOtherFaces.append(otherFacei);
|
||||||
|
faceDistance = distSqr;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
const labelList& otherFaceFaces = otherPatch.faceFaces()[otherFacei];
|
||||||
|
forAll(otherFaceFaces, otherFaceFacei)
|
||||||
|
{
|
||||||
|
if (closest(facei, otherFaceFaces[otherFaceFacei]))
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool Foam::patchToPatches::nearest::intersectFaces
|
||||||
|
(
|
||||||
|
const primitiveOldTimePatch& srcPatch,
|
||||||
|
const vectorField& srcPointNormals,
|
||||||
|
const vectorField& srcPointNormals0,
|
||||||
|
const primitiveOldTimePatch& tgtPatch,
|
||||||
|
const label srcFacei,
|
||||||
|
const label tgtFacei
|
||||||
|
)
|
||||||
|
{
|
||||||
|
const bool srcCouples =
|
||||||
|
intersectFaces
|
||||||
|
(
|
||||||
|
srcPatch,
|
||||||
|
tgtPatch,
|
||||||
|
srcFacei,
|
||||||
|
tgtFacei,
|
||||||
|
srcLocalTgtFaces_[srcFacei],
|
||||||
|
srcDistances_[srcFacei]
|
||||||
|
);
|
||||||
|
|
||||||
|
const bool tgtCouples =
|
||||||
|
intersectFaces
|
||||||
|
(
|
||||||
|
tgtPatch,
|
||||||
|
srcPatch,
|
||||||
|
tgtFacei,
|
||||||
|
srcFacei,
|
||||||
|
tgtLocalSrcFaces_[tgtFacei],
|
||||||
|
tgtDistances_[tgtFacei]
|
||||||
|
);
|
||||||
|
|
||||||
|
return srcCouples || tgtCouples;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void Foam::patchToPatches::nearest::initialise
|
||||||
|
(
|
||||||
|
const primitiveOldTimePatch& srcPatch,
|
||||||
|
const vectorField& srcPointNormals,
|
||||||
|
const vectorField& srcPointNormals0,
|
||||||
|
const primitiveOldTimePatch& tgtPatch
|
||||||
|
)
|
||||||
|
{
|
||||||
|
patchToPatch::initialise
|
||||||
|
(
|
||||||
|
srcPatch,
|
||||||
|
srcPointNormals,
|
||||||
|
srcPointNormals0,
|
||||||
|
tgtPatch
|
||||||
|
);
|
||||||
|
|
||||||
|
srcDistances_.resize(srcPatch.size());
|
||||||
|
srcDistances_ = vGreat;
|
||||||
|
|
||||||
|
tgtDistances_.resize(tgtPatch.size());
|
||||||
|
tgtDistances_ = vGreat;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void Foam::patchToPatches::nearest::rDistributeTgt
|
||||||
|
(
|
||||||
|
const primitiveOldTimePatch& tgtPatch,
|
||||||
|
const distributionMap& tgtMap
|
||||||
|
)
|
||||||
|
{
|
||||||
|
// Create a list-list of distances to match the addressing
|
||||||
|
List<List<scalar>> tgtDistances(tgtLocalSrcFaces_.size());
|
||||||
|
forAll(tgtLocalSrcFaces_, tgtFacei)
|
||||||
|
{
|
||||||
|
if (!tgtLocalSrcFaces_[tgtFacei].empty())
|
||||||
|
{
|
||||||
|
tgtDistances[tgtFacei].resize(1, tgtDistances_[tgtFacei]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Let the base class reverse distribute the addressing
|
||||||
|
patchToPatch::rDistributeTgt(tgtPatch, tgtMap);
|
||||||
|
|
||||||
|
// Reverse distribute the distances
|
||||||
|
rDistributeListList(tgtPatch.size(), tgtMap, tgtDistances);
|
||||||
|
|
||||||
|
// If there is more than one address, remove all but the closest
|
||||||
|
forAll(tgtLocalSrcFaces_, tgtFacei)
|
||||||
|
{
|
||||||
|
if (tgtLocalSrcFaces_[tgtFacei].size() > 1)
|
||||||
|
{
|
||||||
|
const label i = findMin(tgtDistances[tgtFacei]);
|
||||||
|
|
||||||
|
const label srcFacei = tgtLocalSrcFaces_[tgtFacei][i];
|
||||||
|
|
||||||
|
tgtLocalSrcFaces_[tgtFacei].resize(1);
|
||||||
|
tgtLocalSrcFaces_[tgtFacei][0] = srcFacei;
|
||||||
|
|
||||||
|
tgtDistances_[tgtFacei] = tgtDistances[tgtFacei][i];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
Foam::patchToPatches::nearest::nearest(const bool reverse)
|
||||||
|
:
|
||||||
|
patchToPatch(reverse)
|
||||||
|
{}
|
||||||
|
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
Foam::patchToPatches::nearest::~nearest()
|
||||||
|
{}
|
||||||
|
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
Foam::tmpNrc<Foam::List<Foam::DynamicList<Foam::scalar>>>
|
||||||
|
Foam::patchToPatches::nearest::srcWeights(const primitivePatch& srcPatch) const
|
||||||
|
{
|
||||||
|
tmpNrc<List<DynamicList<scalar>>> tResult
|
||||||
|
(
|
||||||
|
new List<DynamicList<scalar>>(srcLocalTgtFaces_.size())
|
||||||
|
);
|
||||||
|
|
||||||
|
List<DynamicList<scalar>>& result = tResult.ref();
|
||||||
|
|
||||||
|
forAll(srcLocalTgtFaces_, srcFacei)
|
||||||
|
{
|
||||||
|
if (!srcLocalTgtFaces_[srcFacei].empty())
|
||||||
|
{
|
||||||
|
result[srcFacei].resize(1, scalar(1));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return tResult;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Foam::tmpNrc<Foam::List<Foam::DynamicList<Foam::scalar>>>
|
||||||
|
Foam::patchToPatches::nearest::tgtWeights(const primitivePatch& tgtPatch) const
|
||||||
|
{
|
||||||
|
tmpNrc<List<DynamicList<scalar>>> tResult
|
||||||
|
(
|
||||||
|
new List<DynamicList<scalar>>(tgtLocalSrcFaces_.size())
|
||||||
|
);
|
||||||
|
|
||||||
|
List<DynamicList<scalar>>& result = tResult.ref();
|
||||||
|
|
||||||
|
forAll(tgtLocalSrcFaces_, tgtFacei)
|
||||||
|
{
|
||||||
|
if (!tgtLocalSrcFaces_[tgtFacei].empty())
|
||||||
|
{
|
||||||
|
result[tgtFacei].resize(1, scalar(1));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return tResult;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// ************************************************************************* //
|
||||||
157
src/meshTools/patchToPatch/nearest/nearestPatchToPatch.H
Normal file
157
src/meshTools/patchToPatch/nearest/nearestPatchToPatch.H
Normal file
@ -0,0 +1,157 @@
|
|||||||
|
/*---------------------------------------------------------------------------*\
|
||||||
|
========= |
|
||||||
|
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||||
|
\\ / O peration | Website: https://openfoam.org
|
||||||
|
\\ / A nd | Copyright (C) 2021-2022 OpenFOAM Foundation
|
||||||
|
\\/ M anipulation |
|
||||||
|
-------------------------------------------------------------------------------
|
||||||
|
License
|
||||||
|
This file is part of OpenFOAM.
|
||||||
|
|
||||||
|
OpenFOAM is free software: you can redistribute it and/or modify it
|
||||||
|
under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation, either version 3 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
|
||||||
|
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||||
|
for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
Class
|
||||||
|
Foam::patchToPatches::nearest
|
||||||
|
|
||||||
|
Description
|
||||||
|
Class to generate patchToPatch coupling geometry. Couples a face to the
|
||||||
|
single nearest opposite face only.
|
||||||
|
|
||||||
|
SourceFiles
|
||||||
|
nearest.C
|
||||||
|
|
||||||
|
\*---------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
#ifndef nearestPatchToPatch_H
|
||||||
|
#define nearestPatchToPatch_H
|
||||||
|
|
||||||
|
#include "patchToPatch.H"
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
namespace Foam
|
||||||
|
{
|
||||||
|
namespace patchToPatches
|
||||||
|
{
|
||||||
|
|
||||||
|
/*---------------------------------------------------------------------------*\
|
||||||
|
Class nearest Declaration
|
||||||
|
\*---------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
class nearest
|
||||||
|
:
|
||||||
|
public patchToPatch
|
||||||
|
{
|
||||||
|
// Private Member Data
|
||||||
|
|
||||||
|
//- For each source face, the distance to its coupled target face
|
||||||
|
List<scalar> srcDistances_;
|
||||||
|
|
||||||
|
//- For each target face, the distance to its coupled source face
|
||||||
|
List<scalar> tgtDistances_;
|
||||||
|
|
||||||
|
|
||||||
|
// Private Member Functions
|
||||||
|
|
||||||
|
//- Get the bound box for a source face
|
||||||
|
virtual treeBoundBox srcBox
|
||||||
|
(
|
||||||
|
const face& srcFace,
|
||||||
|
const pointField& srcPoints,
|
||||||
|
const vectorField& srcPointNormals
|
||||||
|
) const;
|
||||||
|
|
||||||
|
//- Intersect two faces
|
||||||
|
bool intersectFaces
|
||||||
|
(
|
||||||
|
const primitivePatch& patch,
|
||||||
|
const primitivePatch& otherPatch,
|
||||||
|
const label facei,
|
||||||
|
const label otherFacei,
|
||||||
|
DynamicList<label>& faceOtherFaces,
|
||||||
|
scalar& faceDistance
|
||||||
|
) const;
|
||||||
|
|
||||||
|
//- Intersect two faces
|
||||||
|
virtual bool intersectFaces
|
||||||
|
(
|
||||||
|
const primitiveOldTimePatch& srcPatch,
|
||||||
|
const vectorField& srcPointNormals,
|
||||||
|
const vectorField& srcPointNormals0,
|
||||||
|
const primitiveOldTimePatch& tgtPatch,
|
||||||
|
const label srcFacei,
|
||||||
|
const label tgtFacei
|
||||||
|
);
|
||||||
|
|
||||||
|
//- Initialisation
|
||||||
|
virtual void initialise
|
||||||
|
(
|
||||||
|
const primitiveOldTimePatch& srcPatch,
|
||||||
|
const vectorField& srcPointNormals,
|
||||||
|
const vectorField& srcPointNormals0,
|
||||||
|
const primitiveOldTimePatch& tgtPatch
|
||||||
|
);
|
||||||
|
|
||||||
|
//- Send data that resulted from an intersection between the source
|
||||||
|
// patch and a distributed source-local-target patch back to the
|
||||||
|
// original target processes.
|
||||||
|
virtual void rDistributeTgt
|
||||||
|
(
|
||||||
|
const primitiveOldTimePatch& tgtPatch,
|
||||||
|
const distributionMap& tgtMap
|
||||||
|
);
|
||||||
|
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
//- Runtime type information
|
||||||
|
TypeName("nearest");
|
||||||
|
|
||||||
|
|
||||||
|
// Constructors
|
||||||
|
|
||||||
|
//- Construct from components
|
||||||
|
nearest(const bool reverse);
|
||||||
|
|
||||||
|
|
||||||
|
//- Destructor
|
||||||
|
~nearest();
|
||||||
|
|
||||||
|
|
||||||
|
// Member Functions
|
||||||
|
|
||||||
|
//- For each source face, the coupled target weights
|
||||||
|
virtual tmpNrc<List<DynamicList<scalar>>> srcWeights
|
||||||
|
(
|
||||||
|
const primitivePatch& srcPatch
|
||||||
|
) const;
|
||||||
|
|
||||||
|
//- For each target face, the coupled source weights
|
||||||
|
virtual tmpNrc<List<DynamicList<scalar>>> tgtWeights
|
||||||
|
(
|
||||||
|
const primitivePatch& tgtPatch
|
||||||
|
) const;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
} // End namespace patchToPatches
|
||||||
|
} // End namespace Foam
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// ************************************************************************* //
|
||||||
1063
src/meshTools/patchToPatch/patchToPatch/patchToPatch.C
Normal file
1063
src/meshTools/patchToPatch/patchToPatch/patchToPatch.C
Normal file
File diff suppressed because it is too large
Load Diff
485
src/meshTools/patchToPatch/patchToPatch/patchToPatch.H
Normal file
485
src/meshTools/patchToPatch/patchToPatch/patchToPatch.H
Normal file
@ -0,0 +1,485 @@
|
|||||||
|
/*---------------------------------------------------------------------------*\
|
||||||
|
========= |
|
||||||
|
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||||
|
\\ / O peration | Website: https://openfoam.org
|
||||||
|
\\ / A nd | Copyright (C) 2011-2022 OpenFOAM Foundation
|
||||||
|
\\/ M anipulation |
|
||||||
|
-------------------------------------------------------------------------------
|
||||||
|
License
|
||||||
|
This file is part of OpenFOAM.
|
||||||
|
|
||||||
|
OpenFOAM is free software: you can redistribute it and/or modify it
|
||||||
|
under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation, either version 3 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
|
||||||
|
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||||
|
for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
Class
|
||||||
|
Foam::patchToPatch
|
||||||
|
|
||||||
|
Description
|
||||||
|
Class to generate coupling geometry between two primitive patches
|
||||||
|
|
||||||
|
SourceFiles
|
||||||
|
patchToPatch.C
|
||||||
|
patchToPatchParallelOps.C
|
||||||
|
|
||||||
|
\*---------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
#ifndef patchToPatch_H
|
||||||
|
#define patchToPatch_H
|
||||||
|
|
||||||
|
#include "distributionMap.H"
|
||||||
|
#include "primitivePatch.H"
|
||||||
|
#include "primitiveOldTimePatch.H"
|
||||||
|
#include "runTimeSelectionTables.H"
|
||||||
|
#include "treeBoundBox.H"
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
namespace Foam
|
||||||
|
{
|
||||||
|
|
||||||
|
/*---------------------------------------------------------------------------*\
|
||||||
|
Class patchToPatch Declaration
|
||||||
|
\*---------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
class patchToPatch
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
|
||||||
|
// Public Structures
|
||||||
|
|
||||||
|
//- Structure to conveniently store processor and face indices
|
||||||
|
struct procFace
|
||||||
|
{
|
||||||
|
//- The processor index
|
||||||
|
label proci;
|
||||||
|
|
||||||
|
//- The face index
|
||||||
|
label facei;
|
||||||
|
|
||||||
|
//- Equality comparison
|
||||||
|
friend bool operator==(const procFace& a, const procFace& b)
|
||||||
|
{
|
||||||
|
return a.proci == b.proci && a.facei == b.facei;
|
||||||
|
}
|
||||||
|
|
||||||
|
//- Inequality comparison
|
||||||
|
friend bool operator!=(const procFace& a, const procFace& b)
|
||||||
|
{
|
||||||
|
return !(a == b);
|
||||||
|
}
|
||||||
|
|
||||||
|
//- Output stream operator
|
||||||
|
friend Ostream& operator<<(Ostream& os, const procFace& p)
|
||||||
|
{
|
||||||
|
return os << p.proci << token::SPACE << p.facei;
|
||||||
|
}
|
||||||
|
|
||||||
|
//- Input stream operator
|
||||||
|
friend Istream& operator>>(Istream& is, procFace& p)
|
||||||
|
{
|
||||||
|
return is >> p.proci >> p.facei;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
protected:
|
||||||
|
|
||||||
|
// Private Data
|
||||||
|
|
||||||
|
//- Flag to indicate that the two patches are co-directional and
|
||||||
|
// that the orientation of one should therefore be reversed
|
||||||
|
const bool reverse_;
|
||||||
|
|
||||||
|
//- Index of the processor holding all faces of the patchToPatch, or -1
|
||||||
|
// if spread across multiple processors
|
||||||
|
label singleProcess_;
|
||||||
|
|
||||||
|
//- When running in parallel, a map from local source face index to
|
||||||
|
// source processor and face index
|
||||||
|
autoPtr<List<procFace>> localSrcProcFacesPtr_;
|
||||||
|
|
||||||
|
//- When running in parallel, a map from local target face index to
|
||||||
|
// target processor and face index
|
||||||
|
autoPtr<List<procFace>> localTgtProcFacesPtr_;
|
||||||
|
|
||||||
|
//- For each source face, the coupled local target faces
|
||||||
|
List<DynamicList<label>> srcLocalTgtFaces_;
|
||||||
|
|
||||||
|
//- For each target face, the coupled local source faces
|
||||||
|
List<DynamicList<label>> tgtLocalSrcFaces_;
|
||||||
|
|
||||||
|
|
||||||
|
// Private Member Functions
|
||||||
|
|
||||||
|
// Indexing
|
||||||
|
|
||||||
|
//- Transfer list-list b into list-list a
|
||||||
|
template<class SubListA, class SubListB>
|
||||||
|
static inline void transferListList
|
||||||
|
(
|
||||||
|
List<SubListA>& a,
|
||||||
|
List<SubListB>& b
|
||||||
|
);
|
||||||
|
|
||||||
|
//- Reverse distribute a list-list given the map
|
||||||
|
template<class Type>
|
||||||
|
static inline void rDistributeListList
|
||||||
|
(
|
||||||
|
const label size,
|
||||||
|
const distributionMap& map,
|
||||||
|
List<List<Type>>& data
|
||||||
|
);
|
||||||
|
|
||||||
|
//- Reverse distribute a dynamic list-list given the map
|
||||||
|
template<class Type>
|
||||||
|
static inline void rDistributeListList
|
||||||
|
(
|
||||||
|
const label size,
|
||||||
|
const distributionMap& map,
|
||||||
|
List<DynamicList<Type>>& data
|
||||||
|
);
|
||||||
|
|
||||||
|
//- Map local faces to proc faces
|
||||||
|
static List<List<procFace>> localFacesToProcFaces
|
||||||
|
(
|
||||||
|
const List<DynamicList<label>>& localFaces,
|
||||||
|
const List<procFace>& map = NullObjectRef<List<procFace>>()
|
||||||
|
);
|
||||||
|
|
||||||
|
//- Map proc faces to local faces
|
||||||
|
static List<DynamicList<label>> procFacesToLocalFaces
|
||||||
|
(
|
||||||
|
const List<List<procFace>>& procFaces,
|
||||||
|
const HashTable<label, procFace, Hash<procFace>>& map
|
||||||
|
);
|
||||||
|
|
||||||
|
|
||||||
|
// Searching
|
||||||
|
|
||||||
|
//- Get the bound box for a source face
|
||||||
|
virtual treeBoundBox srcBox
|
||||||
|
(
|
||||||
|
const face& srcFace,
|
||||||
|
const pointField& srcPoints,
|
||||||
|
const vectorField& srcPointNormals
|
||||||
|
) const = 0;
|
||||||
|
|
||||||
|
//- Get the bound box for a source face
|
||||||
|
treeBoundBox srcBox
|
||||||
|
(
|
||||||
|
const primitiveOldTimePatch& srcPatch,
|
||||||
|
const vectorField& srcPointNormals,
|
||||||
|
const vectorField& srcPointNormals0,
|
||||||
|
const label srcFacei
|
||||||
|
) const;
|
||||||
|
|
||||||
|
//- Get the bound box for the source patch
|
||||||
|
treeBoundBox srcBox
|
||||||
|
(
|
||||||
|
const primitiveOldTimePatch& srcPatch,
|
||||||
|
const vectorField& srcPointNormals,
|
||||||
|
const vectorField& srcPointNormals0
|
||||||
|
) const;
|
||||||
|
|
||||||
|
//- Get the bound box for a target face
|
||||||
|
treeBoundBox tgtBox
|
||||||
|
(
|
||||||
|
const primitiveOldTimePatch& tgtPatch,
|
||||||
|
const label tgtFacei
|
||||||
|
) const;
|
||||||
|
|
||||||
|
//- Get the bound box for the target patch
|
||||||
|
treeBoundBox tgtBox
|
||||||
|
(
|
||||||
|
const primitiveOldTimePatch& tgtPatch
|
||||||
|
) const;
|
||||||
|
|
||||||
|
|
||||||
|
// Intersection
|
||||||
|
|
||||||
|
//- Intersect two faces
|
||||||
|
virtual bool intersectFaces
|
||||||
|
(
|
||||||
|
const primitiveOldTimePatch& srcPatch,
|
||||||
|
const vectorField& srcPointNormals,
|
||||||
|
const vectorField& srcPointNormals0,
|
||||||
|
const primitiveOldTimePatch& tgtPatch,
|
||||||
|
const label srcFacei,
|
||||||
|
const label tgtFacei
|
||||||
|
) = 0;
|
||||||
|
|
||||||
|
//- Intersect two faces
|
||||||
|
bool findOrIntersectFaces
|
||||||
|
(
|
||||||
|
const primitiveOldTimePatch& srcPatch,
|
||||||
|
const vectorField& srcPointNormals,
|
||||||
|
const vectorField& srcPointNormals0,
|
||||||
|
const primitiveOldTimePatch& tgtPatch,
|
||||||
|
const label srcFacei,
|
||||||
|
const label tgtFacei
|
||||||
|
);
|
||||||
|
|
||||||
|
//- Intersect a queue of source-target face pairs. Update completion
|
||||||
|
// lists and form a new queue of target-source face pairs.
|
||||||
|
label intersectPatchQueue
|
||||||
|
(
|
||||||
|
const primitiveOldTimePatch& srcPatch,
|
||||||
|
const vectorField& srcPointNormals,
|
||||||
|
const vectorField& srcPointNormals0,
|
||||||
|
const primitiveOldTimePatch& tgtPatch,
|
||||||
|
const bool isSrc,
|
||||||
|
const DynamicList<labelPair>& queue,
|
||||||
|
labelList& faceComplete,
|
||||||
|
DynamicList<labelPair>& otherQueue,
|
||||||
|
const labelList& otherFaceComplete,
|
||||||
|
boolList& otherFaceQueued,
|
||||||
|
boolList& otherFaceVisited
|
||||||
|
);
|
||||||
|
|
||||||
|
//- Intersect the patches
|
||||||
|
void intersectPatches
|
||||||
|
(
|
||||||
|
const primitiveOldTimePatch& srcPatch,
|
||||||
|
const vectorField& srcPointNormals,
|
||||||
|
const vectorField& srcPointNormals0,
|
||||||
|
const primitiveOldTimePatch& tgtPatch
|
||||||
|
);
|
||||||
|
|
||||||
|
|
||||||
|
// Parallel functionality
|
||||||
|
|
||||||
|
//- Determine whether or not the intersection of the given patches
|
||||||
|
// is on a single process. Set singleProcess_ to that process if
|
||||||
|
// so, and to -1 if not.
|
||||||
|
void calcSingleProcess
|
||||||
|
(
|
||||||
|
const primitiveOldTimePatch& srcPatch,
|
||||||
|
const primitiveOldTimePatch& tgtPatch
|
||||||
|
);
|
||||||
|
|
||||||
|
//- Determine which target faces need to be sent to the source.
|
||||||
|
// This is done before intersection. Bound boxes are used to
|
||||||
|
// estimate what faces will intersect.
|
||||||
|
labelListList tgtPatchSendFaces
|
||||||
|
(
|
||||||
|
const primitiveOldTimePatch& srcPatch,
|
||||||
|
const vectorField& srcPointNormals,
|
||||||
|
const vectorField& srcPointNormals0,
|
||||||
|
const primitiveOldTimePatch& tgtPatch
|
||||||
|
) const;
|
||||||
|
|
||||||
|
//- Determine which source faces need to be sent to the target.
|
||||||
|
// This is done after intersection, using the addressing generated
|
||||||
|
// by the intersection.
|
||||||
|
labelListList srcPatchSendFaces() const;
|
||||||
|
|
||||||
|
//- Create a distribution map from a list-list of faces to be sent
|
||||||
|
// (i.e., the result of calling one of the above methods).
|
||||||
|
distributionMap patchDistributionMap
|
||||||
|
(
|
||||||
|
labelListList&& sendFaces
|
||||||
|
) const;
|
||||||
|
|
||||||
|
//- Distribute a patch given its distribution map. Just generate
|
||||||
|
// local-proc-face addressing; not the distributed patch itself.
|
||||||
|
void distributePatch
|
||||||
|
(
|
||||||
|
const distributionMap& map,
|
||||||
|
List<procFace>& localProcFaces
|
||||||
|
) const;
|
||||||
|
|
||||||
|
//- Distribute a patch given its distribution map
|
||||||
|
PrimitiveOldTimePatch<faceList, pointField> distributePatch
|
||||||
|
(
|
||||||
|
const distributionMap& map,
|
||||||
|
const primitiveOldTimePatch& patch,
|
||||||
|
List<procFace>& localProcFaces
|
||||||
|
) const;
|
||||||
|
|
||||||
|
|
||||||
|
// Hooks
|
||||||
|
|
||||||
|
//- Initialisation
|
||||||
|
virtual void initialise
|
||||||
|
(
|
||||||
|
const primitiveOldTimePatch& srcPatch,
|
||||||
|
const vectorField& srcPointNormals,
|
||||||
|
const vectorField& srcPointNormals0,
|
||||||
|
const primitiveOldTimePatch& tgtPatch
|
||||||
|
);
|
||||||
|
|
||||||
|
//- Distribute the target patch so that enough is locally available
|
||||||
|
// for its intersection with the source patch can be computed.
|
||||||
|
// Happens before intersection. Bound boxes are used to determine
|
||||||
|
// what is needed where. Return the resulting local patch and the
|
||||||
|
// map from which it was calculated.
|
||||||
|
virtual
|
||||||
|
tmpNrc<PrimitiveOldTimePatch<faceList, pointField>>
|
||||||
|
distributeTgt
|
||||||
|
(
|
||||||
|
const primitiveOldTimePatch& srcPatch,
|
||||||
|
const vectorField& srcPointNormals,
|
||||||
|
const vectorField& srcPointNormals0,
|
||||||
|
const primitiveOldTimePatch& tgtPatch,
|
||||||
|
distributionMap& tgtMap
|
||||||
|
);
|
||||||
|
|
||||||
|
//- Distribute the source patch so that everything the target
|
||||||
|
// intersects is locally available. Happens after intersection.
|
||||||
|
// The intersection addressing is used to determine what is needed
|
||||||
|
// where. Return the resulting local patch and the map from which
|
||||||
|
// it was calculated.
|
||||||
|
virtual
|
||||||
|
tmpNrc<PrimitiveOldTimePatch<faceList, pointField>>
|
||||||
|
distributeSrc
|
||||||
|
(
|
||||||
|
const primitiveOldTimePatch& srcPatch,
|
||||||
|
distributionMap& srcMap
|
||||||
|
);
|
||||||
|
|
||||||
|
//- Send data that resulted from an intersection between the source
|
||||||
|
// patch and a distributed source-local-target patch back to the
|
||||||
|
// original target processes.
|
||||||
|
virtual void rDistributeTgt
|
||||||
|
(
|
||||||
|
const primitiveOldTimePatch& tgtPatch,
|
||||||
|
const distributionMap& tgtMap
|
||||||
|
);
|
||||||
|
|
||||||
|
//- Finalising
|
||||||
|
virtual label finalise
|
||||||
|
(
|
||||||
|
const primitiveOldTimePatch& srcPatch,
|
||||||
|
const vectorField& srcPointNormals,
|
||||||
|
const vectorField& srcPointNormals0,
|
||||||
|
const primitiveOldTimePatch& tgtPatch,
|
||||||
|
const transformer& tgtToSrc
|
||||||
|
);
|
||||||
|
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
//- Runtime type information
|
||||||
|
TypeName("patchToPatch");
|
||||||
|
|
||||||
|
|
||||||
|
//- Declare runtime constructor selection table
|
||||||
|
declareRunTimeSelectionTable
|
||||||
|
(
|
||||||
|
autoPtr,
|
||||||
|
patchToPatch,
|
||||||
|
bool,
|
||||||
|
(const bool reverse),
|
||||||
|
(reverse)
|
||||||
|
);
|
||||||
|
|
||||||
|
|
||||||
|
// Constructors
|
||||||
|
|
||||||
|
//- Construct from components
|
||||||
|
patchToPatch(const bool reverse);
|
||||||
|
|
||||||
|
//- Disallow default bitwise copy construction
|
||||||
|
patchToPatch(const patchToPatch&) = delete;
|
||||||
|
|
||||||
|
|
||||||
|
//- Destructor
|
||||||
|
virtual ~patchToPatch();
|
||||||
|
|
||||||
|
|
||||||
|
// Selector
|
||||||
|
|
||||||
|
//- Select from name
|
||||||
|
static autoPtr<patchToPatch> New
|
||||||
|
(
|
||||||
|
const word& patchToPatchType,
|
||||||
|
const bool reverse
|
||||||
|
);
|
||||||
|
|
||||||
|
|
||||||
|
// Member Functions
|
||||||
|
|
||||||
|
// Access
|
||||||
|
|
||||||
|
//- Flag to indicate that the two patches are co-directional and
|
||||||
|
// that the orientation of one should therefore be reversed
|
||||||
|
inline bool reverse() const;
|
||||||
|
|
||||||
|
//- Index of the processor holding all faces of the patchToPatch,
|
||||||
|
// or -1 if spread across multiple processors
|
||||||
|
inline label singleProcess() const;
|
||||||
|
|
||||||
|
//- Is this intersection on a single process?
|
||||||
|
inline bool isSingleProcess() const;
|
||||||
|
|
||||||
|
//- For each source face, the coupled target procs and faces
|
||||||
|
inline List<List<procFace>> srcTgtProcFaces() const;
|
||||||
|
|
||||||
|
//- For each target face, the coupled source procs and faces
|
||||||
|
inline List<List<procFace>> tgtSrcProcFaces() const;
|
||||||
|
|
||||||
|
//- For each source face, the coupled target weights
|
||||||
|
virtual tmpNrc<List<DynamicList<scalar>>> srcWeights
|
||||||
|
(
|
||||||
|
const primitivePatch& srcPatch
|
||||||
|
) const = 0;
|
||||||
|
|
||||||
|
//- For each target face, the coupled source weights
|
||||||
|
virtual tmpNrc<List<DynamicList<scalar>>> tgtWeights
|
||||||
|
(
|
||||||
|
const primitivePatch& tgtPatch
|
||||||
|
) const = 0;
|
||||||
|
|
||||||
|
|
||||||
|
// Manipulation
|
||||||
|
|
||||||
|
//- Update addressing and weights for the given patches
|
||||||
|
void update
|
||||||
|
(
|
||||||
|
const primitiveOldTimePatch& srcPatch,
|
||||||
|
const vectorField& srcPointNormals,
|
||||||
|
const vectorField& srcPointNormals0,
|
||||||
|
const primitiveOldTimePatch& tgtPatch,
|
||||||
|
const transformer& tgtToSrc = NullObjectRef<transformer>()
|
||||||
|
);
|
||||||
|
|
||||||
|
//- Update addressing and weights for the given patches
|
||||||
|
void update
|
||||||
|
(
|
||||||
|
const primitivePatch& srcPatch,
|
||||||
|
const vectorField& srcPointNormals,
|
||||||
|
const primitivePatch& tgtPatch,
|
||||||
|
const transformer& tgtToSrc = NullObjectRef<transformer>()
|
||||||
|
);
|
||||||
|
|
||||||
|
|
||||||
|
// Member Operators
|
||||||
|
|
||||||
|
//- Disallow default bitwise assignment
|
||||||
|
void operator=(const patchToPatch&) = delete;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
} // End namespace Foam
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
#include "patchToPatchI.H"
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// ************************************************************************* //
|
||||||
125
src/meshTools/patchToPatch/patchToPatch/patchToPatchI.H
Normal file
125
src/meshTools/patchToPatch/patchToPatch/patchToPatchI.H
Normal file
@ -0,0 +1,125 @@
|
|||||||
|
/*---------------------------------------------------------------------------*\
|
||||||
|
========= |
|
||||||
|
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||||
|
\\ / O peration | Website: https://openfoam.org
|
||||||
|
\\ / A nd | Copyright (C) 2011-2022 OpenFOAM Foundation
|
||||||
|
\\/ M anipulation |
|
||||||
|
-------------------------------------------------------------------------------
|
||||||
|
License
|
||||||
|
This file is part of OpenFOAM.
|
||||||
|
|
||||||
|
OpenFOAM is free software: you can redistribute it and/or modify it
|
||||||
|
under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation, either version 3 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
|
||||||
|
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||||
|
for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
\*---------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
#include "patchToPatch.H"
|
||||||
|
|
||||||
|
// * * * * * * * * * * * Private Static Member Functions * * * * * * * * * * //
|
||||||
|
|
||||||
|
template<class SubListA, class SubListB>
|
||||||
|
inline void Foam::patchToPatch::transferListList
|
||||||
|
(
|
||||||
|
List<SubListA>& a,
|
||||||
|
List<SubListB>& b
|
||||||
|
)
|
||||||
|
{
|
||||||
|
a.resize(b.size());
|
||||||
|
forAll(a, i)
|
||||||
|
{
|
||||||
|
a[i].transfer(b[i]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
template<class Type>
|
||||||
|
inline void Foam::patchToPatch::rDistributeListList
|
||||||
|
(
|
||||||
|
const label size,
|
||||||
|
const distributionMap& map,
|
||||||
|
List<List<Type>>& data
|
||||||
|
)
|
||||||
|
{
|
||||||
|
distributionMapBase::distribute
|
||||||
|
(
|
||||||
|
Pstream::commsTypes::nonBlocking,
|
||||||
|
List<labelPair>(),
|
||||||
|
size,
|
||||||
|
map.constructMap(),
|
||||||
|
false,
|
||||||
|
map.subMap(),
|
||||||
|
false,
|
||||||
|
data,
|
||||||
|
ListAppendEqOp<Type>(),
|
||||||
|
flipOp(),
|
||||||
|
List<Type>()
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
template<class Type>
|
||||||
|
inline void Foam::patchToPatch::rDistributeListList
|
||||||
|
(
|
||||||
|
const label size,
|
||||||
|
const distributionMap& map,
|
||||||
|
List<DynamicList<Type>>& data
|
||||||
|
)
|
||||||
|
{
|
||||||
|
List<List<Type>> tData;
|
||||||
|
transferListList(tData, data);
|
||||||
|
rDistributeListList(size, map, tData);
|
||||||
|
transferListList(data, tData);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
inline bool Foam::patchToPatch::reverse() const
|
||||||
|
{
|
||||||
|
return reverse_;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
inline Foam::label Foam::patchToPatch::singleProcess() const
|
||||||
|
{
|
||||||
|
return singleProcess_;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
inline bool Foam::patchToPatch::isSingleProcess() const
|
||||||
|
{
|
||||||
|
return singleProcess_ != -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
inline Foam::List<Foam::List<Foam::patchToPatch::procFace>>
|
||||||
|
Foam::patchToPatch::srcTgtProcFaces() const
|
||||||
|
{
|
||||||
|
return
|
||||||
|
isSingleProcess()
|
||||||
|
? localFacesToProcFaces(srcLocalTgtFaces_)
|
||||||
|
: localFacesToProcFaces(srcLocalTgtFaces_, localTgtProcFacesPtr_());
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
inline Foam::List<Foam::List<Foam::patchToPatch::procFace>>
|
||||||
|
Foam::patchToPatch::tgtSrcProcFaces() const
|
||||||
|
{
|
||||||
|
return
|
||||||
|
isSingleProcess()
|
||||||
|
? localFacesToProcFaces(tgtLocalSrcFaces_)
|
||||||
|
: localFacesToProcFaces(tgtLocalSrcFaces_, localSrcProcFacesPtr_());
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// ************************************************************************* //
|
||||||
@ -0,0 +1,469 @@
|
|||||||
|
/*---------------------------------------------------------------------------*\
|
||||||
|
========= |
|
||||||
|
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||||
|
\\ / O peration | Website: https://openfoam.org
|
||||||
|
\\ / A nd | Copyright (C) 2011-2022 OpenFOAM Foundation
|
||||||
|
\\/ M anipulation |
|
||||||
|
-------------------------------------------------------------------------------
|
||||||
|
License
|
||||||
|
This file is part of OpenFOAM.
|
||||||
|
|
||||||
|
OpenFOAM is free software: you can redistribute it and/or modify it
|
||||||
|
under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation, either version 3 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
|
||||||
|
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||||
|
for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
\*---------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
#include "patchToPatch.H"
|
||||||
|
#include "treeBoundBoxList.H"
|
||||||
|
#include "uindirectPrimitivePatch.H"
|
||||||
|
#include "uindirectPrimitiveOldTimePatch.H"
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
|
||||||
|
|
||||||
|
void Foam::patchToPatch::calcSingleProcess
|
||||||
|
(
|
||||||
|
const primitiveOldTimePatch& srcPatch,
|
||||||
|
const primitiveOldTimePatch& tgtPatch
|
||||||
|
)
|
||||||
|
{
|
||||||
|
singleProcess_ = 0;
|
||||||
|
|
||||||
|
if (Pstream::parRun())
|
||||||
|
{
|
||||||
|
boolList procHasFaces(Pstream::nProcs(), false);
|
||||||
|
|
||||||
|
if ((srcPatch.size() > 0) || (tgtPatch.size() > 0))
|
||||||
|
{
|
||||||
|
procHasFaces[Pstream::myProcNo()] = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
Pstream::gatherList(procHasFaces);
|
||||||
|
Pstream::scatterList(procHasFaces);
|
||||||
|
|
||||||
|
const label nProcsHaveFaces = count(procHasFaces, true);
|
||||||
|
|
||||||
|
if (nProcsHaveFaces == 0)
|
||||||
|
{
|
||||||
|
singleProcess_ = 0;
|
||||||
|
}
|
||||||
|
if (nProcsHaveFaces == 1)
|
||||||
|
{
|
||||||
|
singleProcess_ = findIndex(procHasFaces, true);
|
||||||
|
}
|
||||||
|
if (nProcsHaveFaces > 1)
|
||||||
|
{
|
||||||
|
singleProcess_ = -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Foam::labelListList Foam::patchToPatch::tgtPatchSendFaces
|
||||||
|
(
|
||||||
|
const primitiveOldTimePatch& srcPatch,
|
||||||
|
const vectorField& srcPointNormals,
|
||||||
|
const vectorField& srcPointNormals0,
|
||||||
|
const primitiveOldTimePatch& tgtPatch
|
||||||
|
) const
|
||||||
|
{
|
||||||
|
// Get the bound boxes for the source patch. Just a single box for now.
|
||||||
|
List<treeBoundBoxList> srcPatchProcBbs(Pstream::nProcs());
|
||||||
|
if (srcPatch.size())
|
||||||
|
{
|
||||||
|
srcPatchProcBbs[Pstream::myProcNo()] =
|
||||||
|
treeBoundBoxList
|
||||||
|
(
|
||||||
|
1,
|
||||||
|
srcBox(srcPatch, srcPointNormals, srcPointNormals0)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
srcPatchProcBbs[Pstream::myProcNo()] = treeBoundBoxList();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Distribute the boxes
|
||||||
|
Pstream::gatherList(srcPatchProcBbs);
|
||||||
|
Pstream::scatterList(srcPatchProcBbs);
|
||||||
|
|
||||||
|
// Send a target face to a process if it overlaps the source patch box
|
||||||
|
// for that process
|
||||||
|
List<DynamicList<label>> resultDyn(Pstream::nProcs());
|
||||||
|
forAll(tgtPatch, tgtFacei)
|
||||||
|
{
|
||||||
|
const treeBoundBox tgtFaceBb = tgtBox(tgtPatch, tgtFacei);
|
||||||
|
forAll(srcPatchProcBbs, proci)
|
||||||
|
{
|
||||||
|
forAll(srcPatchProcBbs[proci], bbi)
|
||||||
|
{
|
||||||
|
if (srcPatchProcBbs[proci][bbi].overlaps(tgtFaceBb))
|
||||||
|
{
|
||||||
|
resultDyn[proci].append(tgtFacei);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Transfer to non-dynamic storage
|
||||||
|
labelListList result(Pstream::nProcs());
|
||||||
|
forAll(result, proci)
|
||||||
|
{
|
||||||
|
result[proci].transfer(resultDyn[proci]);
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Foam::labelListList Foam::patchToPatch::srcPatchSendFaces() const
|
||||||
|
{
|
||||||
|
// Send a source face to a proc if target face on that proc intersects it
|
||||||
|
List<labelHashSet> resultDyn(Pstream::nProcs());
|
||||||
|
forAll(tgtLocalSrcFaces_, tgtFacei)
|
||||||
|
{
|
||||||
|
const label tgtProci = localTgtProcFacesPtr_()[tgtFacei].proci;
|
||||||
|
|
||||||
|
forAll(tgtLocalSrcFaces_[tgtFacei], i)
|
||||||
|
{
|
||||||
|
const label srcFacei = tgtLocalSrcFaces_[tgtFacei][i];
|
||||||
|
|
||||||
|
resultDyn[tgtProci].insert(srcFacei);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Transfer to non-dynamic storage
|
||||||
|
labelListList result(Pstream::nProcs());
|
||||||
|
forAll(result, proci)
|
||||||
|
{
|
||||||
|
result[proci] = resultDyn[proci].toc();
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Foam::distributionMap Foam::patchToPatch::patchDistributionMap
|
||||||
|
(
|
||||||
|
labelListList&& sendFaces
|
||||||
|
) const
|
||||||
|
{
|
||||||
|
// Figure out how many target faces are to be received
|
||||||
|
labelList nReceiveFaces(Pstream::nProcs());
|
||||||
|
{
|
||||||
|
labelListList nSendFaces(Pstream::nProcs());
|
||||||
|
|
||||||
|
nSendFaces[Pstream::myProcNo()].setSize(Pstream::nProcs());
|
||||||
|
forAll(sendFaces, proci)
|
||||||
|
{
|
||||||
|
nSendFaces[Pstream::myProcNo()][proci] =
|
||||||
|
sendFaces[proci].size();
|
||||||
|
}
|
||||||
|
|
||||||
|
Pstream::gatherList(nSendFaces);
|
||||||
|
Pstream::scatterList(nSendFaces);
|
||||||
|
|
||||||
|
forAll(sendFaces, proci)
|
||||||
|
{
|
||||||
|
nReceiveFaces[proci] =
|
||||||
|
nSendFaces[proci][Pstream::myProcNo()];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Determine order of receiving
|
||||||
|
labelListList receiveFaces(Pstream::nProcs());
|
||||||
|
|
||||||
|
// Local faces first
|
||||||
|
receiveFaces[Pstream::myProcNo()] =
|
||||||
|
identity(sendFaces[Pstream::myProcNo()].size());
|
||||||
|
|
||||||
|
// Remote faces next
|
||||||
|
label localFacei = receiveFaces[Pstream::myProcNo()].size();
|
||||||
|
forAll(receiveFaces, proci)
|
||||||
|
{
|
||||||
|
if (proci != Pstream::myProcNo())
|
||||||
|
{
|
||||||
|
const label n = nReceiveFaces[proci];
|
||||||
|
receiveFaces[proci].setSize(n);
|
||||||
|
for (label i = 0; i < n; i ++)
|
||||||
|
{
|
||||||
|
receiveFaces[proci][i] = localFacei ++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Construct and return the map
|
||||||
|
return
|
||||||
|
distributionMap
|
||||||
|
(
|
||||||
|
localFacei,
|
||||||
|
move(sendFaces),
|
||||||
|
move(receiveFaces)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void Foam::patchToPatch::distributePatch
|
||||||
|
(
|
||||||
|
const distributionMap& map,
|
||||||
|
List<procFace>& localProcFaces
|
||||||
|
) const
|
||||||
|
{
|
||||||
|
static const label thisProci = Pstream::myProcNo();
|
||||||
|
|
||||||
|
// Exchange per-processor data
|
||||||
|
List<labelList> procLocalFaceis(Pstream::nProcs());
|
||||||
|
{
|
||||||
|
PstreamBuffers pBufs(Pstream::commsTypes::nonBlocking);
|
||||||
|
|
||||||
|
// Send
|
||||||
|
for (label proci = 0; proci < Pstream::nProcs(); proci++)
|
||||||
|
{
|
||||||
|
const labelList& sendFaces = map.subMap()[proci];
|
||||||
|
|
||||||
|
if (proci != thisProci && sendFaces.size())
|
||||||
|
{
|
||||||
|
UOPstream(proci, pBufs)() << sendFaces;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pBufs.finishedSends();
|
||||||
|
|
||||||
|
// Map local data
|
||||||
|
{
|
||||||
|
const labelList& sendFaces = map.subMap()[thisProci];
|
||||||
|
|
||||||
|
procLocalFaceis[thisProci] = sendFaces;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Receive remote data
|
||||||
|
for (label proci = 0; proci < Pstream::nProcs(); proci++)
|
||||||
|
{
|
||||||
|
const labelList& receiveNewFaces = map.constructMap()[proci];
|
||||||
|
|
||||||
|
if (proci != thisProci && receiveNewFaces.size())
|
||||||
|
{
|
||||||
|
UIPstream(proci, pBufs)() >> procLocalFaceis[proci];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Allocate
|
||||||
|
{
|
||||||
|
label nLocalFaces = 0;
|
||||||
|
forAll(procLocalFaceis, proci)
|
||||||
|
{
|
||||||
|
nLocalFaces += procLocalFaceis[proci].size();
|
||||||
|
}
|
||||||
|
localProcFaces.setSize(nLocalFaces);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Renumber and flatten
|
||||||
|
label localTgtFacei = 0;
|
||||||
|
|
||||||
|
// Local data first
|
||||||
|
{
|
||||||
|
const labelList& fis = procLocalFaceis[thisProci];
|
||||||
|
forAll(fis, i)
|
||||||
|
{
|
||||||
|
localProcFaces[localTgtFacei] = {thisProci, fis[i]};
|
||||||
|
localTgtFacei ++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Remote data after
|
||||||
|
forAll(procLocalFaceis, proci)
|
||||||
|
{
|
||||||
|
if (proci != thisProci)
|
||||||
|
{
|
||||||
|
const labelList& fis = procLocalFaceis[proci];
|
||||||
|
forAll(fis, i)
|
||||||
|
{
|
||||||
|
localProcFaces[localTgtFacei] = {proci, fis[i]};
|
||||||
|
localTgtFacei ++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Foam::PrimitiveOldTimePatch<Foam::faceList, Foam::pointField>
|
||||||
|
Foam::patchToPatch::distributePatch
|
||||||
|
(
|
||||||
|
const distributionMap& map,
|
||||||
|
const primitiveOldTimePatch& patch,
|
||||||
|
List<procFace>& localProcFaces
|
||||||
|
) const
|
||||||
|
{
|
||||||
|
static const label thisProci = Pstream::myProcNo();
|
||||||
|
|
||||||
|
// Exchange per-processor data
|
||||||
|
List<labelList> procLocalFaceis(Pstream::nProcs());
|
||||||
|
List<faceList> procLocalFaces(Pstream::nProcs());
|
||||||
|
List<pointField> procLocalPoints(Pstream::nProcs());
|
||||||
|
List<pointField> procLocalPoints0(Pstream::nProcs());
|
||||||
|
{
|
||||||
|
PstreamBuffers pBufs(Pstream::commsTypes::nonBlocking);
|
||||||
|
|
||||||
|
// Send
|
||||||
|
for (label proci = 0; proci < Pstream::nProcs(); proci++)
|
||||||
|
{
|
||||||
|
const labelList& sendTgtFaces = map.subMap()[proci];
|
||||||
|
|
||||||
|
if (proci != thisProci && sendTgtFaces.size())
|
||||||
|
{
|
||||||
|
uindirectPrimitiveOldTimePatch subPatch
|
||||||
|
(
|
||||||
|
UIndirectList<face>(patch, sendTgtFaces),
|
||||||
|
patch.points(),
|
||||||
|
patch.points0()
|
||||||
|
);
|
||||||
|
|
||||||
|
UOPstream(proci, pBufs)()
|
||||||
|
<< sendTgtFaces
|
||||||
|
<< subPatch.localFaces()
|
||||||
|
<< subPatch.localPoints()
|
||||||
|
<< (patch.has0() ? subPatch.localPoints0() : pointField());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pBufs.finishedSends();
|
||||||
|
|
||||||
|
// Map local data
|
||||||
|
{
|
||||||
|
const labelList& sendTgtFaces = map.subMap()[thisProci];
|
||||||
|
|
||||||
|
uindirectPrimitiveOldTimePatch subPatch
|
||||||
|
(
|
||||||
|
UIndirectList<face>(patch, sendTgtFaces),
|
||||||
|
patch.points(),
|
||||||
|
patch.points0()
|
||||||
|
);
|
||||||
|
|
||||||
|
procLocalFaceis[thisProci] = sendTgtFaces;
|
||||||
|
procLocalFaces[thisProci] = subPatch.localFaces();
|
||||||
|
procLocalPoints[thisProci] = subPatch.localPoints();
|
||||||
|
if (patch.has0())
|
||||||
|
{
|
||||||
|
procLocalPoints0[thisProci] = subPatch.localPoints0();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Receive remote data
|
||||||
|
for (label proci = 0; proci < Pstream::nProcs(); proci++)
|
||||||
|
{
|
||||||
|
const labelList& receiveNewTgtFaces = map.constructMap()[proci];
|
||||||
|
|
||||||
|
if (proci != thisProci && receiveNewTgtFaces.size())
|
||||||
|
{
|
||||||
|
UIPstream(proci, pBufs)()
|
||||||
|
>> procLocalFaceis[proci]
|
||||||
|
>> procLocalFaces[proci]
|
||||||
|
>> procLocalPoints[proci]
|
||||||
|
>> procLocalPoints0[proci];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Allocate
|
||||||
|
faceList localTgtFaces;
|
||||||
|
pointField localTgtPoints;
|
||||||
|
pointField localTgtPoints0;
|
||||||
|
{
|
||||||
|
label nLocalFaces = 0, nLocalPoints = 0;
|
||||||
|
forAll(procLocalFaceis, proci)
|
||||||
|
{
|
||||||
|
nLocalFaces += procLocalFaces[proci].size();
|
||||||
|
nLocalPoints += procLocalPoints[proci].size();
|
||||||
|
}
|
||||||
|
localProcFaces.setSize(nLocalFaces);
|
||||||
|
localTgtFaces.setSize(nLocalFaces);
|
||||||
|
localTgtPoints.setSize(nLocalPoints);
|
||||||
|
if (patch.has0())
|
||||||
|
{
|
||||||
|
localTgtPoints0.setSize(nLocalPoints);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Renumber and flatten
|
||||||
|
label localTgtFacei = 0, localTgtPointi = 0;
|
||||||
|
|
||||||
|
// Local data first
|
||||||
|
{
|
||||||
|
const labelList& fis = procLocalFaceis[thisProci];
|
||||||
|
const faceList& fs = procLocalFaces[thisProci];
|
||||||
|
forAll(fis, i)
|
||||||
|
{
|
||||||
|
localProcFaces[localTgtFacei] = {thisProci, fis[i]};
|
||||||
|
localTgtFaces[localTgtFacei] = face(fs[i] + localTgtPointi);
|
||||||
|
localTgtFacei ++;
|
||||||
|
}
|
||||||
|
|
||||||
|
const pointField& ps = procLocalPoints[thisProci];
|
||||||
|
const pointField& ps0 = procLocalPoints0[thisProci];
|
||||||
|
forAll(ps, i)
|
||||||
|
{
|
||||||
|
localTgtPoints[localTgtPointi] = ps[i];
|
||||||
|
if (patch.has0())
|
||||||
|
{
|
||||||
|
localTgtPoints0[localTgtPointi] = ps0[i];
|
||||||
|
}
|
||||||
|
localTgtPointi ++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Remote data after
|
||||||
|
forAll(procLocalFaces, proci)
|
||||||
|
{
|
||||||
|
if (proci != thisProci)
|
||||||
|
{
|
||||||
|
const labelList& fis = procLocalFaceis[proci];
|
||||||
|
const faceList& fs = procLocalFaces[proci];
|
||||||
|
forAll(fis, i)
|
||||||
|
{
|
||||||
|
localProcFaces[localTgtFacei] = {proci, fis[i]};
|
||||||
|
localTgtFaces[localTgtFacei] = face(fs[i] + localTgtPointi);
|
||||||
|
localTgtFacei ++;
|
||||||
|
}
|
||||||
|
|
||||||
|
const pointField& ps = procLocalPoints[proci];
|
||||||
|
const pointField& ps0 = procLocalPoints0[proci];
|
||||||
|
forAll(ps, i)
|
||||||
|
{
|
||||||
|
localTgtPoints[localTgtPointi] = ps[i];
|
||||||
|
if (patch.has0())
|
||||||
|
{
|
||||||
|
localTgtPoints0[localTgtPointi] = ps0[i];
|
||||||
|
}
|
||||||
|
localTgtPointi ++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return
|
||||||
|
patch.has0()
|
||||||
|
? PrimitiveOldTimePatch<faceList, pointField>
|
||||||
|
(
|
||||||
|
localTgtFaces,
|
||||||
|
localTgtPoints,
|
||||||
|
localTgtPoints0
|
||||||
|
)
|
||||||
|
: PrimitiveOldTimePatch<faceList, pointField>
|
||||||
|
(
|
||||||
|
localTgtFaces,
|
||||||
|
localTgtPoints
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// ************************************************************************* //
|
||||||
332
src/meshTools/patchToPatch/rays/raysPatchToPatch.C
Normal file
332
src/meshTools/patchToPatch/rays/raysPatchToPatch.C
Normal file
@ -0,0 +1,332 @@
|
|||||||
|
/*---------------------------------------------------------------------------*\
|
||||||
|
========= |
|
||||||
|
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||||
|
\\ / O peration | Website: https://openfoam.org
|
||||||
|
\\ / A nd | Copyright (C) 2021-2022 OpenFOAM Foundation
|
||||||
|
\\/ M anipulation |
|
||||||
|
-------------------------------------------------------------------------------
|
||||||
|
License
|
||||||
|
This file is part of OpenFOAM.
|
||||||
|
|
||||||
|
OpenFOAM is free software: you can redistribute it and/or modify it
|
||||||
|
under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation, either version 3 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
|
||||||
|
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||||
|
for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
\*---------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
#include "raysPatchToPatch.H"
|
||||||
|
#include "intersectionPatchToPatch.H"
|
||||||
|
#include "addToRunTimeSelectionTable.H"
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
namespace Foam
|
||||||
|
{
|
||||||
|
namespace patchToPatches
|
||||||
|
{
|
||||||
|
defineTypeNameAndDebug(rays, 0);
|
||||||
|
addToRunTimeSelectionTable(patchToPatch, rays, bool);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
|
||||||
|
|
||||||
|
Foam::treeBoundBox Foam::patchToPatches::rays::srcBox
|
||||||
|
(
|
||||||
|
const face& srcFace,
|
||||||
|
const pointField& srcPoints,
|
||||||
|
const vectorField& srcPointNormals
|
||||||
|
) const
|
||||||
|
{
|
||||||
|
return intersection::srcBoxStatic(srcFace, srcPoints, srcPointNormals);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool Foam::patchToPatches::rays::intersectFaces
|
||||||
|
(
|
||||||
|
const primitiveOldTimePatch& srcPatch,
|
||||||
|
const vectorField& srcPointNormals,
|
||||||
|
const vectorField& srcPointNormals0,
|
||||||
|
const primitiveOldTimePatch& tgtPatch,
|
||||||
|
const label srcFacei,
|
||||||
|
const label tgtFacei
|
||||||
|
)
|
||||||
|
{
|
||||||
|
const treeBoundBox srcFaceBox =
|
||||||
|
patchToPatch::srcBox
|
||||||
|
(
|
||||||
|
srcPatch,
|
||||||
|
srcPointNormals,
|
||||||
|
srcPointNormals0,
|
||||||
|
srcFacei
|
||||||
|
);
|
||||||
|
const treeBoundBox tgtFaceBox =
|
||||||
|
patchToPatch::tgtBox(tgtPatch, tgtFacei);
|
||||||
|
|
||||||
|
if (srcFaceBox.overlaps(tgtFaceBox))
|
||||||
|
{
|
||||||
|
srcLocalTgtFaces_[srcFacei].append(tgtFacei);
|
||||||
|
tgtLocalSrcFaces_[tgtFacei].append(srcFacei);
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Foam::tmpNrc<Foam::PrimitiveOldTimePatch<Foam::faceList, Foam::pointField>>
|
||||||
|
Foam::patchToPatches::rays::distributeTgt
|
||||||
|
(
|
||||||
|
const primitiveOldTimePatch& srcPatch,
|
||||||
|
const vectorField& srcPointNormals,
|
||||||
|
const vectorField& srcPointNormals0,
|
||||||
|
const primitiveOldTimePatch& tgtPatch,
|
||||||
|
distributionMap& tgtMap
|
||||||
|
)
|
||||||
|
{
|
||||||
|
// Intercept generation of the local patch. Store it. Return a const
|
||||||
|
// reference tmp instead of a pointer.
|
||||||
|
|
||||||
|
tmpNrc<PrimitiveOldTimePatch<faceList, pointField>> localTgtPatchPtr =
|
||||||
|
patchToPatch::distributeTgt
|
||||||
|
(
|
||||||
|
srcPatch,
|
||||||
|
srcPointNormals,
|
||||||
|
srcPointNormals0,
|
||||||
|
tgtPatch,
|
||||||
|
tgtMap
|
||||||
|
);
|
||||||
|
|
||||||
|
localTgtPatchPtr_.reset(localTgtPatchPtr.ptr());
|
||||||
|
|
||||||
|
return
|
||||||
|
tmpNrc<PrimitiveOldTimePatch<faceList, pointField>>
|
||||||
|
(
|
||||||
|
localTgtPatchPtr_()
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Foam::tmpNrc<Foam::PrimitiveOldTimePatch<Foam::faceList, Foam::pointField>>
|
||||||
|
Foam::patchToPatches::rays::distributeSrc
|
||||||
|
(
|
||||||
|
const primitiveOldTimePatch& srcPatch,
|
||||||
|
distributionMap& srcMap
|
||||||
|
)
|
||||||
|
{
|
||||||
|
// Intercept generation of the local patch. Store it. Return a const
|
||||||
|
// reference tmp instead of a pointer.
|
||||||
|
|
||||||
|
tmpNrc<PrimitiveOldTimePatch<faceList, pointField>> localSrcPatchPtr =
|
||||||
|
patchToPatch::distributeSrc(srcPatch, srcMap);
|
||||||
|
|
||||||
|
localSrcPatchPtr_.reset(localSrcPatchPtr.ptr());
|
||||||
|
|
||||||
|
return
|
||||||
|
tmpNrc<PrimitiveOldTimePatch<faceList, pointField>>
|
||||||
|
(
|
||||||
|
localSrcPatchPtr_()
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Foam::label Foam::patchToPatches::rays::finalise
|
||||||
|
(
|
||||||
|
const primitiveOldTimePatch& srcPatch,
|
||||||
|
const vectorField& srcPointNormals,
|
||||||
|
const vectorField& srcPointNormals0,
|
||||||
|
const primitiveOldTimePatch& tgtPatch,
|
||||||
|
const transformer& tgtToSrc
|
||||||
|
)
|
||||||
|
{
|
||||||
|
const label nCouples =
|
||||||
|
patchToPatch::finalise
|
||||||
|
(
|
||||||
|
srcPatch,
|
||||||
|
srcPointNormals,
|
||||||
|
srcPointNormals0,
|
||||||
|
tgtPatch,
|
||||||
|
tgtToSrc
|
||||||
|
);
|
||||||
|
|
||||||
|
// Transform the source-local target patch back to the target
|
||||||
|
if (!isSingleProcess() && !isNull(tgtToSrc))
|
||||||
|
{
|
||||||
|
autoPtr<PrimitiveOldTimePatch<faceList, pointField>>
|
||||||
|
localTgtPatchPtr(localTgtPatchPtr_.ptr());
|
||||||
|
|
||||||
|
localTgtPatchPtr_.set
|
||||||
|
(
|
||||||
|
new PrimitiveOldTimePatch<faceList, pointField>
|
||||||
|
(
|
||||||
|
localTgtPatchPtr(),
|
||||||
|
tgtToSrc.invTransformPosition(localTgtPatchPtr().points()),
|
||||||
|
isNull(localTgtPatchPtr().points0())
|
||||||
|
? NullObjectRef<pointField>()
|
||||||
|
: tgtToSrc.invTransformPosition(localTgtPatchPtr().points0())()
|
||||||
|
)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
return nCouples;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Foam::patchToPatch::procFace Foam::patchToPatches::rays::ray
|
||||||
|
(
|
||||||
|
const primitiveOldTimePatch& outPatch,
|
||||||
|
const autoPtr<PrimitiveOldTimePatch<faceList, pointField>>&
|
||||||
|
localOutPatchPtr,
|
||||||
|
const autoPtr<List<procFace>>& localOutProcFacesPtr,
|
||||||
|
const List<DynamicList<label>>& inLocalOutFaces,
|
||||||
|
const scalar fraction,
|
||||||
|
const label inFacei,
|
||||||
|
const point& inP,
|
||||||
|
const vector& inN,
|
||||||
|
point& outP
|
||||||
|
) const
|
||||||
|
{
|
||||||
|
forAll(inLocalOutFaces[inFacei], i)
|
||||||
|
{
|
||||||
|
const label localOutFacei = inLocalOutFaces[inFacei][i];
|
||||||
|
|
||||||
|
const face& outF =
|
||||||
|
isSingleProcess()
|
||||||
|
? outPatch[localOutFacei]
|
||||||
|
: localOutPatchPtr()[localOutFacei];
|
||||||
|
|
||||||
|
const pointField& outPoints =
|
||||||
|
isSingleProcess()
|
||||||
|
? outPatch.points()
|
||||||
|
: localOutPatchPtr().points();
|
||||||
|
const pointField& outPoints0 =
|
||||||
|
isSingleProcess()
|
||||||
|
? outPatch.points0()
|
||||||
|
: localOutPatchPtr().points0();
|
||||||
|
|
||||||
|
const pointField outPoly
|
||||||
|
(
|
||||||
|
(1 - fraction)*outF.points(outPoints0)
|
||||||
|
+ fraction*outF.points(outPoints)
|
||||||
|
);
|
||||||
|
|
||||||
|
const pointHit ray =
|
||||||
|
face(identity(outPoly.size()))
|
||||||
|
.ray(inP, inN, outPoly, Foam::intersection::algorithm::visible);
|
||||||
|
|
||||||
|
if (ray.hit())
|
||||||
|
{
|
||||||
|
outP = ray.rawPoint();
|
||||||
|
|
||||||
|
return
|
||||||
|
isSingleProcess()
|
||||||
|
? procFace({Pstream::myProcNo(), localOutFacei})
|
||||||
|
: localOutProcFacesPtr()[localOutFacei];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return procFace({-1, -1});
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
Foam::patchToPatches::rays::rays
|
||||||
|
(
|
||||||
|
const bool reverse
|
||||||
|
)
|
||||||
|
:
|
||||||
|
patchToPatch(reverse)
|
||||||
|
{}
|
||||||
|
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
Foam::patchToPatches::rays::~rays()
|
||||||
|
{}
|
||||||
|
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
Foam::tmpNrc<Foam::List<Foam::DynamicList<Foam::scalar>>>
|
||||||
|
Foam::patchToPatches::rays::srcWeights(const primitivePatch& srcPatch) const
|
||||||
|
{
|
||||||
|
NotImplemented;
|
||||||
|
return tmpNrc<List<DynamicList<scalar>>>(nullptr);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Foam::tmpNrc<Foam::List<Foam::DynamicList<Foam::scalar>>>
|
||||||
|
Foam::patchToPatches::rays::tgtWeights(const primitivePatch& tgtPatch) const
|
||||||
|
{
|
||||||
|
NotImplemented;
|
||||||
|
return tmpNrc<List<DynamicList<scalar>>>(nullptr);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Foam::patchToPatch::procFace Foam::patchToPatches::rays::srcToTgtRay
|
||||||
|
(
|
||||||
|
const primitiveOldTimePatch& tgtPatch,
|
||||||
|
const scalar fraction,
|
||||||
|
const label srcFacei,
|
||||||
|
const vector& srcP,
|
||||||
|
const vector& srcN,
|
||||||
|
point& tgtP
|
||||||
|
) const
|
||||||
|
{
|
||||||
|
return
|
||||||
|
ray
|
||||||
|
(
|
||||||
|
tgtPatch,
|
||||||
|
localTgtPatchPtr_,
|
||||||
|
localTgtProcFacesPtr_,
|
||||||
|
srcLocalTgtFaces_,
|
||||||
|
fraction,
|
||||||
|
srcFacei,
|
||||||
|
srcP,
|
||||||
|
srcN,
|
||||||
|
tgtP
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Foam::patchToPatch::procFace Foam::patchToPatches::rays::tgtToSrcRay
|
||||||
|
(
|
||||||
|
const primitiveOldTimePatch& srcPatch,
|
||||||
|
const scalar fraction,
|
||||||
|
const label tgtFacei,
|
||||||
|
const vector& tgtP,
|
||||||
|
const vector& tgtN,
|
||||||
|
point& srcP
|
||||||
|
) const
|
||||||
|
{
|
||||||
|
return
|
||||||
|
ray
|
||||||
|
(
|
||||||
|
srcPatch,
|
||||||
|
localSrcPatchPtr_,
|
||||||
|
localSrcProcFacesPtr_,
|
||||||
|
tgtLocalSrcFaces_,
|
||||||
|
fraction,
|
||||||
|
tgtFacei,
|
||||||
|
tgtP,
|
||||||
|
tgtN,
|
||||||
|
srcP
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// ************************************************************************* //
|
||||||
204
src/meshTools/patchToPatch/rays/raysPatchToPatch.H
Normal file
204
src/meshTools/patchToPatch/rays/raysPatchToPatch.H
Normal file
@ -0,0 +1,204 @@
|
|||||||
|
/*---------------------------------------------------------------------------*\
|
||||||
|
========= |
|
||||||
|
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||||
|
\\ / O peration | Website: https://openfoam.org
|
||||||
|
\\ / A nd | Copyright (C) 2021-2022 OpenFOAM Foundation
|
||||||
|
\\/ M anipulation |
|
||||||
|
-------------------------------------------------------------------------------
|
||||||
|
License
|
||||||
|
This file is part of OpenFOAM.
|
||||||
|
|
||||||
|
OpenFOAM is free software: you can redistribute it and/or modify it
|
||||||
|
under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation, either version 3 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
|
||||||
|
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||||
|
for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
Class
|
||||||
|
Foam::patchToPatches::intersection
|
||||||
|
|
||||||
|
Description
|
||||||
|
Class to generate patchToPatch coupling geometry. Coupling is determined by
|
||||||
|
means of comparing the bound boxes generated by the intersection method.
|
||||||
|
This generates an outer "envelope" of possible intersections that can be
|
||||||
|
used for ray shooting and Lagrangian transfer.
|
||||||
|
|
||||||
|
SourceFiles
|
||||||
|
rays.C
|
||||||
|
|
||||||
|
\*---------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
#ifndef raysPatchToPatch_H
|
||||||
|
#define raysPatchToPatch_H
|
||||||
|
|
||||||
|
#include "patchToPatch.H"
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
namespace Foam
|
||||||
|
{
|
||||||
|
namespace patchToPatches
|
||||||
|
{
|
||||||
|
|
||||||
|
/*---------------------------------------------------------------------------*\
|
||||||
|
Class rays Declaration
|
||||||
|
\*---------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
class rays
|
||||||
|
:
|
||||||
|
public patchToPatch
|
||||||
|
{
|
||||||
|
// Private Data
|
||||||
|
|
||||||
|
// Parallel
|
||||||
|
|
||||||
|
//- Cache of the part of the source patch local to the target
|
||||||
|
autoPtr<PrimitiveOldTimePatch<faceList, pointField>>
|
||||||
|
localSrcPatchPtr_;
|
||||||
|
|
||||||
|
//- Cache of the part of the target patch local to the source
|
||||||
|
autoPtr<PrimitiveOldTimePatch<faceList, pointField>>
|
||||||
|
localTgtPatchPtr_;
|
||||||
|
|
||||||
|
|
||||||
|
// Private Member Functions
|
||||||
|
|
||||||
|
//- Get the bound box for a source face
|
||||||
|
virtual treeBoundBox srcBox
|
||||||
|
(
|
||||||
|
const face& srcFace,
|
||||||
|
const pointField& srcPoints,
|
||||||
|
const vectorField& srcPointNormals
|
||||||
|
) const;
|
||||||
|
|
||||||
|
//- Intersect two faces
|
||||||
|
virtual bool intersectFaces
|
||||||
|
(
|
||||||
|
const primitiveOldTimePatch& srcPatch,
|
||||||
|
const vectorField& srcPointNormals,
|
||||||
|
const vectorField& srcPointNormals0,
|
||||||
|
const primitiveOldTimePatch& tgtPatch,
|
||||||
|
const label srcFacei,
|
||||||
|
const label tgtFacei
|
||||||
|
);
|
||||||
|
|
||||||
|
//- Distribute the target patch so that enough is locally available
|
||||||
|
// for its intersection with the source patch can be computed
|
||||||
|
virtual
|
||||||
|
tmpNrc<PrimitiveOldTimePatch<faceList, pointField>>
|
||||||
|
distributeTgt
|
||||||
|
(
|
||||||
|
const primitiveOldTimePatch& srcPatch,
|
||||||
|
const vectorField& srcPointNormals,
|
||||||
|
const vectorField& srcPointNormals0,
|
||||||
|
const primitiveOldTimePatch& tgtPatch,
|
||||||
|
distributionMap& tgtMap
|
||||||
|
);
|
||||||
|
|
||||||
|
//- Distribute the source patch so that everything the target
|
||||||
|
// intersects is locally available. Happens after intersection.
|
||||||
|
virtual
|
||||||
|
tmpNrc<PrimitiveOldTimePatch<faceList, pointField>>
|
||||||
|
distributeSrc
|
||||||
|
(
|
||||||
|
const primitiveOldTimePatch& srcPatch,
|
||||||
|
distributionMap& srcMap
|
||||||
|
);
|
||||||
|
|
||||||
|
//- Finalising
|
||||||
|
virtual label finalise
|
||||||
|
(
|
||||||
|
const primitiveOldTimePatch& srcPatch,
|
||||||
|
const vectorField& srcPointNormals,
|
||||||
|
const vectorField& srcPointNormals0,
|
||||||
|
const primitiveOldTimePatch& tgtPatch,
|
||||||
|
const transformer& tgtToSrc
|
||||||
|
);
|
||||||
|
|
||||||
|
//- Compute a ray intersection
|
||||||
|
procFace ray
|
||||||
|
(
|
||||||
|
const primitiveOldTimePatch& outPatch,
|
||||||
|
const autoPtr<PrimitiveOldTimePatch<faceList, pointField>>&
|
||||||
|
localOutPatchPtr,
|
||||||
|
const autoPtr<List<procFace>>& localOutProcFacesPtr,
|
||||||
|
const List<DynamicList<label>>& inLocalOutFacesPtr,
|
||||||
|
const scalar fraction,
|
||||||
|
const label inFacei,
|
||||||
|
const point& inP,
|
||||||
|
const vector& inN,
|
||||||
|
point& outP
|
||||||
|
) const;
|
||||||
|
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
//- Runtime type information
|
||||||
|
TypeName("rays");
|
||||||
|
|
||||||
|
|
||||||
|
// Constructors
|
||||||
|
|
||||||
|
//- Construct from components
|
||||||
|
rays(const bool reverse);
|
||||||
|
|
||||||
|
|
||||||
|
//- Destructor
|
||||||
|
~rays();
|
||||||
|
|
||||||
|
|
||||||
|
// Member Functions
|
||||||
|
|
||||||
|
//- For each source face, the coupled target weights
|
||||||
|
virtual tmpNrc<List<DynamicList<scalar>>> srcWeights
|
||||||
|
(
|
||||||
|
const primitivePatch& srcPatch
|
||||||
|
) const;
|
||||||
|
|
||||||
|
//- For each target face, the coupled source weights
|
||||||
|
virtual tmpNrc<List<DynamicList<scalar>>> tgtWeights
|
||||||
|
(
|
||||||
|
const primitivePatch& tgtPatch
|
||||||
|
) const;
|
||||||
|
|
||||||
|
//- Compute a ray intersection from the source side to the target
|
||||||
|
procFace srcToTgtRay
|
||||||
|
(
|
||||||
|
const primitiveOldTimePatch& tgtPatch,
|
||||||
|
const scalar fraction,
|
||||||
|
const label srcFacei,
|
||||||
|
const vector& srcP,
|
||||||
|
const vector& srcN,
|
||||||
|
point& tgtP
|
||||||
|
) const;
|
||||||
|
|
||||||
|
//- Compute a ray intersection from the target side to the source
|
||||||
|
procFace tgtToSrcRay
|
||||||
|
(
|
||||||
|
const primitiveOldTimePatch& srcPatch,
|
||||||
|
const scalar fraction,
|
||||||
|
const label tgtFacei,
|
||||||
|
const vector& tgtP,
|
||||||
|
const vector& tgtN,
|
||||||
|
point& srcP
|
||||||
|
) const;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
} // End namespace patchToPatches
|
||||||
|
} // End namespace Foam
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// ************************************************************************* //
|
||||||
Reference in New Issue
Block a user