1 /*---------------------------------------------------------------------------*\
3 \\ / F ield | foam-extend: Open Source CFD
4 \\ / O peration | Version: 3.2
5 \\ / A nd | Web: http://www.foam-extend.org
6 \\/ M anipulation | For copyright notice see file Copyright
7 -------------------------------------------------------------------------------
9 This file is part of foam-extend.
11 foam-extend is free software: you can redistribute it and/or modify it
12 under the terms of the GNU General Public License as published by the
13 Free Software Foundation, either version 3 of the License, or (at your
14 option) any later version.
16 foam-extend is distributed in the hope that it will be useful, but
17 WITHOUT ANY WARRANTY; without even the implied warranty of
18 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
19 General Public License for more details.
21 You should have received a copy of the GNU General Public License
22 along with foam-extend. If not, see <http://www.gnu.org/licenses/>.
26 \*---------------------------------------------------------------------------*/
28 #include "contactPatchPair.H"
29 #include "contactProblem.H"
30 #include "surfaceFields.H"
32 // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
34 // Construct from components
35 Foam::contactPatchPair::contactPatchPair
38 const contactProblem& cp,
39 const word& masterPatchName,
40 const word& slavePatchName,
41 const dimensionedScalar& frictionCoeff,
42 const scalar contactTol,
43 const intersection::algorithm alg,
44 const intersection::direction dir
49 masterPatch_(masterPatchName, cp.mesh().boundaryMesh()),
50 slavePatch_(slavePatchName, cp.mesh().boundaryMesh()),
51 frictionCoeff_(frictionCoeff),
52 contactTol_(contactTol),
55 cp.mesh().boundaryMesh()[masterPatch_.index()]
59 cp.mesh().boundaryMesh()[slavePatch_.index()]
61 masterToSlaveInterpolate_
63 cp.mesh().boundaryMesh()[masterPatch_.index()], // from patch
64 cp.mesh().boundaryMesh()[slavePatch_.index()], // to patch
68 slaveToMasterInterpolate_
70 cp.mesh().boundaryMesh()[slavePatch_.index()], // from patch
71 cp.mesh().boundaryMesh()[masterPatch_.index()], // to patch
78 // Construct from dictionary
79 Foam::contactPatchPair::contactPatchPair
82 const contactProblem& cp,
83 const dictionary& dict
88 masterPatch_(dict.lookup("masterPatch"), cp.mesh().boundaryMesh()),
89 slavePatch_(dict.lookup("slavePatch"), cp.mesh().boundaryMesh()),
90 frictionCoeff_(dict.lookup("frictionCoeff")),
91 contactTol_(readScalar(dict.lookup("contactTol"))),
94 cp.mesh().boundaryMesh()[masterPatch_.index()]
98 cp.mesh().boundaryMesh()[slavePatch_.index()]
100 masterToSlaveInterpolate_
102 cp.mesh().boundaryMesh()[masterPatch_.index()], // from patch
103 cp.mesh().boundaryMesh()[slavePatch_.index()], // to patch
104 intersection::algorithmNames_.read(dict.lookup("projectionAlgo")),
105 intersection::directionNames_.read(dict.lookup("projectionDir"))
108 slaveToMasterInterpolate_
110 cp.mesh().boundaryMesh()[slavePatch_.index()], // from patch
111 cp.mesh().boundaryMesh()[masterPatch_.index()], // to patch
112 intersection::algorithmNames_.read(dict.lookup("projectionAlgo")),
113 intersection::directionNames_.read(dict.lookup("projectionDir"))
119 // * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * //
122 // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
124 Foam::tmp<Foam::scalarField>
125 Foam::contactPatchPair::masterTouchFraction() const
127 // Get reference to displacement field and mesh
128 const volVectorField& U = cp_.U();
129 const fvMesh& mesh = cp_.mesh();
131 // Interpolate slave displacement into master vertices
132 vectorField masterVertexU =
133 slaveToMasterInterpolate_.pointInterpolate<vector>
135 slaveInterpolate_.faceToPointInterpolate
137 U.boundaryField()[slavePatch_.index()]
141 const vectorField& projectionDir =
142 mesh.boundaryMesh()[masterPatch_.index()].pointNormals();
145 // Calculate master gap function
146 scalarField vertexMasterGap =
150 - masterInterpolate_.faceToPointInterpolate
152 U.boundaryField()[masterPatch_.index()]
156 ) + slaveToMasterInterpolate_.pointDistanceToIntersection() - contactTol_;
158 // Calculate area in contact
160 const faceList& masterPatchLocalFaces =
161 mesh.boundaryMesh()[masterPatch_.index()].localFaces();
163 const pointField& masterPatchLocalPoints =
164 mesh.boundaryMesh()[masterPatch_.index()].localPoints();
166 tmp<scalarField> ttouchFrac
168 new scalarField(masterPatchLocalFaces.size(), 0)
170 scalarField& touchFrac = ttouchFrac();
172 forAll (masterPatchLocalFaces, faceI)
175 masterPatchLocalFaces[faceI].areaInContact
177 masterPatchLocalPoints,
186 Foam::tmp<Foam::scalarField>
187 Foam::contactPatchPair::slaveTouchFraction() const
189 // Get reference to displacement field and mesh
190 const volVectorField& U = cp_.U();
191 const fvMesh& mesh = cp_.mesh();
193 // Interpolate master displacement into slave vertices
194 vectorField slaveVertexU =
195 masterToSlaveInterpolate_.pointInterpolate<vector>
197 masterInterpolate_.faceToPointInterpolate
199 U.boundaryField()[masterPatch_.index()]
203 const vectorField& projectionDir =
204 mesh.boundaryMesh()[slavePatch_.index()].pointNormals();
207 // Calculate slave gap function
208 scalarField vertexSlaveGap =
212 - slaveInterpolate_.faceToPointInterpolate
214 U.boundaryField()[slavePatch_.index()]
218 ) + masterToSlaveInterpolate_.pointDistanceToIntersection() - contactTol_;
220 // Calculate area in contact
222 const faceList& slavePatchLocalFaces =
223 mesh.boundaryMesh()[slavePatch_.index()].localFaces();
225 const pointField& slavePatchLocalPoints =
226 mesh.boundaryMesh()[slavePatch_.index()].localPoints();
228 tmp<scalarField> ttouchFrac
230 new scalarField(slavePatchLocalFaces.size(), 0)
232 scalarField& touchFrac = ttouchFrac();
234 forAll (slavePatchLocalFaces, faceI)
237 slavePatchLocalFaces[faceI].areaInContact
239 slavePatchLocalPoints,
248 void Foam::contactPatchPair::correct
250 const FieldField<Field, vector>& curTraction,
251 FieldField<Field, vector>& newTraction,
252 FieldField<Field, vector>& refValue,
253 FieldField<Field, scalar>& valueFraction
256 // Get reference to displacement field and mesh
257 const volVectorField::GeometricBoundaryField& Upatches =
258 cp_.U().boundaryField();
260 const fvMesh& mesh = cp_.mesh();
261 const surfaceVectorField::GeometricBoundaryField& Apatches =
262 mesh.Sf().boundaryField();
263 const surfaceScalarField::GeometricBoundaryField& magApatches =
264 mesh.magSf().boundaryField();
267 const label masterIndex = masterPatch_.index();
268 const label slaveIndex = slavePatch_.index();
270 // Calculate patch normals
271 vectorField nMasterPatch = Apatches[masterIndex]/magApatches[masterIndex];
273 vectorField nSlavePatch = Apatches[slaveIndex]/magApatches[slaveIndex];
276 // Calculate slave pressure and tangential force
278 scalarField slavePressure = -( nSlavePatch & curTraction[slaveIndex]);
280 // Enforce gradient condition on the master patch
282 // Calculate relative tangential velocity for master patch
283 vectorField relUmaster =
284 slaveToMasterInterpolate_.faceInterpolate<vector>
288 - Upatches[masterIndex];
290 relUmaster -= nMasterPatch*(nMasterPatch & relUmaster);
291 relUmaster /= mag(relUmaster) + VSMALL;
293 // Calculate tangential master traction
294 scalarField magMasterTangential =
295 Foam::mag((I - nMasterPatch*nMasterPatch) & curTraction[masterIndex]);
297 // Calculate master pressure
298 scalarField masterPressure =
301 slaveToMasterInterpolate_.faceInterpolate<scalar>
308 // Calculate master traction, using the positive part of
309 // slave pressure and tangential fricton
310 // Mind the signs: pressure = negative gradient (minus master normal)
311 // friction = positive pressure
312 newTraction[masterIndex] +=
313 masterTouchFraction()*
315 -nMasterPatch*masterPressure
319 frictionCoeff_.value()*masterPressure,
324 // Enforce direction mixed condition on the slave patch
326 // Calculate slave fraction. Correct for negative pressure
327 // (if the pressure is negative, the contact is released)
328 //HJ, fiddle pos pressure!!!
329 scalarField slaveFrac = slaveTouchFraction();
331 // Calculate slave displacement
332 vectorField slaveVertexU =
333 masterToSlaveInterpolate_.pointInterpolate<vector>
335 masterInterpolate_.faceToPointInterpolate
337 Upatches[masterIndex]
341 const vectorField& projectionDir =
342 mesh.boundaryMesh()[slaveIndex].pointNormals();
344 // Calculate slave displacement
345 vectorField slaveDisp =
346 slaveInterpolate_.pointToFaceInterpolate
349 + masterToSlaveInterpolate_.pointDistanceToIntersection()
353 // Accumulate normal of slave displacement
354 refValue[slaveIndex] +=
360 (nSlavePatch & Upatches[slaveIndex])
361 + slaveFrac*contactTol_
363 (nSlavePatch & slaveDisp)
367 // Accumulate slave friction
369 // Calculate relative tangential velocity for slave patch
370 vectorField relUslave =
371 masterToSlaveInterpolate_.faceInterpolate<vector>
373 Upatches[masterIndex]
375 - Upatches[slaveIndex];
377 relUslave -= nSlavePatch*(nSlavePatch & relUslave);
378 relUslave /= mag(relUslave) + VSMALL;
380 // Take out normal component out of slave traction and find the
381 // magnitude of the tangential traction.
382 scalarField magSlaveTangential =
383 Foam::mag((I - nSlavePatch*nSlavePatch) & curTraction[slaveIndex]);
385 // Calculate slave traction
386 newTraction[slaveIndex] +=
390 frictionCoeff_.value()*max(slavePressure, scalar(0)),
394 // Accumulate slave touch fraction
395 valueFraction[slaveIndex] += slaveFrac;
398 Info << "slavePressure: " << slavePressure << nl
399 << "slaveTouchFrac: " << slaveTouchFraction() << nl
400 // << "slaveFrac: " << slaveFrac << nl
401 << "refValueSlave: " << refValue[slaveIndex].component(vector::Y) << nl
402 // << "slaveTraction: " << newTraction[slaveIndex] << nl
403 << "masterTouchFrac: " << masterTouchFraction() << nl
404 // << "interpolated slave pressure: "
405 // << slaveToMasterInterpolate_.faceInterpolate<scalar>
410 // << "masterTraction: "
411 // << newTraction[masterIndex].component(vector::Y)
417 void Foam::contactPatchPair::writeDict(Ostream& os) const
419 os << nl << name() << nl << token::BEGIN_BLOCK;
421 os << "masterPatch " << masterPatch_.name() << token::END_STATEMENT << nl
422 << "slavePatch " << slavePatch_.name() << token::END_STATEMENT << nl
423 << "frictionCoeff " << frictionCoeff_ << token::END_STATEMENT << nl
424 << "contactTol " << contactTol_ << token::END_STATEMENT << nl
426 << intersection::algorithmNames_
427 [masterToSlaveInterpolate_.projectionAlgo()]
428 << token::END_STATEMENT << nl
430 << intersection::directionNames_
431 [masterToSlaveInterpolate_.projectionDir()]
432 << token::END_STATEMENT << nl
433 << token::END_BLOCK << endl;
437 // * * * * * * * * * * * * * * * Member Operators * * * * * * * * * * * * * //
440 // * * * * * * * * * * * * * * * Friend Functions * * * * * * * * * * * * * //
443 // * * * * * * * * * * * * * * * Friend Operators * * * * * * * * * * * * * //
446 // ************************************************************************* //