1 /*---------------------------------------------------------------------------*\
3 \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
5 \\ / A nd | Copyright (C) 2004-2007 Hrvoje Jasak
7 -------------------------------------------------------------------------------
9 This file is part of OpenFOAM.
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 the
13 Free Software Foundation; either version 2 of the License, or (at your
14 option) any later version.
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
21 You should have received a copy of the GNU General Public License
22 along with OpenFOAM; if not, write to the Free Software Foundation,
23 Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
29 Arbitrary crack propagation solver.
30 Cracks may propagate along any mesh internal face.
33 Carolan D, Tuković Z, Murphy N, Ivankovic A, Arbitrary crack propagation
34 in multi-phase materials using the finite volume method, Computational
35 Materials Science, 2013, http://dx.doi.org/10.1016/j.commatsci.2012.11.049.
38 Zeljko Tukovic, FSB Zagreb
42 \*---------------------------------------------------------------------------*/
45 #include "constitutiveModel.H"
46 //#include "componentReferenceList.H"
47 #include "crackerFvMesh.H"
48 #include "processorPolyPatch.H"
49 #include "SortableList.H"
50 #include "solidInterface.H"
51 #include "solidCohesiveFvPatchVectorField.H"
52 #include "solidCohesiveFixedModeMixFvPatchVectorField.H"
54 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
56 int main(int argc, char *argv[])
58 # include "setRootCase.H"
59 # include "createTime.H"
60 # include "createCrackerMesh.H"
61 # include "createFields.H"
62 # include "createCrack.H"
63 //# include "createReference.H"
64 # include "createHistory.H"
65 # include "readDivSigmaExpMethod.H"
66 # include "createSolidInterfaceNoModify.H"
68 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
70 Info<< "\nStarting time loop\n" << endl;
74 scalar maxEffTractionFraction = 0;
76 // time rates for predictor
77 volTensorField gradV = fvc::ddt(gradU);
78 surfaceVectorField snGradV =
79 (snGradU - snGradU.oldTime())/runTime.deltaT();
81 //# include "initialiseSolution.H"
85 # include "readSolidMechanicsControls.H"
86 # include "setDeltaT.H"
90 Info<< "\nTime: " << runTime.timeName() << " s\n" << endl;
92 volScalarField rho = rheology.rho();
93 volScalarField mu = rheology.mu();
94 volScalarField lambda = rheology.lambda();
95 surfaceScalarField muf = fvc::interpolate(mu);
96 surfaceScalarField lambdaf = fvc::interpolate(lambda);
98 if (solidInterfaceCorr)
100 solidInterfacePtr->modifyProperties(muf, lambdaf);
103 //# include "waveCourantNo.H"
106 lduMatrix::solverPerformance solverPerf;
107 scalar initialResidual = 0;
108 scalar relativeResidual = 1;
109 //scalar forceResidual = 1;
110 label nFacesToBreak = 0;
111 label nCoupledFacesToBreak = 0;
112 bool topoChange = false;
114 // Predictor step using time rates
117 Info<< "Predicting U, gradU and snGradU using velocity"
119 U += V*runTime.deltaT();
120 gradU += gradV*runTime.deltaT();
121 snGradU += snGradV*runTime.deltaT();
126 surfaceVectorField n = mesh.Sf()/mesh.magSf();
131 # include "calculateDivSigmaExp.H"
137 fvm::laplacian(2*muf + lambdaf, U, "laplacian(DU,U)")
141 //# include "setReference.H"
143 if (solidInterfaceCorr)
145 solidInterfacePtr->correct(UEqn);
153 solverPerf = UEqn.solve();
157 # include "aitkenRelaxation.H"
166 initialResidual = solverPerf.initialResidual();
167 aitkenInitialRes = gMax(mag(U.internalField()));
170 //gradU = solidInterfacePtr->grad(U);
171 // use leastSquaresSolidInterface grad scheme
172 gradU = fvc::grad(U);
174 # include "calculateRelativeResidual.H"
175 //# include "calculateForceResidual.H"
177 if (iCorr % infoFrequency == 0)
179 Info << "\tTime " << runTime.value()
180 << ", Corr " << iCorr
181 << ", Solving for " << U.name()
182 << " using " << solverPerf.solverName()
183 << ", res = " << solverPerf.initialResidual()
184 << ", rel res = " << relativeResidual;
187 Info << ", aitken = " << aitkenTheta;
189 Info << ", inner iters " << solverPerf.nIterations() << endl;
198 solverPerf.initialResidual() > convergenceTolerance
199 //relativeResidual > convergenceTolerance
205 Info << "Solving for " << U.name() << " using "
206 << solverPerf.solverName()
207 << ", Initial residual = " << initialResidual
208 << ", Final residual = " << solverPerf.initialResidual()
209 << ", No outer iterations " << iCorr
210 << ", Relative residual " << relativeResidual << endl;
212 # include "calculateTraction.H"
213 # include "updateCrack.H"
215 Info<< "Max effective traction fraction: "
216 << maxEffTractionFraction << endl;
218 // reset counter if faces want to crack
219 if ((nFacesToBreak > 0) || (nCoupledFacesToBreak > 0)) iCorr = 0;
221 while( (nFacesToBreak > 0) || (nCoupledFacesToBreak > 0));
223 if (cohesivePatchUPtr)
225 if (returnReduce(cohesivePatchUPtr->size(), sumOp<label>()))
227 cohesivePatchUPtr->cracking();
236 cohesivePatchUFixedModePtr->size(),
241 Pout << "Number of faces in crack: "
242 << cohesivePatchUFixedModePtr->size() << endl;
243 cohesivePatchUFixedModePtr->relativeSeparationDistance();
247 // update time rates for predictor
251 gradV = fvc::ddt(gradU);
252 snGradV = (snGradU - snGradU.oldTime())/runTime.deltaT();
255 # include "calculateEpsilonSigma.H"
256 # include "writeFields.H"
257 # include "writeHistory.H"
259 Info<< "ExecutionTime = " << runTime.elapsedCpuTime() << " s"
260 << " ClockTime = " << runTime.elapsedClockTime() << " s\n\n"
264 Info<< "End\n" << endl;
270 // ************************************************************************* //