surfaceAlignedSBRStressFvMotionSolver.C
Go to the documentation of this file.
1 /*---------------------------------------------------------------------------*\
2  ========= |
3  \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
4  \\ / O peration |
5  \\ / A nd | www.openfoam.com
6  \\/ M anipulation |
7 -------------------------------------------------------------------------------
8  Copyright (C) 2015 OpenFOAM Foundation
9  Copyright (C) 2015-2020 OpenCFD Ltd.
10 -------------------------------------------------------------------------------
11 License
12  This file is part of OpenFOAM.
13 
14  OpenFOAM is free software: you can redistribute it and/or modify it
15  under the terms of the GNU General Public License as published by
16  the Free Software Foundation, either version 3 of the License, or
17  (at your option) any later version.
18 
19  OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
20  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
21  FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
22  for more details.
23 
24  You should have received a copy of the GNU General Public License
25  along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
26 
27 \*---------------------------------------------------------------------------*/
28 
31 #include "pointIndexHit.H"
32 #include "fvmLaplacian.H"
33 #include "fvcDiv.H"
34 #include "surfaceInterpolate.H"
35 #include "unitConversion.H"
36 #include "motionDiffusivity.H"
37 #include "fvcSmooth.H"
38 #include "pointMVCWeight.H"
39 #include "dimensionedSymmTensor.H"
40 #include "quaternion.H"
41 #include "fvOptions.H"
42 
43 // * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
44 
45 namespace Foam
46 {
47  defineTypeNameAndDebug(surfaceAlignedSBRStressFvMotionSolver, 0);
48 
50  (
51  motionSolver,
52  surfaceAlignedSBRStressFvMotionSolver,
53  dictionary
54  );
55 }
56 
57 
58 // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
59 
60 Foam::surfaceAlignedSBRStressFvMotionSolver::
61 surfaceAlignedSBRStressFvMotionSolver
62 (
63  const polyMesh& mesh,
64  const IOdictionary& dict
65 )
66 :
68  surfaceNames_(coeffDict().lookup("surfaces")),
69  surfaceMesh_(surfaceNames_.size()),
70  cellRot_
71  (
72  IOobject
73  (
74  "cellRot",
75  fvMesh_.time().timeName(),
76  fvMesh_,
77  IOobject::NO_READ,
78  IOobject::NO_WRITE
79  ),
80  fvMesh_,
82  ),
83  maxAng_(coeffDict().getOrDefault<scalar>("maxAng", 80)),
84  minAng_(coeffDict().getOrDefault<scalar>("minAng", 20)),
85  accFactor_(coeffDict().getOrDefault<scalar>("accFactor", 1)),
86  smoothFactor_(coeffDict().getOrDefault<scalar>("smoothFactor", 0.9)),
87  nNonOrthogonalCorr_(coeffDict().get<label>("nNonOrthogonalCorr")),
88  pointDisplacement_(pointDisplacement()),
89  sigmaD_
90  (
91  IOobject
92  (
93  "sigmaD",
94  fvMesh_.time().timeName(),
95  fvMesh_,
96  IOobject::READ_IF_PRESENT,
97  IOobject::NO_WRITE
98  ),
99  fvMesh_,
101  ),
102  minSigmaDiff_(coeffDict().getOrDefault<scalar>("minSigmaDiff", 1e-4))
103 {
104  forAll(surfaceNames_, i)
105  {
106  surfaceMesh_.set
107  (
108  i,
109  new triSurfaceMesh
110  (
111  IOobject
112  (
113  surfaceNames_[i],
114  mesh.time().constant(),
115  "triSurface",
116  mesh.time(),
117  IOobject::MUST_READ,
118  IOobject::NO_WRITE
119  )
120  )
121  );
122  }
123 }
124 
125 
126 // * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * //
127 
130 {}
131 
132 
133 // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
134 
135 
136 void Foam::surfaceAlignedSBRStressFvMotionSolver::calculateCellRot()
137 {
138  cellRot_.primitiveFieldRef() = Zero;
139  pointDisplacement_.primitiveFieldRef() = Zero;
140 
141  // Find intersections
142  pointField start(fvMesh_.nInternalFaces());
143  pointField end(start.size());
144 
145  const vectorField& Cc = fvMesh_.cellCentres();
146  const polyBoundaryMesh& pbm = fvMesh_.boundaryMesh();
147 
148  for (label faceI = 0; faceI < fvMesh_.nInternalFaces(); faceI++)
149  {
150  start[faceI] = Cc[fvMesh_.faceOwner()[faceI]];
151  end[faceI] = Cc[fvMesh_.faceNeighbour()[faceI]];
152  }
153 
154  DynamicList<label> hitCells;
155 
156  forAll(surfaceMesh_, surfi)
157  {
158  List<pointIndexHit> hit(start.size());
159  surfaceMesh_[surfi].findLineAny(start, end, hit);
160 
161  labelField pointsCount(fvMesh_.nPoints(), 1);
162 
163  const vectorField& nf = surfaceMesh_[surfi].faceNormals();
164 
165  const vectorField& SfMesh = fvMesh_.faceAreas();
166 
167  const vectorField nSfMesh(SfMesh/mag(SfMesh));
168 
169  DynamicList<label> cellsHit;
170 
171  forAll(hit, facei)
172  {
173  if (hit[facei].hit())
174  {
175  label rotCellId(-1);
176  const vector hitPoint = hit[facei].hitPoint();
177 
178  if (fvMesh_.isInternalFace(facei))
179  {
180  const vector cCOne = Cc[fvMesh_.faceOwner()[facei]];
181  const vector cCTwo = Cc[fvMesh_.faceNeighbour()[facei]];
182 
183  if (mag(cCOne - hitPoint) < mag(cCTwo - hitPoint))
184  {
185  rotCellId = fvMesh_.faceOwner()[facei];
186  }
187  else
188  {
189  rotCellId = fvMesh_.faceNeighbour()[facei];
190  }
191  }
192  else
193  {
194  label patchi = pbm.whichPatch(facei);
195  if (isA<processorPolyPatch>(pbm[patchi]))
196  {
197  const point& ownCc = Cc[fvMesh_.faceOwner()[facei]];
198 
199  const vector cCentreOne = ownCc - hitPoint;
200 
201  const vector nbrCc =
202  refCast<const processorPolyPatch>(pbm[patchi])
203  .neighbFaceCellCentres()[facei];
204 
205  const vector cCentreTwo = nbrCc - hitPoint;
206 
207  if (cCentreOne < cCentreTwo)
208  {
209  rotCellId = fvMesh_.faceOwner()[facei];
210  }
211  }
212  }
213 
214  // Note: faces on boundaries that get hit are not included as
215  // the pointDisplacement on boundaries is usually zero for
216  // this solver.
217 
218  // Search for closest direction on faces on mesh
219  // and surface normal.
220  if (rotCellId != -1)
221  {
222  const labelList& cFaces = fvMesh_.cells()[rotCellId];
223 
224  scalar cosMax(-GREAT);
225  label faceId(-1);
226  forAll(cFaces, k)
227  {
228  scalar tmp =
229  mag(nf[hit[facei].index()] & nSfMesh[cFaces[k]]);
230 
231  if (tmp > cosMax)
232  {
233  cosMax = tmp;
234  faceId = cFaces[k];
235  }
236  }
237  if
238  (
239  faceId != -1
240  &&
241  (
242  ::cos(degToRad(minAng_)) > cosMax
243  || cosMax > ::cos(degToRad(maxAng_))
244 
245  )
246  )
247  {
248  cellRot_[rotCellId] =
249  nSfMesh[faceId]^nf[hit[facei].index()];
250 
251  const scalar magRot = mag(cellRot_[rotCellId]);
252 
253  if (magRot > 0)
254  {
255  const scalar theta = ::asin(magRot);
256  quaternion q(cellRot_[rotCellId]/magRot, theta);
257  const tensor R = q.R();
258  const labelList& cPoints =
259  fvMesh_.cellPoints(rotCellId);
260 
261  forAll(cPoints, j)
262  {
263  const label pointId = cPoints[j];
264 
265  pointsCount[pointId]++;
266 
267  const vector pointPos =
268  fvMesh_.points()[pointId];
269 
270  pointDisplacement_[pointId] +=
271  (R & (pointPos - hitPoint))
272  - (pointPos - hitPoint);
273  }
274  }
275  }
276  }
277  }
278  }
279 
280  vectorField& pd = pointDisplacement_.primitiveFieldRef();
281  forAll(pd, pointi)
282  {
283  vector& point = pd[pointi];
284  point /= pointsCount[pointi];
285  }
286  }
287 }
288 
289 
291 {
292  // The points have moved so before interpolation update
293  // the motionSolver accordingly
294  this->movePoints(fvMesh_.points());
295 
296  volVectorField& cellDisp = cellDisplacement();
297 
298  diffusivity().correct();
299 
300  // Calculate rotations on surface intersection
301  calculateCellRot();
302 
304  (
305  new volVectorField
306  (
307  IOobject
308  (
309  "Ud",
310  fvMesh_.time().timeName(),
311  fvMesh_,
314  ),
315  fvMesh_,
317  cellMotionBoundaryTypes<vector>
318  (
319  pointDisplacement().boundaryField()
320  )
321  )
322  );
323 
324  volVectorField& Ud = tUd.ref();
325 
326  const vectorList& C = fvMesh_.C();
327  forAll(Ud, i)
328  {
329  pointMVCWeight pointInter(fvMesh_, C[i], i);
330  Ud[i] = pointInter.interpolate(pointDisplacement_);
331  }
332 
334  fvc::smooth(Udx, smoothFactor_);
335 
337  fvc::smooth(Udy, smoothFactor_);
338 
340  fvc::smooth(Udz, smoothFactor_);
341 
342  Ud.replace(vector::X, Udx);
343  Ud.replace(vector::Y, Udy);
344  Ud.replace(vector::Z, Udz);
345 
346  const volTensorField gradD("gradD", fvc::grad(Ud));
347 
349  (
350  new volScalarField
351  (
352  IOobject
353  (
354  "mu",
355  fvMesh_.time().timeName(),
356  fvMesh_,
359  ),
360  fvMesh_,
362  )
363  );
364  volScalarField& mu = tmu.ref();
365 
366  const scalarList& V = fvMesh_.V();
367  mu.primitiveFieldRef() = (1.0/V);
368 
369  const volScalarField lambda(-mu);
370 
371  const volSymmTensorField newSigmaD
372  (
373  mu*twoSymm(gradD) + (lambda*I)*tr(gradD)
374  );
375 
376  const volSymmTensorField magNewSigmaD(sigmaD_ + accFactor_*newSigmaD);
377 
378  const scalar diffSigmaD =
379  gSum(mag(sigmaD_.oldTime().primitiveField()))
380  - gSum(mag(magNewSigmaD.primitiveField()));
381 
382  if (mag(diffSigmaD) > minSigmaDiff_)
383  {
384  sigmaD_ = magNewSigmaD;
385  }
386 
387  const dimensionedScalar oneViscosity("viscosity", dimViscosity, 1.0);
388 
389  const surfaceScalarField Df(oneViscosity*diffusivity().operator()());
390 
391  pointDisplacement_.boundaryFieldRef().updateCoeffs();
392 
394 
395  const volTensorField gradCd(fvc::grad(cellDisp));
396 
397  for (int nonOrth=0; nonOrth<=nNonOrthogonalCorr_; nonOrth++)
398  {
399  fvVectorMatrix DEqn
400  (
402  (
403  2*Df*fvc::interpolate(mu),
404  cellDisp,
405  "laplacian(diffusivity,cellDisplacement)"
406  )
407  + fvc::div
408  (
409  Df*
410  (
412  * (fvMesh_.Sf() & fvc::interpolate(gradCd.T() - gradCd))
413  - fvc::interpolate(lambda)*fvMesh_.Sf()
414  * fvc::interpolate(tr(gradCd))
415  )
416  )
417  ==
418  oneViscosity*fvc::div(sigmaD_)
419  + fvOptions(cellDisp)
420  );
421 
422  fvOptions.constrain(DEqn);
423 
424  // Note: solve uncoupled
425  DEqn.solveSegregatedOrCoupled(DEqn.solverDict());
426 
427  fvOptions.correct(cellDisp);
428  }
429 }
430 
431 
432 // ************************************************************************* //
Foam::addToRunTimeSelectionTable
addToRunTimeSelectionTable(decompositionMethod, kahipDecomp, dictionary)
surfaceAlignedSBRStressFvMotionSolver.H
Foam::IOobject::NO_WRITE
Definition: IOobject.H:195
Foam::labelList
List< label > labelList
A List of labels.
Definition: List.H:67
Foam::IOdictionary
IOdictionary is derived from dictionary and IOobject to give the dictionary automatic IO functionalit...
Definition: IOdictionary.H:54
Foam::IOobject
Defines the attributes of an object for which implicit objectRegistry management is supported,...
Definition: IOobject.H:169
Foam::GeometricField::component
tmp< GeometricField< cmptType, PatchField, GeoMesh > > component(const direction) const
Return a component of the field.
pointIndexHit.H
Foam::fvc::grad
tmp< GeometricField< typename outerProduct< vector, Type >::type, fvPatchField, volMesh >> grad(const GeometricField< Type, fvsPatchField, surfaceMesh > &ssf)
Definition: fvcGrad.C:54
Foam::Vector< scalar >::Z
Definition: Vector.H:81
Foam::Vector< scalar >::Y
Definition: Vector.H:81
fvOptions.H
Foam::GeometricField::replace
void replace(const direction d, const GeometricField< cmptType, PatchField, GeoMesh > &gcf)
Replace specified field component with content from another field.
Foam::fv::optionList::correct
void correct(GeometricField< Type, fvPatchField, volMesh > &field)
Apply correction to field.
Definition: fvOptionListTemplates.C:355
Foam::polyBoundaryMesh
A polyBoundaryMesh is a polyPatch list with additional search methods and registered IO.
Definition: polyBoundaryMesh.H:63
Foam::constant::physicoChemical::mu
const dimensionedScalar mu
Atomic mass unit.
Definition: createFieldRefs.H:4
Foam::dimLength
const dimensionSet dimLength(0, 1, 0, 0, 0, 0, 0)
Definition: dimensionSets.H:52
Foam::dimensionedSymmTensor
dimensioned< symmTensor > dimensionedSymmTensor
Dimensioned tensor obtained from generic dimensioned type.
Definition: dimensionedSymmTensor.H:50
Foam::tmp
A class for managing temporary objects.
Definition: PtrList.H:61
Foam::Zero
static constexpr const zero Zero
Global zero (0)
Definition: zero.H:131
Foam::fv::optionList::constrain
void constrain(fvMatrix< Type > &eqn)
Apply constraints to equation.
Definition: fvOptionListTemplates.C:314
quaternion.H
Foam::fv::options::New
static options & New(const fvMesh &mesh)
Construct fvOptions and register to database if not present.
Definition: fvOptions.C:103
Foam::GeometricField::primitiveField
const Internal::FieldType & primitiveField() const
Return a const-reference to the internal field.
Definition: GeometricFieldI.H:53
fvcDiv.H
Calculate the divergence of the given field.
unitConversion.H
Unit conversion functions.
Foam::fvc::div
tmp< GeometricField< Type, fvPatchField, volMesh > > div(const GeometricField< Type, fvsPatchField, surfaceMesh > &ssf)
Definition: fvcDiv.C:49
Foam::triSurfaceMesh
IOoject and searching on triSurface.
Definition: triSurfaceMesh.H:106
Foam::gSum
Type gSum(const FieldField< Field, Type > &f)
Definition: FieldFieldFunctions.C:594
Foam::pointMVCWeight::interpolate
Type interpolate(const GeometricField< Type, pointPatchField, pointMesh > &psip) const
Interpolate field.
Definition: pointMVCWeightI.H:34
Foam::polyMesh
Mesh consisting of general polyhedral cells.
Definition: polyMesh.H:77
forAll
#define forAll(list, i)
Loop across all elements in list.
Definition: stdFoam.H:296
Foam::vectorField
Field< vector > vectorField
Specialisation of Field<T> for vector.
Definition: primitiveFieldsFwd.H:54
Foam::dimensionedVector
dimensioned< vector > dimensionedVector
Dimensioned vector obtained from generic dimensioned type.
Definition: dimensionedVector.H:50
Foam::surfaceAlignedSBRStressFvMotionSolver::solve
virtual void solve()
Solve for motion.
Definition: surfaceAlignedSBRStressFvMotionSolver.C:290
R
#define R(A, B, C, D, E, F, K, M)
Foam::tmp::ref
T & ref() const
Definition: tmpI.H:227
fvOptions
fv::options & fvOptions
Definition: setRegionFluidFields.H:23
Foam::Field< vector >
Foam::labelField
Field< label > labelField
Specialisation of Field<T> for label.
Definition: labelField.H:52
Foam::fvm::laplacian
tmp< fvMatrix< Type > > laplacian(const GeometricField< Type, fvPatchField, volMesh > &vf, const word &name)
Definition: fvmLaplacian.C:48
faceId
label faceId(-1)
fvmLaplacian.H
Calculate the matrix for the laplacian of the field.
Foam::Vector< scalar >::X
Definition: Vector.H:81
Foam::surfaceAlignedSBRStressFvMotionSolver::~surfaceAlignedSBRStressFvMotionSolver
~surfaceAlignedSBRStressFvMotionSolver()
Destructor.
Definition: surfaceAlignedSBRStressFvMotionSolver.C:129
Foam::dimensionedScalar
dimensioned< scalar > dimensionedScalar
Dimensioned scalar obtained from generic dimensioned type.
Definition: dimensionedScalarFwd.H:42
Foam::polyBoundaryMesh::whichPatch
label whichPatch(const label faceIndex) const
Return patch index for a given face label.
Definition: polyBoundaryMesh.C:812
Foam::pointMVCWeight
Container to calculate weights for interpolating directly from vertices of cell using Mean Value Coor...
Definition: pointMVCWeight.H:69
Foam::displacementSBRStressFvMotionSolver
Mesh motion solver for an fvMesh. Based on solving the cell-centre solid-body rotation stress equatio...
Definition: displacementSBRStressFvMotionSolver.H:59
Foam::radiation::lookup
Lookup type of boundary radiation properties.
Definition: lookup.H:63
Foam::fv::options
Finite-volume options.
Definition: fvOptions.H:55
dict
dictionary dict
Definition: searchingEngine.H:14
Foam::dimViscosity
const dimensionSet dimViscosity
dimensionedSymmTensor.H
lambda
dimensionedScalar lambda("lambda", dimTime/sqr(dimLength), laminarTransport)
pointMVCWeight.H
mesh
dynamicFvMesh & mesh
Definition: createDynamicFvMesh.H:6
addToRunTimeSelectionTable.H
Macros for easy insertion into run-time selection tables.
Foam::dimensioned< scalar >
stdFoam::end
constexpr auto end(C &c) -> decltype(c.end())
Return iterator to the end of the container c.
Definition: stdFoam.H:121
Foam::C::C
C()
Construct null.
Definition: C.C:43
Foam
Namespace for OpenFOAM.
Definition: atmBoundaryLayer.C:33
Foam::fvc::interpolate
static tmp< GeometricField< Type, fvsPatchField, surfaceMesh > > interpolate(const GeometricField< Type, fvPatchField, volMesh > &tvf, const surfaceScalarField &faceFlux, Istream &schemeData)
Interpolate field onto faces using scheme given by Istream.
Foam::vector
Vector< scalar > vector
A scalar version of the templated Vector.
Definition: vector.H:51
Foam::degToRad
constexpr scalar degToRad(const scalar deg) noexcept
Conversion from degrees to radians.
Definition: unitConversion.H:48
motionDiffusivity.H
Foam::GeometricField::T
tmp< GeometricField< Type, PatchField, GeoMesh > > T() const
Return transpose (only if it is a tensor field)
Definition: GeometricField.C:1046
Foam::List< vector >
Foam::mag
dimensioned< typename typeOfMag< Type >::type > mag(const dimensioned< Type > &dt)
k
label k
Boltzmann constant.
Definition: LISASMDCalcMethod2.H:41
Foam::constant::electromagnetic::e
const dimensionedScalar e
Elementary charge.
Definition: createFields.H:11
Foam::fvMatrix
A special matrix type and solver, designed for finite volume solutions of scalar equations....
Definition: fvPatchField.H:68
Foam::tr
dimensionedScalar tr(const dimensionedSphericalTensor &dt)
Definition: dimensionedSphericalTensor.C:51
Foam::point
vector point
Point is a vector.
Definition: point.H:43
Foam::C
Graphite solid properties.
Definition: C.H:50
Foam::GeometricField< vector, fvPatchField, volMesh >
Foam::IOobject::NO_READ
Definition: IOobject.H:188
Foam::defineTypeNameAndDebug
defineTypeNameAndDebug(combustionModel, 0)
Foam::twoSymm
dimensionedSymmTensor twoSymm(const dimensionedSymmTensor &dt)
Definition: dimensionedSymmTensor.C:95
Foam::tensor
Tensor< scalar > tensor
Tensor of scalars, i.e. Tensor<scalar>.
Definition: symmTensor.H:61
Foam::asin
dimensionedScalar asin(const dimensionedScalar &ds)
Definition: dimensionedScalar.C:267
fvcSmooth.H
Provides functions smooth spread and sweep which use the FaceCellWave algorithm to smooth and redistr...
Foam::I
static const Identity< scalar > I
Definition: Identity.H:95
Foam::dimless
const dimensionSet dimless
Dimensionless.
Definition: dimensionSets.C:189
Foam::fvc::smooth
void smooth(volScalarField &field, const scalar coeff)
Definition: fvcSmooth.C:44
Foam::cos
dimensionedScalar cos(const dimensionedScalar &ds)
Definition: dimensionedScalar.C:265