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 | Copyright (C) 2015 OpenFOAM Foundation
6  \\/ M anipulation | Copyright (C) 2015 OpenCFD Ltd.
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 
28 #include "pointIndexHit.H"
29 #include "fvmLaplacian.H"
30 #include "fvcDiv.H"
31 #include "surfaceInterpolate.H"
32 #include "unitConversion.H"
33 #include "motionDiffusivity.H"
34 #include "fvcSmooth.H"
35 #include "pointMVCWeight.H"
36 #include "dimensionedSymmTensor.H"
37 #include "quaternion.H"
38 
39 // * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
40 
41 namespace Foam
42 {
43  defineTypeNameAndDebug(surfaceAlignedSBRStressFvMotionSolver, 0);
44 
46  (
47  motionSolver,
48  surfaceAlignedSBRStressFvMotionSolver,
49  dictionary
50  );
51 }
52 
53 
54 // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
55 
58 (
59  const polyMesh& mesh,
60  const IOdictionary& dict
61 )
62 :
64  surfaceNames_(coeffDict().lookup("surfaces")),
65  surfaceMesh_(surfaceNames_.size()),
66  cellRot_
67  (
68  IOobject
69  (
70  "cellRot",
71  fvMesh_.time().timeName(),
72  fvMesh_,
73  IOobject::NO_READ,
74  IOobject::NO_WRITE
75  ),
76  fvMesh_,
77  dimensionedVector("zero", dimless, vector::zero)
78  ),
79  maxAng_(coeffDict().lookupOrDefault<scalar>("maxAng", 80.0)),
80  minAng_(coeffDict().lookupOrDefault<scalar>("minAng", 20.0)),
81  accFactor_(coeffDict().lookupOrDefault<scalar>("accFactor", 1.0)),
82  smoothFactor_(coeffDict().lookupOrDefault<scalar>("smoothFactor", 0.9)),
83  nNonOrthogonalCorr_(readLabel(coeffDict().lookup("nNonOrthogonalCorr"))),
84  pointDisplacement_(pointDisplacement()),
85  sigmaD_
86  (
87  IOobject
88  (
89  "sigmaD",
90  fvMesh_.time().timeName(),
91  fvMesh_,
92  IOobject::READ_IF_PRESENT,
93  IOobject::NO_WRITE
94  ),
95  fvMesh_,
96  dimensionedSymmTensor("zero", dimless, symmTensor::zero)
97  ),
98  minSigmaDiff_(coeffDict().lookupOrDefault<scalar>("minSigmaDiff", 1e-4))
99 {
100  forAll (surfaceNames_, i)
101  {
102  surfaceMesh_.set
103  (
104  i,
105  new triSurfaceMesh
106  (
107  IOobject
108  (
109  surfaceNames_[i],
110  mesh.time().constant(),
111  "triSurface",
112  mesh.time(),
113  IOobject::MUST_READ,
114  IOobject::NO_WRITE
115  )
116  )
117  );
118  }
119 }
120 
121 
122 // * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * //
123 
126 {}
127 
128 
129 // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
130 
131 
133 {
134  cellRot_.internalField() = vector::zero;
135  pointDisplacement_.internalField() = vector::zero;
136 
137  // Find intersections
138  pointField start(fvMesh_.nInternalFaces());
139  pointField end(start.size());
140 
141  for (label faceI = 0; faceI < fvMesh_.nInternalFaces(); faceI++)
142  {
143  start[faceI] = fvMesh_.cellCentres()[fvMesh_.faceOwner()[faceI]];
144  end[faceI] = fvMesh_.cellCentres()[fvMesh_.faceNeighbour()[faceI]];
145  }
146 
147  DynamicList<label> hitCells;
148 
149  forAll (surfaceMesh_, surfI)
150  {
151  List<pointIndexHit> hit(start.size());
152  surfaceMesh_[surfI].findLineAny(start, end, hit);
153 
154  labelField pointsCount(fvMesh_.nPoints(), 1);
155 
156  const vectorField& nf = surfaceMesh_[surfI].faceNormals();
157 
158  const vectorField& SfMesh = fvMesh_.faceAreas();
159 
160  const vectorField nSfMesh(SfMesh/mag(SfMesh));
161 
162  DynamicList<label> cellsHit;
163 
164  forAll(hit, faceI)
165  {
166  if (hit[faceI].hit())
167  {
168  label rotCellId(-1);
169  const vector hitPoint = hit[faceI].hitPoint();
170 
171  if (fvMesh_.isInternalFace(faceI))
172  {
173  const vector cCOne =
174  fvMesh_.cellCentres()[fvMesh_.faceOwner()[faceI]];
175 
176  const vector cCTwo =
177  fvMesh_.cellCentres()[fvMesh_.faceNeighbour()[faceI]];
178 
179  if (mag(cCOne - hitPoint) < mag(cCTwo - hitPoint))
180  {
181  rotCellId = fvMesh_.faceOwner()[faceI];
182  }
183  else
184  {
185  rotCellId = fvMesh_.faceNeighbour()[faceI];
186  }
187  }
188  else
189  {
190  label patchI = fvMesh_.boundaryMesh().whichPatch(faceI);
191  if
192  (
193  isA<processorPolyPatch>(fvMesh_.boundaryMesh()[patchI])
194  )
195  {
196  const point& ownCc =
197  fvMesh_.cellCentres()[fvMesh_.faceOwner()[faceI]];
198 
199  const vector cCentreOne = ownCc - hitPoint;
200 
201  const vector nbrCc =
202  refCast<const processorPolyPatch>
203  (
204  fvMesh_.boundaryMesh()[patchI]
205  ).neighbFaceCellCentres()[faceI];
206 
207  const vector cCentreTwo = nbrCc - hitPoint;
208 
209  if (cCentreOne < cCentreTwo)
210  {
211  rotCellId = fvMesh_.faceOwner()[faceI];
212  }
213  }
214  }
215 
216  // Note: faces on boundaries that get hit are noy included as
217  // the pointDisplacement on boundaries is usually zero for
218  // this solver.
219 
220  // Search for closest direction on faces on mesh
221  // and surface normal.
222  if (rotCellId != -1)
223  {
224  const labelList& cFaces = fvMesh_.cells()[rotCellId];
225 
226  scalar cosMax(-GREAT);
227  label faceId(-1);
228  forAll(cFaces, k)
229  {
230  scalar tmp =
231  mag(nf[hit[faceI].index()] & nSfMesh[cFaces[k]]);
232 
233  if (tmp > cosMax)
234  {
235  cosMax = tmp;
236  faceId = cFaces[k];
237  }
238  }
239  if
240  (
241  faceId != -1
242  &&
243  (
244  ::cos(degToRad(minAng_)) > cosMax
245  || cosMax > ::cos(degToRad(maxAng_))
246 
247  )
248  )
249  {
250  cellRot_[rotCellId] =
251  nSfMesh[faceId] ^ nf[hit[faceI].index()];
252 
253  const scalar magRot = mag(cellRot_[rotCellId]);
254 
255  if (magRot > 0)
256  {
257  const scalar theta = ::asin(magRot);
258  quaternion q(cellRot_[rotCellId]/magRot, theta);
259  const tensor R = q.R();
260  const labelList& cPoints =
261  fvMesh_.cellPoints(rotCellId);
262 
263  forAll (cPoints, j)
264  {
265  const label pointId = cPoints[j];
266 
267  pointsCount[pointId]++;
268 
269  const vector pointPos =
270  fvMesh_.points()[pointId];
271 
272  pointDisplacement_[pointId] +=
273  (R & (pointPos - hitPoint))
274  - (pointPos - hitPoint);
275  }
276  }
277  }
278  }
279  }
280  }
281 
282  forAll (pointDisplacement_.internalField(), iPoint)
283  {
284  vector& point = pointDisplacement_.internalField()[iPoint];
285  point /= pointsCount[iPoint];
286  }
287 
288 
289  }
290 }
291 
292 
294 {
295  // The points have moved so before interpolation update
296  // the mtionSolver accordingly
297  this->movePoints(fvMesh_.points());
298 
299  volVectorField& cellDisp = cellDisplacement();
300 
301  diffusivity().correct();
302 
303  // Calculate rotations on surface intersection
304  calculateCellRot();
305 
307  (
308  new volVectorField
309  (
310  IOobject
311  (
312  "Ud",
313  fvMesh_.time().timeName(),
314  fvMesh_,
317  ),
318  fvMesh_,
320  cellMotionBoundaryTypes<vector>
321  (
322  pointDisplacement().boundaryField()
323  )
324  )
325  );
326 
327  volVectorField& Ud = tUd();
328 
329  const vectorList& C = fvMesh_.C();
330  forAll (Ud, i)
331  {
332  pointMVCWeight pointInter(fvMesh_, C[i], i);
333  Ud[i] = pointInter.interpolate(pointDisplacement_);
334  }
335 
337  fvc::smooth(Udx, smoothFactor_);
338 
340  fvc::smooth(Udy, smoothFactor_);
341 
343  fvc::smooth(Udz, smoothFactor_);
344 
345  Ud.replace(vector::X, Udx);
346  Ud.replace(vector::Y, Udy);
347  Ud.replace(vector::Z, Udz);
348 
349  const volTensorField gradD("gradD", fvc::grad(Ud));
350 
352  (
353  new volScalarField
354  (
355  IOobject
356  (
357  "mu",
358  fvMesh_.time().timeName(),
359  fvMesh_,
362  ),
363  fvMesh_,
364  dimensionedScalar("zero", dimless, 0.0)
365  )
366  );
367  volScalarField& mu = tmu();
368 
369  const scalarList& V = fvMesh_.V();
370  mu.internalField() = (1.0/V);
371 
372  const volScalarField lambda(-mu);
373 
374  const volSymmTensorField newSigmaD
375  (
376  mu*twoSymm(gradD) + (lambda*I)*tr(gradD)
377  );
378 
379  const volSymmTensorField magNewSigmaD(sigmaD_ + accFactor_*newSigmaD);
380 
381  const scalar diffSigmaD =
382  gSum(mag(sigmaD_.oldTime().internalField()))
383  - gSum(mag(magNewSigmaD.internalField()));
384 
385  if (mag(diffSigmaD) > minSigmaDiff_)
386  {
387  sigmaD_ = magNewSigmaD;
388  }
389 
390  const surfaceScalarField Df(diffusivity().operator()());
391  pointDisplacement_.boundaryField().updateCoeffs();
392 
393  const volTensorField gradCd(fvc::grad(cellDisp));
394 
395  for (int nonOrth=0; nonOrth<=nNonOrthogonalCorr_; nonOrth++)
396  {
397  fvVectorMatrix DEqn
398  (
400  (
401  2*Df*fvc::interpolate(mu),
402  cellDisp,
403  "laplacian(diffusivity,cellDisplacement)"
404  )
405  + fvc::div
406  (
407  Df*
408  (
410  * (fvMesh_.Sf() & fvc::interpolate(gradCd.T() - gradCd))
411  - fvc::interpolate(lambda)*fvMesh_.Sf()
412  * fvc::interpolate(tr(gradCd))
413  )
414  )
415  ==
416  fvc::div(sigmaD_)
417  );
418 
419  DEqn.solve();
420  }
421 }
422 
423 // ************************************************************************* //
surfaceAlignedSBRStressFvMotionSolver.H
Foam::IOdictionary
IOdictionary is derived from dictionary and IOobject to give the dictionary automatic IO functionalit...
Definition: IOdictionary.H:53
Foam::Tensor
Templated 3D tensor derived from VectorSpace adding construction from 9 components,...
Definition: complexI.H:224
Foam::IOobject
IOobject defines the attributes of an object for which implicit objectRegistry management is supporte...
Definition: IOobject.H:91
Foam::GeometricField::component
tmp< GeometricField< cmptType, PatchField, GeoMesh > > component(const direction) const
Return a component of the field.
pointIndexHit.H
Foam::dimless
const dimensionSet dimless(0, 0, 0, 0, 0, 0, 0)
Definition: dimensionSets.H:47
Foam::fvc::grad
tmp< GeometricField< typename outerProduct< vector, Type >::type, fvPatchField, volMesh >> grad(const GeometricField< Type, fvsPatchField, surfaceMesh > &ssf)
Definition: fvcGrad.C:52
Foam::Vector< scalar >::Z
@ Z
Definition: Vector.H:89
Foam::Vector< scalar >::zero
static const Vector zero
Definition: Vector.H:80
Foam::Vector< scalar >::Y
@ Y
Definition: Vector.H:89
Foam::constant::physicoChemical::mu
const dimensionedScalar mu
Atomic mass unit.
Definition: createFields.H:13
Foam::dimLength
const dimensionSet dimLength(0, 1, 0, 0, 0, 0, 0)
Definition: dimensionSets.H:50
forAll
#define forAll(list, i)
Loop across all elements in list.
Definition: UList.H:406
Foam::tmp
A class for managing temporary objects.
Definition: PtrList.H:118
Foam::DynamicList< label >
quaternion.H
Foam::addToRunTimeSelectionTable
addToRunTimeSelectionTable(ensightPart, ensightPartCells, istream)
Foam::fvc::interpolate
tmp< GeometricField< Type, fvsPatchField, surfaceMesh > > interpolate(const GeometricField< Type, fvPatchField, volMesh > &vf, const surfaceScalarField &faceFlux, Istream &schemeData)
Interpolate field onto faces using scheme given by Istream.
Definition: surfaceInterpolate.C:110
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:47
Foam::triSurfaceMesh
IOoject and searching on triSurface.
Definition: triSurfaceMesh.H:63
Foam::gSum
Type gSum(const FieldField< Field, Type > &f)
Definition: FieldFieldFunctions.C:564
Foam::mag
dimensioned< scalar > mag(const dimensioned< Type > &)
Foam::pointMVCWeight::interpolate
Type interpolate(const GeometricField< Type, pointPatchField, pointMesh > &psip) const
Interpolate field.
Definition: pointMVCWeightI.H:32
Foam::polyMesh
Mesh consisting of general polyhedral cells.
Definition: polyMesh.H:74
Foam::IOobject::NO_WRITE
@ NO_WRITE
Definition: IOobject.H:118
Foam::quaternion
Quaternion class used to perform rotations in 3D space.
Definition: quaternion.H:60
Foam::fvMatrix::solve
SolverPerformance< Type > solve(const dictionary &)
Solve segregated or coupled returning the solution statistics.
Foam::surfaceAlignedSBRStressFvMotionSolver::solve
virtual void solve()
Solve for motion.
Definition: surfaceAlignedSBRStressFvMotionSolver.C:293
R
#define R(A, B, C, D, E, F, K, M)
Foam::label
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
Foam::Field
Pre-declare SubField and related Field type.
Definition: Field.H:57
Foam::IOobject::NO_READ
@ NO_READ
Definition: IOobject.H:111
Foam::fvm::laplacian
tmp< fvMatrix< Type > > laplacian(const GeometricField< Type, fvPatchField, volMesh > &vf, const word &name)
Definition: fvmLaplacian.C:46
faceId
label faceId(-1)
fvmLaplacian.H
Calculate the matrix for the laplacian of the field.
Foam::Vector< scalar >::X
@ X
Definition: Vector.H:89
Foam::surfaceAlignedSBRStressFvMotionSolver::calculateCellRot
void calculateCellRot()
Calculate cellRot.
Definition: surfaceAlignedSBRStressFvMotionSolver.C:132
Foam::surfaceAlignedSBRStressFvMotionSolver::~surfaceAlignedSBRStressFvMotionSolver
~surfaceAlignedSBRStressFvMotionSolver()
Destructor.
Definition: surfaceAlignedSBRStressFvMotionSolver.C:125
Foam::GeometricField::internalField
InternalField & internalField()
Return internal field.
Definition: GeometricField.C:724
Foam::pointMVCWeight
Container to calculate weights for interpolating directly from vertices of cell using Mean Value Coor...
Definition: pointMVCWeight.H:67
Foam::surfaceAlignedSBRStressFvMotionSolver::surfaceAlignedSBRStressFvMotionSolver
surfaceAlignedSBRStressFvMotionSolver(const surfaceAlignedSBRStressFvMotionSolver &)
Disallow default bitwise copy construct.
Foam::displacementSBRStressFvMotionSolver
Mesh motion solver for an fvMesh. Based on solving the cell-centre solid-body rotation stress equatio...
Definition: displacementSBRStressFvMotionSolver.H:54
Foam::I
static const sphericalTensor I(1)
dict
dictionary dict
Definition: searchingEngine.H:14
dimensionedSymmTensor.H
pointMVCWeight.H
mesh
dynamicFvMesh & mesh
Definition: createDynamicFvMesh.H:18
addToRunTimeSelectionTable.H
Macros for easy insertion into run-time selection tables.
boundaryField
cellIbMask *cellIbMaskExt *faceIbMask *cellIbMask boundaryField().evaluateCoupled()
Foam::dimensioned
Generic dimensioned Type class.
Definition: dimensionedScalarFwd.H:41
Foam::C::C
C()
Construct null.
Definition: C.C:41
surfaceInterpolate.H
Surface Interpolation.
Foam
Namespace for OpenFOAM.
Definition: combustionModel.C:30
motionDiffusivity.H
Foam::GeometricField::T
tmp< GeometricField< Type, PatchField, GeoMesh > > T() const
Return transpose (only if it is a tensor field)
Definition: GeometricField.C:996
Foam::Vector< scalar >
Foam::List
A 1D array of objects of type <T>, where the size of the vector is known and used for subscript bound...
Definition: HashTable.H:59
k
label k
Boltzmann constant.
Definition: LISASMDCalcMethod2.H:41
Foam::constant::electromagnetic::e
const dimensionedScalar e
Elementary charge.
Definition: doubleFloat.H:94
Foam::fvMatrix
A special matrix type and solver, designed for finite volume solutions of scalar equations....
Definition: fvPatchField.H:68
Foam::readLabel
label readLabel(Istream &is)
Definition: label.H:64
Foam::GeometricField::replace
void replace(const direction, const GeometricField< cmptType, PatchField, GeoMesh > &)
Foam::quaternion::R
tensor R() const
The rotation tensor corresponding the quaternion.
Definition: quaternionI.H:235
Foam::tr
dimensionedScalar tr(const dimensionedSphericalTensor &dt)
Definition: dimensionedSphericalTensor.C:49
Foam::C
Graphite solid properties.
Definition: C.H:57
Foam::GeometricField
Generic GeometricField class.
Definition: surfaceFieldsFwd.H:52
Foam::defineTypeNameAndDebug
defineTypeNameAndDebug(combustionModel, 0)
Foam::twoSymm
dimensionedSymmTensor twoSymm(const dimensionedSymmTensor &dt)
Definition: dimensionedSymmTensor.C:93
lambda
dimensionedScalar lambda(laminarTransport.lookup("lambda"))
Foam::asin
dimensionedScalar asin(const dimensionedScalar &ds)
Definition: dimensionedScalar.C:258
fvcSmooth.H
Provides functions smooth spread and sweep which use the FaceCellWave algorithm to smooth and redistr...
lookup
stressControl lookup("compactNormalStress") >> compactNormalStress
Foam::degToRad
scalar degToRad(const scalar deg)
Conversion from degrees to radians.
Definition: unitConversion.H:45
Foam::fvc::smooth
void smooth(volScalarField &field, const scalar coeff)
Definition: fvcSmooth.C:35
Foam::cos
dimensionedScalar cos(const dimensionedScalar &ds)
Definition: dimensionedScalar.C:256