nonConformalProcessorCyclicLagrangianPatch.C
Go to the documentation of this file.
1 /*---------------------------------------------------------------------------*\
2  ========= |
3  \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
4  \\ / O peration | Website: https://openfoam.org
5  \\ / A nd | Copyright (C) 2025-2026 OpenFOAM Foundation
6  \\/ M anipulation |
7 -------------------------------------------------------------------------------
8 License
9  This file is part of OpenFOAM.
10 
11  OpenFOAM is free software: you can redistribute it and/or modify it
12  under the terms of the GNU General Public License as published by
13  the Free Software Foundation, either version 3 of the License, or
14  (at your option) any later version.
15 
16  OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
17  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
18  FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
19  for more details.
20 
21  You should have received a copy of the GNU General Public License
22  along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
23 
24 \*---------------------------------------------------------------------------*/
25 
27 #include "LagrangianFields.H"
28 #include "meshSearch.H"
29 #include "RemoteData.H"
30 #include "tracking.H"
32 
33 // * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
34 
35 namespace Foam
36 {
38 
40  (
43  polyPatch
44  );
45 }
46 
47 
48 // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
49 
52 (
53  const polyPatch& poly,
54  const LagrangianBoundaryMesh& boundaryMesh
55 )
56 :
57  processorCyclicLagrangianPatch(poly, boundaryMesh),
58  nonConformalProcessorCyclicPoly_
59  (
61  )
62 {}
63 
64 
65 // * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * //
66 
69 {}
70 
71 
72 // * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * * //
73 
75 (
76  PstreamBuffers& pBufs,
79 ) const
80 {
81  const LagrangianSubMesh& patchMesh = this->mesh();
82 
83  // Sub-set the step fractions
84  SubField<scalar> sendFraction = patchMesh.sub(fraction.primitiveField());
85 
86  // Sub-set the receiving information
87  SubField<label> receivePatchFace =
88  patchMesh.sub(mesh.receivePatchFacePtr_());
89  SubField<point> receivePosition =
90  patchMesh.sub(mesh.receivePositionPtr_());
91 
92  // Send
93  UOPstream(nonConformalProcessorCyclicPoly_.neighbProcNo(), pBufs)()
94  << receivePatchFace
95  << receivePosition
96  << sendFraction;
97 
98  // Remove the sent elements
99  patchMesh.sub(mesh.states()) = LagrangianState::toBeRemoved;
100 
101  // Invalidate the now used receiving information
102  receivePatchFace = -1;
103  receivePosition = point::nan;
104 }
105 
106 
108 (
109  PstreamBuffers& pBufs,
112 ) const
113 {
114  const meshSearch& searchEngine = meshSearch::New(mesh.poly());
115 
116  // Receive
117  UIPstream uips(nonConformalProcessorCyclicPoly_.neighbProcNo(), pBufs);
118  labelField receivePatchFace(uips);
119  pointField receivePosition(uips);
120  scalarField receiveFraction(uips);
121 
122  // Get a reference to the receiving original patch
123  const polyPatch& receivePp =
124  nonConformalProcessorCyclicPoly_.referPatch().origPatch();
125 
126  // Search for the elements on the receiving side
127  barycentricField receiveCoordinates(receivePatchFace.size());
128  labelField receiveCelli(receivePatchFace.size());
129  labelField receiveFacei(receivePatchFace.size());
130  labelField receiveFaceTrii(receivePatchFace.size());
131  forAll(receivePatchFace, i)
132  {
133  receiveCelli[i] =
134  mesh.poly().faceOwner()[receivePatchFace[i] + receivePp.start()];
135 
136  if
137  (
139  (
140  searchEngine,
141  receivePosition[i],
142  receiveCoordinates[i],
143  receiveCelli[i],
144  receiveFacei[i],
145  receiveFaceTrii[i],
146  receiveFraction[i]
147  )
148  )
149  {
150  // The search hit a boundary. Compute the positional error.
151  const scalar positionalErrorSqr =
152  magSqr
153  (
154  receivePosition[i]
156  (
157  mesh.poly(),
158  receiveCoordinates[i],
159  receiveCelli[i],
160  receiveFacei[i],
161  receiveFaceTrii[i],
162  receiveFraction[i]
163  )
164  );
165 
166  // If the positional error is significant, relative to the size of
167  // the receiving face, then register as a failure
168  if
169  (
170  sqr(positionalErrorSqr)
171  > sqr(small)*magSqr(receivePp.faceAreas()[receivePatchFace[i]])
172  )
173  {
174  referPatch().nPositionalErrors_ ++;
175 
176  if (positionalErrorSqr > referPatch().maxPositionalErrorSqr_)
177  {
178  referPatch().maxPositionalErrorSqr_ = positionalErrorSqr;
179  referPatch().maxPositionalErrorReceivePosition_ =
180  receivePosition[i];
181  }
182  }
183  }
184  }
185 
186  // Insert the received elements
187  receiveMeshPtr_.set
188  (
190  (
191  mesh.append
192  (
193  receiveCoordinates,
194  receiveCelli,
195  receiveFacei,
196  receiveFaceTrii
197  )
198  )
199  );
200 
201  // Set the step fractions of the elements
202  mesh.appendSpecifiedField<scalar, LagrangianInternalDynamicField>
203  (
204  receiveMeshPtr_(),
206  receiveFraction
207  );
208 
209  // Set the elements to be in the adjacent cell
210  receiveMeshPtr_().sub(mesh.states()) = LagrangianState::inCell;
211 }
212 
213 
214 // ************************************************************************* //
#define forAll(list, i)
Loop across all elements in list.
Definition: UList.H:449
Macros for easy insertion into run-time selection tables.
Field with dimensions and associated with geometry type GeoMesh which is used to size the field and a...
Boundary part of a Lagrangian mesh. Just a list of Lagrangian patches with some added convenience fun...
Class containing Lagrangian geometry and topology.
Base class for Lagrangian patches.
Mesh that relates to a sub-section of a Lagrangian mesh. This is used to construct fields that relate...
word sub(const word &fieldName) const
Return the name of a field corresponding to this sub-mesh.
void size(const label)
Override size to be inconsistent with allocated storage.
Definition: ListI.H:164
Buffers for inter-processor communications streams (UOPstream, UIPstream).
Pre-declare related SubField type.
Definition: SubField.H:63
Input inter-processor communications stream operating on external buffer.
Definition: UIPstream.H:57
Output inter-processor communications stream operating on external buffer.
Definition: UOPstream.H:58
static const Form nan
Definition: VectorSpace.H:124
const polyMesh & poly() const
Return reference to polyMesh.
Definition: fvMesh.H:456
Mesh object that implements searches within the local cells and faces.
Definition: meshSearch.H:59
static const meshSearch & New(const polyMesh &mesh, const pointInCellShapes=pointInCellShapes::tets)
Lookup or construct from mesh and cell decomposition option.
Definition: meshSearch.C:61
virtual void evaluate(PstreamBuffers &, LagrangianMesh &, const LagrangianInternalScalarDynamicField &fraction) const
Evaluate changes in elements that have tracked to this patch.
nonConformalProcessorCyclicLagrangianPatch(const polyPatch &, const LagrangianBoundaryMesh &)
Construct from a patch and a boundary mesh.
virtual void initEvaluate(PstreamBuffers &, LagrangianMesh &, const LagrangianInternalScalarDynamicField &fraction) const
Initialise evaluation of changes in elements that have tracked to.
Non-conformal processor cyclic poly patch. As nonConformalCyclicPolyPatch, but the neighbouring patch...
virtual const labelList & faceOwner() const
Return face owner.
Definition: polyMesh.C:1321
A patch is a list of labels that address the faces in the global face list.
Definition: polyPatch.H:71
const vectorField::subField faceAreas() const
Return face areas.
Definition: polyPatch.C:233
label start() const
Return start label of this patch in the polyMesh face list.
Definition: polyPatch.H:277
Processor-cyclic Lagrangian patch. This is used for the patches that interface between processors acr...
Foam::fvMesh mesh(Foam::IOobject(regionName, runTime.name(), runTime, Foam::IOobject::MUST_READ), false)
point position(const polyMesh &mesh, const barycentric &coordinates, const label celli, const label facei, const label faceTrii, const scalar stepFraction)
Return the position given the coordinates and tet topology.
Definition: trackingI.H:224
bool locate(const polyMesh &mesh, const point &position, barycentric &coordinates, label &celli, label &facei, label &faceTrii, const scalar stepFraction, const string &debugPrefix=NullObjectRef< string >())
Initialise the location at the given position. Returns whether or not a.
Definition: tracking.C:1592
const unitSet fraction
Namespace for OpenFOAM.
addToRunTimeSelectionTable(polyPatch, mergedCyclicPolyPatch, word)
To & refCast(From &r)
Reference type cast template function.
Definition: typeInfo.H:141
tmp< DimensionedField< typename outerProduct< Type, Type >::type, GeoMesh, Field >> sqr(const DimensionedField< Type, GeoMesh, PrimitiveField > &df)
tmp< DimensionedField< scalar, GeoMesh, Field > > magSqr(const DimensionedField< Type, GeoMesh, PrimitiveField > &df)
defineTypeNameAndDebug(atmosphericBoundaryLayer, 0)