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/>.
24 \*---------------------------------------------------------------------------*/
26 #include "solidCohesiveFixedModeMixFvPatchVectorField.H"
27 #include "addToRunTimeSelectionTable.H"
28 #include "volFields.H"
29 #include "constitutiveModel.H"
30 #include "regionSplit.H"
31 #include "crackerFvMesh.H"
33 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
38 // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
40 solidCohesiveFixedModeMixFvPatchVectorField::
41 solidCohesiveFixedModeMixFvPatchVectorField
44 const DimensionedField<vector, volMesh>& iF
47 directionMixedFvPatchVectorField(p, iF),
48 fieldName_("undefined"),
49 relaxationFactor_(1.0),
50 traction_(p.size(), vector::zero),
51 initiationTraction_(p.size(), vector::zero),
52 separationDistance_(p.size(), vector::zero),
53 oldSeparationDistance_(p.size(), vector::zero),
54 unloadingSeparationDistance_(p.size(), vector::zero),
55 minUnloadingSeparationDistance_(0.0),
57 explicitSeparationDistance_(false),
64 solidCohesiveFixedModeMixFvPatchVectorField::
65 solidCohesiveFixedModeMixFvPatchVectorField
68 const DimensionedField<vector, volMesh>& iF,
69 const dictionary& dict
72 directionMixedFvPatchVectorField(p, iF),
73 fieldName_(dimensionedInternalField().name()),
74 relaxationFactor_(readScalar(dict.lookup("relaxationFactor"))),
75 traction_(p.size(), vector::zero),
76 initiationTraction_(p.size(), vector::zero),
77 separationDistance_(p.size(), vector::zero),
78 oldSeparationDistance_(p.size(), vector::zero),
79 unloadingSeparationDistance_(p.size(), vector::zero),
80 minUnloadingSeparationDistance_
82 readScalar(dict.lookup("minUnloadingSeparationDistance"))
84 beta_(readScalar(dict.lookup("beta"))),
85 explicitSeparationDistance_(dict.lookup("explicitSeparationDistance")),
86 contact_(dict.lookup("contact")),
87 contactConstant_(readScalar(dict.lookup("contactConstant"))),
90 Info << "Creating solidCohesiveFixedModeMix boundary condition for "
91 << patch().name() << " patch" << nl
92 << "NOTE: this method only uses sigmaMax and GIc from "
93 << "cohesiveProperties; tauMax and GIIc are ignored!"
96 if (minUnloadingSeparationDistance_ < 0.001)
98 minUnloadingSeparationDistance_ = 0.001;
101 if (minUnloadingSeparationDistance_ > 1.0)
103 minUnloadingSeparationDistance_ = 1.0;
106 Info << "minUnloadingSeparationDistance: "
107 << minUnloadingSeparationDistance_ << endl;
109 // if (beta_ < (1 - SMALL))
118 Info << "beta: " << beta_ << endl;
120 if (dict.found("refValue"))
122 this->refValue() = vectorField("refValue", dict, p.size());
126 this->refValue() = vector::zero;
129 if (dict.found("refGradient"))
131 this->refGrad() = vectorField("refGradient", dict, p.size());
135 this->refGrad() = vector::zero;
138 if (dict.found("valueFraction"))
140 this->valueFraction() =
141 symmTensorField("valueFraction", dict, p.size());
145 this->valueFraction() = symmTensor::zero;
148 if (dict.found("value"))
150 vectorField::operator=(vectorField("value", dict, p.size()));
154 vectorField normalValue = transform(valueFraction(), refValue());
156 vectorField gradValue =
157 this->patchInternalField() + refGrad()/this->patch().deltaCoeffs();
159 vectorField transformGradValue =
160 transform(I - valueFraction(), gradValue);
162 vectorField::operator=(normalValue + transformGradValue);
165 if (dict.found("traction"))
168 vectorField("traction", dict, p.size());
171 if (dict.found("initiationTraction"))
173 initiationTraction_ =
174 vectorField("initiationTraction", dict, p.size());
177 if (dict.found("separationDistance"))
179 separationDistance_ =
180 vectorField("separationDistance", dict, p.size());
183 if (dict.found("oldSeparationDistance"))
185 separationDistance_ =
186 vectorField("oldSeparationDistance", dict, p.size());
189 if (dict.found("unloadingSeparationDistance"))
191 unloadingSeparationDistance_ =
192 vectorField("unloadingSeparationDistance", dict, p.size());
197 solidCohesiveFixedModeMixFvPatchVectorField::
198 solidCohesiveFixedModeMixFvPatchVectorField
200 const solidCohesiveFixedModeMixFvPatchVectorField& cpf
203 directionMixedFvPatchVectorField(cpf),
204 fieldName_(cpf.fieldName_),
205 relaxationFactor_(cpf.relaxationFactor_),
206 traction_(cpf.traction_),
207 initiationTraction_(cpf.initiationTraction_),
208 separationDistance_(cpf.separationDistance_),
209 oldSeparationDistance_(cpf.oldSeparationDistance_),
210 unloadingSeparationDistance_(cpf.unloadingSeparationDistance_),
211 minUnloadingSeparationDistance_(cpf.minUnloadingSeparationDistance_),
213 explicitSeparationDistance_(cpf.explicitSeparationDistance_),
214 contact_(cpf.contact_),
215 contactConstant_(cpf.contactConstant_),
220 solidCohesiveFixedModeMixFvPatchVectorField::
221 solidCohesiveFixedModeMixFvPatchVectorField
223 const solidCohesiveFixedModeMixFvPatchVectorField& cpf,
225 const DimensionedField<vector, volMesh>& iF,
226 const fvPatchFieldMapper& mapper
229 directionMixedFvPatchVectorField(cpf, p, iF, mapper),
230 fieldName_(cpf.fieldName_),
231 relaxationFactor_(cpf.relaxationFactor_),
232 traction_(cpf.traction_, mapper),
233 initiationTraction_(cpf.initiationTraction_, mapper),
234 separationDistance_(cpf.separationDistance_, mapper),
235 oldSeparationDistance_(cpf.oldSeparationDistance_, mapper),
236 unloadingSeparationDistance_(cpf.unloadingSeparationDistance_, mapper),
237 minUnloadingSeparationDistance_(cpf.minUnloadingSeparationDistance_),
239 explicitSeparationDistance_(cpf.explicitSeparationDistance_),
240 contact_(cpf.contact_),
241 contactConstant_(cpf.contactConstant_),
246 solidCohesiveFixedModeMixFvPatchVectorField::
247 solidCohesiveFixedModeMixFvPatchVectorField
249 const solidCohesiveFixedModeMixFvPatchVectorField& cpf,
250 const DimensionedField<vector, volMesh>& iF
253 directionMixedFvPatchVectorField(cpf, iF),
254 fieldName_(cpf.fieldName_),
255 relaxationFactor_(cpf.relaxationFactor_),
256 traction_(cpf.traction_),
257 initiationTraction_(cpf.initiationTraction_),
258 separationDistance_(cpf.separationDistance_),
259 oldSeparationDistance_(cpf.oldSeparationDistance_),
260 unloadingSeparationDistance_(cpf.unloadingSeparationDistance_),
261 minUnloadingSeparationDistance_(cpf.minUnloadingSeparationDistance_),
263 explicitSeparationDistance_(cpf.explicitSeparationDistance_),
264 contact_(cpf.contact_),
265 contactConstant_(cpf.contactConstant_),
270 // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
274 solidCohesiveFixedModeMixFvPatchVectorField::relativeSeparationDistance() const
276 tmp<scalarField> tRelativeSeparationDistance
278 new scalarField(size(), 0.0)
281 vectorField n = patch().nf();
283 const constitutiveModel& rheology =
284 this->db().objectRegistry::lookupObject<constitutiveModel>
285 ("rheologyProperties");
286 label patchID = patch().index();
287 const scalarField sigmaMax =
288 rheology.cohLaw().sigmaMax()().boundaryField()[patchID];
289 const scalarField GIc = rheology.cohLaw().GIc()().boundaryField()[patchID];
290 const scalarField deltaC = GIc/sigmaMax;
291 int numCrackedFaces = 0;
293 for (label i=0; i<size(); i++)
296 separationDistance_[i];
298 if (mag(n[i]&curSepDist) < 0)
300 curSepDist -= n[i]*(n[i]&curSepDist);
303 tRelativeSeparationDistance()[i] =
304 // mag(curSepDist)/law().deltaC().value();
305 mag(curSepDist)/deltaC[i];
307 if (tRelativeSeparationDistance()[i] > 1.0) numCrackedFaces++;
310 Info<< "Relative separation distance, max: "
311 << gMax(tRelativeSeparationDistance())
312 << ", avr: " << gAverage(tRelativeSeparationDistance())
313 << ", min: " << gMin(tRelativeSeparationDistance())
314 << ", numCrackedFaces: " << numCrackedFaces << endl;
316 return tRelativeSeparationDistance;
320 void solidCohesiveFixedModeMixFvPatchVectorField::autoMap
322 const fvPatchFieldMapper& m
325 // if (cohesiveLawPtr_ == NULL)
327 // FatalErrorIn("cohesiveFvPatchVectorField::autoMap")
328 // << "NULL cohesive law"
329 // << abort(FatalError);
332 directionMixedFvPatchVectorField::autoMap(m);
334 traction_.autoMap(m);
335 initiationTraction_.autoMap(m);
336 separationDistance_.autoMap(m);
337 oldSeparationDistance_.autoMap(m);
338 unloadingSeparationDistance_.autoMap(m);
340 // Must use primitive mesh data because fvMesh data is packed in fields
341 // and cannot be accessed during mapping. HJ, 12/Dec/2008
342 vectorField n = patch().patch().faceNormals();
344 const labelList& addressing = m.directAddressing();
346 label nNewFaces = m.size() - m.sizeBeforeMapping();
348 if ( (patch().size()==1) && (nNewFaces == 1) )
351 this->valueFraction()[i] = symmTensor::zero;
352 traction_[i] = vector::zero; // set in solver
353 initiationTraction_[i] = vector::zero; // set in solver
354 separationDistance_[i] = vector::zero;
355 oldSeparationDistance_[i] = vector::zero;
356 unloadingSeparationDistance_[i] = vector::zero;
358 else if ( (patch().size()==2) && (nNewFaces == 1) )
361 this->valueFraction()[i] = symmTensor::zero;
362 traction_[i] = vector::zero; //law().sigmaMax().value()*n[i];
363 initiationTraction_[i] = vector::zero; //law().sigmaMax().value()*n[i];
364 separationDistance_[i] = vector::zero;
365 oldSeparationDistance_[i] = vector::zero;
366 unloadingSeparationDistance_[i] = vector::zero;
368 else if ( (patch().size()==2) && (nNewFaces == 2) )
371 this->valueFraction()[i] = symmTensor::zero;
372 traction_[i] = vector::zero; //law().sigmaMax().value()*n[i];
373 initiationTraction_[i] = vector::zero; //law().sigmaMax().value()*n[i];
374 separationDistance_[i] = vector::zero;
375 oldSeparationDistance_[i] = vector::zero;
376 unloadingSeparationDistance_[i] = vector::zero;
378 this->valueFraction()[i] = symmTensor::zero;
379 traction_[i] = vector::zero; //law().sigmaMax().value()*n[i];
380 initiationTraction_[i] = vector::zero; //law().sigmaMax().value()*n[i];
381 separationDistance_[i] = vector::zero;
382 oldSeparationDistance_[i] = vector::zero;
383 unloadingSeparationDistance_[i] = vector::zero;
387 for (label i = 1; i < patch().size(); i++)
389 if (addressing[i] == 0)
391 //Info << "correcting automap for face " << i << " to zero" << endl;
392 this->valueFraction()[i] = symmTensor::zero;
393 traction_[i] = vector::zero; //law().sigmaMax().value()*n[i];
394 initiationTraction_[i] = vector::zero;
395 separationDistance_[i] = vector::zero;
396 oldSeparationDistance_[i] = vector::zero;
397 unloadingSeparationDistance_[i] = vector::zero;
402 // label sizeByTwo = patch().size()/2;
403 // for (label i = 0; i < sizeByTwo; i++)
405 // if (addressing[i] == addressing[sizeByTwo + i])
407 // this->valueFraction()[i] = symmTensor::zero;
408 // this->valueFraction()[sizeByTwo + i] = symmTensor::zero;
410 // traction_[i] = law().sigmaMax().value()*n[i];
411 // traction_[sizeByTwo + i] =
412 // law().sigmaMax().value()*n[sizeByTwo + i];
414 // initiationTraction_[i] = law().sigmaMax().value()*n[i];
415 // initiationTraction_[sizeByTwo + i] =
416 // law().sigmaMax().value()*n[sizeByTwo + i];
418 // separationDistance_[i] = vector::zero;
419 // separationDistance_[sizeByTwo + i] = vector::zero;
421 // oldSeparationDistance_[i] = vector::zero;
422 // oldSeparationDistance_[sizeByTwo + i] = vector::zero;
424 // unloadingSeparationDistance_[i] = vector::zero;
425 // unloadingSeparationDistance_[sizeByTwo + i] = vector::zero;
431 // Reverse-map the given fvPatchField onto this fvPatchField
432 void solidCohesiveFixedModeMixFvPatchVectorField::rmap
434 const fvPatchVectorField& ptf,
435 const labelList& addr
438 directionMixedFvPatchVectorField::rmap(ptf, addr);
440 const solidCohesiveFixedModeMixFvPatchVectorField& dmptf =
441 refCast<const solidCohesiveFixedModeMixFvPatchVectorField>(ptf);
443 // No need to grab the cohesive zone pointer more than once
444 // if (!cohesiveLawPtr_)
446 // cohesiveLawPtr_ = dmptf.cohesiveLawPtr_->clone().ptr();
449 relaxationFactor_ = dmptf.relaxationFactor_;
450 traction_.rmap(dmptf.traction_, addr);
451 initiationTraction_.rmap(dmptf.initiationTraction_, addr);
452 separationDistance_.rmap(dmptf.separationDistance_, addr);
453 oldSeparationDistance_.rmap(dmptf.oldSeparationDistance_, addr);
454 unloadingSeparationDistance_.rmap
456 dmptf.unloadingSeparationDistance_,
459 minUnloadingSeparationDistance_ = dmptf.minUnloadingSeparationDistance_;
461 contact_ = dmptf.contact_;
462 contactConstant_ = dmptf.contactConstant_;
466 // Update the coefficients associated with the patch field
467 void solidCohesiveFixedModeMixFvPatchVectorField::updateCoeffs()
474 vectorField n = patch().nf();
476 // lookup cohesive law from rheology
477 // Note: this method only uses sigmaMax and GIc
478 // tauMax and GIIc are ignored
479 const constitutiveModel& rheology =
480 this->db().objectRegistry::lookupObject<constitutiveModel>
481 ("rheologyProperties");
482 label patchID = patch().index();
483 const scalarField sigmaMax =
484 rheology.cohLaw().sigmaMax()().boundaryField()[patchID];
485 //const scalarField tauMax =
486 // rheology.cohLaw().tauMax()().boundaryField()[patchID];
487 const scalarField GIc =
488 rheology.cohLaw().GIc()().boundaryField()[patchID];
489 //const scalarField GIIc =
490 // rheology.cohLaw().GIIc()().boundaryField()[patchID];
491 const scalarField deltaC = GIc/sigmaMax;
493 if (curTimeIndex_ != this->db().time().timeIndex())
495 forAll(unloadingSeparationDistance_, faceI)
498 separationDistance_[faceI];
500 if (explicitSeparationDistance_)
502 curSepDist = oldSeparationDistance_[faceI];
505 scalar curNormalSepDist = (n[faceI]&curSepDist);
507 if (curNormalSepDist < 0)
509 curSepDist -= n[faceI]*(n[faceI]&curSepDist);
510 curNormalSepDist = 0;
513 vector curTangentialSepDist =
514 ((I - n[faceI]*n[faceI])&curSepDist);
516 if (beta_ < SMALL) // Mode I
521 > minUnloadingSeparationDistance_*deltaC[faceI]
527 > mag(unloadingSeparationDistance_[faceI])
530 unloadingSeparationDistance_[faceI] =
531 curNormalSepDist*n[faceI];
535 else // Mixed mode I/II
537 scalar curEffSepDist =
540 sqr(curNormalSepDist)
541 + sqr(beta_)*magSqr(curTangentialSepDist)
547 > minUnloadingSeparationDistance_*deltaC[faceI]
553 > mag(unloadingSeparationDistance_[faceI])
556 unloadingSeparationDistance_[faceI] =
557 curNormalSepDist*n[faceI]
558 + beta_*curTangentialSepDist;
564 oldSeparationDistance_ = separationDistance_;
565 curTimeIndex_ = this->db().time().timeIndex();
568 // Get face cells regions
569 const unallocLabelList& faceCells = patch().faceCells();
571 const fvMesh& mesh = patch().boundaryMesh().mesh();
573 if (!isA<crackerFvMesh>(mesh))
577 "void solidCohesiveFixedModeMixFvPatchVectorField::"
578 "updateCoeffs() const"
579 ) << "Mesh should be of type: " << crackerFvMesh::typeName
580 << abort(FatalError);
583 const crackerFvMesh& crackerMesh = refCast<const crackerFvMesh>(mesh);
585 const regionSplit& regions = crackerMesh.regions();
587 labelField faceCellRegion(size(), -1);
588 forAll(faceCellRegion, faceI)
590 faceCellRegion[faceI] = regions[faceCells[faceI]];
592 labelField globalFaceCellRegion =
593 crackerMesh.globalCrackField(faceCellRegion);
595 // Looking up rheology
596 const fvPatchField<scalar>& mu =
597 patch().lookupPatchField<volScalarField, scalar>("mu");
598 const fvPatchField<scalar>& lambda =
599 patch().lookupPatchField<volScalarField, scalar>("lambda");
601 const fvPatchField<tensor>& gradU =
602 patch().lookupPatchField<volTensorField, tensor>("grad(U)");
604 // Patch displacement
605 const vectorField& UPatch = *this;
607 // Global displacement
608 vectorField globalUPatch = crackerMesh.globalCrackField(UPatch);
610 // Update separation distance
611 vectorField newSeparationDistance(patch().size(), vector::zero);
612 const labelList& gcfa = crackerMesh.globalCrackFaceAddressing();
613 label globalIndex = crackerMesh.localCrackStart();
614 for (label i = 0; i < patch().size(); i++)
616 newSeparationDistance[i] =
617 globalUPatch[gcfa[globalIndex]]
618 - globalUPatch[globalIndex];
623 // label sizeByTwo = patch().size()/2;
624 // for (label i = 0; i < sizeByTwo; i++)
626 // newSeparationDistance[i] = UPatch[sizeByTwo + i] - UPatch[i];
627 // newSeparationDistance[sizeByTwo + i] = -newSeparationDistance[i];
630 // newSeparationDistance =
631 // beta_*((I-n*n)&newSeparationDistance)
632 // + (n&newSeparationDistance)*n;
634 if (explicitSeparationDistance_)
636 separationDistance_ = newSeparationDistance;
640 separationDistance_ =
643 *(newSeparationDistance - separationDistance_);
646 // for (label i=0; i<sizeByTwo; i++)
647 globalIndex = crackerMesh.localCrackStart();
648 for (label i = 0; i < patch().size(); i++)
650 vector curSepDist = separationDistance_[i];
652 if (explicitSeparationDistance_)
654 curSepDist = oldSeparationDistance_[i];
657 scalar curNormalSepDist = (n[i]&curSepDist);
658 scalar curNegNormalSepDist = 0;
660 if (curNormalSepDist < 0)
662 curSepDist -= n[i]*(n[i]&curSepDist);
663 curNegNormalSepDist = curNormalSepDist;
664 curNormalSepDist = 0;
667 vector curTangentialSepDist =
668 ((I - n[i]*n[i])&curSepDist);
670 scalar curNormalTraction = 0;
671 vector curTangentialTraction = vector::zero;
673 // if (faceCellRegion[i] == faceCellRegion[sizeByTwo+i])
676 globalFaceCellRegion[globalIndex]
677 == globalFaceCellRegion[gcfa[globalIndex]]
682 // Mode II or Mixed mode I/II
684 scalar curEffSepDist =
687 sqr(curNormalSepDist)
688 + sqr(beta_)*mag(curTangentialSepDist)
694 > (mag(unloadingSeparationDistance_[i]) - SMALL)
699 if (curEffSepDist > deltaC[i])
701 curNormalTraction = 0.0;
702 curTangentialTraction = vector::zero;
706 curNormalTraction = (n[i]&initiationTraction_[i]);
707 curTangentialTraction =
708 ((I - n[i]*n[i])&initiationTraction_[i]);
711 // scale traction based on cohesive law
712 // Not needed for Dugdale as traction stays at initiation value
713 // if (curNormalTraction >= 0)
717 // curNormalTraction *=
719 // // law().traction(curEffSepDist)
720 // // /law().sigmaMax().value();
722 // curTangentialTraction *=
724 // // law().traction(curEffSepDist)
725 // // /law().sigmaMax().value();
731 // curTangentialTraction *=
732 // law().traction(curEffSepDist)
733 // /law().sigmaMax().value();
740 scalar unloadingNormalTraction =
741 (n[i]&initiationTraction_[i]);
742 vector unloadingTangentialTraction =
743 ((I - n[i]*n[i])&initiationTraction_[i]);
745 if (unloadingNormalTraction >= 0)
747 // scaling not needed for Dugdale
748 // unloadingNormalTraction *=
751 // mag(unloadingSeparationDistance_[i])
753 // /law().sigmaMax().value();
755 // unloadingTangentialTraction *=
758 // mag(unloadingSeparationDistance_[i])
760 // /law().sigmaMax().value();
763 unloadingNormalTraction
766 /mag(unloadingSeparationDistance_[i])
769 curTangentialTraction =
770 unloadingTangentialTraction
773 /mag(unloadingSeparationDistance_[i])
778 // scaling not needed for Dugdale
779 // unloadingTangentialTraction *=
782 // mag(unloadingSeparationDistance_[i])
784 // /law().sigmaMax().value();
786 curTangentialTraction =
787 unloadingTangentialTraction
790 /mag(unloadingSeparationDistance_[i])
793 curNormalTraction = unloadingNormalTraction;
804 > (mag(unloadingSeparationDistance_[i]) - SMALL)
809 if (curNormalSepDist > deltaC[i])
811 curNormalTraction = 0.0;
812 curTangentialTraction = vector::zero;
817 (n[i]&initiationTraction_[i]);
819 curTangentialTraction =
820 ((I - n[i]*n[i])&initiationTraction_[i]);
823 // scaling not needed for Dugdale
824 // curNormalTraction *=
825 // law().traction(curNormalSepDist)
826 // /law().sigmaMax().value();
828 // scaling not needed for Dugdale
829 // curTangentialTraction *=
830 // law().traction(curNormalSepDist)
831 // /law().sigmaMax().value();
837 scalar unloadingNormalTraction =
838 (n[i]&initiationTraction_[i]);
839 // scaling not needed for Dugdale
840 //*law().traction(mag(unloadingSeparationDistance_[i]))
841 ///law().sigmaMax().value();
843 vector unloadingTangentialTraction =
844 ((I - n[i]*n[i])&initiationTraction_[i]);
845 // scaling not needed for Dugdale
846 // *law().traction(mag(unloadingSeparationDistance_[i]))
847 // /law().sigmaMax().value();
850 unloadingNormalTraction
853 /mag(unloadingSeparationDistance_[i])
856 // if (curNegNormalSepDist < 0)
858 // curNormalTraction =
859 // unloadingNormalTraction
861 // curNegNormalSepDist
862 // /mag(unloadingSeparationDistance_[i])
866 curTangentialTraction =
867 unloadingTangentialTraction
870 /mag(unloadingSeparationDistance_[i])
876 // Correct direction of tangential traction
877 // to be aligned with tangential separation distance
878 if (mag(curTangentialSepDist) > SMALL)
880 curTangentialTraction =
881 mag(curTangentialTraction)
882 *curTangentialSepDist
883 /mag(curTangentialSepDist);
887 if (contact_ && (curNegNormalSepDist < 0))
890 (1.0/(1.0-contactConstant_))
891 *sigmaMax[i]/deltaC[i];
892 // *law().sigmaMax().value()
893 ///law().deltaC().value();
895 curNormalTraction = m*curNegNormalSepDist;
897 // Info << "Contact: " << curNegNormalSepDist/law().deltaC().value()
898 // << ", " << curNormalTraction << endl;
899 //Info << "Contact: " << curNegNormalSepDist/deltaC[i]
900 // << ", " << curNormalTraction << endl;
903 traction_[i] = curNormalTraction*n[i] + curTangentialTraction;
904 // traction_[sizeByTwo + i] = -traction_[i];
910 - (n & (mu*gradU.T() - (mu + lambda)*gradU))
914 directionMixedFvPatchVectorField::updateCoeffs();
919 void solidCohesiveFixedModeMixFvPatchVectorField::write(Ostream& os) const
921 directionMixedFvPatchVectorField::write(os);
922 traction_.writeEntry("traction", os);
923 initiationTraction_.writeEntry("initiationTraction", os);
924 separationDistance_.writeEntry("separationDistance", os);
925 oldSeparationDistance_.writeEntry("oldSeparationDistance", os);
926 unloadingSeparationDistance_.writeEntry("unloadingSeparationDistance", os);
927 //os.writeKeyword("cohesiveLaw") << law().type()
928 // << token::END_STATEMENT << nl;
929 os.writeKeyword("relaxationFactor") << relaxationFactor_
930 << token::END_STATEMENT << nl;
931 os.writeKeyword("beta") << beta_
932 << token::END_STATEMENT << nl;
933 os.writeKeyword("explicitSeparationDistance")
934 << explicitSeparationDistance_
935 << token::END_STATEMENT << nl;
936 os.writeKeyword("contact") << contact_
937 << token::END_STATEMENT << nl;
938 os.writeKeyword("contactConstant") << contactConstant_
939 << token::END_STATEMENT << nl;
940 os.writeKeyword("minUnloadingSeparationDistance")
941 << minUnloadingSeparationDistance_
942 << token::END_STATEMENT << nl;
946 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
951 solidCohesiveFixedModeMixFvPatchVectorField
954 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
956 } // End namespace Foam
958 // ************************************************************************* //