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