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/>.
25 Class describes a multiple body contact problem. Each individual contact
26 is described by a contactPatchPair. contactProblem handles
27 multiple contact updates and sets the boundary conditions on the
30 \*---------------------------------------------------------------------------*/
32 #include "contactProblem.H"
34 #include "FieldFields.H"
35 #include "directionMixedFvPatchFields.H"
36 #include "surfaceFields.H"
38 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
43 // * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
45 defineTypeNameAndDebug(contactProblem, 0);
47 // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
49 // Read constructor given IOobject
50 contactProblem::contactProblem
53 const volTensorField& gradU
67 contactPatchPairList(),
70 urfValue_(readScalar(lookup("urfValue"))),
71 urfTraction_(readScalar(lookup("urfTraction"))),
72 urfFraction_(readScalar(lookup("urfFraction")))
74 // Read contactPatchPairList
75 Istream& is = lookup("contacts");
77 PtrList<entry> contactEntries(is);
79 contactPatchPairList& contacts = *this;
81 contacts.setSize(contactEntries.size());
83 forAll(contacts, contactI)
90 contactEntries[contactI].keyword(),
92 contactEntries[contactI].dict()
99 // * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * //
102 // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
104 void contactProblem::correct()
106 contactPatchPairList& contacts = *this;
108 // Create fields for accumulation
109 volVectorField::GeometricBoundaryField& Upatches = U().boundaryField();
111 FieldField<Field, vector> curTraction(Upatches.size());
112 FieldField<Field, vector> newTraction(Upatches.size());
113 FieldField<Field, vector> refValue(Upatches.size());
114 FieldField<Field, scalar> valueFraction(Upatches.size());
116 forAll (Upatches, patchI)
121 new vectorField(Upatches[patchI].size(), vector::zero)
127 new vectorField(Upatches[patchI].size(), vector::zero)
133 new vectorField(Upatches[patchI].size(), vector::zero)
139 new scalarField(Upatches[patchI].size(), 0)
143 // Collect patches involved in contact
144 boolList contactPatches(Upatches.size(), false);
146 forAll (contacts, contactI)
148 contactPatches[contacts[contactI].masterPatch().index()] = true;
149 contactPatches[contacts[contactI].slavePatch().index()] = true;
152 // Calculate the traction for all involved patches
155 const volTensorField::GeometricBoundaryField& gradUpatches =
156 gradU().boundaryField();
158 const surfaceVectorField::GeometricBoundaryField& Apatches =
159 mesh().Sf().boundaryField();
160 const surfaceScalarField::GeometricBoundaryField& magApatches =
161 mesh().magSf().boundaryField();
163 // Lookup mu and lambda form object registry
164 const volScalarField& mu =
165 mesh().objectRegistry::lookupObject<volScalarField>("mu");
167 const volScalarField::GeometricBoundaryField& muPatches =
170 const volScalarField& lambda =
171 mesh().objectRegistry::lookupObject<volScalarField>("lambda");
173 const volScalarField::GeometricBoundaryField& lambdaPatches =
174 lambda.boundaryField();
176 forAll (Upatches, patchI)
178 if (contactPatches[patchI])
180 vectorField nPatch = Apatches[patchI]/magApatches[patchI];
182 curTraction[patchI] =
188 + gradUpatches[patchI].T()
190 + I*(lambdaPatches[patchI]*tr(gradUpatches[patchI]))
195 // Accumulate contact data and active patches
196 forAll (contacts, contactI)
198 contacts[contactI].correct
207 // Enforce accumulated contact onto the patches
208 forAll (Upatches, patchI)
210 if (contactPatches[patchI])
212 // Cast the patch into direction mixed type
213 directionMixedFvPatchVectorField& curUPatch =
214 refCast<directionMixedFvPatchVectorField>(Upatches[patchI]);
216 // Set the values using under-relaxation
217 curUPatch.refValue() =
218 (1.0 - urfValue_)*curUPatch.refValue()
219 + urfValue_*refValue[patchI];
221 // Calculate the gradient from under-relaxad accumulated traction
222 vectorField nPatch = Apatches[patchI]/magApatches[patchI];
224 curUPatch.refGrad() =
226 (1.0 - urfTraction_)*curTraction[patchI]
227 + urfTraction_*newTraction[patchI]
231 muPatches[patchI]*gradUpatches[patchI].T()
234 + lambdaPatches[patchI]
235 )*gradUpatches[patchI]
241 lambdaPatches[patchI]*tr(gradUpatches[patchI])
244 )/(2.0*muPatches[patchI] + lambdaPatches[patchI]);
246 // Set the value fractions
247 curUPatch.valueFraction() =
248 (1.0 - urfFraction_)*curUPatch.valueFraction()
249 + I*urfFraction_*valueFraction[patchI];
255 tmp<volScalarField> contactProblem::contactArea() const
257 tmp<volScalarField> tca
264 U().time().timeName(),
274 volScalarField& ca = tca();
276 // Set contact area boundary
277 const contactPatchPairList& contacts = *this;
279 forAll (contacts, contactI)
281 // Get master contact
282 ca.boundaryField()[contacts[contactI].masterPatch().index()] +=
283 contacts[contactI].masterTouchFraction();
286 ca.boundaryField()[contacts[contactI].slavePatch().index()] +=
287 contacts[contactI].slaveTouchFraction();
294 // Return a list of contactPatchPair names
295 wordList contactProblem::names() const
297 const contactPatchPairList& contacts = *this;
299 wordList t(contacts.size());
301 forAll (contacts, contactI)
303 t[contactI] = contacts[contactI].name();
310 bool contactProblem::read()
312 if (regIOobject::read())
314 urfValue_ = readScalar(lookup("urfValue"));
315 urfTraction_ = readScalar(lookup("urfTraction"));
316 urfFraction_ = readScalar(lookup("urfFraction"));
318 // Decided not to re-read contactPatchPairList. HJ, 10/Jul/2004
328 // * * * * * * * * * * * * * * * IOstream Operators * * * * * * * * * * * * //
331 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
333 } // End namespace Foam
335 // ************************************************************************* //