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)/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/mappedPolyPatch.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