pointConstraints.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) 2013-2025 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 
26 #include "pointConstraints.H"
27 #include "emptyPointPatch.H"
28 #include "wedgePointPatch.H"
29 #include "polyMesh.H"
30 #include "pointMesh.H"
31 #include "globalMeshData.H"
32 #include "twoDPointCorrector.H"
33 
34 // * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
35 
36 namespace Foam
37 {
39 }
40 
41 
42 // * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
43 
44 void Foam::pointConstraints::makePatchPatchAddressing()
45 {
46  if (debug)
47  {
48  Pout<< "pointConstraints::makePatchPatchAddressing() : "
49  << "constructing boundary addressing"
50  << endl << incrIndent;
51  }
52 
53  const pointMesh& pMesh = mesh();
54  const polyMesh& mesh = pMesh();
55 
56  const pointBoundaryMesh& pbm = pMesh.boundary();
57  const polyBoundaryMesh& bm = mesh.boundaryMesh();
58 
59 
60  // first count the total number of patch-patch points
61 
62  label nPatchPatchPoints = 0;
63 
64  forAll(pbm, patchi)
65  {
66  if
67  (
68  !isA<emptyPointPatch>(pbm[patchi])
69  && !isA<wedgePointPatch>(pbm[patchi])
70  && !pbm[patchi].coupled()
71  )
72  {
73  const labelList& bp = bm[patchi].boundaryPoints();
74 
75  nPatchPatchPoints += bp.size();
76 
77  if (debug)
78  {
79  Pout<< indent << "On patch:" << pbm[patchi].name()
80  << " nBoundaryPoints:" << bp.size() << endl;
81  }
82  }
83  }
84 
85  if (debug)
86  {
87  Pout<< indent << "Found nPatchPatchPoints:" << nPatchPatchPoints
88  << endl;
89  }
90 
91 
92  // Go through all patches and mark up the external edge points
93  // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
94 
95  // From meshpoint to index in patchPatchPointConstraints_.
96  Map<label> patchPatchPointSet(2*nPatchPatchPoints);
97 
98  // Constraints (initialised to unconstrained)
99  patchPatchPointConstraints_.setSize(nPatchPatchPoints, pointConstraint());
100 
101  // From constraint index to mesh point
102  labelList patchPatchPoints(nPatchPatchPoints);
103 
104  label pppi = 0;
105 
106  forAll(pbm, patchi)
107  {
108  if
109  (
110  !isA<emptyPointPatch>(pbm[patchi])
111  && !isA<wedgePointPatch>(pbm[patchi])
112  && !pbm[patchi].coupled()
113  )
114  {
115  const labelList& bp = bm[patchi].boundaryPoints();
116  const labelList& meshPoints = pbm[patchi].meshPoints();
117 
118  forAll(bp, pointi)
119  {
120  label ppp = meshPoints[bp[pointi]];
121 
122  Map<label>::iterator iter = patchPatchPointSet.find(ppp);
123 
124  label constraintI = -1;
125 
126  if (iter == patchPatchPointSet.end())
127  {
128  patchPatchPointSet.insert(ppp, pppi);
129  patchPatchPoints[pppi] = ppp;
130  constraintI = pppi++;
131  }
132  else
133  {
134  constraintI = iter();
135  }
136 
137  // Apply to patch constraints
138  pbm[patchi].applyConstraint
139  (
140  bp[pointi],
141  patchPatchPointConstraints_[constraintI]
142  );
143  }
144  }
145  }
146 
147  if (debug)
148  {
149  Pout<< indent << "Have (local) constrained points:"
150  << nPatchPatchPoints << endl;
151  }
152 
153 
154  // Extend set with constraints across coupled points
155  // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
156 
157  {
158  const globalMeshData& gd = mesh.globalData();
159  const labelListList& globalPointSlaves = gd.globalPointSlaves();
160  const distributionMap& globalPointSlavesMap = gd.globalPointSlavesMap();
161  const Map<label>& cpPointMap = gd.coupledPatch().meshPointMap();
162  const labelList& cpMeshPoints = gd.coupledPatch().meshPoints();
163 
164  // Constraints on coupled points
165  List<pointConstraint> constraints
166  (
167  globalPointSlavesMap.constructSize()
168  );
169 
170  // Copy from patchPatch constraints into coupledConstraints.
171  forAll(pbm, patchi)
172  {
173  if
174  (
175  !isA<emptyPointPatch>(pbm[patchi])
176  && !isA<wedgePointPatch>(pbm[patchi])
177  && !pbm[patchi].coupled()
178  )
179  {
180  const labelList& bp = bm[patchi].boundaryPoints();
181  const labelList& meshPoints = pbm[patchi].meshPoints();
182 
183  forAll(bp, pointi)
184  {
185  label ppp = meshPoints[bp[pointi]];
186 
187  Map<label>::const_iterator fnd = cpPointMap.find(ppp);
188  if (fnd != cpPointMap.end())
189  {
190  // Can just copy (instead of apply) constraint
191  // will already be consistent across multiple patches.
192  constraints[fnd()] = patchPatchPointConstraints_
193  [
194  patchPatchPointSet[ppp]
195  ];
196  }
197  }
198  }
199  }
200 
201  // Exchange data
202  globalPointSlavesMap.distribute(constraints);
203 
204  // Combine master with slave constraints
205  forAll(globalPointSlaves, pointi)
206  {
207  const labelList& slaves = globalPointSlaves[pointi];
208 
209  // Combine master constraint with slave constraints
210  forAll(slaves, i)
211  {
212  constraints[pointi].combine(constraints[slaves[i]]);
213  }
214  // Duplicate master constraint into slave slots
215  forAll(slaves, i)
216  {
217  constraints[slaves[i]] = constraints[pointi];
218  }
219  }
220 
221  // Send back
222  globalPointSlavesMap.reverseDistribute
223  (
224  cpMeshPoints.size(),
225  constraints
226  );
227 
228  // Add back into patchPatch constraints
229  forAll(constraints, coupledPointi)
230  {
231  if (constraints[coupledPointi].first() != 0)
232  {
233  label meshPointi = cpMeshPoints[coupledPointi];
234 
235  Map<label>::iterator iter = patchPatchPointSet.find(meshPointi);
236 
237  label constraintI = -1;
238 
239  if (iter == patchPatchPointSet.end())
240  {
241  // Pout<< indent << "on meshpoint:" << meshPointi
242  // << " coupled:" << coupledPointi
243  // << " at:" << mesh.points()[meshPointi]
244  // << " have new constraint:"
245  // << constraints[coupledPointi]
246  // << endl;
247 
248  // Allocate new constraint
249  if (patchPatchPoints.size() <= pppi)
250  {
251  patchPatchPoints.setSize(pppi+100);
252  }
253  patchPatchPointSet.insert(meshPointi, pppi);
254  patchPatchPoints[pppi] = meshPointi;
255  constraintI = pppi++;
256  }
257  else
258  {
259  // Pout<< indent << "on meshpoint:" << meshPointi
260  // << " coupled:" << coupledPointi
261  // << " at:" << mesh.points()[meshPointi]
262  // << " have possibly extended constraint:"
263  // << constraints[coupledPointi]
264  // << endl;
265 
266  constraintI = iter();
267  }
268 
269  // Extend the patchPatchPointConstraints_ array if necessary
270  if (patchPatchPointConstraints_.size() <= constraintI)
271  {
272  patchPatchPointConstraints_.setSize
273  (
274  constraintI + 1,
275  pointConstraint()
276  );
277  }
278 
279  // Combine (new or existing) constraint with one
280  // on coupled.
281  patchPatchPointConstraints_[constraintI].combine
282  (
283  constraints[coupledPointi]
284  );
285  }
286  }
287  }
288 
289 
290  nPatchPatchPoints = pppi;
291  patchPatchPoints.setSize(nPatchPatchPoints);
292  patchPatchPointConstraints_.setSize(nPatchPatchPoints);
293 
294 
295  if (debug)
296  {
297  Pout<< indent << "Have (global) constrained points:"
298  << nPatchPatchPoints << endl;
299  }
300 
301 
302  // Copy out all non-trivial constraints
303  // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
304 
305  patchPatchPointConstraintPoints_.setSize(nPatchPatchPoints);
306  patchPatchPointConstraintTensors_.setSize(nPatchPatchPoints);
307 
308  label nConstraints = 0;
309 
310  forAll(patchPatchPointConstraints_, i)
311  {
312  // Note: check for more than zero constraints. (could check for
313  // more than one constraint but what about coupled points that
314  // inherit the constraintness)
315  if (patchPatchPointConstraints_[i].first() != 0)
316  {
317  patchPatchPointConstraintPoints_[nConstraints] =
318  patchPatchPoints[i];
319 
320  patchPatchPointConstraintTensors_[nConstraints] =
321  patchPatchPointConstraints_[i].constraintTransformation();
322 
323  nConstraints++;
324  }
325  }
326 
327  if (debug)
328  {
329  Pout<< indent << "Have non-trivial constrained points:"
330  << nConstraints << endl;
331  }
332 
333  patchPatchPointConstraints_.setSize(nConstraints);
334  patchPatchPointConstraintPoints_.setSize(nConstraints);
335  patchPatchPointConstraintTensors_.setSize(nConstraints);
336 
337 
338  if (debug)
339  {
340  Pout<< decrIndent
341  << "pointConstraints::makePatchPatchAddressing() : "
342  << "finished constructing boundary addressing"
343  << endl;
344  }
345 }
346 
347 
348 // * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * * //
349 
351 :
353  <
354  pointMesh,
357  >(pm)
358 {
359  if (debug)
360  {
361  Pout<< "pointConstraints::pointConstraints(const pointMesh&): "
362  << "Constructing from pointMesh " << pm.name()
363  << endl;
364  }
365 
366  makePatchPatchAddressing();
367 }
368 
369 
370 // * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * * //
371 
373 {
374  if (debug)
375  {
376  Pout<< "pointConstraints::~pointConstraints()" << endl;
377  }
378 }
379 
380 
381 // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
382 
384 {
385  return true;
386 }
387 
388 
390 {
391  makePatchPatchAddressing();
392 }
393 
394 
396 {
397  makePatchPatchAddressing();
398 }
399 
400 
402 {
404  makePatchPatchAddressing();
405 }
406 
407 
409 (
410  pointVectorField& pf,
411  const bool overrideFixedValue
412 ) const
413 {
414  // Override constrained pointPatchField types with the constraint value.
415  // This relies on only constrained pointPatchField implementing the evaluate
416  // function
418 
419  // Sync any dangling points
420  syncUntransformedData
421  (
422  pf.mesh()(),
423  pf.primitiveFieldRef(),
425  );
426 
427  // Apply multiple constraints on edge/corner points
428  constrainCorners(pf);
429 
430  // Apply any 2D motion constraints (or should they go before
431  // corner constraints?)
433  (
434  mesh()().points(),
435  pf.primitiveFieldRef()
436  );
437 
438  if (overrideFixedValue)
439  {
440  setPatchFields(pf);
441  }
442 }
443 
444 
445 template<>
446 void Foam::pointConstraints::constrainCorners<Foam::scalar>
447 (
448  PointField<scalar>& pf
449 ) const
450 {}
451 
452 
453 template<>
454 void Foam::pointConstraints::constrainCorners<Foam::label>
455 (
456  PointField<label>& pf
457 ) const
458 {}
459 
460 
461 // ************************************************************************* //
#define forAll(list, i)
Loop across all elements in list.
Definition: UList.H:433
Templated abstract base-class for demand-driven mesh objects used to automate their allocation to the...
static twoDPointCorrector & New(const word &name, const polyMesh &mesh)
Construct and return the named DemandDrivenMeshObject.
const Mesh & mesh() const
Return mesh.
Internal::FieldType & primitiveFieldRef()
Return a reference to the primitive field.
void correctBoundaryConditions()
Correct boundary field.
friend class iterator
Declare friendship with the iterator.
Definition: HashTable.H:194
friend class const_iterator
Declare friendship with the const_iterator.
Definition: HashTable.H:197
const word & name() const
Return name.
Definition: IOobject.H:307
virtual const fileName & name() const
Return the name of the stream.
Definition: IOstream.H:297
void size(const label)
Override size to be inconsistent with allocated storage.
Definition: ListI.H:164
void setSize(const label)
Reset size of List.
Definition: List.C:281
Application of (multi-)patch point constraints.
virtual bool movePoints()
Correct weighting factors for moving mesh.
pointConstraints(const pointMesh &)
Constructor from pointMesh.
virtual void topoChange(const polyTopoChangeMap &)
Update mesh topology using the morph engine.
virtual void distribute(const polyDistributionMap &)
Update corresponding to the given distribution map.
virtual void mapMesh(const polyMeshMap &)
Update from another mesh using the given map.
~pointConstraints()
Destructor.
void constrainDisplacement(pointVectorField &displacement, const bool overrideValue=false) const
Apply boundary conditions (single-patch constraints),.
Mesh representing a set of points created from polyMesh.
Definition: pointMesh.H:53
const globalMeshData & globalData() const
Return parallel info.
Definition: pointMesh.H:141
Class containing mesh-to-mesh mapping information after a mesh distribution where we send parts of me...
Class containing mesh-to-mesh mapping information.
Definition: polyMeshMap.H:51
Class containing mesh-to-mesh mapping information after a change in polyMesh topology.
void correctDisplacement(const pointField &p, vectorField &disp) const
Correct motion displacements.
Foam::fvMesh mesh(Foam::IOobject(regionName, runTime.name(), runTime, Foam::IOobject::MUST_READ), false)
#define FatalErrorInFunction
Report an error message using Foam::FatalError.
Definition: error.H:334
label patchi
const pointField & points
Namespace for OpenFOAM.
Ostream & decrIndent(Ostream &os)
Decrement the indent level.
Definition: Ostream.H:242
List< label > labelList
A List of labels.
Definition: labelList.H:56
intWM_LABEL_SIZE_t label
A label is an int32_t or int64_t as specified by the pre-processor macro WM_LABEL_SIZE.
Definition: label.H:59
Ostream & endl(Ostream &os)
Add newline and flush stream.
Definition: Ostream.H:258
errorManip< error > abort(error &err)
Definition: errorManip.H:131
Ostream & incrIndent(Ostream &os)
Increment the indent level.
Definition: Ostream.H:235
labelList first(const UList< labelPair > &p)
Definition: patchToPatch.C:39
List< labelList > labelListList
A List of labelList.
Definition: labelList.H:57
defineTypeNameAndDebug(combustionModel, 0)
prefixOSstream Pout(cout, "Pout")
Definition: IOstreams.H:53
error FatalError
Ostream & indent(Ostream &os)
Indent stream.
Definition: Ostream.H:228